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..8e6054d92 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) +BASE_CPPFLAGS += -DUSE_TYPED_RSET +# makeBpt is created locally +MAKEBPT = $(INSTALL_HOST_BIN)/makeBpt$(HOSTEXE) +# 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/Makefile b/src/Makefile index 257099840..dfd1d3be9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,77 +4,28 @@ # Copyright (c) 2002 The Regents 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 the file LICENSE that is included with this distribution. #************************************************************************* TOP = .. include $(TOP)/configure/CONFIG +# PDB Tools + DIRS += tools -DIRS += tools/test -tools/test_DEPEND_DIRS = tools - -DIRS += template/base -template/base_DEPEND_DIRS = tools - -DIRS += template/ext -template/ext_DEPEND_DIRS = tools - -# Common - -DIRS += libCom -libCom_DEPEND_DIRS = tools - -DIRS += libCom/RTEMS -libCom/RTEMS_DEPEND_DIRS = libCom - -DIRS += libCom/test -libCom/test_DEPEND_DIRS = libCom/RTEMS - -# Channel Access - -DIRS += ca/client -ca/client_DEPEND_DIRS = libCom - -DIRS += ca/client/tools -ca/client/tools_DEPEND_DIRS = ca/client - -DIRS += ca/legacy/gdd -ca/legacy/gdd_DEPEND_DIRS = ca/client - -DIRS += ca/legacy/pcas -ca/legacy/pcas_DEPEND_DIRS = ca/legacy/gdd - -DIRS += ca/legacy/pcas/ex -# needs ioc for dbStaticHost -ca/legacy/pcas/ex_DEPEND_DIRS = ca/legacy/pcas libCom ioc - -DIRS += ca/client/perl -ca/client/perl_DEPEND_DIRS = ca/client - # PDB Core DIRS += ioc -ioc_DEPEND_DIRS = libCom ca/client - -DIRS += ioc/db/test -ioc/db/test_DEPEND_DIRS = ioc libCom/RTEMS - -DIRS += ioc/dbtemplate/test -ioc/dbtemplate/test_DEPEND_DIRS = ioc +ioc_DEPEND_DIRS = tools # PDB Standard Record Definitions DIRS += std -std_DEPEND_DIRS = ioc libCom/RTEMS +std_DEPEND_DIRS = ioc -DIRS += std/filters/test -std/filters/test_DEPEND_DIRS = std - -DIRS += std/rec/test -std/rec/test_DEPEND_DIRS = std +# Templates +DIRS += template include $(TOP)/configure/RULES_DIRS - 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/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/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/ioc/Makefile b/src/ioc/Makefile index 6dbd13b54..646a966c5 100644 --- a/src/ioc/Makefile +++ b/src/ioc/Makefile @@ -4,7 +4,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. #************************************************************************* TOP=../.. @@ -37,4 +37,3 @@ include $(IOCDIR)/dbStatic/RULES include $(IOCDIR)/bpt/RULES include $(IOCDIR)/db/RULES include $(IOCDIR)/dbtemplate/RULES - diff --git a/src/ioc/bpt/Makefile b/src/ioc/bpt/Makefile index b8d73345f..ea1db1f14 100644 --- a/src/ioc/bpt/Makefile +++ b/src/ioc/bpt/Makefile @@ -4,7 +4,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/ioc/Makefile. diff --git a/src/libCom/Com.rc b/src/libCom/Com.rc deleted file mode 100644 index d5a5562b7..000000000 --- a/src/libCom/Com.rc +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include "epicsVersion.h" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION EPICS_VERSION,EPICS_REVISION,EPICS_MODIFICATION,EPICS_PATCH_LEVEL - PRODUCTVERSION EPICS_VERSION,EPICS_REVISION,EPICS_MODIFICATION,EPICS_PATCH_LEVEL - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_UNKNOWN - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments","Common Library for EPICS\0" - VALUE "CompanyName", "The EPICS collaboration\0" - VALUE "FileDescription", "Common Library\0" - VALUE "FileVersion", EPICS_VERSION_STRING "\0" - VALUE "InternalName", "Com\0" - VALUE "LegalCopyright", "Copyright (C) Univ. of California, Univ. of Chicago\0" - VALUE "OriginalFilename", "Com.dll\0" - VALUE "ProductName", "Experimental Physics and Industrial Control System (EPICS)\0" - VALUE "ProductVersion", EPICS_VERSION_STRING "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/src/libCom/Makefile b/src/libCom/Makefile deleted file mode 100644 index ee93ada0a..000000000 --- a/src/libCom/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -TOP = ../.. -include $(TOP)/configure/CONFIG - -# Uncomment this to remove the (benign) valgrind helper stubs -#USR_CFLAGS += -DNVALGRIND - -SRC = $(TOP)/src -LIBCOM = $(SRC)/libCom - -INC += valgrind/valgrind.h - -include $(LIBCOM)/as/Makefile -include $(LIBCOM)/bucketLib/Makefile -include $(LIBCOM)/calc/Makefile -include $(LIBCOM)/cvtFast/Makefile -include $(LIBCOM)/cppStd/Makefile -include $(LIBCOM)/cxxTemplates/Makefile -include $(LIBCOM)/dbmf/Makefile -include $(LIBCOM)/ellLib/Makefile -include $(LIBCOM)/env/Makefile -include $(LIBCOM)/error/Makefile -include $(LIBCOM)/fdmgr/Makefile -include $(LIBCOM)/flex/Makefile -include $(LIBCOM)/freeList/Makefile -include $(LIBCOM)/gpHash/Makefile -include $(LIBCOM)/iocsh/Makefile -include $(LIBCOM)/log/Makefile -include $(LIBCOM)/macLib/Makefile -include $(LIBCOM)/misc/Makefile -include $(LIBCOM)/osi/Makefile -include $(LIBCOM)/pool/Makefile -include $(LIBCOM)/ring/Makefile -include $(LIBCOM)/taskwd/Makefile -include $(LIBCOM)/timer/Makefile -include $(LIBCOM)/yacc/Makefile -include $(LIBCOM)/yajl/Makefile - -# Library to build: -LIBRARY=Com - -Com_SYS_LIBS_WIN32 = ws2_32 advapi32 user32 - -Com_RCS = Com.rc - -ifeq ($(T_A),$(EPICS_HOST_ARCH)) - # Antelope & flex are needed to finish libCom - DELAY_INSTALL_LIBS = YES -endif - -include $(TOP)/configure/RULES - -include $(LIBCOM)/as/RULES -include $(LIBCOM)/env/RULES -include $(LIBCOM)/error/RULES -include $(LIBCOM)/flex/RULES -include $(LIBCOM)/misc/RULES -include $(LIBCOM)/osi/RULES - diff --git a/src/libCom/RTEMS/Makefile b/src/libCom/RTEMS/Makefile deleted file mode 100644 index 4c0b64c04..000000000 --- a/src/libCom/RTEMS/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../../.. -include $(TOP)/configure/CONFIG - -INC += epicsRtemsInitHooks.h - -rtemsCom_SRCS += rtems_init.c -rtemsCom_SRCS += rtems_config.c -rtemsCom_SRCS += rtems_netconfig.c -rtemsCom_SRCS += rtems_util.c -rtemsCom_SRCS += setBootConfigFromNVRAM.c -rtemsCom_SRCS += epicsRtemsInitHookPre.c -rtemsCom_SRCS += epicsRtemsInitHookPost.c - -LIBRARY_RTEMS = rtemsCom - -include $(TOP)/configure/RULES diff --git a/src/libCom/RTEMS/epicsRtemsInitHookPost.c b/src/libCom/RTEMS/epicsRtemsInitHookPost.c deleted file mode 100644 index f589eb9cf..000000000 --- a/src/libCom/RTEMS/epicsRtemsInitHookPost.c +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 The University of Chicago, as Operator of Argonne -* National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Dummy version -- use if application does not provide its own version - */ -#include "epicsRtemsInitHooks.h" - -int -epicsRtemsInitPostSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config) -{ - return 0; -} diff --git a/src/libCom/RTEMS/epicsRtemsInitHookPre.c b/src/libCom/RTEMS/epicsRtemsInitHookPre.c deleted file mode 100644 index 08efe1fe2..000000000 --- a/src/libCom/RTEMS/epicsRtemsInitHookPre.c +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 The University of Chicago, as Operator of Argonne -* National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Dummy version -- use if application does not provide its own version - */ -#include "epicsRtemsInitHooks.h" - -int -epicsRtemsInitPreSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config) -{ - return 0; -} diff --git a/src/libCom/RTEMS/epicsRtemsInitHooks.h b/src/libCom/RTEMS/epicsRtemsInitHooks.h deleted file mode 100644 index b7f09c100..000000000 --- a/src/libCom/RTEMS/epicsRtemsInitHooks.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 The University of Chicago, as Operator of Argonne -* National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Hooks into RTEMS startup code - */ -#include -#include - -extern char *env_nfsServer; -extern char *env_nfsPath; -extern char *env_nfsMountPoint; - -/* - * Return 0 for success, non-zero for failure (will cause panic) - */ -int epicsRtemsInitPreSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config); -int epicsRtemsInitPostSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config); diff --git a/src/libCom/RTEMS/rtems_config.c b/src/libCom/RTEMS/rtems_config.c deleted file mode 100644 index 147c08b10..000000000 --- a/src/libCom/RTEMS/rtems_config.c +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS configuration for EPICS - * Author: W. Eric Norum - * norume@aps.anl.gov - * (630) 252-4793 - */ - -#include - -/* - *********************************************************************** - * RTEMS CONFIGURATION * - *********************************************************************** - */ -#define CONFIGURE_RTEMS_INIT_TASKS_TABLE - -#if __RTEMS_MAJOR__>4 || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99) -# define CONFIGURE_UNIFIED_WORK_AREAS -#else -# define CONFIGURE_EXECUTIVE_RAM_SIZE (2000*1024) -#endif - -#define CONFIGURE_MAXIMUM_TASKS rtems_resource_unlimited(30) -#define CONFIGURE_MAXIMUM_SEMAPHORES rtems_resource_unlimited(500) -#define CONFIGURE_MAXIMUM_TIMERS rtems_resource_unlimited(20) -#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES rtems_resource_unlimited(5) -#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1 - -#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 150 -#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM -#define CONFIGURE_MAXIMUM_DRIVERS 8 - -#define CONFIGURE_MICROSECONDS_PER_TICK 20000 - -#define CONFIGURE_INIT_TASK_PRIORITY 80 - -#define CONFIGURE_MALLOC_STATISTICS 1 - -#define CONFIGURE_INIT -#define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | \ - RTEMS_NO_TIMESLICE | \ - RTEMS_NO_ASR | \ - RTEMS_INTERRUPT_LEVEL(0)) -#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_FLOATING_POINT | RTEMS_LOCAL) -#define CONFIGURE_INIT_TASK_STACK_SIZE (16*1024) -rtems_task Init (rtems_task_argument argument); - -#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER -#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER - -#define CONFIGURE_FILESYSTEM_NFS -#define CONFIGURE_FILESYSTEM_IMFS - -/* - * This should be made BSP dependent, not CPU dependent but I know of no - * appropriate conditionals to use. - * The new general time support makes including the RTC driverr less important. - */ -#if !defined(mpc604) && !defined(__mc68040__) && !defined(__mcf5200__) && !defined(mpc7455) && !defined(__arm__) && !defined(__nios2__)/* don't have RTC code */ -#define CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER -#endif - - -#include -#include diff --git a/src/libCom/RTEMS/rtems_init.c b/src/libCom/RTEMS/rtems_init.c deleted file mode 100644 index 82871da0d..000000000 --- a/src/libCom/RTEMS/rtems_init.c +++ /dev/null @@ -1,668 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS startup task for EPICS - * Author: W. Eric Norum - * eric.norum@usask.ca - * (306) 966-5394 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsTime.h" -#include "epicsExit.h" -#include "envDefs.h" -#include "errlog.h" -#include "logClient.h" -#include "osiUnistd.h" -#include "iocsh.h" -#include "osdTime.h" - -#include "epicsRtemsInitHooks.h" - -/* - * Prototypes for some functions not in header files - */ -void tzset(void); -int fileno(FILE *); -int main(int argc, char **argv); - -static void -logReset (void) -{ - void rtems_bsp_reset_cause(char *buf, size_t capacity) __attribute__((weak)); - void (*fp)(char *buf, size_t capacity) = rtems_bsp_reset_cause; - - if (fp) { - char buf[80]; - fp(buf, sizeof buf); - errlogPrintf ("Startup after %s.\n", buf); - } - else { - errlogPrintf ("Startup.\n"); - } -} - -/* - *********************************************************************** - * FATAL ERROR REPORTING * - *********************************************************************** - */ -/* - * Delay for a while, then terminate - */ -static void -delayedPanic (const char *msg) -{ - extern rtems_interval rtemsTicksPerSecond; - - rtems_task_wake_after (rtemsTicksPerSecond); - rtems_panic (msg); -} - -/* - * Log error and terminate - */ -void -LogFatal (const char *msg, ...) -{ - va_list ap; - - va_start (ap, msg); - errlogVprintf (msg, ap); - va_end (ap); - delayedPanic (msg); -} - -/* - * Log RTEMS error and terminate - */ -void -LogRtemsFatal (const char *msg, rtems_status_code sc) -{ - errlogPrintf ("%s: %s\n", msg, rtems_status_text (sc)); - delayedPanic (msg); -} - -/* - * Log network error and terminate - */ -void -LogNetFatal (const char *msg, int err) -{ - errlogPrintf ("%s: %d\n", msg, err); - delayedPanic (msg); -} - -void * -mustMalloc(int size, const char *msg) -{ - void *p; - - if ((p = malloc (size)) == NULL) - LogFatal ("Can't allocate space for %s.\n", msg); - return p; -} - -/* - *********************************************************************** - * REMOTE FILE ACCESS * - *********************************************************************** - */ -#ifdef OMIT_NFS_SUPPORT -# include -#endif - -static int -initialize_local_filesystem(char **argv) -{ - extern char _DownloadLocation[] __attribute__((weak)); - extern char _FlashBase[] __attribute__((weak)); - extern char _FlashSize[] __attribute__((weak)); - - argv[0] = rtems_bsdnet_bootp_boot_file_name; - if (_FlashSize && (_DownloadLocation || _FlashBase)) { - extern char _edata[]; - size_t flashIndex = _edata - _DownloadLocation; - char *header = _FlashBase + flashIndex; - - if (memcmp(header + 257, "ustar ", 8) == 0) { - int fd; - printf ("***** Unpack in-memory file system (IMFS) *****\n"); - if (rtems_tarfs_load("/", (unsigned char *)header, (size_t)_FlashSize - flashIndex) != 0) { - printf("Can't unpack tar filesystem\n"); - return 0; - } - if ((fd = open(rtems_bsdnet_bootp_cmdline, 0)) >= 0) { - close(fd); - printf ("***** Found startup script (%s) in IMFS *****\n", rtems_bsdnet_bootp_cmdline); - argv[1] = rtems_bsdnet_bootp_cmdline; - return 1; - } - printf ("***** Startup script (%s) not in IMFS *****\n", rtems_bsdnet_bootp_cmdline); - } - } - return 0; -} - -#ifndef OMIT_NFS_SUPPORT -#if __RTEMS_MAJOR__>4 || \ - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || \ - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99) -int -nfsMount(char *uidhost, char *path, char *mntpoint) -{ - int devl = strlen(uidhost) + strlen(path) + 2; - char *dev; - int rval = -1; - - if ((dev = malloc(devl)) == NULL) { - fprintf(stderr,"nfsMount: out of memory\n"); - return -1; - } - sprintf(dev, "%s:%s", uidhost, path); - printf("Mount %s on %s\n", dev, mntpoint); - if (rtems_mkdir(mntpoint, S_IRWXU | S_IRWXG | S_IRWXO)) - printf("Warning -- unable to make directory \"%s\"\n", mntpoint); - if (mount(dev, mntpoint, RTEMS_FILESYSTEM_TYPE_NFS, - RTEMS_FILESYSTEM_READ_WRITE, NULL)) { - perror("mount failed"); - } - else { - rval = 0; - } - free(dev); - return rval; -} -#define NFS_INIT -#else -#define NFS_INIT rpcUdpInit(); nfsInit(0,0); -#endif -#endif - -static void -initialize_remote_filesystem(char **argv, int hasLocalFilesystem) -{ -#ifdef OMIT_NFS_SUPPORT - printf ("***** Initializing TFTP *****\n"); -#if __RTEMS_MAJOR__>4 || \ - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || \ - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99) - mount_and_make_target_path(NULL, - "/TFTP", - RTEMS_FILESYSTEM_TYPE_TFTPFS, - RTEMS_FILESYSTEM_READ_WRITE, - NULL); -#else - rtems_bsdnet_initialize_tftp_filesystem (); -#endif - if (!hasLocalFilesystem) { - char *path; - int pathsize = 200; - int l; - - path = mustMalloc(pathsize, "Command path name "); - strcpy (path, "/TFTP/BOOTP_HOST/epics/"); - l = strlen (path); - if (gethostname (&path[l], pathsize - l - 10) || (path[l] == '\0')) - { - LogFatal ("Can't get host name"); - } - strcat (path, "/st.cmd"); - argv[1] = path; - } -#else - char *server_name; - char *server_path; - char *mount_point; - char *cp; - int l = 0; - - printf ("***** Initializing NFS *****\n"); - NFS_INIT - if (env_nfsServer && env_nfsPath && env_nfsMountPoint) { - server_name = env_nfsServer; - server_path = env_nfsPath; - mount_point = env_nfsMountPoint; - cp = mount_point; - while ((cp = strchr(cp+1, '/')) != NULL) { - *cp = '\0'; - if ((mkdir (mount_point, 0755) != 0) - && (errno != EEXIST)) - LogFatal("Can't create directory \"%s\": %s.\n", - mount_point, strerror(errno)); - *cp = '/'; - } - argv[1] = rtems_bsdnet_bootp_cmdline; - } - else if (hasLocalFilesystem) { - return; - } - else { - /* - * Use first component of nvram/bootp command line pathname - * to set up initial NFS mount. A "/tftpboot/" is prepended - * if the pathname does not begin with a '/'. This allows - * NFS and TFTP to have a similar view of the remote system. - */ - if (rtems_bsdnet_bootp_cmdline[0] == '/') - cp = rtems_bsdnet_bootp_cmdline + 1; - else - cp = rtems_bsdnet_bootp_cmdline; - cp = strchr(cp, '/'); - if ((cp == NULL) - || ((l = cp - rtems_bsdnet_bootp_cmdline) == 0)) - LogFatal("\"%s\" is not a valid command pathname.\n", rtems_bsdnet_bootp_cmdline); - cp = mustMalloc(l + 20, "NFS mount paths"); - server_path = cp; - server_name = rtems_bsdnet_bootp_server_name; - if (rtems_bsdnet_bootp_cmdline[0] == '/') { - mount_point = server_path; - strncpy(mount_point, rtems_bsdnet_bootp_cmdline, l); - mount_point[l] = '\0'; - argv[1] = rtems_bsdnet_bootp_cmdline; - /* - * Its probably common to embed the mount point in the server - * name so, when this is occurring, dont clobber the mount point - * by appending the first node from the command path. This allows - * the mount point to be a different path then the server's mount - * path. - * - * This allows for example a line similar to as follows the DHCP - * configuration file. - * - * server-name "159.233@192.168.0.123:/vol/vol0/bootRTEMS"; - */ - if ( server_name ) { - const size_t allocSize = strlen ( server_name ) + 2; - char * const pServerName = mustMalloc( allocSize, - "NFS mount paths"); - char * const pServerPath = mustMalloc ( allocSize, - "NFS mount paths"); - const int scanfStatus = sscanf ( - server_name, - "%[^:] : / %s", - pServerName, - pServerPath + 1u ); - if ( scanfStatus == 2 ) { - pServerPath[0u]= '/'; - server_name = pServerName; - server_path = pServerPath; - } - else { - free ( pServerName ); - free ( pServerPath ); - } - } - } - else { - char *abspath = mustMalloc(strlen(rtems_bsdnet_bootp_cmdline)+2,"Absolute command path"); - strcpy(server_path, "/tftpboot/"); - mount_point = server_path + strlen(server_path); - strncpy(mount_point, rtems_bsdnet_bootp_cmdline, l); - mount_point[l] = '\0'; - mount_point--; - strcpy(abspath, "/"); - strcat(abspath, rtems_bsdnet_bootp_cmdline); - argv[1] = abspath; - } - } - errlogPrintf("nfsMount(\"%s\", \"%s\", \"%s\")\n", - server_name, server_path, mount_point); - nfsMount(server_name, server_path, mount_point); -#endif -} - -static -char rtems_etc_hosts[] = "127.0.0.1 localhost\n"; - -/* If it doesn't already exist, create /etc/hosts with an entry for 'localhost' */ -static -void fixup_hosts(void) -{ - FILE *fp; - int ret; - struct stat STAT; - - ret=stat("/etc/hosts", &STAT); - if(ret==0) - { - return; /* already exists, assume file */ - } else if(errno!=ENOENT) { - perror("error: fixup_hosts stat /etc/hosts"); - return; - } - - ret = mkdir("/etc", 0775); - if(ret!=0 && errno!=EEXIST) - { - perror("error: fixup_hosts create /etc"); - return; - } - - if((fp=fopen("/etc/hosts", "w"))==NULL) - { - perror("error: fixup_hosts create /etc/hosts"); - } - - if(fwrite(rtems_etc_hosts, 1, sizeof(rtems_etc_hosts)-1, fp)!=sizeof(rtems_etc_hosts)-1) - { - perror("error: failed to write /etc/hosts"); - } - - fclose(fp); -} - -/* - * Get to the startup script directory - * The TFTP filesystem requires a trailing '/' on chdir arguments. - */ -static void -set_directory (const char *commandline) -{ - const char *cp; - char *directoryPath; - int l; - - cp = strrchr(commandline, '/'); - if (cp == NULL) { - l = 0; - cp = "/"; - } - else { - l = cp - commandline; - cp = commandline; - } - directoryPath = mustMalloc(l + 2, "Command path directory "); - strncpy(directoryPath, cp, l); - directoryPath[l] = '/'; - directoryPath[l+1] = '\0'; - if (chdir (directoryPath) < 0) - LogFatal ("Can't set initial directory(%s): %s\n", directoryPath, strerror(errno)); - else - errlogPrintf("chdir(\"%s\")\n", directoryPath); - free(directoryPath); -} - -/* - *********************************************************************** - * RTEMS/EPICS COMMANDS * - *********************************************************************** - */ -/* - * RTEMS status - */ -static void -rtems_netstat (unsigned int level) -{ - rtems_bsdnet_show_if_stats (); - rtems_bsdnet_show_mbuf_stats (); - if (level >= 1) { - rtems_bsdnet_show_inet_routes (); - } - if (level >= 2) { - rtems_bsdnet_show_ip_stats (); - rtems_bsdnet_show_icmp_stats (); - rtems_bsdnet_show_udp_stats (); - rtems_bsdnet_show_tcp_stats (); - } -} - -static const iocshArg netStatArg0 = { "level",iocshArgInt}; -static const iocshArg * const netStatArgs[1] = {&netStatArg0}; -static const iocshFuncDef netStatFuncDef = {"netstat",1,netStatArgs}; -static void netStatCallFunc(const iocshArgBuf *args) -{ - rtems_netstat(args[0].ival); -} - -static const iocshFuncDef heapSpaceFuncDef = {"heapSpace",0,NULL}; -static void heapSpaceCallFunc(const iocshArgBuf *args) -{ - rtems_malloc_statistics_t s; - double x; - - malloc_get_statistics(&s); - x = s.space_available - (unsigned long)(s.lifetime_allocated - s.lifetime_freed); - if (x >= 1024*1024) - printf("Heap space: %.1f MB\n", x / (1024 * 1024)); - else - printf("Heap space: %.1f kB\n", x / 1024); -} - -#ifndef OMIT_NFS_SUPPORT -static const iocshArg nfsMountArg0 = { "[uid.gid@]host",iocshArgString}; -static const iocshArg nfsMountArg1 = { "server path",iocshArgString}; -static const iocshArg nfsMountArg2 = { "mount point",iocshArgString}; -static const iocshArg * const nfsMountArgs[3] = {&nfsMountArg0,&nfsMountArg1, - &nfsMountArg2}; -static const iocshFuncDef nfsMountFuncDef = {"nfsMount",3,nfsMountArgs}; -static void nfsMountCallFunc(const iocshArgBuf *args) -{ - char *cp = args[2].sval; - while ((cp = strchr(cp+1, '/')) != NULL) { - *cp = '\0'; - if ((mkdir (args[2].sval, 0755) != 0) && (errno != EEXIST)) { - printf("Can't create directory \"%s\": %s.\n", - args[2].sval, strerror(errno)); - return; - } - *cp = '/'; - } - nfsMount(args[0].sval, args[1].sval, args[2].sval); -} -#endif - -/* - * Register RTEMS-specific commands - */ -static void iocshRegisterRTEMS (void) -{ - iocshRegister(&netStatFuncDef, netStatCallFunc); - iocshRegister(&heapSpaceFuncDef, heapSpaceCallFunc); -#ifndef OMIT_NFS_SUPPORT - iocshRegister(&nfsMountFuncDef, nfsMountCallFunc); -#endif -} - -/* - * Set up the console serial line (no handshaking) - */ -static void -initConsole (void) -{ - struct termios t; - - if (tcgetattr (fileno (stdin), &t) < 0) { - printf ("tcgetattr failed: %s\n", strerror (errno)); - return; - } - t.c_iflag &= ~(IXOFF | IXON | IXANY); - if (tcsetattr (fileno (stdin), TCSANOW, &t) < 0) { - printf ("tcsetattr failed: %s\n", strerror (errno)); - return; - } -} - -/* - * Ensure that the configuration object files - * get pulled in from the library - */ -extern rtems_configuration_table Configuration; -extern struct rtems_bsdnet_config rtems_bsdnet_config; -const void *rtemsConfigArray[] = { - &Configuration, - &rtems_bsdnet_config -}; - -/* - * Hook to ensure that BSP cleanup code gets run on exit - */ -static void -exitHandler(void) -{ - rtems_shutdown_executive(0); -} - -/* - * RTEMS Startup task - */ -rtems_task -Init (rtems_task_argument ignored) -{ - int result; - char *argv[3] = { NULL, NULL, NULL }; - char *cp; - rtems_task_priority newpri; - rtems_status_code sc; - rtems_time_of_day now; - - /* - * Explain why we're here - */ - logReset(); - - /* - * Architecture-specific hooks - */ - if (epicsRtemsInitPreSetBootConfigFromNVRAM(&rtems_bsdnet_config) != 0) - delayedPanic("epicsRtemsInitPreSetBootConfigFromNVRAM"); - if (rtems_bsdnet_config.bootp == NULL) { - extern void setBootConfigFromNVRAM(void); - setBootConfigFromNVRAM(); - } - if (epicsRtemsInitPostSetBootConfigFromNVRAM(&rtems_bsdnet_config) != 0) - delayedPanic("epicsRtemsInitPostSetBootConfigFromNVRAM"); - - /* - * Override RTEMS configuration - */ - rtems_task_set_priority ( - RTEMS_SELF, - epicsThreadGetOssPriorityValue(epicsThreadPriorityIocsh), - &newpri); - - /* - * Create a reasonable environment - */ - initConsole (); - putenv ("TERM=xterm"); - putenv ("IOCSH_HISTSIZE=20"); - - /* - * Display some OS information - */ - printf("\n***** RTEMS Version: %s *****\n", - rtems_get_version_string()); - - /* - * Start network - */ - if ((cp = getenv("EPICS_TS_NTP_INET")) != NULL) - rtems_bsdnet_config.ntp_server[0] = cp; - if (rtems_bsdnet_config.network_task_priority == 0) - { - unsigned int p; - if (epicsThreadHighestPriorityLevelBelow(epicsThreadPriorityScanLow, &p) - == epicsThreadBooleanStatusSuccess) - { - rtems_bsdnet_config.network_task_priority = epicsThreadGetOssPriorityValue(p); - } - } - printf("\n***** Initializing network *****\n"); - rtems_bsdnet_initialize_network(); - initialize_remote_filesystem(argv, initialize_local_filesystem(argv)); - fixup_hosts(); - - /* - * More environment: iocsh prompt and hostname - */ - { - char hostname[1024]; - gethostname(hostname, 1023); - char *cp = mustMalloc(strlen(hostname)+3, "iocsh prompt"); - sprintf(cp, "%s> ", hostname); - epicsEnvSet ("IOCSH_PS1", cp); - epicsEnvSet("IOC_NAME", hostname); - } - - /* - * Use BSP-supplied time of day if available otherwise supply default time. - * It is very likely that other time synchronization facilities in EPICS - * will soon override this value. - */ - if (rtems_clock_get(RTEMS_CLOCK_GET_TOD,&now) != RTEMS_SUCCESSFUL) { - now.year = 2001; - now.month = 1; - now.day = 1; - now.hour = 0; - now.minute = 0; - now.second = 0; - now.ticks = 0; - if ((sc = rtems_clock_set (&now)) != RTEMS_SUCCESSFUL) - printf ("***** Can't set time: %s\n", rtems_status_text (sc)); - } - if (getenv("TZ") == NULL) { - const char *tzp = envGetConfigParamPtr(&EPICS_TIMEZONE); - if (tzp == NULL) { - printf("Warning -- no timezone information available -- times will be displayed as GMT.\n"); - } - else { - char tz[10]; - int minWest, toDst = 0, fromDst = 0; - if(sscanf(tzp, "%9[^:]::%d:%d:%d", tz, &minWest, &toDst, &fromDst) < 2) { - printf("Warning: EPICS_TIMEZONE (%s) unrecognizable -- times will be displayed as GMT.\n", tzp); - } - else { - char posixTzBuf[40]; - char *p = posixTzBuf; - p += sprintf(p, "%cST%d:%.2d", tz[0], minWest/60, minWest%60); - if (toDst != fromDst) - p += sprintf(p, "%cDT", tz[0]); - epicsEnvSet("TZ", posixTzBuf); - } - } - } - tzset(); - osdTimeRegister(); - - /* - * Run the EPICS startup script - */ - printf ("***** Preparing EPICS application *****\n"); - iocshRegisterRTEMS (); - set_directory (argv[1]); - epicsEnvSet ("IOC_STARTUP_SCRIPT", argv[1]); - atexit(exitHandler); - errlogFlush(); - printf ("***** Starting EPICS application *****\n"); - result = main ((sizeof argv / sizeof argv[0]) - 1, argv); - printf ("***** IOC application terminating *****\n"); - epicsThreadSleep(1.0); - epicsExit(result); -} diff --git a/src/libCom/RTEMS/rtems_netconfig.c b/src/libCom/RTEMS/rtems_netconfig.c deleted file mode 100644 index 832a6646b..000000000 --- a/src/libCom/RTEMS/rtems_netconfig.c +++ /dev/null @@ -1,120 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS network configuration for EPICS - * Author: W. Eric Norum - * eric.norum@usask.ca - * (306) 966-5394 - * - * This file can be copied to an application source dirctory - * and modified to override the values shown below. - */ -#include -#include -#include - -extern void rtems_bsdnet_loopattach(); -static struct rtems_bsdnet_ifconfig loopback_config = { - "lo0", /* name */ - (int (*)(struct rtems_bsdnet_ifconfig *, int))rtems_bsdnet_loopattach, /* attach function */ - NULL, /* link to next interface */ - "127.0.0.1", /* IP address */ - "255.0.0.0", /* IP net mask */ -}; - -/* - * The following conditionals select the network interface card. - * - * On RTEMS-pc386 targets all network drivers which support run-time - * probing are linked. - * On other targets the network interface specified by the board-support - * package is used. - * To use a different NIC for a particular application, copy this file to the - * application directory and make the appropriate changes. - */ -#if defined(__i386__) -extern int rtems_fxp_attach (struct rtems_bsdnet_ifconfig *, int); -static struct rtems_bsdnet_ifconfig fxp_driver_config = { - "fxp1", /* name */ - rtems_fxp_attach, /* attach function */ - &loopback_config, /* link to next interface */ -}; -extern int rtems_3c509_driver_attach (struct rtems_bsdnet_ifconfig *, int); -static struct rtems_bsdnet_ifconfig e3c509_driver_config = { - "ep0", /* name */ - rtems_3c509_driver_attach, /* attach function */ - &fxp_driver_config, /* link to next interface */ -}; -#define FIRST_DRIVER_CONFIG &e3c509_driver_config -#else - -# if defined(__PPC) - /* - * FIXME: This really belongs in the BSP - */ -# ifndef RTEMS_BSP_NETWORK_DRIVER_NAME -# define RTEMS_BSP_NETWORK_DRIVER_NAME "dc1" -# endif -# ifndef RTEMS_BSP_NETWORK_DRIVER_ATTACH -# define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_dec21140_driver_attach - extern int rtems_dec21140_driver_attach(); -# endif -# endif - -static struct rtems_bsdnet_ifconfig bsp_driver_config = { - RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */ - RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */ - &loopback_config, /* link to next interface */ -}; -#define FIRST_DRIVER_CONFIG &bsp_driver_config - -#endif - -/* - * Allow configure/os/CONFIG_SITE.Common.RTEMS to provide domain name - */ -#ifdef RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME -# define XSTR(x) STR(x) -# define STR(x) #x -# define MY_DOMAINNAME XSTR(RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME) -#else -# define MY_DOMAINNAME NULL -#endif - -/* - * Allow non-BOOTP network configuration - */ -#ifndef MY_DO_BOOTP -# define MY_DO_BOOTP rtems_bsdnet_do_bootp -#endif - -/* - * Allow site- and BSP-specific network buffer space configuration. - * The macro values are specified in KBytes. - */ -#ifndef RTEMS_NETWORK_CONFIG_MBUF_SPACE -# define RTEMS_NETWORK_CONFIG_MBUF_SPACE 180 -#endif -#ifndef RTEMS_NETWORK_CONFIG_CLUSTER_SPACE -# define RTEMS_NETWORK_CONFIG_CLUSTER_SPACE 350 -#endif - -/* - * Network configuration - */ -struct rtems_bsdnet_config rtems_bsdnet_config = { - FIRST_DRIVER_CONFIG, /* Link to next interface */ - MY_DO_BOOTP, /* How to find network config */ - 10, /* If 0 then the network daemons will run at a */ - /* priority just less than the lowest-priority */ - /* EPICS scan thread. */ - /* If non-zero then the network daemons will run */ - /* at this *RTEMS* priority */ - RTEMS_NETWORK_CONFIG_MBUF_SPACE*1024, - RTEMS_NETWORK_CONFIG_CLUSTER_SPACE*1024, - NULL, /* Host name */ - MY_DOMAINNAME, /* Domain name */ -}; diff --git a/src/libCom/RTEMS/rtems_util.c b/src/libCom/RTEMS/rtems_util.c deleted file mode 100644 index ca64f9650..000000000 --- a/src/libCom/RTEMS/rtems_util.c +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS utilitiy routines for EPICS - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - * - * Supplies routines that are present in vxWorks but missing in RTEMS. - */ - -#include -#include -#include -#include -#include -#include - -/* - * Like connect(), but with an explicit timeout - */ -int connectWithTimeout (int sfd, - struct sockaddr *addr, - int addrlen, - struct timeval *timeout) -{ - struct timeval sv; - socklen_t svlen = sizeof sv; - int ret; - - if (!timeout) - return connect (sfd, addr, addrlen); - if (getsockopt (sfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&sv, &svlen) < 0) - return -1; - if (setsockopt (sfd, SOL_SOCKET, SO_RCVTIMEO, (char *)timeout, sizeof *timeout) < 0) - return -1; - ret = connect (sfd, addr, addrlen); - setsockopt (sfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&sv, sizeof sv); - return ret; -} diff --git a/src/libCom/RTEMS/setBootConfigFromNVRAM.c b/src/libCom/RTEMS/setBootConfigFromNVRAM.c deleted file mode 100644 index 6a162c602..000000000 --- a/src/libCom/RTEMS/setBootConfigFromNVRAM.c +++ /dev/null @@ -1,370 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -char *env_nfsServer; -char *env_nfsPath; -char *env_nfsMountPoint; - -/* - * Split argument string of form nfs_server:nfs_export: - * The nfs_export component will be used as: - * - the path to the directory exported from the NFS server - * - the local mount point - * - a prefix of - * For example, the argument string: - * romeo:/export/users:smith/ioc/iocexample/st.cmd - * would: - * - mount /export/users from NFS server romeo on /export/users - * - chdir to /export/users/smith/ioc/iocexample - * - read commands from st.cmd - */ -static void -splitRtemsBsdnetBootpCmdline(void) -{ - char *cp1, *cp2, *cp3; - - if ((cp1 = rtems_bsdnet_bootp_cmdline) == NULL) - return; - if (((cp2 = strchr(cp1, ':')) != NULL) - && (((cp3 = strchr(cp2+1, ' ')) != NULL) - || ((cp3 = strchr(cp2+1, ':')) != NULL))) { - int l1 = cp2 - cp1; - int l2 = cp3 - cp2 - 1; - int l3 = strlen(cp3) - 1; - if (l1 && l2 && l3) { - *cp2++ = '\0'; - *cp3 = '\0'; - env_nfsServer = cp1; - env_nfsMountPoint = env_nfsPath = epicsStrDup(cp2); - *cp3 = '/'; - rtems_bsdnet_bootp_cmdline = cp2; - } - } -} - -/* - * Split NFS mount information of the form nfs_server:host_path:local_path - */ -static void -splitNfsMountPath(char *nfsString) -{ - char *cp2, *cp3; - - if (nfsString == NULL) - return; - if (((cp2 = strchr(nfsString, ':')) != NULL) - && (((cp3 = strchr(cp2+1, ' ')) != NULL) - || ((cp3 = strchr(cp2+1, ':')) != NULL))) { - int l1 = cp2 - nfsString; - int l2 = cp3 - cp2 - 1; - int l3 = strlen(cp3) - 1; - if (l1 && l2 && l3) { - *cp2++ = '\0'; - *cp3++ = '\0'; - env_nfsServer = nfsString; - env_nfsPath = cp2; - env_nfsMountPoint = cp3; - } - } -} - -#if defined(HAVE_MOTLOAD) - -/* - * Motorola MOTLOAD NVRAM Access - */ -static char * -gev(const char *parm, volatile char *nvp) -{ - const char *val; - const char *name; - char *ret; - char c; - - for (;;) { - if (*nvp == '\0') - return NULL; - name = parm; - while ((c = *nvp++) != '\0') { - if ((c == '=') && (*name == '\0')) { - val = (char *)nvp; - while (*nvp++ != '\0') - continue; - ret = malloc(nvp - val); - if (ret == NULL) - return NULL; - strcpy(ret, val); - return ret; - } - if (c != *name++) { - while (*nvp++ != '\0') - continue; - break; - } - } - } -} - -static char * -motScriptParm(const char *mot_script_boot, char parm) -{ - const char *cp; - char *ret; - int l; - - while (*mot_script_boot != '\0') { - if (isspace(*(unsigned char *)mot_script_boot) - && (*(mot_script_boot+1) == '-') - && (*(mot_script_boot+2) == parm)) { - mot_script_boot += 3; - cp = mot_script_boot; - while ((*mot_script_boot != '\0') && - !isspace(*(unsigned char *)mot_script_boot)) - mot_script_boot++; - l = mot_script_boot - cp; - ret = malloc(l+1); - if (ret == NULL) - return NULL; - strncpy(ret, cp, l); - *(ret+l) = '\0'; - return ret; - } - mot_script_boot++; - } - return NULL; -} - -void -setBootConfigFromNVRAM(void) -{ - char *cp; - const char *mot_script_boot; - char *nvp; - -# if defined(BSP_NVRAM_BASE_ADDR) - nvp = (volatile unsigned char *)(BSP_NVRAM_BASE_ADDR+0x70f8); -# elif defined(BSP_I2C_VPD_EEPROM_DEV_NAME) - char gev_buf[3592]; - int fd; - if ((fd = open(BSP_I2C_VPD_EEPROM_DEV_NAME, 0)) < 0) { - printf("Can't open %s: %s\n", BSP_I2C_VPD_EEPROM_DEV_NAME, strerror(errno)); - return; - } - lseek(fd, 0x10f8, SEEK_SET); - if (read(fd, gev_buf, sizeof gev_buf) != sizeof gev_buf) { - printf("Can't read %s: %s\n", BSP_I2C_VPD_EEPROM_DEV_NAME, strerror(errno)); - return; - } - close(fd); - nvp = gev_buf; -# else -# error "No way to read GEV!" -# endif - - if (rtems_bsdnet_config.bootp != NULL) - return; - mot_script_boot = gev("mot-script-boot", nvp); - if ((rtems_bsdnet_bootp_server_name = gev("mot-/dev/enet0-sipa", nvp)) == NULL) - rtems_bsdnet_bootp_server_name = motScriptParm(mot_script_boot, 's'); - if ((rtems_bsdnet_config.gateway = gev("mot-/dev/enet0-gipa", nvp)) == NULL) - rtems_bsdnet_config.gateway = motScriptParm(mot_script_boot, 'g'); - if ((rtems_bsdnet_config.ifconfig->ip_netmask = gev("mot-/dev/enet0-snma", nvp)) == NULL) - rtems_bsdnet_config.ifconfig->ip_netmask = motScriptParm(mot_script_boot, 'm'); - - rtems_bsdnet_config.name_server[0] = gev("rtems-dns-server", nvp); - if (rtems_bsdnet_config.name_server[0] == NULL) - rtems_bsdnet_config.name_server[0] = rtems_bsdnet_bootp_server_name; - cp = gev("rtems-dns-domainname", nvp); - if (cp) - rtems_bsdnet_config.domainname = cp; - - if ((rtems_bsdnet_config.ifconfig->ip_address = gev("mot-/dev/enet0-cipa", nvp)) == NULL) - rtems_bsdnet_config.ifconfig->ip_address = motScriptParm(mot_script_boot, 'c'); - rtems_bsdnet_config.hostname = gev("rtems-client-name", nvp); - if (rtems_bsdnet_config.hostname == NULL) - rtems_bsdnet_config.hostname = rtems_bsdnet_config.ifconfig->ip_address; - - if ((rtems_bsdnet_bootp_boot_file_name = gev("mot-/dev/enet0-file", nvp)) == NULL) - rtems_bsdnet_bootp_boot_file_name = motScriptParm(mot_script_boot, 'f'); - rtems_bsdnet_bootp_cmdline = gev("epics-script", nvp); - splitRtemsBsdnetBootpCmdline(); - splitNfsMountPath(gev("epics-nfsmount", nvp)); - rtems_bsdnet_config.ntp_server[0] = gev("epics-ntpserver", nvp); - if (rtems_bsdnet_config.ntp_server[0] == NULL) - rtems_bsdnet_config.ntp_server[0] = rtems_bsdnet_bootp_server_name; - if ((cp = gev("epics-tz", nvp)) != NULL) - epicsEnvSet("TZ", cp); -} - -#elif defined(HAVE_PPCBUG) -/* - * Motorola PPCBUG NVRAM Access - */ -struct ppcbug_nvram { - uint32_t PacketVersionIdentifier; - uint32_t NodeControlMemoryAddress; - uint32_t BootFileLoadAddress; - uint32_t BootFileExecutionAddress; - uint32_t BootFileExecutionDelay; - uint32_t BootFileLength; - uint32_t BootFileByteOffset; - uint32_t TraceBufferAddress; - uint32_t ClientIPAddress; - uint32_t ServerIPAddress; - uint32_t SubnetIPAddressMask; - uint32_t BroadcastIPAddressMask; - uint32_t GatewayIPAddress; - uint8_t BootpRarpRetry; - uint8_t TftpRarpRetry; - uint8_t BootpRarpControl; - uint8_t UpdateControl; - char BootFilenameString[64]; - char ArgumentFilenameString[64]; -}; - -static char *addr(char *cbuf, uint32_t addr) -{ - struct in_addr a; - if ((a.s_addr = addr) == 0) - return NULL; - return (char *)inet_ntop(AF_INET, &a, cbuf, INET_ADDRSTRLEN); -} - -void -setBootConfigFromNVRAM(void) -{ - static struct ppcbug_nvram nvram; - static char ip_address[INET_ADDRSTRLEN]; - static char ip_netmask[INET_ADDRSTRLEN]; - static char server[INET_ADDRSTRLEN]; - static char gateway[INET_ADDRSTRLEN]; - - if (rtems_bsdnet_config.bootp != NULL) - return; - - /* - * Get network configuation from PPCBUG. - * The 'correct' way to do this would be to issue a .NETCFIG PPCBUG - * system call. Unfortunately it is very difficult to issue such a - * call once RTEMS is up and running so we just copy from the 'known' - * location of the network configuration parameters. - * Care must be taken to access the NVRAM a byte at a time. - */ - -#if defined(NVRAM_INDIRECT) - { - volatile char *addrLo = (volatile char *)0x80000074; - volatile char *addrHi = (volatile char *)0x80000075; - volatile char *data = (volatile char *)0x80000077; - int addr = 0x1000; - char *d = (char *)&nvram; - - while (d < ((char *)&nvram + sizeof nvram)) { - *addrLo = addr & 0xFF; - *addrHi = (addr >> 8) & 0xFF; - *d++ = *data; - addr++; - } - } -#else - { - volatile char *s = (volatile char *)0xFFE81000; - char *d = (char *)&nvram; - - while (d < ((char *)&nvram + sizeof nvram)) - *d++ = *s++; - } -#endif - /* - * Assume that the boot server is also the name, log and ntp server! - */ - rtems_bsdnet_config.name_server[0] = - rtems_bsdnet_config.ntp_server[0] = - rtems_bsdnet_bootp_server_name = addr(server, nvram.ServerIPAddress); - rtems_bsdnet_bootp_server_address.s_addr = nvram.ServerIPAddress; - /* - * Nothing better to use as host name! - */ - rtems_bsdnet_config.ifconfig->ip_address = - rtems_bsdnet_config.hostname = addr(ip_address, nvram.ClientIPAddress); - - rtems_bsdnet_config.gateway = addr(gateway, nvram.GatewayIPAddress); - rtems_bsdnet_config.ifconfig->ip_netmask = addr(ip_netmask, nvram.SubnetIPAddressMask); - - rtems_bsdnet_bootp_boot_file_name = nvram.BootFilenameString; - rtems_bsdnet_bootp_cmdline = nvram.ArgumentFilenameString; - splitRtemsBsdnetBootpCmdline(); -} - -#elif defined(__mcf528x__) - -static char * -env(const char *parm, const char *defaultValue) -{ - const char *cp = bsp_getbenv(parm); - - if (!cp) { - if (!defaultValue) - return NULL; - cp = defaultValue; - printf ("%s environment variable missing -- using %s.\n", parm, cp); - } - return epicsStrDup(cp); -} - -void -setBootConfigFromNVRAM(void) -{ - const char *cp1; - - if (rtems_bsdnet_config.bootp != NULL) - return; - rtems_bsdnet_config.gateway = env("GATEWAY", NULL); - rtems_bsdnet_config.ifconfig->ip_netmask = env("NETMASK", "255.255.252.0"); - - rtems_bsdnet_bootp_server_name = env("SERVER", "192.168.0.1"); - rtems_bsdnet_config.name_server[0] = env("NAMESERVER", rtems_bsdnet_bootp_server_name); - rtems_bsdnet_config.ntp_server[0] = env("NTPSERVER", rtems_bsdnet_bootp_server_name); - cp1 = env("DOMAIN", NULL); - if (cp1 != NULL) - rtems_bsdnet_config.domainname = cp1; - rtems_bsdnet_config.hostname = env("HOSTNAME", "iocNobody"); - rtems_bsdnet_config.ifconfig->ip_address = env("IPADDR0", "192.168.0.2"); - rtems_bsdnet_bootp_boot_file_name = env("BOOTFILE", "uC5282App.boot"); - rtems_bsdnet_bootp_cmdline = env("CMDLINE", "epics/iocBoot/iocNobody/st.cmd"); - splitNfsMountPath(env("NFSMOUNT", NULL)); - if ((cp1 = env("TZ", NULL)) != NULL) - epicsEnvSet("TZ", cp1); -} - -#else -/* - * Placeholder for systems without NVRAM - */ -void -setBootConfigFromNVRAM(void) -{ - printf("SYSTEM HAS NO NON-VOLATILE RAM!\n"); - printf("YOU MUST USE SOME OTHER METHOD TO OBTAIN NETWORK CONFIGURATION\n"); -} -#endif diff --git a/src/libCom/as/Makefile b/src/libCom/as/Makefile deleted file mode 100644 index 65f752018..000000000 --- a/src/libCom/as/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 Brookhaven Science Associates, as Operator of -# Brookhaven National Lab. -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************ - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/as - -INC += asLib.h -INC += asTrapWrite.h - -Com_SRCS += asLib.c -Com_SRCS += asTrapWrite.c - -CLEANS += asLib.c asLib_lex.c diff --git a/src/libCom/as/RULES b/src/libCom/as/RULES deleted file mode 100644 index a2a416f6e..000000000 --- a/src/libCom/as/RULES +++ /dev/null @@ -1,21 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 Brookhaven Science Associates, as Operator of -# Brookhaven National Lab. -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************ - -# This is a Makefile fragment, see src/libCom/Makefile. - -# Extra rule since asLib_lex.c is included by asLib.c -asLib$(DEP): asLib_lex.c -asLib.c: asLib_lex.c - -# Ensure that lexer and parser are built before they are needed -asLib.c: $(EPICS_BASE_HOST_BIN)/antelope$(HOSTEXE) -asLib_lex.c: $(EPICS_BASE_HOST_BIN)/e_flex$(HOSTEXE) -asLib_lex.c: $(INSTALL_INCLUDE)/flex.skel.static diff --git a/src/libCom/as/asLib.h b/src/libCom/as/asLib.h deleted file mode 100644 index 95fed7a9a..000000000 --- a/src/libCom/as/asLib.h +++ /dev/null @@ -1,244 +0,0 @@ -/* asLib.h */ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 09-27-93*/ - -#ifndef INCasLibh -#define INCasLibh - -#include "shareLib.h" -#include "ellLib.h" -#include "errMdef.h" -#include "errlog.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct asgMember *ASMEMBERPVT; -typedef struct asgClient *ASCLIENTPVT; -typedef int (*ASINPUTFUNCPTR)(char *buf,int max_size); -typedef enum{ - asClientCOAR /*Change of access rights*/ - /*For now this is all*/ -} asClientStatus; - -typedef void (*ASCLIENTCALLBACK) (ASCLIENTPVT,asClientStatus); - -/* The following routines are macros with the following syntax -long asCheckGet(ASCLIENTPVT asClientPvt); -long asCheckPut(ASCLIENTPVT asClientPvt); -*/ -#define asCheckGet(asClientPvt) \ - (!asActive || ((asClientPvt)->access >= asREAD)) -#define asCheckPut(asClientPvt) \ - (!asActive || ((asClientPvt)->access >= asWRITE)) - -/* More convenience macros -void *asTrapWriteWithData(ASCLIENTPVT asClientPvt, - const char *userid, const char *hostid, void *addr, - int dbrType, int no_elements, void *data); -void asTrapWriteAfter(ASCLIENTPVT asClientPvt); -*/ -#define asTrapWriteWithData(asClientPvt, user, host, addr, type, count, data) \ - ((asActive && (asClientPvt)->trapMask) \ - ? asTrapWriteBeforeWithData((user), (host), (addr), (type), (count), (data)) \ - : 0) -#define asTrapWriteAfter(pvt) \ - if (pvt) asTrapWriteAfterWrite(pvt) - -/* This macro is for backwards compatibility, upgrade any code - calling it to use asTrapWriteWithData() instead ASAP: -void *asTrapWriteBefore(ASCLIENTPVT asClientPvt, - const char *userid, const char *hostid, void *addr); -*/ -#define asTrapWriteBefore(asClientPvt, user, host, addr) \ - asTrapWriteWithData(asClientPvt, user, host, addr, 0, 0, NULL) - - -epicsShareFunc long epicsShareAPI asInitialize(ASINPUTFUNCPTR inputfunction); -epicsShareFunc long epicsShareAPI asInitFile( - const char *filename,const char *substitutions); -epicsShareFunc long epicsShareAPI asInitFP(FILE *fp,const char *substitutions); -/*caller must provide permanent storage for asgName*/ -epicsShareFunc long epicsShareAPI asAddMember( - ASMEMBERPVT *asMemberPvt,const char *asgName); -epicsShareFunc long epicsShareAPI asRemoveMember(ASMEMBERPVT *asMemberPvt); -/*caller must provide permanent storage for newAsgName*/ -epicsShareFunc long epicsShareAPI asChangeGroup( - ASMEMBERPVT *asMemberPvt,const char *newAsgName); -epicsShareFunc void * epicsShareAPI asGetMemberPvt(ASMEMBERPVT asMemberPvt); -epicsShareFunc void epicsShareAPI asPutMemberPvt( - ASMEMBERPVT asMemberPvt,void *userPvt); -/*client must provide permanent storage for user and host*/ -epicsShareFunc long epicsShareAPI asAddClient( - ASCLIENTPVT *asClientPvt,ASMEMBERPVT asMemberPvt, - int asl,const char *user,char *host); -/*client must provide permanent storage for user and host*/ -epicsShareFunc long epicsShareAPI asChangeClient( - ASCLIENTPVT asClientPvt,int asl,const char *user,char *host); -epicsShareFunc long epicsShareAPI asRemoveClient(ASCLIENTPVT *asClientPvt); -epicsShareFunc void * epicsShareAPI asGetClientPvt(ASCLIENTPVT asClientPvt); -epicsShareFunc void epicsShareAPI asPutClientPvt( - ASCLIENTPVT asClientPvt,void *userPvt); -epicsShareFunc long epicsShareAPI asRegisterClientCallback( - ASCLIENTPVT asClientPvt, ASCLIENTCALLBACK pcallback); -epicsShareFunc long epicsShareAPI asComputeAllAsg(void); -/* following declared below after ASG is declared -epicsShareFunc long epicsShareAPI asComputeAsg(ASG *pasg); -*/ -epicsShareFunc long epicsShareAPI asCompute(ASCLIENTPVT asClientPvt); -epicsShareFunc int epicsShareAPI asDump( - void (*memcallback)(ASMEMBERPVT,FILE *), - void (*clientcallback)(ASCLIENTPVT,FILE *),int verbose); -epicsShareFunc int epicsShareAPI asDumpFP(FILE *fp, - void (*memcallback)(ASMEMBERPVT,FILE *), - void (*clientcallback)(ASCLIENTPVT,FILE *),int verbose); -epicsShareFunc int epicsShareAPI asDumpUag(const char *uagname); -epicsShareFunc int epicsShareAPI asDumpUagFP(FILE *fp,const char *uagname); -epicsShareFunc int epicsShareAPI asDumpHag(const char *hagname); -epicsShareFunc int epicsShareAPI asDumpHagFP(FILE *fp,const char *hagname); -epicsShareFunc int epicsShareAPI asDumpRules(const char *asgname); -epicsShareFunc int epicsShareAPI asDumpRulesFP(FILE *fp,const char *asgname); -epicsShareFunc int epicsShareAPI asDumpMem(const char *asgname, - void (*memcallback)(ASMEMBERPVT,FILE *),int clients); -epicsShareFunc int epicsShareAPI asDumpMemFP(FILE *fp,const char *asgname, - void (*memcallback)(ASMEMBERPVT,FILE *),int clients); -epicsShareFunc int epicsShareAPI asDumpHash(void); -epicsShareFunc int epicsShareAPI asDumpHashFP(FILE *fp); - -epicsShareFunc void * epicsShareAPI asTrapWriteBeforeWithData( - const char *userid, const char *hostid, void *addr, - int dbrType, int no_elements, void *data); - -epicsShareFunc void epicsShareAPI asTrapWriteAfterWrite(void *pvt); - -#define S_asLib_clientsExist (M_asLib| 1) /*Client Exists*/ -#define S_asLib_noUag (M_asLib| 2) /*User Access Group does not exist*/ -#define S_asLib_noHag (M_asLib| 3) /*Host Access Group does not exist*/ -#define S_asLib_noAccess (M_asLib| 4) /*access security: no access allowed*/ -#define S_asLib_noModify (M_asLib| 5) /*access security: no modification allowed*/ -#define S_asLib_badConfig (M_asLib| 6) /*access security: bad configuration file*/ -#define S_asLib_badCalc (M_asLib| 7) /*access security: bad calculation espression*/ -#define S_asLib_dupAsg (M_asLib| 8) /*Duplicate Access Security Group */ -#define S_asLib_InitFailed (M_asLib| 9) /*access security: Init failed*/ -#define S_asLib_asNotActive (M_asLib|10) /*access security is not active*/ -#define S_asLib_badMember (M_asLib|11) /*access security: bad ASMEMBERPVT*/ -#define S_asLib_badClient (M_asLib|12) /*access security: bad ASCLIENTPVT*/ -#define S_asLib_badAsg (M_asLib|13) /*access security: bad ASG*/ -#define S_asLib_noMemory (M_asLib|14) /*access security: no Memory */ - -/*Private declarations */ -epicsShareExtern int asActive; - -/* definition of access rights*/ -typedef enum{asNOACCESS,asREAD,asWRITE} asAccessRights; - -struct gphPvt; - -/*Base pointers for access security*/ -typedef struct asBase{ - ELLLIST uagList; - ELLLIST hagList; - ELLLIST asgList; - struct gphPvt *phash; -} ASBASE; - -epicsShareExtern volatile ASBASE *pasbase; - -/*Defs for User Access Groups*/ -typedef struct{ - ELLNODE node; - char *user; -} UAGNAME; -typedef struct uag{ - ELLNODE node; - char *name; - ELLLIST list; /*list of UAGNAME*/ -} UAG; -/*Defs for Host Access Groups*/ -typedef struct{ - ELLNODE node; - char *host; -} HAGNAME; -typedef struct hag{ - ELLNODE node; - char *name; - ELLLIST list; /*list of HAGNAME*/ -} HAG; -/*Defs for Access SecurityGroups*/ -typedef struct { - ELLNODE node; - UAG *puag; -}ASGUAG; -typedef struct { - ELLNODE node; - HAG *phag; -}ASGHAG; -#define AS_TRAP_WRITE 1 -typedef struct{ - ELLNODE node; - asAccessRights access; - int level; - unsigned long inpUsed; /*bitmap of which inputs are used*/ - int result; /*Result of calc converted to TRUE/FALSE*/ - char *calc; - void *rpcl; - ELLLIST uagList; /*List of ASGUAG*/ - ELLLIST hagList; /*List of ASGHAG*/ - int trapMask; -} ASGRULE; -typedef struct{ - ELLNODE node; - char *inp; - void *capvt; - struct asg *pasg; - int inpIndex; -}ASGINP; - -typedef struct asg{ - ELLNODE node; - char *name; - ELLLIST inpList; - ELLLIST ruleList; - ELLLIST memberList; - double *pavalue; /*pointer to array of input values*/ - unsigned long inpBad; /*bitmap of which inputs are bad*/ - unsigned long inpChanged; /*bitmap of inputs that changed*/ -} ASG; -typedef struct asgMember { - ELLNODE node; - ASG *pasg; - ELLLIST clientList; - const char *asgName; - void *userPvt; -} ASGMEMBER; - -typedef struct asgClient { - ELLNODE node; - ASGMEMBER *pasgMember; - const char *user; - char *host; - void *userPvt; - ASCLIENTCALLBACK pcallback; - int level; - asAccessRights access; - int trapMask; -} ASGCLIENT; - -epicsShareFunc long epicsShareAPI asComputeAsg(ASG *pasg); -/*following is "friend" function*/ -epicsShareFunc void * epicsShareAPI asCalloc(size_t nobj,size_t size); -epicsShareFunc char * epicsShareAPI asStrdup(unsigned char *str); -epicsShareFunc void asFreeAll(ASBASE *pasbase); -#ifdef __cplusplus -} -#endif - -#endif /*INCasLibh*/ diff --git a/src/libCom/as/asLib.y b/src/libCom/as/asLib.y deleted file mode 100644 index 55d48ebad..000000000 --- a/src/libCom/as/asLib.y +++ /dev/null @@ -1,230 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -%{ -static int yyerror(char *); -static int yy_start; -#include "asLibRoutines.c" -static int yyFailed = FALSE; -static int line_num=1; -static UAG *yyUag=NULL; -static HAG *yyHag=NULL; -static ASG *yyAsg=NULL; -static ASGRULE *yyAsgRule=NULL; -%} - -%start asconfig - -%token tokenUAG tokenHAG tokenASG tokenRULE tokenCALC -%token tokenINP -%token tokenINTEGER -%token tokenSTRING - -%union -{ - int Int; - char *Str; -} - -%% - -asconfig: asconfig asconfig_item - | asconfig_item - -asconfig_item: tokenUAG uag_head uag_body - | tokenUAG uag_head - | tokenHAG hag_head hag_body - | tokenHAG hag_head - | tokenASG asg_head asg_body - | tokenASG asg_head - ; - -uag_head: '(' tokenSTRING ')' - { - yyUag = asUagAdd($2); - if(!yyUag) yyerror(""); - free((void *)$2); - } - ; - -uag_body: '{' uag_user_list '}' - { - ; - } - ; - -uag_user_list: uag_user_list ',' uag_user_list_name - | uag_user_list_name - ; - -uag_user_list_name: tokenSTRING - { - if (asUagAddUser(yyUag,$1)) - yyerror(""); - free((void *)$1); - } - ; - -hag_head: '(' tokenSTRING ')' - { - yyHag = asHagAdd($2); - if(!yyHag) yyerror(""); - free((void *)$2); - } - ; - -hag_body: '{' hag_host_list '}' - ; - -hag_host_list: hag_host_list ',' hag_host_list_name - | hag_host_list_name - ; - -hag_host_list_name: tokenSTRING - { - if (asHagAddHost(yyHag,$1)) - yyerror(""); - free((void *)$1); - } - ; - -asg_head: '(' tokenSTRING ')' - { - yyAsg = asAsgAdd($2); - if(!yyAsg) yyerror(""); - free((void *)$2); - } - ; - -asg_body: '{' asg_body_list '}' - { - } - -asg_body_list: asg_body_list asg_body_item - | asg_body_item - -asg_body_item: inp_config | rule_config - ; - -inp_config: tokenINP '(' tokenSTRING ')' - { - if (asAsgAddInp(yyAsg,$3,$1)) - yyerror(""); - free((void *)$3); - } - ; - -rule_config: tokenRULE rule_head rule_body - | tokenRULE rule_head - -rule_head: rule_head_manditory rule_head_options - -rule_head_manditory: '(' tokenINTEGER ',' tokenSTRING - { - asAccessRights rights; - - if((strcmp($4,"NONE")==0)) { - rights=asNOACCESS; - } else if((strcmp($4,"READ")==0)) { - rights=asREAD; - } else if((strcmp($4,"WRITE")==0)) { - rights=asWRITE; - } else { - yyerror("Access rights must be NONE, READ or WRITE"); - rights = asNOACCESS; - } - yyAsgRule = asAsgAddRule(yyAsg,rights,$2); - free((void *)$4); - } - ; - -rule_head_options: ')' - | rule_log_options - -rule_log_options: ',' tokenSTRING ')' - { - if((strcmp($2,"TRAPWRITE")==0)) { - long status; - status = asAsgAddRuleOptions(yyAsgRule,AS_TRAP_WRITE); - if(status) yyerror(""); - } else if((strcmp($2,"NOTRAPWRITE")!=0)) { - yyerror("Log options must be TRAPWRITE or NOTRAPWRITE"); - } - free((void *)$2); - } - ; - -rule_body: '{' rule_list '}' - ; - -rule_list: rule_list rule_list_item - | rule_list_item - ; - -rule_list_item: tokenUAG '(' rule_uag_list ')' - | tokenHAG '(' rule_hag_list ')' - | tokenCALC '(' tokenSTRING ')' - { - if (asAsgRuleCalc(yyAsgRule,$3)) - yyerror(""); - free((void *)$3); - } - ; - -rule_uag_list: rule_uag_list ',' rule_uag_list_name - | rule_uag_list_name - ; - -rule_uag_list_name: tokenSTRING - { - if (asAsgRuleUagAdd(yyAsgRule,$1)) - yyerror(""); - free((void *)$1); - } - ; - -rule_hag_list: rule_hag_list ',' rule_hag_list_name - | rule_hag_list_name - ; - -rule_hag_list_name: tokenSTRING - { - if (asAsgRuleHagAdd(yyAsgRule,$1)) - yyerror(""); - free((void *)$1); - } - ; -%% - -#include "asLib_lex.c" - -static int yyerror(char *str) -{ - if (strlen(str)) - errlogPrintf("%s at line %d\n", str, line_num); - else - errlogPrintf("Error at line %d\n", line_num); - yyFailed = TRUE; - return 0; -} -static int myParse(ASINPUTFUNCPTR inputfunction) -{ - static int FirstFlag = 1; - int rtnval; - - my_yyinput = &inputfunction; - if (!FirstFlag) { - line_num=1; - yyFailed = FALSE; - yyreset(); - yyrestart(NULL); - } - FirstFlag = 0; - rtnval = yyparse(); - if(rtnval!=0 || yyFailed) return(-1); else return(0); -} diff --git a/src/libCom/as/asLibRoutines.c b/src/libCom/as/asLibRoutines.c deleted file mode 100644 index e7f1d90bf..000000000 --- a/src/libCom/as/asLibRoutines.c +++ /dev/null @@ -1,1352 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 10-15-93 */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "dbDefs.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "epicsMutex.h" -#include "errlog.h" -#include "gpHash.h" -#include "freeList.h" -#include "macLib.h" -#include "postfix.h" -#include "asLib.h" - -static epicsMutexId asLock; -#define LOCK epicsMutexMustLock(asLock) -#define UNLOCK epicsMutexUnlock(asLock) - -/*following must be global because asCa nneeds it*/ -epicsShareDef ASBASE volatile *pasbase=NULL; -static ASBASE *pasbasenew=NULL; -epicsShareDef int asActive = FALSE; - -static void *freeListPvt = NULL; - - -#define DEFAULT "DEFAULT" - -/* Defined in asLib.y */ -static int myParse(ASINPUTFUNCPTR inputfunction); - -/*private routines */ -static long asAddMemberPvt(ASMEMBERPVT *pasMemberPvt,const char *asgName); -static long asComputeAllAsgPvt(void); -static long asComputeAsgPvt(ASG *pasg); -static long asComputePvt(ASCLIENTPVT asClientPvt); -static UAG *asUagAdd(const char *uagName); -static long asUagAddUser(UAG *puag,const char *user); -static HAG *asHagAdd(const char *hagName); -static long asHagAddHost(HAG *phag,const char *host); -static ASG *asAsgAdd(const char *asgName); -static long asAsgAddInp(ASG *pasg,const char *inp,int inpIndex); -static ASGRULE *asAsgAddRule(ASG *pasg,asAccessRights access,int level); -static long asAsgAddRuleOptions(ASGRULE *pasgrule,int trapMask); -static long asAsgRuleUagAdd(ASGRULE *pasgrule,const char *name); -static long asAsgRuleHagAdd(ASGRULE *pasgrule,const char *name); -static long asAsgRuleCalc(ASGRULE *pasgrule,const char *calc); - -/* - asInitialize can be called while access security is already active. - This is accomplished by doing the following: - - The version pointed to by pasbase is kept as is but locked against changes - A new version is created and pointed to by pasbasenew - If anything goes wrong. The original version is kept. This results is some - wasted space but at least things still work. - If the new access security configuration is successfully read then: - the old memberList is moved from old to new. - the old structures are freed. -*/ -static void asInitializeOnce(void *arg) -{ - asLock = epicsMutexMustCreate(); -} -long epicsShareAPI asInitialize(ASINPUTFUNCPTR inputfunction) -{ - ASG *pasg; - long status; - ASBASE *pasbaseold; - GPHENTRY *pgphentry; - UAG *puag; - UAGNAME *puagname; - HAG *phag; - HAGNAME *phagname; - static epicsThreadOnceId asInitializeOnceFlag = EPICS_THREAD_ONCE_INIT; - - epicsThreadOnce(&asInitializeOnceFlag,asInitializeOnce,(void *)0); - LOCK; - pasbasenew = asCalloc(1,sizeof(ASBASE)); - if(!freeListPvt) freeListInitPvt(&freeListPvt,sizeof(ASGCLIENT),20); - ellInit(&pasbasenew->uagList); - ellInit(&pasbasenew->hagList); - ellInit(&pasbasenew->asgList); - asAsgAdd(DEFAULT); - status = myParse(inputfunction); - if(status) { - status = S_asLib_badConfig; - /*Not safe to call asFreeAll */ - UNLOCK; - return(status); - } - pasg = (ASG *)ellFirst(&pasbasenew->asgList); - while(pasg) { - pasg->pavalue = asCalloc(CALCPERFORM_NARGS, sizeof(double)); - pasg = (ASG *)ellNext(&pasg->node); - } - gphInitPvt(&pasbasenew->phash, 256); - /*Hash each uagname and each hagname*/ - puag = (UAG *)ellFirst(&pasbasenew->uagList); - while(puag) { - puagname = (UAGNAME *)ellFirst(&puag->list); - while(puagname) { - pgphentry = gphAdd(pasbasenew->phash,puagname->user,puag); - if(!pgphentry) { - errlogPrintf("Duplicated user '%s' in UAG '%s'\n", - puagname->user, puag->name); - } - puagname = (UAGNAME *)ellNext(&puagname->node); - } - puag = (UAG *)ellNext(&puag->node); - } - phag = (HAG *)ellFirst(&pasbasenew->hagList); - while(phag) { - phagname = (HAGNAME *)ellFirst(&phag->list); - while(phagname) { - pgphentry = gphAdd(pasbasenew->phash,phagname->host,phag); - if(!pgphentry) { - errlogPrintf("Duplicated host '%s' in HAG '%s'\n", - phagname->host, phag->name); - } - phagname = (HAGNAME *)ellNext(&phagname->node); - } - phag = (HAG *)ellNext(&phag->node); - } - pasbaseold = (ASBASE *)pasbase; - pasbase = (ASBASE volatile *)pasbasenew; - if(pasbaseold) { - ASG *poldasg; - ASGMEMBER *poldmem; - ASGMEMBER *pnextoldmem; - - poldasg = (ASG *)ellFirst(&pasbaseold->asgList); - while(poldasg) { - poldmem = (ASGMEMBER *)ellFirst(&poldasg->memberList); - while(poldmem) { - pnextoldmem = (ASGMEMBER *)ellNext(&poldmem->node); - ellDelete(&poldasg->memberList,&poldmem->node); - status = asAddMemberPvt(&poldmem,poldmem->asgName); - poldmem = pnextoldmem; - } - poldasg = (ASG *)ellNext(&poldasg->node); - } - asFreeAll(pasbaseold); - } - asActive = TRUE; - UNLOCK; - return(0); -} - -long epicsShareAPI asInitFile(const char *filename,const char *substitutions) -{ - FILE *fp; - long status; - - fp = fopen(filename,"r"); - if(!fp) { - errlogPrintf("asInitFile: Can't open file '%s'\n", filename); - return(S_asLib_badConfig); - } - status = asInitFP(fp,substitutions); - if(fclose(fp)==EOF) { - errMessage(0,"asInitFile: fclose failed!"); - if(!status) status = S_asLib_badConfig; - } - return(status); -} - -#define BUF_SIZE 200 -static char *my_buffer; -static char *my_buffer_ptr; -static FILE *stream; -static char *mac_input_buffer=NULL; -static MAC_HANDLE *macHandle = NULL; - -static int myInputFunction(char *buf, int max_size) -{ - int l,n; - char *fgetsRtn; - - if(*my_buffer_ptr==0) { - if(macHandle) { - fgetsRtn = fgets(mac_input_buffer,BUF_SIZE,stream); - if(fgetsRtn) { - n = macExpandString(macHandle,mac_input_buffer, - my_buffer,BUF_SIZE); - if(n<0) { - errlogPrintf("access security: macExpandString failed\n" - "input line: %s\n",mac_input_buffer); - return(0); - } - } - } else { - fgetsRtn = fgets(my_buffer,BUF_SIZE,stream); - } - if(fgetsRtn==NULL) return(0); - my_buffer_ptr = my_buffer; - } - l = strlen(my_buffer_ptr); - n = (l<=max_size ? l : max_size); - memcpy(buf,my_buffer_ptr,n); - my_buffer_ptr += n; - return(n); -} - -long epicsShareAPI asInitFP(FILE *fp,const char *substitutions) -{ - char buffer[BUF_SIZE]; - char mac_buffer[BUF_SIZE]; - long status; - char **macPairs; - - buffer[0] = 0; - my_buffer = buffer; - my_buffer_ptr = my_buffer; - stream = fp; - if(substitutions) { - if((status = macCreateHandle(&macHandle,NULL))) { - errMessage(status,"asInitFP: macCreateHandle error"); - return(status); - } - macParseDefns(macHandle,substitutions,&macPairs); - if(macPairs ==NULL) { - macDeleteHandle(macHandle); - macHandle = NULL; - } else { - macInstallMacros(macHandle,macPairs); - free(macPairs); - mac_input_buffer = mac_buffer; - } - } - status = asInitialize(myInputFunction); - if(macHandle) { - macDeleteHandle(macHandle); - macHandle = NULL; - } - return(status); -} - -long epicsShareAPI asAddMember(ASMEMBERPVT *pasMemberPvt,const char *asgName) -{ - long status; - - if(!asActive) return(S_asLib_asNotActive); - LOCK; - status = asAddMemberPvt(pasMemberPvt,asgName); - UNLOCK; - return(status); -} - -long epicsShareAPI asRemoveMember(ASMEMBERPVT *asMemberPvt) -{ - ASGMEMBER *pasgmember; - - if(!asActive) return(S_asLib_asNotActive); - pasgmember = *asMemberPvt; - if(!pasgmember) return(S_asLib_badMember); - LOCK; - if (ellCount(&pasgmember->clientList) > 0) { - UNLOCK; - return(S_asLib_clientsExist); - } - if(pasgmember->pasg) { - ellDelete(&pasgmember->pasg->memberList,&pasgmember->node); - } else { - errMessage(-1,"Logic error in asRemoveMember"); - UNLOCK; - return(-1); - } - free(pasgmember); - *asMemberPvt = NULL; - UNLOCK; - return(0); -} - -long epicsShareAPI asChangeGroup(ASMEMBERPVT *asMemberPvt,const char *newAsgName) -{ - ASGMEMBER *pasgmember; - long status; - - if(!asActive) return(S_asLib_asNotActive); - pasgmember = *asMemberPvt; - if(!pasgmember) return(S_asLib_badMember); - LOCK; - if(pasgmember->pasg) { - ellDelete(&pasgmember->pasg->memberList,&pasgmember->node); - } else { - errMessage(-1,"Logic error in asChangeGroup"); - UNLOCK; - return(-1); - } - status = asAddMemberPvt(asMemberPvt,newAsgName); - UNLOCK; - return(status); -} - -void * epicsShareAPI asGetMemberPvt(ASMEMBERPVT asMemberPvt) -{ - ASGMEMBER *pasgmember = asMemberPvt; - - if(!asActive) return(NULL); - if(!pasgmember) return(NULL); - return(pasgmember->userPvt); -} - -void epicsShareAPI asPutMemberPvt(ASMEMBERPVT asMemberPvt,void *userPvt) -{ - ASGMEMBER *pasgmember = asMemberPvt; - - if(!asActive) return; - if(!pasgmember) return; - pasgmember->userPvt = userPvt; - return; -} - -long epicsShareAPI asAddClient(ASCLIENTPVT *pasClientPvt,ASMEMBERPVT asMemberPvt, - int asl,const char *user,char *host) -{ - ASGMEMBER *pasgmember = asMemberPvt; - ASGCLIENT *pasgclient; - int len, i; - - long status; - if(!asActive) return(S_asLib_asNotActive); - if(!pasgmember) return(S_asLib_badMember); - pasgclient = freeListCalloc(freeListPvt); - if(!pasgclient) return(S_asLib_noMemory); - len = strlen(host); - for (i = 0; i < len; i++) { - host[i] = (char)tolower((int)host[i]); - } - *pasClientPvt = pasgclient; - pasgclient->pasgMember = asMemberPvt; - pasgclient->level = asl; - pasgclient->user = user; - pasgclient->host = host; - LOCK; - ellAdd(&pasgmember->clientList,&pasgclient->node); - status = asComputePvt(pasgclient); - UNLOCK; - return(status); -} - -long epicsShareAPI asChangeClient( - ASCLIENTPVT asClientPvt,int asl,const char *user,char *host) -{ - ASGCLIENT *pasgclient = asClientPvt; - long status; - int len, i; - - if(!asActive) return(S_asLib_asNotActive); - if(!pasgclient) return(S_asLib_badClient); - len = strlen(host); - for (i = 0; i < len; i++) { - host[i] = (char)tolower((int)host[i]); - } - LOCK; - pasgclient->level = asl; - pasgclient->user = user; - pasgclient->host = host; - status = asComputePvt(pasgclient); - UNLOCK; - return(status); -} - -long epicsShareAPI asRemoveClient(ASCLIENTPVT *asClientPvt) -{ - ASGCLIENT *pasgclient = *asClientPvt; - ASGMEMBER *pasgMember; - - if(!asActive) return(S_asLib_asNotActive); - if(!pasgclient) return(S_asLib_badClient); - LOCK; - pasgMember = pasgclient->pasgMember; - if(!pasgMember) { - errMessage(-1,"asRemoveClient: No ASGMEMBER"); - UNLOCK; - return(-1); - } - ellDelete(&pasgMember->clientList,&pasgclient->node); - UNLOCK; - freeListFree(freeListPvt,pasgclient); - *asClientPvt = NULL; - return(0); -} - -long epicsShareAPI asRegisterClientCallback(ASCLIENTPVT asClientPvt, - ASCLIENTCALLBACK pcallback) -{ - ASGCLIENT *pasgclient = asClientPvt; - - if(!asActive) return(S_asLib_asNotActive); - if(!pasgclient) return(S_asLib_badClient); - LOCK; - pasgclient->pcallback = pcallback; - (*pasgclient->pcallback)(pasgclient,asClientCOAR); - UNLOCK; - return(0); -} - -void * epicsShareAPI asGetClientPvt(ASCLIENTPVT asClientPvt) -{ - ASGCLIENT *pasgclient = asClientPvt; - - if(!asActive) return(NULL); - if(!pasgclient) return(NULL); - return(pasgclient->userPvt); -} - -void epicsShareAPI asPutClientPvt(ASCLIENTPVT asClientPvt,void *userPvt) -{ - ASGCLIENT *pasgclient = asClientPvt; - if(!asActive) return; - if(!pasgclient) return; - LOCK; - pasgclient->userPvt = userPvt; - UNLOCK; -} - -long epicsShareAPI asComputeAllAsg(void) -{ - long status; - - if(!asActive) return(S_asLib_asNotActive); - LOCK; - status = asComputeAllAsgPvt(); - UNLOCK; - return(status); -} - -long epicsShareAPI asComputeAsg(ASG *pasg) -{ - long status; - - if(!asActive) return(S_asLib_asNotActive); - LOCK; - status = asComputeAsgPvt(pasg); - UNLOCK; - return(status); -} - -long epicsShareAPI asCompute(ASCLIENTPVT asClientPvt) -{ - long status; - - if(!asActive) return(S_asLib_asNotActive); - LOCK; - status = asComputePvt(asClientPvt); - UNLOCK; - return(status); -} - -/*The dump routines do not lock. Thus they may get inconsistant data.*/ -/*HOWEVER if they did lock and a user interrupts one of then then BAD BAD*/ -static const char *asAccessName[] = {"NONE","READ","WRITE"}; -static const char *asTrapOption[] = {"NOTRAPWRITE","TRAPWRITE"}; -static const char *asLevelName[] = {"ASL0","ASL1"}; -int epicsShareAPI asDump( - void (*memcallback)(struct asgMember *,FILE *), - void (*clientcallback)(struct asgClient *,FILE *), - int verbose) -{ - return asDumpFP(stdout,memcallback,clientcallback,verbose); -} - -int epicsShareAPI asDumpFP( - FILE *fp, - void (*memcallback)(struct asgMember *,FILE *), - void (*clientcallback)(struct asgClient *,FILE *), - int verbose) -{ - UAG *puag; - UAGNAME *puagname; - HAG *phag; - HAGNAME *phagname; - ASG *pasg; - ASGINP *pasginp; - ASGRULE *pasgrule; - ASGHAG *pasghag; - ASGUAG *pasguag; - ASGMEMBER *pasgmember; - ASGCLIENT *pasgclient; - - if(!asActive) return(0); - puag = (UAG *)ellFirst(&pasbase->uagList); - if(!puag) fprintf(fp,"No UAGs\n"); - while(puag) { - fprintf(fp,"UAG(%s)",puag->name); - puagname = (UAGNAME *)ellFirst(&puag->list); - if(puagname) fprintf(fp," {"); else fprintf(fp,"\n"); - while(puagname) { - fprintf(fp,"%s",puagname->user); - puagname = (UAGNAME *)ellNext(&puagname->node); - if(puagname) fprintf(fp,","); else fprintf(fp,"}\n"); - } - puag = (UAG *)ellNext(&puag->node); - } - phag = (HAG *)ellFirst(&pasbase->hagList); - if(!phag) fprintf(fp,"No HAGs\n"); - while(phag) { - fprintf(fp,"HAG(%s)",phag->name); - phagname = (HAGNAME *)ellFirst(&phag->list); - if(phagname) fprintf(fp," {"); else fprintf(fp,"\n"); - while(phagname) { - fprintf(fp,"%s",phagname->host); - phagname = (HAGNAME *)ellNext(&phagname->node); - if(phagname) fprintf(fp,","); else fprintf(fp,"}\n"); - } - phag = (HAG *)ellNext(&phag->node); - } - pasg = (ASG *)ellFirst(&pasbase->asgList); - if(!pasg) fprintf(fp,"No ASGs\n"); - while(pasg) { - int print_end_brace; - - fprintf(fp,"ASG(%s)",pasg->name); - pasginp = (ASGINP *)ellFirst(&pasg->inpList); - pasgrule = (ASGRULE *)ellFirst(&pasg->ruleList); - if(pasginp || pasgrule) { - fprintf(fp," {\n"); - print_end_brace = TRUE; - } else { - fprintf(fp,"\n"); - print_end_brace = FALSE; - } - while(pasginp) { - - fprintf(fp,"\tINP%c(%s)",(pasginp->inpIndex + 'A'),pasginp->inp); - if(verbose) { - if((pasg->inpBad & (1ul << pasginp->inpIndex))) - fprintf(fp," INVALID"); - else - fprintf(fp," VALID"); - fprintf(fp," value=%f",pasg->pavalue[pasginp->inpIndex]); - } - fprintf(fp,"\n"); - pasginp = (ASGINP *)ellNext(&pasginp->node); - } - while(pasgrule) { - int print_end_brace; - - fprintf(fp,"\tRULE(%d,%s,%s)", - pasgrule->level,asAccessName[pasgrule->access], - asTrapOption[pasgrule->trapMask]); - pasguag = (ASGUAG *)ellFirst(&pasgrule->uagList); - pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList); - if(pasguag || pasghag || pasgrule->calc) { - fprintf(fp," {\n"); - print_end_brace = TRUE; - } else { - fprintf(fp,"\n"); - print_end_brace = FALSE; - } - if(pasguag) fprintf(fp,"\t\tUAG("); - while(pasguag) { - fprintf(fp,"%s",pasguag->puag->name); - pasguag = (ASGUAG *)ellNext(&pasguag->node); - if(pasguag) fprintf(fp,","); else fprintf(fp,")\n"); - } - pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList); - if(pasghag) fprintf(fp,"\t\tHAG("); - while(pasghag) { - fprintf(fp,"%s",pasghag->phag->name); - pasghag = (ASGHAG *)ellNext(&pasghag->node); - if(pasghag) fprintf(fp,","); else fprintf(fp,")\n"); - } - if(pasgrule->calc) { - fprintf(fp,"\t\tCALC(\"%s\")",pasgrule->calc); - if(verbose) - fprintf(fp," result=%s",(pasgrule->result==1 ? "TRUE" : "FALSE")); - fprintf(fp,"\n"); - } - if(print_end_brace) fprintf(fp,"\t}\n"); - pasgrule = (ASGRULE *)ellNext(&pasgrule->node); - } - pasgmember = (ASGMEMBER *)ellFirst(&pasg->memberList); - if(!verbose) pasgmember = NULL; - if(pasgmember) fprintf(fp,"\tMEMBERLIST\n"); - while(pasgmember) { - if(strlen(pasgmember->asgName)==0) - fprintf(fp,"\t\t"); - else - fprintf(fp,"\t\t%s",pasgmember->asgName); - if(memcallback) memcallback(pasgmember,fp); - fprintf(fp,"\n"); - pasgclient = (ASGCLIENT *)ellFirst(&pasgmember->clientList); - while(pasgclient) { - fprintf(fp,"\t\t\t %s %s",pasgclient->user,pasgclient->host); - if(pasgclient->level>=0 && pasgclient->level<=1) - fprintf(fp," %s",asLevelName[pasgclient->level]); - else - fprintf(fp," Illegal Level %d",pasgclient->level); - if(pasgclient->access<=2) - fprintf(fp," %s %s", - asAccessName[pasgclient->access], - asTrapOption[pasgclient->trapMask]); - else - fprintf(fp," Illegal Access %d",pasgclient->access); - if(clientcallback) clientcallback(pasgclient,fp); - fprintf(fp,"\n"); - pasgclient = (ASGCLIENT *)ellNext(&pasgclient->node); - } - pasgmember = (ASGMEMBER *)ellNext(&pasgmember->node); - } - if(print_end_brace) fprintf(fp,"}\n"); - pasg = (ASG *)ellNext(&pasg->node); - } - return(0); -} - -int epicsShareAPI asDumpUag(const char *uagname) -{ - return asDumpUagFP(stdout,uagname); -} - -int epicsShareAPI asDumpUagFP(FILE *fp,const char *uagname) -{ - UAG *puag; - UAGNAME *puagname; - - if(!asActive) return(0); - puag = (UAG *)ellFirst(&pasbase->uagList); - if(!puag) fprintf(fp,"No UAGs\n"); - while(puag) { - if(uagname && strcmp(uagname,puag->name)!=0) { - puag = (UAG *)ellNext(&puag->node); - continue; - } - fprintf(fp,"UAG(%s)",puag->name); - puagname = (UAGNAME *)ellFirst(&puag->list); - if(puagname) fprintf(fp," {"); else fprintf(fp,"\n"); - while(puagname) { - fprintf(fp,"%s",puagname->user); - puagname = (UAGNAME *)ellNext(&puagname->node); - if(puagname) fprintf(fp,","); else fprintf(fp,"}\n"); - } - puag = (UAG *)ellNext(&puag->node); - } - return(0); -} - -int epicsShareAPI asDumpHag(const char *hagname) -{ - return asDumpHagFP(stdout,hagname); -} - -int epicsShareAPI asDumpHagFP(FILE *fp,const char *hagname) -{ - HAG *phag; - HAGNAME *phagname; - - if(!asActive) return(0); - phag = (HAG *)ellFirst(&pasbase->hagList); - if(!phag) fprintf(fp,"No HAGs\n"); - while(phag) { - if(hagname && strcmp(hagname,phag->name)!=0) { - phag = (HAG *)ellNext(&phag->node); - continue; - } - fprintf(fp,"HAG(%s)",phag->name); - phagname = (HAGNAME *)ellFirst(&phag->list); - if(phagname) fprintf(fp," {"); else fprintf(fp,"\n"); - while(phagname) { - fprintf(fp,"%s",phagname->host); - phagname = (HAGNAME *)ellNext(&phagname->node); - if(phagname) fprintf(fp,","); else fprintf(fp,"}\n"); - } - phag = (HAG *)ellNext(&phag->node); - } - return(0); -} - -int epicsShareAPI asDumpRules(const char *asgname) -{ - return asDumpRulesFP(stdout,asgname); -} - -int epicsShareAPI asDumpRulesFP(FILE *fp,const char *asgname) -{ - ASG *pasg; - ASGINP *pasginp; - ASGRULE *pasgrule; - ASGHAG *pasghag; - ASGUAG *pasguag; - - if(!asActive) return(0); - pasg = (ASG *)ellFirst(&pasbase->asgList); - if(!pasg) fprintf(fp,"No ASGs\n"); - while(pasg) { - int print_end_brace; - - if(asgname && strcmp(asgname,pasg->name)!=0) { - pasg = (ASG *)ellNext(&pasg->node); - continue; - } - fprintf(fp,"ASG(%s)",pasg->name); - pasginp = (ASGINP *)ellFirst(&pasg->inpList); - pasgrule = (ASGRULE *)ellFirst(&pasg->ruleList); - if(pasginp || pasgrule) { - fprintf(fp," {\n"); - print_end_brace = TRUE; - } else { - fprintf(fp,"\n"); - print_end_brace = FALSE; - } - while(pasginp) { - - fprintf(fp,"\tINP%c(%s)",(pasginp->inpIndex + 'A'),pasginp->inp); - if ((pasg->inpBad & (1ul << pasginp->inpIndex))) - fprintf(fp," INVALID"); - fprintf(fp," value=%f",pasg->pavalue[pasginp->inpIndex]); - fprintf(fp,"\n"); - pasginp = (ASGINP *)ellNext(&pasginp->node); - } - while(pasgrule) { - int print_end_brace; - - fprintf(fp,"\tRULE(%d,%s,%s)", - pasgrule->level,asAccessName[pasgrule->access], - asTrapOption[pasgrule->trapMask]); - pasguag = (ASGUAG *)ellFirst(&pasgrule->uagList); - pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList); - if(pasguag || pasghag || pasgrule->calc) { - fprintf(fp," {\n"); - print_end_brace = TRUE; - } else { - fprintf(fp,"\n"); - print_end_brace = FALSE; - } - if(pasguag) fprintf(fp,"\t\tUAG("); - while(pasguag) { - fprintf(fp,"%s",pasguag->puag->name); - pasguag = (ASGUAG *)ellNext(&pasguag->node); - if(pasguag) fprintf(fp,","); else fprintf(fp,")\n"); - } - pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList); - if(pasghag) fprintf(fp,"\t\tHAG("); - while(pasghag) { - fprintf(fp,"%s",pasghag->phag->name); - pasghag = (ASGHAG *)ellNext(&pasghag->node); - if(pasghag) fprintf(fp,","); else fprintf(fp,")\n"); - } - if(pasgrule->calc) { - fprintf(fp,"\t\tCALC(\"%s\")",pasgrule->calc); - fprintf(fp," result=%s",(pasgrule->result==1 ? "TRUE" : "FALSE")); - fprintf(fp,"\n"); - } - if(print_end_brace) fprintf(fp,"\t}\n"); - pasgrule = (ASGRULE *)ellNext(&pasgrule->node); - } - if(print_end_brace) fprintf(fp,"}\n"); - pasg = (ASG *)ellNext(&pasg->node); - } - return(0); -} - -int epicsShareAPI asDumpMem(const char *asgname,void (*memcallback)(ASMEMBERPVT,FILE *), - int clients) -{ - return asDumpMemFP(stdout,asgname,memcallback,clients); -} - -int epicsShareAPI asDumpMemFP(FILE *fp,const char *asgname, - void (*memcallback)(ASMEMBERPVT,FILE *),int clients) -{ - ASG *pasg; - ASGMEMBER *pasgmember; - ASGCLIENT *pasgclient; - - if(!asActive) return(0); - pasg = (ASG *)ellFirst(&pasbase->asgList); - if(!pasg) fprintf(fp,"No ASGs\n"); - while(pasg) { - - if(asgname && strcmp(asgname,pasg->name)!=0) { - pasg = (ASG *)ellNext(&pasg->node); - continue; - } - fprintf(fp,"ASG(%s)\n",pasg->name); - pasgmember = (ASGMEMBER *)ellFirst(&pasg->memberList); - if(pasgmember) fprintf(fp,"\tMEMBERLIST\n"); - while(pasgmember) { - if(strlen(pasgmember->asgName)==0) - fprintf(fp,"\t\t"); - else - fprintf(fp,"\t\t%s",pasgmember->asgName); - if(memcallback) memcallback(pasgmember,fp); - fprintf(fp,"\n"); - pasgclient = (ASGCLIENT *)ellFirst(&pasgmember->clientList); - if(!clients) pasgclient = NULL; - while(pasgclient) { - fprintf(fp,"\t\t\t %s %s", - pasgclient->user,pasgclient->host); - if(pasgclient->level>=0 && pasgclient->level<=1) - fprintf(fp," %s",asLevelName[pasgclient->level]); - else - fprintf(fp," Illegal Level %d",pasgclient->level); - if(pasgclient->access<=2) - fprintf(fp," %s %s", - asAccessName[pasgclient->access], - asTrapOption[pasgclient->trapMask]); - else - fprintf(fp," Illegal Access %d",pasgclient->access); - fprintf(fp,"\n"); - pasgclient = (ASGCLIENT *)ellNext(&pasgclient->node); - } - pasgmember = (ASGMEMBER *)ellNext(&pasgmember->node); - } - pasg = (ASG *)ellNext(&pasg->node); - } - return(0); -} - -epicsShareFunc int epicsShareAPI asDumpHash(void) -{ - return asDumpHashFP(stdout); -} - -epicsShareFunc int epicsShareAPI asDumpHashFP(FILE *fp) -{ - if(!asActive) return(0); - gphDumpFP(fp,pasbase->phash); - return(0); -} - -/*Start of private routines*/ -/* asCalloc is "friend" function */ -epicsShareFunc void * epicsShareAPI asCalloc(size_t nobj,size_t size) -{ - void *p; - - p=callocMustSucceed(nobj,size,"asCalloc"); - return(p); -} -epicsShareFunc char * epicsShareAPI asStrdup(unsigned char *str) -{ - size_t len = strlen((char *) str); - char *buf = asCalloc(1, len + 1); - strcpy(buf, (char *) str); - return buf; -} - -static long asAddMemberPvt(ASMEMBERPVT *pasMemberPvt,const char *asgName) -{ - ASGMEMBER *pasgmember; - ASG *pgroup; - ASGCLIENT *pasgclient; - - if(*pasMemberPvt) { - pasgmember = *pasMemberPvt; - } else { - pasgmember = asCalloc(1,sizeof(ASGMEMBER)); - ellInit(&pasgmember->clientList); - *pasMemberPvt = pasgmember; - } - pasgmember->asgName = asgName; - pgroup = (ASG *)ellFirst(&pasbase->asgList); - while(pgroup) { - if(strcmp(pgroup->name,pasgmember->asgName)==0) goto got_it; - pgroup = (ASG *)ellNext(&pgroup->node); - } - /* Put it in DEFAULT*/ - pgroup = (ASG *)ellFirst(&pasbase->asgList); - while(pgroup) { - if(strcmp(pgroup->name,DEFAULT)==0) goto got_it; - pgroup = (ASG *)ellNext(&pgroup->node); - } - errMessage(-1,"Logic Error in asAddMember"); - return(-1); -got_it: - pasgmember->pasg = pgroup; - ellAdd(&pgroup->memberList,&pasgmember->node); - pasgclient = (ASGCLIENT *)ellFirst(&pasgmember->clientList); - while(pasgclient) { - asComputePvt((ASCLIENTPVT)pasgclient); - pasgclient = (ASGCLIENT *)ellNext(&pasgclient->node); - } - return(0); -} - -static long asComputeAllAsgPvt(void) -{ - ASG *pasg; - - if(!asActive) return(S_asLib_asNotActive); - pasg = (ASG *)ellFirst(&pasbase->asgList); - while(pasg) { - asComputeAsgPvt(pasg); - pasg = (ASG *)ellNext(&pasg->node); - } - return(0); -} - -static long asComputeAsgPvt(ASG *pasg) -{ - ASGRULE *pasgrule; - ASGMEMBER *pasgmember; - ASGCLIENT *pasgclient; - - if(!asActive) return(S_asLib_asNotActive); - pasgrule = (ASGRULE *)ellFirst(&pasg->ruleList); - while(pasgrule) { - double result = pasgrule->result; /* set for VAL */ - long status; - - if(pasgrule->calc && (pasg->inpChanged & pasgrule->inpUsed)) { - status = calcPerform(pasg->pavalue,&result,pasgrule->rpcl); - if(status) { - pasgrule->result = 0; - errMessage(status,"asComputeAsg"); - } else { - pasgrule->result = ((result>.99) && (result<1.01)) ? 1 : 0; - } - } - pasgrule = (ASGRULE *)ellNext(&pasgrule->node); - } - pasg->inpChanged = FALSE; - pasgmember = (ASGMEMBER *)ellFirst(&pasg->memberList); - while(pasgmember) { - pasgclient = (ASGCLIENT *)ellFirst(&pasgmember->clientList); - while(pasgclient) { - asComputePvt((ASCLIENTPVT)pasgclient); - pasgclient = (ASGCLIENT *)ellNext(&pasgclient->node); - } - pasgmember = (ASGMEMBER *)ellNext(&pasgmember->node); - } - return(0); -} - -static long asComputePvt(ASCLIENTPVT asClientPvt) -{ - asAccessRights access=asNOACCESS; - int trapMask=0; - ASGCLIENT *pasgclient = asClientPvt; - ASGMEMBER *pasgMember; - ASG *pasg; - ASGRULE *pasgrule; - asAccessRights oldaccess; - GPHENTRY *pgphentry; - - if(!asActive) return(S_asLib_asNotActive); - if(!pasgclient) return(S_asLib_badClient); - pasgMember = pasgclient->pasgMember; - if(!pasgMember) return(S_asLib_badMember); - pasg = pasgMember->pasg; - if(!pasg) return(S_asLib_badAsg); - oldaccess=pasgclient->access; - pasgrule = (ASGRULE *)ellFirst(&pasg->ruleList); - while(pasgrule) { - if(access == asWRITE) break; - if(access>=pasgrule->access) goto next_rule; - if(pasgclient->level > pasgrule->level) goto next_rule; - /*if uagList is empty then no need to check uag*/ - if(ellCount(&pasgrule->uagList)>0){ - ASGUAG *pasguag; - UAG *puag; - - pasguag = (ASGUAG *)ellFirst(&pasgrule->uagList); - while(pasguag) { - if((puag = pasguag->puag)) { - pgphentry = gphFind(pasbase->phash,pasgclient->user,puag); - if(pgphentry) goto check_hag; - } - pasguag = (ASGUAG *)ellNext(&pasguag->node); - } - goto next_rule; - } -check_hag: - /*if hagList is empty then no need to check hag*/ - if(ellCount(&pasgrule->hagList)>0) { - ASGHAG *pasghag; - HAG *phag; - - pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList); - while(pasghag) { - if((phag = pasghag->phag)) { - pgphentry=gphFind(pasbase->phash,pasgclient->host,phag); - if(pgphentry) goto check_calc; - } - pasghag = (ASGHAG *)ellNext(&pasghag->node); - } - goto next_rule; - } -check_calc: - if(!pasgrule->calc - || (!(pasg->inpBad & pasgrule->inpUsed) && (pasgrule->result==1))) { - access = pasgrule->access; - trapMask = pasgrule->trapMask; - } -next_rule: - pasgrule = (ASGRULE *)ellNext(&pasgrule->node); - } - pasgclient->access = access; - pasgclient->trapMask = trapMask; - if(pasgclient->pcallback && oldaccess!=access) { - (*pasgclient->pcallback)(pasgclient,asClientCOAR); - } - return(0); -} - -void asFreeAll(ASBASE *pasbase) -{ - UAG *puag; - UAGNAME *puagname; - HAG *phag; - HAGNAME *phagname; - ASG *pasg; - ASGINP *pasginp; - ASGRULE *pasgrule; - ASGHAG *pasghag; - ASGUAG *pasguag; - void *pnext; - - puag = (UAG *)ellFirst(&pasbase->uagList); - while(puag) { - puagname = (UAGNAME *)ellFirst(&puag->list); - while(puagname) { - pnext = ellNext(&puagname->node); - ellDelete(&puag->list,&puagname->node); - free(puagname); - puagname = pnext; - } - pnext = ellNext(&puag->node); - ellDelete(&pasbase->uagList,&puag->node); - free(puag); - puag = pnext; - } - phag = (HAG *)ellFirst(&pasbase->hagList); - while(phag) { - phagname = (HAGNAME *)ellFirst(&phag->list); - while(phagname) { - pnext = ellNext(&phagname->node); - ellDelete(&phag->list,&phagname->node); - free(phagname); - phagname = pnext; - } - pnext = ellNext(&phag->node); - ellDelete(&pasbase->hagList,&phag->node); - free(phag); - phag = pnext; - } - pasg = (ASG *)ellFirst(&pasbase->asgList); - while(pasg) { - free(pasg->pavalue); - pasginp = (ASGINP *)ellFirst(&pasg->inpList); - while(pasginp) { - pnext = ellNext(&pasginp->node); - ellDelete(&pasg->inpList,&pasginp->node); - free(pasginp); - pasginp = pnext; - } - pasgrule = (ASGRULE *)ellFirst(&pasg->ruleList); - while(pasgrule) { - free(pasgrule->calc); - free(pasgrule->rpcl); - pasguag = (ASGUAG *)ellFirst(&pasgrule->uagList); - while(pasguag) { - pnext = ellNext(&pasguag->node); - ellDelete(&pasgrule->uagList,&pasguag->node); - free(pasguag); - pasguag = pnext; - } - pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList); - while(pasghag) { - pnext = ellNext(&pasghag->node); - ellDelete(&pasgrule->hagList,&pasghag->node); - free(pasghag); - pasghag = pnext; - } - pnext = ellNext(&pasgrule->node); - ellDelete(&pasg->ruleList,&pasgrule->node); - free(pasgrule); - pasgrule = pnext; - } - pnext = ellNext(&pasg->node); - ellDelete(&pasbase->asgList,&pasg->node); - free(pasg); - pasg = pnext; - } - gphFreeMem(pasbase->phash); - free(pasbase); -} - -/*Beginning of routines called by lex code*/ -static UAG *asUagAdd(const char *uagName) -{ - UAG *pprev; - UAG *pnext; - UAG *puag; - int cmpvalue; - ASBASE *pasbase = (ASBASE *)pasbasenew; - - /*Insert in alphabetic order*/ - pnext = (UAG *)ellFirst(&pasbase->uagList); - while(pnext) { - cmpvalue = strcmp(uagName,pnext->name); - if(cmpvalue < 0) break; - if(cmpvalue==0) { - errlogPrintf("Duplicate User Access Group named '%s'\n", uagName); - return(NULL); - } - pnext = (UAG *)ellNext(&pnext->node); - } - puag = asCalloc(1,sizeof(UAG)+strlen(uagName)+1); - ellInit(&puag->list); - puag->name = (char *)(puag+1); - strcpy(puag->name,uagName); - if(pnext==NULL) { /*Add to end of list*/ - ellAdd(&pasbase->uagList,&puag->node); - } else { - pprev = (UAG *)ellPrevious(&pnext->node); - ellInsert(&pasbase->uagList,&pprev->node,&puag->node); - } - return(puag); -} - -static long asUagAddUser(UAG *puag,const char *user) -{ - UAGNAME *puagname; - - if(!puag) return(0); - puagname = asCalloc(1,sizeof(UAGNAME)+strlen(user)+1); - puagname->user = (char *)(puagname+1); - strcpy(puagname->user,user); - ellAdd(&puag->list,&puagname->node); - return(0); -} - -static HAG *asHagAdd(const char *hagName) -{ - HAG *pprev; - HAG *pnext; - HAG *phag; - int cmpvalue; - ASBASE *pasbase = (ASBASE *)pasbasenew; - - /*Insert in alphabetic order*/ - pnext = (HAG *)ellFirst(&pasbase->hagList); - while(pnext) { - cmpvalue = strcmp(hagName,pnext->name); - if(cmpvalue < 0) break; - if(cmpvalue==0) { - errlogPrintf("Duplicate Host Access Group named '%s'\n", hagName); - return(NULL); - } - pnext = (HAG *)ellNext(&pnext->node); - } - phag = asCalloc(1,sizeof(HAG)+strlen(hagName)+1); - ellInit(&phag->list); - phag->name = (char *)(phag+1); - strcpy(phag->name,hagName); - if(pnext==NULL) { /*Add to end of list*/ - ellAdd(&pasbase->hagList,&phag->node); - } else { - pprev = (HAG *)ellPrevious(&pnext->node); - ellInsert(&pasbase->hagList,&pprev->node,&phag->node); - } - return(phag); -} - -static long asHagAddHost(HAG *phag,const char *host) -{ - HAGNAME *phagname; - int len, i; - - if (!phag) return 0; - len = strlen(host); - phagname = asCalloc(1, sizeof(HAGNAME) + len + 1); - phagname->host = (char *)(phagname + 1); - for (i = 0; i < len; i++) { - phagname->host[i] = (char)tolower((int)host[i]); - } - ellAdd(&phag->list, &phagname->node); - return 0; -} - -static ASG *asAsgAdd(const char *asgName) -{ - ASG *pprev; - ASG *pnext; - ASG *pasg; - int cmpvalue; - ASBASE *pasbase = (ASBASE *)pasbasenew; - - /*Insert in alphabetic order*/ - pnext = (ASG *)ellFirst(&pasbase->asgList); - while(pnext) { - cmpvalue = strcmp(asgName,pnext->name); - if(cmpvalue < 0) break; - if(cmpvalue==0) { - if(strcmp(DEFAULT,pnext->name)==0) { - if(ellCount(&pnext->inpList)==0 - && ellCount(&pnext->ruleList)==0) - return(pnext); - } - errlogPrintf("Duplicate Access Security Group named '%s'\n", asgName); - return(NULL); - } - pnext = (ASG *)ellNext(&pnext->node); - } - pasg = asCalloc(1,sizeof(ASG)+strlen(asgName)+1); - ellInit(&pasg->inpList); - ellInit(&pasg->ruleList); - ellInit(&pasg->memberList); - pasg->name = (char *)(pasg+1); - strcpy(pasg->name,asgName); - if(pnext==NULL) { /*Add to end of list*/ - ellAdd(&pasbase->asgList,&pasg->node); - } else { - pprev = (ASG *)ellPrevious(&pnext->node); - ellInsert(&pasbase->asgList,&pprev->node,&pasg->node); - } - return(pasg); -} - -static long asAsgAddInp(ASG *pasg,const char *inp,int inpIndex) -{ - ASGINP *pasginp; - - if(!pasg) return(0); - pasginp = asCalloc(1,sizeof(ASGINP)+strlen(inp)+1); - pasginp->inp = (char *)(pasginp+1); - strcpy(pasginp->inp,inp); - pasginp->pasg = pasg; - pasginp->inpIndex = inpIndex; - ellAdd(&pasg->inpList,&pasginp->node); - return(0); -} - -static ASGRULE *asAsgAddRule(ASG *pasg,asAccessRights access,int level) -{ - ASGRULE *pasgrule; - - if(!pasg) return(0); - pasgrule = asCalloc(1,sizeof(ASGRULE)); - pasgrule->access = access; - pasgrule->trapMask = 0; - pasgrule->level = level; - ellInit(&pasgrule->uagList); - ellInit(&pasgrule->hagList); - ellAdd(&pasg->ruleList,&pasgrule->node); - return(pasgrule); -} - -static long asAsgAddRuleOptions(ASGRULE *pasgrule,int trapMask) -{ - if(!pasgrule) return(0); - pasgrule->trapMask = trapMask; - return(0); -} - -static long asAsgRuleUagAdd(ASGRULE *pasgrule, const char *name) -{ - ASGUAG *pasguag; - UAG *puag; - ASBASE *pasbase = (ASBASE *)pasbasenew; - - if (!pasgrule) - return 0; - - puag = (UAG *)ellFirst(&pasbase->uagList); - while (puag) { - if (strcmp(puag->name, name)==0) - break; - puag = (UAG *)ellNext(&puag->node); - } - if (!puag){ - errlogPrintf("No User Access Group named '%s' defined\n", name); - return S_asLib_noUag; - } - - pasguag = asCalloc(1, sizeof(ASGUAG)); - pasguag->puag = puag; - ellAdd(&pasgrule->uagList, &pasguag->node); - return 0; -} - -static long asAsgRuleHagAdd(ASGRULE *pasgrule, const char *name) -{ - ASGHAG *pasghag; - HAG *phag; - ASBASE *pasbase = (ASBASE *)pasbasenew; - - if (!pasgrule) - return 0; - - phag = (HAG *)ellFirst(&pasbase->hagList); - while (phag) { - if (strcmp(phag->name, name)==0) - break; - phag = (HAG *)ellNext(&phag->node); - } - if (!phag){ - errlogPrintf("No Host Access Group named '%s' defined\n", name); - return S_asLib_noHag; - } - - pasghag = asCalloc(1, sizeof(ASGHAG)); - pasghag->phag = phag; - ellAdd(&pasgrule->hagList, &pasghag->node); - return 0; -} - -static long asAsgRuleCalc(ASGRULE *pasgrule,const char *calc) -{ - short err; - long status; - size_t insize; - unsigned long stores; - - if (!pasgrule) return 0; - insize = strlen(calc) + 1; - pasgrule->calc = asCalloc(1, insize); - strcpy(pasgrule->calc, calc); - pasgrule->rpcl = asCalloc(1, INFIX_TO_POSTFIX_SIZE(insize)); - status = postfix(pasgrule->calc, pasgrule->rpcl, &err); - if(status) { - free(pasgrule->calc); - free(pasgrule->rpcl); - pasgrule->calc = NULL; - pasgrule->rpcl = NULL; - status = S_asLib_badCalc; - errlogPrintf("%s in CALC expression '%s'\n", calcErrorStr(err), calc); - return status; - } - calcArgUsage(pasgrule->rpcl, &pasgrule->inpUsed, &stores); - /* Until someone proves stores are not dangerous, don't allow them */ - if (stores) { - free(pasgrule->calc); - free(pasgrule->rpcl); - pasgrule->calc = NULL; - pasgrule->rpcl = NULL; - status = S_asLib_badCalc; - errlogPrintf("Assignment operator used in CALC expression '%s'\n", - calc); - } - return(status); -} diff --git a/src/libCom/as/asLib_lex.l b/src/libCom/as/asLib_lex.l deleted file mode 100644 index 924105c14..000000000 --- a/src/libCom/as/asLib_lex.l +++ /dev/null @@ -1,94 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -newline "\n" -backslash "\\" -doublequote "\"" -comment "#" -whitespace [ \t\r] -escape {backslash}. -stringchar [^"\n\\] - -name [a-zA-Z0-9_\-+:.\[\]<>;] -digit [0-9] -punctuation [(){},] -link [A-L] - -%{ -static ASINPUTFUNCPTR *my_yyinput; -#undef YY_INPUT -#define YY_INPUT(b,r,ms) (r=(*my_yyinput)((char *)b,ms)) - -static int yyreset(void) -{ - line_num=1; - BEGIN INITIAL; - return(0); -} - -%} - -%% - -UAG { return(tokenUAG); } -HAG { return(tokenHAG); } -ASG { return(tokenASG); } -RULE { return(tokenRULE); } -CALC { return(tokenCALC); } - -INP{link} { - yylval.Int = (unsigned char)yytext[3]; - yylval.Int -= 'A'; - return(tokenINP); -} - -{digit}+ { /*integer*/ - yylval.Int = atoi((char *)yytext); - return(tokenINTEGER); -} - -{name}+ { /*unquoted string*/ - yylval.Str=asStrdup(yytext); - return(tokenSTRING); -} - -{doublequote}({stringchar}|{escape})*{doublequote} { /* quoted string */ - yylval.Str=asStrdup(yytext+1); - yylval.Str[strlen(yylval.Str)-1] = '\0'; - return(tokenSTRING); -} - -{doublequote}({stringchar}|{escape})*{newline} { /* bad string */ - yyerror("Newline in quoted string, closing quote missing"); -} - -{punctuation} { return(yytext[0]); } - -{newline} { line_num++; } - -{comment}.* ; -{whitespace} ; - -. { - char message[40]; - YY_BUFFER_STATE *dummy=0; - - if (isprint((int) yytext[0])) { - sprintf(message, "Invalid character '%c'", yytext[0]); - } - else { - sprintf(message, "Invalid character 0x%2.2x", yytext[0]); - } - yyerror(message); - - /*The following suppress compiler warning messages*/ - if (0) yyunput('c',(unsigned char *) message); - if (0) yy_switch_to_buffer(*dummy); -} - -%% diff --git a/src/libCom/as/asTrapWrite.c b/src/libCom/as/asTrapWrite.c deleted file mode 100644 index 544e9a211..000000000 --- a/src/libCom/as/asTrapWrite.c +++ /dev/null @@ -1,175 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*asTrapWrite.c */ -/* Author: Marty Kraimer Date: 07NOV2000 */ - -/* Matthias Clausen and Vladis Korobov at DESY - * implemented the first logging of Channel Access Puts - * This implementation uses many ideas from their implementation -*/ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "ellLib.h" -#include "freeList.h" -#include "epicsStdio.h" -#include "cantProceed.h" -#include "epicsMutex.h" -#include "ellLib.h" - -#include "asLib.h" -#include "asTrapWrite.h" - -typedef struct listenerPvt { - ELLNODE node; - struct listener *plistener; - void *userPvt; -}listenerPvt; - -typedef struct listener{ - ELLNODE node; - asTrapWriteListener func; -}listener; - -typedef struct writeMessage { - ELLNODE node; - asTrapWriteMessage message; - ELLLIST listenerPvtList; -}writeMessage; - - -typedef struct asTrapWritePvt -{ - ELLLIST listenerList; - ELLLIST writeMessageList; - void *freeListWriteMessage; - void *freeListListenerPvt; - epicsMutexId lock; -}asTrapWritePvt; - -static asTrapWritePvt *pasTrapWritePvt = 0; - -static void asTrapWriteInit(void) -{ - pasTrapWritePvt = callocMustSucceed(1,sizeof(asTrapWritePvt),"asTrapWriteInit"); - ellInit(&pasTrapWritePvt->listenerList); - ellInit(&pasTrapWritePvt->writeMessageList); - freeListInitPvt( - &pasTrapWritePvt->freeListWriteMessage,sizeof(writeMessage),20); - freeListInitPvt( - &pasTrapWritePvt->freeListListenerPvt,sizeof(listenerPvt),20); - pasTrapWritePvt->lock = epicsMutexMustCreate(); -} - -asTrapWriteId epicsShareAPI asTrapWriteRegisterListener( - asTrapWriteListener func) -{ - listener *plistener; - if(pasTrapWritePvt==0) asTrapWriteInit(); - plistener = callocMustSucceed(1,sizeof(listener),"asTrapWriteRegisterListener"); - plistener->func = func; - epicsMutexMustLock(pasTrapWritePvt->lock); - ellAdd(&pasTrapWritePvt->listenerList,&plistener->node); - epicsMutexUnlock(pasTrapWritePvt->lock); - return((asTrapWriteId)plistener); -} - -void epicsShareAPI asTrapWriteUnregisterListener(asTrapWriteId id) -{ - listener *plistener = (listener *)id; - writeMessage *pwriteMessage; - - if(pasTrapWritePvt==0) return; - epicsMutexMustLock(pasTrapWritePvt->lock); - pwriteMessage = (writeMessage *)ellFirst(&pasTrapWritePvt->writeMessageList); - while(pwriteMessage) { - listenerPvt *plistenerPvt - = (listenerPvt *)ellFirst(&pwriteMessage->listenerPvtList); - while(plistenerPvt) { - listenerPvt *pnext - = (listenerPvt *)ellNext(&plistenerPvt->node); - if(plistenerPvt->plistener == plistener) { - ellDelete(&pwriteMessage->listenerPvtList,&plistenerPvt->node); - freeListFree(pasTrapWritePvt->freeListListenerPvt, plistenerPvt); - } - plistenerPvt = pnext; - } - pwriteMessage = (writeMessage *)ellNext(&pwriteMessage->node); - } - ellDelete(&pasTrapWritePvt->listenerList,&plistener->node); - free(plistener); - epicsMutexUnlock(pasTrapWritePvt->lock); -} - -void * epicsShareAPI asTrapWriteBeforeWithData( - const char *userid, const char *hostid, void *addr, - int dbrType, int no_elements, void *data) -{ - writeMessage *pwriteMessage; - listener *plistener; - - if (pasTrapWritePvt == 0 || - ellCount(&pasTrapWritePvt->listenerList) <= 0) return 0; - - pwriteMessage = (writeMessage *)freeListCalloc( - pasTrapWritePvt->freeListWriteMessage); - pwriteMessage->message.userid = userid; - pwriteMessage->message.hostid = hostid; - pwriteMessage->message.serverSpecific = addr; - pwriteMessage->message.dbrType = dbrType; - pwriteMessage->message.no_elements = no_elements; - pwriteMessage->message.data = data; - ellInit(&pwriteMessage->listenerPvtList); - - epicsMutexMustLock(pasTrapWritePvt->lock); - ellAdd(&pasTrapWritePvt->writeMessageList, &pwriteMessage->node); - plistener = (listener *)ellFirst(&pasTrapWritePvt->listenerList); - while (plistener) { - listenerPvt *plistenerPvt = (listenerPvt *)freeListCalloc( - pasTrapWritePvt->freeListListenerPvt); - - plistenerPvt->plistener = plistener; - pwriteMessage->message.userPvt = 0; - plistener->func(&pwriteMessage->message, 0); - plistenerPvt->userPvt = pwriteMessage->message.userPvt; - ellAdd(&pwriteMessage->listenerPvtList, &plistenerPvt->node); - plistener = (listener *)ellNext(&plistener->node); - } - epicsMutexUnlock(pasTrapWritePvt->lock); - return pwriteMessage; -} - -void epicsShareAPI asTrapWriteAfterWrite(void *pvt) -{ - writeMessage *pwriteMessage = (writeMessage *)pvt; - listenerPvt *plistenerPvt; - - if (pwriteMessage == 0 || - pasTrapWritePvt == 0) return; - - epicsMutexMustLock(pasTrapWritePvt->lock); - plistenerPvt = (listenerPvt *)ellFirst(&pwriteMessage->listenerPvtList); - while (plistenerPvt) { - listenerPvt *pnext = (listenerPvt *)ellNext(&plistenerPvt->node); - listener *plistener = plistenerPvt->plistener; - - pwriteMessage->message.userPvt = plistenerPvt->userPvt; - plistener->func(&pwriteMessage->message, 1); - ellDelete(&pwriteMessage->listenerPvtList, &plistenerPvt->node); - freeListFree(pasTrapWritePvt->freeListListenerPvt, plistenerPvt); - plistenerPvt = pnext; - } - ellDelete(&pasTrapWritePvt->writeMessageList, &pwriteMessage->node); - freeListFree(pasTrapWritePvt->freeListWriteMessage, pwriteMessage); - epicsMutexUnlock(pasTrapWritePvt->lock); -} diff --git a/src/libCom/as/asTrapWrite.h b/src/libCom/as/asTrapWrite.h deleted file mode 100644 index b8033cb94..000000000 --- a/src/libCom/as/asTrapWrite.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*asTrapWrite.h*/ -/* Author: Marty Kraimer Date: 07NOV2000 */ - -#ifndef INCasTrapWriteh -#define INCasTrapWriteh - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct asTrapWriteMessage { - const char *userid; - const char *hostid; - void *serverSpecific; - void *userPvt; - int dbrType; /* Data type from ca/db_access.h, NOT dbFldTypes.h */ - int no_elements; - void *data; /* Might be NULL if no data is available */ -} asTrapWriteMessage; - - -typedef void *asTrapWriteId; -typedef void(*asTrapWriteListener)(asTrapWriteMessage *pmessage,int after); - -epicsShareFunc asTrapWriteId epicsShareAPI asTrapWriteRegisterListener( - asTrapWriteListener func); -epicsShareFunc void epicsShareAPI asTrapWriteUnregisterListener( - asTrapWriteId id); - -/* - * asTrapWriteListener is called before and after the write is performed. - * The listener can set userPvt on the before call and retrieve it after - * after = (0,1) (before,after) the put. - * - * Each asTrapWriteMessage can change or may be deleted after - * the user's asTrapWriteListener returns - * - * asTrapWriteListener delays the associated server thread so it must not - * do anything that causes to to block. -*/ - -#ifdef __cplusplus -} -#endif - -#endif /*INCasTrapWriteh*/ diff --git a/src/libCom/bucketLib/Makefile b/src/libCom/bucketLib/Makefile deleted file mode 100644 index f66dc7d47..000000000 --- a/src/libCom/bucketLib/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/bucketLib -INC += bucketLib.h -Com_SRCS += bucketLib.c diff --git a/src/libCom/bucketLib/bucketLib.c b/src/libCom/bucketLib/bucketLib.c deleted file mode 100644 index 40df596a4..000000000 --- a/src/libCom/bucketLib/bucketLib.c +++ /dev/null @@ -1,522 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey O. Hill - * hill@atdiv.lanl.gov - * (505) 665 1831 - * Date: 9-93 - * - * NOTES: - * .01 Storage for identifier must persist until an item is deleted - */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "freeList.h" /* bucketLib uses freeListLib inside the DLL */ -#include "bucketLib.h" - -/* - * these data type dependent routines are - * provided in the bucketLib.c - */ -typedef BUCKETID bucketHash(BUCKET *pb, const void *pId); -typedef ITEM **bucketCompare(ITEM **ppi, const void *pId); - -static bucketCompare bucketUnsignedCompare; -static bucketCompare bucketPointerCompare; -static bucketCompare bucketStringCompare; -static bucketHash bucketUnsignedHash; -static bucketHash bucketPointerHash; -static bucketHash bucketStringHash; - -typedef struct { - bucketHash *pHash; - bucketCompare *pCompare; - buckTypeOfId type; -}bucketSET; - -static bucketSET BSET[] = { - {bucketUnsignedHash, bucketUnsignedCompare, bidtUnsigned}, - {bucketPointerHash, bucketPointerCompare, bidtPointer}, - {bucketStringHash, bucketStringCompare, bidtString} -}; - -static int bucketAddItem(BUCKET *prb, bucketSET *pBSET, - const void *pId, const void *pApp); -static void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId); - - - -/* - * bucket id bit width - */ -#define BUCKETID_BIT_WIDTH (sizeof(BUCKETID)*CHAR_BIT) - -/* - * Maximum bucket size - */ -#define BUCKET_MAX_WIDTH 12 - - -/* - * bucketUnsignedCompare() - */ -static ITEM **bucketUnsignedCompare (ITEM **ppi, const void *pId) -{ - unsigned id; - unsigned *pItemId; - ITEM *pi; - - id = * (unsigned *) pId; - while ( (pi = *ppi) ) { - if (bidtUnsigned == pi->type) { - pItemId = (unsigned *) pi->pId; - if (id == *pItemId) { - return ppi; - } - } - ppi = &pi->pItem; - } - return NULL; -} - - -/* - * bucketPointerCompare() - */ -static ITEM **bucketPointerCompare (ITEM **ppi, const void *pId) -{ - void *ptr; - void **pItemId; - ITEM *pi; - - ptr = * (void **) pId; - while ( (pi = *ppi) ) { - if (bidtPointer == pi->type ) { - pItemId = (void **) pi->pId; - if (ptr == *pItemId) { - return ppi; - } - } - ppi = &pi->pItem; - } - return NULL; -} - - -/* - * bucketStringCompare () - */ -static ITEM **bucketStringCompare (ITEM **ppi, const void *pId) -{ - const char *pStr = pId; - ITEM *pi; - int status; - - while ( (pi = *ppi) ) { - if (bidtString == pi->type) { - status = strcmp (pStr, (char *)pi->pId); - if (status == '\0') { - return ppi; - } - } - ppi = &pi->pItem; - } - return NULL; -} - - -/* - * bucketUnsignedHash () - */ -static BUCKETID bucketUnsignedHash (BUCKET *pb, const void *pId) -{ - const unsigned *pUId = (const unsigned *) pId; - unsigned src; - BUCKETID hashid; - - src = *pUId; - hashid = src; - src = src >> pb->hashIdNBits; - while (src) { - hashid = hashid ^ src; - src = src >> pb->hashIdNBits; - } - hashid = hashid & pb->hashIdMask; - - return hashid; -} - - -/* - * bucketPointerHash () - */ -static BUCKETID bucketPointerHash (BUCKET *pb, const void *pId) -{ - void * const *ppId = (void * const *) pId; - size_t src; - BUCKETID hashid; - - /* - * This makes the assumption that size_t - * can be used to hold a pointer value - * (this assumption may not port to all - * CPU architectures) - */ - src = (size_t) *ppId; - hashid = src; - src = src >> pb->hashIdNBits; - while(src){ - hashid = hashid ^ src; - src = src >> pb->hashIdNBits; - } - hashid = hashid & pb->hashIdMask; - - return hashid; -} - - -/* - * bucketStringHash () - */ -static BUCKETID bucketStringHash (BUCKET *pb, const void *pId) -{ - const char *pStr = (const char *) pId; - BUCKETID hashid; - unsigned i; - - hashid = 0; - i = 1; - while(*pStr){ - hashid += *pStr * i; - pStr++; - i++; - } - - hashid = hashid % (pb->hashIdMask+1); - - return hashid; -} - - - -/* - * bucketCreate() - */ -epicsShareFunc BUCKET * epicsShareAPI bucketCreate (unsigned nHashTableEntries) -{ - BUCKETID mask; - unsigned nbits; - BUCKET *pb; - - /* - * no absurd sized buckets - */ - if (nHashTableEntries<=1) { - fprintf (stderr, "Tiny bucket create failed\n"); - return NULL; - } - - /* - * count the number of bits in the bucket id - */ - if ( BUCKETID_BIT_WIDTH > 0 ) { - for (nbits=0; nbits=BUCKETID_BIT_WIDTH) { - fprintf ( - stderr, - "%s at %d: Requested index width=%d to large. max=%ld\n", - __FILE__, - __LINE__, - nbits, - (long)(BUCKETID_BIT_WIDTH-1)); - return NULL; - } - - pb = (BUCKET *) calloc(1, sizeof(*pb)); - if (!pb) { - return pb; - } - - pb->hashIdMask = mask; - pb->hashIdNBits = nbits; - freeListInitPvt(&pb->freeListPVT, sizeof(ITEM), 1024); - - pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable)); - if (!pb->pTable) { - freeListCleanup(pb->freeListPVT); - free (pb); - return NULL; - } - return pb; -} - - -/* - * bucketFree() - */ -epicsShareFunc int epicsShareAPI bucketFree (BUCKET *prb) -{ - /* - * deleting a bucket with entries in use - * will cause memory leaks and is not allowed - */ - assert (prb->nInUse==0); - - /* - * free the free list - */ - freeListCleanup(prb->freeListPVT); - free (prb->pTable); - free (prb); - - return S_bucket_success; -} - - -/* - * bucketAddItem() - */ -epicsShareFunc int epicsShareAPI - bucketAddItemUnsignedId(BUCKET *prb, const unsigned *pId, const void *pApp) -{ - return bucketAddItem(prb, &BSET[bidtUnsigned], pId, pApp); -} -epicsShareFunc int epicsShareAPI - bucketAddItemPointerId(BUCKET *prb, void * const *pId, const void *pApp) -{ - return bucketAddItem(prb, &BSET[bidtPointer], pId, pApp); -} -epicsShareFunc int epicsShareAPI - bucketAddItemStringId(BUCKET *prb, const char *pId, const void *pApp) -{ - return bucketAddItem(prb, &BSET[bidtString], pId, pApp); -} -static int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, const void *pApp) -{ - BUCKETID hashid; - ITEM **ppi; - ITEM **ppiExists; - ITEM *pi; - - /* - * try to get it off the free list first. If - * that fails then malloc() - */ - pi = (ITEM *) freeListMalloc(prb->freeListPVT); - if (!pi) { - return S_bucket_noMemory; - } - - /* - * create the hash index - */ - hashid = (*pBSET->pHash) (prb, pId); - - pi->pApp = pApp; - pi->pId = pId; - pi->type = pBSET->type; - assert ((hashid & ~prb->hashIdMask) == 0); - ppi = &prb->pTable[hashid]; - /* - * Dont reuse a resource id ! - */ - ppiExists = (*pBSET->pCompare) (ppi, pId); - if (ppiExists) { - freeListFree(prb->freeListPVT,pi); - return S_bucket_idInUse; - } - pi->pItem = *ppi; - prb->pTable[hashid] = pi; - prb->nInUse++; - - return S_bucket_success; -} - -/* - * bucketLookupAndRemoveItem () - */ -static void *bucketLookupAndRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId) -{ - BUCKETID hashid; - ITEM **ppi; - ITEM *pi; - void *pApp; - - /* - * create the hash index - */ - hashid = (*pBSET->pHash) (prb, pId); - - assert((hashid & ~prb->hashIdMask) == 0); - ppi = &prb->pTable[hashid]; - ppi = (*pBSET->pCompare) (ppi, pId); - if(!ppi){ - return NULL; - } - prb->nInUse--; - pi = *ppi; - *ppi = pi->pItem; - - pApp = (void *) pi->pApp; - - /* - * stuff it on the free list - */ - freeListFree(prb->freeListPVT, pi); - - return pApp; -} -epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId) -{ - return bucketLookupAndRemoveItem(prb, &BSET[bidtUnsigned], pId); -} -epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemPointerId (BUCKET *prb, void * const *pId) -{ - return bucketLookupAndRemoveItem(prb, &BSET[bidtPointer], pId); -} -epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemStringId (BUCKET *prb, const char *pId) -{ - return bucketLookupAndRemoveItem(prb, &BSET[bidtString], pId); -} - - -/* - * bucketRemoveItem() - */ -epicsShareFunc int epicsShareAPI - bucketRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId) -{ - return bucketLookupAndRemoveItem(prb, &BSET[bidtUnsigned], pId)?S_bucket_success:S_bucket_uknId; -} -epicsShareFunc int epicsShareAPI - bucketRemoveItemPointerId (BUCKET *prb, void * const *pId) -{ - return bucketLookupAndRemoveItem(prb, &BSET[bidtPointer], pId)?S_bucket_success:S_bucket_uknId; -} -epicsShareFunc int epicsShareAPI - bucketRemoveItemStringId (BUCKET *prb, const char *pId) -{ - return bucketLookupAndRemoveItem(prb, &BSET[bidtString], pId)?S_bucket_success:S_bucket_uknId; -} - - -/* - * bucketLookupItem() - */ -epicsShareFunc void * epicsShareAPI - bucketLookupItemUnsignedId (BUCKET *prb, const unsigned *pId) -{ - return bucketLookupItem(prb, &BSET[bidtUnsigned], pId); -} -epicsShareFunc void * epicsShareAPI - bucketLookupItemPointerId (BUCKET *prb, void * const *pId) -{ - return bucketLookupItem(prb, &BSET[bidtPointer], pId); -} -epicsShareFunc void * epicsShareAPI - bucketLookupItemStringId (BUCKET *prb, const char *pId) -{ - return bucketLookupItem(prb, &BSET[bidtString], pId); -} -static void *bucketLookupItem (BUCKET *pb, bucketSET *pBSET, const void *pId) -{ - BUCKETID hashid; - ITEM **ppi; - - /* - * create the hash index - */ - hashid = (*pBSET->pHash) (pb, pId); - assert((hashid & ~pb->hashIdMask) == 0); - - /* - * at the bottom level just - * linear search for it. - */ - ppi = (*pBSET->pCompare) (&pb->pTable[hashid], pId); - if(ppi){ - return (void *) (*ppi)->pApp; - } - return NULL; -} - - - -/* - * bucketShow() - */ -epicsShareFunc int epicsShareAPI bucketShow(BUCKET *pb) -{ - ITEM **ppi; - ITEM *pi; - unsigned nElem; - double X; - double XX; - double mean; - double stdDev; - unsigned count; - unsigned maxEntries; - - printf( " Bucket entries in use = %d bytes in use = %ld\n", - pb->nInUse, - (long) (sizeof(*pb)+(pb->hashIdMask+1)* - sizeof(ITEM *)+pb->nInUse*sizeof(ITEM))); - - ppi = pb->pTable; - nElem = pb->hashIdMask+1; - X = 0.0; - XX = 0.0; - maxEntries = 0; - while (ppi < &pb->pTable[nElem]) { - pi = *ppi; - count = 0; - while (pi) { - count++; - pi = pi->pItem; - } - X += count; - XX += count*count; - if (count > maxEntries) maxEntries = count; - ppi++; - } - - mean = X/nElem; - stdDev = sqrt(XX/nElem - mean*mean); - printf( " Bucket entries/hash id - mean = %f std dev = %f max = %d\n", - mean, - stdDev, - maxEntries); - - return S_bucket_success; -} - - diff --git a/src/libCom/bucketLib/bucketLib.h b/src/libCom/bucketLib/bucketLib.h deleted file mode 100644 index 60d73b459..000000000 --- a/src/libCom/bucketLib/bucketLib.h +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey O. Hill - * hill@luke.lanl.gov - * (505) 665 1831 - * Date: 9-93 - * - * NOTES: - * .01 Storage for identifier must persist until an item is deleted - */ - -#ifndef INCbucketLibh -#define INCbucketLibh - -#ifdef __cplusplus -extern "C" { -#endif - -#include "errMdef.h" -#include "epicsTypes.h" -#include "shareLib.h" - -typedef unsigned BUCKETID; - -typedef enum {bidtUnsigned, bidtPointer, bidtString} buckTypeOfId; - -typedef struct item{ - struct item *pItem; - const void *pId; - const void *pApp; - buckTypeOfId type; -}ITEM; - -typedef struct bucket{ - ITEM **pTable; - void *freeListPVT; - unsigned hashIdMask; - unsigned hashIdNBits; - unsigned nInUse; -}BUCKET; - -epicsShareFunc BUCKET * epicsShareAPI bucketCreate (unsigned nHashTableEntries); -epicsShareFunc int epicsShareAPI bucketFree (BUCKET *prb); -epicsShareFunc int epicsShareAPI bucketShow (BUCKET *pb); - -/* - * !! Identifier must exist (and remain constant) at the specified address until - * the item is deleted from the bucket !! - */ -epicsShareFunc int epicsShareAPI bucketAddItemUnsignedId (BUCKET *prb, - const unsigned *pId, const void *pApp); -epicsShareFunc int epicsShareAPI bucketAddItemPointerId (BUCKET *prb, - void * const *pId, const void *pApp); -epicsShareFunc int epicsShareAPI bucketAddItemStringId (BUCKET *prb, - const char *pId, const void *pApp); - -epicsShareFunc int epicsShareAPI bucketRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId); -epicsShareFunc int epicsShareAPI bucketRemoveItemPointerId (BUCKET *prb, void * const *pId); -epicsShareFunc int epicsShareAPI bucketRemoveItemStringId (BUCKET *prb, const char *pId); - -epicsShareFunc void * epicsShareAPI bucketLookupItemUnsignedId (BUCKET *prb, const unsigned *pId); -epicsShareFunc void * epicsShareAPI bucketLookupItemPointerId (BUCKET *prb, void * const *pId); -epicsShareFunc void * epicsShareAPI bucketLookupItemStringId (BUCKET *prb, const char *pId); - -epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId); -epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemPointerId (BUCKET *prb, void * const *pId); -epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemStringId (BUCKET *prb, const char *pId); - - -/* - * Status returned by bucketLib functions - */ -#define BUCKET_SUCCESS S_bucket_success -#define S_bucket_success 0 -#define S_bucket_noMemory (M_bucket | 1) /*Memory allocation failed*/ -#define S_bucket_idInUse (M_bucket | 2) /*Identifier already in use*/ -#define S_bucket_uknId (M_bucket | 3) /*Unknown identifier*/ - -#ifdef __cplusplus -} -#endif - -#endif /*INCbucketLibh*/ - diff --git a/src/libCom/calc/Makefile b/src/libCom/calc/Makefile deleted file mode 100644 index 493cb3245..000000000 --- a/src/libCom/calc/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/calc -INC += postfix.h -Com_SRCS += postfix.c -Com_SRCS += calcPerform.c - diff --git a/src/libCom/calc/calcPerform.c b/src/libCom/calc/calcPerform.c deleted file mode 100644 index c0f4aebb8..000000000 --- a/src/libCom/calc/calcPerform.c +++ /dev/null @@ -1,504 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Julie Sander and Bob Dalesio - * Date: 07-27-87 - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "osiUnistd.h" -#include "dbDefs.h" -#include "epicsMath.h" -#include "epicsTypes.h" -#include "errlog.h" -#include "postfix.h" -#include "postfixPvt.h" - -static double calcRandom(void); -static int cond_search(const char **ppinst, int match); - -#ifndef PI -#define PI 3.14159265358979323 -#endif - -/* Turn off global optimization for 64-bit MSVC builds */ -#if defined(_WIN32) && defined(_M_X64) && !defined(_MINGW) -# pragma optimize("g", off) -#endif - -/* calcPerform - * - * Evalutate the postfix expression - */ -epicsShareFunc long - calcPerform(double *parg, double *presult, const char *pinst) -{ - double stack[CALCPERFORM_STACK+1]; /* zero'th entry not used */ - double *ptop; /* stack pointer */ - double top; /* value from top of stack */ - epicsInt32 itop; /* integer from top of stack */ - epicsUInt32 utop; /* unsigned integer from top of stack */ - int op; - int nargs; - - /* initialize */ - ptop = stack; - - /* RPN evaluation loop */ - while ((op = *pinst++) != END_EXPRESSION){ - switch (op){ - - case LITERAL_DOUBLE: - memcpy(++ptop, pinst, sizeof(double)); - pinst += sizeof(double); - break; - - case LITERAL_INT: - memcpy(&itop, pinst, sizeof(epicsInt32)); - *++ptop = itop; - pinst += sizeof(epicsInt32); - break; - - case FETCH_VAL: - *++ptop = *presult; - break; - - case FETCH_A: - case FETCH_B: - case FETCH_C: - case FETCH_D: - case FETCH_E: - case FETCH_F: - case FETCH_G: - case FETCH_H: - case FETCH_I: - case FETCH_J: - case FETCH_K: - case FETCH_L: - *++ptop = parg[op - FETCH_A]; - break; - - case STORE_A: - case STORE_B: - case STORE_C: - case STORE_D: - case STORE_E: - case STORE_F: - case STORE_G: - case STORE_H: - case STORE_I: - case STORE_J: - case STORE_K: - case STORE_L: - parg[op - STORE_A] = *ptop--; - break; - - case CONST_PI: - *++ptop = PI; - break; - - case CONST_D2R: - *++ptop = PI/180.; - break; - - case CONST_R2D: - *++ptop = 180./PI; - break; - - case UNARY_NEG: - *ptop = - *ptop; - break; - - case ADD: - top = *ptop--; - *ptop += top; - break; - - case SUB: - top = *ptop--; - *ptop -= top; - break; - - case MULT: - top = *ptop--; - *ptop *= top; - break; - - case DIV: - top = *ptop--; - *ptop /= top; - break; - - case MODULO: - itop = (epicsInt32) *ptop--; - if (itop) - *ptop = (epicsInt32) *ptop % itop; - else - *ptop = epicsNAN; - break; - - case POWER: - top = *ptop--; - *ptop = pow(*ptop, top); - break; - - case ABS_VAL: - *ptop = fabs(*ptop); - break; - - case EXP: - *ptop = exp(*ptop); - break; - - case LOG_10: - *ptop = log10(*ptop); - break; - - case LOG_E: - *ptop = log(*ptop); - break; - - case MAX: - nargs = *pinst++; - while (--nargs) { - top = *ptop--; - if (*ptop < top || isnan(top)) - *ptop = top; - } - break; - - case MIN: - nargs = *pinst++; - while (--nargs) { - top = *ptop--; - if (*ptop > top || isnan(top)) - *ptop = top; - } - break; - - case SQU_RT: - *ptop = sqrt(*ptop); - break; - - case ACOS: - *ptop = acos(*ptop); - break; - - case ASIN: - *ptop = asin(*ptop); - break; - - case ATAN: - *ptop = atan(*ptop); - break; - - case ATAN2: - top = *ptop--; - *ptop = atan2(top, *ptop); /* Ouch!: Args backwards! */ - break; - - case COS: - *ptop = cos(*ptop); - break; - - case SIN: - *ptop = sin(*ptop); - break; - - case TAN: - *ptop = tan(*ptop); - break; - - case COSH: - *ptop = cosh(*ptop); - break; - - case SINH: - *ptop = sinh(*ptop); - break; - - case TANH: - *ptop = tanh(*ptop); - break; - - case CEIL: - *ptop = ceil(*ptop); - break; - - case FLOOR: - *ptop = floor(*ptop); - break; - - case FINITE: - nargs = *pinst++; - top = finite(*ptop); - while (--nargs) { - --ptop; - top = top && finite(*ptop); - } - *ptop = top; - break; - - case ISINF: - *ptop = isinf(*ptop); - break; - - case ISNAN: - nargs = *pinst++; - top = isnan(*ptop); - while (--nargs) { - --ptop; - top = top || isnan(*ptop); - } - *ptop = top; - break; - - case NINT: - top = *ptop; - *ptop = (epicsInt32) (top >= 0 ? top + 0.5 : top - 0.5); - break; - - case RANDOM: - *++ptop = calcRandom(); - break; - - case REL_OR: - top = *ptop--; - *ptop = *ptop || top; - break; - - case REL_AND: - top = *ptop--; - *ptop = *ptop && top; - break; - - case REL_NOT: - *ptop = ! *ptop; - break; - - /* For bitwise operations on values with bit 31 set, double values - * must first be cast to unsigned to correctly set that bit; the - * double value must be negative in that case. The result must be - * cast to a signed integer before converting to the double result. - */ - - case BIT_OR: - utop = *ptop--; - *ptop = (epicsInt32) ((epicsUInt32) *ptop | utop); - break; - - case BIT_AND: - utop = *ptop--; - *ptop = (epicsInt32) ((epicsUInt32) *ptop & utop); - break; - - case BIT_EXCL_OR: - utop = *ptop--; - *ptop = (epicsInt32) ((epicsUInt32) *ptop ^ utop); - break; - - case BIT_NOT: - utop = *ptop; - *ptop = (epicsInt32) ~utop; - break; - - /* The shift operators use signed integers, so a right-shift will - * extend the sign bit into the left-hand end of the value. The - * double-casting through unsigned here is important, see above. - */ - - case RIGHT_SHIFT: - utop = *ptop--; - *ptop = ((epicsInt32) (epicsUInt32) *ptop) >> (utop & 31); - break; - - case LEFT_SHIFT: - utop = *ptop--; - *ptop = ((epicsInt32) (epicsUInt32) *ptop) << (utop & 31); - break; - - case NOT_EQ: - top = *ptop--; - *ptop = *ptop != top; - break; - - case LESS_THAN: - top = *ptop--; - *ptop = *ptop < top; - break; - - case LESS_OR_EQ: - top = *ptop--; - *ptop = *ptop <= top; - break; - - case EQUAL: - top = *ptop--; - *ptop = *ptop == top; - break; - - case GR_OR_EQ: - top = *ptop--; - *ptop = *ptop >= top; - break; - - case GR_THAN: - top = *ptop--; - *ptop = *ptop > top; - break; - - case COND_IF: - if (*ptop-- == 0.0 && - cond_search(&pinst, COND_ELSE)) return -1; - break; - - case COND_ELSE: - if (cond_search(&pinst, COND_END)) return -1; - break; - - case COND_END: - break; - - default: - errlogPrintf("calcPerform: Bad Opcode %d at %p\n", op, pinst-1); - return -1; - } - } - - /* The stack should now have one item on it, the expression value */ - if (ptop != stack + 1) - return -1; - *presult = *ptop; - return 0; -} -#if defined(_WIN32) && defined(_M_X64) && !defined(_MINGW) -# pragma optimize("", on) -#endif - - -epicsShareFunc long -calcArgUsage(const char *pinst, unsigned long *pinputs, unsigned long *pstores) -{ - unsigned long inputs = 0; - unsigned long stores = 0; - char op; - while ((op = *pinst++) != END_EXPRESSION) { - switch (op) { - - case LITERAL_DOUBLE: - pinst += sizeof(double); - break; - case LITERAL_INT: - pinst += sizeof(epicsInt32); - break; - case MIN: - case MAX: - case FINITE: - case ISNAN: - pinst++; - break; - - case FETCH_A: - case FETCH_B: - case FETCH_C: - case FETCH_D: - case FETCH_E: - case FETCH_F: - case FETCH_G: - case FETCH_H: - case FETCH_I: - case FETCH_J: - case FETCH_K: - case FETCH_L: - /* Don't claim to use an arg we already stored to */ - inputs |= (1 << (op - FETCH_A)) & ~stores; - break; - - case STORE_A: - case STORE_B: - case STORE_C: - case STORE_D: - case STORE_E: - case STORE_F: - case STORE_G: - case STORE_H: - case STORE_I: - case STORE_J: - case STORE_K: - case STORE_L: - stores |= (1 << (op - STORE_A)); - break; - - default: - break; - } - } - if (pinputs) *pinputs = inputs; - if (pstores) *pstores = stores; - return 0; -} - -/* Generate a random number between 0 and 1 using the algorithm - * seed = (multy * seed) + addy Random Number Generator by Knuth - * SemiNumerical Algorithms - * Chapter 1 - * randy = seed / 65535.0 To normalize the number between 0 - 1 - */ -static unsigned short seed = 0xa3bf; -static unsigned short multy = 191 * 8 + 5; /* 191 % 8 == 5 */ -static unsigned short addy = 0x3141; - -static double calcRandom(void) -{ - seed = (seed * multy) + addy; - - /* between 0 - 1 */ - return (double) seed / 65535.0; -} - -/* Search the instruction stream for a matching operator, skipping any - * other conditional instructions found, and leave *ppinst pointing to - * the next instruction to be executed. - */ -static int cond_search(const char **ppinst, int match) -{ - const char *pinst = *ppinst; - int count = 1; - int op; - - while ((op = *pinst++) != END_EXPRESSION) { - if (op == match && --count == 0) { - *ppinst = pinst; - return 0; - } - switch (op) { - case LITERAL_DOUBLE: - pinst += sizeof(double); - break; - case LITERAL_INT: - pinst += sizeof(epicsInt32); - break; - case MIN: - case MAX: - case FINITE: - case ISNAN: - pinst++; - break; - case COND_IF: - count++; - break; - } - } - return 1; -} diff --git a/src/libCom/calc/postfix.c b/src/libCom/calc/postfix.c deleted file mode 100644 index 463ceea82..000000000 --- a/src/libCom/calc/postfix.c +++ /dev/null @@ -1,626 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Subroutines used to convert an infix expression to a postfix expression - * - * Original Author: Bob Dalesio - * Date: 12-12-86 -*/ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "epicsAssert.h" -#include "epicsStdlib.h" -#include "epicsString.h" -#include "epicsTypes.h" -#include "postfix.h" -#include "postfixPvt.h" -#include "shareLib.h" - - -/* declarations for postfix */ - -/* element types */ -typedef enum { - OPERAND, - LITERAL_OPERAND, - STORE_OPERATOR, - UNARY_OPERATOR, - VARARG_OPERATOR, - BINARY_OPERATOR, - SEPERATOR, - CLOSE_PAREN, - CONDITIONAL, - EXPR_TERMINATOR, -} element_type; - - -/* element table - * - * structure of an element - */ -typedef struct expression_element{ - char *name; /* character representation of an element */ - char in_stack_pri; /* priority on translation stack */ - char in_coming_pri; /* priority in input string */ - signed char runtime_effect; /* stack change, positive means push */ - element_type type; /* element type */ - rpn_opcode code; /* postfix opcode */ -} ELEMENT; - -/* - * NOTE: Keep these lists sorted. Elements are searched in reverse order, - * and where two names start with the same substring we must pick out the - * longest name first (hence the sort requirement). - * NOTE: All VARARG_OPERATORs have to be made known to the calcExprDump() - * routine at the end of this file. - */ -static const ELEMENT operands[] = { -/* name prio's stack element type opcode */ -{"!", 7, 8, 0, UNARY_OPERATOR, REL_NOT}, -{"(", 0, 8, 0, UNARY_OPERATOR, NOT_GENERATED}, -{"-", 7, 8, 0, UNARY_OPERATOR, UNARY_NEG}, -{".", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"0", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"0X", 0, 0, 1, LITERAL_OPERAND,LITERAL_INT}, -{"1", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"2", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"3", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"4", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"5", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"6", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"7", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"8", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"9", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"A", 0, 0, 1, OPERAND, FETCH_A}, -{"ABS", 7, 8, 0, UNARY_OPERATOR, ABS_VAL}, -{"ACOS", 7, 8, 0, UNARY_OPERATOR, ACOS}, -{"ASIN", 7, 8, 0, UNARY_OPERATOR, ASIN}, -{"ATAN", 7, 8, 0, UNARY_OPERATOR, ATAN}, -{"ATAN2", 7, 8, -1, UNARY_OPERATOR, ATAN2}, -{"B", 0, 0, 1, OPERAND, FETCH_B}, -{"C", 0, 0, 1, OPERAND, FETCH_C}, -{"CEIL", 7, 8, 0, UNARY_OPERATOR, CEIL}, -{"COS", 7, 8, 0, UNARY_OPERATOR, COS}, -{"COSH", 7, 8, 0, UNARY_OPERATOR, COSH}, -{"D", 0, 0, 1, OPERAND, FETCH_D}, -{"D2R", 0, 0, 1, OPERAND, CONST_D2R}, -{"E", 0, 0, 1, OPERAND, FETCH_E}, -{"EXP", 7, 8, 0, UNARY_OPERATOR, EXP}, -{"F", 0, 0, 1, OPERAND, FETCH_F}, -{"FINITE", 7, 8, 0, VARARG_OPERATOR,FINITE}, -{"FLOOR", 7, 8, 0, UNARY_OPERATOR, FLOOR}, -{"G", 0, 0, 1, OPERAND, FETCH_G}, -{"H", 0, 0, 1, OPERAND, FETCH_H}, -{"I", 0, 0, 1, OPERAND, FETCH_I}, -{"INF", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"ISINF", 7, 8, 0, UNARY_OPERATOR, ISINF}, -{"ISNAN", 7, 8, 0, VARARG_OPERATOR,ISNAN}, -{"J", 0, 0, 1, OPERAND, FETCH_J}, -{"K", 0, 0, 1, OPERAND, FETCH_K}, -{"L", 0, 0, 1, OPERAND, FETCH_L}, -{"LN", 7, 8, 0, UNARY_OPERATOR, LOG_E}, -{"LOG", 7, 8, 0, UNARY_OPERATOR, LOG_10}, -{"LOGE", 7, 8, 0, UNARY_OPERATOR, LOG_E}, -{"MAX", 7, 8, 0, VARARG_OPERATOR,MAX}, -{"MIN", 7, 8, 0, VARARG_OPERATOR,MIN}, -{"NINT", 7, 8, 0, UNARY_OPERATOR, NINT}, -{"NAN", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"NOT", 7, 8, 0, UNARY_OPERATOR, BIT_NOT}, -{"PI", 0, 0, 1, OPERAND, CONST_PI}, -{"R2D", 0, 0, 1, OPERAND, CONST_R2D}, -{"RNDM", 0, 0, 1, OPERAND, RANDOM}, -{"SIN", 7, 8, 0, UNARY_OPERATOR, SIN}, -{"SINH", 7, 8, 0, UNARY_OPERATOR, SINH}, -{"SQR", 7, 8, 0, UNARY_OPERATOR, SQU_RT}, -{"SQRT", 7, 8, 0, UNARY_OPERATOR, SQU_RT}, -{"TAN", 7, 8, 0, UNARY_OPERATOR, TAN}, -{"TANH", 7, 8, 0, UNARY_OPERATOR, TANH}, -{"VAL", 0, 0, 1, OPERAND, FETCH_VAL}, -{"~", 7, 8, 0, UNARY_OPERATOR, BIT_NOT}, -}; - -static const ELEMENT operators[] = { -/* name prio's stack element type opcode */ -{"!=", 3, 3, -1, BINARY_OPERATOR,NOT_EQ}, -{"#", 3, 3, -1, BINARY_OPERATOR,NOT_EQ}, -{"%", 5, 5, -1, BINARY_OPERATOR,MODULO}, -{"&", 2, 2, -1, BINARY_OPERATOR,BIT_AND}, -{"&&", 2, 2, -1, BINARY_OPERATOR,REL_AND}, -{")", 0, 0, 0, CLOSE_PAREN, NOT_GENERATED}, -{"*", 5, 5, -1, BINARY_OPERATOR,MULT}, -{"**", 6, 6, -1, BINARY_OPERATOR,POWER}, -{"+", 4, 4, -1, BINARY_OPERATOR,ADD}, -{",", 0, 0, 0, SEPERATOR, NOT_GENERATED}, -{"-", 4, 4, -1, BINARY_OPERATOR,SUB}, -{"/", 5, 5, -1, BINARY_OPERATOR,DIV}, -{":", 0, 0, -1, CONDITIONAL, COND_ELSE}, -{":=", 0, 0, -1, STORE_OPERATOR, STORE_A}, -{";", 0, 0, 0, EXPR_TERMINATOR,NOT_GENERATED}, -{"<", 3, 3, -1, BINARY_OPERATOR,LESS_THAN}, -{"<<", 2, 2, -1, BINARY_OPERATOR,LEFT_SHIFT}, -{"<=", 3, 3, -1, BINARY_OPERATOR,LESS_OR_EQ}, -{"=", 3, 3, -1, BINARY_OPERATOR,EQUAL}, -{"==", 3, 3, -1, BINARY_OPERATOR,EQUAL}, -{">", 3, 3, -1, BINARY_OPERATOR,GR_THAN}, -{">=", 3, 3, -1, BINARY_OPERATOR,GR_OR_EQ}, -{">>", 2, 2, -1, BINARY_OPERATOR,RIGHT_SHIFT}, -{"?", 0, 0, -1, CONDITIONAL, COND_IF}, -{"AND", 2, 2, -1, BINARY_OPERATOR,BIT_AND}, -{"OR", 1, 1, -1, BINARY_OPERATOR,BIT_OR}, -{"XOR", 1, 1, -1, BINARY_OPERATOR,BIT_EXCL_OR}, -{"^", 6, 6, -1, BINARY_OPERATOR,POWER}, -{"|", 1, 1, -1, BINARY_OPERATOR,BIT_OR}, -{"||", 1, 1, -1, BINARY_OPERATOR,REL_OR}, -}; - - -/* get_element - * - * find the next expression element in the infix expression - */ -static int - get_element(int opnd, const char **ppsrc, const ELEMENT **ppel) -{ - const ELEMENT *ptable, *pel; - - *ppel = NULL; - - while (isspace((int) (unsigned char) **ppsrc)) ++*ppsrc; - if (**ppsrc == '\0') return FALSE; - - if (opnd) { - ptable = operands; - pel = ptable + NELEMENTS(operands) - 1; - } else { - ptable = operators; - pel = ptable + NELEMENTS(operators) - 1; - } - - while (pel >= ptable) { - size_t len = strlen(pel->name); - - if (epicsStrnCaseCmp(*ppsrc, pel->name, len) == 0) { - *ppel = pel; - *ppsrc += len; - return TRUE; - } - --pel; - } - return FALSE; -} - - -/* postfix - * - * convert an infix expression to a postfix expression - */ -epicsShareFunc long - postfix(const char *psrc, char *pout, short *perror) -{ - ELEMENT stack[80]; - ELEMENT *pstacktop = stack; - const ELEMENT *pel; - int operand_needed = TRUE; - int runtime_depth = 0; - int cond_count = 0; - char * const pdest = pout; - char *pnext; - - if (psrc == NULL || *psrc == '\0' || - pout == NULL || perror == NULL) { - if (perror) *perror = CALC_ERR_NULL_ARG; - if (pout) *pout = END_EXPRESSION; - return -1; - } - - /* place the expression elements into postfix */ - *pout = END_EXPRESSION; - *perror = CALC_ERR_NONE; - - while (get_element(operand_needed, &psrc, &pel)) { - switch (pel->type) { - - case OPERAND: - *pout++ = pel->code; - runtime_depth += pel->runtime_effect; - operand_needed = FALSE; - break; - - case LITERAL_OPERAND: - runtime_depth += pel->runtime_effect; - - psrc -= strlen(pel->name); - if (pel->code == LITERAL_DOUBLE) { - double lit_d; - epicsInt32 lit_i; - - if (epicsParseDouble(psrc, &lit_d, &pnext)) { - *perror = CALC_ERR_BAD_LITERAL; - goto bad; - } - psrc = pnext; - lit_i = (epicsInt32) lit_d; - if (lit_d != (double) lit_i) { - *pout++ = pel->code; - memcpy(pout, &lit_d, sizeof(double)); - pout += sizeof(double); - } else { - *pout++ = LITERAL_INT; - memcpy(pout, &lit_i, sizeof(epicsInt32)); - pout += sizeof(epicsInt32); - } - } - else { - epicsUInt32 lit_ui; - - assert(pel->code == LITERAL_INT); - if (epicsParseUInt32(psrc, &lit_ui, 0, &pnext)) { - *perror = CALC_ERR_BAD_LITERAL; - goto bad; - } - psrc = pnext; - *pout++ = LITERAL_INT; - memcpy(pout, &lit_ui, sizeof(epicsUInt32)); - pout += sizeof(epicsUInt32); - } - - operand_needed = FALSE; - break; - - case STORE_OPERATOR: - if (pout == pdest || pstacktop > stack || - *--pout < FETCH_A || *pout > FETCH_L) { - *perror = CALC_ERR_BAD_ASSIGNMENT; - goto bad; - } - /* Convert fetch into a store on the stack */ - *++pstacktop = *pel; - pstacktop->code = STORE_A + *pout - FETCH_A; - runtime_depth -= 1; - operand_needed = TRUE; - break; - - case UNARY_OPERATOR: - case VARARG_OPERATOR: - /* Move operators of >= priority to the output */ - while ((pstacktop > stack) && - (pstacktop->in_stack_pri >= pel->in_coming_pri)) { - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - - /* Push new operator onto stack */ - pstacktop++; - *pstacktop = *pel; - break; - - case BINARY_OPERATOR: - /* Move operators of >= priority to the output */ - while ((pstacktop > stack) && - (pstacktop->in_stack_pri >= pel->in_coming_pri)) { - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - - /* Push new operator onto stack */ - pstacktop++; - *pstacktop = *pel; - - operand_needed = TRUE; - break; - - case SEPERATOR: - /* Move operators to the output until open paren */ - while (pstacktop->name[0] != '(') { - if (pstacktop <= stack+1) { - *perror = CALC_ERR_BAD_SEPERATOR; - goto bad; - } - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - operand_needed = TRUE; - pstacktop->runtime_effect -= 1; - break; - - case CLOSE_PAREN: - /* Move operators to the output until matching paren */ - while (pstacktop->name[0] != '(') { - if (pstacktop <= stack+1) { - *perror = CALC_ERR_PAREN_NOT_OPEN; - goto bad; - } - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - pstacktop--; /* remove ( from stack */ - /* if there is a vararg operator before the opening paren, - it inherits the (opening) paren's stack effect */ - if ((pstacktop > stack) && - pstacktop->type == VARARG_OPERATOR) { - pstacktop->runtime_effect = (pstacktop+1)->runtime_effect; - /* check for no arguments */ - if (pstacktop->runtime_effect > 0) { - *perror = CALC_ERR_INCOMPLETE; - goto bad; - } - } - break; - - case CONDITIONAL: - /* Move operators of > priority to the output */ - while ((pstacktop > stack) && - (pstacktop->in_stack_pri > pel->in_coming_pri)) { - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - - /* Add new element to the output */ - *pout++ = pel->code; - runtime_depth += pel->runtime_effect; - - /* For : operator, also push COND_END code to stack */ - if (pel->name[0] == ':') { - if (--cond_count < 0) { - *perror = CALC_ERR_CONDITIONAL; - goto bad; - } - pstacktop++; - *pstacktop = *pel; - pstacktop->code = COND_END; - pstacktop->runtime_effect = 0; - } else { - cond_count++; - } - - operand_needed = TRUE; - break; - - case EXPR_TERMINATOR: - /* Move everything from stack to the output */ - while (pstacktop > stack) { - if (pstacktop->name[0] == '(') { - *perror = CALC_ERR_PAREN_OPEN; - goto bad; - } - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - - if (cond_count != 0) { - *perror = CALC_ERR_CONDITIONAL; - goto bad; - } - if (runtime_depth > 1) { - *perror = CALC_ERR_TOOMANY; - goto bad; - } - - operand_needed = TRUE; - break; - - default: - *perror = CALC_ERR_INTERNAL; - goto bad; - } - - if (runtime_depth < 0) { - *perror = CALC_ERR_UNDERFLOW; - goto bad; - } - if (runtime_depth >= CALCPERFORM_STACK) { - *perror = CALC_ERR_OVERFLOW; - goto bad; - } - } - - if (*psrc != '\0') { - *perror = CALC_ERR_SYNTAX; - goto bad; - } - - /* Move everything from stack to the output */ - while (pstacktop > stack) { - if (pstacktop->name[0] == '(') { - *perror = CALC_ERR_PAREN_OPEN; - goto bad; - } - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - *pout = END_EXPRESSION; - - if (cond_count != 0) { - *perror = CALC_ERR_CONDITIONAL; - goto bad; - } - if (operand_needed || runtime_depth != 1) { - *perror = CALC_ERR_INCOMPLETE; - goto bad; - } - return 0; - -bad: - *pdest = END_EXPRESSION; - return -1; -} - - -/* calcErrorStr - * - * Return a message string appropriate for the given error code - */ -epicsShareFunc const char * - calcErrorStr(short error) -{ - static const char *errStrs[] = { - "No error", - "Too many results returned", - "Badly formed numeric literal", - "Bad assignment target", - "Comma without enclosing parentheses", - "Close parenthesis found without open", - "Parenthesis still open at end of expression", - "Unbalanced conditional ?: operators", - "Incomplete expression, operand missing", - "Not enough operands provided", - "Runtime stack overflow", - "Syntax error, unknown operator/operand", - "NULL or empty input argument to postfix()", - "Internal error, unknown element type", - }; - - if (error < CALC_ERR_NONE || error > CALC_ERR_INTERNAL) - return NULL; - return errStrs[error]; -} - - -/* calcExprDump - * - * Disassemble the given postfix instructions to stdout - */ -epicsShareFunc void - calcExprDump(const char *pinst) -{ - static const char *opcodes[] = { - "End Expression", - /* Operands */ - "LITERAL_DOUBLE", "LITERAL_INT", "VAL", - "FETCH_A", "FETCH_B", "FETCH_C", "FETCH_D", "FETCH_E", "FETCH_F", - "FETCH_G", "FETCH_H", "FETCH_I", "FETCH_J", "FETCH_K", "FETCH_L", - /* Assignment */ - "STORE_A", "STORE_B", "STORE_C", "STORE_D", "STORE_E", "STORE_F", - "STORE_G", "STORE_H", "STORE_I", "STORE_J", "STORE_K", "STORE_L", - /* Trigonometry Constants */ - "CONST_PI", - "CONST_D2R", - "CONST_R2D", - /* Arithmetic */ - "UNARY_NEG", - "ADD", - "SUB", - "MULT", - "DIV", - "MODULO", - "POWER", - /* Algebraic */ - "ABS_VAL", - "EXP", - "LOG_10", - "LOG_E", - "MAX", - "MIN", - "SQU_RT", - /* Trigonometric */ - "ACOS", - "ASIN", - "ATAN", - "ATAN2", - "COS", - "COSH", - "SIN", - "SINH", - "TAN", - "TANH", - /* Numeric */ - "CEIL", - "FLOOR", - "FINITE", - "ISINF", - "ISNAN", - "NINT", - "RANDOM", - /* Boolean */ - "REL_OR", - "REL_AND", - "REL_NOT", - /* Bitwise */ - "BIT_OR", - "BIT_AND", - "BIT_EXCL_OR", - "BIT_NOT", - "RIGHT_SHIFT", - "LEFT_SHIFT", - /* Relationals */ - "NOT_EQ", - "LESS_THAN", - "LESS_OR_EQ", - "EQUAL", - "GR_OR_EQ", - "GR_THAN", - /* Conditional */ - "COND_IF", - "COND_ELSE", - "COND_END", - /* Misc */ - "NOT_GENERATED" - }; - char op; - double lit_d; - epicsInt32 lit_i; - - while ((op = *pinst) != END_EXPRESSION) { - switch (op) { - case LITERAL_DOUBLE: - memcpy(&lit_d, ++pinst, sizeof(double)); - printf("\tDouble %g\n", lit_d); - pinst += sizeof(double); - break; - case LITERAL_INT: - memcpy(&lit_i, ++pinst, sizeof(epicsInt32)); - printf("\tInteger %d (0x%x)\n", lit_i, lit_i); - pinst += sizeof(epicsInt32); - break; - case MIN: - case MAX: - case FINITE: - case ISNAN: - printf("\t%s, %d arg(s)\n", opcodes[(int) op], *++pinst); - pinst++; - break; - default: - printf("\t%s\n", opcodes[(int) op]); - pinst++; - } - } -} diff --git a/src/libCom/calc/postfix.h b/src/libCom/calc/postfix.h deleted file mode 100644 index b90492012..000000000 --- a/src/libCom/calc/postfix.h +++ /dev/null @@ -1,89 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* postfix.h - * Original Author: Bob Dalesio - * Date: 9-21-88 - */ - -#ifndef INCpostfixh -#define INCpostfixh - -#include "shareLib.h" - -#define CALCPERFORM_NARGS 12 -#define CALCPERFORM_STACK 80 - -#define INFIX_TO_POSTFIX_SIZE(n) ((n)*21/6) -/* The above expression is an estimate of the maximum postfix buffer - * size needed for a given infix expression buffer (the argument must count - * the trailing nil byte in the input expression string). The actual size - * needed is never larger than this value, although it is actually a - * few bytes smaller for some sizes. - * - * The maximum expansion from infix to postfix is for the sub-expression - * .1?.1: - * which is 6 characters long and results in 21 bytes of postfix: - * .1 => LITERAL_DOUBLE + 8 byte value - * ? => COND_IF - * .1 => LITERAL_DOUBLE + 8 byte value - * : => COND_ELSE - * ... - * => COND_END - * For other short expressions the factor 21/6 always gives a big enough - * postfix buffer (proven by hand, look at '1+' and '.1+' as well). - */ - -/* These are not hard limits, just default sizes for the database */ -#define MAX_INFIX_SIZE 100 -#define MAX_POSTFIX_SIZE INFIX_TO_POSTFIX_SIZE(MAX_INFIX_SIZE) - - -/* Error numbers from postfix */ - -#define CALC_ERR_NONE 0 /* No error */ -#define CALC_ERR_TOOMANY 1 /* Too many results returned */ -#define CALC_ERR_BAD_LITERAL 2 /* Bad numeric literal */ -#define CALC_ERR_BAD_ASSIGNMENT 3 /* Bad assignment target */ -#define CALC_ERR_BAD_SEPERATOR 4 /* Comma without parentheses */ -#define CALC_ERR_PAREN_NOT_OPEN 5 /* Close parenthesis without open */ -#define CALC_ERR_PAREN_OPEN 6 /* Open parenthesis at end of expression */ -#define CALC_ERR_CONDITIONAL 7 /* Unbalanced conditional ?: operators */ -#define CALC_ERR_INCOMPLETE 8 /* Incomplete expression, operand missing */ -#define CALC_ERR_UNDERFLOW 9 /* Runtime stack would underflow */ -#define CALC_ERR_OVERFLOW 10 /* Runtime stack would overflow */ -#define CALC_ERR_SYNTAX 11 /* Syntax error */ -#define CALC_ERR_NULL_ARG 12 /* NULL or empty input argument */ -#define CALC_ERR_INTERNAL 13 /* Internal error, bad element type */ -/* Changes in the above errors must also be made in calcErrorStr() */ - - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc long - postfix(const char *pinfix, char *ppostfix, short *perror); - -epicsShareFunc long - calcPerform(double *parg, double *presult, const char *ppostfix); - -epicsShareFunc long - calcArgUsage(const char *ppostfix, unsigned long *pinputs, unsigned long *pstores); - -epicsShareFunc const char * - calcErrorStr(short error); - -epicsShareFunc void - calcExprDump(const char *pinst); - -#ifdef __cplusplus -} -#endif - -#endif /* INCpostfixh */ diff --git a/src/libCom/calc/postfixPvt.h b/src/libCom/calc/postfixPvt.h deleted file mode 100644 index 53efb32e0..000000000 --- a/src/libCom/calc/postfixPvt.h +++ /dev/null @@ -1,104 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* postfixPvt.h - * Original Author: Bob Dalesio - * Date: 9-21-88 - */ - -/* Notes: - * 1. The FETCH_A through FETCH_L and STORE_A through STORE_L opcodes must - * be contiguous. - * 2. The LITERAL opcodes are followed by a binary representation of their - * values, but these are not aligned properly. - * 3. The var-arg functions MIN, MAX, FINITE and ISNAN are followed by - * a byte giving the number of arguments to process. - * 4. You can't use strlen() on an RPN buffer since the literal values - * can contain zero bytes. - */ - -#ifndef INCpostfixPvth -#define INCpostfixPvth - - -/* RPN opcodes */ -typedef enum { - END_EXPRESSION = 0, - /* Operands */ - LITERAL_DOUBLE, LITERAL_INT, FETCH_VAL, - FETCH_A, FETCH_B, FETCH_C, FETCH_D, FETCH_E, FETCH_F, - FETCH_G, FETCH_H, FETCH_I, FETCH_J, FETCH_K, FETCH_L, - /* Assignment */ - STORE_A, STORE_B, STORE_C, STORE_D, STORE_E, STORE_F, - STORE_G, STORE_H, STORE_I, STORE_J, STORE_K, STORE_L, - /* Trigonometry Constants */ - CONST_PI, - CONST_D2R, - CONST_R2D, - /* Arithmetic */ - UNARY_NEG, - ADD, - SUB, - MULT, - DIV, - MODULO, - POWER, - /* Algebraic */ - ABS_VAL, - EXP, - LOG_10, - LOG_E, - MAX, - MIN, - SQU_RT, - /* Trigonometric */ - ACOS, - ASIN, - ATAN, - ATAN2, - COS, - COSH, - SIN, - SINH, - TAN, - TANH, - /* Numeric */ - CEIL, - FLOOR, - FINITE, - ISINF, - ISNAN, - NINT, - RANDOM, - /* Boolean */ - REL_OR, - REL_AND, - REL_NOT, - /* Bitwise */ - BIT_OR, - BIT_AND, - BIT_EXCL_OR, - BIT_NOT, - RIGHT_SHIFT, - LEFT_SHIFT, - /* Relationals */ - NOT_EQ, - LESS_THAN, - LESS_OR_EQ, - EQUAL, - GR_OR_EQ, - GR_THAN, - /* Conditional */ - COND_IF, - COND_ELSE, - COND_END, - /* Misc */ - NOT_GENERATED -} rpn_opcode; - -#endif /* INCpostfixPvth */ diff --git a/src/libCom/cppStd/Makefile b/src/libCom/cppStd/Makefile deleted file mode 100644 index 782c4da25..000000000 --- a/src/libCom/cppStd/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/cppStd -INC += epicsAlgorithm.h -INC += epicsExcept.h - diff --git a/src/libCom/cppStd/epicsAlgorithm.h b/src/libCom/cppStd/epicsAlgorithm.h deleted file mode 100644 index 20850242d..000000000 --- a/src/libCom/cppStd/epicsAlgorithm.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// epicsAlgorithm.h -// Authors: Jeff Hill & Andrew Johnson - -#ifndef __EPICS_ALGORITHM_H__ -#define __EPICS_ALGORITHM_H__ - -#include "epicsMath.h" - -// The C++ standard only requires types to be less-than comparable, so -// the epicsMin and epicsMax templates only use operator < - -// epicsMin - -template -inline const T& epicsMin (const T& a, const T& b) -{ - return (b < a) ? b : a; -} - -// If b is a NaN the above template returns a, but should return NaN. -// These specializations ensure that epicsMin(x,NaN) == NaN - -template <> -inline const float& epicsMin (const float& a, const float& b) -{ - return (b < a) || isnan(b) ? b : a; -} - -template <> -inline const double& epicsMin (const double& a, const double& b) -{ - return (b < a) || isnan(b) ? b : a; -} - - -// epicsMax - -template -inline const T& epicsMax (const T& a, const T& b) -{ - return (a < b) ? b : a; -} - -// If b is a NaN the above template returns a, but should return NaN. -// These specializations ensure that epicsMax(x,NaN) == NaN - -template <> -inline const float& epicsMax (const float& a, const float& b) -{ - return (a < b) || isnan(b) ? b : a; -} - -template <> -inline const double& epicsMax (const double& a, const double& b) -{ - return (a < b) || isnan(b) ? b : a; -} - - -// epicsSwap - -template -inline void epicsSwap(T& a, T& b) -{ - T temp = a; - a = b; - b = temp; -} - -#endif // __EPICS_ALGORITHM_H__ diff --git a/src/libCom/cppStd/epicsExcept.h b/src/libCom/cppStd/epicsExcept.h deleted file mode 100644 index e68999735..000000000 --- a/src/libCom/cppStd/epicsExcept.h +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// Author: Andrew Johnson & Jeff Hill -// Date: December 2000 - -#ifndef __EPICS_EXCEPT_H__ -#define __EPICS_EXCEPT_H__ - -#define epicsThrowHere(exc) \ - throw locationException(exc, __FILE__, __LINE__) - -class sourceLocation { -public: // Functions - sourceLocation(const char *fileName, int lineNumber); -// sourceLocation(const sourceLocation&); Copy constructable -// sourceLocation& operator=(const sourceLocation&); Assignable - - const char *fileName() const; - int lineNumber() const; - -private: // Hide compiler-generated member functions - sourceLocation(); // default constructor - -private: // Data - const char *file; - int line; -}; - -template -class locationException : public T, public sourceLocation { -public: - locationException(const T& exc, const char *fileName, int lineNumber); -}; - - -/* Example: - * if (status) epicsThrowHere(std::logic_error("operation failed!")); - * try { ... } catch(sourceLocation& where) { ... } - */ - -// END OF DECLARATIONS - -// INLINE FUNCTIONS - -// sourceFileLocation -inline sourceLocation::sourceLocation (const char *fileName, int lineNumber) : - file(fileName), line(lineNumber) {} - -inline const char* sourceLocation::fileName () const { - return this->file; -} - -inline int sourceLocation::lineNumber () const { - return this->line; -} - -// locationException -template -inline locationException::locationException - (const char *fileName, int lineNumber, const E& exc) : - T(exc), sourceLocation(fileName, lineNumber) {} - - -#endif // __EPICS_EXCEPT_H__ diff --git a/src/libCom/cvtFast/Makefile b/src/libCom/cvtFast/Makefile deleted file mode 100644 index 473693c83..000000000 --- a/src/libCom/cvtFast/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/cvtFast -INC += cvtFast.h -Com_SRCS += cvtFast.c - diff --git a/src/libCom/cvtFast/cvtFast.c b/src/libCom/cvtFast/cvtFast.c deleted file mode 100644 index 4e04b4515..000000000 --- a/src/libCom/cvtFast/cvtFast.c +++ /dev/null @@ -1,523 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Fast numeric to string conversions - * - * Original Authors: - * Bob Dalesio, Mark Anderson and Marty Kraimer - * Date: 12 January 1993 - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "cvtFast.h" -#include "epicsMath.h" -#include "epicsStdio.h" - -/* - * These routines convert numbers up to +/- 10,000,000. - * They defer to sprintf() for numbers requiring more than - * 8 places of precision. - */ -static epicsInt32 frac_multiplier[] = - {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000}; - -int cvtFloatToString(float flt_value, char *pdest, - epicsUInt16 precision) -{ - int got_one, i; - epicsInt32 whole, iplace, number, fraction, fplace; - float ftemp; - char *startAddr; - - /* can this routine handle this conversion */ - if (isnan(flt_value) || precision > 8 || - flt_value > 10000000.0 || flt_value < -10000000.0) { - if (precision > 8 || flt_value >= 1e8 || flt_value <= -1e8) { - if (precision > 12) precision = 12; /* FIXME */ - sprintf(pdest, "%*.*e", precision+6, precision, (double) flt_value); - } else { - if (precision > 3) precision = 3; /* FIXME */ - sprintf(pdest, "%.*f", precision, (double) flt_value); - } - return((int)strlen(pdest)); - } - startAddr = pdest; - - /* determine the sign */ - if (flt_value < 0){ - *pdest++ = '-'; - flt_value = -flt_value; - }; - - /* remove the whole number portion */ - whole = (epicsInt32)flt_value; - ftemp = flt_value - whole; - - /* multiplier to convert fractional portion to integer */ - fplace = frac_multiplier[precision]; - fraction = (epicsInt32)(ftemp * fplace * 10); - fraction = (fraction + 5) / 10; /* round up */ - - /* determine rounding into the whole number portion */ - if ((fraction / fplace) >= 1){ - whole++; - fraction -= fplace; - } - - /* whole numbers */ - got_one = 0; - for (iplace = 10000000; iplace >= 1; iplace /= 10){ - if (whole >= iplace){ - got_one = 1; - number = whole / iplace; - whole = whole - (number * iplace); - *pdest = number + '0'; - pdest++; - }else if (got_one){ - *pdest = '0'; - pdest++; - } - } - if (!got_one){ - *pdest = '0'; - pdest++; - } - - /* fraction */ - if (precision > 0){ - /* convert fractional portional to ASCII */ - *pdest = '.'; - pdest++; - for (fplace /= 10, i = precision; i > 0; fplace /= 10,i--){ - number = fraction / fplace; - fraction -= number * fplace; - *pdest = number + '0'; - pdest++; - } - } - *pdest = 0; - - return((int)(pdest - startAddr)); -} - -int cvtDoubleToString( - double flt_value, - char *pdest, - epicsUInt16 precision) -{ - epicsUInt16 got_one,i; - epicsInt32 whole,iplace,number,fraction,fplace; - double ftemp; - char *startAddr; - - /* can this routine handle this conversion */ - if (isnan(flt_value) || precision > 8 || flt_value > 10000000.0 || flt_value < -10000000.0) { - if (precision > 8 || flt_value > 1e16 || flt_value < -1e16) { - if(precision>17) precision=17; - sprintf(pdest,"%*.*e",precision+7,precision, - flt_value); - } else { - if(precision>3) precision=3; - sprintf(pdest,"%.*f",precision,flt_value); - } - return((int)strlen(pdest)); - } - startAddr = pdest; - - /* determine the sign */ - if (flt_value < 0){ - *pdest++ = '-'; - flt_value = -flt_value; - }; - - /* remove the whole number portion */ - whole = (epicsInt32)flt_value; - ftemp = flt_value - whole; - - /* multiplier to convert fractional portion to integer */ - fplace = frac_multiplier[precision]; - fraction = (epicsInt32)(ftemp * fplace * 10); - fraction = (fraction + 5) / 10; /* round up */ - - /* determine rounding into the whole number portion */ - if ((fraction / fplace) >= 1){ - whole++; - fraction -= fplace; - } - - /* whole numbers */ - got_one = 0; - for (iplace = 10000000; iplace >= 1; iplace /= 10){ - if (whole >= iplace){ - got_one = 1; - number = whole / iplace; - whole = whole - (number * iplace); - *pdest = number + '0'; - pdest++; - }else if (got_one){ - *pdest = '0'; - pdest++; - } - } - if (!got_one){ - *pdest = '0'; - pdest++; - } - - /* fraction */ - if (precision > 0){ - /* convert fractional portional to ASCII */ - *pdest = '.'; - pdest++; - for (fplace /= 10, i = precision; i > 0; fplace /= 10,i--){ - number = fraction / fplace; - fraction -= number * fplace; - *pdest = number + '0'; - pdest++; - } - } - *pdest = 0; - - return((int)(pdest - startAddr)); -} - -/* - * These routines are provided for backwards compatibility, - * extensions such as MEDM, edm and histtool use them. - */ - -/* - * cvtFloatToExpString - * - * Converts a float to a %e formatted string - */ -int cvtFloatToExpString(float val, char *pdest, epicsUInt16 precision) -{ - return epicsSnprintf(pdest, MAX_STRING_SIZE, "%.*e", precision, val); -} - -/* - * cvtFloatToCompactString - * - * Converts a float to a %g formatted string. - * The result uses %f notation for 10e-4 < |value| < 10e+4, - * otherwise %e notation. - */ -int cvtFloatToCompactString(float val, char *pdest, epicsUInt16 precision) -{ - if ((val < 1.e4 && val > 1.e-4) || - (val > -1.e4 && val < -1.e-4) || - val == 0.0) - return cvtFloatToString(val, pdest, precision); - - return cvtFloatToExpString(val, pdest, precision); -} - - -/* - * cvtDoubleToExpString - * - * Converts a double to a %e formatted string - */ - -int cvtDoubleToExpString(double val, char *pdest, epicsUInt16 precision) -{ - return epicsSnprintf(pdest, MAX_STRING_SIZE, "%.*e", precision, val); -} - - -/* - * cvtDoubleToCompactString - * - * Converts a double to %g formatted string. - * The result uses %f notation for 10e-4 < |value| < 10e+4, - * otherwise %e notation. - */ -int cvtDoubleToCompactString(double val, char *pdest, epicsUInt16 precision) -{ - if ((val < 1.e4 && val > 1.e-4) || - (val > -1.e4 && val < -1.e-4) || - val == 0.0) - return cvtDoubleToString(val, pdest, precision); - - return cvtDoubleToExpString(val, pdest, precision); -} - - -/* Integer conversion primitives */ - -static size_t - UInt32ToDec(epicsUInt32 val, char *pdest) -{ - int i; - char digit[10]; - size_t len; - - for (i = 0; val; i++) { - epicsUInt32 tenth = val / 10; - - digit[i] = val - tenth * 10 + '0'; - val = tenth; - } - len = i; - - while (i > 0) - *pdest++ = digit[--i]; - - *pdest = 0; - return len; -} - -static size_t - UInt32ToBase(epicsUInt32 val, char *pdest, int base) -{ - int i; - char digit, digits[32]; - size_t len; - - for (i = 0; val; i++) { - epicsUInt32 tenth = val / base; - - digit = val - tenth * base; - digits[i] = digit < 10 ? digit + '0' : digit - 10 + 'a'; - val = tenth; - } - len = i; - - while (i > 0) - *pdest++ = digits[--i]; - - *pdest = 0; - return len; -} - -static size_t - UInt64ToDec(epicsUInt64 val, char *pdest) -{ - int i; - char digit[20]; - size_t len; - - for (i = 0; val; i++) { - epicsUInt64 tenth = val / 10; - - digit[i] = val - tenth * 10 + '0'; - val = tenth; - } - - len = i; - while (i > 0) - *pdest++ = digit[--i]; - - *pdest = 0; - return len; -} - -static size_t - UInt64ToBase(epicsUInt64 val, char *pdest, int base) -{ - int i; - char digit, digits[64]; - size_t len; - - for (i = 0; val; i++) { - epicsUInt64 tenth = val / base; - - digit = val - tenth * base; - digits[i] = digit < 10 ? digit + '0' : digit - 10 + 'a'; - val = tenth; - } - len = i; - - while (i > 0) - *pdest++ = digits[--i]; - - *pdest = 0; - return len; -} - - -/* Integer conversion routines */ - -size_t - cvtUInt32ToString(epicsUInt32 val, char *pdest) -{ - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 1; - } - - return UInt32ToDec(val, pdest); -} - -size_t - cvtInt32ToString(epicsInt32 val, char *pdest) -{ - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 1; - } - - if (val > 0) - return UInt32ToDec(val, pdest); - - if (val == -0x80000000) { - strcpy(pdest, "-2147483648"); - return strlen(pdest); - } - - *pdest++ = '-'; - return 1 + UInt32ToDec(-val, pdest); -} - - -size_t - cvtUInt64ToString(epicsUInt64 val, char *pdest) -{ - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 1; - } - - return UInt64ToDec(val, pdest); -} - -size_t - cvtInt64ToString(epicsInt64 val, char *pdest) -{ - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 1; - } - - if (val > 0) - return UInt64ToDec(val, pdest); - - if (val == -0x8000000000000000LL) { - strcpy(pdest, "-9223372036854775808"); - return strlen(pdest); - } - - *pdest++ = '-'; - return 1 + UInt64ToDec(-val, pdest); -} - - -size_t - cvtInt32ToHexString(epicsInt32 val, char *pdest) -{ - if (val < 0) - *pdest++ = '-'; - - *pdest++ = '0'; - *pdest++ = 'x'; - - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 3; - } - - if (val > 0) - return 2 + UInt32ToBase(val, pdest, 16); - - if (val == -0x80000000) { - strcpy(pdest, "80000000"); - return 11; - } - - return 3 + UInt32ToBase(-val, pdest, 16); -} - -size_t - cvtUInt32ToHexString(epicsUInt32 val, char *pdest) -{ - *pdest++ = '0'; - *pdest++ = 'x'; - - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 3; - } - - return 2 + UInt32ToBase(val, pdest, 16); -} - -size_t - cvtInt32OctalString(epicsInt32 val, char *pdest) -{ - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 1; - } - - if (val > 0) { - *pdest++ = '0'; - return 1 + UInt32ToBase(val, pdest, 8); - } - - if (val == -0x80000000) { - strcpy(pdest, "-020000000000"); - return strlen(pdest); - } - - *pdest++ = '-'; - *pdest++ = '0'; - return 2 + UInt32ToBase(-val, pdest, 8); -} - -size_t - cvtInt64ToHexString(epicsInt64 val, char *pdest) -{ - if (val < 0) - *pdest++ = '-'; - - *pdest++ = '0'; - *pdest++ = 'x'; - - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 3; - } - - if (val > 0) - return 2 + UInt64ToBase(val, pdest, 16); - - if (val == -0x8000000000000000LL) { - strcpy(pdest, "8000000000000000"); - return 19; - } - - return 3 + UInt64ToBase(-val, pdest, 16); -} - -size_t - cvtUInt64ToHexString(epicsUInt64 val, char *pdest) -{ - *pdest++ = '0'; - *pdest++ = 'x'; - - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 3; - } - - return 2 + UInt64ToBase(val, pdest, 16); -} - diff --git a/src/libCom/cvtFast/cvtFast.h b/src/libCom/cvtFast/cvtFast.h deleted file mode 100644 index db06dda53..000000000 --- a/src/libCom/cvtFast/cvtFast.h +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Fast numeric to string conversions - * - * Original Authors: - * Bob Dalesio, Mark Anderson and Marty Kraimer - * Date: 12 January 1993 - */ - -#ifndef INCcvtFasth -#define INCcvtFasth - -#include - -#include "epicsTypes.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * All functions return the number of characters in the output - */ -epicsShareFunc int - cvtFloatToString(float val, char *pdest, epicsUInt16 prec); -epicsShareFunc int - cvtDoubleToString(double val, char *pdest, epicsUInt16 prec); - -epicsShareFunc int - cvtFloatToExpString(float val, char *pdest, epicsUInt16 prec); -epicsShareFunc int - cvtDoubleToExpString(double val, char *pdest, epicsUInt16 prec); -epicsShareFunc int - cvtFloatToCompactString(float val, char *pdest, epicsUInt16 prec); -epicsShareFunc int - cvtDoubleToCompactString(double val, char *pdest, epicsUInt16 prec); - -epicsShareFunc size_t - cvtInt32ToString(epicsInt32 val, char *pdest); -epicsShareFunc size_t - cvtUInt32ToString(epicsUInt32 val, char *pdest); -epicsShareFunc size_t - cvtInt64ToString(epicsInt64 val, char *pdest); -epicsShareFunc size_t - cvtUInt64ToString(epicsUInt64 val, char *pdest); - -epicsShareFunc size_t - cvtInt32ToHexString(epicsInt32 val, char *pdest); -epicsShareFunc size_t - cvtUInt32ToHexString(epicsUInt32 val, char *pdest); -epicsShareFunc size_t - cvtInt32ToOctalString(epicsInt32 val, char *pdest); -epicsShareFunc size_t - cvtInt64ToHexString(epicsInt64 val, char *pdest); -epicsShareFunc size_t - cvtUInt64ToHexString(epicsUInt64 val, char *pdest); - -/* Support the original names */ - -#define cvtCharToString(val, str) cvtInt32ToString(val, str) -#define cvtUcharToString(val, str) cvtUInt32ToString(val, str) -#define cvtShortToString(val, str) cvtInt32ToString(val, str) -#define cvtUshortToString(val, str) cvtUInt32ToString(val, str) -#define cvtLongToString(val, str) cvtInt32ToString(val, str) -#define cvtUlongToString(val, str) cvtUInt32ToString(val, str) - -#define cvtLongToHexString(val, str) cvtInt32ToHexString(val, str) -#define cvtULongToHexString(val, str) cvtUInt32ToHexString(val, str) -#define cvtLongToOctalString(val, str) cvtInt32ToOctalString(val, str) - -#ifdef __cplusplus -} -#endif - -#endif /*INCcvtFasth*/ diff --git a/src/libCom/cxxTemplates/Makefile b/src/libCom/cxxTemplates/Makefile deleted file mode 100644 index c67668f55..000000000 --- a/src/libCom/cxxTemplates/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/cxxTemplates -INC += resourceLib.h -INC += tsDLList.h -INC += tsSLList.h -INC += tsMinMax.h -INC += tsFreeList.h -INC += epicsSingleton.h -INC += epicsGuard.h -Com_SRCS += resourceLib.cpp -Com_SRCS += epicsSingletonMutex.cpp - diff --git a/src/libCom/cxxTemplates/README b/src/libCom/cxxTemplates/README deleted file mode 100644 index 786c598b3..000000000 --- a/src/libCom/cxxTemplates/README +++ /dev/null @@ -1,35 +0,0 @@ - -C++ templates: -tsSLList.h - type safe single linked list template -tsDLList.h - type safe double linked list template -resourceLib.h - hash table template -tsFreeeList.h - free list allocator / deallocator - -the test subdir contains examples - -Since I am using templates the linked lists are type safe -(no casting of pointers ala ellList and dllList). -Also, the node class in embedded in the item on the -list (more efficient use of pool). - -The file resourceLib.h provides a core hashing library -"resTable " where "itemClass" objects -are stored in the hash table and "idClass" is the data type -of the key for the hash table. The identifier class provides -the hash alg. I have provided simple string "stringId" and -unsigned integer "uintId" key types in resourceLib.h. It -is easy to implement a new key class. - -There are examples under cxxTemplate/test. The list/hashing -templates all depend on a particular inheritance hierarchy. -If the inheritance hierarchy is wrong nothing will compile. -For instance, in tsDLList.h the template data type "T" -must derive from tsDLNode. Likewise, in tsSLList.h -"T" must derive from tsSLNode. Likewise, in resourceLib.h -class "T" (the type stored in the hash table) must derive -from class "ID" (the hash table key type) and also derive from -tsSLNode. - - - - diff --git a/src/libCom/cxxTemplates/epicsGuard.h b/src/libCom/cxxTemplates/epicsGuard.h deleted file mode 100644 index f0aa401a5..000000000 --- a/src/libCom/cxxTemplates/epicsGuard.h +++ /dev/null @@ -1,114 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsGuardh -#define epicsGuardh - -#ifndef assert // allow use of epicsAssert.h -# include -#endif - -/* - * Author: Jeffrey O. Hill - */ - -template < class T > class epicsGuardRelease; - -// Automatically applies and releases the mutex. -// This class is also useful in situations where -// C++ exceptions are possible. -template < class T > -class epicsGuard { -public: - typedef epicsGuardRelease release_t; - epicsGuard ( T & ); - void assertIdenticalMutex ( const T & ) const; - ~epicsGuard (); -private: - T * _pTargetMutex; - epicsGuard ( const epicsGuard & ); - epicsGuard & operator = ( const epicsGuard & ); - friend class epicsGuardRelease < T >; -}; - -// Automatically releases and reapplies the mutex. -// This class is also useful in situations where -// C++ exceptions are possible. -template < class T > -class epicsGuardRelease { -public: - typedef epicsGuard guard_t; - epicsGuardRelease ( epicsGuard < T > & ); - ~epicsGuardRelease (); -private: - epicsGuard < T > & _guard; - T * _pTargetMutex; - epicsGuardRelease ( const epicsGuardRelease & ); - epicsGuardRelease & operator = ( const epicsGuardRelease & ); -}; - -// same interface as epicsMutex -class epicsMutexNOOP { -public: - void lock (); - bool tryLock (); - void unlock (); - void show ( unsigned level ) const; -}; - -template < class T > -inline epicsGuard < T > :: epicsGuard ( T & mutexIn ) : - _pTargetMutex ( & mutexIn ) -{ - _pTargetMutex->lock (); -} - -template < class T > -inline epicsGuard < T > :: ~epicsGuard () -{ - _pTargetMutex->unlock (); -} - -template < class T > -inline void epicsGuard < T > :: assertIdenticalMutex ( - const T & mutexToVerify ) const -{ - assert ( _pTargetMutex == & mutexToVerify ); -} - -template < class T > -inline epicsGuardRelease < T > :: - epicsGuardRelease ( epicsGuard & guardIn ) : - _guard ( guardIn ), - _pTargetMutex ( guardIn._pTargetMutex ) -{ - // Setting the guard's _pTargetMutex to nill will - // allow assertIdenticalMutex to catch situations - // where a guard is being used and it has been - // released, and also situations where ~epicsGuard () - // runs and an epicsGuardRelease is still referencing - // the guard will be detected. - _guard._pTargetMutex = 0; - _pTargetMutex->unlock (); -} - -template < class T > -inline epicsGuardRelease < T > :: ~epicsGuardRelease () -{ - _pTargetMutex->lock (); - _guard._pTargetMutex = _pTargetMutex; -} - -inline void epicsMutexNOOP::lock () {} -inline bool epicsMutexNOOP::tryLock () { return true; } -inline void epicsMutexNOOP::unlock () {} -inline void epicsMutexNOOP::show ( unsigned ) const {} - -#endif // epicsGuardh diff --git a/src/libCom/cxxTemplates/epicsSingleton.h b/src/libCom/cxxTemplates/epicsSingleton.h deleted file mode 100644 index 2c63d3ff7..000000000 --- a/src/libCom/cxxTemplates/epicsSingleton.h +++ /dev/null @@ -1,216 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - */ - -#ifndef epicsSingleton_h -#define epicsSingleton_h - -#include -#include - -#include "shareLib.h" -#include "epicsAssert.h" - -class epicsShareClass SingletonUntyped { -public: - SingletonUntyped (); - ~SingletonUntyped (); - typedef void * ( * PBuild ) (); - void incrRefCount ( PBuild ); - typedef void ( * PDestroy ) ( void * ); - void decrRefCount ( PDestroy ); - void * pInstance () const; -private: - void * _pInstance; - std :: size_t _refCount; - SingletonUntyped ( const SingletonUntyped & ); - SingletonUntyped & operator = ( const SingletonUntyped & ); -}; - -// This class exists for the purpose of avoiding file scope -// object chicken and egg problems. It implements thread safe -// lazy initialization. To avoid locking overhead retain a -// copy of the epicsSingleton :: reference for future use. -template < class TYPE > -class epicsSingleton { -public: - class reference { - public: - reference ( epicsSingleton & ); - reference ( const reference & ); - ~reference (); - // this somewhat convoluted reference of the return - // type ref through the epicsSingleton template is - // required for the archaic Tornado gnu compiler - typename epicsSingleton < TYPE > :: reference & - operator = ( const reference & ); - TYPE * operator -> (); - const TYPE * operator -> () const; - TYPE & operator * (); - const TYPE & operator * () const; - private: - epicsSingleton * _pSingleton; - }; - friend class reference; - epicsSingleton () {} - // mutex lock/unlock pair overhead incured - // when either of these are called - reference getReference (); - const reference getReference () const; -private: - SingletonUntyped _singletonUntyped; - static void * _build (); - static void _destroy ( void * ); - epicsSingleton ( const epicsSingleton & ); - epicsSingleton & operator = ( const epicsSingleton & ); -}; - -template < class TYPE > -inline epicsSingleton < TYPE > :: reference :: - reference ( epicsSingleton & es ): - _pSingleton ( & es ) -{ - es._singletonUntyped. - incrRefCount ( & epicsSingleton < TYPE > :: _build ); -} - -template < class TYPE > -inline epicsSingleton < TYPE > :: reference :: - reference ( const reference & ref ) : - _pSingleton ( ref._pSingleton ) -{ - assert ( _pSingleton ); - _pSingleton->_singletonUntyped. - incrRefCount ( & epicsSingleton < TYPE > :: _build ); -} - -template < class TYPE > -inline epicsSingleton < TYPE > :: reference :: - ~reference () -{ - assert ( _pSingleton ); - _pSingleton->_singletonUntyped. - decrRefCount ( & epicsSingleton < TYPE > :: _destroy ); -} - -template < class TYPE > -typename epicsSingleton < TYPE > :: reference & - epicsSingleton < TYPE > :: reference :: - operator = ( const reference & ref ) -{ - if ( _pSingleton != ref._pSingleton ) { - assert ( _pSingleton ); - _pSingleton->_singletonUntyped. - decrRefCount ( epicsSingleton < TYPE > :: _destroy ); - _pSingleton = ref._pSingleton; - assert ( _pSingleton ); - _pSingleton->_singletonUntyped. - incrRefCount ( & epicsSingleton < TYPE > :: _build ); - } - return *this; -} - -template < class TYPE > -inline TYPE * - epicsSingleton < TYPE > :: reference :: - operator -> () -{ - assert ( _pSingleton ); - return reinterpret_cast < TYPE * > - ( _pSingleton->_singletonUntyped.pInstance () ); -} - -template < class TYPE > -inline const TYPE * - epicsSingleton < TYPE > :: reference :: - operator -> () const -{ - assert ( _pSingleton ); - return reinterpret_cast < const TYPE * > - ( _pSingleton->_singletonUntyped.pInstance () ); -} - -template < class TYPE > -inline TYPE & - epicsSingleton < TYPE > :: reference :: - operator * () -{ - return * this->operator -> (); -} - -template < class TYPE > -inline const TYPE & - epicsSingleton < TYPE > :: reference :: - operator * () const -{ - return * this->operator -> (); -} - -inline SingletonUntyped :: SingletonUntyped () : - _pInstance ( 0 ), _refCount ( 0 ) -{ -} - -inline void * SingletonUntyped :: pInstance () const -{ - return _pInstance; -} - -inline SingletonUntyped :: ~SingletonUntyped () -{ - // we dont assert fail on non-zero _refCount - // and or non nill _pInstance here because this - // is designed to tolarate situations where - // file scope epicsSingleton objects (which - // theoretically dont have storage lifespan - // issues) are deleted in a non-determanistic - // order -# if 0 - assert ( _refCount == 0 ); - assert ( _pInstance == 0 ); -# endif -} - -template < class TYPE > -void * epicsSingleton < TYPE > :: _build () -{ - return new TYPE (); -} - -template < class TYPE > -void epicsSingleton < TYPE > :: - _destroy ( void * pDestroyTypeless ) -{ - TYPE * pDestroy = - reinterpret_cast < TYPE * > ( pDestroyTypeless ); - delete pDestroy; -} - -template < class TYPE > -inline typename epicsSingleton < TYPE > :: reference - epicsSingleton < TYPE > :: getReference () -{ - return reference ( * this ); -} - -template < class TYPE > -inline const typename epicsSingleton < TYPE > :: reference - epicsSingleton < TYPE > :: getReference () const -{ - epicsSingleton < TYPE > * pConstCastAway = - const_cast < epicsSingleton < TYPE > * > ( this ); - return pConstCastAway->getReference (); -} - -#endif // epicsSingleton_h - diff --git a/src/libCom/cxxTemplates/epicsSingletonBase.cpp b/src/libCom/cxxTemplates/epicsSingletonBase.cpp deleted file mode 100644 index bf9a466d4..000000000 --- a/src/libCom/cxxTemplates/epicsSingletonBase.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey O. Hill - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsMutex.h" -#include "epicsGuard.h" -#include "epicsThread.h" -#include "epicsSingleton.h" -#include "epicsExit.h" - -static epicsThreadOnceId epicsSingletonOnceId = EPICS_THREAD_ONCE_INIT; -static epicsMutex *pSingletonBaseMutexEPICS; - -static void epicsSingletonCleanup (void *) -{ - delete pSingletonBaseMutexEPICS; -} - -static void epicsSingletonOnce ( void * ) -{ - pSingletonBaseMutexEPICS = newEpicsMutex; - epicsAtExit ( epicsSingletonCleanup,0 ); -} - -epicsSingletonBase::epicsSingletonBase () : pSingleton ( 0 ) -{ -} - -void * epicsSingletonBase::singletonPointer () const -{ - return this->pSingleton; -} - -epicsSingletonBase::~epicsSingletonBase () -{ -} - -void epicsSingletonBase::lockedFactory () -{ - if ( ! this->pSingleton ) { - epicsThreadOnce ( & epicsSingletonOnceId, epicsSingletonOnce, 0 ); - epicsGuard < epicsMutex > guard ( *pSingletonBaseMutexEPICS ); - if ( ! this->pSingleton ) { - this->pSingleton = this->factory (); - } - } -} diff --git a/src/libCom/cxxTemplates/epicsSingletonMutex.cpp b/src/libCom/cxxTemplates/epicsSingletonMutex.cpp deleted file mode 100644 index 8cd69d969..000000000 --- a/src/libCom/cxxTemplates/epicsSingletonMutex.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff O. Hill - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsMutex.h" -#include "epicsGuard.h" -#include "epicsThread.h" -#include "epicsSingleton.h" - -#ifndef SIZE_MAX -# define SIZE_MAX UINT_MAX -#endif - -static epicsThreadOnceId epicsSigletonOnceFlag ( EPICS_THREAD_ONCE_INIT ); -static epicsMutex * pEPICSSigletonMutex = 0; - -extern "C" void SingletonMutexOnce ( void * /* pParm */ ) -{ - // This class exists for the purpose of avoiding file scope - // object chicken and egg problems. Therefore, pEPICSSigletonMutex - // is never destroyed. - pEPICSSigletonMutex = newEpicsMutex; -} - -void SingletonUntyped :: incrRefCount ( PBuild pBuild ) -{ - epicsThreadOnce ( & epicsSigletonOnceFlag, SingletonMutexOnce, 0 ); - epicsGuard < epicsMutex > - guard ( *pEPICSSigletonMutex ); - assert ( _refCount < SIZE_MAX ); - if ( _refCount == 0 ) { - _pInstance = ( * pBuild ) (); - } - _refCount++; -} - -void SingletonUntyped :: decrRefCount ( PDestroy pDestroy ) -{ - epicsGuard < epicsMutex > - guard ( *pEPICSSigletonMutex ); - assert ( _refCount > 0 ); - _refCount--; - if ( _refCount == 0 ) { - ( *pDestroy ) ( _pInstance ); - _pInstance = 0; - } -} diff --git a/src/libCom/cxxTemplates/resourceLib.cpp b/src/libCom/cxxTemplates/resourceLib.cpp deleted file mode 100644 index f3a9a9993..000000000 --- a/src/libCom/cxxTemplates/resourceLib.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#include "resourceLib.h" - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template class intId < unsigned, 8u, sizeof(unsigned)*CHAR_BIT >; - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif diff --git a/src/libCom/cxxTemplates/resourceLib.h b/src/libCom/cxxTemplates/resourceLib.h deleted file mode 100644 index 7b61e238d..000000000 --- a/src/libCom/cxxTemplates/resourceLib.h +++ /dev/null @@ -1,1170 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * General hash table templates for fast indexing of resources - * of any base resource type and any resource identifier type. Fast - * indexing is implemented with a hash lookup. The identifier type - * implements the hash algorithm (or derives from one of the supplied - * identifier types which provide a hashing routine). The table expands - * dynamically depending on load, and without introducing non-determanistic - * latency. - * - * Unsigned integer and string identifier classes are supplied here. - * - * Authors Jeffrey O. Hill - * Marty Kraimer (string hash algorithm) - * influenced by papers by Peter K. Pearson and Per-Ake Larson - * - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef INCresourceLibh -#define INCresourceLibh - -#include -#include - -#include -#include -#include -#include -#ifndef assert // allow use of epicsAssert.h -#include -#endif - -#include "tsSLList.h" -#include "epicsString.h" -#include "shareLib.h" -typedef size_t resTableIndex; - -template < class T, class ID > class resTableIter; -template < class T, class ID > class resTableIterConst; - -// -// class resTable -// -// This class stores resource entries of type T which can be efficiently -// located with a hash key of type ID. -// -// NOTES: -// 1) class T must derive from class ID and also from class tsSLNode -// -// 2) If the "resTable::show (unsigned level)" member function is called then -// class T must also implement a "show (unsigned level)" member function which -// dumps increasing diagnostics information with increasing "level" to -// standard out. -// -// 3) Classes of type ID must implement the following member functions: -// -// // equivalence test -// bool operator == (const ID &); -// -// // ID to hash index convert (see examples below) -// resTableIndex hash (unsigned nBitsHashIndex) const; -// -// 4) Storage for identifier of type ID must persist until the item of type -// T is deleted from the resTable -// -template -class resTable { -public: - resTable (); - virtual ~resTable(); - // Call " void T::show (unsigned level)" for each entry - void show ( unsigned level ) const; - void verify () const; - int add ( T & res ); // returns -1 (id exists in table), 0 (success) - T * remove ( const ID &idIn ); // remove entry - void removeAll ( tsSLList & destination ); // remove all entries - T * lookup ( const ID &idIn ) const; // locate entry - // Call (pT->*pCB) () for each entry but expect poor performance - // with sparcely populated tables - void traverse ( void (T::*pCB)() ); - void traverseConst ( void (T::*pCB)() const ) const; - unsigned numEntriesInstalled () const; - void setTableSize ( const unsigned newTableSize ); - // iterate through all entries but expect poor performance - // with sparcely populated tables - typedef resTableIter < T, ID > iterator; - typedef resTableIterConst < T, ID > iteratorConst; - iterator firstIter (); - iteratorConst firstIter () const; -private: - tsSLList < T > * pTable; - unsigned nextSplitIndex; - unsigned hashIxMask; - unsigned hashIxSplitMask; - unsigned nBitsHashIxSplitMask; - unsigned logBaseTwoTableSize; - unsigned nInUse; - resTableIndex hash ( const ID & idIn ) const; - T * find ( tsSLList & list, const ID & idIn ) const; - void splitBucket (); - unsigned tableSize () const; - bool setTableSizePrivate ( unsigned logBaseTwoTableSize ); - resTable ( const resTable & ); - resTable & operator = ( const resTable & ); - static unsigned resTableBitMask ( const unsigned nBits ); - friend class resTableIter < T, ID >; - friend class resTableIterConst < T, ID >; -}; - -// -// class resTableIter -// -// an iterator for the resource table class -// -template < class T, class ID > -class resTableIter { -public: - resTableIter (); - bool valid () const; - bool operator == ( const resTableIter < T,ID > & rhs ) const; - bool operator != ( const resTableIter < T,ID > & rhs ) const; - resTableIter < T, ID > & operator = ( const resTableIter < T, ID > & ); - T & operator * () const; - T * operator -> () const; - resTableIter < T, ID > & operator ++ (); - resTableIter < T, ID > operator ++ ( int ); - T * pointer (); -private: - tsSLIter < T > iter; - unsigned index; - resTable < T,ID > * pResTable; - resTableIter ( resTable < T,ID > & tableIn ); - void findNextEntry (); - friend class resTable < T, ID >; -}; - -// -// class resTableIterConst -// -// an iterator for a const resource table class -// -template < class T, class ID > -class resTableIterConst { -public: - resTableIterConst (); - bool valid () const; - bool operator == ( const resTableIterConst < T,ID > & rhs ) const; - bool operator != ( const resTableIterConst < T,ID > & rhs ) const; - resTableIterConst < T, ID > & operator = ( const resTableIterConst < T, ID > & ); - const T & operator * () const; - const T * operator -> () const; - resTableIterConst < T, ID > & operator ++ (); - resTableIterConst < T, ID > operator ++ ( int ); - const T * pointer () const; -private: - tsSLIterConst < T > iter; - unsigned index; - const resTable < T,ID > * pResTable; - resTableIterConst ( const resTable < T,ID > & tableIn ); - void findNextEntry (); - friend class resTable < T, ID >; -}; - -// -// Some ID classes that work with the above template -// - -// -// class intId -// -// signed or unsigned integer identifier (class T must be -// a signed or unsigned integer type) -// -// this class works as type ID in resTable -// -// 1<. -// Set this parameter to zero if unsure of the correct minimum -// hash table size. -// -// MAX_ID_WIDTH specifies the maximum number of ls bits in an -// integer identifier which might be set at any time. -// -// MIN_INDEX_WIDTH and MAX_ID_WIDTH are specified here at -// compile time so that the hash index can be produced -// efficiently. Hash indexes are produced more efficiently -// when (MAX_ID_WIDTH - MIN_INDEX_WIDTH) is minimized. -// -template -class intId { -public: - intId (const T &idIn); - bool operator == (const intId &idIn) const; - resTableIndex hash () const; - const T getId() const; -protected: - T id; -}; - -// -// class chronIntIdResTable -// -// a specialized resTable which uses unsigned integer keys which are -// allocated in chronological sequence -// -// NOTE: ITEM must public inherit from chronIntIdRes -// -class chronIntId : public intId -{ -public: - chronIntId ( const unsigned &idIn ); -}; - -template -class chronIntIdResTable : public resTable { -public: - chronIntIdResTable (); - virtual ~chronIntIdResTable (); - void idAssignAdd ( ITEM & item ); -private: - unsigned allocId; - chronIntIdResTable ( const chronIntIdResTable & ); - chronIntIdResTable & operator = ( const chronIntIdResTable & ); -}; - -// -// class chronIntIdRes -// -// resource with unsigned chronological identifier -// -template -class chronIntIdRes : public chronIntId, public tsSLNode { -public: - chronIntIdRes (); -private: - void setId (unsigned newId); - chronIntIdRes (const chronIntIdRes & ); - friend class chronIntIdResTable; -}; - -// -// class stringId -// -// character string identifier -// -class epicsShareClass stringId { -public: - enum allocationType {copyString, refString}; - stringId (const char * idIn, allocationType typeIn=copyString); - virtual ~stringId(); - resTableIndex hash () const; - bool operator == (const stringId &idIn) const; - const char * resourceName() const; // return the pointer to the string - void show (unsigned level) const; -private: - stringId & operator = ( const stringId & ); - stringId ( const stringId &); - const char * pStr; - const allocationType allocType; -}; - -///////////////////////////////////////////////// -// resTable member functions -///////////////////////////////////////////////// - -// -// resTable::resTable () -// -template -inline resTable::resTable () : - pTable ( 0 ), nextSplitIndex ( 0 ), hashIxMask ( 0 ), - hashIxSplitMask ( 0 ), nBitsHashIxSplitMask ( 0 ), - logBaseTwoTableSize ( 0 ), nInUse ( 0 ) {} - -template -inline unsigned resTable::resTableBitMask ( const unsigned nBits ) -{ - return ( 1 << nBits ) - 1; -} - -// -// resTable::remove () -// -// remove a res from the resTable -// -template -T * resTable::remove ( const ID & idIn ) -{ - if ( this->pTable ) { - // search list for idIn and remove the first match - tsSLList & list = this->pTable [ this->hash(idIn) ]; - tsSLIter pItem = list.firstIter (); - T *pPrev = 0; - while ( pItem.valid () ) { - const ID & idOfItem = *pItem; - if ( idOfItem == idIn ) { - if ( pPrev ) { - list.remove ( *pPrev ); - } - else { - list.get (); - } - this->nInUse--; - break; - } - pPrev = pItem.pointer (); - pItem++; - } - return pItem.pointer (); - } - else { - return 0; - } -} - -template -void resTable::removeAll ( tsSLList & destination ) -{ - const unsigned N = this->tableSize (); - for ( unsigned i = 0u; i < N; i++ ) { - while ( T * pItem = this->pTable[i].get() ) { - destination.add ( *pItem ); - } - } - this->nInUse = 0; -} - -// -// resTable::lookup () -// -template -inline T * resTable::lookup ( const ID & idIn ) const -{ - if ( this->pTable ) { - tsSLList & list = this->pTable [ this->hash ( idIn ) ]; - return this->find ( list, idIn ); - } - else { - return 0; - } -} - -// -// resTable::hash () -// -template -inline resTableIndex resTable::hash ( const ID & idIn ) const -{ - resTableIndex h = idIn.hash (); - resTableIndex h0 = h & this->hashIxMask; - if ( h0 >= this->nextSplitIndex ) { - return h0; - } - return h & this->hashIxSplitMask; -} - -// -// resTable::show -// -template -void resTable::show ( unsigned level ) const -{ - const unsigned N = this->tableSize (); - - printf ( "Hash table with %u buckets and %u items of type %s installed\n", - N, this->nInUse, typeid(T).name() ); - - if ( level >= 1u && N ) { - - if ( level >= 2u ) { - tsSLList * pList = this->pTable; - while ( pList < & this->pTable[N] ) { - tsSLIter pItem = pList->firstIter (); - while ( pItem.valid () ) { - tsSLIter pNext = pItem; - pNext++; - pItem.pointer()->show ( level - 2u ); - pItem = pNext; - } - pList++; - } - } - - double X = 0.0; - double XX = 0.0; - unsigned maxEntries = 0u; - unsigned empty = 0; - for ( unsigned i = 0u; i < N; i++ ) { - tsSLIter pItem = this->pTable[i].firstIter (); - unsigned count = 0; - while ( pItem.valid () ) { - if ( level >= 3u ) { - pItem->show ( level ); - } - count++; - pItem++; - } - if ( count > 0u ) { - X += count; - XX += count * count; - if ( count > maxEntries ) { - maxEntries = count; - } - } else - empty++; - } - - double mean = X / N; - double stdDev = sqrt( XX / N - mean * mean ); - printf ( - "entries per bucket: mean = %f std dev = %f max = %u\n", - mean, stdDev, maxEntries ); - printf("%u empty buckets\n", empty); - if ( X != this->nInUse ) { - printf ("this->nInUse didnt match items counted which was %f????\n", X ); - } - } -} - -// self test -template -void resTable::verify () const -{ - const unsigned N = this->tableSize (); - - if ( this->pTable ) { - assert ( this->nextSplitIndex <= this->hashIxMask + 1 ); - assert ( this->hashIxMask ); - assert ( this->hashIxMask == ( this->hashIxSplitMask >> 1 ) ); - assert ( this->hashIxSplitMask ); - assert ( this->nBitsHashIxSplitMask ); - assert ( resTableBitMask ( this->nBitsHashIxSplitMask ) - == this->hashIxSplitMask ); - assert ( this->logBaseTwoTableSize ); - assert ( this->nBitsHashIxSplitMask <= this->logBaseTwoTableSize ); - } - else { - assert ( this->nextSplitIndex == 0 ); - assert ( this->hashIxMask == 0 ); - assert ( this->hashIxSplitMask == 0 ); - assert ( this->nBitsHashIxSplitMask == 0 ); - assert ( this->logBaseTwoTableSize == 0 ); - } - - unsigned total = 0u; - for ( unsigned i = 0u; i < N; i++ ) { - tsSLIter pItem = this->pTable[i].firstIter (); - unsigned count = 0; - while ( pItem.valid () ) { - resTableIndex index = this->hash ( *pItem ); - assert ( index == i ); - count++; - pItem++; - } - total += count; - } - assert ( total == this->nInUse ); -} - - -// -// resTable::traverse -// -template -void resTable::traverse ( void (T::*pCB)() ) -{ - const unsigned N = this->tableSize (); - for ( unsigned i = 0u; i < N; i++ ) { - tsSLIter pItem = this->pTable[i].firstIter (); - while ( pItem.valid () ) { - tsSLIter pNext = pItem; - pNext++; - ( pItem.pointer ()->*pCB ) (); - pItem = pNext; - } - } -} - -// -// resTable::traverseConst -// -template -void resTable::traverseConst ( void (T::*pCB)() const ) const -{ - const unsigned N = this->tableSize (); - for ( unsigned i = 0u; i < N; i++ ) { - const tsSLList < T > & table = this->pTable[i]; - tsSLIterConst pItem = table.firstIter (); - while ( pItem.valid () ) { - tsSLIterConst pNext = pItem; - pNext++; - ( pItem.pointer ()->*pCB ) (); - pItem = pNext; - } - } -} - -template -inline unsigned resTable::numEntriesInstalled () const -{ - return this->nInUse; -} - -template -inline unsigned resTable::tableSize () const -{ - if ( this->pTable ) { - return ( this->hashIxMask + 1 ) + this->nextSplitIndex; - } - else { - return 0; - } -} - -// it will be more efficent to call this once prior to installing -// the first entry -template -void resTable::setTableSize ( const unsigned newTableSize ) -{ - if ( newTableSize == 0u ) { - return; - } - - // - // count the number of bits in newTableSize and round up - // to the next power of two - // - unsigned newMask = newTableSize - 1; - unsigned nbits; - for ( nbits = 0; nbits < sizeof (newTableSize) * CHAR_BIT; nbits++ ) { - unsigned nBitsMask = resTableBitMask ( nbits ); - if ( ( newMask & ~nBitsMask ) == 0){ - break; - } - } - setTableSizePrivate ( nbits ); -} - -template -bool resTable::setTableSizePrivate ( unsigned logBaseTwoTableSizeIn ) -{ - // dont shrink - if ( this->logBaseTwoTableSize >= logBaseTwoTableSizeIn ) { - return true; - } - - // dont allow ridiculously small tables - if ( logBaseTwoTableSizeIn < 4 ) { - logBaseTwoTableSizeIn = 4; - } - - const unsigned newTableSize = 1 << logBaseTwoTableSizeIn; -# if ! defined (__GNUC__) || __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 92 ) - const unsigned oldTableSize = this->pTable ? 1 << this->logBaseTwoTableSize : 0; -# endif - const unsigned oldTableOccupiedSize = this->tableSize (); - - tsSLList * pNewTable; - try { - pNewTable = ( tsSLList * ) - ::operator new ( newTableSize * sizeof ( tsSLList ) ); - } - catch ( ... ){ - if ( ! this->pTable ) { - throw; - } - return false; - } - - // run the constructors using placement new - unsigned i; - for ( i = 0u; i < oldTableOccupiedSize; i++ ) { - new ( &pNewTable[i] ) tsSLList ( this->pTable[i] ); - } - for ( i = oldTableOccupiedSize; i < newTableSize; i++ ) { - new ( &pNewTable[i] ) tsSLList; - } - // Run the destructors explicitly. Currently this destructor is a noop. - // The Tornado II compiler and RedHat 6.2 will not compile ~tsSLList() but - // since its a NOOP we can find an ugly workaround -# if ! defined (__GNUC__) || __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 92 ) - for ( i = 0; i < oldTableSize; i++ ) { - this->pTable[i].~tsSLList(); - } -# endif - - if ( ! this->pTable ) { - this->hashIxSplitMask = resTableBitMask ( logBaseTwoTableSizeIn ); - this->nBitsHashIxSplitMask = logBaseTwoTableSizeIn; - this->hashIxMask = this->hashIxSplitMask >> 1; - this->nextSplitIndex = 0; - } - - operator delete ( this->pTable ); - this->pTable = pNewTable; - this->logBaseTwoTableSize = logBaseTwoTableSizeIn; - - return true; -} - -template -void resTable::splitBucket () -{ - // double the hash table when necessary - // (this results in only a memcpy overhead, but - // no hashing or entry redistribution) - if ( this->nextSplitIndex > this->hashIxMask ) { - bool success = this->setTableSizePrivate ( this->nBitsHashIxSplitMask + 1 ); - if ( ! success ) { - return; - } - this->nBitsHashIxSplitMask += 1; - this->hashIxSplitMask = resTableBitMask ( this->nBitsHashIxSplitMask ); - this->hashIxMask = this->hashIxSplitMask >> 1; - this->nextSplitIndex = 0; - } - - // rehash only the items in the split bucket - tsSLList tmp ( this->pTable[ this->nextSplitIndex ] ); - this->nextSplitIndex++; - T *pItem = tmp.get(); - while ( pItem ) { - resTableIndex index = this->hash ( *pItem ); - this->pTable[index].add ( *pItem ); - pItem = tmp.get(); - } -} - -// -// add a res to the resTable -// -template -int resTable::add ( T &res ) -{ - if ( ! this->pTable ) { - this->setTableSizePrivate ( 10 ); - } - else if ( this->nInUse >= this->tableSize() ) { - this->splitBucket (); - tsSLList &list = this->pTable[this->hash(res)]; - if ( this->find ( list, res ) != 0 ) { - return -1; - } - } - tsSLList &list = this->pTable[this->hash(res)]; - if ( this->find ( list, res ) != 0 ) { - return -1; - } - list.add ( res ); - this->nInUse++; - return 0; -} - -// -// find -// searches from where the iterator points to the -// end of the list for idIn -// -// iterator points to the item found upon return -// (or NULL if nothing matching was found) -// -template -T * resTable::find ( tsSLList &list, const ID &idIn ) const -{ - tsSLIter pItem = list.firstIter (); - while ( pItem.valid () ) { - const ID & idOfItem = *pItem; - if ( idOfItem == idIn ) { - break; - } - pItem++; - } - return pItem.pointer (); -} - -// -// ~resTable::resTable() -// -template -resTable::~resTable() -{ - operator delete ( this->pTable ); -} - -// -// resTable::resTable ( const resTable & ) -// private - not to be used - implemented to eliminate warnings -// -template -inline resTable::resTable ( const resTable & ) -{ -} - -// -// resTable::resTable & operator = ( const resTable & ) -// private - not to be used - implemented to eliminate warnings -// -template -inline resTable & resTable::operator = ( const resTable & ) -{ - return *this; -} - -template -inline resTableIterConst < T, ID > resTable::firstIter () const -{ - return resTableIterConst < T, ID > ( *this ); -} - -template -inline resTableIter < T, ID > resTable::firstIter () -{ - return resTableIter < T, ID > ( *this ); -} - -////////////////////////////////////////////// -// resTableIter member functions -////////////////////////////////////////////// - -template < class T, class ID > -inline resTableIter::resTableIter ( resTable < T,ID > & tableIn ) : - index ( 0 ), pResTable ( & tableIn ) -{ - this->findNextEntry (); -} - -template < class T, class ID > -inline resTableIter::resTableIter () : - iter ( tsSLList::invalidIter() ), - index ( 0 ), pResTable ( 0 ) -{ -} - -template < class T, class ID > -inline void resTableIter::findNextEntry () -{ - if ( this->pResTable ) { - while ( this->index < this->pResTable->tableSize() ) { - this->iter = this->pResTable->pTable[this->index++].firstIter (); - if ( this->iter.valid () ) { - break; - } - } - } -} - -template < class T, class ID > -inline bool resTableIter::valid () const -{ - return this->iter.valid (); -} - -template < class T, class ID > -inline bool resTableIter::operator == - ( const resTableIter < T,ID > & rhs ) const -{ - return ( this->pResTable == rhs.pResTable - && this->index == rhs.index - && this->iter == rhs.iter ); -} - -template < class T, class ID > -inline bool resTableIter::operator != - ( const resTableIter < T,ID > & rhs ) const -{ - return ! this->operator == ( rhs ); -} - -template < class T, class ID > -inline resTableIter < T, ID > & resTableIter::operator = - ( const resTableIter < T, ID > & rhs ) -{ - this->pResTable = rhs.pResTable; - this->index = rhs.index; - this->iter = rhs.iter; - return *this; -} - -template < class T, class ID > -inline T & resTableIter::operator * () const -{ - return this->iter.operator * (); -} - -template < class T, class ID > -inline T * resTableIter::operator -> () const -{ - return this->iter.operator -> (); -} - -template < class T, class ID > -inline resTableIter & resTableIter::operator ++ () -{ - this->iter++; - if ( ! this->iter.valid() ) { - this->findNextEntry (); - } - return *this; -} - -template < class T, class ID > -inline resTableIter resTableIter::operator ++ ( int ) -{ - resTableIter tmp = *this; - this->operator ++ (); - return tmp; -} - -template < class T, class ID > -inline T * resTableIter::pointer () -{ - return this->iter.pointer (); -} - -////////////////////////////////////////////// -// resTableIterConst member functions -////////////////////////////////////////////// - -template < class T, class ID > -inline resTableIterConst::resTableIterConst ( const resTable < T,ID > & tableIn ) : - index ( 0 ), pResTable ( & tableIn ) -{ - this->findNextEntry (); -} - -template < class T, class ID > -inline resTableIterConst::resTableIterConst () : - iter ( tsSLList::invalidIter() ), - index ( 0 ), pResTable ( 0 ) -{ -} - -template < class T, class ID > -inline void resTableIterConst::findNextEntry () -{ - if ( this->pResTable ) { - while ( this->index < this->pResTable->tableSize() ) { - const tsSLList * pList = & this->pResTable->pTable[this->index++]; - this->iter = pList->firstIter (); - if ( this->iter.valid () ) { - break; - } - } - } -} - -template < class T, class ID > -inline bool resTableIterConst::valid () const -{ - return this->iter.valid (); -} - -template < class T, class ID > -inline bool resTableIterConst::operator == - ( const resTableIterConst < T,ID > & rhs ) const -{ - return ( this->pResTable == rhs.pResTable - && this->index == rhs.index - && this->iter == rhs.iter ); -} - -template < class T, class ID > -inline bool resTableIterConst::operator != - ( const resTableIterConst < T,ID > & rhs ) const -{ - return ! this->operator == ( rhs ); -} - -template < class T, class ID > -inline resTableIterConst < T, ID > & resTableIterConst::operator = - ( const resTableIterConst < T, ID > & rhs ) -{ - this->pResTable = rhs.pResTable; - this->index = rhs.index; - this->iter = rhs.iter; - return *this; -} - -template < class T, class ID > -inline const T & resTableIterConst::operator * () const -{ - return this->iter.operator * (); -} - -template < class T, class ID > -inline const T * resTableIterConst::operator -> () const -{ - return this->iter.operator -> (); -} - -template < class T, class ID > -inline resTableIterConst & resTableIterConst::operator ++ () -{ - this->iter++; - if ( ! this->iter.valid() ) { - this->findNextEntry (); - } - return *this; -} - -template < class T, class ID > -inline resTableIterConst resTableIterConst::operator ++ ( int ) -{ - resTableIterConst tmp = *this; - this->operator ++ (); - return tmp; -} - -template < class T, class ID > -inline const T * resTableIterConst::pointer () const -{ - return this->iter.pointer (); -} - -////////////////////////////////////////////// -// chronIntIdResTable member functions -////////////////////////////////////////////// -inline chronIntId::chronIntId ( const unsigned &idIn ) : - intId ( idIn ) {} - -// -// chronIntIdResTable::chronIntIdResTable() -// -template -inline chronIntIdResTable::chronIntIdResTable () : - resTable (), allocId(1u) {} - -template -inline chronIntIdResTable::chronIntIdResTable ( const chronIntIdResTable & ) : - resTable (), allocId(1u) {} - -template -inline chronIntIdResTable & chronIntIdResTable:: - operator = ( const chronIntIdResTable & ) -{ - return *this; -} - -// -// chronIntIdResTable::~chronIntIdResTable() -// (not inline because it is virtual) -// -template -chronIntIdResTable::~chronIntIdResTable() {} - -// -// chronIntIdResTable::add() -// -// NOTE: This detects (and avoids) the case where -// the PV id wraps around and we attempt to have two -// resources with the same id. -// -template -inline void chronIntIdResTable::idAssignAdd (ITEM &item) -{ - int status; - do { - item.chronIntIdRes::setId (allocId++); - status = this->resTable::add (item); - } - while (status); -} - -///////////////////////////////////////////////// -// chronIntIdRes member functions -///////////////////////////////////////////////// - -// -// chronIntIdRes::chronIntIdRes -// -template -inline chronIntIdRes::chronIntIdRes () : chronIntId (UINT_MAX) {} - -// -// id::setId () -// -// workaround for bug in DEC compiler -// -template -inline void chronIntIdRes::setId (unsigned newId) -{ - this->id = newId; -} - -///////////////////////////////////////////////// -// intId member functions -///////////////////////////////////////////////// - -// -// intId::intId -// -// (if this is inline SUN PRO botches the template instantiation) -template -intId::intId (const T &idIn) - : id (idIn) {} - -// -// intId::operator == () -// -template -inline bool intId::operator == - (const intId &idIn) const -{ - return this->id == idIn.id; -} - -// -// intId::getId () -// -template -inline const T intId::getId () const -{ - return this->id; -} - -// -// integerHash() -// -// converts any integer into a hash table index -// -template < class T > -inline resTableIndex integerHash ( unsigned MIN_INDEX_WIDTH, - unsigned MAX_ID_WIDTH, const T &id ) -{ - resTableIndex hashid = static_cast ( id ); - - // - // the intent here is to gurantee that all components of the - // integer contribute even if the resTableIndex returned might - // index a small table. - // - // On most compilers the optimizer will unroll this loop so this - // is actually a very small inline function - // - // Experiments using the microsoft compiler show that this isnt - // slower than switching on the architecture size and unrolling the - // loop explicitly (that solution has resulted in portability - // problems in the past). - // - unsigned width = MAX_ID_WIDTH; - do { - width >>= 1u; - hashid ^= hashid>>width; - } while (width>MIN_INDEX_WIDTH); - - // - // the result here is always masked to the - // proper size after it is returned to the "resTable" class - // - return hashid; -} - - -// -// intId::hash() -// -template -inline resTableIndex intId::hash () const -{ - return integerHash ( MIN_INDEX_WIDTH, MAX_ID_WIDTH, this->id ); -} - -//////////////////////////////////////////////////// -// stringId member functions -//////////////////////////////////////////////////// - -// -// stringId::operator == () -// -inline bool stringId::operator == - (const stringId &idIn) const -{ - if (this->pStr!=NULL && idIn.pStr!=NULL) { - return strcmp(this->pStr,idIn.pStr)==0; - } - return false; // not equal -} - -// -// stringId::resourceName () -// -inline const char * stringId::resourceName () const -{ - return this->pStr; -} - -#ifdef instantiateRecourceLib - -// -// stringId::stringId() -// -stringId::stringId (const char * idIn, allocationType typeIn) : - allocType (typeIn) -{ - if (typeIn==copyString) { - unsigned nChars = strlen (idIn) + 1u; - this->pStr = new char [nChars]; - memcpy ( (void *) this->pStr, idIn, nChars ); - } - else { - this->pStr = idIn; - } -} - -// -// stringId::show () -// -void stringId::show (unsigned level) const -{ - if (level>2u) { - printf ("resource id = %s\n", this->pStr); - } -} - -// -// stringId::~stringId() -// -// -// this needs to be instantiated only once (normally in libCom) -// -stringId::~stringId() -{ - if (this->allocType==copyString) { - if (this->pStr!=NULL) { - // - // the microsoft and solaris compilers will - // not allow a pointer to "const char" - // to be deleted - // - // the HP-UX compiler gives us a warning on - // each cast away of const, but in this case - // it cant be avoided. - // - // The DEC compiler complains that const isnt - // really significant in a cast if it is present. - // - // I hope that deleting a pointer to "char" - // is the same as deleting a pointer to - // "const char" on all compilers - // - delete [] const_cast(this->pStr); - } - } -} - -// -// stringId::hash() -// -resTableIndex stringId::hash() const -{ - if (!this->pStr) { - return 0u; - } - return epicsStrHash(this->pStr, 0); -} - -#endif // if instantiateRecourceLib is defined - -#endif // INCresourceLibh - diff --git a/src/libCom/cxxTemplates/test/Makefile b/src/libCom/cxxTemplates/test/Makefile deleted file mode 100644 index 61d807c65..000000000 --- a/src/libCom/cxxTemplates/test/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -TOP=../../../.. - -include $(TOP)/configure/CONFIG - -resourceLibTest_SRCS += resourceLibTest.cc -TESTPROD_HOST += resourceLibTest - -tsDLListBench_SRCS += tsDLListBench.cc -TESTPROD_HOST += tsDLListBench - -tsDLListTest_SRCS += tsDLListTest.cc -TESTPROD_HOST += tsDLListTest - -tsSLListBench_SRCS += tsSLListBench.cc -TESTPROD_HOST += tsSLListBench - -tsSLListTest_SRCS += tsSLListTest.cc -TESTPROD_HOST += tsSLListTest - -minmaxTest_SRCS += minmaxTest.cc -TESTPROD_HOST += minmaxTest - -PROD_LIBS = Com - -include $(TOP)/configure/RULES - diff --git a/src/libCom/cxxTemplates/test/minmaxTest.cc b/src/libCom/cxxTemplates/test/minmaxTest.cc deleted file mode 100644 index b5cf5b110..000000000 --- a/src/libCom/cxxTemplates/test/minmaxTest.cc +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#include "tsMinMax.h" - -int main () -{ - float f1 = 3.3f; - float f2 = 3.4f; - float f3; - - f3 = tsMin(f1,f2); - assert(f3==f1); - - f3 = tsMax(f1,f2); - assert(f3==f2); - - int i1 = 3; - int i2 = 4; - int i3; - - i3 = tsMin(i1,i2); - assert(i3==i1); - - i3 = tsMax(i1,i2); - assert(i3==i2); - - return 0; -} - diff --git a/src/libCom/cxxTemplates/test/resourceLibTest.cc b/src/libCom/cxxTemplates/test/resourceLibTest.cc deleted file mode 100644 index 1a6a2c1f9..000000000 --- a/src/libCom/cxxTemplates/test/resourceLibTest.cc +++ /dev/null @@ -1,309 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#define instantiateRecourceLib -#include "resourceLib.h" - -#if defined(__GNUC__) && ( __GNUC__<2 || (__GNUC__==2 && __GNUC__<8) ) -typedef intId testIntId; -#else -typedef intId testIntId; -#endif - -#define verify(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -static void empty() -{ -} - -class albert : public testIntId, public tsSLNode { -public: - albert (resTable< albert, testIntId > &atIn, unsigned idIn) : - testIntId(idIn), at(atIn) - { - verify (at.add (*this)==0); - } - void show (unsigned /* level */) - { - } - void destroy() - { - at.remove(*this); - delete this; - } -private: - resTable< albert, testIntId > &at; -}; - -class fred : public testIntId, public tsSLNode { -public: - fred (const char *pNameIn, unsigned idIn) : - testIntId(idIn), pName(pNameIn) {} - void show (unsigned) - { - printf("fred %s\n", pName); - } - void destroy() - { - // always on stack so noop - } -private: - const char * const pName; -}; - -class jane : public stringId, public tsSLNode { -public: - jane (const char *pNameIn) : stringId (pNameIn) {} - - void testTraverse(); - - void destroy() - { - // always on stack so noop - } -}; - -// -// jane::testTraverse() -// -void jane::testTraverse() -{ - printf("Traverse Test\n"); - this->show(10); -} - -int main() -{ - unsigned i; - clock_t start, finish; - double duration; - const unsigned LOOPS = 500000; - resTable < fred, testIntId > intTbl; - resTable < jane, stringId> strTbl; - fred fred0("fred0",0); - fred fred1("fred1",0x1000a432); - fred fred2("fred2",0x0000a432); - fred fred3("fred3",1); - fred fred4("fred4",2); - fred fred5("fred5",3); - fred fred6("fred6",4); - fred fred7("fred7",5); - fred fred8("fred8",6); - fred fred9("fred9",7); - jane jane1("rrrrrrrrrrrrrrrrrrrrrrrrrr1"); - jane jane2("rrrrrrrrrrrrrrrrrrrrrrrrrr2"); - fred *pFred; - jane *pJane; - testIntId intId0 (0); - testIntId intId1 (0x1000a432); - testIntId intId2 (0x0000a432); - testIntId intId3 (1); - testIntId intId4 (2); - testIntId intId5 (3); - testIntId intId6 (4); - testIntId intId7 (5); - testIntId intId8 (6); - testIntId intId9 (7); - - stringId strId1("rrrrrrrrrrrrrrrrrrrrrrrrrr1"); - strTbl.verify (); - stringId strId2("rrrrrrrrrrrrrrrrrrrrrrrrrr2"); - strTbl.verify (); - - intTbl.setTableSize ( 100000 ); - - verify (intTbl.add(fred0)==0); - intTbl.verify (); - verify (intTbl.add(fred1)==0); - intTbl.verify (); - verify (intTbl.add(fred2)==0); - intTbl.verify (); - verify (intTbl.add(fred3)==0); - intTbl.verify (); - verify (intTbl.add(fred4)==0); - intTbl.verify (); - - intTbl.setTableSize ( 200000 ); - - verify (intTbl.add(fred5)==0); - intTbl.verify (); - verify (intTbl.add(fred6)==0); - intTbl.verify (); - verify (intTbl.add(fred7)==0); - intTbl.verify (); - verify (intTbl.add(fred8)==0); - intTbl.verify (); - verify (intTbl.add(fred9)==0); - intTbl.verify (); - - start = clock(); - for (i=0; i alTbl; - - for (i=0; i alTblIter ( alTbl.firstIter() ); - albert *pa; - i=0; - while ( ( pa = alTblIter.pointer() ) ) { - i++; - alTblIter++; - } - verify ( i == elementCount ); - alTbl.verify (); - - for ( i = 0; i < elementCount; i++ ) { - verify ( pAlbert[i] == alTbl.lookup( pAlbert[i]->getId() ) ); - } - alTbl.verify (); - - for ( i = 0; i < elementCount; i += 2 ) { - verify ( pAlbert[i] == alTbl.remove ( pAlbert[i]->getId() ) ); - } - alTbl.verify (); - - for ( i = 0; i < elementCount; i += 2 ) { - verify ( 0 == alTbl.lookup ( pAlbert[i]->getId() ) ); - } - alTbl.verify (); - - for ( i = 1; i < elementCount; i += 2 ) { - verify ( pAlbert[i] == alTbl.lookup ( pAlbert[i]->getId() ) ); - } - alTbl.verify (); - - return 0; -} - - - diff --git a/src/libCom/cxxTemplates/test/tsDLListBench.cc b/src/libCom/cxxTemplates/test/tsDLListBench.cc deleted file mode 100644 index 577a3829d..000000000 --- a/src/libCom/cxxTemplates/test/tsDLListBench.cc +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "tsDLList.h" -#include -#include -#include - -class fred : public tsDLNode { -public: - fred() : count(0) {} - void inc () {count++;} -private: - unsigned count; -}; - -class jane : public fred, public tsDLNode { -public: - jane() {} -private: -}; - -#define LOOPCOUNT 100000 - -int main () -{ - tsDLList list; - tsDLIter iter = list.firstIter(); - fred *pFred; - unsigned i; - clock_t clk; - clock_t diff; - double delay; - - for (i=0; iinc(); - iter++; - } - diff = clock() - clk; - delay = diff; - delay = delay/CLOCKS_PER_SEC; - delay = delay/LOOPCOUNT; - printf("delay = %15.10f\n", delay); - - pFred = new fred(); - clk = clock(); - for (i=0; iinc(); - } - diff = clock() - clk; - delay = diff; - delay = delay/CLOCKS_PER_SEC; - delay = delay/LOOPCOUNT; - printf("delay = %15.10f\n", delay); - - return 0; -} - diff --git a/src/libCom/cxxTemplates/test/tsDLListTest.cc b/src/libCom/cxxTemplates/test/tsDLListTest.cc deleted file mode 100644 index 02fe0dcd9..000000000 --- a/src/libCom/cxxTemplates/test/tsDLListTest.cc +++ /dev/null @@ -1,131 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - - -#include "tsDLList.h" -#include -#include - -#define verify(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -class fred : public tsDLNode { -public: - fred(const char * const pNameIn) : pName(pNameIn){} - void show () {printf("%s\n", pName);} -private: - const char * const pName; -}; - -class jane : public fred, public tsDLNode { -public: - jane(const char * const pNameIn) : fred(pNameIn){} -private: -}; - -int main () -{ - unsigned i; - tsDLList list; - fred *pFred; - fred *pFredII; - fred *pFredBack; - tsDLList janeList; - tsDLIter janeFwdIter = janeList.firstIter(); - tsDLIter janeBwdIter = janeList.lastIter(); - jane *pJane; - - pFred = new fred ("A"); - pFredII = new fred ("B"); - - list.add (*pFred); - list.add (*pFredII); - tsDLIter iter = list.firstIter(); - verify (iter.pointer() == pFred); - iter++; - verify (iter.pointer() == pFredII); - list.remove(*pFred); - list.add(*pFred); - pFredBack = list.get(); - verify (pFredBack == pFredII); - pFredBack = list.get(); - verify (pFredBack == pFred); - verify (list.count() == 0u); - list.add(*pFred); - list.add(*pFredII); - list.add(* new fred("C")); - list.add(* new fred("D")); - - iter = list.firstIter(); - while ( iter.valid() ) { - iter->show(); - iter++; - } - - pJane = new jane("JA"); - janeList.add(*pJane); - pJane = new jane("JB"); - verify ( janeList.find ( *pJane ) == -1 ); - janeList.add(*pJane); - verify ( janeList.find ( *pJane ) == 1 ); - - while ( janeFwdIter.valid() ) { - janeFwdIter->show(); - janeFwdIter++; - } - - while ( janeBwdIter.valid() ) { - janeBwdIter->show(); - janeBwdIter--; - } - - iter = list.firstIter(); - while ( iter.valid() ) { - iter->show(); - iter++; - } - - tsDLIter < jane > bdIter = janeList.firstIter (); - i = 0; - while ( bdIter.valid () ) { - i++; - bdIter++; - } - verify ( i == janeList.count () ); - - iter = list.firstIter(); - while ( iter.pointer() ) { - list.remove( * iter.pointer() ); - iter++; - } - verify (list.count()==0); - - janeFwdIter = janeList.firstIter(); - while ( janeFwdIter.valid() ) { - janeList.remove( * janeFwdIter.pointer() ); - janeFwdIter++; - } - verify (janeList.count()==0); - - pJane = new jane("JA"); - janeList.add(*pJane); - pJane = new jane("JB"); - janeList.add(*pJane); - janeBwdIter = janeList.lastIter(); - while ( janeBwdIter.valid() ) { - janeList.remove( * janeBwdIter.pointer() ); - janeBwdIter--; - } - verify (janeList.count()==0); - - return 0; -} - diff --git a/src/libCom/cxxTemplates/test/tsSLListBench.cc b/src/libCom/cxxTemplates/test/tsSLListBench.cc deleted file mode 100644 index 0b786dfd3..000000000 --- a/src/libCom/cxxTemplates/test/tsSLListBench.cc +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - - -#include "tsSLList.h" -#include -#include -#include - -/* - * gnuc does not provide this under sunos4 - */ -#if !defined(CLOCKS_PER_SEC) && defined(SUNOS4) -# define CLOCKS_PER_SEC 1000000 -#endif - -class fred : public tsSLNode { -public: - fred() : count(0) {} - void inc () {count++;} -private: - unsigned count; -}; - -class jane : public fred, public tsSLNode { -public: - jane() {} -private: -}; - -#define LOOPCOUNT 100000 - -int main () -{ - tsSLList list; - fred *pFred; - unsigned i; - clock_t clk; - clock_t diff; - double delay; - - for (i=0; i iter ( list.firstIter () ); - while ( iter.valid () ) { - iter->inc (); - iter++; - } - } - diff = clock() - clk; - delay = diff; - delay = delay/CLOCKS_PER_SEC; - delay = delay/LOOPCOUNT; - printf("delay = %15.10f\n", delay); - - pFred = new fred(); - clk = clock(); - { - tsSLIter iter ( list.firstIter () ); - for ( i=0; iinc(); - } - } - diff = clock() - clk; - delay = diff; - delay = delay/CLOCKS_PER_SEC; - delay = delay/LOOPCOUNT; - printf("delay = %15.10f\n", delay); - - return 0; -} - diff --git a/src/libCom/cxxTemplates/test/tsSLListTest.cc b/src/libCom/cxxTemplates/test/tsSLListTest.cc deleted file mode 100644 index 32f96359d..000000000 --- a/src/libCom/cxxTemplates/test/tsSLListTest.cc +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - - -#include "tsSLList.h" -#include -#include - -class fred : public tsSLNode { -public: - fred(const char * const pNameIn) : pName(pNameIn){} - void show () {printf("%s\n", pName);} -private: - const char * const pName; -}; - -class jane : public fred, public tsSLNode { -public: - jane(const char * const pNameIn) : fred(pNameIn){} -private: -}; - -int main () -{ - tsSLList list; - fred *pFred; - fred *pFredII; - fred *pFredBack; - tsSLList janeList; - jane *pJane; - - pFred = new fred("A"); - pFredII = new fred("B"); - - list.add(*pFred); - list.add(*pFredII); - { - tsSLIter iter1 = list.firstIter (); - tsSLIter iter2 = iter1; - tsSLIter iter3 = iter1; - assert ( iter1 == iter3++ ); - assert ( iter3 == ++iter2 ); - list.remove ( *pFredII ); // removes pFred - } - list.add ( *pFred ); - pFredBack = list.get(); - assert (pFredBack == pFred); - pFredBack = list.get(); - assert (pFredBack == pFredII); - list.add(*pFredII); - list.add(*pFred); - while ( list.get () ); - pFredBack = list.get(); - assert (pFredBack == 0); - list.add(*pFred); - list.add(*pFredII); - list.add(* new fred("C")); - list.add(* new fred("D")); - - { - tsSLIter < fred > iter = list.firstIter(); - while ( iter.valid () ) { - iter->show(); - ++iter; - } - } - - pJane = new jane("JA"); - janeList.add(*pJane); - pJane = new jane("JB"); - janeList.add(*pJane); - - { - tsSLIter < jane > iter = janeList.firstIter (); - while ( iter.valid () ) { - iter->show(); - ++iter; - } - } - - { - tsSLIter < fred > iter = list.firstIter (); - while ( iter.valid () ) { - iter->show (); - iter++; - } - } - - while ( list.get () ); - - { - tsSLIter < fred > iter = list.firstIter (); - assert ( ! iter.valid () ); - } - - return 0; -} - diff --git a/src/libCom/cxxTemplates/tsDLList.h b/src/libCom/cxxTemplates/tsDLList.h deleted file mode 100644 index a315ecaab..000000000 --- a/src/libCom/cxxTemplates/tsDLList.h +++ /dev/null @@ -1,684 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * type safe doubly linked list templates - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef tsDLListH_include -#define tsDLListH_include - -template class tsDLList; -template class tsDLIterConst; -template class tsDLIter; - -// -// class tsDLNode -// -// a node in a doubly linked list containing entries of type T -// ( class T must publicly derive from class tsDLNode ) -// -template < class T > -class tsDLNode { -public: - tsDLNode (); - tsDLNode ( const tsDLNode & ); - const tsDLNode & operator = ( const tsDLNode & ); -private: - T * pNext; - T * pPrev; - friend class tsDLList; - friend class tsDLIter; - friend class tsDLIterConst; -}; - -// -// class tsDLList -// -// a doubly linked list containing entries of type T -// ( class T must publicly derive from class tsDLNode ) -// -template < class T > -class tsDLList { -public: - tsDLList (); // create empty list - unsigned count () const; // number of items on list - void add ( T & item ); // add item to end of list - void add ( tsDLList & addList ); // add to end of list - addList left empty - void push ( T & item ); // add item to beginning of list - void push ( tsDLList & pushList ); // add to beg of list - pushList left empty - void remove ( T & item ); // remove item from list - void removeAll ( tsDLList & destination ); - T * get (); // removes first item on list - T * pop (); // same as get () - void insertAfter ( T & item, T & itemBefore ); // insert item immediately after itemBefore - void insertBefore ( T & item, T & itemAfter ); // insert item immediately before itemAfter - int find ( const T & item ) const; // returns -1 if not present, node number if present - T * first ( void ) const; // ptr to first item on list - T * last ( void ) const; // ptr to last item on list - tsDLIterConst firstIter () const; - tsDLIter firstIter (); - tsDLIterConst lastIter () const; - tsDLIter lastIter (); - static tsDLIterConst invalidConstIter (); - static tsDLIter invalidIter (); -private: - T * pFirst; - T * pLast; - unsigned itemCount; - void clear (); - tsDLList ( const tsDLList & ); // not allowed - const tsDLList & operator = ( const tsDLList & ); // not allowed -}; - -// -// class tsDLIterConst -// -// bi-directional iterator for a const doubly linked list -// -template -class tsDLIterConst { -public: - tsDLIterConst (); - bool valid () const; - bool operator == ( const tsDLIterConst & rhs ) const; - bool operator != ( const tsDLIterConst & rhs ) const; - tsDLIterConst & operator = ( const tsDLIterConst & ); - const T & operator * () const; - const T * operator -> () const; - tsDLIterConst & operator ++ (); - tsDLIterConst operator ++ (int); - tsDLIterConst & operator -- (); - tsDLIterConst operator -- (int); - const T * pointer () const; -private: - const T * pEntry; - tsDLIterConst ( const T * pInitialEntry ); - friend class tsDLList ; -}; - -// -// class tsDLIter -// -// bi-directional iterator for a doubly linked list -// -template -class tsDLIter { -public: - tsDLIter (); - bool valid () const; - bool operator == ( const tsDLIter & rhs ) const; - bool operator != ( const tsDLIter & rhs ) const; - tsDLIter & operator = ( const tsDLIter & ); - T & operator * () const; - T * operator -> () const; - tsDLIter & operator ++ (); - tsDLIter operator ++ ( int ); - tsDLIter & operator -- (); - tsDLIter operator -- ( int ); - T * pointer () const; -private: - T * pEntry; - tsDLIter ( T *pInitialEntry ); - friend class tsDLList ; -}; - -/////////////////////////////////// -// tsDLNode member functions -/////////////////////////////////// - -// -// tsDLNode::tsDLNode () -// -template -inline tsDLNode::tsDLNode() : pNext(0), pPrev(0) {} - -template -inline tsDLNode::tsDLNode ( const tsDLNode & ) : - pNext (0), pPrev(0) {} - -// -// tsDLNode::operator = () -// -// when someone tries to copy another node into a node -// do _not_ change the node pointers -// -template -inline const tsDLNode & tsDLNode::operator = ( const tsDLNode & ) -{ - return * this; -} - -////////////////////////////////////// -// tsDLList member functions -////////////////////////////////////// - -// -// tsDLList::tsDLList () -// -template -inline tsDLList::tsDLList () -{ - this->clear (); -} - -// -// tsDLList::count () -// -// (returns the number of items on the list) -// -template -inline unsigned tsDLList::count () const -{ - return this->itemCount; -} - -// -// tsDLList::first () -// -template -inline T * tsDLList::first (void) const -{ - return this->pFirst; -} - -// -// tsDLList::last () -// -template -inline T *tsDLList::last (void) const -{ - return this->pLast; -} - -// -// tsDLList::clear () -// -template -inline void tsDLList::clear () -{ - this->pFirst = 0; - this->pLast = 0; - this->itemCount = 0u; -} - -// -// tsDLList::remove () -// -template -inline void tsDLList::remove ( T &item ) -{ - tsDLNode &theNode = item; - - if ( this->pLast == &item ) { - this->pLast = theNode.pPrev; - } - else { - tsDLNode &nextNode = *theNode.pNext; - nextNode.pPrev = theNode.pPrev; - } - - if ( this->pFirst == &item ) { - this->pFirst = theNode.pNext; - } - else { - tsDLNode &prevNode = *theNode.pPrev; - prevNode.pNext = theNode.pNext; - } - - this->itemCount--; -} - -// -// tsDLList::removeAll () -// -template -inline void tsDLList::removeAll ( - tsDLList & destination ) -{ - destination.pFirst = this->pFirst; - destination.pLast = this->pLast; - destination.itemCount = this->itemCount; - this->pFirst = 0; - this->pLast = 0; - this->itemCount = 0; -} - -// -// tsDLList::get () -// -template -inline T * tsDLList::get() -{ - T *pItem = this->pFirst; - - if ( pItem ) { - this->remove ( *pItem ); - } - - return pItem; -} - -// -// tsDLList::pop () -// -// (returns the first item on the list) -template -inline T * tsDLList::pop () -{ - return this->get (); -} - -// -// tsDLList::add () -// -// adds addList to the end of the list -// (and removes all items from addList) -// -template -inline void tsDLList::add ( tsDLList &addList ) -{ - if ( addList.itemCount != 0u ) { - if ( this->itemCount == 0u ) { - this->pFirst = addList.pFirst; - } - else { - tsDLNode *pLastNode = this->pLast; - tsDLNode *pAddListFirstNode = addList.pFirst; - pLastNode->pNext = addList.pFirst; - pAddListFirstNode->pPrev = addList.pLast; - } - this->pLast = addList.pLast; - this->itemCount += addList.itemCount; - addList.clear(); - } -} - -// -// tsDLList::add () -// -// add an item to the end of the list -// -template -inline void tsDLList::add (T &item) -{ - tsDLNode &theNode = item; - - theNode.pNext = 0; - theNode.pPrev = this->pLast; - - if ( this->itemCount ) { - tsDLNode &lastNode = *this->pLast; - lastNode.pNext = &item; - } - else { - this->pFirst = &item; - } - - this->pLast = &item; - - this->itemCount++; -} - -// -// tsDLList::insertAfter () -// -// place item in the list immediately after itemBefore -// -template -inline void tsDLList::insertAfter (T &item, T &itemBefore) -{ - tsDLNode &nodeItem = item; - tsDLNode &nodeBefore = itemBefore; - - nodeItem.pPrev = &itemBefore; - nodeItem.pNext = nodeBefore.pNext; - nodeBefore.pNext = &item; - - if (nodeItem.pNext) { - tsDLNode *pNextNode = nodeItem.pNext; - pNextNode->pPrev = &item; - } - else { - this->pLast = &item; - } - - this->itemCount++; -} - -// -// tsDLList::insertBefore () -// -// place item in the list immediately before itemAfter -// -template -inline void tsDLList::insertBefore (T &item, T &itemAfter) -{ - tsDLNode &node = item; - tsDLNode &nodeAfter = itemAfter; - - node.pNext = &itemAfter; - node.pPrev = nodeAfter.pPrev; - nodeAfter.pPrev = &item; - - if (node.pPrev) { - tsDLNode &prevNode = *node.pPrev; - prevNode.pNext = &item; - } - else { - this->pFirst = &item; - } - - this->itemCount++; -} - -// -// tsDLList::push () -// -// adds pushList to the beginning of the list -// (and removes all items from pushList) -// -template -inline void tsDLList::push ( tsDLList & pushList ) -{ - if ( pushList.itemCount != 0u ) { - if ( this->itemCount ) { - tsDLNode * pFirstNode = this->pFirst; - tsDLNode * pAddListLastNode = pushList.pLast; - pFirstNode->pPrev = pushList.pLast; - pAddListLastNode->pNext = this->pFirst; - } - else { - this->pLast = pushList.pLast; - } - this->pFirst = pushList.pFirst; - this->itemCount += pushList.itemCount; - pushList.clear(); - } -} - -// -// tsDLList::push () -// -// add an item at the beginning of the list -// -template -inline void tsDLList::push (T &item) -{ - tsDLNode &theNode = item; - theNode.pPrev = 0; - theNode.pNext = this->pFirst; - - if ( this->itemCount ) { - tsDLNode *pFirstNode = this->pFirst; - pFirstNode->pPrev = & item; - } - else { - this->pLast = & item; - } - - this->pFirst = &item; - - this->itemCount++; -} - -// -// tsDLList::find () -// returns -1 if the item isnt on the list -// and the node number (beginning with zero if -// it is) -// -template < class T > -int tsDLList < T > :: find ( const T &item ) const -{ - tsDLIterConst < T > thisItem ( &item ); - tsDLIterConst < T > iter ( this->first () ); - int itemNo = 0; - - while ( iter.valid () ) { - if ( iter == thisItem ) { - return itemNo; - } - itemNo++; - iter++; - } - return -1; -} - -template < class T > -inline tsDLIterConst tsDLList < T > :: firstIter () const -{ - return tsDLIterConst < T > ( this->pFirst ); -} - -template < class T > -inline tsDLIter tsDLList < T > :: firstIter () -{ - return tsDLIter < T > ( this->pFirst ); -} - -template < class T > -inline tsDLIterConst tsDLList < T > :: lastIter () const -{ - return tsDLIterConst < T > ( this->pLast ); -} - -template < class T > -inline tsDLIter tsDLList < T > :: lastIter () -{ - return tsDLIter < T > ( this->pLast ); -} - -template < class T > -inline tsDLIterConst tsDLList < T > :: invalidConstIter () -{ - return tsDLIterConst < T > ( 0 ); -} - -template < class T > -inline tsDLIter tsDLList < T > :: invalidIter () -{ - return tsDLIter < T > ( 0 ); -} - -////////////////////////////////////////// -// tsDLIterConst member functions -////////////////////////////////////////// -template -inline tsDLIterConst::tsDLIterConst ( const T *pInitialEntry ) : - pEntry ( pInitialEntry ) {} - -template -inline tsDLIterConst::tsDLIterConst () : - pEntry ( 0 ) {} - -template -inline bool tsDLIterConst::valid () const -{ - return this->pEntry != 0; -} - -template -inline bool tsDLIterConst::operator == (const tsDLIterConst &rhs) const -{ - return this->pEntry == rhs.pEntry; -} - -template -inline bool tsDLIterConst::operator != (const tsDLIterConst &rhs) const -{ - return this->pEntry != rhs.pEntry; -} - -template -inline tsDLIterConst & tsDLIterConst::operator = ( const tsDLIterConst & rhs ) -{ - this->pEntry = rhs.pEntry; - return *this; -} - -template -inline const T & tsDLIterConst::operator * () const -{ - return *this->pEntry; -} - -template -inline const T * tsDLIterConst::operator -> () const -{ - return this->pEntry; -} - -// -// prefix ++ -// -template -inline tsDLIterConst & tsDLIterConst::operator ++ () -{ - const tsDLNode &node = *this->pEntry; - this->pEntry = node.pNext; - return *this; -} - -// -// postfix ++ -// -template -inline tsDLIterConst tsDLIterConst::operator ++ (int) -{ - const tsDLIterConst tmp = *this; - const tsDLNode &node = *this->pEntry; - this->pEntry = node.pNext; - return tmp; -} - -// -// prefix -- -// -template -inline tsDLIterConst & tsDLIterConst::operator -- () -{ - const tsDLNode &entryNode = *this->pEntry; - this->pEntry = entryNode.pPrev; - return *this; -} - -// -// postfix -- -// -template -inline tsDLIterConst tsDLIterConst::operator -- (int) -{ - const tsDLIterConst tmp = *this; - const tsDLNode &entryNode = *this->pEntry; - this->pEntry = entryNode.pPrev; - return tmp; -} - -template -inline const T * tsDLIterConst::pointer () const -{ - return this->pEntry; -} - -////////////////////////////////////////// -// tsDLIter member functions -////////////////////////////////////////// - -template -inline tsDLIter::tsDLIter ( T * pInitialEntry ) : - pEntry ( pInitialEntry ) {} - -template -inline tsDLIter::tsDLIter () : - pEntry ( 0 ) {} - -template -inline bool tsDLIter::valid () const -{ - return this->pEntry != 0; -} - -template -inline bool tsDLIter::operator == (const tsDLIter &rhs) const -{ - return this->pEntry == rhs.pEntry; -} - -template -inline bool tsDLIter::operator != (const tsDLIter &rhs) const -{ - return this->pEntry != rhs.pEntry; -} - -template -inline tsDLIter & tsDLIter::operator = ( const tsDLIter & rhs ) -{ - this->pEntry = rhs.pEntry; - return *this; -} - -template -inline T & tsDLIter::operator * () const -{ - return *this->pEntry; -} - -template -inline T * tsDLIter::operator -> () const -{ - return this->pEntry; -} - -template -inline tsDLIter & tsDLIter::operator ++ () // prefix ++ -{ - const tsDLNode &entryNode = *this->pEntry; - this->pEntry = entryNode.pNext; - return *this; -} - -template -inline tsDLIter tsDLIter::operator ++ (int) // postfix ++ -{ - const tsDLIter tmp = *this; - const tsDLNode &entryNode = *this->pEntry; - this->pEntry = entryNode.pNext; - return tmp; -} - -template -inline tsDLIter & tsDLIter::operator -- () // prefix -- -{ - const tsDLNode &entryNode = *this->pEntry; - this->pEntry = entryNode.pPrev; - return *this; -} - -template -inline tsDLIter tsDLIter::operator -- (int) // postfix -- -{ - const tsDLIter tmp = *this; - const tsDLNode &entryNode = *this->pEntry; - this->pEntry = entryNode.pPrev; - return tmp; -} - -template -inline T * tsDLIter::pointer () const -{ - return this->pEntry; -} - -#endif // tsDLListH_include - diff --git a/src/libCom/cxxTemplates/tsFreeList.h b/src/libCom/cxxTemplates/tsFreeList.h deleted file mode 100644 index 55787ac6b..000000000 --- a/src/libCom/cxxTemplates/tsFreeList.h +++ /dev/null @@ -1,191 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef tsFreeList_h -#define tsFreeList_h - -/* - * Author: Jeff Hill - */ - -// -// TODO: this should allow free list chaining so that a free -// list (in a different lock domain) is used to provide the -// tsFreeListChunk. -// - -// -// To allow your class to be allocated off of a free list -// using the new operator: -// -// 1) add the following static, private free list data members -// to your class -// -// static tsFreeList < class classXYZ > freeList; -// -// 2) add the following member functions to your class -// -// inline void * classXYZ::operator new ( size_t size ) -// { -// return freeList.allocate ( size ); -// } -// -// inline void classXYZ::operator delete ( void *pCadaver, size_t size ) -// { -// freeList.release ( pCadaver, size ); -// } -// -// NOTES: -// -// 1) A NOOP mutex class may be specified if mutual exclusion isnt required -// -// 2) If you wish to force use of the new operator, then declare your class's -// destructor as a protected member function. -// -// 3) Setting N to zero causes the free list to be bypassed -// - -#ifdef EPICS_FREELIST_DEBUG -# define tsFreeListDebugBypass 1 -# define tsFreeListMemSetNew(P,SIZE) memset ( (P), 0xaa, (SIZE) ) -# define tsFreeListMemSetDelete(P,SIZE) memset ( (P), 0xdd, (SIZE) ) -#else -# define tsFreeListDebugBypass 0 -# define tsFreeListMemSetNew(P,SIZE) -# define tsFreeListMemSetDelete(P,SIZE) -#endif - -#include -#include "string.h" - -#include "compilerDependencies.h" -#include "epicsMutex.h" -#include "epicsGuard.h" - -// ms visual studio 6.0 and before incorrectly -// warn about a missing delete operator if only the -// newly preferred delete operator with a size argument -// is present -#if defined ( _MSC_VER ) && _MSC_VER <= 1200 -# pragma warning ( disable : 4291 ) -#endif - -template < class T > union tsFreeListItem; -template < class T, unsigned N> struct tsFreeListChunk; - -template < class T, unsigned N = 0x400, - class MUTEX = epicsMutex > -class tsFreeList { -public: - tsFreeList (); - ~tsFreeList (); - void * allocate ( size_t size ); - void release ( void * p ); - void release ( void * p, size_t size ); -private: - MUTEX mutex; - tsFreeListItem < T > * pFreeList; - tsFreeListChunk < T, N > * pChunkList; - void * allocateFromNewChunk (); -}; - -template < class T > -union tsFreeListItem { -public: - char pad [ sizeof ( T ) ]; - tsFreeListItem < T > * pNext; -}; - -template < class T, unsigned N = 0x400 > -struct tsFreeListChunk { - tsFreeListItem < T > items [N]; - tsFreeListChunk < T, N > * pNext; -}; - -template < class T, unsigned N, class MUTEX > -inline tsFreeList < T, N, MUTEX > :: tsFreeList () : - pFreeList ( 0 ), pChunkList ( 0 ) {} - -template < class T, unsigned N, class MUTEX > -tsFreeList < T, N, MUTEX > :: ~tsFreeList () -{ - while ( tsFreeListChunk < T, N > *pChunk = this->pChunkList ) { - this->pChunkList = this->pChunkList->pNext; - delete pChunk; - } -} - -template < class T, unsigned N, class MUTEX > -void * tsFreeList < T, N, MUTEX >::allocate ( size_t size ) -{ - if ( size != sizeof ( T ) || N == 0u || tsFreeListDebugBypass ) { - void * p = ::operator new ( size ); - tsFreeListMemSetNew ( p, size ); - return p; - } - - epicsGuard < MUTEX > guard ( this->mutex ); - - tsFreeListItem < T > * p = this->pFreeList; - if ( p ) { - this->pFreeList = p->pNext; - return static_cast < void * > ( p ); - } - return this->allocateFromNewChunk (); -} - -template < class T, unsigned N, class MUTEX > -void * tsFreeList < T, N, MUTEX >::allocateFromNewChunk () -{ - tsFreeListChunk < T, N > * pChunk = - new tsFreeListChunk < T, N >; - - for ( unsigned i=1u; i < N-1; i++ ) { - pChunk->items[i].pNext = &pChunk->items[i+1]; - } - pChunk->items[N-1].pNext = 0; - if ( N > 1 ) { - this->pFreeList = &pChunk->items[1u]; - } - pChunk->pNext = this->pChunkList; - this->pChunkList = pChunk; - - return static_cast ( &pChunk->items[0] ); -} - -template < class T, unsigned N, class MUTEX > -void tsFreeList < T, N, MUTEX >::release ( void * pCadaver, size_t size ) -{ - if ( size != sizeof ( T ) ) { - tsFreeListMemSetDelete ( pCadaver, size ); - ::operator delete ( pCadaver ); - } - else { - this->release ( pCadaver ); - } -} - -template < class T, unsigned N, class MUTEX > -void tsFreeList < T, N, MUTEX >::release ( void * pCadaver ) -{ - if ( N == 0u || tsFreeListDebugBypass ) { - tsFreeListMemSetDelete ( pCadaver, sizeof ( T ) ); - ::operator delete ( pCadaver ); - } - else if ( pCadaver ) { - epicsGuard < MUTEX > guard ( this->mutex ); - tsFreeListItem < T > * p = - static_cast < tsFreeListItem < T > * > ( pCadaver ); - p->pNext = this->pFreeList; - this->pFreeList = p; - } -} - -#endif // tsFreeList_h diff --git a/src/libCom/cxxTemplates/tsMinMax.h b/src/libCom/cxxTemplates/tsMinMax.h deleted file mode 100644 index 5adac3ef2..000000000 --- a/src/libCom/cxxTemplates/tsMinMax.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -// -// simple type safe inline template functions to replace -// the min() and max() macros -// - -#ifndef tsMinMaxh -#define tsMinMaxh - -template -inline const T & tsMax ( const T & a, const T & b ) -{ - return ( a > b ) ? a : b; -} - -template -inline const T & tsMin ( const T & a, const T & b ) -{ - return ( a < b ) ? a : b; -} - -#endif // tsMinMaxh diff --git a/src/libCom/cxxTemplates/tsSLList.h b/src/libCom/cxxTemplates/tsSLList.h deleted file mode 100644 index ce29a6f5c..000000000 --- a/src/libCom/cxxTemplates/tsSLList.h +++ /dev/null @@ -1,443 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * type safe singly linked list templates - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef tsSLListh -#define tsSLListh - -#ifndef assert // allow use of epicsAssert.h -#include -#endif - -// -// the hp compiler complains about parameterized friend -// class that has not been declared without this? -// -template < class T > class tsSLList; -template < class T > class tsSLIter; -template < class T > class tsSLIterConst; - -// -// tsSLNode -// NOTE: class T must derive from tsSLNode -// -template -class tsSLNode { -public: - tsSLNode (); - tsSLNode < T > & operator = ( const tsSLNode < T > & ); -private: - void removeNextItem (); // removes the item after this node - T *pNext; - tsSLNode ( const tsSLNode < T > & ); - friend class tsSLList < T >; - friend class tsSLIter < T >; - friend class tsSLIterConst < T >; -}; - - -// -// tsSLList -// NOTE: class T must derive from tsSLNode -// -template < class T > -class tsSLList : public tsSLNode < T > { -public: - tsSLList (); // creates an empty list - tsSLList ( tsSLList & ); - void insert ( T &item, tsSLNode < T > &itemBefore ); // insert after item before - void add ( T &item ); // add to the beginning of the list - T * get (); // remove from the beginning of the list - T * pop (); // same as get - void push ( T &item ); // same as add - T * first () const; - void remove ( T &itemBefore ); - tsSLIterConst firstIter () const; - tsSLIter firstIter (); - static tsSLIterConst invalidConstIter (); - static tsSLIter invalidIter (); -private: - const tsSLList < T > & operator = ( const tsSLList < T > & ); -}; - -// -// tsSLIterConst -// -template < class T > -class tsSLIterConst { -public: - tsSLIterConst (); - bool valid () const; - bool operator == (const tsSLIterConst &rhs) const; - bool operator != (const tsSLIterConst &rhs) const; - tsSLIterConst & operator = (const tsSLIterConst &); - const T & operator * () const; - const T * operator -> () const; - tsSLIterConst & operator ++ (); - tsSLIterConst operator ++ (int); - const T * pointer () const; -protected: - const T * pEntry; - tsSLIterConst ( const T *pInitialEntry ); - friend class tsSLList < T >; -}; - -// -// tsSLIter -// -template < class T > -class tsSLIter { -public: - tsSLIter (); - bool valid () const; - bool operator == (const tsSLIter &rhs) const; - bool operator != (const tsSLIter &rhs) const; - tsSLIter & operator = (const tsSLIter &); - T & operator * () const; - T * operator -> () const; - tsSLIter & operator ++ (); - tsSLIter operator ++ (int); - T * pointer () const; -private: - T *pEntry; - tsSLIter ( T *pInitialEntry ); - friend class tsSLList < T >; -}; - -////////////////////////////////////////// -// -// tsSLNode inline member functions -// -////////////////////////////////////////// - -// -// tsSLNode::tsSLNode () -// -template < class T > -inline tsSLNode < T > :: tsSLNode () : pNext ( 0 ) {} - -// -// tsSLNode::tsSLNode ( const tsSLNode < T > & ) -// private - not to be used - implemented to eliminate warnings -// -template < class T > -inline tsSLNode < T > :: tsSLNode ( const tsSLNode < T > & ) -{ -} - -// -// tsSLNode::operator = -// -// when someone copies into a class deriving from this -// do _not_ change the node pointers -// -template < class T > -inline tsSLNode < T > & tsSLNode < T >::operator = - ( const tsSLNode < T > & ) -{ - return *this; -} - -// -// removeNextItem () -// -// removes the item after this node -// -template -inline void tsSLNode::removeNextItem () -{ - T *pItem = this->pNext; - if ( pItem ) { - tsSLNode < T > *pNode = pItem; - this->pNext = pNode->pNext; - } -} - -////////////////////////////////////////// -// -// tsSLList inline member functions -// -////////////////////////////////////////// - -// -// tsSLList::tsSLList() -// create an empty list -// -template < class T > -inline tsSLList < T > :: tsSLList () -{ -} - -// -// tsSLList::tsSLList( tsSLList & ) -// -template < class T > -inline tsSLList < T > :: tsSLList ( tsSLList &listIn ) -{ - this->pNext = listIn.pNext; - listIn.pNext = 0; -} - -// -// tsSLList::insert() -// (itemBefore might be the list header object and therefore -// will not always be of type T) -// -template < class T > -inline void tsSLList < T > :: insert ( T &item, tsSLNode < T > &itemBefore ) -{ - tsSLNode < T > &node = item; - node.pNext = itemBefore.pNext; - itemBefore.pNext = &item; -} - -// -// tsSLList::add () -// -template < class T > -inline void tsSLList < T > :: add ( T &item ) -{ - this->insert ( item, *this ); -} - -// -// tsSLList::get () -// -template < class T > -inline T * tsSLList < T > :: get () -{ - tsSLNode < T > *pThisNode = this; - T *pItem = pThisNode->pNext; - pThisNode->removeNextItem (); - return pItem; -} - -// -// tsSLList::pop () -// -template < class T > -inline T * tsSLList < T > :: pop () -{ - return this->get (); -} - -// -// tsSLList::push () -// -template -inline void tsSLList < T > :: push ( T &item ) -{ - this->add (item); -} - -template -inline T * tsSLList < T > :: first () const -{ - const tsSLNode < T > *pThisNode = this; - return pThisNode->pNext; -} - -template -inline void tsSLList < T > :: remove ( T &itemBefore ) -{ - tsSLNode < T > *pBeforeNode = &itemBefore; - tsSLNode < T > *pAfterNode = pBeforeNode->pNext; - pBeforeNode->pNext = pAfterNode->pNext; -} - -template -inline tsSLIterConst tsSLList < T > :: firstIter () const -{ - const tsSLNode < T > *pThisNode = this; - return tsSLIterConst ( pThisNode->pNext ); -} - -template -inline tsSLIter tsSLList < T > :: firstIter () -{ - tsSLNode < T > *pThisNode = this; - return tsSLIter ( pThisNode->pNext ); -} - -template -inline tsSLIterConst tsSLList < T > :: invalidConstIter () -{ - return tsSLIterConst ( 0 ); -} - -template -inline tsSLIter tsSLList < T > :: invalidIter () -{ - return tsSLIter ( 0 ); -} - -////////////////////////////////////////// -// -// tsSLIterConst inline member functions -// -////////////////////////////////////////// - -template < class T > -inline tsSLIterConst::tsSLIterConst ( const T *pInitialEntry ) : - pEntry ( pInitialEntry ) -{ -} - -template < class T > -inline tsSLIterConst::tsSLIterConst () : - pEntry ( 0 ) -{ -} - -template < class T > -inline bool tsSLIterConst::valid () const -{ - return this->pEntry != 0; -} - -template < class T > -inline bool tsSLIterConst::operator == ( const tsSLIterConst &rhs ) const -{ - return this->pEntry == rhs.pConstEntry; -} - -template < class T > -inline bool tsSLIterConst::operator != (const tsSLIterConst &rhs) const -{ - return this->pEntry != rhs.pConstEntry; -} - -template < class T > -inline tsSLIterConst & tsSLIterConst::operator = ( const tsSLIterConst & rhs ) -{ - this->pEntry = rhs.pEntry; - return *this; -} - -template < class T > -inline const T & tsSLIterConst::operator * () const -{ - return *this->pEntry; -} - -template < class T > -inline const T * tsSLIterConst::operator -> () const -{ - return this->pEntry; -} - -template < class T > -inline tsSLIterConst & tsSLIterConst::operator ++ () // prefix ++ -{ - const tsSLNode < T > *pCurNode = this->pEntry; - this->pEntry = pCurNode->pNext; - return *this; -} - -template < class T > -inline tsSLIterConst tsSLIterConst::operator ++ ( int ) // postfix ++ -{ - const tsSLIterConst tmp = *this; - const tsSLNode < T > *pCurNode = this->pEntry; - this->pEntry = pCurNode->pNext; - return tmp; -} - -template -inline const T * tsSLIterConst < T > :: pointer () const -{ - return this->pEntry; -} - -////////////////////////////////////////// -// -// tsSLIter inline member functions -// -////////////////////////////////////////// - -template < class T > -inline tsSLIter::tsSLIter ( T *pInitialEntry ) : - pEntry ( pInitialEntry ) -{ -} - -template < class T > -inline tsSLIter::tsSLIter () : - pEntry ( 0 ) -{ -} - -template < class T > -inline bool tsSLIter::valid () const -{ - return this->pEntry != 0; -} - -template < class T > -inline bool tsSLIter::operator == ( const tsSLIter &rhs ) const -{ - return this->pEntry == rhs.pEntry; -} - -template < class T > -inline bool tsSLIter::operator != ( const tsSLIter &rhs ) const -{ - return this->pEntry != rhs.pEntry; -} - -template < class T > -inline tsSLIter & tsSLIter::operator = ( const tsSLIter & rhs ) -{ - this->pEntry = rhs.pEntry; - return *this; -} - -template < class T > -inline T & tsSLIter::operator * () const -{ - return *this->pEntry; -} - -template < class T > -inline T * tsSLIter::operator -> () const -{ - return this->pEntry; -} - -template < class T > -inline tsSLIter & tsSLIter::operator ++ () // prefix ++ -{ - const tsSLNode < T > *pCurNode = this->pEntry; - this->pEntry = pCurNode->pNext; - return *this; -} - -template < class T > -inline tsSLIter tsSLIter::operator ++ ( int ) // postfix ++ -{ - const tsSLIter tmp = *this; - const tsSLNode < T > *pCurNode = this->pEntry; - this->pEntry = pCurNode->pNext; - return tmp; -} - -template -inline T * tsSLIter < T > :: pointer () const -{ - return this->pEntry; -} - -#endif // tsSLListh diff --git a/src/libCom/dbmf/Makefile b/src/libCom/dbmf/Makefile deleted file mode 100644 index 2a190eac6..000000000 --- a/src/libCom/dbmf/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/dbmf -INC += dbmf.h -Com_SRCS += dbmf.c - diff --git a/src/libCom/dbmf/dbmf.c b/src/libCom/dbmf/dbmf.c deleted file mode 100644 index e04a7bedf..000000000 --- a/src/libCom/dbmf/dbmf.c +++ /dev/null @@ -1,299 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jim Kowalkowski and Marty Kraimer - * Date: 4/97 - * - * Intended for applications that create and free requently - * - */ - -#include -#include -#include -#include - -#include "valgrind/valgrind.h" - -#ifndef NVALGRIND -/* buffer around allocations to detect out of bounds access */ -#define REDZONE sizeof(double) -#else -#define REDZONE 0 -#endif - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsMutex.h" -#include "ellLib.h" -#include "dbmf.h" -/* -#define DBMF_FREELIST_DEBUG 1 -*/ -#ifndef DBMF_FREELIST_DEBUG - -/*Default values for dblfInit */ -#define DBMF_SIZE 64 -#define DBMF_INITIAL_ITEMS 10 - -typedef struct chunkNode {/*control block for each set of chunkItems*/ - ELLNODE node; - void *pchunk; - int nNotFree; -}chunkNode; - -typedef struct itemHeader{ - void *pnextFree; - chunkNode *pchunkNode; -}itemHeader; - -typedef struct dbmfPrivate { - ELLLIST chunkList; - epicsMutexId lock; - size_t size; - size_t allocSize; - int chunkItems; - size_t chunkSize; - int nAlloc; - int nFree; - int nGtSize; - void *freeList; -} dbmfPrivate; -dbmfPrivate dbmfPvt; -static dbmfPrivate *pdbmfPvt = NULL; -int dbmfDebug=0; - -int dbmfInit(size_t size, int chunkItems) -{ - if(pdbmfPvt) { - printf("dbmfInit: Already initialized\n"); - return(-1); - } - pdbmfPvt = &dbmfPvt; - ellInit(&pdbmfPvt->chunkList); - pdbmfPvt->lock = epicsMutexMustCreate(); - /*allign to at least a double*/ - pdbmfPvt->size = size + size%sizeof(double); - /* layout is - * | itemHeader | REDZONE | size | REDZONE | - */ - pdbmfPvt->allocSize = pdbmfPvt->size + sizeof(itemHeader) + 2*REDZONE; - pdbmfPvt->chunkItems = chunkItems; - pdbmfPvt->chunkSize = pdbmfPvt->allocSize * pdbmfPvt->chunkItems; - pdbmfPvt->nAlloc = 0; - pdbmfPvt->nFree = 0; - pdbmfPvt->nGtSize = 0; - pdbmfPvt->freeList = NULL; - VALGRIND_CREATE_MEMPOOL(pdbmfPvt, REDZONE, 0); - return(0); -} - - -void* dbmfMalloc(size_t size) -{ - void **pnextFree; - void **pfreeList; - char *pmem = NULL; - chunkNode *pchunkNode; - itemHeader *pitemHeader; - - if(!pdbmfPvt) dbmfInit(DBMF_SIZE,DBMF_INITIAL_ITEMS); - epicsMutexMustLock(pdbmfPvt->lock); - pfreeList = &pdbmfPvt->freeList; - if(*pfreeList == NULL) { - int i; - size_t nbytesTotal; - - if(dbmfDebug) printf("dbmfMalloc allocating new storage\n"); - nbytesTotal = pdbmfPvt->chunkSize + sizeof(chunkNode); - pmem = (char *)malloc(nbytesTotal); - if(!pmem) { - epicsMutexUnlock(pdbmfPvt->lock); - cantProceed("dbmfMalloc malloc failed\n"); - return(NULL); - } - pchunkNode = (chunkNode *)(pmem + pdbmfPvt->chunkSize); - pchunkNode->pchunk = pmem; - pchunkNode->nNotFree=0; - ellAdd(&pdbmfPvt->chunkList,&pchunkNode->node); - for(i=0; ichunkItems; i++) { - pitemHeader = (itemHeader *)pmem; - pitemHeader->pchunkNode = pchunkNode; - pnextFree = &pitemHeader->pnextFree; - *pnextFree = *pfreeList; *pfreeList = (void *)pmem; - pdbmfPvt->nFree++; - pmem += pdbmfPvt->allocSize; - } - } - if(size<=pdbmfPvt->size) { - pnextFree = *pfreeList; *pfreeList = *pnextFree; - pmem = (void *)pnextFree; - pdbmfPvt->nAlloc++; pdbmfPvt->nFree--; - pitemHeader = (itemHeader *)pnextFree; - pitemHeader->pchunkNode->nNotFree += 1; - } else { - pmem = malloc(sizeof(itemHeader) + 2*REDZONE + size); - if(!pmem) { - epicsMutexUnlock(pdbmfPvt->lock); - cantProceed("dbmfMalloc malloc failed\n"); - return(NULL); - } - pdbmfPvt->nAlloc++; - pdbmfPvt->nGtSize++; - pitemHeader = (itemHeader *)pmem; - pitemHeader->pchunkNode = NULL; /* not part of free list */ - if(dbmfDebug) printf("dbmfMalloc: size %lu mem %p\n", - (unsigned long)size,pmem); - } - epicsMutexUnlock(pdbmfPvt->lock); - pmem += sizeof(itemHeader) + REDZONE; - VALGRIND_MEMPOOL_ALLOC(pdbmfPvt, pmem, size); - return((void *)pmem); -} - -char * dbmfStrdup(const char *str) -{ - size_t len = strlen(str); - char *buf = dbmfMalloc(len + 1); /* FIXME Can return NULL */ - - return strcpy(buf, str); -} - -char * dbmfStrndup(const char *str, size_t len) -{ - char *buf = dbmfMalloc(len + 1); /* FIXME Can return NULL */ - - buf[len] = '\0'; - return strncpy(buf, str, len); -} - -void dbmfFree(void* mem) -{ - char *pmem = (char *)mem; - chunkNode *pchunkNode; - itemHeader *pitemHeader; - - if(!mem) return; - if(!pdbmfPvt) { - printf("dbmfFree called but dbmfInit never called\n"); - return; - } - VALGRIND_MEMPOOL_FREE(pdbmfPvt, mem); - pmem -= sizeof(itemHeader) + REDZONE; - epicsMutexMustLock(pdbmfPvt->lock); - pitemHeader = (itemHeader *)pmem; - if(!pitemHeader->pchunkNode) { - if(dbmfDebug) printf("dbmfGree: mem %p\n",pmem); - free((void *)pmem); pdbmfPvt->nAlloc--; - }else { - void **pfreeList = &pdbmfPvt->freeList; - void **pnextFree = &pitemHeader->pnextFree; - - pchunkNode = pitemHeader->pchunkNode; - pchunkNode->nNotFree--; - *pnextFree = *pfreeList; *pfreeList = pnextFree; - pdbmfPvt->nAlloc--; pdbmfPvt->nFree++; - } - epicsMutexUnlock(pdbmfPvt->lock); -} - -int dbmfShow(int level) -{ - if(pdbmfPvt==NULL) { - printf("Never initialized\n"); - return(0); - } - printf("size %lu allocSize %lu chunkItems %d ", - (unsigned long)pdbmfPvt->size, - (unsigned long)pdbmfPvt->allocSize,pdbmfPvt->chunkItems); - printf("nAlloc %d nFree %d nChunks %d nGtSize %d\n", - pdbmfPvt->nAlloc,pdbmfPvt->nFree, - ellCount(&pdbmfPvt->chunkList),pdbmfPvt->nGtSize); - if(level>0) { - chunkNode *pchunkNode; - - pchunkNode = (chunkNode *)ellFirst(&pdbmfPvt->chunkList); - while(pchunkNode) { - printf("pchunkNode %p nNotFree %d\n", - (void*)pchunkNode,pchunkNode->nNotFree); - pchunkNode = (chunkNode *)ellNext(&pchunkNode->node); - } - } - if(level>1) { - void **pnextFree;; - - epicsMutexMustLock(pdbmfPvt->lock); - pnextFree = (void**)pdbmfPvt->freeList; - while(pnextFree) { - printf("%p\n",*pnextFree); - pnextFree = (void**)*pnextFree; - } - epicsMutexUnlock(pdbmfPvt->lock); - } - return(0); -} - -void dbmfFreeChunks(void) -{ - chunkNode *pchunkNode; - chunkNode *pnext;; - - if(!pdbmfPvt) { - printf("dbmfFreeChunks called but dbmfInit never called\n"); - return; - } - epicsMutexMustLock(pdbmfPvt->lock); - if(pdbmfPvt->nFree - != (pdbmfPvt->chunkItems * ellCount(&pdbmfPvt->chunkList))) { - printf("dbmfFinish: not all free\n"); - epicsMutexUnlock(pdbmfPvt->lock); - return; - } - pchunkNode = (chunkNode *)ellFirst(&pdbmfPvt->chunkList); - while(pchunkNode) { - pnext = (chunkNode *)ellNext(&pchunkNode->node); - ellDelete(&pdbmfPvt->chunkList,&pchunkNode->node); - free(pchunkNode->pchunk); - pchunkNode = pnext; - } - pdbmfPvt->nFree = 0; pdbmfPvt->freeList = NULL; - epicsMutexUnlock(pdbmfPvt->lock); -} - -#else /* DBMF_FREELIST_DEBUG */ - -int dbmfInit(size_t size, int chunkItems) -{ return 0; } - -void* dbmfMalloc(size_t size) -{ return malloc(size); } - -char * dbmfStrdup(const char *str) -{ return strdup((char*)str); } - -void dbmfFree(void* mem) -{ free(mem); } - -int dbmfShow(int level) -{ return 0; } - -void dbmfFreeChunks(void) {} - -#endif /* DBMF_FREELIST_DEBUG */ - -char * dbmfStrcat3(const char *lhs, const char *mid, const char *rhs) -{ - size_t len = strlen(lhs) + strlen(mid) + strlen(rhs) + 1; - char *buf = dbmfMalloc(len); - strcpy(buf, lhs); - strcat(buf, mid); - strcat(buf, rhs); - return buf; -} - diff --git a/src/libCom/dbmf/dbmf.h b/src/libCom/dbmf/dbmf.h deleted file mode 100644 index 2c8a28f2c..000000000 --- a/src/libCom/dbmf/dbmf.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jim Kowalkowski and Marty Kraimer - * Date: 4/97 - * - * A library to manage storage that is allocated and then freed. - */ -#ifndef DBMF_H -#define DBMF_H - -#include -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int dbmfInit(size_t size, int chunkItems); -epicsShareFunc void * dbmfMalloc(size_t bytes); -epicsShareFunc char * dbmfStrdup(const char *str); -epicsShareFunc char * dbmfStrndup(const char *str, size_t len); -epicsShareFunc char * dbmfStrcat3(const char *lhs, const char *mid, - const char *rhs); -epicsShareFunc void dbmfFree(void *bytes); -epicsShareFunc void dbmfFreeChunks(void); -epicsShareFunc int dbmfShow(int level); - -/* Rules: - * 1) Size is always made a multiple of 8. - * 2) if dbmfInit is not called before one of the other routines then it - * is automatically called with size=64 and chunkItems=10 - * 3) These routines should only be used to allocate storage that will - * shortly thereafter be freed. - * 4) dbmfFreeChunks can only free chunks that contain only free items -*/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/ellLib/Makefile b/src/libCom/ellLib/Makefile deleted file mode 100644 index 9a5cb3e67..000000000 --- a/src/libCom/ellLib/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/ellLib -INC += ellLib.h -Com_SRCS += ellLib.c -Com_SRCS += ellSort.c diff --git a/src/libCom/ellLib/ellLib.c b/src/libCom/ellLib/ellLib.c deleted file mode 100644 index c539a843f..000000000 --- a/src/libCom/ellLib/ellLib.c +++ /dev/null @@ -1,331 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: John Winans (ANL) - * Date: 07-02-92 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "ellLib.h" - - /**************************************************************************** - * - * This function adds a node to the end of a linked list. - * - *****************************************************************************/ -void ellAdd (ELLLIST *pList, ELLNODE *pNode) -{ - pNode->next = NULL; - pNode->previous = pList->node.previous; - - if (pList->count) - pList->node.previous->next = pNode; - else - pList->node.next = pNode; - - pList->node.previous = pNode; - pList->count++; - - return; -} - /**************************************************************************** - * - * This function concatinates the second linked list to the end of the first - * list. The second list is left empty. Either list (or both) lists may - * be empty at the begining of the operation. - * - *****************************************************************************/ -void ellConcat (ELLLIST *pDstList, ELLLIST *pAddList) -{ - if (pAddList->count == 0) - return; /* Add list is empty, nothing to add. */ - - if (pDstList->count == 0) { - /* Destination list is empty... just transfer the add list over. */ - pDstList->node.next = pAddList->node.next; - pDstList->node.previous = pAddList->node.previous; - pDstList->count = pAddList->count; - } else { - /* Destination list not empty... append the add list. */ - pDstList->node.previous->next = pAddList->node.next; - pAddList->node.next->previous = pDstList->node.previous; - pDstList->node.previous = pAddList->node.previous; - pDstList->count += pAddList->count; - } - - pAddList->count = 0; - pAddList->node.next = NULL; - pAddList->node.previous = NULL; - - return; -} - /**************************************************************************** - * - * This function deletes a specific node from a specified list; - * - *****************************************************************************/ -void ellDelete (ELLLIST *pList, ELLNODE *pNode) -{ - if (pList->node.previous == pNode) - pList->node.previous = pNode->previous; - else - pNode->next->previous = pNode->previous; - - if (pList->node.next == pNode) - pList->node.next = pNode->next; - else - pNode->previous->next = pNode->next; - - pList->count--; - - return; -} - /**************************************************************************** - * - * This function extracts a sublist that starts with pStartNode and ends with - * pEndNode from pSrcList and places it in pDstList. - * - * WRS is unclear as to what happens when pDstList is non-empty at the start - * of the operation. We will place the extracted list at the END of pDstList - * when it is non-empty. - * - *****************************************************************************/ -void ellExtract (ELLLIST *pSrcList, ELLNODE *pStartNode, ELLNODE *pEndNode, ELLLIST *pDstList) -{ - ELLNODE *pnode; - int count; - - /* Cut the list out of the source list (update count later) */ - if (pStartNode->previous != NULL) - pStartNode->previous->next = pEndNode->next; - else - pSrcList->node.next = pEndNode->next; - - if (pEndNode->next != NULL) { - pEndNode->next->previous = pStartNode->previous; - pEndNode->next = NULL; - } - else - pSrcList->node.previous = pStartNode->previous; - - /* Place the sublist into the destination list */ - pStartNode->previous = pDstList->node.previous; - if (pDstList->count) - pDstList->node.previous->next = pStartNode; - else - pDstList->node.next = pStartNode; - - pDstList->node.previous = pEndNode; - - /* Adjust the counts */ - pnode = pStartNode; - count = 1; - while(pnode != pEndNode) - { - pnode = pnode->next; - count++; - } - pSrcList->count -= count; - pDstList->count += count; - - return; -} - /**************************************************************************** - * - * This function returns the first node in the specified list. The node is - * removed from the list. If the list is empty, NULL will be returned. - * - *****************************************************************************/ -ELLNODE * ellGet (ELLLIST *pList) -{ - ELLNODE *pnode = pList->node.next; - - if (pnode != NULL) - ellDelete(pList, pnode); - - return pnode; -} -/**************************************************************************** -* -* This function returns the last node in the specified list. The node is -* removed from the list. If the list is empty, NULL will be returned. -* -*****************************************************************************/ -ELLNODE * ellPop (ELLLIST *pList) -{ - ELLNODE *pnode = pList->node.previous; - - if (pnode != NULL) - ellDelete(pList, pnode); - - return pnode; -} - /**************************************************************************** - * - * This function inserts the specified node pNode after pPrev in the list - * plist. If pPrev is NULL, then pNode will be inserted at the head of the - * list. - * - *****************************************************************************/ -void ellInsert (ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode) -{ - if (pPrev != NULL) { - pNode->previous = pPrev; - pNode->next = pPrev->next; - pPrev->next = pNode; - } else { - pNode->previous = NULL; - pNode->next = plist->node.next; - plist->node.next = pNode; - } - - if (pNode->next == NULL) - plist->node.previous = pNode; - else - pNode->next->previous = pNode; - - plist->count++; - - return; -} - /**************************************************************************** - * - * This function returns the nodeNum'th element in pList. If there is no - * nodeNum'th node in the list, NULL will be returned. - * - *****************************************************************************/ -ELLNODE * ellNth (ELLLIST *pList, int nodeNum) -{ - ELLNODE *pnode; - - if ((nodeNum < 1) || (pList->count == 0)) - return NULL; - - if (nodeNum > pList->count/2) { - if (nodeNum > pList->count) - return NULL; - - pnode = pList->node.previous; - nodeNum = pList->count - nodeNum; - while(nodeNum) { - pnode = pnode->previous; - nodeNum--; - } - return pnode; - } - - pnode = pList->node.next; - while (--nodeNum > 0) - pnode = pnode->next; - - return pnode; -} - /**************************************************************************** - * - * This function returns the node, nStep nodes forward from pNode. If there is - * no node that many steps from pNode, NULL will be returned. - * - *****************************************************************************/ -ELLNODE * ellNStep (ELLNODE *pNode, int nStep) -{ - if (nStep > 0) { - while ((pNode != NULL) && nStep) { - pNode = pNode->next; - nStep--; - } - } else { - while ((pNode != NULL) && nStep) { - pNode = pNode->previous; - nStep++; - } - } - return pNode; -} - /**************************************************************************** - * - * This function returns the node number of pNode within pList. If the node is - * not in pList, -1 is returned. Note that the first node is 1. - * - *****************************************************************************/ -int ellFind (ELLLIST *pList, ELLNODE *pNode) -{ - ELLNODE *got = pList->node.next; - int count = 1; - - while ((got != pNode) && (got != NULL)) { - got = got->next; - count++; - } - if (got == NULL) - return -1; - - return count; -} - /**************************************************************************** - * - * This function frees the nodes in a list. It makes the list into an empty - * list, and calls freeFunc() for all the nodes that are (were) in that list. - * - * NOTE: the nodes in the list are free()'d on the assumption that the node - * structures were malloc()'d one-at-a-time and that the ELLNODE structure is - * the first member of the parent structure. - * - *****************************************************************************/ -void ellFree2 (ELLLIST *pList, FREEFUNC freeFunc) -{ - ELLNODE *nnode = pList->node.next; - ELLNODE *pnode; - - while (nnode != NULL) - { - pnode = nnode; - nnode = nnode->next; - freeFunc(pnode); - } - pList->node.next = NULL; - pList->node.previous = NULL; - pList->count = 0; -} - - /**************************************************************************** - * - * This function verifies that the list is consistent. - * joh 12-12-97 - * - *****************************************************************************/ -void ellVerify (ELLLIST *pList) -{ - ELLNODE *pNode; - ELLNODE *pNext; - int count = 0; - - assert (pList); - - pNode = ellFirst(pList); - if (pNode) { - assert (ellPrevious(pNode) == NULL); - while (1) { - count++; - pNext = ellNext(pNode); - if (pNext) { - assert (ellPrevious(pNext) == pNode); - } else { - break; - } - pNode = pNext; - } - assert (ellNext(pNode) == NULL); - } - - assert (pNode == ellLast(pList)); - assert (count == ellCount(pList)); -} diff --git a/src/libCom/ellLib/ellLib.h b/src/libCom/ellLib/ellLib.h deleted file mode 100644 index 52b58d169..000000000 --- a/src/libCom/ellLib/ellLib.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: John Winans (ANL) - * Andrew Johnson - */ -#ifndef INC_ellLib_H -#define INC_ellLib_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct ELLNODE { - struct ELLNODE *next; - struct ELLNODE *previous; -} ELLNODE; - -#define ELLNODE_INIT {NULL, NULL} - -typedef struct ELLLIST { - ELLNODE node; - int count; -} ELLLIST; - -#define ELLLIST_INIT {ELLNODE_INIT, 0} - -typedef void (*FREEFUNC)(void *); - -#define ellInit(PLIST) {\ - (PLIST)->node.next = (PLIST)->node.previous = NULL;\ - (PLIST)->count = 0;\ -} -#define ellCount(PLIST) ((PLIST)->count) -#define ellFirst(PLIST) ((PLIST)->node.next) -#define ellLast(PLIST) ((PLIST)->node.previous) -#define ellNext(PNODE) ((PNODE)->next) -#define ellPrevious(PNODE) ((PNODE)->previous) -#define ellFree(PLIST) ellFree2(PLIST, free) - -epicsShareFunc void ellAdd (ELLLIST *pList, ELLNODE *pNode); -epicsShareFunc void ellConcat (ELLLIST *pDstList, ELLLIST *pAddList); -epicsShareFunc void ellDelete (ELLLIST *pList, ELLNODE *pNode); -epicsShareFunc void ellExtract (ELLLIST *pSrcList, ELLNODE *pStartNode, ELLNODE *pEndNode, ELLLIST *pDstList); -epicsShareFunc ELLNODE * ellGet (ELLLIST *pList); -epicsShareFunc ELLNODE * ellPop (ELLLIST *pList); -epicsShareFunc void ellInsert (ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode); -epicsShareFunc ELLNODE * ellNth (ELLLIST *pList, int nodeNum); -epicsShareFunc ELLNODE * ellNStep (ELLNODE *pNode, int nStep); -epicsShareFunc int ellFind (ELLLIST *pList, ELLNODE *pNode); -typedef int (*pListCmp)(const ELLNODE* A, const ELLNODE* B); -epicsShareFunc void ellSortStable(ELLLIST *pList, pListCmp); -epicsShareFunc void ellFree2 (ELLLIST *pList, FREEFUNC freeFunc); -epicsShareFunc void ellVerify (ELLLIST *pList); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_ellLib_H */ diff --git a/src/libCom/ellLib/ellSort.c b/src/libCom/ellLib/ellSort.c deleted file mode 100644 index 2f8f2748b..000000000 --- a/src/libCom/ellLib/ellSort.c +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Assoc., as Operator of Argonne -* National Laboratory. -* Copyright (c) 2016 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Use of mergesort algorithm based on analysis by - * http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html - */ -#include - -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "ellLib.h" - -static void ellMoveN(ELLLIST* pTo, ELLLIST* pFrom, int count ) -{ - for(;count && ellCount(pFrom); count--) { - ELLNODE *node = ellGet(pFrom); - ellAdd(pTo, node); - } -} - -/* Stable (MergeSort) to given list. - * The comparison function cmp(A,B) is expected - * to return -1 for AB. - */ -void ellSortStable(ELLLIST *pList, pListCmp cmp) -{ - ELLLIST INP, P, Q; - size_t insize = 1; /* initial sub-list size */ - if(ellCount(pList)<=1) - return; - - ellInit(&INP); - ellInit(&P); - ellInit(&Q); - - /* Process is to iteratively sort - * a sequence of sub-lists of size 'insize' - */ - - while(insize < ellCount(pList)) { - - assert(ellCount(&INP)==0); - - /* shift previous results to inputs */ - ellConcat(&INP, pList); - - while(ellCount(&INP)) - { - ELLNODE *p, *q; - - /* Pull out the next pair of sub-lists */ - ellMoveN(&Q, &INP, insize); - ellMoveN(&P, &INP, insize); - - /* merge these sub-lists */ - while((p=ellFirst(&P)) && (q=ellFirst(&Q))) - { - if((*cmp)(p,q) < 0) { - ellAdd(pList, ellGet(&P)); - } else { - ellAdd(pList, ellGet(&Q)); - } - } - - /* concatenate any remaining to result */ - if(ellFirst(&P)) - ellConcat(pList, &P); - else if(ellFirst(&Q)) - ellConcat(pList, &Q); - - assert(!ellFirst(&P) && !ellFirst(&Q)); - } - - insize *= 2; - } - -} diff --git a/src/libCom/env/Makefile b/src/libCom/env/Makefile deleted file mode 100644 index 69c9d253b..000000000 --- a/src/libCom/env/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/env - -INC += envDefs.h - -Com_SRCS += envSubr.c -Com_SRCS += envData.c - -CLEANS += envData.c diff --git a/src/libCom/env/RULES b/src/libCom/env/RULES deleted file mode 100644 index 2737d5d4a..000000000 --- a/src/libCom/env/RULES +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -envData.c: $(LIBCOM)/env/envDefs.h $(LIBCOM)/env/bldEnvData.pl \ - $(CONFIG)/CONFIG_ENV $(CONFIG)/CONFIG_SITE_ENV \ - $(wildcard $(CONFIG)/os/CONFIG_SITE_ENV.$(T_A)) - $(PERL) $(LIBCOM)/env/bldEnvData.pl $(QUIET_FLAG) -t $(T_A) \ - -c $(CMPLR_CLASS) -s $(OS_CLASS) $(CONFIG) diff --git a/src/libCom/env/bldEnvData.pl b/src/libCom/env/bldEnvData.pl deleted file mode 100644 index 9df15a535..000000000 --- a/src/libCom/env/bldEnvData.pl +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/perl -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# -# Author: Kay-Uwe Kasemir -# Date: 1-30-97 - -use strict; - -# This program is never installed, so it can't use FindBin to get -# the path to the lib/perl directory. However it can load the -# EPICS:: modules directly from the src/tools directory instead: -use lib '../../tools'; - -use Getopt::Std; -use File::Basename; -use EPICS::Path; -use EPICS::Release; -use Text::Wrap; - -my $tool = basename($0); - -our ($opt_h, $opt_q, $opt_t, $opt_s, $opt_c); -our $opt_o = 'envData.c'; - -$Getopt::Std::OUTPUT_HELP_VERSION = 1; -$Text::Wrap::columns = 75; - -HELP_MESSAGE() unless getopts('ho:qt:s:c:') && @ARGV == 1; -HELP_MESSAGE() if $opt_h; - -my $config = AbsPath(shift); -my $env_defs = AbsPath('../env/envDefs.h'); - -# Parse the ENV_PARAM declarations in envDefs.h -# to get the param names we are interested in -# -open SRC, '<', $env_defs - or die "$tool: Cannot open $env_defs: $!\n"; - -my @vars; -while () { - if (m/epicsShareExtern\s+const\s+ENV_PARAM\s+([A-Za-z_]\w*)\s*;/) { - push @vars, $1; - } -} -close SRC; - -# A list of configure/CONFIG_* files to read -# -my @configs = ("$config/CONFIG_ENV", "$config/CONFIG_SITE_ENV"); - -if ($opt_t) { - my $config_arch_env = "$config/os/CONFIG_SITE_ENV.$opt_t"; - push @configs, $config_arch_env - if -f $config_arch_env; -} - -my @sources = ($env_defs, @configs); - -# Get values from the config files -# -my (%values, @dummy); -readRelease($_, \%values, \@dummy) foreach @configs; -expandRelease(\%values); - -# Get values from the command-line -# -$values{EPICS_BUILD_COMPILER_CLASS} = $opt_c if $opt_c; -$values{EPICS_BUILD_OS_CLASS} = $opt_s if $opt_s; -$values{EPICS_BUILD_TARGET_ARCH} = $opt_t if $opt_t; - -# Warn about vars with no configured value -# -my @undefs = grep {!exists $values{$_}} @vars; -warn "$tool: No value given for $_\n" foreach @undefs; - -print "Generating $opt_o\n" unless $opt_q; - -# Start creating the output -# -open OUT, '>', $opt_o - or die "$tool: Cannot create $opt_o: $!\n"; - -my $sources = join "\n", map {" * $_"} @sources; - -print OUT << "END"; -/* Generated file $opt_o - * - * Created from -$sources - */ - -#include -#define epicsExportSharedSymbols -#include "envDefs.h" - -END - -# Define a default value for each named parameter -# -foreach my $var (@vars) { - my $default = $values{$var}; - if (defined $default) { - $default =~ s/^"//; - $default =~ s/"$//; - } - else { - $default = ''; - } - - print OUT "epicsShareDef const ENV_PARAM $var =\n", - " {\"$var\", \"$default\"};\n"; -} - -# Also provide a list of all defined parameters -# -print OUT "\n", - "epicsShareDef const ENV_PARAM* env_param_list[] = {\n", - wrap(' ', ' ', join(', ', map("&$_", @vars), 'NULL')), - "\n};\n"; -close OUT; - -sub HELP_MESSAGE { - print STDERR "Usage: $tool [options] configure\n", - " -h Help: Print this message\n", - " -q Quiet: Only print errors\n", - " -o file Output filename, default is $opt_o\n", - " -t arch Target architecture \$(T_A) name\n", - " -s os Operating system \$(OS_CLASS)\n", - " -c comp Compiler class \$(CMPLR_CLASS)\n", - "\n"; - - exit 1; -} diff --git a/src/libCom/env/envDefs.h b/src/libCom/env/envDefs.h deleted file mode 100644 index 650f8ee58..000000000 --- a/src/libCom/env/envDefs.h +++ /dev/null @@ -1,108 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Roger A. Cole - * Date: 07-20-91 - * - */ -/**************************************************************************** -* TITLE envDefs.h - definitions for environment get/set routines -* -* DESCRIPTION -* This file defines the environment parameters for EPICS. These -* ENV_PARAM's are created in envData.c by bldEnvData for -* use by EPICS programs running under UNIX and VxWorks. -* -* User programs can define their own environment parameters for their -* own use--the only caveat is that such parameters aren't automatically -* setup by EPICS. -* -*****************************************************************************/ - -#ifndef envDefsH -#define envDefsH - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -typedef struct envParam { - char *name; /* text name of the parameter */ - char *pdflt; -} ENV_PARAM; - -/* - * bldEnvData.pl looks for "epicsShareExtern const ENV_PARAM ;" - */ -epicsShareExtern const ENV_PARAM EPICS_CA_ADDR_LIST; -epicsShareExtern const ENV_PARAM EPICS_CA_CONN_TMO; -epicsShareExtern const ENV_PARAM EPICS_CA_AUTO_ADDR_LIST; -epicsShareExtern const ENV_PARAM EPICS_CA_REPEATER_PORT; -epicsShareExtern const ENV_PARAM EPICS_CA_SERVER_PORT; -epicsShareExtern const ENV_PARAM EPICS_CA_MAX_ARRAY_BYTES; -epicsShareExtern const ENV_PARAM EPICS_CA_AUTO_ARRAY_BYTES; -epicsShareExtern const ENV_PARAM EPICS_CA_MAX_SEARCH_PERIOD; -epicsShareExtern const ENV_PARAM EPICS_CA_NAME_SERVERS; -epicsShareExtern const ENV_PARAM EPICS_CA_MCAST_TTL; -epicsShareExtern const ENV_PARAM EPICS_CAS_INTF_ADDR_LIST; -epicsShareExtern const ENV_PARAM EPICS_CAS_IGNORE_ADDR_LIST; -epicsShareExtern const ENV_PARAM EPICS_CAS_AUTO_BEACON_ADDR_LIST; -epicsShareExtern const ENV_PARAM EPICS_CAS_BEACON_ADDR_LIST; -epicsShareExtern const ENV_PARAM EPICS_CAS_SERVER_PORT; -epicsShareExtern const ENV_PARAM EPICS_CA_BEACON_PERIOD; /* deprecated */ -epicsShareExtern const ENV_PARAM EPICS_CAS_BEACON_PERIOD; -epicsShareExtern const ENV_PARAM EPICS_CAS_BEACON_PORT; -epicsShareExtern const ENV_PARAM EPICS_BUILD_COMPILER_CLASS; -epicsShareExtern const ENV_PARAM EPICS_BUILD_OS_CLASS; -epicsShareExtern const ENV_PARAM EPICS_BUILD_TARGET_ARCH; -epicsShareExtern const ENV_PARAM EPICS_TIMEZONE; -epicsShareExtern const ENV_PARAM EPICS_TS_NTP_INET; -epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_PORT; -epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_INET; -epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_FILE_LIMIT; -epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_FILE_NAME; -epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_FILE_COMMAND; -epicsShareExtern const ENV_PARAM EPICS_CMD_PROTO_PORT; -epicsShareExtern const ENV_PARAM EPICS_AR_PORT; -epicsShareExtern const ENV_PARAM IOCSH_PS1; -epicsShareExtern const ENV_PARAM IOCSH_HISTSIZE; -epicsShareExtern const ENV_PARAM IOCSH_HISTEDIT_DISABLE; - -epicsShareExtern const ENV_PARAM *env_param_list[]; - -struct in_addr; - -epicsShareFunc char * epicsShareAPI - envGetConfigParam(const ENV_PARAM *pParam, int bufDim, char *pBuf); -epicsShareFunc const char * epicsShareAPI - envGetConfigParamPtr(const ENV_PARAM *pParam); -epicsShareFunc long epicsShareAPI - envPrtConfigParam(const ENV_PARAM *pParam); -epicsShareFunc long epicsShareAPI - envGetInetAddrConfigParam(const ENV_PARAM *pParam, struct in_addr *pAddr); -epicsShareFunc long epicsShareAPI - envGetDoubleConfigParam(const ENV_PARAM *pParam, double *pDouble); -epicsShareFunc long epicsShareAPI - envGetLongConfigParam(const ENV_PARAM *pParam, long *pLong); -epicsShareFunc unsigned short epicsShareAPI envGetInetPortConfigParam - (const ENV_PARAM *pEnv, unsigned short defaultPort); -epicsShareFunc long epicsShareAPI - envGetBoolConfigParam(const ENV_PARAM *pParam, int *pBool); -epicsShareFunc long epicsShareAPI epicsPrtEnvParams(void); -epicsShareFunc void epicsShareAPI epicsEnvSet (const char *name, const char *value); -epicsShareFunc void epicsShareAPI epicsEnvShow (const char *name); - -#ifdef __cplusplus -} -#endif - -#endif /*envDefsH*/ - diff --git a/src/libCom/env/envSubr.c b/src/libCom/env/envSubr.c deleted file mode 100644 index 283b13290..000000000 --- a/src/libCom/env/envSubr.c +++ /dev/null @@ -1,426 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Roger A. Cole - * Date: 07-20-91 - */ -/*+/mod*********************************************************************** -* TITLE envSubr.c - routines to get and set EPICS environment parameters -* -* DESCRIPTION -* These routines are oriented for use with EPICS environment -* parameters under UNIX and VxWorks. They may be used for other -* purposes, as well. -* -* Many EPICS environment parameters are predefined in envDefs.h. -* -* QUICK REFERENCE -* #include "envDefs.h" -* ENV_PARAM param; -* char *envGetConfigParamPtr( pParam ) -* char *envGetConfigParam( pParam, bufDim, pBuf ) -* long envGetLongConfigParam( pParam, pLong ) -* long envGetDoubleConfigParam( pParam, pDouble ) -* long envGetInetAddrConfigParam( pParam, pAddr ) -* long envPrtConfigParam( pParam ) -* -* SEE ALSO -* $epics/share/bin/envSetupParams, envDefs.h -* -*-***************************************************************************/ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdlib.h" -#include "epicsStdio.h" -#include "epicsString.h" -#include "errMdef.h" -#include "errlog.h" -#include "envDefs.h" -#include "epicsAssert.h" -#include "osiSock.h" - - -/*+/subr********************************************************************** -* NAME envGetConfigParamPtr - returns a pointer to the configuration -* parameter value string -* -* DESCRIPTION -* Returns a pointer to a configuration parameter value. -* If the configuration parameter isn't found in the environment, -* then a pointer to the default value for the parameter is copied. -* If no parameter is found and there is no default, then -* NULL is returned. -* -* RETURNS -* pointer to the environment variable value string, or -* NULL if no parameter value and no default value was found -* -* EXAMPLES -* 1. Get the value for the EPICS-defined environment parameter -* EPICS_TS_NTP_INET. -* -* #include "envDefs.h" -* const char *pStr; -* -* pStr = envGetConfigParamPtr(&EPICS_TS_NTP_INET); -* if (pStr) { -* printf("NTP time server is: %s\n", pStr); -* } -* -*-*/ -const char * epicsShareAPI envGetConfigParamPtr( -const ENV_PARAM *pParam /* I pointer to config param structure */ -) -{ - const char *pEnv; /* pointer to environment string */ - - pEnv = getenv(pParam->name); - - if (pEnv == NULL) { - pEnv = pParam->pdflt; - } - - if (pEnv) { - if (pEnv[0u] == '\0') { - pEnv = NULL; - } - } - - return pEnv; -} - - -/*+/subr********************************************************************** -* NAME envGetConfigParam - get value of a configuration parameter -* -* DESCRIPTION -* Gets the value of a configuration parameter and copies it -* into the caller's buffer. If the configuration parameter -* isn't found in the environment, then the default value for -* the parameter is copied. If no parameter is found and there -* is no default, then '\0' is copied and NULL is returned. -* -* RETURNS -* pointer to callers buffer, or -* NULL if no parameter value or default value was found -* -* EXAMPLES -* 1. Get the value for the EPICS-defined environment parameter -* EPICS_TS_NTP_INET. -* -* #include "envDefs.h" -* char temp[80]; -* -* printf("NTP time server is: %s\n", -* envGetConfigParam(&EPICS_TS_NTP_INET, sizeof(temp), temp)); -* -* 2. Get the value for the DISPLAY environment parameter under UNIX. -* -* #include "envDefs.h" -* char temp[80]; -* ENV_PARAM display={"DISPLAY",""} -* -* if (envGetConfigParam(&display, sizeof(temp), temp) == NULL) -* printf("DISPLAY isn't defined\n"); -* else -* printf("DISPLAY is %s\n", temp); -* -*-*/ -char * epicsShareAPI envGetConfigParam( -const ENV_PARAM *pParam,/* I pointer to config param structure */ -int bufDim, /* I dimension of parameter buffer */ -char *pBuf /* I pointer to parameter buffer */ -) -{ - const char *pEnv; /* pointer to environment string */ - - pEnv = envGetConfigParamPtr(pParam); - if (!pEnv) { - return NULL; - } - - strncpy(pBuf, pEnv, bufDim-1); - pBuf[bufDim-1] = '\0'; - - return pBuf; -} - -/*+/subr********************************************************************** -* NAME envGetDoubleConfigParam - get value of a double configuration parameter -* -* DESCRIPTION -* Gets the value of a configuration parameter and copies it into the -* caller's real (double) buffer. If the configuration parameter isn't -* found in the environment, then the default value for the parameter -* is copied. -* -* If no parameter is found and there is no default, then -1 is -* returned and the caller's buffer is unmodified. -* -* RETURNS -* 0, or -* -1 if an error is encountered -* -* EXAMPLE -* 1. Get the value for the real environment parameter EPICS_THRESHOLD. -* -* #include "envDefs.h" -* double threshold; -* long status; -* -* status = envGetDoubleConfigParam(&EPICS_THRESHOLD, &threshold); -* if (status == 0) { -* printf("the threshold is: %lf\n", threshold); -* } -* else { -* printf("%s could not be found or was not a real number\n", -* EPICS_THRESHOLD.name); -* } -* -*-*/ -long epicsShareAPI envGetDoubleConfigParam( -const ENV_PARAM *pParam,/* I pointer to config param structure */ -double *pDouble /* O pointer to place to store value */ -) -{ - char text[128]; - char *ptext; - int count; - - ptext = envGetConfigParam(pParam, sizeof text, text); - if (ptext != NULL) { - count = epicsScanDouble(text, pDouble); - if (count == 1) { - return 0; - } - (void)fprintf(stderr,"Unable to find a real number in %s=%s\n", - pParam->name, text); - } - - return -1; -} - -/*+/subr********************************************************************** -* NAME envGetInetAddrConfigParam - get value of an inet addr config parameter -* -* DESCRIPTION -* Gets the value of a configuration parameter and copies it into -* the caller's (struct in_addr) buffer. If the configuration parameter -* isn't found in the environment, then the default value for -* the parameter is copied. -* -* If no parameter is found and there is no default, then -1 is -* returned and the callers buffer is unmodified. -* -* RETURNS -* 0, or -* -1 if an error is encountered -* -* EXAMPLE -* 1. Get the value for the inet address environment parameter EPICS_INET. -* -* #include "envDefs.h" -* struct in_addr addr; -* long status; -* -* status = envGetInetAddrConfigParam(&EPICS_INET, &addr); -* if (status == 0) { -* printf("the s_addr is: %x\n", addr.s_addr); -* } -* else { -* printf("%s could not be found or was not an inet address\n", -* EPICS_INET.name); -* } -* -*-*/ -long epicsShareAPI envGetInetAddrConfigParam( -const ENV_PARAM *pParam,/* I pointer to config param structure */ -struct in_addr *pAddr /* O pointer to struct to receive inet addr */ -) -{ - char text[128]; - char *ptext; - long status; - struct sockaddr_in sin; - - ptext = envGetConfigParam(pParam, sizeof text, text); - if (ptext) { - status = aToIPAddr (text, 0u, &sin); - if (status == 0) { - *pAddr = sin.sin_addr; - return 0; - } - (void)fprintf(stderr,"Unable to find an IP address or valid host name in %s=%s\n", - pParam->name, text); - } - return -1; -} - -/*+/subr********************************************************************** -* NAME envGetLongConfigParam - get value of an integer config parameter -* -* DESCRIPTION -* Gets the value of a configuration parameter and copies it -* into the caller's integer (long) buffer. If the configuration -* parameter isn't found in the environment, then the default value for -* the parameter is copied. -* -* If no parameter is found and there is no default, then -1 is -* returned and the callers buffer is unmodified. -* -* RETURNS -* 0, or -* -1 if an error is encountered -* -* EXAMPLE -* 1. Get the value as a long for the integer environment parameter -* EPICS_NUMBER_OF_ITEMS. -* -* #include "envDefs.h" -* long count; -* long status; -* -* status = envGetLongConfigParam(&EPICS_NUMBER_OF_ITEMS, &count); -* if (status == 0) { -* printf("and the count is: %d\n", count); -* } -* else { -* printf("%s could not be found or was not an integer\n", -* EPICS_NUMBER_OF_ITEMS.name); -* } -* -*-*/ -long epicsShareAPI envGetLongConfigParam( -const ENV_PARAM *pParam,/* I pointer to config param structure */ -long *pLong /* O pointer to place to store value */ -) -{ - char text[128]; - char *ptext; - int count; - - ptext = envGetConfigParam(pParam, sizeof text, text); - if (ptext) { - count = sscanf(text, "%ld", pLong); - if (count == 1) - return 0; - (void)fprintf(stderr,"Unable to find an integer in %s=%s\n", - pParam->name, text); - } - return -1; -} - - -long epicsShareAPI -envGetBoolConfigParam(const ENV_PARAM *pParam, int *pBool) -{ - char text[20]; - - if(!envGetConfigParam(pParam, sizeof(text), text)) - return -1; - *pBool = epicsStrCaseCmp(text, "yes")==0; - return 0; -} - -/*+/subr********************************************************************** -* NAME envPrtConfigParam - print value of a configuration parameter -* -* DESCRIPTION -* Prints the value of a configuration parameter. -* -* RETURNS -* 0 -* -* EXAMPLE -* 1. Print the value for the EPICS-defined environment parameter -* EPICS_TS_NTP_INET. -* -* #include "envDefs.h" -* -* envPrtConfigParam(&EPICS_TS_NTP_INET); -* -*-*/ -long epicsShareAPI envPrtConfigParam( -const ENV_PARAM *pParam) /* pointer to config param structure */ -{ - const char *pVal; - - pVal = envGetConfigParamPtr(pParam); - if (pVal == NULL) - fprintf(stdout, "%s is undefined\n", pParam->name); - else - fprintf(stdout,"%s: %s\n", pParam->name, pVal); - return 0; -} - -/*+/subr********************************************************************** -* NAME epicsPrtEnvParams - print value of all configuration parameters -* -* DESCRIPTION -* Prints all configuration parameters and their current value. -* -* RETURNS -* 0 -* -* EXAMPLE -* 1. Print the value for all EPICS-defined environment parameters. -* -* #include "envDefs.h" -* -* epicsPrtEnvParams(); -* -*-*/ -long epicsShareAPI -epicsPrtEnvParams(void) -{ - const ENV_PARAM **ppParam = env_param_list; - - while (*ppParam != NULL) - envPrtConfigParam(*(ppParam++)); - - return 0; -} - -/* - * envGetInetPortConfigParam () - */ -epicsShareFunc unsigned short epicsShareAPI envGetInetPortConfigParam - (const ENV_PARAM *pEnv, unsigned short defaultPort) -{ - long longStatus; - long epicsParam; - - longStatus = envGetLongConfigParam (pEnv, &epicsParam); - if (longStatus!=0) { - epicsParam = (long) defaultPort; - errlogPrintf ("EPICS Environment \"%s\" integer fetch failed\n", pEnv->name); - errlogPrintf ("setting \"%s\" = %ld\n", pEnv->name, epicsParam); - } - - if (epicsParam<=IPPORT_USERRESERVED || epicsParam>USHRT_MAX) { - errlogPrintf ("EPICS Environment \"%s\" out of range\n", pEnv->name); - /* - * Quit if the port is wrong due coding error - */ - assert (epicsParam != (long) defaultPort); - epicsParam = (long) defaultPort; - errlogPrintf ("Setting \"%s\" = %ld\n", pEnv->name, epicsParam); - } - - /* - * ok to clip to unsigned short here because we checked the range - */ - return (unsigned short) epicsParam; -} - diff --git a/src/libCom/error/Makefile b/src/libCom/error/Makefile deleted file mode 100644 index 0a99b0def..000000000 --- a/src/libCom/error/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/error - -INC += epicsPrint.h -INC += errMdef.h -INC += errSymTbl.h -INC += errlog.h -INC += error.h - -Com_SRCS += errlog.c -Com_SRCS += errSymLib.c -Com_SRCS += errSymTbl.c - -# For bldErrSymTbl -# -ERR_S_FILES += $(LIBCOM)/osi/devLib.h -ERR_S_FILES += $(LIBCOM)/osi/epicsTime.h -ERR_S_FILES += $(LIBCOM)/as/asLib.h -ERR_S_FILES += $(LIBCOM)/misc/epicsStdlib.h -ERR_S_FILES += $(LIBCOM)/pool/epicsThreadPool.h -ERR_S_FILES += $(SRC)/ioc/db/dbAccessDefs.h -ERR_S_FILES += $(SRC)/ioc/dbStatic/devSup.h -ERR_S_FILES += $(SRC)/ioc/dbStatic/drvSup.h -ERR_S_FILES += $(SRC)/ioc/dbStatic/recSup.h -ERR_S_FILES += $(SRC)/ioc/dbStatic/dbStaticLib.h -ERR_S_FILES += $(LIBCOM)/error/errMdef.h -ERR_S_FILES += $(SRC)/ca/legacy/pcas/generic/casdef.h -ERR_S_FILES += $(SRC)/ca/legacy/gdd/gddAppFuncTable.h - -CLEANS += errSymTbl.c diff --git a/src/libCom/error/RULES b/src/libCom/error/RULES deleted file mode 100644 index dc2926ff3..000000000 --- a/src/libCom/error/RULES +++ /dev/null @@ -1,11 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -errSymTbl.c: $(ERR_S_FILES) $(LIBCOM)/error/makeStatTbl.pl - $(PERL) $(LIBCOM)/error/makeStatTbl.pl $(ERR_S_FILES) diff --git a/src/libCom/error/epicsPrint.h b/src/libCom/error/epicsPrint.h deleted file mode 100644 index db889794a..000000000 --- a/src/libCom/error/epicsPrint.h +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*epicsPrint.h */ - -/*This is now obsolete. Replaced by errlog.h */ -#ifndef INCepicsPrintH -#define INCepicsPrintH - -#include "errlog.h" - -#endif /*INCepicsPrintH*/ diff --git a/src/libCom/error/errMdef.h b/src/libCom/error/errMdef.h deleted file mode 100644 index 4dbbecaf1..000000000 --- a/src/libCom/error/errMdef.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Error Handling definitions */ -/* - * Author: Marty Kraimer - * Date: 6-1-90 - */ - -#ifndef INCerrMdefh -#define INCerrMdefh - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define RTN_SUCCESS(STATUS) ((STATUS)==0) - -#define M_dbAccess (501 <<16) /*Database Access Routines */ -#define M_drvSup (503 <<16) /*Driver Support*/ -#define M_devSup (504 <<16) /*Device Support*/ -#define M_recSup (505 <<16) /*Record Support*/ -#define M_recType (506 <<16) /*Record Type*/ -#define M_record (507 <<16) /*Database Records*/ -#define M_ar (508 <<16) /*Archiver; see arDefs.h*/ -#define M_ts (509 <<16) /*Time Stamp Routines; see tsDefs.h*/ -#define M_arAcc (510 <<16) /*Archive Access Library Routines*/ -#define M_bf (511 <<16) /*Block File Routines; see bfDefs.h*/ -#define M_syd (512 <<16) /*Sync Data Routines; see sydDefs.h*/ -#define M_ppr (513 <<16) /*Portable Plot Routines; see pprPlotDefs.h*/ -#define M_env (514 <<16) /*Environment Routines; see envDefs.h*/ -#define M_gen (515 <<16) /*General Purpose Routines; see genDefs.h*/ -#define M_gpib (516 <<16) /*Gpib driver & device support; see drvGpibInterface.h*/ -#define M_bitbus (517 <<16) /*Bitbus driver & device support; see drvBitBusInterface.h*/ -#define M_dbLib (519 <<16) /*Static Database Access */ -#define M_epvxi (520 <<16) /*VXI Driver*/ -#define M_devLib (521 <<16) /*Device Resource Registration*/ -#define M_asLib (522 <<16) /*Access Security */ -#define M_cas (523 <<16) /*CA server*/ -#define M_casApp (524 <<16) /*CA server application*/ -#define M_bucket (525 <<16) /*Bucket Hash*/ -#define M_gddFuncTbl (526 <<16) /*gdd jump table*/ -#define M_stdlib (527 <<16) /*EPICS Standard library*/ -#define M_pool (528 <<16) /*Thread pool*/ -#define M_time (529 <<16) /*epicsTime*/ - -epicsShareFunc void epicsShareAPI errSymLookup(long status, char *pBuf, unsigned bufLength); -epicsShareFunc const char* errSymMsg(long status); -epicsShareFunc void epicsShareAPI errSymTest(unsigned short modnum, unsigned short begErrNum, unsigned short endErrNum); -epicsShareFunc void epicsShareAPI errSymTestPrint(long errNum); -epicsShareFunc int epicsShareAPI errSymBld(void); -epicsShareFunc int epicsShareAPI errSymbolAdd (long errNum,char *name); -epicsShareFunc void epicsShareAPI errSymDump(void); -epicsShareFunc void epicsShareAPI tstErrSymFind(void); - -#ifdef __cplusplus -} -#endif - -#endif /*INCerrMdefh*/ diff --git a/src/libCom/error/errSymLib.c b/src/libCom/error/errSymLib.c deleted file mode 100644 index aa1f3961c..000000000 --- a/src/libCom/error/errSymLib.c +++ /dev/null @@ -1,334 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * errSymLib.c - * Author: Marty Kraimer - * Date: 6-1-90 - * - *************************************************************************** - * This must ultimately be replaced by a facility that allows remote - * nodes access to the error messages. A message handling communication - * task should be written that allows multiple remote nodes to request - * notification of all error messages. - * For now lets just print messages and last errno via logMsg or printf - *************************************************************************** - */ - -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsAssert.h" -#include "dbDefs.h" -#include "errMdef.h" -#include "errSymTbl.h" -#include "ellLib.h" -#include "errlog.h" - - -static unsigned short errhash(long errNum); - -typedef struct errnumnode { - ELLNODE node; - long errNum; - struct errnumnode *hashnode; - char *message; - long pad; -} ERRNUMNODE; -#define NHASH 256 - - -static ELLLIST errnumlist = ELLLIST_INIT; -static ERRNUMNODE **hashtable; -static int initialized = FALSE; -extern ERRSYMTAB_ID errSymTbl; - -/**************************************************************** - * ERRSYMBLD - * - * Create the normal ell LIST of sorted error messages nodes - * Followed by linked hash lists - that link together those - * ell nodes that have a common hash number. - * - ***************************************************************/ -int epicsShareAPI errSymBld(void) -{ - ERRSYMBOL *errArray = errSymTbl->symbols; - ERRNUMNODE *perrNumNode = NULL; - ERRNUMNODE *pNextNode = NULL; - ERRNUMNODE **phashnode = NULL; - int i; - int modnum; - unsigned short hashInd; - - if(initialized) return(0); - hashtable = (ERRNUMNODE**)callocMustSucceed - (NHASH, sizeof(ERRNUMNODE*),"errSymBld"); - for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) { - modnum = errArray->errNum >> 16; - if (modnum < 501) { - fprintf(stderr, "errSymBld: ERROR - Module number in errSymTbl < 501 was Module=%lx Name=%s\n", - errArray->errNum, errArray->name); - continue; - } - if ((errSymbolAdd(errArray->errNum, errArray->name)) <0 ) { - fprintf(stderr, "errSymBld: ERROR - errSymbolAdd() failed \n"); - continue; - } - } - perrNumNode = (ERRNUMNODE *) ellFirst(&errnumlist); - while (perrNumNode) { - /* hash each perrNumNode->errNum */ - hashInd = errhash(perrNumNode->errNum); - phashnode = (ERRNUMNODE**)&hashtable[hashInd]; - pNextNode = (ERRNUMNODE*) *phashnode; - /* search for last node (NULL) of hashnode linked list */ - while (pNextNode) { - phashnode = &pNextNode->hashnode; - pNextNode = *phashnode; - } - *phashnode = perrNumNode; - perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode); - } - initialized = TRUE; - return(0); -} - - - -/**************************************************************** - * HASH - * returns the hash index of errNum -****************************************************************/ -static unsigned short errhash(long errNum) -{ -unsigned short modnum; -unsigned short errnum; - - modnum = (unsigned short) (errNum >> 16); - errnum = (unsigned short) (errNum & 0xffff); - return((unsigned short)(((modnum - 500) * 20) + errnum) % NHASH); -} - -/**************************************************************** - * ERRSYMBOLADD - * adds symbols to the master errnumlist as compiled from errSymTbl.c - ***************************************************************/ -int epicsShareAPI errSymbolAdd (long errNum,char *name) -{ - ERRNUMNODE *pNew; - - pNew = (ERRNUMNODE*)callocMustSucceed(1,sizeof(ERRNUMNODE),"errSymbolAdd"); - pNew->errNum = errNum; - pNew->message = name; - ellAdd(&errnumlist,(ELLNODE*)pNew); - return(0); -} - -/**************************************************************** - * errRawCopy - ***************************************************************/ -static void errRawCopy ( long statusToDecode, char *pBuf, unsigned bufLength ) -{ - unsigned modnum, errnum; - unsigned nChar; - int status; - - modnum = (unsigned) statusToDecode; - modnum >>= 16; - modnum &= 0xffff; - errnum = (unsigned) statusToDecode; - errnum &= 0xffff; - - if ( bufLength ) { - if ( modnum == 0 ) { - if ( bufLength > 11 ) { - status = sprintf ( pBuf, "err = %d", errnum ); - } - else if ( bufLength > 5 ) { - status = sprintf ( pBuf, "%d", errnum ); - } - else { - strncpy ( pBuf,"", bufLength ); - pBuf[bufLength-1] = '\0'; - status = 0; - } - } - else { - if ( bufLength > 50 ) { - status = sprintf ( pBuf, - "status = (%d,%d) not in symbol table", modnum, errnum ); - } - else if ( bufLength > 25 ) { - status = sprintf ( pBuf, - "status = (%d,%d)", modnum, errnum ); - } - else if ( bufLength > 15 ) { - status = sprintf ( pBuf, - "(%d,%d)", modnum, errnum ); - } - else { - strncpy ( pBuf, - "", bufLength); - pBuf[bufLength-1] = '\0'; - status = 0; - } - } - assert (status >= 0 ); - nChar = (unsigned) status; - assert ( nChar < bufLength ); - } -} - -static -const char* errSymLookupInternal(long status) -{ - unsigned modNum; - unsigned hashInd; - ERRNUMNODE *pNextNode; - ERRNUMNODE **phashnode = NULL; - - if(!initialized) errSymBld(); - - modNum = (unsigned) status; - modNum >>= 16; - modNum &= 0xffff; - if ( modNum <= 500 ) { - const char * pStr = strerror ((int) status); - if ( pStr ) { - return pStr; - } - } - else { - hashInd = errhash(status); - phashnode = (ERRNUMNODE**)&hashtable[hashInd]; - pNextNode = *phashnode; - while(pNextNode) { - if(pNextNode->errNum==status){ - return pNextNode->message; - } - phashnode = &pNextNode->hashnode; - pNextNode = *phashnode; - } - } - return NULL; -} - -const char* errSymMsg(long status) -{ - const char* msg = errSymLookupInternal(status); - return msg ? msg : ""; -} - -/**************************************************************** - * errSymLookup - ***************************************************************/ -void epicsShareAPI errSymLookup (long status, char * pBuf, unsigned bufLength) -{ - const char* msg = errSymLookupInternal(status); - if(msg) { - strncpy(pBuf, msg, bufLength); - pBuf[bufLength-1] = '\0'; - return; - } - errRawCopy(status, pBuf, bufLength); -} - -/**************************************************************** - * errSymDump - ***************************************************************/ -void epicsShareAPI errSymDump(void) -{ -ERRNUMNODE **phashnode = NULL; -ERRNUMNODE *pNextNode; -int i; -int modnum; -int errnum; -int msgcount; -int firstTime; - - if (!initialized) errSymBld(); - - msgcount = 0; - printf("errSymDump: number of hash slots=%d\n", NHASH); - for ( i=0; i < NHASH; i++) { - phashnode = &hashtable[i]; - pNextNode = *phashnode; - firstTime=1; - while (pNextNode) { - if (firstTime) { - printf("HASHNODE=%d\n", i); - firstTime=0; - } - modnum = pNextNode->errNum >> 16; - errnum = pNextNode->errNum & 0xffff; - printf("\tmod %d num %d \"%s\"\n" - , modnum , errnum , pNextNode->message); - msgcount++; - phashnode = &pNextNode->hashnode; - pNextNode = *phashnode; - } - } - printf("\nerrSymDump: total number of error messages=%d\n", msgcount); -} - - -/**************************************************************** - * errSymTestPrint - ***************************************************************/ -void epicsShareAPI errSymTestPrint(long errNum) -{ - char message[256]; - unsigned short modnum; - unsigned short errnum; - - if (!initialized) errSymBld(); - - message[0] = '\0'; - modnum = (unsigned short) (errNum >> 16); - errnum = (unsigned short) (errNum & 0xffff); - if (modnum < 501) { - fprintf(stderr, "Usage: errSymTestPrint(long errNum) \n"); - fprintf(stderr, "errSymTestPrint: module number < 501 \n"); - return; - } - errSymLookup(errNum, message, sizeof(message)); - if ( message[0] == '\0' ) return; - printf("module %hu number %hu message=\"%s\"\n", - modnum, errnum, message); - return; -} - -/**************************************************************** - * ERRSYMTEST -****************************************************************/ -void epicsShareAPI errSymTest(unsigned short modnum, - unsigned short begErrNum, unsigned short endErrNum) -{ - long errNum; - unsigned short errnum; - - if(!initialized) errSymBld(); - if (modnum < 501) - return; - - /* print range of error messages */ - for (errnum = begErrNum; errnum <= endErrNum; errnum++) { - errNum = modnum << 16; - errNum |= (errnum & 0xffff); - errSymTestPrint(errNum); - } -} diff --git a/src/libCom/error/errSymTbl.h b/src/libCom/error/errSymTbl.h deleted file mode 100644 index 2b1712621..000000000 --- a/src/libCom/error/errSymTbl.h +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INCerrSymTblh -#define INCerrSymTblh 1 - -#ifndef NELEMENTS -#define NELEMENTS(array) /* number of elements in an array */ \ - (sizeof (array) / sizeof ((array) [0])) -#endif -#define LOCAL static - -typedef struct /* ERRSYMBOL - entry in symbol table */ - { - char *name; /* pointer to symbol name */ - long errNum; /* errMessage symbol number */ - } ERRSYMBOL; -typedef struct /* ERRSYMTAB - symbol table */ - { - int nsymbols; /* current number of symbols in table */ - ERRSYMBOL *symbols; /* ptr to array of symbol entries */ - } ERRSYMTAB; -typedef ERRSYMTAB *ERRSYMTAB_ID; - - -#endif /* INCerrSymTblh */ diff --git a/src/libCom/error/errlog.c b/src/libCom/error/errlog.c deleted file mode 100644 index b6789978a..000000000 --- a/src/libCom/error/errlog.c +++ /dev/null @@ -1,703 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Original Author: Marty Kraimer - * Date: 07JAN1998 - */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#define ERRLOG_INIT -#include "adjustment.h" -#include "dbDefs.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "epicsInterrupt.h" -#include "errMdef.h" -#include "error.h" -#include "ellLib.h" -#include "errlog.h" -#include "epicsStdio.h" -#include "epicsExit.h" - - -#define BUFFER_SIZE 1280 -#define MAX_MESSAGE_SIZE 256 - -/*Declare storage for errVerbose */ -epicsShareDef int errVerbose = 0; - -static void errlogExitHandler(void *); -static void errlogThread(void); - -static char *msgbufGetFree(int noConsoleMessage); -static void msgbufSetSize(int size); /* Send 'size' chars plus trailing '\0' */ -static char *msgbufGetSend(int *noConsoleMessage); -static void msgbufFreeSend(void); - -typedef struct listenerNode{ - ELLNODE node; - errlogListener listener; - void *pPrivate; -} listenerNode; - -/*each message consists of a msgNode immediately followed by the message */ -typedef struct msgNode { - ELLNODE node; - char *message; - int length; - int noConsoleMessage; -} msgNode; - -static struct { - epicsEventId waitForWork; /*errlogThread waits for this*/ - epicsMutexId msgQueueLock; - epicsMutexId listenerLock; - epicsEventId waitForFlush; /*errlogFlush waits for this*/ - epicsEventId flush; /*errlogFlush sets errlogThread does a Try*/ - epicsMutexId flushLock; - epicsEventId waitForExit; /*errlogExitHandler waits for this*/ - int atExit; /*TRUE when errlogExitHandler is active*/ - ELLLIST listenerList; - ELLLIST msgQueue; - msgNode *pnextSend; - int errlogInitFailed; - int buffersize; - int maxMsgSize; - int msgNeeded; - int sevToLog; - int toConsole; - FILE *console; - int missedMessages; - char *pbuffer; -} pvtData; - - -/* - * vsnprintf with truncation message - */ -static int tvsnPrint(char *str, size_t size, const char *format, va_list ap) -{ - static const char tmsg[] = "<>\n"; - int nchar = epicsVsnprintf(str, size, format ? format : "", ap); - - if (nchar >= size) { - if (size > sizeof tmsg) - strcpy(str + size - sizeof tmsg, tmsg); - nchar = size - 1; - } - return nchar; -} - -epicsShareFunc int errlogPrintf(const char *pFormat, ...) -{ - va_list pvar; - char *pbuffer; - int nchar; - int isOkToBlock; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage - ("errlogPrintf called from interrupt level\n"); - return 0; - } - - errlogInit(0); - isOkToBlock = epicsThreadIsOkToBlock(); - - if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) { - FILE *console = pvtData.console ? pvtData.console : stderr; - - va_start(pvar, pFormat); - nchar = vfprintf(console, pFormat, pvar); - va_end (pvar); - fflush(console); - } - - if (pvtData.atExit) - return nchar; - - pbuffer = msgbufGetFree(isOkToBlock); - if (!pbuffer) - return 0; - - va_start(pvar, pFormat); - nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar); - va_end(pvar); - msgbufSetSize(nchar); - return nchar; -} - -epicsShareFunc int errlogVprintf( - const char *pFormat,va_list pvar) -{ - int nchar; - char *pbuffer; - int isOkToBlock; - FILE *console; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage - ("errlogVprintf called from interrupt level\n"); - return 0; - } - - errlogInit(0); - if (pvtData.atExit) - return 0; - isOkToBlock = epicsThreadIsOkToBlock(); - - pbuffer = msgbufGetFree(isOkToBlock); - if (!pbuffer) { - console = pvtData.console ? pvtData.console : stderr; - vfprintf(console, pFormat, pvar); - fflush(console); - return 0; - } - - nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar); - if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) { - console = pvtData.console ? pvtData.console : stderr; - fprintf(console, "%s", pbuffer); - fflush(console); - } - msgbufSetSize(nchar); - return nchar; -} - -epicsShareFunc int epicsShareAPI errlogMessage(const char *message) -{ - errlogPrintf("%s", message); - return 0; -} - -epicsShareFunc int errlogPrintfNoConsole( const char *pFormat, ...) -{ - va_list pvar; - int nchar; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage - ("errlogPrintfNoConsole called from interrupt level\n"); - return 0; - } - - errlogInit(0); - va_start(pvar, pFormat); - nchar = errlogVprintfNoConsole(pFormat, pvar); - va_end(pvar); - return nchar; -} - -epicsShareFunc int errlogVprintfNoConsole( - const char *pFormat,va_list pvar) -{ - int nchar; - char *pbuffer; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage - ("errlogVprintfNoConsole called from interrupt level\n"); - return 0; - } - - errlogInit(0); - if (pvtData.atExit) - return 0; - - pbuffer = msgbufGetFree(1); - if (!pbuffer) - return 0; - - nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar); - msgbufSetSize(nchar); - return nchar; -} - - -epicsShareFunc int errlogSevPrintf( - const errlogSevEnum severity,const char *pFormat, ...) -{ - va_list pvar; - int nchar; - int isOkToBlock; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage - ("errlogSevPrintf called from interrupt level\n"); - return 0; - } - - errlogInit(0); - if (pvtData.sevToLog > severity) - return 0; - - isOkToBlock = epicsThreadIsOkToBlock(); - if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) { - FILE *console = pvtData.console ? pvtData.console : stderr; - - fprintf(console, "sevr=%s ", errlogGetSevEnumString(severity)); - va_start(pvar, pFormat); - vfprintf(console, pFormat, pvar); - va_end(pvar); - fflush(console); - } - - va_start(pvar, pFormat); - nchar = errlogSevVprintf(severity, pFormat, pvar); - va_end(pvar); - return nchar; -} - -epicsShareFunc int errlogSevVprintf( - const errlogSevEnum severity,const char *pFormat,va_list pvar) -{ - char *pnext; - int nchar; - int totalChar = 0; - int isOkToBlock; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage - ("errlogSevVprintf called from interrupt level\n"); - return 0; - } - - errlogInit(0); - if (pvtData.atExit) - return 0; - - isOkToBlock = epicsThreadIsOkToBlock(); - pnext = msgbufGetFree(isOkToBlock); - if (!pnext) - return 0; - - nchar = sprintf(pnext, "sevr=%s ", errlogGetSevEnumString(severity)); - pnext += nchar; totalChar += nchar; - nchar = tvsnPrint(pnext, pvtData.maxMsgSize - totalChar - 1, pFormat, pvar); - pnext += nchar; totalChar += nchar; - if (pnext[-1] != '\n') { - strcpy(pnext,"\n"); - totalChar++; - } - msgbufSetSize(totalChar); - return nchar; -} - - -epicsShareFunc char * epicsShareAPI errlogGetSevEnumString( - const errlogSevEnum severity) -{ - errlogInit(0); - if (severity > 3) - return "unknown"; - return errlogSevEnumString[severity]; -} - -epicsShareFunc void epicsShareAPI errlogSetSevToLog( - const errlogSevEnum severity) -{ - errlogInit(0); - pvtData.sevToLog = severity; -} - -epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog(void) -{ - errlogInit(0); - return pvtData.sevToLog; -} - -epicsShareFunc void epicsShareAPI errlogAddListener( - errlogListener listener, void *pPrivate) -{ - listenerNode *plistenerNode; - - errlogInit(0); - if (pvtData.atExit) - return; - - plistenerNode = callocMustSucceed(1,sizeof(listenerNode), - "errlogAddListener"); - epicsMutexMustLock(pvtData.listenerLock); - plistenerNode->listener = listener; - plistenerNode->pPrivate = pPrivate; - ellAdd(&pvtData.listenerList,&plistenerNode->node); - epicsMutexUnlock(pvtData.listenerLock); -} - -epicsShareFunc int epicsShareAPI errlogRemoveListeners( - errlogListener listener, void *pPrivate) -{ - listenerNode *plistenerNode; - int count = 0; - - errlogInit(0); - if (!pvtData.atExit) - epicsMutexMustLock(pvtData.listenerLock); - - plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList); - while (plistenerNode) { - listenerNode *pnext = (listenerNode *)ellNext(&plistenerNode->node); - - if (plistenerNode->listener == listener && - plistenerNode->pPrivate == pPrivate) { - ellDelete(&pvtData.listenerList, &plistenerNode->node); - free(plistenerNode); - ++count; - } - plistenerNode = pnext; - } - - if (!pvtData.atExit) - epicsMutexUnlock(pvtData.listenerLock); - - if (count == 0) { - FILE *console = pvtData.console ? pvtData.console : stderr; - - fprintf(console, - "errlogRemoveListeners: No listeners found\n"); - } - return count; -} - -epicsShareFunc int epicsShareAPI eltc(int yesno) -{ - errlogInit(0); - errlogFlush(); - pvtData.toConsole = yesno; - return 0; -} - -epicsShareFunc int errlogSetConsole(FILE *stream) -{ - errlogInit(0); - pvtData.console = stream; - return 0; -} - -epicsShareFunc void errPrintf(long status, const char *pFileName, - int lineno, const char *pformat, ...) -{ - va_list pvar; - char *pnext; - int nchar; - int totalChar=0; - int isOkToBlock; - char name[256]; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage("errPrintf called from interrupt level\n"); - return; - } - - errlogInit(0); - isOkToBlock = epicsThreadIsOkToBlock(); - if (status == 0) - status = errno; - - if (status > 0) { - errSymLookup(status, name, sizeof(name)); - } - - if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) { - FILE *console = pvtData.console ? pvtData.console : stderr; - - if (pFileName) - fprintf(console, "filename=\"%s\" line number=%d\n", - pFileName, lineno); - if (status > 0) - fprintf(console, "%s ", name); - - va_start(pvar, pformat); - vfprintf(console, pformat, pvar); - va_end(pvar); - fputc('\n', console); - fflush(console); - } - - if (pvtData.atExit) - return; - - pnext = msgbufGetFree(isOkToBlock); - if (!pnext) - return; - - if (pFileName) { - nchar = sprintf(pnext,"filename=\"%s\" line number=%d\n", - pFileName, lineno); - pnext += nchar; totalChar += nchar; - } - - if (status > 0) { - nchar = sprintf(pnext,"%s ",name); - pnext += nchar; totalChar += nchar; - } - va_start(pvar, pformat); - nchar = tvsnPrint(pnext, pvtData.maxMsgSize - totalChar - 1, pformat, pvar); - va_end(pvar); - if (nchar>0) { - pnext += nchar; - totalChar += nchar; - } - strcpy(pnext, "\n"); - totalChar++ ; /*include the \n */ - msgbufSetSize(totalChar); -} - - -static void errlogExitHandler(void *pvt) -{ - pvtData.atExit = 1; - epicsEventSignal(pvtData.waitForWork); - epicsEventMustWait(pvtData.waitForExit); -} - -struct initArgs { - int bufsize; - int maxMsgSize; -}; - -static void errlogInitPvt(void *arg) -{ - struct initArgs *pconfig = (struct initArgs *) arg; - epicsThreadId tid; - - pvtData.errlogInitFailed = TRUE; - pvtData.buffersize = pconfig->bufsize; - pvtData.maxMsgSize = pconfig->maxMsgSize; - pvtData.msgNeeded = adjustToWorstCaseAlignment(pvtData.maxMsgSize + - sizeof(msgNode)); - ellInit(&pvtData.listenerList); - ellInit(&pvtData.msgQueue); - pvtData.toConsole = TRUE; - pvtData.console = NULL; - pvtData.waitForWork = epicsEventMustCreate(epicsEventEmpty); - pvtData.listenerLock = epicsMutexMustCreate(); - pvtData.msgQueueLock = epicsMutexMustCreate(); - pvtData.waitForFlush = epicsEventMustCreate(epicsEventEmpty); - pvtData.flush = epicsEventMustCreate(epicsEventEmpty); - pvtData.flushLock = epicsMutexMustCreate(); - pvtData.waitForExit = epicsEventMustCreate(epicsEventEmpty); - pvtData.pbuffer = callocMustSucceed(1, pvtData.buffersize, - "errlogInitPvt"); - - errSymBld(); /* Better not to do this lazily... */ - - tid = epicsThreadCreate("errlog", epicsThreadPriorityLow, - epicsThreadGetStackSize(epicsThreadStackSmall), - (EPICSTHREADFUNC)errlogThread, 0); - if (tid) { - pvtData.errlogInitFailed = FALSE; - } -} - - -epicsShareFunc int epicsShareAPI errlogInit2(int bufsize, int maxMsgSize) -{ - static epicsThreadOnceId errlogOnceFlag = EPICS_THREAD_ONCE_INIT; - struct initArgs config; - - if (pvtData.atExit) - return 0; - - if (bufsize < BUFFER_SIZE) - bufsize = BUFFER_SIZE; - config.bufsize = bufsize; - - if (maxMsgSize < MAX_MESSAGE_SIZE) - maxMsgSize = MAX_MESSAGE_SIZE; - config.maxMsgSize = maxMsgSize; - - epicsThreadOnce(&errlogOnceFlag, errlogInitPvt, &config); - if (pvtData.errlogInitFailed) { - fprintf(stderr,"errlogInit failed\n"); - exit(1); - } - return 0; -} - -epicsShareFunc int epicsShareAPI errlogInit(int bufsize) -{ - return errlogInit2(bufsize, MAX_MESSAGE_SIZE); -} - -epicsShareFunc void epicsShareAPI errlogFlush(void) -{ - int count; - - errlogInit(0); - if (pvtData.atExit) - return; - - /*If nothing in queue dont wake up errlogThread*/ - epicsMutexMustLock(pvtData.msgQueueLock); - count = ellCount(&pvtData.msgQueue); - epicsMutexUnlock(pvtData.msgQueueLock); - if (count <= 0) - return; - - /*must let errlogThread empty queue*/ - epicsMutexMustLock(pvtData.flushLock); - epicsEventSignal(pvtData.flush); - epicsEventSignal(pvtData.waitForWork); - epicsEventMustWait(pvtData.waitForFlush); - epicsMutexUnlock(pvtData.flushLock); -} - -static void errlogThread(void) -{ - listenerNode *plistenerNode; - int noConsoleMessage; - char *pmessage; - - epicsAtExit(errlogExitHandler,0); - while (TRUE) { - epicsEventMustWait(pvtData.waitForWork); - while ((pmessage = msgbufGetSend(&noConsoleMessage))) { - epicsMutexMustLock(pvtData.listenerLock); - if (pvtData.toConsole && !noConsoleMessage) { - FILE *console = pvtData.console ? pvtData.console : stderr; - - fprintf(console, "%s", pmessage); - fflush(console); - } - - plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList); - while (plistenerNode) { - (*plistenerNode->listener)(plistenerNode->pPrivate, pmessage); - plistenerNode = (listenerNode *)ellNext(&plistenerNode->node); - } - - epicsMutexUnlock(pvtData.listenerLock); - msgbufFreeSend(); - } - - if (pvtData.atExit) - break; - if (epicsEventTryWait(pvtData.flush) != epicsEventWaitOK) - continue; - - epicsThreadSleep(.2); /*just wait an extra .2 seconds*/ - epicsEventSignal(pvtData.waitForFlush); - } - epicsEventSignal(pvtData.waitForExit); -} - - -static msgNode *msgbufGetNode(void) -{ - char *pbuffer = pvtData.pbuffer; - char *pnextFree; - msgNode *pnextSend; - - if (ellCount(&pvtData.msgQueue) == 0 ) { - pnextFree = pbuffer; /* Reset if empty */ - } - else { - msgNode *pfirst = (msgNode *)ellFirst(&pvtData.msgQueue); - msgNode *plast = (msgNode *)ellLast(&pvtData.msgQueue); - char *plimit = pbuffer + pvtData.buffersize; - - pnextFree = plast->message + adjustToWorstCaseAlignment(plast->length); - if (pfirst > plast) { - plimit = (char *)pfirst; - } - else if (pnextFree + pvtData.msgNeeded > plimit) { - pnextFree = pbuffer; /* Hit end, wrap to start */ - plimit = (char *)pfirst; - } - if (pnextFree + pvtData.msgNeeded > plimit) { - return 0; /* No room */ - } - } - - pnextSend = (msgNode *)pnextFree; - pnextSend->message = pnextFree + sizeof(msgNode); - pnextSend->length = 0; - return pnextSend; -} - -static char *msgbufGetFree(int noConsoleMessage) -{ - msgNode *pnextSend; - - if (epicsMutexLock(pvtData.msgQueueLock) != epicsMutexLockOK) - return 0; - - if ((ellCount(&pvtData.msgQueue) == 0) && pvtData.missedMessages) { - int nchar; - - pnextSend = msgbufGetNode(); - nchar = sprintf(pnextSend->message, - "errlog: %d messages were discarded\n", pvtData.missedMessages); - pnextSend->length = nchar + 1; - pvtData.missedMessages = 0; - ellAdd(&pvtData.msgQueue, &pnextSend->node); - } - - pvtData.pnextSend = pnextSend = msgbufGetNode(); - if (pnextSend) { - pnextSend->noConsoleMessage = noConsoleMessage; - pnextSend->length = 0; - return pnextSend->message; /* NB: msgQueueLock is still locked */ - } - - ++pvtData.missedMessages; - epicsMutexUnlock(pvtData.msgQueueLock); - return 0; -} - -static void msgbufSetSize(int size) -{ - msgNode *pnextSend = pvtData.pnextSend; - - pnextSend->length = size+1; - ellAdd(&pvtData.msgQueue, &pnextSend->node); - epicsMutexUnlock(pvtData.msgQueueLock); - epicsEventSignal(pvtData.waitForWork); -} - - -static char * msgbufGetSend(int *noConsoleMessage) -{ - msgNode *pnextSend; - - epicsMutexMustLock(pvtData.msgQueueLock); - pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue); - epicsMutexUnlock(pvtData.msgQueueLock); - if (!pnextSend) - return 0; - - *noConsoleMessage = pnextSend->noConsoleMessage; - return pnextSend->message; -} - -static void msgbufFreeSend(void) -{ - msgNode *pnextSend; - - epicsMutexMustLock(pvtData.msgQueueLock); - pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue); - if (!pnextSend) { - FILE *console = pvtData.console ? pvtData.console : stderr; - - fprintf(console, "errlog: msgbufFreeSend logic error\n"); - epicsThreadSuspendSelf(); - } - ellDelete(&pvtData.msgQueue, &pnextSend->node); - epicsMutexUnlock(pvtData.msgQueueLock); -} diff --git a/src/libCom/error/errlog.h b/src/libCom/error/errlog.h deleted file mode 100644 index 14061bb87..000000000 --- a/src/libCom/error/errlog.h +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INCerrlogh -#define INCerrlogh - -#include -#include - -#include "shareLib.h" -#include "compilerDependencies.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* define errMessage with a macro so we can print the file and line number*/ -#define errMessage(S, PM) \ - errPrintf(S, __FILE__, __LINE__, "%s", PM) -/* epicsPrintf and epicsVprintf old versions of errlog routines*/ -#define epicsPrintf errlogPrintf -#define epicsVprintf errlogVprintf - -typedef void (*errlogListener)(void *pPrivate, const char *message); - -typedef enum {errlogInfo, errlogMinor, errlogMajor, errlogFatal} errlogSevEnum; - -#ifdef ERRLOG_INIT -epicsShareDef char * errlogSevEnumString[] = {"info","minor","major","fatal"}; -#else -epicsShareExtern char * errlogSevEnumString[]; -#endif - -epicsShareFunc int errlogPrintf( - const char *pformat, ...) EPICS_PRINTF_STYLE(1,2); -epicsShareFunc int errlogVprintf( - const char *pformat,va_list pvar); -epicsShareFunc int errlogSevPrintf( - const errlogSevEnum severity,const char *pformat, ...) EPICS_PRINTF_STYLE(2,3); -epicsShareFunc int errlogSevVprintf( - const errlogSevEnum severity,const char *pformat,va_list pvar); -epicsShareFunc int epicsShareAPI errlogMessage( - const char *message); - -epicsShareFunc char * epicsShareAPI errlogGetSevEnumString( - const errlogSevEnum severity); -epicsShareFunc void epicsShareAPI errlogSetSevToLog( - const errlogSevEnum severity ); -epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog(void); - -epicsShareFunc void epicsShareAPI errlogAddListener( - errlogListener listener, void *pPrivate); -epicsShareFunc int epicsShareAPI errlogRemoveListeners( - errlogListener listener, void *pPrivate); - -epicsShareFunc int epicsShareAPI eltc(int yesno); -epicsShareFunc int errlogSetConsole(FILE *stream); - -epicsShareFunc int epicsShareAPI errlogInit(int bufsize); -epicsShareFunc int epicsShareAPI errlogInit2(int bufsize, int maxMsgSize); -epicsShareFunc void epicsShareAPI errlogFlush(void); - -/*other routines that write to log file*/ -epicsShareFunc void errPrintf(long status, const char *pFileName, - int lineno, const char *pformat, ...) EPICS_PRINTF_STYLE(4,5); - -epicsShareExtern int errVerbose; - -/* The following are added so that logMsg on vxWorks does not cause - * the message to appear twice on the console - */ -epicsShareFunc int errlogPrintfNoConsole( - const char *pformat, ...) EPICS_PRINTF_STYLE(1,2); -epicsShareFunc int errlogVprintfNoConsole( - const char *pformat,va_list pvar); - -#ifdef __cplusplus -} -#endif - -#endif /*INCerrlogh*/ diff --git a/src/libCom/error/error.h b/src/libCom/error/error.h deleted file mode 100644 index 18cf7eebd..000000000 --- a/src/libCom/error/error.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* error.h - errMessage symbol table header */ - -/* - * Author: Marty Kraimer - * Date: 6-1-90 - */ - - -#ifndef INCerrorh -#define INCerrorh 1 - -#define NELEMENTS(array) /* number of elements in an array */ \ - (sizeof (array) / sizeof ((array) [0])) - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct /* ERRSYMBOL - entry in symbol table */ - { - char *name; /* pointer to symbol name */ - long errNum; /* errMessage symbol number */ - } ERRSYMBOL; -typedef struct /* ERRSYMTAB - symbol table */ - { - short nsymbols; /* current number of symbols in table */ - ERRSYMBOL *symbols; /* ptr to array of symbol entries */ - } ERRSYMTAB; -typedef ERRSYMTAB *ERRSYMTAB_ID; - -/*************************************************************/ -struct errSet { /* This defines one module error set */ - long number; /* dimension of err strings */ - char **papName; /* ptr to arr of ptr to error string */ -}; -struct errDes { /* An array of error sets for modules */ - long number; /* number of err modules */ - struct errSet **papErrSet; /* ptr to arr of ptr to errSet */ -}; -extern struct errDes *dbErrDes; -/*************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif /*INCerrorh*/ diff --git a/src/libCom/error/makeStatTbl.pl b/src/libCom/error/makeStatTbl.pl deleted file mode 100644 index 4f53901f3..000000000 --- a/src/libCom/error/makeStatTbl.pl +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/perl -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# -# makeStatTbl.pl - Create Error Symbol Table -# -# Kay-Uwe Kasemir, 1-31-97, -# based on makeStatTbl shell script. -# -# SYNOPSIS -# perl makeStatTbl.pl hdir [...] -# -# DESCRIPTION -# This tool creates a symbol table (ERRSYMTAB) structure which contains the -# names and values of all the status codes defined in the .h files in the -# specified directory(s). The status codes must be prefixed with "S_" -# in order to be included in this table. -# A "err.h" file must exist in each hdir which defines the module -# numbers, eg. "M_". The table is created on standard output. -# -# This tool's primary use is for creating an error status table used -# by errPrint, and errSymLookup. -# -# FILES -# errMdef.h module number file for each h directory -# -# SEE ALSO: errnoLib(1), symLib(1) -#*/ - -use Cwd; - -die "No args (files to parse) given" if ($#ARGV < 0); - -# parse all lines of all files given: -while (<>) -{ - if (m'^#define[ /t]*S_') - { - chomp; - push @err_sym_line, $_; - } - if (m'^#[ \t]*define[ /t]+M_') - { - chomp; - push @err_facility_line, $_; - } -} - -$out_name = "errSymTbl.c"; -$dir = cwd(); - -open OUT, ">$out_name" or die "Cannot open $out_name"; - -print OUT "/*\n"; -print OUT " * status code symbol table\n"; -print OUT " *\n"; -print OUT " * CREATED BY makeStatTbl.pl\n"; -print OUT " * FROM $dir\n"; -print OUT " * ON " . localtime() . "\n"; -print OUT " */\n"; -print OUT "\n"; -print OUT "#include \"errMdef.h\"\n"; -print OUT "#include \"errSymTbl.h\"\n"; -print OUT "\n"; - - -foreach $line ( @err_facility_line ) -{ - if ($line =~ m'^#[ \t]*define[ \t]+(M_[A-Za-z0-9_]+)[ \t]+(.*)') - { - printf OUT "#ifndef %s\n", $1; - printf OUT "#define %s %s\n", $1, $2; - printf OUT "#endif /* ifdef %s */\n", $1; - } -} - -$count = 0; -foreach $line ( @err_sym_line ) -{ - print OUT "$line\n"; - # define S_symbol /* comment */ - if ($line =~ m'[ \t#]define[ \t]*(S_[A-Za-z0-9_]+).*\/\* ?(.+?) ?\*\/') - { - $symbol[$count] = $1; - $comment[$count]= $2; - ++$count; - } - else - { - # Some status values for '0' (=OK) have no comment: - unless ($line =~ m'[ \t#]define[ \t]*(S_[A-Za-z0-9_]+)') - { - die "cannot decode this line:\n$line\n"; - } - } -} - - -print OUT "\n"; -print OUT "static ERRSYMBOL symbols[] =\n"; -print OUT "{\n"; - -for ($i=0; $i<$count; ++$i) -{ - printf OUT "\t{ \"%s\", (long) %s },\n", - $comment[$i], $symbol[$i]; -} - -print OUT "};\n"; -print OUT "\n"; -print OUT "static ERRSYMTAB symTbl =\n"; -print OUT "{\n"; -print OUT "\tNELEMENTS(symbols), /* current number of symbols in table */\n"; -print OUT "\tsymbols, /* ptr to symbol array */\n"; -print OUT "};\n"; -print OUT "\n"; -print OUT "ERRSYMTAB_ID errSymTbl = &symTbl;\n"; -print OUT "\n"; -print OUT "/*\tEOF $out_name */\n"; - diff --git a/src/libCom/fdmgr/Makefile b/src/libCom/fdmgr/Makefile deleted file mode 100644 index 34b1a3dbc..000000000 --- a/src/libCom/fdmgr/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/fdmgr -INC += fdManager.h -INC += fdmgr.h -Com_SRCS += fdmgr.cpp -Com_SRCS += fdManager.cpp diff --git a/src/libCom/fdmgr/fdManager.cpp b/src/libCom/fdmgr/fdManager.cpp deleted file mode 100644 index 00f4d4a87..000000000 --- a/src/libCom/fdmgr/fdManager.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// File descriptor management C++ class library -// (for multiplexing IO in a single threaded environment) -// -// Author Jeffrey O. Hill -// johill@lanl.gov -// 505 665 1831 -// -// NOTES: -// 1) This library is not thread safe -// - -#include - -#define instantiateRecourceLib -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "epicsThread.h" -#include "fdManager.h" -#include "locationException.h" - -using std :: max; - -epicsShareDef fdManager fileDescriptorManager; - -const unsigned mSecPerSec = 1000u; -const unsigned uSecPerSec = 1000u * mSecPerSec; - -// -// fdManager::fdManager() -// -// hopefully its a reasonable guess that select() and epicsThreadSleep() -// will have the same sleep quantum -// -epicsShareFunc fdManager::fdManager () : - sleepQuantum ( epicsThreadSleepQuantum () ), - fdSetsPtr ( new fd_set [fdrNEnums] ), - pTimerQueue ( 0 ), maxFD ( 0 ), processInProg ( false ), - pCBReg ( 0 ) -{ - int status = osiSockAttach (); - assert (status); - - for ( size_t i = 0u; i < fdrNEnums; i++ ) { - FD_ZERO ( &fdSetsPtr[i] ); - } -} - -// -// fdManager::~fdManager() -// -epicsShareFunc fdManager::~fdManager() -{ - fdReg *pReg; - - while ( (pReg = this->regList.get()) ) { - pReg->state = fdReg::limbo; - pReg->destroy(); - } - while ( (pReg = this->activeList.get()) ) { - pReg->state = fdReg::limbo; - pReg->destroy(); - } - delete this->pTimerQueue; - delete [] this->fdSetsPtr; - osiSockRelease(); -} - -// -// fdManager::process() -// -epicsShareFunc void fdManager::process (double delay) -{ - this->lazyInitTimerQueue (); - - // - // no recursion - // - if (this->processInProg) { - return; - } - this->processInProg = true; - - // - // One shot at expired timers prior to going into - // select. This allows zero delay timers to arm - // fd writes. We will never process the timer queue - // more than once here so that fd activity get serviced - // in a reasonable length of time. - // - double minDelay = this->pTimerQueue->process(epicsTime::getCurrent()); - - if ( minDelay >= delay ) { - minDelay = delay; - } - - bool ioPending = false; - tsDLIter < fdReg > iter = this->regList.firstIter (); - while ( iter.valid () ) { - FD_SET(iter->getFD(), &this->fdSetsPtr[iter->getType()]); - ioPending = true; - ++iter; - } - - if ( ioPending ) { - struct timeval tv; - tv.tv_sec = static_cast ( minDelay ); - tv.tv_usec = static_cast ( (minDelay-tv.tv_sec) * uSecPerSec ); - - fd_set * pReadSet = & this->fdSetsPtr[fdrRead]; - fd_set * pWriteSet = & this->fdSetsPtr[fdrWrite]; - fd_set * pExceptSet = & this->fdSetsPtr[fdrException]; - int status = select (this->maxFD, pReadSet, pWriteSet, pExceptSet, &tv); - - this->pTimerQueue->process(epicsTime::getCurrent()); - - if ( status > 0 ) { - - // - // Look for activity - // - iter=this->regList.firstIter (); - while ( iter.valid () && status > 0 ) { - tsDLIter < fdReg > tmp = iter; - tmp++; - if (FD_ISSET(iter->getFD(), &this->fdSetsPtr[iter->getType()])) { - FD_CLR(iter->getFD(), &this->fdSetsPtr[iter->getType()]); - this->regList.remove(*iter); - this->activeList.add(*iter); - iter->state = fdReg::active; - status--; - } - iter = tmp; - } - - // - // I am careful to prevent problems if they access the - // above list while in a "callBack()" routine - // - fdReg * pReg; - while ( (pReg = this->activeList.get()) ) { - pReg->state = fdReg::limbo; - - // - // Tag current fdReg so that we - // can detect if it was deleted - // during the call back - // - this->pCBReg = pReg; - pReg->callBack(); - if (this->pCBReg != NULL) { - // - // check only after we see that it is non-null so - // that we dont trigger bounds-checker dangling pointer - // error - // - assert (this->pCBReg==pReg); - this->pCBReg = 0; - if (pReg->onceOnly) { - pReg->destroy(); - } - else { - this->regList.add(*pReg); - pReg->state = fdReg::pending; - } - } - } - } - else if ( status < 0 ) { - int errnoCpy = SOCKERRNO; - - // dont depend on flags being properly set if - // an error is retuned from select - for ( size_t i = 0u; i < fdrNEnums; i++ ) { - FD_ZERO ( &fdSetsPtr[i] ); - } - - // - // print a message if its an unexpected error - // - if ( errnoCpy != SOCK_EINTR ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf ( stderr, - "fdManager: select failed because \"%s\"\n", - sockErrBuf ); - } - } - } - else { - /* - * recover from subtle differences between - * windows sockets and UNIX sockets implementation - * of select() - */ - epicsThreadSleep(minDelay); - this->pTimerQueue->process(epicsTime::getCurrent()); - } - this->processInProg = false; - return; -} - -// -// fdReg::destroy() -// (default destroy method) -// -void fdReg::destroy() -{ - delete this; -} - -// -// fdReg::~fdReg() -// -fdReg::~fdReg() -{ - this->manager.removeReg(*this); -} - -// -// fdReg::show() -// -void fdReg::show(unsigned level) const -{ - printf ("fdReg at %p\n", (void *) this); - if (level>1u) { - printf ("\tstate = %d, onceOnly = %d\n", - this->state, this->onceOnly); - } - this->fdRegId::show(level); -} - -// -// fdRegId::show() -// -void fdRegId::show ( unsigned level ) const -{ - printf ( "fdRegId at %p\n", - static_cast ( this ) ); - if ( level > 1u ) { - printf ( "\tfd = %d, type = %d\n", - this->fd, this->type ); - } -} - -// -// fdManager::installReg () -// -void fdManager::installReg (fdReg ®) -{ - this->maxFD = max ( this->maxFD, reg.getFD()+1 ); - // Most applications will find that its important to push here to - // the front of the list so that transient writes get executed - // first allowing incoming read protocol to find that outgoing - // buffer space is newly available. - this->regList.push ( reg ); - reg.state = fdReg::pending; - - int status = this->fdTbl.add ( reg ); - if ( status != 0 ) { - throwWithLocation ( fdInterestSubscriptionAlreadyExits () ); - } -} - -// -// fdManager::removeReg () -// -void fdManager::removeReg (fdReg ®In) -{ - fdReg *pItemFound; - - pItemFound = this->fdTbl.remove (regIn); - if (pItemFound!=®In) { - fprintf(stderr, - "fdManager::removeReg() bad fd registration object\n"); - return; - } - - // - // signal fdManager that the fdReg was deleted - // during the call back - // - if (this->pCBReg == ®In) { - this->pCBReg = 0; - } - - switch (regIn.state) { - case fdReg::active: - this->activeList.remove (regIn); - break; - case fdReg::pending: - this->regList.remove (regIn); - break; - case fdReg::limbo: - break; - default: - // - // here if memory corrupted - // - assert(0); - } - regIn.state = fdReg::limbo; - - FD_CLR(regIn.getFD(), &this->fdSetsPtr[regIn.getType()]); -} - -// -// fdManager::reschedule () -// NOOP - this only runs single threaded, and therefore they can only -// add a new timer from places that will always end up in a reschedule -// -void fdManager::reschedule () -{ -} - -double fdManager::quantum () -{ - return this->sleepQuantum; -} - -// -// lookUpFD() -// -epicsShareFunc fdReg *fdManager::lookUpFD (const SOCKET fd, const fdRegType type) -{ - if (fd<0) { - return NULL; - } - fdRegId id (fd,type); - return this->fdTbl.lookup(id); -} - -// -// fdReg::fdReg() -// -fdReg::fdReg (const SOCKET fdIn, const fdRegType typIn, - const bool onceOnlyIn, fdManager &managerIn) : - fdRegId (fdIn,typIn), state (limbo), - onceOnly (onceOnlyIn), manager (managerIn) -{ - if (!FD_IN_FDSET(fdIn)) { - fprintf (stderr, "%s: fd > FD_SETSIZE ignored\n", - __FILE__); - return; - } - this->manager.installReg (*this); -} - -template class resTable; diff --git a/src/libCom/fdmgr/fdManager.h b/src/libCom/fdmgr/fdManager.h deleted file mode 100644 index 59a2f355f..000000000 --- a/src/libCom/fdmgr/fdManager.h +++ /dev/null @@ -1,204 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * File descriptor management C++ class library - * (for multiplexing IO in a single threaded environment) - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef fdManagerH_included -#define fdManagerH_included - -#include "shareLib.h" // reset share lib defines -#include "tsDLList.h" -#include "resourceLib.h" -#include "epicsTime.h" -#include "osiSock.h" -#include "epicsTimer.h" - -enum fdRegType {fdrRead, fdrWrite, fdrException, fdrNEnums}; - -// -// fdRegId -// -// file descriptor interest id -// -class epicsShareClass fdRegId -{ -public: - - fdRegId (const SOCKET fdIn, const fdRegType typeIn) : - fd(fdIn), type(typeIn) {} - - SOCKET getFD () const - { - return this->fd; - } - - fdRegType getType () const - { - return this->type; - } - - bool operator == (const fdRegId &idIn) const - { - return this->fd == idIn.fd && this->type==idIn.type; - } - - resTableIndex hash () const; - - virtual void show (unsigned level) const; - - virtual ~fdRegId() {} -private: - SOCKET fd; - fdRegType type; -}; - -// -// fdManager -// -// file descriptor manager -// -class fdManager : public epicsTimerQueueNotify { -public: - // - // exceptions - // - class fdInterestSubscriptionAlreadyExits {}; - - epicsShareFunc fdManager (); - epicsShareFunc virtual ~fdManager (); - epicsShareFunc void process ( double delay ); // delay parameter is in seconds - - // returns NULL if the fd is unknown - epicsShareFunc class fdReg *lookUpFD (const SOCKET fd, const fdRegType type); - - epicsTimer & createTimer (); - -private: - tsDLList < fdReg > regList; - tsDLList < fdReg > activeList; - resTable < fdReg, fdRegId > fdTbl; - const double sleepQuantum; - fd_set * fdSetsPtr; - epicsTimerQueuePassive * pTimerQueue; - SOCKET maxFD; - bool processInProg; - // - // Set to fdreg when in call back - // and nill otherwise - // - fdReg * pCBReg; - void reschedule (); - double quantum (); - void installReg (fdReg ®); - void removeReg (fdReg ®); - void lazyInitTimerQueue (); - fdManager ( const fdManager & ); - fdManager & operator = ( const fdManager & ); - friend class fdReg; -}; - -// -// default file descriptor manager -// -epicsShareExtern fdManager fileDescriptorManager; - -// -// fdReg -// -// file descriptor registration -// -class epicsShareClass fdReg : - public fdRegId, public tsDLNode, public tsSLNode { - friend class fdManager; - -public: - - fdReg (const SOCKET fdIn, const fdRegType type, - const bool onceOnly=false, fdManager &manager = fileDescriptorManager); - virtual ~fdReg (); - - virtual void show (unsigned level) const; - - // - // Called by the file descriptor manager: - // 1) If the fdManager is deleted and there are still - // fdReg objects attached - // 2) Immediately after calling "callBack()" if - // the constructor specified "onceOnly" - // - // fdReg::destroy() does a "delete this" - // - virtual void destroy (); - -private: - enum state {active, pending, limbo}; - - // - // called when there is activity on the fd - // NOTES - // 1) the fdManager will call this only once during the - // lifetime of a fdReg object if the constructor - // specified "onceOnly" - // - virtual void callBack ()=0; - - unsigned char state; // state enums go here - unsigned char onceOnly; - fdManager &manager; - - fdReg ( const fdReg & ); - fdReg & operator = ( const fdReg & ); -}; - -// -// fdRegId::hash() -// -inline resTableIndex fdRegId::hash () const -{ - const unsigned fdManagerHashTableMinIndexBits = 8; - const unsigned fdManagerHashTableMaxIndexBits = sizeof(SOCKET)*CHAR_BIT; - resTableIndex hashid; - - hashid = integerHash ( fdManagerHashTableMinIndexBits, - fdManagerHashTableMaxIndexBits, this->fd ); - - // - // also evenly distribute based on the type of fdRegType - // - hashid ^= this->type; - - // - // the result here is always masked to the - // proper size after it is returned to the resource class - // - return hashid; -} - -inline void fdManager::lazyInitTimerQueue () -{ - if ( ! this->pTimerQueue ) { - this->pTimerQueue = & epicsTimerQueuePassive::create ( *this ); - } -} - -inline epicsTimer & fdManager::createTimer () -{ - this->lazyInitTimerQueue (); - return this->pTimerQueue->createTimer (); -} - -#endif // fdManagerH_included - diff --git a/src/libCom/fdmgr/fdmgr.cpp b/src/libCom/fdmgr/fdmgr.cpp deleted file mode 100644 index 342bae862..000000000 --- a/src/libCom/fdmgr/fdmgr.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// File descriptor management C++ class library -// (for multiplexing IO in a single threaded environment) -// -// Author Jeffrey O. Hill -// johill@lanl.gov -// 505 665 1831 -// -// NOTES: -// 1) the routines in this file provide backward compatibility with the original -// "C" based file descriptor manager API -// 2) This library is _not_ thread safe -// - -#include -#define epicsExportSharedSymbols -#include "locationException.h" -#include "epicsAssert.h" -#include "fdManager.h" -#include "fdmgr.h" - -static const fdRegType fdiToFdRegType[] = {fdrRead, fdrWrite, fdrException}; -static const unsigned fdiToFdRegTypeNElements = sizeof (fdiToFdRegType) / sizeof (fdiToFdRegType[0]); -const unsigned mSecPerSec = 1000u; -const unsigned uSecPerSec = 1000u * mSecPerSec; - -class fdRegForOldFdmgr : public fdReg { -public: - // - // exceptions - // - class noFunctionSpecified {}; - class doubleDelete {}; - - epicsShareFunc fdRegForOldFdmgr (const SOCKET fdIn, const fdRegType type, - const bool onceOnly, fdManager &manager, pCallBackFDMgr pFunc, void *pParam); - epicsShareFunc ~fdRegForOldFdmgr (); - -private: - pCallBackFDMgr pFunc; - void *pParam; - epicsShareFunc virtual void callBack (); - fdRegForOldFdmgr ( const fdRegForOldFdmgr & ); - fdRegForOldFdmgr & operator = ( const fdRegForOldFdmgr & ); -}; - -class oldFdmgr; - -// -// timerForOldFdmgr -// -class timerForOldFdmgr : public epicsTimerNotify, public chronIntIdRes { -public: - epicsShareFunc timerForOldFdmgr (oldFdmgr &fdmgr, double delay, pCallBackFDMgr pFunc, void *pParam); - epicsShareFunc virtual ~timerForOldFdmgr (); - - // - // exceptions - // - class noFunctionSpecified {}; - class doubleDelete {}; -private: - epicsTimer &timer; - oldFdmgr &fdmgr; - pCallBackFDMgr pFunc; - void *pParam; - unsigned id; - epicsShareFunc expireStatus expire ( const epicsTime & currentTime ); - timerForOldFdmgr ( const timerForOldFdmgr & ); - timerForOldFdmgr & operator = ( const timerForOldFdmgr & ); -}; - -class oldFdmgr : public fdManager { - friend class timerForOldFdmgr; - friend epicsShareFunc int epicsShareAPI fdmgr_clear_timeout (fdctx *pfdctx, fdmgrAlarmId id); - -public: - oldFdmgr (); - -private: - chronIntIdResTable resTbl; - oldFdmgr ( const oldFdmgr & ); - oldFdmgr & operator = ( const oldFdmgr & ); -}; - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template class chronIntIdResTable ; -template class resTable; - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - -epicsShareFunc fdRegForOldFdmgr::fdRegForOldFdmgr - (const SOCKET fdIn, const fdRegType typeIn, - const bool onceOnlyIn, fdManager &managerIn, - pCallBackFDMgr pFuncIn, void *pParamIn) : - fdReg (fdIn, typeIn, onceOnlyIn, managerIn), - pFunc (pFuncIn), pParam (pParamIn) -{ - if (pFuncIn==NULL) { - throwWithLocation ( noFunctionSpecified () ); - } -} - -epicsShareFunc fdRegForOldFdmgr::~fdRegForOldFdmgr () -{ - if (this->pFunc==NULL) { - throwWithLocation ( doubleDelete () ); - } -} - -epicsShareFunc void fdRegForOldFdmgr::callBack () -{ - (*this->pFunc) (this->pParam); -} - -timerForOldFdmgr::timerForOldFdmgr ( oldFdmgr &fdmgrIn, - double delayIn, pCallBackFDMgr pFuncIn, void * pParamIn ) : - timer ( fdmgrIn.createTimer() ), - fdmgr ( fdmgrIn ), pFunc ( pFuncIn ), pParam( pParamIn ) -{ - if ( pFuncIn == NULL ) { - throwWithLocation ( noFunctionSpecified () ); - } - this->fdmgr.resTbl.idAssignAdd (*this); - this->timer.start ( *this, delayIn ); -} - -timerForOldFdmgr::~timerForOldFdmgr () -{ - this->fdmgr.resTbl.remove ( this->getId() ); - this->timer.destroy (); -} - -epicsTimerNotify::expireStatus timerForOldFdmgr::expire ( const epicsTime & ) -{ - (*this->pFunc) (this->pParam); - return noRestart; -} - -oldFdmgr::oldFdmgr () {} - -extern "C" epicsShareFunc fdctx * epicsShareAPI fdmgr_init (void) -{ - oldFdmgr *pfdm; - - try { - pfdm = new oldFdmgr(); - } - catch (...) - { - pfdm = NULL; - } - - return (fdctx *) pfdm; -} - -extern "C" epicsShareFunc fdmgrAlarmId epicsShareAPI fdmgr_add_timeout ( - fdctx *pfdctx, struct timeval *ptimeout, pCallBackFDMgr pFunc, void *pParam) -{ - double delay = ptimeout->tv_sec + ptimeout->tv_usec / static_cast (uSecPerSec); - oldFdmgr *pfdm = static_cast (pfdctx); - timerForOldFdmgr *pTimer; - unsigned id = fdmgrNoAlarm; - - if (!pfdm) { - return fdmgrNoAlarm; - } - - while (true) { - try { - pTimer = new timerForOldFdmgr - (*pfdm, delay, pFunc, pParam); - } - catch (...) - { - pTimer = NULL; - } - if (pTimer) { - id = pTimer->getId (); - if (id!=fdmgrNoAlarm) { - break; - } - else { - delete pTimer; - } - } - else { - break; - } - } - - return id; -} - -extern "C" epicsShareFunc int epicsShareAPI fdmgr_clear_timeout (fdctx *pfdctx, fdmgrAlarmId id) -{ - oldFdmgr *pfdm = static_cast (pfdctx); - timerForOldFdmgr *pTimer; - - try { - pTimer = pfdm->resTbl.remove (id); - } - catch (...) - { - pTimer = NULL; - } - - if (pTimer==NULL) { - return -1; - } - delete pTimer; - return 0; -} - -extern "C" epicsShareFunc int epicsShareAPI fdmgr_add_callback ( - fdctx *pfdctx, SOCKET fd, enum fdi_type fdi, pCallBackFDMgr pFunc, void *pParam) -{ - oldFdmgr *pfdm = static_cast (pfdctx); - fdRegForOldFdmgr *pfdrbc; - bool onceOnly = (fdi==fdi_write); - unsigned fdiType; - - if (pfdm==NULL) { - return -1; - } - - if (pFunc==NULL) { - return -1; - } - - if (fdi<0) { - return -1; - } - - fdiType = (unsigned) fdi; - - if (fdiType>=fdiToFdRegTypeNElements) { - return -1; - } - - try { - pfdrbc = new fdRegForOldFdmgr (fd, fdiToFdRegType[fdiType], onceOnly, *pfdm, pFunc, pParam); - } - catch (...) - { - pfdrbc = NULL; - } - - if (pfdrbc==NULL) { - return -1; - } - else { - return 0; - } -} - -extern "C" epicsShareFunc int epicsShareAPI fdmgr_clear_callback ( - fdctx *pfdctx, SOCKET fd, enum fdi_type fdi) -{ - oldFdmgr *pfdm = static_cast (pfdctx); - fdReg *pFDR; - - if (pfdm==NULL) { - return -1; - } - - try { - pFDR = pfdm->lookUpFD (fd, fdiToFdRegType[fdi]); - } - catch (...) - { - pFDR = NULL; - } - - if (pFDR==NULL) { - return -1; - } - else { - delete pFDR; - return 0; - } -} - -extern "C" epicsShareFunc int epicsShareAPI fdmgr_pend_event (fdctx *pfdctx, struct timeval *ptimeout) -{ - oldFdmgr *pfdm = static_cast (pfdctx); - double delay = ptimeout->tv_sec + ptimeout->tv_usec / static_cast (uSecPerSec); - - try { - pfdm->process (delay); - } - catch (...) { - return -1; - } - - return 0; -} - -extern "C" epicsShareFunc int epicsShareAPI fdmgr_delete (fdctx *pfdctx) -{ - oldFdmgr *pfdm = static_cast (pfdctx); - delete pfdm; - return 0; -} - -/* - * depricated interface - */ -extern "C" epicsShareFunc int epicsShareAPI fdmgr_clear_fd (fdctx *pfdctx, SOCKET fd) -{ - return fdmgr_clear_callback(pfdctx, fd, fdi_read); -} - -/* - * depricated interface - */ -extern "C" epicsShareFunc int epicsShareAPI fdmgr_add_fd ( - fdctx *pfdctx, SOCKET fd, void (*pfunc)(void *pParam), void *param) -{ - return fdmgr_add_callback (pfdctx, fd, fdi_read, pfunc, param); -} diff --git a/src/libCom/fdmgr/fdmgr.h b/src/libCom/fdmgr/fdmgr.h deleted file mode 100644 index a227335e7..000000000 --- a/src/libCom/fdmgr/fdmgr.h +++ /dev/null @@ -1,169 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* fdmgr.h - * - * Header file associated with a file descriptor manager - * for use with the UNIX system call select - * - * Author Jeffrey O. Hill - * hill@atdiv.lanl.gov - * 505 665 1831 - */ - -#ifndef includeFdmgrH -#define includeFdmgrH - -#include "ellLib.h" -#include "bucketLib.h" -#include "osiSock.h" -#include "epicsThread.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -enum fdi_type {fdi_read, fdi_write, fdi_excp}; -enum alarm_list_type {alt_invalid, alt_alarm, alt_expired, alt_free}; - -typedef void fdctx; -typedef void (*pCallBackFDMgr)(void *); - -/* - * C "typedef" name "alarm" was changed to "fdmgrAlarm" to avoid collisions - * with other libraries. Next the identifier was changed again to - * an unsigned integer type "fdmgrAlarmId". - * - * This "#define" is for codes that used to use a pointer to the old typedef - * "alarm" or "fdmgrAlarm" types to identify an alarm. - * - * ie the following code will allow compilation against - * all versions: - * - * #if defined (NEW_FDMGR_ALARMID) - * fdmgrAlarmId XXXX - * #elif defined (NEW_FDMGR_ALARM) - * fdmgrAlarm *XXXX; - * #else - * alarm *XXXX; - * #endif - * - * XXXX = fdmgrAlarmId fdmgr_add_timeout() - */ -typedef unsigned fdmgrAlarmId; -#define NEW_FDMGR_ALARMID - -/* - * - * Initialize a file descriptor manager session - * - */ -epicsShareFunc fdctx * epicsShareAPI fdmgr_init(void); - -/* - * Specify a function to be called with a specified parameter - * after a specified delay relative to the current time - * - * Returns fdmgrNoAlarm (zero) if alarm cant be created - */ -#define fdmgrNoAlarm 0 -epicsShareFunc fdmgrAlarmId epicsShareAPI fdmgr_add_timeout( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -struct timeval *ptimeout, /* relative delay from current time */ -pCallBackFDMgr pfunc, /* function (handler) to call */ -void *param /* first parameter passed to the func */ -); - -/* - * Clear a timeout which has not executed its function (handler) - * yet. - */ -epicsShareFunc int epicsShareAPI fdmgr_clear_timeout( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -fdmgrAlarmId id /* alarm to delete */ -); - -/* - * - * Specify a function (handler) to be called with a specified parameter - * when a file descriptor becomes active. The parameter fdi (file - * descriptor interest) specifies the type of activity (IO) we wish - * to be informed of: read, write, or exception. For more - * info on this see the man pages for the UNIX system call select(). - * - * read and exception callbacks are permanent( ie the application's - * function (handler) continues to be called each time the - * file descriptor becomes active until fdmgr_add_callback() - * is called). - * - * write callbacks are called only once after each call to - * fdmgr_add_callback() - * - */ -epicsShareFunc int epicsShareAPI fdmgr_add_callback( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -SOCKET fd, /* file descriptor */ -enum fdi_type fdi, /* file descriptor interest type */ -pCallBackFDMgr pfunc, /* function (handler) to call */ -void *param /* first parameter passed to the func */ -); - -/* - * - * Clear nterest in a type of file descriptor activity (IO). - * - */ -epicsShareFunc int epicsShareAPI fdmgr_clear_callback( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -SOCKET fd, /* file descriptor */ -enum fdi_type fdi /* file descriptor interest type */ -); - -/* - * - * Wait a specified delay relative from the current time for file - * descriptor activity (IO) or timeouts (timer expiration). Application - * specified functions (handlers) will not be called unless the - * application waits in this function or polls it frequently - * enough. - * - */ -epicsShareFunc int epicsShareAPI fdmgr_pend_event( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -struct timeval *ptimeout -); - - -/* - * obsolete interface - */ -epicsShareFunc int epicsShareAPI fdmgr_clear_fd( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -SOCKET fd -); - -/* - * obsolete interface - */ -epicsShareFunc int epicsShareAPI fdmgr_add_fd( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -SOCKET fd, -pCallBackFDMgr pfunc, /* function (handler) to call */ -void *param -); - -epicsShareFunc int epicsShareAPI fdmgr_delete(fdctx *pfdctx); - -#ifdef __cplusplus -} -#endif - -#endif /* ifndef includeFdmgrH (last line in this file) */ - diff --git a/src/libCom/flex/COPYING b/src/libCom/flex/COPYING deleted file mode 100644 index 9b01361ca..000000000 --- a/src/libCom/flex/COPYING +++ /dev/null @@ -1,38 +0,0 @@ -Flex carries the copyright used for BSD software, slightly modified -because it originated at the Lawrence Berkeley (not Livermore!) Laboratory, -which operates under a contract with the Department of Energy: - - Copyright (c) 1990 The Regents of the University of California. - All rights reserved. - - This code is derived from software contributed to Berkeley by - Vern Paxson. - - The United States Government has rights in this work pursuant - to contract no. DE-AC03-76SF00098 between the United States - Department of Energy and the University of California. - - Redistribution and use in source and binary forms are permitted - provided that: (1) source distributions retain this entire - copyright notice and comment, and (2) distributions including - binaries display the following acknowledgement: ``This product - includes software developed by the University of California, - Berkeley and its contributors'' in the documentation or other - materials provided with the distribution and in all advertising - materials mentioning features or use of this software. Neither the - name of the University nor the names of its contributors may be - used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. - -This basically says "do whatever you please with this software except -remove this notice or take advantage of the University's (or the flex -authors') name". - -Note that the "flex.skel" scanner skeleton carries no copyright notice. -You are free to do whatever you please with scanners generated using flex; -for them, you are not even bound by the above copyright. diff --git a/src/libCom/flex/Changes b/src/libCom/flex/Changes deleted file mode 100644 index 0111a1f21..000000000 --- a/src/libCom/flex/Changes +++ /dev/null @@ -1,345 +0,0 @@ -Changes between 2.3 Patch #7 (28Mar91) and 2.3 Patch #6: - - - Fixed out-of-bounds array access that caused bad tables - to be produced on machines where the bad reference happened - to yield a 1. This caused problems installing or running - flex on some Suns, in particular. - - -Changes between 2.3 Patch #6 (29Aug90) and 2.3 Patch #5: - - - Fixed a serious bug in yymore() which basically made it - completely broken. Thanks goes to Jean Christophe of - the Nethack development team for finding the problem - and passing along the fix. - - -Changes between 2.3 Patch #5 (16Aug90) and 2.3 Patch #4: - - - An up-to-date version of initscan.c so "make test" will - work after applying the previous patches - - -Changes between 2.3 Patch #4 (14Aug90) and 2.3 Patch #3: - - - Fixed bug in hexadecimal escapes which allowed only digits, - not letters, in escapes - - Fixed bug in previous "Changes" file! - - -Changes between 2.3 Patch #3 (03Aug90) and 2.3 Patch #2: - - - Correction to patch #2 for gcc compilation; thanks goes to - Paul Eggert for catching this. - - -Changes between 2.3 Patch #2 (02Aug90) and original 2.3 release: - - - Fixed (hopefully) headaches involving declaring malloc() - and free() for gcc, which defines __STDC__ but (often) doesn't - come with the standard include files such as . - Reordered #ifdef maze in the scanner skeleton in the hope of - getting the declarations right for cfront and g++, too. - - - Note that this patch supercedes patch #1 for release 2.3, - which was never announced but was available briefly for - anonymous ftp. - - -Changes between 2.3 (full) release of 28Jun90 and 2.2 (alpha) release: - - User-visible: - - - A lone <> rule (that is, one which is not qualified with - a list of start conditions) now specifies the EOF action for - *all* start conditions which haven't already had <> actions - given. To specify an end-of-file action for just the initial - state, use <>. - - - -d debug output is now contigent on the global yy_flex_debug - being set to a non-zero value, which it is by default. - - - A new macro, YY_USER_INIT, is provided for the user to specify - initialization action to be taken on the first call to the - scanner. This action is done before the scanner does its - own initialization. - - - yy_new_buffer() has been added as an alias for yy_create_buffer() - - - Comments beginning with '#' and extending to the end of the line - now work, but have been deprecated (in anticipation of making - flex recognize #line directives). - - - The funky restrictions on when semi-colons could follow the - YY_NEW_FILE and yyless macros have been removed. They now - behave identically to functions. - - - A bug in the sample redefinition of YY_INPUT in the documentation - has been corrected. - - - A bug in the sample simple tokener in the documentation has - been corrected. - - - The documentation on the incompatibilities between flex and - lex has been reordered so that the discussion of yylineno - and input() come first, as it's anticipated that these will - be the most common source of headaches. - - - Things which didn't used to be documented but now are: - - - flex interprets "^foo|bar" differently from lex. flex interprets - it as "match either a 'foo' or a 'bar', providing it comes at the - beginning of a line", whereas lex interprets it as "match either - a 'foo' at the beginning of a line, or a 'bar' anywhere". - - - flex initializes the global "yyin" on the first call to the - scanner, while lex initializes it at compile-time. - - - yy_switch_to_buffer() can be used in the yywrap() macro/routine. - - - flex scanners do not use stdio for their input, and hence when - writing an interactive scanner one must explictly call fflush() - after writing out a prompt. - - - flex scanner can be made reentrant (after a fashion) by using - "yyrestart( yyin );". This is useful for interactive scanners - which have interrupt handlers that long-jump out of the scanner. - - - a defense of why yylineno is not supported is included, along - with a suggestion on how to convert scanners which rely on it. - - - Other changes: - - - Prototypes and proper declarations of void routines have - been added to the flex source code, courtesy of Kevin B. Kenny. - - - Routines dealing with memory allocation now use void* pointers - instead of char* - see Makefile for porting implications. - - - Error-checking is now done when flex closes a file. - - - Various lint tweaks were added to reduce the number of gripes. - - - Makefile has been further parameterized to aid in porting. - - - Support for SCO Unix added. - - - Flex now sports the latest & greatest UC copyright notice - (which is only slightly different from the previous one). - - - A note has been added to flexdoc.1 mentioning work in progress - on modifying flex to generate straight C code rather than a - table-driven automaton, with an email address of whom to contact - if you are working along similar lines. - - -Changes between 2.2 Patch #3 (30Mar90) and 2.2 Patch #2: - - - fixed bug which caused -I scanners to bomb - - -Changes between 2.2 Patch #2 (27Mar90) and 2.2 Patch #1: - - - fixed bug writing past end of input buffer in yyunput() - - fixed bug detecting NUL's at the end of a buffer - - -Changes between 2.2 Patch #1 (23Mar90) and 2.2 (alpha) release: - - - Makefile fixes: definition of MAKE variable for systems - which don't have it; installation of flexdoc.1 along with - flex.1; fixed two bugs which could cause "bigtest" to fail. - - - flex.skel fix for compiling with g++. - - - README and flexdoc.1 no longer list an out-of-date BITNET address - for contacting me. - - - minor typos and formatting changes to flex.1 and flexdoc.1. - - -Changes between 2.2 (alpha) release of March '90 and previous release: - - User-visible: - - - Full user documentation now available. - - - Support for 8-bit scanners. - - - Scanners now accept NUL's. - - - A facility has been added for dealing with multiple - input buffers. - - - Two manual entries now. One which fully describes flex - (rather than just its differences from lex), and the - other for quick(er) reference. - - - A number of changes to bring flex closer into compliance - with the latest POSIX lex draft: - - %t support - flex now accepts multiple input files and concatenates - them together to form its input - previous -c (compress) flag renamed -C - do-nothing -c and -n flags added - Any indented code or code within %{}'s in section 2 is - now copied to the output - - - yyleng is now a bona fide global integer. - - - -d debug information now gives the line number of the - matched rule instead of which number rule it was from - the beginning of the file. - - - -v output now includes a summary of the flags used to generate - the scanner. - - - unput() and yyrestart() are now globally callable. - - - yyrestart() no longer closes the previous value of yyin. - - - C++ support; generated scanners can be compiled with C++ compiler. - - - Primitive -lfl library added, containing default main() - which calls yylex(). A number of routines currently living - in the scanner skeleton will probably migrate to here - in the future (in particular, yywrap() will probably cease - to be a macro and instead be a function in the -lfl library). - - - Hexadecimal (\x) escape sequences added. - - - Support for MS-DOS, VMS, and Turbo-C integrated. - - - The %used/%unused operators have been deprecated. They - may go away soon. - - - Other changes: - - - Makefile enhanced for easier testing and installation. - - The parser has been tweaked to detect some erroneous - constructions which previously were missed. - - Scanner input buffer overflow is now detected. - - Bugs with missing "const" declarations fixed. - - Out-of-date Minix/Atari patches provided. - - Scanners no longer require printf() unless FLEX_DEBUG is being used. - - A subtle input() bug has been fixed. - - Line numbers for "continued action" rules (those following - the special '|' action) are now correct. - - unput() bug fixed; had been causing problems porting flex to VMS. - - yymore() handling rewritten to fix bug with interaction - between yymore() and trailing context. - - EOF in actions now generates an error message. - - Bug involving -CFe and generating equivalence classes fixed. - - Bug which made -CF be treated as -Cf fixed. - - Support for SysV tmpnam() added. - - Unused #define's for scanner no longer generated. - - Error messages which are associated with a particular input - line are now all identified with their input line in standard - format. - - % directives which are valid to lex but not to flex are - now ignored instead of generating warnings. - - -DSYS_V flag can now also be specified -DUSG for System V - compilation. - - -Changes between 2.1 beta-test release of June '89 and previous release: - - User-visible: - - - -p flag generates a performance report to stderr. The report - consists of comments regarding features of the scanner rules - which result in slower scanners. - - - -b flag generates backtracking information to lex.backtrack. - This is a list of scanner states which require backtracking - and the characters on which they do so. By adding rules - one can remove backtracking states. If all backtracking states - are eliminated, the generated scanner will run faster. - Backtracking is not yet documented in the manual entry. - - - Variable trailing context now works, i.e., one can have - rules like "(foo)*/[ \t]*bletch". Some trailing context - patterns still cannot be properly matched and generate - error messages. These are patterns where the ending of the - first part of the rule matches the beginning of the second - part, such as "zx*/xy*", where the 'x*' matches the 'x' at - the beginning of the trailing context. Lex won't get these - patterns right either. - - - Faster scanners. - - - End-of-file rules. The special rule "<>" indicates - actions which are to be taken when an end-of-file is - encountered and yywrap() returns non-zero (i.e., indicates - no further files to process). See manual entry for example. - - - The -r (reject used) flag is gone. flex now scans the input - for occurrences of the string "REJECT" to determine if the - action is needed. It tries to be intelligent about this but - can be fooled. One can force the presence or absence of - REJECT by adding a line in the first section of the form - "%used REJECT" or "%unused REJECT". - - - yymore() has been implemented. Similarly to REJECT, flex - detects the use of yymore(), which can be overridden using - "%used" or "%unused". - - - Patterns like "x{0,3}" now work (i.e., with lower-limit == 0). - - - Removed '\^x' for ctrl-x misfeature. - - - Added '\a' and '\v' escape sequences. - - - \ now works for octal escape sequences; previously - \0 was required. - - - Better error reporting; line numbers are associated with rules. - - - yyleng is a macro; it cannot be accessed outside of the - scanner source file. - - - yytext and yyleng should not be modified within a flex action. - - - Generated scanners #define the name FLEX_SCANNER. - - - Rules are internally separated by YY_BREAK in lex.yy.c rather - than break, to allow redefinition. - - - The macro YY_USER_ACTION can be redefined to provide an action - which is always executed prior to the matched rule's action. - - - yyrestart() is a new action which can be used to restart - the scanner after it has seen an end-of-file (a "real" one, - that is, one for which yywrap() returned non-zero). It takes - a FILE* argument indicating a new file to scan and sets - things up so that a subsequent call to yylex() will start - scanning that file. - - - Internal scanner names all preceded by "yy_" - - - lex.yy.c is deleted if errors are encountered during processing. - - - Comments may be put in the first section of the input by preceding - them with '#'. - - - - Other changes: - - - Some portability-related bugs fixed, in particular for machines - with unsigned characters or sizeof( int* ) != sizeof( int ). - Also, tweaks for VMS and Microsoft C (MS-DOS), and identifiers all - trimmed to be 31 or fewer characters. Shortened file names - for dinosaur OS's. Checks for allocating > 64K memory - on 16 bit'ers. Amiga tweaks. Compiles using gcc on a Sun-3. - - Compressed and fast scanner skeletons merged. - - Skeleton header files done away with. - - Generated scanner uses prototypes and "const" for __STDC__. - - -DSV flag is now -DSYS_V for System V compilation. - - Removed all references to FTL language. - - Software now covered by BSD Copyright. - - flex will replace lex in subsequent BSD releases. diff --git a/src/libCom/flex/EPICS_READ_THIS b/src/libCom/flex/EPICS_READ_THIS deleted file mode 100644 index a1d04b97d..000000000 --- a/src/libCom/flex/EPICS_READ_THIS +++ /dev/null @@ -1,32 +0,0 @@ -This is a version of the BSD flex that has had its skeleton file munged in -order to force it to build lex programs that have all their functions and -variables defined as static. - -The file flex.skel.static is simply a copy of flex.skel that has been altered -to make all the components into static variables. - -In order to be able to actually use the lex files produced by this flavor of -flex, you must #include them into your C programs. Otherwise they will -be uncallable (all functions are static). This is typical of lex programs -that are used by yacc programs anyway. - -The scan.c file is actually the output of scan.l.DISTRIB when run through -itself, using the regular flex.skel skeleton with the -i option. - -To regenerate scan.c, make sure you have a build of a working e_flex binary -somewhere, then in this directory (not an O. build directory): - -% mv scan.l.DISTRIB scan.l -% /path/to/e_flex -Sflex.skel -8 -i scan.l -% mv lex.yy.c scan.c -% make - -Then use the new binary to make sure it can build itself: - -% O./e_flex -Sflex.skel -8 -i scan.l -% mv lex.yy.c scan.c -% make - -If that succeeds, don't forget to rename scan.l back again: - -% mv scan.l scan.l.DISTRIB diff --git a/src/libCom/flex/Flex.doc b/src/libCom/flex/Flex.doc deleted file mode 100644 index 3a37128e1..000000000 --- a/src/libCom/flex/Flex.doc +++ /dev/null @@ -1,1792 +0,0 @@ - 26 May 1990 FLEX(1) - - NAME - flex - fast lexical analyzer generator - - SYNOPSIS - flex [-bcdfinpstvFILT8 -C[efmF] -Sskeleton] [filename ...] - - DESCRIPTION - flex is a tool for generating scanners: programs which recognized lexi- - cal patterns in text. flex reads the given input files, or its standard - input if no file names are given, for a description of a scanner to gen- - erate. The description is in the form of pairs of regular expressions - and C code, called rules. flex generates as output a C source file, - lex.yy.c, which defines a routine yylex(). This file is compiled and - linked with the -lfl library to produce an executable. When the execut- - able is run, it analyzes its input for occurrences of the regular - expressions. Whenever it finds one, it executes the corresponding C - code. - - SOME SIMPLE EXAMPLES - - First some simple examples to get the flavor of how one uses flex. The - following flex input specifies a scanner which whenever it encounters - the string "username" will replace it with the user's login name: - - %% - username printf( "%s", getlogin() ); - - By default, any text not matched by a flex scanner is copied to the out- - put, so the net effect of this scanner is to copy its input file to its - output with each occurrence of "username" expanded. In this input, - there is just one rule. "username" is the pattern and the "printf" is - the action. The "%%" marks the beginning of the rules. - - Here's another simple example: - - int num_lines = 0, num_chars = 0; - - %% - \n ++num_lines; ++num_chars; - . ++num_chars; - - %% - main() - { - yylex(); - printf( "# of lines = %d, # of chars = %d\n", - num_lines, num_chars ); - } - - This scanner counts the number of characters and the number of lines in - its input (it produces no output other than the final report on the - counts). The first line declares two globals, "num_lines" and - "num_chars", which are accessible both inside yylex() and in the main() - - Version 2.3 1 - - FLEX(1) 26 May 1990 - - routine declared after the second "%%". There are two rules, one which - matches a newline ("\n") and increments both the line count and the - character count, and one which matches any character other than a new- - line (indicated by the "." regular expression). - - A somewhat more complicated example: - - /* scanner for a toy Pascal-like language */ - - %{ - /* need this for the call to atof() below */ - #include - %} - - DIGIT [0-9] - ID [a-z][a-z0-9]* - - %% - - {DIGIT}+ { - printf( "An integer: %s (%d)\n", yytext, - atoi( yytext ) ); - } - - {DIGIT}+"."{DIGIT}* { - printf( "A float: %s (%g)\n", yytext, - atof( yytext ) ); - } - - if|then|begin|end|procedure|function { - printf( "A keyword: %s\n", yytext ); - } - - {ID} printf( "An identifier: %s\n", yytext ); - - "+"|"-"|"*"|"/" printf( "An operator: %s\n", yytext ); - - "{"[^}\n]*"}" /* eat up one-line comments */ - - [ \t\n]+ /* eat up whitespace */ - - . printf( "Unrecognized character: %s\n", yytext ); - - %% - - main( argc, argv ) - int argc; - char **argv; - { - ++argv, --argc; /* skip over program name */ - if ( argc > 0 ) - yyin = fopen( argv[0], "r" ); - else - yyin = stdin; - - 2 Version 2.3 - - 26 May 1990 FLEX(1) - - yylex(); - } - - This is the beginnings of a simple scanner for a language like Pascal. - It identifies different types of tokens and reports on what it has seen. - - The details of this example will be explained in the following sections. - - FORMAT OF THE INPUT FILE - The flex input file consists of three sections, separated by a line with - just %% in it: - - definitions - %% - rules - %% - user code - - The definitions section contains declarations of simple name definitions - to simplify the scanner specification, and declarations of start condi- - tions, which are explained in a later section. - - Name definitions have the form: - - name definition - - The "name" is a word beginning with a letter or an underscore ('_') fol- - lowed by zero or more letters, digits, '_', or '-' (dash). The defini- - tion is taken to begin at the first non-white-space character following - the name and continuing to the end of the line. The definition can sub- - sequently be referred to using "{name}", which will expand to "(defini- - tion)". For example, - - DIGIT [0-9] - ID [a-z][a-z0-9]* - - defines "DIGIT" to be a regular expression which matches a single digit, - and "ID" to be a regular expression which matches a letter followed by - zero-or-more letters-or-digits. A subsequent reference to - - {DIGIT}+"."{DIGIT}* - - is identical to - - ([0-9])+"."([0-9])* - - and matches one-or-more digits followed by a '.' followed by zero-or- - more digits. - - The rules section of the flex input contains a series of rules of the - form: - - pattern action - - Version 2.3 3 - - FLEX(1) 26 May 1990 - - where the pattern must be unindented and the action must begin on the - same line. - - See below for a further description of patterns and actions. - - Finally, the user code section is simply copied to lex.yy.c verbatim. - It is used for companion routines which call or are called by the - scanner. The presence of this section is optional; if it is missing, - the second %% in the input file may be skipped, too. - - In the definitions and rules sections, any indented text or text - enclosed in %{ and %} is copied verbatim to the output (with the %{}'s - removed). The %{}'s must appear unindented on lines by themselves. - - In the rules section, any indented or %{} text appearing before the - first rule may be used to declare variables which are local to the scan- - ning routine and (after the declarations) code which is to be executed - whenever the scanning routine is entered. Other indented or %{} text in - the rule section is still copied to the output, but its meaning is not - well-defined and it may well cause compile-time errors (this feature is - present for POSIX compliance; see below for other such features). - - In the definitions section, an unindented comment (i.e., a line begin- - ning with "/*") is also copied verbatim to the output up to the next - "*/". Also, any line in the definitions section beginning with '#' is - ignored, though this style of comment is deprecated and may go away in - the future. - - PATTERNS - The patterns in the input are written using an extended set of regular - expressions. These are: - - x match the character 'x' - . any character except newline - [xyz] a "character class"; in this case, the pattern - matches either an 'x', a 'y', or a 'z' - [abj-oZ] a "character class" with a range in it; matches - an 'a', a 'b', any letter from 'j' through 'o', - or a 'Z' - [^A-Z] a "negated character class", i.e., any character - but those in the class. In this case, any - character EXCEPT an uppercase letter. - [^A-Z\n] any character EXCEPT an uppercase letter or - a newline - r* zero or more r's, where r is any regular expression - r+ one or more r's - r? zero or one r's (that is, "an optional r") - r{2,5} anywhere from two to five r's - r{2,} two or more r's - r{4} exactly 4 r's - {name} the expansion of the "name" definition - (see above) - "[xyz]\"foo" - - 4 Version 2.3 - - 26 May 1990 FLEX(1) - - the literal string: [xyz]"foo - \X if X is an 'a', 'b', 'f', 'n', 'r', 't', or 'v', - then the ANSI-C interpretation of \x. - Otherwise, a literal 'X' (used to escape - operators such as '*') - \123 the character with octal value 123 - \x2a the character with hexadecimal value 2a - (r) match an r; parentheses are used to override - precedence (see below) - - rs the regular expression r followed by the - regular expression s; called "concatenation" - - r|s either an r or an s - - r/s an r but only if it is followed by an s. The - s is not part of the matched text. This type - of pattern is called as "trailing context". - ^r an r, but only at the beginning of a line - r$ an r, but only at the end of a line. Equivalent - to "r/\n". - - r an r, but only in start condition s (see - below for discussion of start conditions) - r - same, but in any of start conditions s1, - s2, or s3 - - <> an end-of-file - <> - an end-of-file when in start condition s1 or s2 - - The regular expressions listed above are grouped according to pre- - cedence, from highest precedence at the top to lowest at the bottom. - Those grouped together have equal precedence. For example, - - foo|bar* - - is the same as - - (foo)|(ba(r*)) - - since the '*' operator has higher precedence than concatenation, and - concatenation higher than alternation ('|'). This pattern therefore - matches either the string "foo" or the string "ba" followed by zero-or- - more r's. To match "foo" or zero-or-more "bar"'s, use: - - foo|(bar)* - - Version 2.3 5 - - FLEX(1) 26 May 1990 - - and to match zero-or-more "foo"'s-or-"bar"'s: - - (foo|bar)* - - Some notes on patterns: - - - A negated character class such as the example "[^A-Z]" above will - match a newline unless "\n" (or an equivalent escape sequence) is - one of the characters explicitly present in the negated character - class (e.g., "[^A-Z\n]"). This is unlike how many other regular - expression tools treat negated character classes, but unfortunately - the inconsistency is historically entrenched. Matching newlines - means that a pattern like [^"]* can match an entire input (over- - flowing the scanner's input buffer) unless there's another quote in - the input. - - - A rule can have at most one instance of trailing context (the '/' - operator or the '$' operator). The start condition, '^', and - "<>" patterns can only occur at the beginning of a pattern, - and, as well as with '/' and '$', cannot be grouped inside - parentheses. A '^' which does not occur at the beginning of a rule - or a '$' which does not occur at the end of a rule loses its spe- - cial properties and is treated as a normal character. - - The following are illegal: - - foo/bar$ - foobar - - Note that the first of these, can be written "foo/bar\n". - - The following will result in '$' or '^' being treated as a normal - character: - - foo|(bar$) - foo|^bar - - If what's wanted is a "foo" or a bar-followed-by-a-newline, the - following could be used (the special '|' action is explained - below): - - foo | - bar$ /* action goes here */ - - A similar trick will work for matching a foo or a bar-at-the- - beginning-of-a-line. - - HOW THE INPUT IS MATCHED - When the generated scanner is run, it analyzes its input looking for - strings which match any of its patterns. If it finds more than one - match, it takes the one matching the most text (for trailing context - rules, this includes the length of the trailing part, even though it - will then be returned to the input). If it finds two or more matches of - - 6 Version 2.3 - - 26 May 1990 FLEX(1) - - the same length, the rule listed first in the flex input file is chosen. - - Once the match is determined, the text corresponding to the match - (called the token) is made available in the global character pointer - yytext, and its length in the global integer yyleng. The action - corresponding to the matched pattern is then executed (a more detailed - description of actions follows), and then the remaining input is scanned - for another match. - - If no match is found, then the default rule is executed: the next char- - acter in the input is considered matched and copied to the standard out- - put. Thus, the simplest legal flex input is: - - %% - - which generates a scanner that simply copies its input (one character at - a time) to its output. - - ACTIONS - Each pattern in a rule has a corresponding action, which can be any - arbitrary C statement. The pattern ends at the first non-escaped whi- - tespace character; the remainder of the line is its action. If the - action is empty, then when the pattern is matched the input token is - simply discarded. For example, here is the specification for a program - which deletes all occurrences of "zap me" from its input: - - %% - "zap me" - - (It will copy all other characters in the input to the output since they - will be matched by the default rule.) - - Here is a program which compresses multiple blanks and tabs down to a - single blank, and throws away whitespace found at the end of a line: - - %% - [ \t]+ putchar( ' ' ); - [ \t]+$ /* ignore this token */ - - If the action contains a '{', then the action spans till the balancing - '}' is found, and the action may cross multiple lines. flex knows about - C strings and comments and won't be fooled by braces found within them, - but also allows actions to begin with %{ and will consider the action to - be all the text up to the next %} (regardless of ordinary braces inside - the action). - - An action consisting solely of a vertical bar ('|') means "same as the - action for the next rule." See below for an illustration. - - Actions can include arbitrary C code, including return statements to - return a value to whatever routine called yylex(). Each time yylex() is - called it continues processing tokens from where it last left off until - it either reaches the end of the file or executes a return. Once it - - Version 2.3 7 - - FLEX(1) 26 May 1990 - - reaches an end-of-file, however, then any subsequent call to yylex() - will simply immediately return, unless yyrestart() is first called (see - below). - - Actions are not allowed to modify yytext or yyleng. - - There are a number of special directives which can be included within an - action: - - - ECHO copies yytext to the scanner's output. - - - BEGIN followed by the name of a start condition places the scanner - in the corresponding start condition (see below). - - - REJECT directs the scanner to proceed on to the "second best" rule - which matched the input (or a prefix of the input). The rule is - chosen as described above in "How the Input is Matched", and yytext - and yyleng set up appropriately. It may either be one which - matched as much text as the originally chosen rule but came later - in the flex input file, or one which matched less text. For exam- - ple, the following will both count the words in the input and call - the routine special() whenever "frob" is seen: - - int word_count = 0; - %% - - frob special(); REJECT; - [^ \t\n]+ ++word_count; - - Without the REJECT, any "frob"'s in the input would not be counted - as words, since the scanner normally executes only one action per - token. Multiple REJECT's are allowed, each one finding the next - best choice to the currently active rule. For example, when the - following scanner scans the token "abcd", it will write "abcdab- - caba" to the output: - - %% - a | - ab | - abc | - abcd ECHO; REJECT; - .|\n /* eat up any unmatched character */ - - (The first three rules share the fourth's action since they use the - special '|' action.) REJECT is a particularly expensive feature in - terms scanner performance; if it is used in any of the scanner's - actions it will slow down all of the scanner's matching. Further- - more, REJECT cannot be used with the -f or -F options (see below). - - Note also that unlike the other special actions, REJECT is a - branch; code immediately following it in the action will not be - executed. - - - yymore() tells the scanner that the next time it matches a rule, - - 8 Version 2.3 - - 26 May 1990 FLEX(1) - - the corresponding token should be appended onto the current value - of yytext rather than replacing it. For example, given the input - "mega-kludge" the following will write "mega-mega-kludge" to the - output: - - %% - mega- ECHO; yymore(); - kludge ECHO; - - First "mega-" is matched and echoed to the output. Then "kludge" - is matched, but the previous "mega-" is still hanging around at the - beginning of yytext so the ECHO for the "kludge" rule will actually - write "mega-kludge". The presence of yymore() in the scanner's - action entails a minor performance penalty in the scanner's match- - ing speed. - - - yyless(n) returns all but the first n characters of the current - token back to the input stream, where they will be rescanned when - the scanner looks for the next match. yytext and yyleng are - adjusted appropriately (e.g., yyleng will now be equal to n ). For - example, on the input "foobar" the following will write out - "foobarbar": - - %% - foobar ECHO; yyless(3); - [a-z]+ ECHO; - - An argument of 0 to yyless will cause the entire current input - string to be scanned again. Unless you've changed how the scanner - will subsequently process its input (using BEGIN, for example), - this will result in an endless loop. - - - unput(c) puts the character c back onto the input stream. It will - be the next character scanned. The following action will take the - current token and cause it to be rescanned enclosed in parentheses. - - { - int i; - unput( ')' ); - for ( i = yyleng - 1; i >= 0; --i ) - unput( yytext[i] ); - unput( '(' ); - } - - Note that since each unput() puts the given character back at the - beginning of the input stream, pushing back strings must be done - back-to-front. - - - input() reads the next character from the input stream. For exam- - ple, the following is one way to eat up C comments: - - %% - "/*" { - register int c; - - Version 2.3 9 - - FLEX(1) 26 May 1990 - - for ( ; ; ) - { - while ( (c = input()) != '*' && - c != EOF ) - ; /* eat up text of comment */ - - if ( c == '*' ) - { - while ( (c = input()) == '*' ) - ; - if ( c == '/' ) - break; /* found the end */ - } - - if ( c == EOF ) - { - error( "EOF in comment" ); - break; - } - } - } - - (Note that if the scanner is compiled using C++, then input() is - instead referred to as yyinput(), in order to avoid a name clash - with the C++ stream by the name of input.) - - - yyterminate() can be used in lieu of a return statement in an - action. It terminates the scanner and returns a 0 to the scanner's - caller, indicating "all done". Subsequent calls to the scanner - will immediately return unless preceded by a call to yyrestart() - (see below). By default, yyterminate() is also called when an - end-of-file is encountered. It is a macro and may be redefined. - - THE GENERATED SCANNER - The output of flex is the file lex.yy.c, which contains the scanning - routine yylex(), a number of tables used by it for matching tokens, and - a number of auxiliary routines and macros. By default, yylex() is - declared as follows: - - int yylex() - { - ... various definitions and the actions in here ... - } - - (If your environment supports function prototypes, then it will be "int - yylex( void )".) This definition may be changed by redefining the - "YY_DECL" macro. For example, you could use: - - #undef YY_DECL - #define YY_DECL float lexscan( a, b ) float a, b; - - to give the scanning routine the name lexscan, returning a float, and - taking two floats as arguments. Note that if you give arguments to the - - 10 Version 2.3 - - 26 May 1990 FLEX(1) - - scanning routine using a K&R-style/non-prototyped function declaration, - you must terminate the definition with a semi-colon (;). - - Whenever yylex() is called, it scans tokens from the global input file - yyin (which defaults to stdin). It continues until it either reaches an - end-of-file (at which point it returns the value 0) or one of its - actions executes a return statement. In the former case, when called - again the scanner will immediately return unless yyrestart() is called - to point yyin at the new input file. ( yyrestart() takes one argument, - a FILE * pointer.) In the latter case (i.e., when an action executes a - return), the scanner may then be called again and it will resume scan- - ning where it left off. - - By default (and for purposes of efficiency), the scanner uses block- - reads rather than simple getc() calls to read characters from yyin. The - nature of how it gets its input can be controlled by redefining the - YY_INPUT macro. YY_INPUT's calling sequence is - "YY_INPUT(buf,result,max_size)". Its action is to place up to max_size - characters in the character array buf and return in the integer variable - result either the number of characters read or the constant YY_NULL (0 - on Unix systems) to indicate EOF. The default YY_INPUT reads from the - global file-pointer "yyin". - - A sample redefinition of YY_INPUT (in the definitions section of the - input file): - - %{ - #undef YY_INPUT - #define YY_INPUT(buf,result,max_size) \ - { \ - int c = getchar(); \ - result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \ - } - %} - - This definition will change the input processing to occur one character - at a time. - - You also can add in things like keeping track of the input line number - this way; but don't expect your scanner to go very fast. - - When the scanner receives an end-of-file indication from YY_INPUT, it - then checks the yywrap() function. If yywrap() returns false (zero), - then it is assumed that the function has gone ahead and set up yyin to - point to another input file, and scanning continues. If it returns true - (non-zero), then the scanner terminates, returning 0 to its caller. - - The default yywrap() always returns 1. Presently, to redefine it you - must first "#undef yywrap", as it is currently implemented as a macro. - As indicated by the hedging in the previous sentence, it may be changed - to a true function in the near future. - - The scanner writes its ECHO output to the yyout global (default, - stdout), which may be redefined by the user simply by assigning it to - - Version 2.3 11 - - FLEX(1) 26 May 1990 - - some other FILE pointer. - - START CONDITIONS - flex provides a mechanism for conditionally activating rules. Any rule - whose pattern is prefixed with "" will only be active when the - scanner is in the start condition named "sc". For example, - - [^"]* { /* eat up the string body ... */ - ... - } - - will be active only when the scanner is in the "STRING" start condition, - and - - \. { /* handle an escape ... */ - ... - } - - will be active only when the current start condition is either "INI- - TIAL", "STRING", or "QUOTE". - - Start conditions are declared in the definitions (first) section of the - input using unindented lines beginning with either %s or %x followed by - a list of names. The former declares inclusive start conditions, the - latter exclusive start conditions. A start condition is activated using - the BEGIN action. Until the next BEGIN action is executed, rules with - the given start condition will be active and rules with other start con- - ditions will be inactive. If the start condition is inclusive, then - rules with no start conditions at all will also be active. If it is - exclusive, then only rules qualified with the start condition will be - active. A set of rules contingent on the same exclusive start condition - describe a scanner which is independent of any of the other rules in the - flex input. Because of this, exclusive start conditions make it easy to - specify "mini-scanners" which scan portions of the input that are syn- - tactically different from the rest (e.g., comments). - - If the distinction between inclusive and exclusive start conditions is - still a little vague, here's a simple example illustrating the connec- - tion between the two. The set of rules: - - %s example - %% - foo /* do something */ - - is equivalent to - - %x example - %% - foo /* do something */ - - The default rule (to ECHO any unmatched character) remains active in - start conditions. - - 12 Version 2.3 - - 26 May 1990 FLEX(1) - - BEGIN(0) returns to the original state where only the rules with no - start conditions are active. This state can also be referred to as the - start-condition "INITIAL", so BEGIN(INITIAL) is equivalent to BEGIN(0). - (The parentheses around the start condition name are not required but - are considered good style.) - - BEGIN actions can also be given as indented code at the beginning of the - rules section. For example, the following will cause the scanner to - enter the "SPECIAL" start condition whenever yylex() is called and the - global variable enter_special is true: - - int enter_special; - - %x SPECIAL - %% - if ( enter_special ) - BEGIN(SPECIAL); - - blahblahblah - ...more rules follow... - - To illustrate the uses of start conditions, here is a scanner which pro- - vides two different interpretations of a string like "123.456". By - default it will treat it as as three tokens, the integer "123", a dot - ('.'), and the integer "456". But if the string is preceded earlier in - the line by the string "expect-floats" it will treat it as a single - token, the floating-point number 123.456: - - %{ - #include - %} - %s expect - - %% - expect-floats BEGIN(expect); - - [0-9]+"."[0-9]+ { - printf( "found a float, = %f\n", - atof( yytext ) ); - } - \n { - /* that's the end of the line, so - * we need another "expect-number" - * before we'll recognize any more - * numbers - */ - BEGIN(INITIAL); - } - - [0-9]+ { - printf( "found an integer, = %d\n", - atoi( yytext ) ); - } - - Version 2.3 13 - - FLEX(1) 26 May 1990 - - "." printf( "found a dot\n" ); - - Here is a scanner which recognizes (and discards) C comments while main- - taining a count of the current input line. - - %x comment - %% - int line_num = 1; - - "/*" BEGIN(comment); - - [^*\n]* /* eat anything that's not a '*' */ - "*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ - \n ++line_num; - "*"+"/" BEGIN(INITIAL); - - Note that start-conditions names are really integer values and can be - stored as such. Thus, the above could be extended in the following - fashion: - - %x comment foo - %% - int line_num = 1; - int comment_caller; - - "/*" { - comment_caller = INITIAL; - BEGIN(comment); - } - - ... - - "/*" { - comment_caller = foo; - BEGIN(comment); - } - - [^*\n]* /* eat anything that's not a '*' */ - "*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ - \n ++line_num; - "*"+"/" BEGIN(comment_caller); - - One can then implement a "stack" of start conditions using an array of - integers. (It is likely that such stacks will become a full-fledged - flex feature in the future.) Note, though, that start conditions do not - have their own name-space; %s's and %x's declare names in the same - fashion as #define's. - - MULTIPLE INPUT BUFFERS - Some scanners (such as those which support "include" files) require - reading from several input streams. As flex scanners do a large amount - of buffering, one cannot control where the next input will be read from - by simply writing a YY_INPUT which is sensitive to the scanning context. - - 14 Version 2.3 - - 26 May 1990 FLEX(1) - - YY_INPUT is only called when the scanner reaches the end of its buffer, - which may be a long time after scanning a statement such as an "include" - which requires switching the input source. - - To negotiate these sorts of problems, flex provides a mechanism for - creating and switching between multiple input buffers. An input buffer - is created by using: - - YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) - - which takes a FILE pointer and a size and creates a buffer associated - with the given file and large enough to hold size characters (when in - doubt, use YY_BUF_SIZE for the size). It returns a YY_BUFFER_STATE han- - dle, which may then be passed to other routines: - - void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) - - switches the scanner's input buffer so subsequent tokens will come from - new_buffer. Note that yy_switch_to_buffer() may be used by yywrap() to - sets things up for continued scanning, instead of opening a new file and - pointing yyin at it. - - void yy_delete_buffer( YY_BUFFER_STATE buffer ) - - is used to reclaim the storage associated with a buffer. - - yy_new_buffer() is an alias for yy_create_buffer(), provided for compa- - tibility with the C++ use of new and delete for creating and destroying - dynamic objects. - - Finally, the YY_CURRENT_BUFFER macro returns a YY_BUFFER_STATE handle to - the current buffer. - - Here is an example of using these features for writing a scanner which - expands include files (the <> feature is discussed below): - - /* the "incl" state is used for picking up the name - * of an include file - */ - %x incl - - %{ - #define MAX_INCLUDE_DEPTH 10 - YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; - int include_stack_ptr = 0; - %} - - %% - include BEGIN(incl); - - [a-z]+ ECHO; - [^a-z\n]*\n? ECHO; - - [ \t]* /* eat the whitespace */ - - Version 2.3 15 - - FLEX(1) 26 May 1990 - - [^ \t\n]+ { /* got the include file name */ - if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) - { - fprintf( stderr, "Includes nested too deeply" ); - exit( 1 ); - } - - include_stack[include_stack_ptr++] = - YY_CURRENT_BUFFER; - - yyin = fopen( yytext, "r" ); - - if ( ! yyin ) - error( ... ); - - yy_switch_to_buffer( - yy_create_buffer( yyin, YY_BUF_SIZE ) ); - - BEGIN(INITIAL); - } - - <> { - if ( --include_stack_ptr < 0 ) - { - yyterminate(); - } - - else - yy_switch_to_buffer( - include_stack[include_stack_ptr] ); - } - - END-OF-FILE RULES - The special rule "<>" indicates actions which are to be taken when - an end-of-file is encountered and yywrap() returns non-zero (i.e., indi- - cates no further files to process). The action must finish by doing one - of four things: - - - the special YY_NEW_FILE action, if yyin has been pointed at a new - file to process; - - - a return statement; - - - the special yyterminate() action; - - - or, switching to a new buffer using yy_switch_to_buffer() as shown - in the example above. - - <> rules may not be used with other patterns; they may only be - qualified with a list of start conditions. If an unqualified <> - rule is given, it applies to all start conditions which do not already - have <> actions. To specify an <> rule for only the initial - start condition, use - - 16 Version 2.3 - - 26 May 1990 FLEX(1) - - <> - - These rules are useful for catching things like unclosed comments. An - example: - - %x quote - %% - - ...other rules for dealing with quotes... - - <> { - error( "unterminated quote" ); - yyterminate(); - } - <> { - if ( *++filelist ) - { - yyin = fopen( *filelist, "r" ); - YY_NEW_FILE; - } - else - yyterminate(); - } - - MISCELLANEOUS MACROS - The macro YY_USER_ACTION can be redefined to provide an action which is - always executed prior to the matched rule's action. For example, it - could be #define'd to call a routine to convert yytext to lower-case. - - The macro YY_USER_INIT may be redefined to provide an action which is - always executed before the first scan (and before the scanner's internal - initializations are done). For example, it could be used to call a rou- - tine to read in a data table or open a logging file. - - In the generated scanner, the actions are all gathered in one large - switch statement and separated using YY_BREAK, which may be redefined. - By default, it is simply a "break", to separate each rule's action from - the following rule's. Redefining YY_BREAK allows, for example, C++ - users to #define YY_BREAK to do nothing (while being very careful that - every rule ends with a "break" or a "return"!) to avoid suffering from - unreachable statement warnings where because a rule's action ends with - "return", the YY_BREAK is inaccessible. - - INTERFACING WITH YACC - One of the main uses of flex is as a companion to the yacc parser- - generator. yacc parsers expect to call a routine named yylex() to find - the next input token. The routine is supposed to return the type of the - next token as well as putting any associated value in the global yylval. - To use flex with yacc, one specifies the -d option to yacc to instruct - it to generate the file y.tab.h containing definitions of all the - %tokens appearing in the yacc input. This file is then included in the - - Version 2.3 17 - - FLEX(1) 26 May 1990 - - flex scanner. For example, if one of the tokens is "TOK_NUMBER", part - of the scanner might look like: - - %{ - #include "y.tab.h" - %} - - %% - - [0-9]+ yylval = atoi( yytext ); return TOK_NUMBER; - - TRANSLATION TABLE - In the name of POSIX compliance, flex supports a translation table for - mapping input characters into groups. The table is specified in the - first section, and its format looks like: - - %t - 1 abcd - 2 ABCDEFGHIJKLMNOPQRSTUVWXYZ - 52 0123456789 - 6 \t\ \n - %t - - This example specifies that the characters 'a', 'b', 'c', and 'd' are to - all be lumped into group #1, upper-case letters in group #2, digits in - group #52, tabs, blanks, and newlines into group #6, and no other char- - acters will appear in the patterns. The group numbers are actually - disregarded by flex; %t serves, though, to lump characters together. - Given the above table, for example, the pattern "a(AA)*5" is equivalent - to "d(ZQ)*0". They both say, "match any character in group #1, followed - by zero-or-more pairs of characters from group #2, followed by a charac- - ter from group #52." Thus %t provides a crude way for introducing - equivalence classes into the scanner specification. - - Note that the -i option (see below) coupled with the equivalence classes - which flex automatically generates take care of virtually all the - instances when one might consider using %t. But what the hell, it's - there if you want it. - - OPTIONS - flex has the following options: - - -b Generate backtracking information to lex.backtrack. This is a list - of scanner states which require backtracking and the input charac- - ters on which they do so. By adding rules one can remove back- - tracking states. If all backtracking states are eliminated and -f - or -F is used, the generated scanner will run faster (see the -p - flag). Only users who wish to squeeze every last cycle out of - their scanners need worry about this option. (See the section on - PERFORMANCE CONSIDERATIONS below.) - - -c is a do-nothing, deprecated option included for POSIX compliance. - - 18 Version 2.3 - - 26 May 1990 FLEX(1) - - NOTE: in previous releases of flex -c specified table-compression - options. This functionality is now given by the -C flag. To ease - the the impact of this change, when flex encounters -c, it - currently issues a warning message and assumes that -C was desired - instead. In the future this "promotion" of -c to -C will go away - in the name of full POSIX compliance (unless the POSIX meaning is - removed first). - - -d makes the generated scanner run in debug mode. Whenever a pattern - is recognized and the global yy_flex_debug is non-zero (which is - the default), the scanner will write to stderr a line of the form: - - --accepting rule at line 53 ("the matched text") - - The line number refers to the location of the rule in the file - defining the scanner (i.e., the file that was fed to flex). Mes- - sages are also generated when the scanner backtracks, accepts the - default rule, reaches the end of its input buffer (or encounters a - NUL; at this point, the two look the same as far as the scanner's - concerned), or reaches an end-of-file. - - -f specifies (take your pick) full table or fast scanner. No table - compression is done. The result is large but fast. This option is - equivalent to -Cf (see below). - - -i instructs flex to generate a case-insensitive scanner. The case of - letters given in the flex input patterns will be ignored, and - tokens in the input will be matched regardless of case. The - matched text given in yytext will have the preserved case (i.e., it - will not be folded). - - -n is another do-nothing, deprecated option included only for POSIX - compliance. - - -p generates a performance report to stderr. The report consists of - comments regarding features of the flex input file which will cause - a loss of performance in the resulting scanner. Note that the use - of REJECT and variable trailing context (see the BUGS section in - flex(1)) entails a substantial performance penalty; use of - yymore(), the ^ operator, and the -I flag entail minor performance - penalties. - - -s causes the default rule (that unmatched scanner input is echoed to - stdout) to be suppressed. If the scanner encounters input that - does not match any of its rules, it aborts with an error. This - option is useful for finding holes in a scanner's rule set. - - -t instructs flex to write the scanner it generates to standard output - instead of lex.yy.c. - - -v specifies that flex should write to stderr a summary of statistics - regarding the scanner it generates. Most of the statistics are - meaningless to the casual flex user, but the first line identifies - the version of flex, which is useful for figuring out where you - - Version 2.3 19 - - FLEX(1) 26 May 1990 - - stand with respect to patches and new releases, and the next two - lines give the date when the scanner was created and a summary of - the flags which were in effect. - - -F specifies that the fast scanner table representation should be - used. This representation is about as fast as the full table - representation (-f), and for some sets of patterns will be consid- - erably smaller (and for others, larger). In general, if the pat- - tern set contains both "keywords" and a catch-all, "identifier" - rule, such as in the set: - - "case" return TOK_CASE; - "switch" return TOK_SWITCH; - ... - "default" return TOK_DEFAULT; - [a-z]+ return TOK_ID; - - then you're better off using the full table representation. If - only the "identifier" rule is present and you then use a hash table - or some such to detect the keywords, you're better off using -F. - - This option is equivalent to -CF (see below). - - -I instructs flex to generate an interactive scanner. Normally, - scanners generated by flex always look ahead one character before - deciding that a rule has been matched. At the cost of some scan- - ning overhead, flex will generate a scanner which only looks ahead - when needed. Such scanners are called interactive because if you - want to write a scanner for an interactive system such as a command - shell, you will probably want the user's input to be terminated - with a newline, and without -I the user will have to type a charac- - ter in addition to the newline in order to have the newline recog- - nized. This leads to dreadful interactive performance. - - If all this seems to confusing, here's the general rule: if a human - will be typing in input to your scanner, use -I, otherwise don't; - if you don't care about squeezing the utmost performance from your - scanner and you don't want to make any assumptions about the input - to your scanner, use -I. - - - Note, -I cannot be used in conjunction with full or fast tables, - i.e., the -f, -F, -Cf, or -CF flags. - - -L instructs flex not to generate #line directives. Without this - option, flex peppers the generated scanner with #line directives so - error messages in the actions will be correctly located with - respect to the original flex input file, and not to the fairly - meaningless line numbers of lex.yy.c. (Unfortunately flex does not - presently generate the necessary directives to "retarget" the line - numbers for those parts of lex.yy.c which it generated. So if - there is an error in the generated code, a meaningless line number - is reported.) - - -T makes flex run in trace mode. It will generate a lot of messages - - 20 Version 2.3 - - 26 May 1990 FLEX(1) - - to stdout concerning the form of the input and the resultant non- - deterministic and deterministic finite automata. This option is - mostly for use in maintaining flex. - - -8 instructs flex to generate an 8-bit scanner, i.e., one which can - recognize 8-bit characters. On some sites, flex is installed with - this option as the default. On others, the default is 7-bit char- - acters. To see which is the case, check the verbose (-v) output - for "equivalence classes created". If the denominator of the - number shown is 128, then by default flex is generating 7-bit char- - acters. If it is 256, then the default is 8-bit characters and the - -8 flag is not required (but may be a good idea to keep the scanner - specification portable). Feeding a 7-bit scanner 8-bit characters - will result in infinite loops, bus errors, or other such fireworks, - so when in doubt, use the flag. Note that if equivalence classes - are used, 8-bit scanners take only slightly more table space than - 7-bit scanners (128 bytes, to be exact); if equivalence classes are - not used, however, then the tables may grow up to twice their 7-bit - size. - - -C[efmF] - controls the degree of table compression. - - -Ce directs flex to construct equivalence classes, i.e., sets of - characters which have identical lexical properties (for example, if - the only appearance of digits in the flex input is in the character - class "[0-9]" then the digits '0', '1', ..., '9' will all be put in - the same equivalence class). Equivalence classes usually give - dramatic reductions in the final table/object file sizes (typically - a factor of 2-5) and are pretty cheap performance-wise (one array - look-up per character scanned). - - -Cf specifies that the full scanner tables should be generated - - flex should not compress the tables by taking advantages of similar - transition functions for different states. - - -CF specifies that the alternate fast scanner representation - (described above under the -F flag) should be used. - - -Cm directs flex to construct meta-equivalence classes, which are - sets of equivalence classes (or characters, if equivalence classes - are not being used) that are commonly used together. Meta- - equivalence classes are often a big win when using compressed - tables, but they have a moderate performance impact (one or two - "if" tests and one array look-up per character scanned). - - A lone -C specifies that the scanner tables should be compressed - but neither equivalence classes nor meta-equivalence classes should - be used. - - The options -Cf or -CF and -Cm do not make sense together - there - is no opportunity for meta-equivalence classes if the table is not - being compressed. Otherwise the options may be freely mixed. - - Version 2.3 21 - - FLEX(1) 26 May 1990 - - The default setting is -Cem, which specifies that flex should gen- - erate equivalence classes and meta-equivalence classes. This set- - ting provides the highest degree of table compression. You can - trade off faster-executing scanners at the cost of larger tables - with the following generally being true: - - slowest & smallest - -Cem - -Cm - -Ce - -C - -C{f,F}e - -C{f,F} - fastest & largest - - Note that scanners with the smallest tables are usually generated - and compiled the quickest, so during development you will usually - want to use the default, maximal compression. - - -Cfe is often a good compromise between speed and size for produc- - tion scanners. - - -C options are not cumulative; whenever the flag is encountered, - the previous -C settings are forgotten. - - -Sskeleton_file - overrides the default skeleton file from which flex constructs its - scanners. You'll never need this option unless you are doing flex - maintenance or development. - - PERFORMANCE CONSIDERATIONS - The main design goal of flex is that it generate high-performance - scanners. It has been optimized for dealing well with large sets of - rules. Aside from the effects of table compression on scanner speed - outlined above, there are a number of options/actions which degrade per- - formance. These are, from most expensive to least: - - REJECT - - pattern sets that require backtracking - arbitrary trailing context - - '^' beginning-of-line operator - yymore() - - with the first three all being quite expensive and the last two being - quite cheap. - - REJECT should be avoided at all costs when performance is important. It - is a particularly expensive option. - - Getting rid of backtracking is messy and often may be an enormous amount - of work for a complicated scanner. In principal, one begins by using - the -b flag to generate a lex.backtrack file. For example, on the input - - 22 Version 2.3 - - 26 May 1990 FLEX(1) - - %% - foo return TOK_KEYWORD; - foobar return TOK_KEYWORD; - - the file looks like: - - State #6 is non-accepting - - associated rule line numbers: - 2 3 - out-transitions: [ o ] - jam-transitions: EOF [ \001-n p-\177 ] - - State #8 is non-accepting - - associated rule line numbers: - 3 - out-transitions: [ a ] - jam-transitions: EOF [ \001-` b-\177 ] - - State #9 is non-accepting - - associated rule line numbers: - 3 - out-transitions: [ r ] - jam-transitions: EOF [ \001-q s-\177 ] - - Compressed tables always backtrack. - - The first few lines tell us that there's a scanner state in which it can - make a transition on an 'o' but not on any other character, and that in - that state the currently scanned text does not match any rule. The - state occurs when trying to match the rules found at lines 2 and 3 in - the input file. If the scanner is in that state and then reads some- - thing other than an 'o', it will have to backtrack to find a rule which - is matched. With a bit of headscratching one can see that this must be - the state it's in when it has seen "fo". When this has happened, if - anything other than another 'o' is seen, the scanner will have to back - up to simply match the 'f' (by the default rule). - - The comment regarding State #8 indicates there's a problem when "foob" - has been scanned. Indeed, on any character other than a 'b', the - scanner will have to back up to accept "foo". Similarly, the comment - for State #9 concerns when "fooba" has been scanned. - - The final comment reminds us that there's no point going to all the - trouble of removing backtracking from the rules unless we're using -f or - -F, since there's no performance gain doing so with compressed scanners. - - The way to remove the backtracking is to add "error" rules: - - %% - foo return TOK_KEYWORD; - foobar return TOK_KEYWORD; - - fooba | - - Version 2.3 23 - - FLEX(1) 26 May 1990 - - foob | - fo { - /* false alarm, not really a keyword */ - return TOK_ID; - } - - Eliminating backtracking among a list of keywords can also be done using - a "catch-all" rule: - - %% - foo return TOK_KEYWORD; - foobar return TOK_KEYWORD; - - [a-z]+ return TOK_ID; - - This is usually the best solution when appropriate. - - Backtracking messages tend to cascade. With a complicated set of rules - it's not uncommon to get hundreds of messages. If one can decipher - them, though, it often only takes a dozen or so rules to eliminate the - backtracking (though it's easy to make a mistake and have an error rule - accidentally match a valid token. A possible future flex feature will - be to automatically add rules to eliminate backtracking). - - Variable trailing context (where both the leading and trailing parts do - not have a fixed length) entails almost the same performance loss as - REJECT (i.e., substantial). So when possible a rule like: - - %% - mouse|rat/(cat|dog) run(); - - is better written: - - %% - mouse/cat|dog run(); - rat/cat|dog run(); - - or as - - %% - mouse|rat/cat run(); - mouse|rat/dog run(); - - Note that here the special '|' action does not provide any savings, and - can even make things worse (see BUGS in flex(1)). - - Another area where the user can increase a scanner's performance (and - one that's easier to implement) arises from the fact that the longer the - tokens matched, the faster the scanner will run. This is because with - long tokens the processing of most input characters takes place in the - (short) inner scanning loop, and does not often have to go through the - additional work of setting up the scanning environment (e.g., yytext) - for the action. Recall the scanner for C comments: - - 24 Version 2.3 - - 26 May 1990 FLEX(1) - - %x comment - %% - int line_num = 1; - - "/*" BEGIN(comment); - - [^*\n]* - "*"+[^*/\n]* - \n ++line_num; - "*"+"/" BEGIN(INITIAL); - - This could be sped up by writing it as: - - %x comment - %% - int line_num = 1; - - "/*" BEGIN(comment); - - [^*\n]* - [^*\n]*\n ++line_num; - "*"+[^*/\n]* - "*"+[^*/\n]*\n ++line_num; - "*"+"/" BEGIN(INITIAL); - - Now instead of each newline requiring the processing of another action, - recognizing the newlines is "distributed" over the other rules to keep - the matched text as long as possible. Note that adding rules does not - slow down the scanner! The speed of the scanner is independent of the - number of rules or (modulo the considerations given at the beginning of - this section) how complicated the rules are with regard to operators - such as '*' and '|'. - - A final example in speeding up a scanner: suppose you want to scan - through a file containing identifiers and keywords, one per line and - with no other extraneous characters, and recognize all the keywords. A - natural first approach is: - - %% - asm | - auto | - break | - ... etc ... - volatile | - while /* it's a keyword */ - - .|\n /* it's not a keyword */ - - To eliminate the back-tracking, introduce a catch-all rule: - - %% - asm | - auto | - - Version 2.3 25 - - FLEX(1) 26 May 1990 - - break | - ... etc ... - volatile | - while /* it's a keyword */ - - [a-z]+ | - .|\n /* it's not a keyword */ - - Now, if it's guaranteed that there's exactly one word per line, then we - can reduce the total number of matches by a half by merging in the - recognition of newlines with that of the other tokens: - - %% - asm\n | - auto\n | - break\n | - ... etc ... - volatile\n | - while\n /* it's a keyword */ - - [a-z]+\n | - .|\n /* it's not a keyword */ - - One has to be careful here, as we have now reintroduced backtracking - into the scanner. In particular, while we know that there will never be - any characters in the input stream other than letters or newlines, flex - can't figure this out, and it will plan for possibly needing backtrack- - ing when it has scanned a token like "auto" and then the next character - is something other than a newline or a letter. Previously it would then - just match the "auto" rule and be done, but now it has no "auto" rule, - only a "auto\n" rule. To eliminate the possibility of backtracking, we - could either duplicate all rules but without final newlines, or, since - we never expect to encounter such an input and therefore don't how it's - classified, we can introduce one more catch-all rule, this one which - doesn't include a newline: - - %% - asm\n | - auto\n | - break\n | - ... etc ... - volatile\n | - while\n /* it's a keyword */ - - [a-z]+\n | - [a-z]+ | - .|\n /* it's not a keyword */ - - Compiled with -Cf, this is about as fast as one can get a flex scanner - to go for this particular problem. - - A final note: flex is slow when matching NUL's, particularly when a - token contains multiple NUL's. It's best to write rules which match - short amounts of text if it's anticipated that the text will often - - 26 Version 2.3 - - 26 May 1990 FLEX(1) - - include NUL's. - - INCOMPATIBILITIES WITH LEX AND POSIX - flex is a rewrite of the Unix lex tool (the two implementations do not - share any code, though), with some extensions and incompatibilities, - both of which are of concern to those who wish to write scanners accept- - able to either implementation. At present, the POSIX lex draft is very - close to the original lex implementation, so some of these incompatibil- - ities are also in conflict with the POSIX draft. But the intent is that - except as noted below, flex as it presently stands will ultimately be - POSIX conformant (i.e., that those areas of conflict with the POSIX - draft will be resolved in flex's favor). Please bear in mind that all - the comments which follow are with regard to the POSIX draft standard of - Summer 1989, and not the final document (or subsequent drafts); they are - included so flex users can be aware of the standardization issues and - those areas where flex may in the near future undergo changes incompati- - ble with its current definition. - - flex is fully compatible with lex with the following exceptions: - - - The undocumented lex scanner internal variable yylineno is not sup- - ported. It is difficult to support this option efficiently, since - it requires examining every character scanned and reexamining the - characters when the scanner backs up. Things get more complicated - when the end of buffer or file is reached or a NUL is scanned - (since the scan must then be restarted with the proper line number - count), or the user uses the yyless(), unput(), or REJECT actions, - or the multiple input buffer functions. - - The fix is to add rules which, upon seeing a newline, increment - yylineno. This is usually an easy process, though it can be a drag - if some of the patterns can match multiple newlines along with - other characters. - - yylineno is not part of the POSIX draft. - - - The input() routine is not redefinable, though it may be called to - read characters following whatever has been matched by a rule. If - input() encounters an end-of-file the normal yywrap() processing is - done. A ``real'' end-of-file is returned by input() as EOF. - - Input is instead controlled by redefining the YY_INPUT macro. - - The flex restriction that input() cannot be redefined is in accor- - dance with the POSIX draft, but YY_INPUT has not yet been accepted - into the draft (and probably won't; it looks like the draft will - simply not specify any way of controlling the scanner's input other - than by making an initial assignment to yyin). - - - flex scanners do not use stdio for input. Because of this, when - writing an interactive scanner one must explicitly call fflush() on - the stream associated with the terminal after writing out a prompt. - With lex such writes are automatically flushed since lex scanners - use getchar() for their input. Also, when writing interactive - - Version 2.3 27 - - FLEX(1) 26 May 1990 - - scanners with flex, the -I flag must be used. - - - flex scanners are not as reentrant as lex scanners. In particular, - if you have an interactive scanner and an interrupt handler which - long-jumps out of the scanner, and the scanner is subsequently - called again, you may get the following message: - - fatal flex scanner internal error--end of buffer missed - - To reenter the scanner, first use - - yyrestart( yyin ); - - - output() is not supported. Output from the ECHO macro is done to - the file-pointer yyout (default stdout). - - The POSIX draft mentions that an output() routine exists but - currently gives no details as to what it does. - - - lex does not support exclusive start conditions (%x), though they - are in the current POSIX draft. - - - When definitions are expanded, flex encloses them in parentheses. - With lex, the following: - - NAME [A-Z][A-Z0-9]* - %% - foo{NAME}? printf( "Found it\n" ); - %% - - will not match the string "foo" because when the macro is expanded - the rule is equivalent to "foo[A-Z][A-Z0-9]*?" and the precedence - is such that the '?' is associated with "[A-Z0-9]*". With flex, - the rule will be expanded to "foo([A-Z][A-Z0-9]*)?" and so the - string "foo" will match. Note that because of this, the ^, $, , - /, and <> operators cannot be used in a flex definition. - - The POSIX draft interpretation is the same as flex's. - - - To specify a character class which matches anything but a left - bracket (']'), in lex one can use "[^]]" but with flex one must use - "[^\]]". The latter works with lex, too. - - - The lex %r (generate a Ratfor scanner) option is not supported. It - is not part of the POSIX draft. - - - If you are providing your own yywrap() routine, you must include a - "#undef yywrap" in the definitions section (section 1). Note that - the "#undef" will have to be enclosed in %{}'s. - - The POSIX draft specifies that yywrap() is a function and this is - very unlikely to change; so flex users are warned that yywrap() is - likely to be changed to a function in the near future. - - 28 Version 2.3 - - 26 May 1990 FLEX(1) - - - After a call to unput(), yytext and yyleng are undefined until the - next token is matched. This is not the case with lex or the - present POSIX draft. - - - The precedence of the {} (numeric range) operator is different. - lex interprets "abc{1,3}" as "match one, two, or three occurrences - of 'abc'", whereas flex interprets it as "match 'ab' followed by - one, two, or three occurrences of 'c'". The latter is in agreement - with the current POSIX draft. - - - The precedence of the ^ operator is different. lex interprets - "^foo|bar" as "match either 'foo' at the beginning of a line, or - 'bar' anywhere", whereas flex interprets it as "match either 'foo' - or 'bar' if they come at the beginning of a line". The latter is - in agreement with the current POSIX draft. - - - To refer to yytext outside of the scanner source file, the correct - definition with flex is "extern char *yytext" rather than "extern - char yytext[]". This is contrary to the current POSIX draft but a - point on which flex will not be changing, as the array representa- - tion entails a serious performance penalty. It is hoped that the - POSIX draft will be emended to support the flex variety of declara- - tion (as this is a fairly painless change to require of lex users). - - - yyin is initialized by lex to be stdin; flex, on the other hand, - initializes yyin to NULL and then assigns it to stdin the first - time the scanner is called, providing yyin has not already been - assigned to a non-NULL value. The difference is subtle, but the - net effect is that with flex scanners, yyin does not have a valid - value until the scanner has been called. - - - The special table-size declarations such as %a supported by lex are - not required by flex scanners; flex ignores them. - - - The name FLEX_SCANNER is #define'd so scanners may be written for - use with either flex or lex. - - The following flex features are not included in lex or the POSIX draft - standard: - - yyterminate() - <> - YY_DECL - #line directives - %{}'s around actions - yyrestart() - comments beginning with '#' (deprecated) - multiple actions on a line - - This last feature refers to the fact that with flex you can put multiple - actions on the same line, separated with semi-colons, while with lex, - the following - - foo handle_foo(); ++num_foos_seen; - - Version 2.3 29 - - FLEX(1) 26 May 1990 - - is (rather surprisingly) truncated to - - foo handle_foo(); - - flex does not truncate the action. Actions that are not enclosed in - braces are simply terminated at the end of the line. - - DIAGNOSTICS - reject_used_but_not_detected undefined or yymore_used_but_not_detected - undefined - These errors can occur at compile time. They indicate that - the scanner uses REJECT or yymore() but that flex failed to notice the - fact, meaning that flex scanned the first two sections looking for - occurrences of these actions and failed to find any, but somehow you - snuck some in (via a #include file, for example). Make an explicit - reference to the action in your flex input file. (Note that previously - flex supported a %used/%unused mechanism for dealing with this problem; - this feature is still supported but now deprecated, and will go away - soon unless the author hears from people who can argue compellingly that - they need it.) - - flex scanner jammed - a scanner compiled with -s has encountered an - input string which wasn't matched by any of its rules. - - flex input buffer overflowed - a scanner rule matched a string long - enough to overflow the scanner's internal input buffer (16K bytes by - default - controlled by YY_BUF_SIZE in "flex.skel". Note that to rede- - fine this macro, you must first #undefine it). - - scanner requires -8 flag - Your scanner specification includes recogniz- - ing 8-bit characters and you did not specify the -8 flag (and your site - has not installed flex with -8 as the default). - - fatal flex scanner internal error--end of buffer missed - This can occur - in an scanner which is reentered after a long-jump has jumped out (or - over) the scanner's activation frame. Before reentering the scanner, - use: - - yyrestart( yyin ); - - too many %t classes! - You managed to put every single character into - its own %t class. flex requires that at least one of the classes share - characters. - - DEFICIENCIES / BUGS - See flex(1). - - SEE ALSO - - flex(1), lex(1), yacc(1), sed(1), awk(1). - - M. E. Lesk and E. Schmidt, LEX - Lexical Analyzer Generator - - 30 Version 2.3 - - 26 May 1990 FLEX(1) - - AUTHOR - Vern Paxson, with the help of many ideas and much inspiration from Van - Jacobson. Original version by Jef Poskanzer. The fast table represen- - tation is a partial implementation of a design done by Van Jacobson. - The implementation was done by Kevin Gong and Vern Paxson. - - Thanks to the many flex beta-testers, feedbackers, and contributors, - especially Casey Leedom, benson@odi.com, Keith Bostic, Frederic Brehm, - Nick Christopher, Jason Coughlin, Scott David Daniels, Leo Eskin, Chris - Faylor, Eric Goldman, Eric Hughes, Jeffrey R. Jones, Kevin B. Kenny, - Ronald Lamprecht, Greg Lee, Craig Leres, Mohamed el Lozy, Jim Meyering, - Marc Nozell, Esmond Pitt, Jef Poskanzer, Jim Roskind, Dave Tallman, - Frank Whaley, Ken Yap, and those whose names have slipped my marginal - mail-archiving skills but whose contributions are appreciated all the - same. - - Thanks to Keith Bostic, John Gilmore, Craig Leres, Bob Mulcahy, Rich - Salz, and Richard Stallman for help with various distribution headaches. - - Thanks to Esmond Pitt and Earle Horton for 8-bit character support; to - Benson Margulies and Fred Burke for C++ support; to Ove Ewerlid for the - basics of support for NUL's; and to Eric Hughes for the basics of sup- - port for multiple buffers. - - Work is being done on extending flex to generate scanners in which the - state machine is directly represented in C code rather than tables. - These scanners may well be substantially faster than those generated - using -f or -F. If you are working in this area and are interested in - comparing notes and seeing whether redundant work can be avoided, con- - tact Ove Ewerlid (ewerlid@mizar.DoCS.UU.SE). - - This work was primarily done when I was at the Real Time Systems Group - at the Lawrence Berkeley Laboratory in Berkeley, CA. Many thanks to all - there for the support I received. - - Send comments to: - - Vern Paxson - Computer Science Department - 4126 Upson Hall - Cornell University - Ithaca, NY 14853-7501 - - vern@cs.cornell.edu - decvax!cornell!vern - - Version 2.3 31 - -99 diff --git a/src/libCom/flex/Makefile b/src/libCom/flex/Makefile deleted file mode 100644 index 20cce5d30..000000000 --- a/src/libCom/flex/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/flex - -parse_YACCOPT = -l -d - -SKELETON_FILE = flex.skel.static - -parse_CPPFLAGS = -DDEFAULT_SKELETON_FILE=$(SKELETON_FILE) - -INC += flex.skel.static - -# flex.c is included in parse.c -e_flex_SRCS += ccl.c -e_flex_SRCS += dfa.c -e_flex_SRCS += ecs.c -e_flex_SRCS += gen.c -e_flex_SRCS += misc.c -e_flex_SRCS += nfa.c -e_flex_SRCS += sym.c -e_flex_SRCS += tblcmp.c -e_flex_SRCS += parse.c -e_flex_OBJS += epicsTempFile$(OBJ) - -PROD_HOST += e_flex - -CLEANS += parse.c parse.h diff --git a/src/libCom/flex/README b/src/libCom/flex/README deleted file mode 100644 index 210290892..000000000 --- a/src/libCom/flex/README +++ /dev/null @@ -1,76 +0,0 @@ -This is release 2.3 of flex - a full release. - -The flex distribution consists of the following files: - - README This message - - Makefile - flexdef.h - parse.y - scan.l - ccl.c - dfa.c - ecs.c flex sources - gen.c - main.c - misc.c - nfa.c - sym.c - tblcmp.c - yylex.c - - libmain.c flex library (-lfl) source - - initscan.c pre-flex'd version of scan.l - - flex.skel skeleton for generated scanners - - flexdoc.1 full user documentation - flex.1 reference documentation - - Changes Differences between this release and the previous one - - COPYING flex's copyright - - MISC/ a directory containing miscellaneous porting-related - notes (for Atari, MS-DOS, Turbo-C, and VMS) - - -Decide where you want to keep flex.skel (suggestion: /usr/local/lib), -but don't move it there yet. Edit "Makefile" and change the definition -of SKELETON_FILE to reflect the full pathname of flex.skel. - -Read the "Porting considerations" note in the Makefile and make -the necessary changes. - -To make flex for the first time, use: - - make first_flex - -which uses the pre-generated copy of the flex scanner (the scanner -itself is written using flex). - -Assuming it builds successfully, you can test it using - - make test - -The "diff" should not show any differences. - -If you're feeling adventurous, issue "make bigtest" and be prepared -to wait a while. - -Install flex using: - - make install - - -Please send problems and feedback to: - - vern@cs.cornell.edu - decvax!cornell!vern - - Vern Paxson - CS Department - 4126 Upson Hall - Cornell University - Ithaca, NY 14853-7501 diff --git a/src/libCom/flex/RULES b/src/libCom/flex/RULES deleted file mode 100644 index 65406f4c5..000000000 --- a/src/libCom/flex/RULES +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -# Ensure that the lexer is built before it is needed -parse.c: $(EPICS_BASE_HOST_BIN)/antelope$(HOSTEXE) diff --git a/src/libCom/flex/ccl.c b/src/libCom/flex/ccl.c deleted file mode 100644 index 36841d9b1..000000000 --- a/src/libCom/flex/ccl.c +++ /dev/null @@ -1,169 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* ccl - routines for character classes */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - -/* ccladd - add a single character to a ccl - * - * synopsis - * int cclp; - * int ch; - * ccladd( cclp, ch ); - */ - -void ccladd(int cclp, int ch) -{ - int ind, len, newpos, i; - - len = ccllen[cclp]; - ind = cclmap[cclp]; - - /* check to see if the character is already in the ccl */ - - for ( i = 0; i < len; ++i ) - if ( ccltbl[ind + i] == ch ) - return; - - newpos = ind + len; - - if ( newpos >= current_max_ccl_tbl_size ) - { - current_max_ccl_tbl_size += MAX_CCL_TBL_SIZE_INCREMENT; - - ++num_reallocs; - - ccltbl = reallocate_character_array( ccltbl, current_max_ccl_tbl_size ); - } - - ccllen[cclp] = len + 1; - ccltbl[newpos] = ch; - } - - -/* cclinit - make an empty ccl - * - * synopsis - * int cclinit(); - * new_ccl = cclinit(); - */ - -int cclinit(void) -{ - if ( ++lastccl >= current_maxccls ) - { - current_maxccls += MAX_CCLS_INCREMENT; - - ++num_reallocs; - - cclmap = reallocate_integer_array( cclmap, current_maxccls ); - ccllen = reallocate_integer_array( ccllen, current_maxccls ); - cclng = reallocate_integer_array( cclng, current_maxccls ); - } - - if ( lastccl == 1 ) - /* we're making the first ccl */ - cclmap[lastccl] = 0; - - else - /* the new pointer is just past the end of the last ccl. Since - * the cclmap points to the \first/ character of a ccl, adding the - * length of the ccl to the cclmap pointer will produce a cursor - * to the first free space - */ - cclmap[lastccl] = cclmap[lastccl - 1] + ccllen[lastccl - 1]; - - ccllen[lastccl] = 0; - cclng[lastccl] = 0; /* ccl's start out life un-negated */ - - return ( lastccl ); - } - - -/* cclnegate - negate a ccl - * - * synopsis - * int cclp; - * cclnegate( ccl ); - */ - -void cclnegate(int cclp) -{ - cclng[cclp] = 1; - } - - -/* list_character_set - list the members of a set of characters in CCL form - * - * synopsis - * int cset[CSIZE]; - * FILE *file; - * list_character_set( cset ); - * - * writes to the given file a character-class representation of those - * characters present in the given set. A character is present if it - * has a non-zero value in the set array. - */ - -void list_character_set(FILE *file, int cset[]) -{ - int i; - char *readable_form(); - - putc( '[', file ); - - for ( i = 0; i < csize; ++i ) - { - if ( cset[i] ) - { - int start_char = i; - - putc( ' ', file ); - - fputs( readable_form( i ), file ); - - while ( ++i < csize && cset[i] ) - ; - - if ( i - 1 > start_char ) - /* this was a run */ - fprintf( file, "-%s", readable_form( i - 1 ) ); - - putc( ' ', file ); - } - } - - putc( ']', file ); - } diff --git a/src/libCom/flex/dfa.c b/src/libCom/flex/dfa.c deleted file mode 100644 index 559a12fd1..000000000 --- a/src/libCom/flex/dfa.c +++ /dev/null @@ -1,1056 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dfa - DFA construction routines */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - - -/* declare functions that have forward references */ - -void dump_associated_rules (FILE*, int); -void dump_transitions (FILE*, int[]); -void sympartition (int[], int, int[], int[]); -int symfollowset (int[], int, int, int[]); - - -/* check_for_backtracking - check a DFA state for backtracking - * - * synopsis - * int ds, state[numecs]; - * check_for_backtracking( ds, state ); - * - * ds is the number of the state to check and state[] is its out-transitions, - * indexed by equivalence class, and state_rules[] is the set of rules - * associated with this state - */ - -void check_for_backtracking(int ds, int state[]) -{ - if ( (reject && ! dfaacc[ds].dfaacc_set) || ! dfaacc[ds].dfaacc_state ) - { /* state is non-accepting */ - ++num_backtracking; - - if ( backtrack_report ) - { - fprintf( backtrack_file, "State #%d is non-accepting -\n", ds ); - - /* identify the state */ - dump_associated_rules( backtrack_file, ds ); - - /* now identify it further using the out- and jam-transitions */ - dump_transitions( backtrack_file, state ); - - putc( '\n', backtrack_file ); - } - } - } - - -/* check_trailing_context - check to see if NFA state set constitutes - * "dangerous" trailing context - * - * synopsis - * int nfa_states[num_states+1], num_states; - * int accset[nacc+1], nacc; - * check_trailing_context( nfa_states, num_states, accset, nacc ); - * - * NOTES - * Trailing context is "dangerous" if both the head and the trailing - * part are of variable size \and/ there's a DFA state which contains - * both an accepting state for the head part of the rule and NFA states - * which occur after the beginning of the trailing context. - * When such a rule is matched, it's impossible to tell if having been - * in the DFA state indicates the beginning of the trailing context - * or further-along scanning of the pattern. In these cases, a warning - * message is issued. - * - * nfa_states[1 .. num_states] is the list of NFA states in the DFA. - * accset[1 .. nacc] is the list of accepting numbers for the DFA state. - */ - -void check_trailing_context(int *nfa_states, int num_states, int *accset, int nacc) -{ - int i, j; - - for ( i = 1; i <= num_states; ++i ) - { - int ns = nfa_states[i]; - int type = state_type[ns]; - int ar = assoc_rule[ns]; - - if ( type == STATE_NORMAL || rule_type[ar] != RULE_VARIABLE ) - { /* do nothing */ - } - - else if ( type == STATE_TRAILING_CONTEXT ) - { - /* potential trouble. Scan set of accepting numbers for - * the one marking the end of the "head". We assume that - * this looping will be fairly cheap since it's rare that - * an accepting number set is large. - */ - for ( j = 1; j <= nacc; ++j ) - if ( accset[j] & YY_TRAILING_HEAD_MASK ) - { - fprintf( stderr, - "%s: Dangerous trailing context in rule at line %d\n", - program_name, rule_linenum[ar] ); - return; - } - } - } - } - - -/* dump_associated_rules - list the rules associated with a DFA state - * - * synopisis - * int ds; - * FILE *file; - * dump_associated_rules( file, ds ); - * - * goes through the set of NFA states associated with the DFA and - * extracts the first MAX_ASSOC_RULES unique rules, sorts them, - * and writes a report to the given file - */ - -void dump_associated_rules(FILE *file, int ds) -{ - int i, j; - int num_associated_rules = 0; - int rule_set[MAX_ASSOC_RULES + 1]; - int *dset = dss[ds]; - int size = dfasiz[ds]; - - for ( i = 1; i <= size; ++i ) - { - int rule_num = rule_linenum[assoc_rule[dset[i]]]; - - for ( j = 1; j <= num_associated_rules; ++j ) - if ( rule_num == rule_set[j] ) - break; - - if ( j > num_associated_rules ) - { /* new rule */ - if ( num_associated_rules < MAX_ASSOC_RULES ) - rule_set[++num_associated_rules] = rule_num; - } - } - - bubble( rule_set, num_associated_rules ); - - fprintf( file, " associated rule line numbers:" ); - - for ( i = 1; i <= num_associated_rules; ++i ) - { - if ( i % 8 == 1 ) - putc( '\n', file ); - - fprintf( file, "\t%d", rule_set[i] ); - } - - putc( '\n', file ); - } - - -/* dump_transitions - list the transitions associated with a DFA state - * - * synopisis - * int state[numecs]; - * FILE *file; - * dump_transitions( file, state ); - * - * goes through the set of out-transitions and lists them in human-readable - * form (i.e., not as equivalence classes); also lists jam transitions - * (i.e., all those which are not out-transitions, plus EOF). The dump - * is done to the given file. - */ - -void dump_transitions(FILE *file, int state[]) -{ - int i, ec; - int out_char_set[CSIZE]; - - for ( i = 0; i < csize; ++i ) - { - ec = abs( ecgroup[i] ); - out_char_set[i] = state[ec]; - } - - fprintf( file, " out-transitions: " ); - - list_character_set( file, out_char_set ); - - /* now invert the members of the set to get the jam transitions */ - for ( i = 0; i < csize; ++i ) - out_char_set[i] = ! out_char_set[i]; - - fprintf( file, "\n jam-transitions: EOF " ); - - list_character_set( file, out_char_set ); - - putc( '\n', file ); - } - - -/* epsclosure - construct the epsilon closure of a set of ndfa states - * - * synopsis - * int t[current_max_dfa_size], numstates, accset[num_rules + 1], nacc; - * int hashval; - * int *epsclosure(); - * t = epsclosure( t, &numstates, accset, &nacc, &hashval ); - * - * NOTES - * the epsilon closure is the set of all states reachable by an arbitrary - * number of epsilon transitions which themselves do not have epsilon - * transitions going out, unioned with the set of states which have non-null - * accepting numbers. t is an array of size numstates of nfa state numbers. - * Upon return, t holds the epsilon closure and numstates is updated. accset - * holds a list of the accepting numbers, and the size of accset is given - * by nacc. t may be subjected to reallocation if it is not large enough - * to hold the epsilon closure. - * - * hashval is the hash value for the dfa corresponding to the state set - */ - -int *epsclosure(int *t, int *ns_addr, int accset[], int *nacc_addr, int *hv_addr) -{ - int stkpos, ns, tsp; - int numstates = *ns_addr, nacc, hashval, transsym, nfaccnum; - int stkend, nstate; - static int did_stk_init = false, *stk; - -#define MARK_STATE(state) \ - trans1[state] = trans1[state] - MARKER_DIFFERENCE; - -#define IS_MARKED(state) (trans1[state] < 0) - -#define UNMARK_STATE(state) \ - trans1[state] = trans1[state] + MARKER_DIFFERENCE; - -#define CHECK_ACCEPT(state) \ - { \ - nfaccnum = accptnum[state]; \ - if ( nfaccnum != NIL ) \ - accset[++nacc] = nfaccnum; \ - } - -#define DO_REALLOCATION \ - { \ - current_max_dfa_size += MAX_DFA_SIZE_INCREMENT; \ - ++num_reallocs; \ - t = reallocate_integer_array( t, current_max_dfa_size ); \ - stk = reallocate_integer_array( stk, current_max_dfa_size ); \ - } \ - -#define PUT_ON_STACK(state) \ - { \ - if ( ++stkend >= current_max_dfa_size ) \ - DO_REALLOCATION \ - stk[stkend] = state; \ - MARK_STATE(state) \ - } - -#define ADD_STATE(state) \ - { \ - if ( ++numstates >= current_max_dfa_size ) \ - DO_REALLOCATION \ - t[numstates] = state; \ - hashval = hashval + state; \ - } - -#define STACK_STATE(state) \ - { \ - PUT_ON_STACK(state) \ - CHECK_ACCEPT(state) \ - if ( nfaccnum != NIL || transchar[state] != SYM_EPSILON ) \ - ADD_STATE(state) \ - } - - if ( ! did_stk_init ) - { - stk = allocate_integer_array( current_max_dfa_size ); - did_stk_init = true; - } - - nacc = stkend = hashval = 0; - - for ( nstate = 1; nstate <= numstates; ++nstate ) - { - ns = t[nstate]; - - /* the state could be marked if we've already pushed it onto - * the stack - */ - if ( ! IS_MARKED(ns) ) - PUT_ON_STACK(ns) - - CHECK_ACCEPT(ns) - hashval = hashval + ns; - } - - for ( stkpos = 1; stkpos <= stkend; ++stkpos ) - { - ns = stk[stkpos]; - transsym = transchar[ns]; - - if ( transsym == SYM_EPSILON ) - { - tsp = trans1[ns] + MARKER_DIFFERENCE; - - if ( tsp != NO_TRANSITION ) - { - if ( ! IS_MARKED(tsp) ) - STACK_STATE(tsp) - - tsp = trans2[ns]; - - if ( tsp != NO_TRANSITION ) - if ( ! IS_MARKED(tsp) ) - STACK_STATE(tsp) - } - } - } - - /* clear out "visit" markers */ - - for ( stkpos = 1; stkpos <= stkend; ++stkpos ) - { - if ( IS_MARKED(stk[stkpos]) ) - { - UNMARK_STATE(stk[stkpos]) - } - else - flexfatal( "consistency check failed in epsclosure()" ); - } - - *ns_addr = numstates; - *hv_addr = hashval; - *nacc_addr = nacc; - - return ( t ); - } - - -/* increase_max_dfas - increase the maximum number of DFAs */ - -void increase_max_dfas(void) -{ - current_max_dfas += MAX_DFAS_INCREMENT; - - ++num_reallocs; - - base = reallocate_integer_array( base, current_max_dfas ); - def = reallocate_integer_array( def, current_max_dfas ); - dfasiz = reallocate_integer_array( dfasiz, current_max_dfas ); - accsiz = reallocate_integer_array( accsiz, current_max_dfas ); - dhash = reallocate_integer_array( dhash, current_max_dfas ); - dss = reallocate_int_ptr_array( dss, current_max_dfas ); - dfaacc = reallocate_dfaacc_union( dfaacc, current_max_dfas ); - - if ( nultrans ) - nultrans = reallocate_integer_array( nultrans, current_max_dfas ); - } - - -/* ntod - convert an ndfa to a dfa - * - * synopsis - * ntod(); - * - * creates the dfa corresponding to the ndfa we've constructed. the - * dfa starts out in state #1. - */ - -void ntod(void) -{ - int *accset, ds, nacc, newds; - int sym, hashval, numstates, dsize; - int num_full_table_rows = 0; /* used only for -f */ - int *nset, *dset; - int targptr, totaltrans, i, comstate, comfreq, targ; - int *epsclosure(int *t, int *ns_addr, int *accset, int *nacc_addr, int *hv_addr); - int snstods(int *sns, int numstates, int *accset, int nacc, int hashval, int *newds_addr); - int symlist[CSIZE + 1]; - int num_start_states; - int todo_head, todo_next; - - /* note that the following are indexed by *equivalence classes* - * and not by characters. Since equivalence classes are indexed - * beginning with 1, even if the scanner accepts NUL's, this - * means that (since every character is potentially in its own - * equivalence class) these arrays must have room for indices - * from 1 to CSIZE, so their size must be CSIZE + 1. - */ - int duplist[CSIZE + 1], state[CSIZE + 1]; - int targfreq[CSIZE + 1], targstate[CSIZE + 1]; - - /* this is so find_table_space(...) will know where to start looking in - * chk/nxt for unused records for space to put in the state - */ - if ( fullspd ) - firstfree = 0; - - accset = allocate_integer_array( num_rules + 1 ); - nset = allocate_integer_array( current_max_dfa_size ); - - /* the "todo" queue is represented by the head, which is the DFA - * state currently being processed, and the "next", which is the - * next DFA state number available (not in use). We depend on the - * fact that snstods() returns DFA's \in increasing order/, and thus - * need only know the bounds of the dfas to be processed. - */ - todo_head = todo_next = 0; - - for ( i = 0; i <= csize; ++i ) - { - duplist[i] = NIL; - symlist[i] = false; - } - - for ( i = 0; i <= num_rules; ++i ) - accset[i] = NIL; - - if ( trace ) - { - dumpnfa( scset[1] ); - fputs( "\n\nDFA Dump:\n\n", stderr ); - } - - inittbl(); - - /* check to see whether we should build a separate table for transitions - * on NUL characters. We don't do this for full-speed (-F) scanners, - * since for them we don't have a simple state number lying around with - * which to index the table. We also don't bother doing it for scanners - * unless (1) NUL is in its own equivalence class (indicated by a - * positive value of ecgroup[NUL]), (2) NUL's equilvalence class is - * the last equivalence class, and (3) the number of equivalence classes - * is the same as the number of characters. This latter case comes about - * when useecs is false or when its true but every character still - * manages to land in its own class (unlikely, but it's cheap to check - * for). If all these things are true then the character code needed - * to represent NUL's equivalence class for indexing the tables is - * going to take one more bit than the number of characters, and therefore - * we won't be assured of being able to fit it into a YY_CHAR variable. - * This rules out storing the transitions in a compressed table, since - * the code for interpreting them uses a YY_CHAR variable (perhaps it - * should just use an integer, though; this is worth pondering ... ###). - * - * Finally, for full tables, we want the number of entries in the - * table to be a power of two so the array references go fast (it - * will just take a shift to compute the major index). If encoding - * NUL's transitions in the table will spoil this, we give it its - * own table (note that this will be the case if we're not using - * equivalence classes). - */ - - /* note that the test for ecgroup[0] == numecs below accomplishes - * both (1) and (2) above - */ - if ( ! fullspd && ecgroup[0] == numecs ) - { /* NUL is alone in its equivalence class, which is the last one */ - int use_NUL_table = (numecs == csize); - - if ( fulltbl && ! use_NUL_table ) - { /* we still may want to use the table if numecs is a power of 2 */ - int power_of_two; - - for ( power_of_two = 1; power_of_two <= csize; power_of_two *= 2 ) - if ( numecs == power_of_two ) - { - use_NUL_table = true; - break; - } - } - - if ( use_NUL_table ) - nultrans = allocate_integer_array( current_max_dfas ); - /* from now on, nultrans != nil indicates that we're - * saving null transitions for later, separate encoding - */ - } - - - if ( fullspd ) - { - for ( i = 0; i <= numecs; ++i ) - state[i] = 0; - place_state( state, 0, 0 ); - } - - else if ( fulltbl ) - { - if ( nultrans ) - /* we won't be including NUL's transitions in the table, - * so build it for entries from 0 .. numecs - 1 - */ - num_full_table_rows = numecs; - - else - /* take into account the fact that we'll be including - * the NUL entries in the transition table. Build it - * from 0 .. numecs. - */ - num_full_table_rows = numecs + 1; - - /* declare it "short" because it's a real long-shot that that - * won't be large enough. - */ - printf( "static short int yy_nxt[][%d] =\n {\n", - /* '}' so vi doesn't get too confused */ - num_full_table_rows ); - - /* generate 0 entries for state #0 */ - for ( i = 0; i < num_full_table_rows; ++i ) - mk2data( 0 ); - - /* force ',' and dataflush() next call to mk2data */ - datapos = NUMDATAITEMS; - - /* force extra blank line next dataflush() */ - dataline = NUMDATALINES; - } - - /* create the first states */ - - num_start_states = lastsc * 2; - - for ( i = 1; i <= num_start_states; ++i ) - { - numstates = 1; - - /* for each start condition, make one state for the case when - * we're at the beginning of the line (the '%' operator) and - * one for the case when we're not - */ - if ( i % 2 == 1 ) - nset[numstates] = scset[(i / 2) + 1]; - else - nset[numstates] = mkbranch( scbol[i / 2], scset[i / 2] ); - - nset = epsclosure( nset, &numstates, accset, &nacc, &hashval ); - - if ( snstods( nset, numstates, accset, nacc, hashval, &ds ) ) - { - numas += nacc; - totnst += numstates; - ++todo_next; - - if ( variable_trailing_context_rules && nacc > 0 ) - check_trailing_context( nset, numstates, accset, nacc ); - } - } - - if ( ! fullspd ) - { - if ( ! snstods( nset, 0, accset, 0, 0, &end_of_buffer_state ) ) - flexfatal( "could not create unique end-of-buffer state" ); - - ++numas; - ++num_start_states; - ++todo_next; - } - - while ( todo_head < todo_next ) - { - targptr = 0; - totaltrans = 0; - - for ( i = 1; i <= numecs; ++i ) - state[i] = 0; - - ds = ++todo_head; - - dset = dss[ds]; - dsize = dfasiz[ds]; - - if ( trace ) - fprintf( stderr, "state # %d:\n", ds ); - - sympartition( dset, dsize, symlist, duplist ); - - for ( sym = 1; sym <= numecs; ++sym ) - { - if ( symlist[sym] ) - { - symlist[sym] = 0; - - if ( duplist[sym] == NIL ) - { /* symbol has unique out-transitions */ - numstates = symfollowset( dset, dsize, sym, nset ); - nset = epsclosure( nset, &numstates, accset, - &nacc, &hashval ); - - if ( snstods( nset, numstates, accset, - nacc, hashval, &newds ) ) - { - totnst = totnst + numstates; - ++todo_next; - numas += nacc; - - if ( variable_trailing_context_rules && nacc > 0 ) - check_trailing_context( nset, numstates, - accset, nacc ); - } - - state[sym] = newds; - - if ( trace ) - fprintf( stderr, "\t%d\t%d\n", sym, newds ); - - targfreq[++targptr] = 1; - targstate[targptr] = newds; - ++numuniq; - } - - else - { - /* sym's equivalence class has the same transitions - * as duplist(sym)'s equivalence class - */ - targ = state[duplist[sym]]; - state[sym] = targ; - - if ( trace ) - fprintf( stderr, "\t%d\t%d\n", sym, targ ); - - /* update frequency count for destination state */ - - i = 0; - while ( targstate[++i] != targ ) - ; - - ++targfreq[i]; - ++numdup; - } - - ++totaltrans; - duplist[sym] = NIL; - } - } - - numsnpairs = numsnpairs + totaltrans; - - if ( caseins && ! useecs ) - { - int j; - - for ( i = 'A', j = 'a'; i <= 'Z'; ++i, ++j ) - state[i] = state[j]; - } - - if ( ds > num_start_states ) - check_for_backtracking( ds, state ); - - if ( nultrans ) - { - nultrans[ds] = state[NUL_ec]; - state[NUL_ec] = 0; /* remove transition */ - } - - if ( fulltbl ) - { - /* supply array's 0-element */ - if ( ds == end_of_buffer_state ) - mk2data( -end_of_buffer_state ); - else - mk2data( end_of_buffer_state ); - - for ( i = 1; i < num_full_table_rows; ++i ) - /* jams are marked by negative of state number */ - mk2data( state[i] ? state[i] : -ds ); - - /* force ',' and dataflush() next call to mk2data */ - datapos = NUMDATAITEMS; - - /* force extra blank line next dataflush() */ - dataline = NUMDATALINES; - } - - else if ( fullspd ) - place_state( state, ds, totaltrans ); - - else if ( ds == end_of_buffer_state ) - /* special case this state to make sure it does what it's - * supposed to, i.e., jam on end-of-buffer - */ - stack1( ds, 0, 0, JAMSTATE ); - - else /* normal, compressed state */ - { - /* determine which destination state is the most common, and - * how many transitions to it there are - */ - - comfreq = 0; - comstate = 0; - - for ( i = 1; i <= targptr; ++i ) - if ( targfreq[i] > comfreq ) - { - comfreq = targfreq[i]; - comstate = targstate[i]; - } - - bldtbl( state, ds, totaltrans, comstate, comfreq ); - } - } - - if ( fulltbl ) - dataend(); - - else if ( ! fullspd ) - { - cmptmps(); /* create compressed template entries */ - - /* create tables for all the states with only one out-transition */ - while ( onesp > 0 ) - { - mk1tbl( onestate[onesp], onesym[onesp], onenext[onesp], - onedef[onesp] ); - --onesp; - } - - mkdeftbl(); - } - } - - -/* snstods - converts a set of ndfa states into a dfa state - * - * synopsis - * int sns[numstates], numstates, newds, accset[num_rules + 1], nacc, hashval; - * int snstods(); - * is_new_state = snstods( sns, numstates, accset, nacc, hashval, &newds ); - * - * on return, the dfa state number is in newds. - */ - -int snstods(int sns[], int numstates, int accset[], int nacc, int hashval, int *newds_addr) -{ - int didsort = 0; - int i, j; - int newds, *oldsns; - - for ( i = 1; i <= lastdfa; ++i ) - if ( hashval == dhash[i] ) - { - if ( numstates == dfasiz[i] ) - { - oldsns = dss[i]; - - if ( ! didsort ) - { - /* we sort the states in sns so we can compare it to - * oldsns quickly. we use bubble because there probably - * aren't very many states - */ - bubble( sns, numstates ); - didsort = 1; - } - - for ( j = 1; j <= numstates; ++j ) - if ( sns[j] != oldsns[j] ) - break; - - if ( j > numstates ) - { - ++dfaeql; - *newds_addr = i; - return ( 0 ); - } - - ++hshcol; - } - - else - ++hshsave; - } - - /* make a new dfa */ - - if ( ++lastdfa >= current_max_dfas ) - increase_max_dfas(); - - newds = lastdfa; - - dss[newds] = (int *) malloc( (unsigned) ((numstates + 1) * sizeof( int )) ); - - if ( ! dss[newds] ) - flexfatal( "dynamic memory failure in snstods()" ); - - /* if we haven't already sorted the states in sns, we do so now, so that - * future comparisons with it can be made quickly - */ - - if ( ! didsort ) - bubble( sns, numstates ); - - for ( i = 1; i <= numstates; ++i ) - dss[newds][i] = sns[i]; - - dfasiz[newds] = numstates; - dhash[newds] = hashval; - - if ( nacc == 0 ) - { - if ( reject ) - dfaacc[newds].dfaacc_set = (int *) 0; - else - dfaacc[newds].dfaacc_state = 0; - - accsiz[newds] = 0; - } - - else if ( reject ) - { - /* we sort the accepting set in increasing order so the disambiguating - * rule that the first rule listed is considered match in the event of - * ties will work. We use a bubble sort since the list is probably - * quite small. - */ - - bubble( accset, nacc ); - - dfaacc[newds].dfaacc_set = - (int *) malloc( (unsigned) ((nacc + 1) * sizeof( int )) ); - - if ( ! dfaacc[newds].dfaacc_set ) - flexfatal( "dynamic memory failure in snstods()" ); - - /* save the accepting set for later */ - for ( i = 1; i <= nacc; ++i ) - dfaacc[newds].dfaacc_set[i] = accset[i]; - - accsiz[newds] = nacc; - } - - else - { /* find lowest numbered rule so the disambiguating rule will work */ - j = num_rules + 1; - - for ( i = 1; i <= nacc; ++i ) - if ( accset[i] < j ) - j = accset[i]; - - dfaacc[newds].dfaacc_state = j; - } - - *newds_addr = newds; - - return ( 1 ); - } - - -/* symfollowset - follow the symbol transitions one step - * - * synopsis - * int ds[current_max_dfa_size], dsize, transsym; - * int nset[current_max_dfa_size], numstates; - * numstates = symfollowset( ds, dsize, transsym, nset ); - */ - -int symfollowset(int ds[], int dsize, int transsym, int nset[]) -{ - int ns, tsp, sym, i, j, lenccl, ch, numstates; - int ccllist; - - numstates = 0; - - for ( i = 1; i <= dsize; ++i ) - { /* for each nfa state ns in the state set of ds */ - ns = ds[i]; - sym = transchar[ns]; - tsp = trans1[ns]; - - if ( sym < 0 ) - { /* it's a character class */ - sym = -sym; - ccllist = cclmap[sym]; - lenccl = ccllen[sym]; - - if ( cclng[sym] ) - { - for ( j = 0; j < lenccl; ++j ) - { /* loop through negated character class */ - ch = ccltbl[ccllist + j]; - - if ( ch == 0 ) - ch = NUL_ec; - - if ( ch > transsym ) - break; /* transsym isn't in negated ccl */ - - else if ( ch == transsym ) - /* next 2 */ goto bottom; - } - - /* didn't find transsym in ccl */ - nset[++numstates] = tsp; - } - - else - for ( j = 0; j < lenccl; ++j ) - { - ch = ccltbl[ccllist + j]; - - if ( ch == 0 ) - ch = NUL_ec; - - if ( ch > transsym ) - break; - - else if ( ch == transsym ) - { - nset[++numstates] = tsp; - break; - } - } - } - - else if ( sym >= 'A' && sym <= 'Z' && caseins ) - flexfatal( "consistency check failed in symfollowset" ); - - else if ( sym == SYM_EPSILON ) - { /* do nothing */ - } - - else if ( abs( ecgroup[sym] ) == transsym ) - nset[++numstates] = tsp; - -bottom: - ; - } - - return ( numstates ); - } - - -/* sympartition - partition characters with same out-transitions - * - * synopsis - * integer ds[current_max_dfa_size], numstates, duplist[numecs]; - * symlist[numecs]; - * sympartition( ds, numstates, symlist, duplist ); - */ - -void sympartition(int ds[], int numstates, int symlist[], int duplist[]) -{ - int tch, i, j, k, ns, dupfwd[CSIZE + 1], lenccl, cclp, ich; - - /* partitioning is done by creating equivalence classes for those - * characters which have out-transitions from the given state. Thus - * we are really creating equivalence classes of equivalence classes. - */ - - for ( i = 1; i <= numecs; ++i ) - { /* initialize equivalence class list */ - duplist[i] = i - 1; - dupfwd[i] = i + 1; - } - - duplist[1] = NIL; - dupfwd[numecs] = NIL; - - for ( i = 1; i <= numstates; ++i ) - { - ns = ds[i]; - tch = transchar[ns]; - - if ( tch != SYM_EPSILON ) - { - if ( tch < -lastccl || tch > csize ) - { - if ( tch > csize && tch <= CSIZE ) - flexerror( "scanner requires -8 flag" ); - - else - flexfatal( - "bad transition character detected in sympartition()" ); - } - - if ( tch >= 0 ) - { /* character transition */ - /* abs() needed for fake %t ec's */ - int ec = abs( ecgroup[tch] ); - - mkechar( ec, dupfwd, duplist ); - symlist[ec] = 1; - } - - else - { /* character class */ - tch = -tch; - - lenccl = ccllen[tch]; - cclp = cclmap[tch]; - mkeccl( ccltbl + cclp, lenccl, dupfwd, duplist, numecs, - NUL_ec ); - - if ( cclng[tch] ) - { - j = 0; - - for ( k = 0; k < lenccl; ++k ) - { - ich = ccltbl[cclp + k]; - - if ( ich == 0 ) - ich = NUL_ec; - - for ( ++j; j < ich; ++j ) - symlist[j] = 1; - } - - for ( ++j; j <= numecs; ++j ) - symlist[j] = 1; - } - - else - for ( k = 0; k < lenccl; ++k ) - { - ich = ccltbl[cclp + k]; - - if ( ich == 0 ) - ich = NUL_ec; - - symlist[ich] = 1; - } - } - } - } - } diff --git a/src/libCom/flex/ecs.c b/src/libCom/flex/ecs.c deleted file mode 100644 index 416ea601a..000000000 --- a/src/libCom/flex/ecs.c +++ /dev/null @@ -1,342 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* ecs - equivalence class routines */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - -/* ccl2ecl - convert character classes to set of equivalence classes - * - * synopsis - * ccl2ecl(); - */ - -void ccl2ecl(void) -{ - int i, ich, newlen, cclp, ccls, cclmec; - - for ( i = 1; i <= lastccl; ++i ) - { - /* we loop through each character class, and for each character - * in the class, add the character's equivalence class to the - * new "character" class we are creating. Thus when we are all - * done, character classes will really consist of collections - * of equivalence classes - */ - - newlen = 0; - cclp = cclmap[i]; - - for ( ccls = 0; ccls < ccllen[i]; ++ccls ) - { - ich = ccltbl[cclp + ccls]; - cclmec = ecgroup[ich]; - - if ( xlation && cclmec < 0 ) - { - /* special hack--if we're doing %t tables then it's - * possible that no representative of this character's - * equivalence class is in the ccl. So waiting till - * we see the representative would be disastrous. Instead, - * we add this character's equivalence class anyway, if it's - * not already present. - */ - int j; - - /* this loop makes this whole process n^2; but we don't - * really care about %t performance anyway - */ - for ( j = 0; j < newlen; ++j ) - if ( ccltbl[cclp + j] == -cclmec ) - break; - - if ( j >= newlen ) - { /* no representative yet, add this one in */ - ccltbl[cclp + newlen] = -cclmec; - ++newlen; - } - } - - else if ( cclmec > 0 ) - { - ccltbl[cclp + newlen] = cclmec; - ++newlen; - } - } - - ccllen[i] = newlen; - } - } - - -/* cre8ecs - associate equivalence class numbers with class members - * - * synopsis - * int cre8ecs(); - * number of classes = cre8ecs( fwd, bck, num ); - * - * fwd is the forward linked-list of equivalence class members. bck - * is the backward linked-list, and num is the number of class members. - * - * Returned is the number of classes. - */ - -int cre8ecs(int fwd[], int bck[], int num) -{ - int i, j, numcl; - - numcl = 0; - - /* create equivalence class numbers. From now on, abs( bck(x) ) - * is the equivalence class number for object x. If bck(x) - * is positive, then x is the representative of its equivalence - * class. - */ - for ( i = 1; i <= num; ++i ) - if ( bck[i] == NIL ) - { - bck[i] = ++numcl; - for ( j = fwd[i]; j != NIL; j = fwd[j] ) - bck[j] = -numcl; - } - - return ( numcl ); - } - - -/* ecs_from_xlation - associate equivalence class numbers using %t table - * - * synopsis - * numecs = ecs_from_xlation( ecmap ); - * - * Upon return, ecmap will map each character code to its equivalence - * class. The mapping will be positive if the character is the representative - * of its class, negative otherwise. - * - * Returns the number of equivalence classes used. - */ - -int ecs_from_xlation(int ecmap[]) -{ - int i; - int nul_is_alone = false; - int did_default_xlation_class = false; - - if ( xlation[0] != 0 ) - { - /* if NUL shares its translation with other characters, choose one - * of the other characters as the representative for the equivalence - * class. This allows a cheap test later to see whether we can - * do away with NUL's equivalence class. - */ - for ( i = 1; i < csize; ++i ) - if ( xlation[i] == -xlation[0] ) - { - xlation[i] = xlation[0]; - ecmap[0] = -xlation[0]; - break; - } - - if ( i >= csize ) - /* didn't find a companion character--remember this fact */ - nul_is_alone = true; - } - - for ( i = 1; i < csize; ++i ) - if ( xlation[i] == 0 ) - { - if ( did_default_xlation_class ) - ecmap[i] = -num_xlations; - - else - { - /* make an equivalence class for those characters not - * specified in the %t table - */ - ++num_xlations; - ecmap[i] = num_xlations; - did_default_xlation_class = true; - } - } - - else - ecmap[i] = xlation[i]; - - if ( nul_is_alone ) - /* force NUL's equivalence class to be the last one */ - { - ++num_xlations; - ecmap[0] = num_xlations; - - /* there's actually a bug here: if someone is fanatic enough to - * put every character in its own translation class, then right - * now we just promoted NUL's equivalence class to be csize + 1; - * we can handle NUL's class number being == csize (by instead - * putting it in its own table), but we can't handle some *other* - * character having to be put in its own table, too. So in - * this case we bail out. - */ - if ( num_xlations > csize ) - flexfatal( "too many %t classes!" ); - } - - return num_xlations; - } - - -/* mkeccl - update equivalence classes based on character class xtions - * - * synopsis - * Char ccls[]; - * int lenccl, fwd[llsiz], bck[llsiz], llsiz, NUL_mapping; - * mkeccl( ccls, lenccl, fwd, bck, llsiz, NUL_mapping ); - * - * where ccls contains the elements of the character class, lenccl is the - * number of elements in the ccl, fwd is the forward link-list of equivalent - * characters, bck is the backward link-list, and llsiz size of the link-list - * - * NUL_mapping is the value which NUL (0) should be mapped to. - */ - -void mkeccl(unsigned char ccls[], int lenccl, int fwd[], int bck[], int llsiz, int NUL_mapping) -{ - int cclp, oldec, newec; - int cclm, i, j; - static unsigned char cclflags[CSIZE]; /* initialized to all '\0' */ - - /* note that it doesn't matter whether or not the character class is - * negated. The same results will be obtained in either case. - */ - - cclp = 0; - - while ( cclp < lenccl ) - { - cclm = ccls[cclp]; - - if ( NUL_mapping && cclm == 0 ) - cclm = NUL_mapping; - - oldec = bck[cclm]; - newec = cclm; - - j = cclp + 1; - - for ( i = fwd[cclm]; i != NIL && i <= llsiz; i = fwd[i] ) - { /* look for the symbol in the character class */ - for ( ; j < lenccl; ++j ) - { - int ccl_char; - - if ( NUL_mapping && ccls[j] == 0 ) - ccl_char = NUL_mapping; - else - ccl_char = ccls[j]; - - if ( ccl_char > i ) - break; - - if ( ccl_char == i && ! cclflags[j] ) - { - /* we found an old companion of cclm in the ccl. - * link it into the new equivalence class and flag it as - * having been processed - */ - - bck[i] = newec; - fwd[newec] = i; - newec = i; - cclflags[j] = 1; /* set flag so we don't reprocess */ - - /* get next equivalence class member */ - /* continue 2 */ - goto next_pt; - } - } - - /* symbol isn't in character class. Put it in the old equivalence - * class - */ - - bck[i] = oldec; - - if ( oldec != NIL ) - fwd[oldec] = i; - - oldec = i; -next_pt: - ; - } - - if ( bck[cclm] != NIL || oldec != bck[cclm] ) - { - bck[cclm] = NIL; - fwd[oldec] = NIL; - } - - fwd[newec] = NIL; - - /* find next ccl member to process */ - - for ( ++cclp; cclflags[cclp] && cclp < lenccl; ++cclp ) - { - /* reset "doesn't need processing" flag */ - cclflags[cclp] = 0; - } - } - } - - -/* mkechar - create equivalence class for single character - * - * synopsis - * int tch, fwd[], bck[]; - * mkechar( tch, fwd, bck ); - */ - -void mkechar(int tch, int fwd[], int bck[]) -{ - /* if until now the character has been a proper subset of - * an equivalence class, break it away to create a new ec - */ - - if ( fwd[tch] != NIL ) - bck[fwd[tch]] = bck[tch]; - - if ( bck[tch] != NIL ) - fwd[bck[tch]] = fwd[tch]; - - fwd[tch] = NIL; - bck[tch] = NIL; - } diff --git a/src/libCom/flex/flex.c b/src/libCom/flex/flex.c deleted file mode 100644 index 196f4e4cc..000000000 --- a/src/libCom/flex/flex.c +++ /dev/null @@ -1,748 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* flex - tool to generate fast lexical analyzers */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#define ENQUOTE(path) #path - -#ifndef lint -char copyright[] = -"@(#) Copyright (c) 1990 The Regents of the University of California.\n\ - All rights reserved.\n"; -#endif /* not lint */ - - -#define epicsExportSharedSymbols -#include "epicsTempFile.h" -#undef epicsExportSharedSymbols - -static char flex_version[] = "2.3"; - - -/* declare functions that have forward references */ - -void flexinit (int, char**); -void readin (void); -void set_up_initial_allocations (void); - - -/* these globals are all defined and commented in flexdef.h */ -int printstats, syntaxerror, eofseen, ddebug, trace, spprdflt; -int interactive, caseins, useecs, fulltbl, usemecs; -int fullspd, gen_line_dirs, performance_report, backtrack_report, csize; -int yymore_used, reject, real_reject, continued_action; -int yymore_really_used, reject_really_used; -int datapos, dataline, linenum; -FILE *skelfile = NULL; -char *infilename = NULL; -int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; -int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; -int current_mns, num_rules, current_max_rules, lastnfa; -int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; -int *accptnum, *assoc_rule, *state_type, *rule_type, *rule_linenum; -int current_state_type; -int variable_trailing_context_rules; -int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP]; -int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE]; -int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, tecfwd[CSIZE + 1]; -int tecbck[CSIZE + 1]; -int *xlation = (int *) 0; -int num_xlations; -int lastsc, current_max_scs, *scset, *scbol, *scxclu, *sceof, *actvsc; -char **scname; -int current_max_dfa_size, current_max_xpairs; -int current_max_template_xpairs, current_max_dfas; -int lastdfa, *nxt, *chk, *tnxt; -int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz; -union dfaacc_union *dfaacc; -int *accsiz, *dhash, numas; -int numsnpairs, jambase, jamstate; -int lastccl, current_maxccls, *cclmap, *ccllen, *cclng, cclreuse; -int current_max_ccl_tbl_size; -Char *ccltbl; -char *starttime, *endtime, nmstr[MAXLINE]; -int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; -int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; -int num_backtracking, bol_needed; -FILE *temp_action_file; -FILE *backtrack_file; -int end_of_buffer_state; -char action_file_name[256>L_tmpnam?256:L_tmpnam]; -char **input_files; -int num_input_files; -char *program_name; - -#ifndef SHORT_FILE_NAMES -static char *outfile = "lex.yy.c"; -#else -static char *outfile = "lexyy.c"; -#endif -static int outfile_created = 0; -static int use_stdout; -static char *skelname = NULL; - - -int main(int argc, char *argv[]) -{ - flexinit( argc, argv ); - - readin(); - - if ( syntaxerror ) - flexend( 1 ); - - if ( yymore_really_used == REALLY_USED ) - yymore_used = true; - else if ( yymore_really_used == REALLY_NOT_USED ) - yymore_used = false; - - if ( reject_really_used == REALLY_USED ) - reject = true; - else if ( reject_really_used == REALLY_NOT_USED ) - reject = false; - - if ( performance_report ) - { - if ( interactive ) - fprintf( stderr, - "-I (interactive) entails a minor performance penalty\n" ); - - if ( yymore_used ) - fprintf( stderr, "yymore() entails a minor performance penalty\n" ); - - if ( reject ) - fprintf( stderr, "REJECT entails a large performance penalty\n" ); - - if ( variable_trailing_context_rules ) - fprintf( stderr, -"Variable trailing context rules entail a large performance penalty\n" ); - } - - if ( reject ) - real_reject = true; - - if ( variable_trailing_context_rules ) - reject = true; - - if ( (fulltbl || fullspd) && reject ) - { - if ( real_reject ) - flexerror( "REJECT cannot be used with -f or -F" ); - else - flexerror( - "variable trailing context rules cannot be used with -f or -F" ); - } - - ntod(); - - /* generate the C state transition tables from the DFA */ - make_tables(); - - /* note, flexend does not return. It exits with its argument as status. */ - - flexend( 0 ); - - /*NOTREACHED*/ -} - - -/* flexend - terminate flex - * - * synopsis - * int status; - * flexend( status ); - * - * status is exit status. - * - * note - * This routine does not return. - */ - -void flexend(int status) -{ - int tblsiz; - char *flex_gettime(); - - if ( skelfile != NULL ) - { - if ( ferror( skelfile ) ) - flexfatal( "error occurred when writing skeleton file" ); - - else if ( fclose( skelfile ) ) - flexfatal( "error occurred when closing skeleton file" ); - } - - if ( temp_action_file ) - { - if ( ferror( temp_action_file ) ) - flexfatal( "error occurred when writing temporary action file" ); - - else if ( fclose( temp_action_file ) ) - flexfatal( "error occurred when closing temporary action file" ); - - else if ( unlink( action_file_name ) ) - flexfatal( "error occurred when deleting temporary action file" ); - } - - if ( status != 0 && outfile_created ) - { - if ( ferror( stdout ) ) - flexfatal( "error occurred when writing output file" ); - - else if ( fclose( stdout ) ) - flexfatal( "error occurred when closing output file" ); - - else if ( unlink( outfile ) ) - flexfatal( "error occurred when deleting output file" ); - } - - if ( backtrack_report && backtrack_file ) - { - if ( num_backtracking == 0 ) - fprintf( backtrack_file, "No backtracking.\n" ); - else if ( fullspd || fulltbl ) - fprintf( backtrack_file, - "%d backtracking (non-accepting) states.\n", - num_backtracking ); - else - fprintf( backtrack_file, "Compressed tables always backtrack.\n" ); - - if ( ferror( backtrack_file ) ) - flexfatal( "error occurred when writing backtracking file" ); - - else if ( fclose( backtrack_file ) ) - flexfatal( "error occurred when closing backtracking file" ); - } - - if ( printstats ) - { - endtime = flex_gettime(); - - fprintf( stderr, "%s version %s usage statistics:\n", program_name, - flex_version ); - fprintf( stderr, " started at %s, finished at %s\n", - starttime, endtime ); - - fprintf( stderr, " scanner options: -" ); - - if ( backtrack_report ) - putc( 'b', stderr ); - if ( ddebug ) - putc( 'd', stderr ); - if ( interactive ) - putc( 'I', stderr ); - if ( caseins ) - putc( 'i', stderr ); - if ( ! gen_line_dirs ) - putc( 'L', stderr ); - if ( performance_report ) - putc( 'p', stderr ); - if ( spprdflt ) - putc( 's', stderr ); - if ( use_stdout ) - putc( 't', stderr ); - if ( trace ) - putc( 'T', stderr ); - if ( printstats ) - putc( 'v', stderr ); /* always true! */ - if ( csize == 256 ) - putc( '8', stderr ); - - fprintf( stderr, " -C" ); - - if ( fulltbl ) - putc( 'f', stderr ); - if ( fullspd ) - putc( 'F', stderr ); - if ( useecs ) - putc( 'e', stderr ); - if ( usemecs ) - putc( 'm', stderr ); - - if ( strcmp( skelname, ENQUOTE(DEFAULT_SKELETON_FILE) ) ) - fprintf( stderr, " -S%s", skelname ); - - putc( '\n', stderr ); - - fprintf( stderr, " %d/%d NFA states\n", lastnfa, current_mns ); - fprintf( stderr, " %d/%d DFA states (%d words)\n", lastdfa, - current_max_dfas, totnst ); - fprintf( stderr, - " %d rules\n", num_rules - 1 /* - 1 for def. rule */ ); - - if ( num_backtracking == 0 ) - fprintf( stderr, " No backtracking\n" ); - else if ( fullspd || fulltbl ) - fprintf( stderr, " %d backtracking (non-accepting) states\n", - num_backtracking ); - else - fprintf( stderr, " compressed tables always backtrack\n" ); - - if ( bol_needed ) - fprintf( stderr, " Beginning-of-line patterns used\n" ); - - fprintf( stderr, " %d/%d start conditions\n", lastsc, - current_max_scs ); - fprintf( stderr, " %d epsilon states, %d double epsilon states\n", - numeps, eps2 ); - - if ( lastccl == 0 ) - fprintf( stderr, " no character classes\n" ); - else - fprintf( stderr, - " %d/%d character classes needed %d/%d words of storage, %d reused\n", - lastccl, current_maxccls, - cclmap[lastccl] + ccllen[lastccl], - current_max_ccl_tbl_size, cclreuse ); - - fprintf( stderr, " %d state/nextstate pairs created\n", numsnpairs ); - fprintf( stderr, " %d/%d unique/duplicate transitions\n", - numuniq, numdup ); - - if ( fulltbl ) - { - tblsiz = lastdfa * numecs; - fprintf( stderr, " %d table entries\n", tblsiz ); - } - - else - { - tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend; - - fprintf( stderr, " %d/%d base-def entries created\n", - lastdfa + numtemps, current_max_dfas ); - fprintf( stderr, " %d/%d (peak %d) nxt-chk entries created\n", - tblend, current_max_xpairs, peakpairs ); - fprintf( stderr, - " %d/%d (peak %d) template nxt-chk entries created\n", - numtemps * nummecs, current_max_template_xpairs, - numtemps * numecs ); - fprintf( stderr, " %d empty table entries\n", nummt ); - fprintf( stderr, " %d protos created\n", numprots ); - fprintf( stderr, " %d templates created, %d uses\n", - numtemps, tmpuses ); - } - - if ( useecs ) - { - tblsiz = tblsiz + csize; - fprintf( stderr, " %d/%d equivalence classes created\n", - numecs, csize ); - } - - if ( usemecs ) - { - tblsiz = tblsiz + numecs; - fprintf( stderr, " %d/%d meta-equivalence classes created\n", - nummecs, csize ); - } - - fprintf( stderr, " %d (%d saved) hash collisions, %d DFAs equal\n", - hshcol, hshsave, dfaeql ); - fprintf( stderr, " %d sets of reallocations needed\n", num_reallocs ); - fprintf( stderr, " %d total table entries needed\n", tblsiz ); - } - - exit( status ); -} - - -/* flexinit - initialize flex - * - * synopsis - * int argc; - * char **argv; - * flexinit( argc, argv ); - */ - -void flexinit(int argc, char **argv) -{ - int i, sawcmpflag; - char *arg, *flex_gettime(), *mktemp(); - - printstats = syntaxerror = trace = spprdflt = interactive = caseins = false; - backtrack_report = performance_report = ddebug = fulltbl = fullspd = false; - yymore_used = continued_action = reject = false; - yymore_really_used = reject_really_used = false; - gen_line_dirs = usemecs = useecs = true; - - sawcmpflag = false; - use_stdout = false; - - csize = DEFAULT_CSIZE; - - program_name = argv[0]; - - /* read flags */ - for ( --argc, ++argv; argc ; --argc, ++argv ) - { - if ( argv[0][0] != '-' || argv[0][1] == '\0' ) - break; - - arg = argv[0]; - - for ( i = 1; arg[i] != '\0'; ++i ) - switch ( arg[i] ) - { - case 'b': - backtrack_report = true; - break; - - case 'c': - fprintf( stderr, - "%s: Assuming use of deprecated -c flag is really intended to be -C\n", - program_name ); - - /* fall through */ - - case 'C': - if ( i != 1 ) - flexerror( "-C flag must be given separately" ); - - if ( ! sawcmpflag ) - { - useecs = false; - usemecs = false; - fulltbl = false; - sawcmpflag = true; - } - - for ( ++i; arg[i] != '\0'; ++i ) - switch ( arg[i] ) - { - case 'e': - useecs = true; - break; - - case 'F': - fullspd = true; - break; - - case 'f': - fulltbl = true; - break; - - case 'm': - usemecs = true; - break; - - default: - lerrif( "unknown -C option '%c'", - (int) arg[i] ); - break; - } - - goto get_next_arg; - - case 'd': - ddebug = true; - break; - - case 'f': - useecs = usemecs = false; - fulltbl = true; - break; - - case 'F': - useecs = usemecs = false; - fullspd = true; - break; - - case 'I': - interactive = true; - break; - - case 'i': - caseins = true; - break; - - case 'L': - gen_line_dirs = false; - break; - - case 'n': - /* stupid do-nothing deprecated option */ - break; - - case 'p': - performance_report = true; - break; - - case 'S': - if ( i != 1 ) - flexerror( "-S flag must be given separately" ); - - skelname = arg + i + 1; - goto get_next_arg; - - case 's': - spprdflt = true; - break; - - case 't': - use_stdout = true; - break; - - case 'T': - trace = true; - break; - - case 'v': - printstats = true; - break; - - case '8': - csize = CSIZE; - break; - - default: - lerrif( "unknown flag '%c'", (int) arg[i] ); - break; - } - -get_next_arg: /* used by -C and -S flags in lieu of a "continue 2" control */ - ; - } - - if ( (fulltbl || fullspd) && usemecs ) - flexerror( "full table and -Cm don't make sense together" ); - - if ( (fulltbl || fullspd) && interactive ) - flexerror( "full table and -I are (currently) incompatible" ); - - if ( fulltbl && fullspd ) - flexerror( "full table and -F are mutually exclusive" ); - - if ( ! skelname ) - { - static char skeleton_name_storage[400]; - - skelname = skeleton_name_storage; - (void) strcpy( skelname, ENQUOTE(DEFAULT_SKELETON_FILE) ); - } - - if ( ! use_stdout ) - { - FILE *prev_stdout = freopen( outfile, "w", stdout ); - - if ( prev_stdout == NULL ) - lerrsf( "could not create %s", outfile ); - - outfile_created = 1; - } - - num_input_files = argc; - input_files = argv; - set_input_file( num_input_files > 0 ? input_files[0] : NULL ); - - if ( backtrack_report ) - { -#ifndef SHORT_FILE_NAMES - backtrack_file = fopen( "lex.backtrack", "w" ); -#else - backtrack_file = fopen( "lex.bck", "w" ); -#endif - - if ( backtrack_file == NULL ) - flexerror( "could not create lex.backtrack" ); - } - - else - backtrack_file = NULL; - - - lastccl = 0; - lastsc = 0; - - /* initialize the statistics */ - starttime = flex_gettime(); - - if ( (skelfile = fopen( skelname, "r" )) == NULL ) - lerrsf( "can't open skeleton file %s", skelname ); - - epicsTempName ( action_file_name, sizeof ( action_file_name ) ); - if ( action_file_name[0] == '\0' ) - { - lerrsf( "can't create temporary file name", "" ); - } - - if ( ( temp_action_file = fopen ( action_file_name, "w" ) ) == NULL ) - lerrsf( "can't open temporary action file %s", action_file_name ); - - lastdfa = lastnfa = num_rules = numas = numsnpairs = tmpuses = 0; - numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 0; - numuniq = numdup = hshsave = eofseen = datapos = dataline = 0; - num_backtracking = onesp = numprots = 0; - variable_trailing_context_rules = bol_needed = false; - - linenum = sectnum = 1; - firstprot = NIL; - - /* used in mkprot() so that the first proto goes in slot 1 - * of the proto queue - */ - lastprot = 1; - - if ( useecs ) - { /* set up doubly-linked equivalence classes */ - /* We loop all the way up to csize, since ecgroup[csize] is the - * position used for NUL characters - */ - ecgroup[1] = NIL; - - for ( i = 2; i <= csize; ++i ) - { - ecgroup[i] = i - 1; - nextecm[i - 1] = i; - } - - nextecm[csize] = NIL; - } - - else - { /* put everything in its own equivalence class */ - for ( i = 1; i <= csize; ++i ) - { - ecgroup[i] = i; - nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */ - } - } - - set_up_initial_allocations(); -} - - -/* readin - read in the rules section of the input file(s) - * - * synopsis - * readin(); - */ - -void readin(void) -{ - skelout(); - - if ( ddebug ) - puts( "#define FLEX_DEBUG" ); - - if ( csize == 256 ) - puts( "#define YY_CHAR unsigned char" ); - else - puts( "#define YY_CHAR char" ); - - line_directive_out( stdout ); - - if ( yyparse() ) - { - pinpoint_message( "fatal parse error" ); - flexend( 1 ); - } - - if ( xlation ) - { - numecs = ecs_from_xlation( ecgroup ); - useecs = true; - } - - else if ( useecs ) - numecs = cre8ecs( nextecm, ecgroup, csize ); - - else - numecs = csize; - - /* now map the equivalence class for NUL to its expected place */ - ecgroup[0] = ecgroup[csize]; - NUL_ec = abs( ecgroup[0] ); - - if ( useecs ) - ccl2ecl(); -} - - - -/* set_up_initial_allocations - allocate memory for internal tables */ - -void set_up_initial_allocations(void) -{ - current_mns = INITIAL_MNS; - firstst = allocate_integer_array( current_mns ); - lastst = allocate_integer_array( current_mns ); - finalst = allocate_integer_array( current_mns ); - transchar = allocate_integer_array( current_mns ); - trans1 = allocate_integer_array( current_mns ); - trans2 = allocate_integer_array( current_mns ); - accptnum = allocate_integer_array( current_mns ); - assoc_rule = allocate_integer_array( current_mns ); - state_type = allocate_integer_array( current_mns ); - - current_max_rules = INITIAL_MAX_RULES; - rule_type = allocate_integer_array( current_max_rules ); - rule_linenum = allocate_integer_array( current_max_rules ); - - current_max_scs = INITIAL_MAX_SCS; - scset = allocate_integer_array( current_max_scs ); - scbol = allocate_integer_array( current_max_scs ); - scxclu = allocate_integer_array( current_max_scs ); - sceof = allocate_integer_array( current_max_scs ); - scname = allocate_char_ptr_array( current_max_scs ); - actvsc = allocate_integer_array( current_max_scs ); - - current_maxccls = INITIAL_MAX_CCLS; - cclmap = allocate_integer_array( current_maxccls ); - ccllen = allocate_integer_array( current_maxccls ); - cclng = allocate_integer_array( current_maxccls ); - - current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE; - ccltbl = allocate_character_array( current_max_ccl_tbl_size ); - - current_max_dfa_size = INITIAL_MAX_DFA_SIZE; - - current_max_xpairs = INITIAL_MAX_XPAIRS; - nxt = allocate_integer_array( current_max_xpairs ); - chk = allocate_integer_array( current_max_xpairs ); - - current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS; - tnxt = allocate_integer_array( current_max_template_xpairs ); - - current_max_dfas = INITIAL_MAX_DFAS; - base = allocate_integer_array( current_max_dfas ); - def = allocate_integer_array( current_max_dfas ); - dfasiz = allocate_integer_array( current_max_dfas ); - accsiz = allocate_integer_array( current_max_dfas ); - dhash = allocate_integer_array( current_max_dfas ); - dss = allocate_int_ptr_array( current_max_dfas ); - dfaacc = allocate_dfaacc_union( current_max_dfas ); - - nultrans = (int *) 0; -} diff --git a/src/libCom/flex/flex.html b/src/libCom/flex/flex.html deleted file mode 100644 index 3b6ae9b80..000000000 --- a/src/libCom/flex/flex.html +++ /dev/null @@ -1,611 +0,0 @@ - - -
-
-
-
-

NAME

-     flex - fast lexical analyzer generator
-
-
-
-

SYNOPSIS

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

DESCRIPTION

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

OPTIONS

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

SUMMARY OF FLEX REGULAR EXPRESSIONS

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

SUMMARY OF SPECIAL ACTIONS

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

VALUES AVAILABLE TO THE USER

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

MACROS THE USER CAN REDEFINE

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

FILES

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

SEE ALSO

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

DIAGNOSTICS

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

AUTHOR

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

DEFICIENCIES / BUGS

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

NAME

-     flex - fast lexical analyzer generator
-
-
-
-

SYNOPSIS

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

DESCRIPTION

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

SOME SIMPLE EXAMPLES

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

FORMAT OF THE INPUT FILE

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

PATTERNS

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

HOW THE INPUT IS MATCHED

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

ACTIONS

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

THE GENERATED SCANNER

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

START CONDITIONS

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

MULTIPLE INPUT BUFFERS

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

END-OF-FILE RULES

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

MISCELLANEOUS MACROS

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

INTERFACING WITH YACC

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

TRANSLATION TABLE

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

OPTIONS

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

PERFORMANCE CONSIDERATIONS

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

INCOMPATIBILITIES WITH LEX AND POSIX

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

DIAGNOSTICS

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

DEFICIENCIES / BUGS

-     See flex(1).
-
-
-
-

SEE ALSO

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

AUTHOR

-     Vern Paxson, with the help of many ideas and  much  inspira-
-     tion  from Van Jacobson.  Original version by Jef Poskanzer.
-     The fast table representation is a partial implementation of
-     a  design done by Van Jacobson.  The implementation was done
-     by Kevin Gong and Vern Paxson.
-
-     Thanks to the many flex beta-testers, feedbackers, and  con-
-     tributors,  especially  Casey  Leedom, benson@odi.com, Keith
-     Bostic, Frederic Brehm, Nick  Christopher,  Jason  Coughlin,
-     Scott  David Daniels, Leo Eskin, Chris Faylor, Eric Goldman,
-     Eric Hughes, Jeffrey R. Jones, Kevin B. Kenny,  Ronald  Lam-
-     precht,  Greg  Lee, Craig Leres, Mohamed el Lozy, Jim Meyer-
-     ing, Marc Nozell, Esmond Pitt, Jef Poskanzer,  Jim  Roskind,
-     Dave  Tallman,  Frank Whaley, Ken Yap, and those whose names
-     have slipped my marginal  mail-archiving  skills  but  whose
-     contributions are appreciated all the same.
-
-     Thanks to Keith Bostic, John Gilmore, Craig Leres, Bob  Mul-
-     cahy,  Rich Salz, and Richard Stallman for help with various
-     distribution headaches.
-
-     Thanks to Esmond Pitt and Earle Horton for  8-bit  character
-     support; to Benson Margulies and Fred Burke for C++ support;
-     to Ove Ewerlid for the basics of support for NUL's;  and  to
-     Eric Hughes for the basics of support for multiple buffers.
-
-     Work is being done on extending flex to generate scanners in
-     which  the  state  machine is directly represented in C code
-     rather than tables.  These scanners  may  well  be  substan-
-     tially  faster  than those generated using -f or -F.  If you
-     are working in this area and  are  interested  in  comparing
-     notes and seeing whether redundant work can be avoided, con-
-     tact Ove Ewerlid (ewerlid@mizar.DoCS.UU.SE).
-
-     This work was primarily done when I was  at  the  Real  Time
-     Systems  Group at the Lawrence Berkeley Laboratory in Berke-
-     ley, CA.  Many  thanks  to  all  there  for  the  support  I
-     received.
-
-     Send comments to:
-
-          Vern Paxson
-          Computer Science Department
-          4126 Upson Hall
-          Cornell University
-          Ithaca, NY 14853-7501
-
-          vern@cs.cornell.edu
-          decvax!cornell!vern
-
-
-
-
-
-
-
-
-
-
-Man(1) output converted with -man2html -
- - diff --git a/src/libCom/flex/gen.c b/src/libCom/flex/gen.c deleted file mode 100644 index aad884074..000000000 --- a/src/libCom/flex/gen.c +++ /dev/null @@ -1,1319 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* gen - actual generation (writing) of flex scanners */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - - -/* declare functions that have forward references */ - -void gen_next_state (int); -void genecs (void); -void indent_put2s (char [], char []); -void indent_puts (char []); - - -static int indent_level = 0; /* each level is 4 spaces */ - -#define indent_up() (++indent_level) -#define indent_down() (--indent_level) -#define set_indent(indent_val) indent_level = indent_val - -/* *everything* is done in terms of arrays starting at 1, so provide - * a null entry for the zero element of all C arrays - */ -static char C_short_decl[] = "static const short int %s[%d] =\n { 0,\n"; -static char C_long_decl[] = "static const long int %s[%d] =\n { 0,\n"; -static char C_state_decl[] = - "static const yy_state_type %s[%d] =\n { 0,\n"; - - -/* indent to the current level */ - -void do_indent(void) -{ - int i = indent_level * 4; - - while ( i >= 8 ) - { - putchar( '\t' ); - i -= 8; - } - - while ( i > 0 ) - { - putchar( ' ' ); - --i; - } - } - - -/* generate the code to keep backtracking information */ - -void gen_backtracking(void) -{ - if ( reject || num_backtracking == 0 ) - return; - - if ( fullspd ) - indent_puts( "if ( yy_current_state[-1].yy_nxt )" ); - else - indent_puts( "if ( yy_accept[yy_current_state] )" ); - - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_last_accepting_state = yy_current_state;" ); - indent_puts( "yy_last_accepting_cpos = yy_cp;" ); - indent_puts( "}" ); - indent_down(); - } - - -/* generate the code to perform the backtrack */ - -void gen_bt_action(void) -{ - if ( reject || num_backtracking == 0 ) - return; - - set_indent( 3 ); - - indent_puts( "case 0: /* must backtrack */" ); - indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" ); - indent_puts( "*yy_cp = yy_hold_char;" ); - - if ( fullspd || fulltbl ) - indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" ); - else - /* backtracking info for compressed tables is taken \after/ - * yy_cp has been incremented for the next state - */ - indent_puts( "yy_cp = yy_last_accepting_cpos;" ); - - indent_puts( "yy_current_state = yy_last_accepting_state;" ); - indent_puts( "goto yy_find_action;" ); - putchar( '\n' ); - - set_indent( 0 ); - } - - -/* genctbl - generates full speed compressed transition table - * - * synopsis - * genctbl(); - */ - -void genctbl(void) -{ - int i; - int end_of_buffer_action = num_rules + 1; - - /* table of verify for transition and offset to next state */ - printf( "static const struct yy_trans_info yy_transition[%d] =\n", - tblend + numecs + 1 ); - printf( " {\n" ); - - /* We want the transition to be represented as the offset to the - * next state, not the actual state number, which is what it currently is. - * The offset is base[nxt[i]] - base[chk[i]]. That's just the - * difference between the starting points of the two involved states - * (to - from). - * - * first, though, we need to find some way to put in our end-of-buffer - * flags and states. We do this by making a state with absolutely no - * transitions. We put it at the end of the table. - */ - /* at this point, we're guaranteed that there's enough room in nxt[] - * and chk[] to hold tblend + numecs entries. We need just two slots. - * One for the action and one for the end-of-buffer transition. We - * now *assume* that we're guaranteed the only character we'll try to - * index this nxt/chk pair with is EOB, i.e., 0, so we don't have to - * make sure there's room for jam entries for other characters. - */ - - base[lastdfa + 1] = tblend + 2; - nxt[tblend + 1] = end_of_buffer_action; - chk[tblend + 1] = numecs + 1; - chk[tblend + 2] = 1; /* anything but EOB */ - nxt[tblend + 2] = 0; /* so that "make test" won't show arb. differences */ - - /* make sure every state has a end-of-buffer transition and an action # */ - for ( i = 0; i <= lastdfa; ++i ) - { - int anum = dfaacc[i].dfaacc_state; - - chk[base[i]] = EOB_POSITION; - chk[base[i] - 1] = ACTION_POSITION; - nxt[base[i] - 1] = anum; /* action number */ - } - - for ( i = 0; i <= tblend; ++i ) - { - if ( chk[i] == EOB_POSITION ) - transition_struct_out( 0, base[lastdfa + 1] - i ); - - else if ( chk[i] == ACTION_POSITION ) - transition_struct_out( 0, nxt[i] ); - - else if ( chk[i] > numecs || chk[i] == 0 ) - transition_struct_out( 0, 0 ); /* unused slot */ - - else /* verify, transition */ - transition_struct_out( chk[i], base[nxt[i]] - (i - chk[i]) ); - } - - - /* here's the final, end-of-buffer state */ - transition_struct_out( chk[tblend + 1], nxt[tblend + 1] ); - transition_struct_out( chk[tblend + 2], nxt[tblend + 2] ); - - printf( " };\n" ); - printf( "\n" ); - - /* table of pointers to start states */ - printf( "static const struct yy_trans_info *yy_start_state_list[%d] =\n", - lastsc * 2 + 1 ); - printf( " {\n" ); - - for ( i = 0; i <= lastsc * 2; ++i ) - printf( " &yy_transition[%d],\n", base[i] ); - - dataend(); - - if ( useecs ) - genecs(); - } - - -/* generate equivalence-class tables */ - -void genecs(void) -{ - int i, j; - static char C_char_decl[] = "static const %s %s[%d] =\n { 0,\n"; - int numrows; - Char clower(); - - if ( numecs < csize ) - printf( C_char_decl, "YY_CHAR", "yy_ec", csize ); - else - printf( C_char_decl, "short", "yy_ec", csize ); - - for ( i = 1; i < csize; ++i ) - { - if ( caseins && (i >= 'A') && (i <= 'Z') ) - ecgroup[i] = ecgroup[clower( i )]; - - ecgroup[i] = abs( ecgroup[i] ); - mkdata( ecgroup[i] ); - } - - dataend(); - - if ( trace ) - { - char *readable_form(); - - fputs( "\n\nEquivalence Classes:\n\n", stderr ); - - numrows = csize / 8; - - for ( j = 0; j < numrows; ++j ) - { - for ( i = j; i < csize; i = i + numrows ) - { - fprintf( stderr, "%4s = %-2d", readable_form( i ), ecgroup[i] ); - - putc( ' ', stderr ); - } - - putc( '\n', stderr ); - } - } - } - - -/* generate the code to find the action number */ - -void gen_find_action(void) -{ - if ( fullspd ) - indent_puts( "yy_act = yy_current_state[-1].yy_nxt;" ); - - else if ( fulltbl ) - indent_puts( "yy_act = yy_accept[yy_current_state];" ); - - else if ( reject ) - { - indent_puts( "yy_current_state = *--yy_state_ptr;" ); - indent_puts( "yy_lp = yy_accept[yy_current_state];" ); - - puts( "find_rule: /* we branch to this label when backtracking */" ); - - indent_puts( "for ( ; ; ) /* until we find what rule we matched */" ); - - indent_up(); - - indent_puts( "{" ); - - indent_puts( "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" ); - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_act = yy_acclist[yy_lp];" ); - - if ( variable_trailing_context_rules ) - { - indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" ); - indent_puts( " yy_looking_for_trail_begin )" ); - indent_up(); - indent_puts( "{" ); - - indent_puts( "if ( yy_act == yy_looking_for_trail_begin )" ); - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_looking_for_trail_begin = 0;" ); - indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" ); - indent_puts( "break;" ); - indent_puts( "}" ); - indent_down(); - - indent_puts( "}" ); - indent_down(); - - indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" ); - indent_up(); - indent_puts( "{" ); - indent_puts( - "yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" ); - indent_puts( - "yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" ); - - if ( real_reject ) - { - /* remember matched text in case we back up due to REJECT */ - indent_puts( "yy_full_match = yy_cp;" ); - indent_puts( "yy_full_state = yy_state_ptr;" ); - indent_puts( "yy_full_lp = yy_lp;" ); - } - - indent_puts( "}" ); - indent_down(); - - indent_puts( "else" ); - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_full_match = yy_cp;" ); - indent_puts( "yy_full_state = yy_state_ptr;" ); - indent_puts( "yy_full_lp = yy_lp;" ); - indent_puts( "break;" ); - indent_puts( "}" ); - indent_down(); - - indent_puts( "++yy_lp;" ); - indent_puts( "goto find_rule;" ); - } - - else - { - /* remember matched text in case we back up due to trailing context - * plus REJECT - */ - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_full_match = yy_cp;" ); - indent_puts( "break;" ); - indent_puts( "}" ); - indent_down(); - } - - indent_puts( "}" ); - indent_down(); - - indent_puts( "--yy_cp;" ); - - /* we could consolidate the following two lines with those at - * the beginning, but at the cost of complaints that we're - * branching inside a loop - */ - indent_puts( "yy_current_state = *--yy_state_ptr;" ); - indent_puts( "yy_lp = yy_accept[yy_current_state];" ); - - indent_puts( "}" ); - - indent_down(); - } - - else - /* compressed */ - indent_puts( "yy_act = yy_accept[yy_current_state];" ); - } - - -/* genftbl - generates full transition table - * - * synopsis - * genftbl(); - */ - -void genftbl(void) -{ - int i; - int end_of_buffer_action = num_rules + 1; - - printf( C_short_decl, "yy_accept", lastdfa + 1 ); - - - dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; - - for ( i = 1; i <= lastdfa; ++i ) - { - int anum = dfaacc[i].dfaacc_state; - - mkdata( anum ); - - if ( trace && anum ) - fprintf( stderr, "state # %d accepts: [%d]\n", i, anum ); - } - - dataend(); - - if ( useecs ) - genecs(); - - /* don't have to dump the actual full table entries - they were created - * on-the-fly - */ - } - - -/* generate the code to find the next compressed-table state */ - -void gen_next_compressed_state(char *char_map) -{ - indent_put2s( "YY_CHAR yy_c = %s;", char_map ); - - /* save the backtracking info \before/ computing the next state - * because we always compute one more state than needed - we - * always proceed until we reach a jam state - */ - gen_backtracking(); - - indent_puts( - "while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" ); - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_current_state = yy_def[yy_current_state];" ); - - if ( usemecs ) - { - /* we've arrange it so that templates are never chained - * to one another. This means we can afford make a - * very simple test to see if we need to convert to - * yy_c's meta-equivalence class without worrying - * about erroneously looking up the meta-equivalence - * class twice - */ - do_indent(); - /* lastdfa + 2 is the beginning of the templates */ - printf( "if ( yy_current_state >= %d )\n", lastdfa + 2 ); - - indent_up(); - indent_puts( "yy_c = yy_meta[(int)yy_c];" ); - indent_down(); - } - - indent_puts( "}" ); - indent_down(); - - indent_puts( - "yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];" ); - } - - -/* generate the code to find the next match */ - -void gen_next_match(void) -{ - /* NOTE - changes in here should be reflected in gen_next_state() and - * gen_NUL_trans() - */ - char *char_map = useecs ? "yy_ec[(int)*yy_cp]" : "*yy_cp"; - char *char_map_2 = useecs ? "yy_ec[*++yy_cp]" : "*++yy_cp"; - - if ( fulltbl ) - { - indent_put2s( - "while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )", - char_map ); - - indent_up(); - - if ( num_backtracking > 0 ) - { - indent_puts( "{" ); - gen_backtracking(); - putchar( '\n' ); - } - - indent_puts( "++yy_cp;" ); - - if ( num_backtracking > 0 ) - indent_puts( "}" ); - - indent_down(); - - putchar( '\n' ); - indent_puts( "yy_current_state = -yy_current_state;" ); - } - - else if ( fullspd ) - { - indent_puts( "{" ); - indent_puts( "const struct yy_trans_info *yy_trans_info;\n" ); - indent_puts( "YY_CHAR yy_c;\n" ); - indent_put2s( "for ( yy_c = %s;", char_map ); - indent_puts( - " (yy_trans_info = &yy_current_state[yy_c])->yy_verify == yy_c;" ); - indent_put2s( " yy_c = %s )", char_map_2 ); - - indent_up(); - - if ( num_backtracking > 0 ) - indent_puts( "{" ); - - indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" ); - - if ( num_backtracking > 0 ) - { - putchar( '\n' ); - gen_backtracking(); - indent_puts( "}" ); - } - - indent_down(); - indent_puts( "}" ); - } - - else - { /* compressed */ - indent_puts( "do" ); - - indent_up(); - indent_puts( "{" ); - - gen_next_state( false ); - - indent_puts( "++yy_cp;" ); - - indent_puts( "}" ); - indent_down(); - - do_indent(); - - if ( interactive ) - printf( "while ( yy_base[yy_current_state] != %d );\n", jambase ); - else - printf( "while ( yy_current_state != %d );\n", jamstate ); - - if ( ! reject && ! interactive ) - { - /* do the guaranteed-needed backtrack to figure out the match */ - indent_puts( "yy_cp = yy_last_accepting_cpos;" ); - indent_puts( "yy_current_state = yy_last_accepting_state;" ); - } - } - } - - -/* generate the code to find the next state */ - -void gen_next_state(int worry_about_NULs) -{ /* NOTE - changes in here should be reflected in get_next_match() */ - char char_map[256]; - - if ( worry_about_NULs && ! nultrans ) - { - if ( useecs ) - (void) sprintf( char_map, "(*yy_cp ? yy_ec[(int)*yy_cp] : %d)", NUL_ec ); - else - (void) sprintf( char_map, "(*yy_cp ? *yy_cp : %d)", NUL_ec ); - } - - else - (void) strcpy( char_map, useecs ? "yy_ec[(int)*yy_cp]" : "*yy_cp" ); - - if ( worry_about_NULs && nultrans ) - { - if ( ! fulltbl && ! fullspd ) - /* compressed tables backtrack *before* they match */ - gen_backtracking(); - - indent_puts( "if ( *yy_cp )" ); - indent_up(); - indent_puts( "{" ); - } - - if ( fulltbl ) - indent_put2s( "yy_current_state = yy_nxt[yy_current_state][%s];", - char_map ); - - else if ( fullspd ) - indent_put2s( "yy_current_state += yy_current_state[%s].yy_nxt;", - char_map ); - - else - gen_next_compressed_state( char_map ); - - if ( worry_about_NULs && nultrans ) - { - indent_puts( "}" ); - indent_down(); - indent_puts( "else" ); - indent_up(); - indent_puts( "yy_current_state = yy_NUL_trans[yy_current_state];" ); - indent_down(); - } - - if ( fullspd || fulltbl ) - gen_backtracking(); - - if ( reject ) - indent_puts( "*yy_state_ptr++ = yy_current_state;" ); - } - - -/* generate the code to make a NUL transition */ - -void gen_NUL_trans(void) -{ /* NOTE - changes in here should be reflected in get_next_match() */ - int need_backtracking = (num_backtracking > 0 && ! reject); - - if ( need_backtracking ) - /* we'll need yy_cp lying around for the gen_backtracking() */ - indent_puts( "YY_CHAR *yy_cp = yy_c_buf_p;" ); - - putchar( '\n' ); - - if ( nultrans ) - { - indent_puts( "yy_current_state = yy_NUL_trans[yy_current_state];" ); - indent_puts( "yy_is_jam = (yy_current_state == 0);" ); - } - - else if ( fulltbl ) - { - do_indent(); - printf( "yy_current_state = yy_nxt[yy_current_state][%d];\n", - NUL_ec ); - indent_puts( "yy_is_jam = (yy_current_state <= 0);" ); - } - - else if ( fullspd ) - { - do_indent(); - printf( "int yy_c = %d;\n", NUL_ec ); - - indent_puts( - "const struct yy_trans_info *yy_trans_info;\n" ); - indent_puts( "yy_trans_info = &yy_current_state[yy_c];" ); - indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" ); - - indent_puts( "yy_is_jam = (yy_trans_info->yy_verify != yy_c);" ); - } - - else - { - char NUL_ec_str[20]; - - (void) sprintf( NUL_ec_str, "%d", NUL_ec ); - gen_next_compressed_state( NUL_ec_str ); - - if ( reject ) - indent_puts( "*yy_state_ptr++ = yy_current_state;" ); - - do_indent(); - - if ( interactive ) - printf( "yy_is_jam = (yy_base[yy_current_state] == %d);\n", - jambase ); - else - printf( "yy_is_jam = (yy_current_state == %d);\n", jamstate ); - } - - /* if we've entered an accepting state, backtrack; note that - * compressed tables have *already* done such backtracking, so - * we needn't bother with it again - */ - if ( need_backtracking && (fullspd || fulltbl) ) - { - putchar( '\n' ); - indent_puts( "if ( ! yy_is_jam )" ); - indent_up(); - indent_puts( "{" ); - gen_backtracking(); - indent_puts( "}" ); - indent_down(); - } - } - - -/* generate the code to find the start state */ - -void gen_start_state(void) -{ - if ( fullspd ) - indent_put2s( "yy_current_state = yy_start_state_list[yy_start%s];", - bol_needed ? " + (yy_bp[-1] == '\\n' ? 1 : 0)" : "" ); - - else - { - indent_puts( "yy_current_state = yy_start;" ); - - if ( bol_needed ) - { - indent_puts( "if ( yy_bp[-1] == '\\n' )" ); - indent_up(); - indent_puts( "++yy_current_state;" ); - indent_down(); - } - - if ( reject ) - { - /* set up for storing up states */ - indent_puts( "yy_state_ptr = yy_state_buf;" ); - indent_puts( "*yy_state_ptr++ = yy_current_state;" ); - } - } - } - - -/* gentabs - generate data statements for the transition tables - * - * synopsis - * gentabs(); - */ - -void gentabs(void) -{ - int i, j, k, *accset, nacc, *acc_array, total_states; - int end_of_buffer_action = num_rules + 1; - - /* *everything* is done in terms of arrays starting at 1, so provide - * a null entry for the zero element of all C arrays - */ - static char C_char_decl[] = - "static const YY_CHAR %s[%d] =\n { 0,\n"; - - acc_array = allocate_integer_array( current_max_dfas ); - nummt = 0; - - /* the compressed table format jams by entering the "jam state", - * losing information about the previous state in the process. - * In order to recover the previous state, we effectively need - * to keep backtracking information. - */ - ++num_backtracking; - - if ( reject ) - { - /* write out accepting list and pointer list - * - * first we generate the "yy_acclist" array. In the process, we compute - * the indices that will go into the "yy_accept" array, and save the - * indices in the dfaacc array - */ - int EOB_accepting_list[2]; - - /* set up accepting structures for the End Of Buffer state */ - EOB_accepting_list[0] = 0; - EOB_accepting_list[1] = end_of_buffer_action; - accsiz[end_of_buffer_state] = 1; - dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list; - - printf( C_short_decl, "yy_acclist", max( numas, 1 ) + 1 ); - - j = 1; /* index into "yy_acclist" array */ - - for ( i = 1; i <= lastdfa; ++i ) - { - acc_array[i] = j; - - if ( accsiz[i] != 0 ) - { - accset = dfaacc[i].dfaacc_set; - nacc = accsiz[i]; - - if ( trace ) - fprintf( stderr, "state # %d accepts: ", i ); - - for ( k = 1; k <= nacc; ++k ) - { - int accnum = accset[k]; - - ++j; - - if ( variable_trailing_context_rules && - ! (accnum & YY_TRAILING_HEAD_MASK) && - accnum > 0 && accnum <= num_rules && - rule_type[accnum] == RULE_VARIABLE ) - { - /* special hack to flag accepting number as part - * of trailing context rule - */ - accnum |= YY_TRAILING_MASK; - } - - mkdata( accnum ); - - if ( trace ) - { - fprintf( stderr, "[%d]", accset[k] ); - - if ( k < nacc ) - fputs( ", ", stderr ); - else - putc( '\n', stderr ); - } - } - } - } - - /* add accepting number for the "jam" state */ - acc_array[i] = j; - - dataend(); - } - - else - { - dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; - - for ( i = 1; i <= lastdfa; ++i ) - acc_array[i] = dfaacc[i].dfaacc_state; - - /* add accepting number for jam state */ - acc_array[i] = 0; - } - - /* spit out "yy_accept" array. If we're doing "reject", it'll be pointers - * into the "yy_acclist" array. Otherwise it's actual accepting numbers. - * In either case, we just dump the numbers. - */ - - /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays - * beginning at 0 and for "jam" state - */ - k = lastdfa + 2; - - if ( reject ) - /* we put a "cap" on the table associating lists of accepting - * numbers with state numbers. This is needed because we tell - * where the end of an accepting list is by looking at where - * the list for the next state starts. - */ - ++k; - - printf( C_short_decl, "yy_accept", k ); - - for ( i = 1; i <= lastdfa; ++i ) - { - mkdata( acc_array[i] ); - - if ( ! reject && trace && acc_array[i] ) - fprintf( stderr, "state # %d accepts: [%d]\n", i, acc_array[i] ); - } - - /* add entry for "jam" state */ - mkdata( acc_array[i] ); - - if ( reject ) - /* add "cap" for the list */ - mkdata( acc_array[i] ); - - dataend(); - - if ( useecs ) - genecs(); - - if ( usemecs ) - { - /* write out meta-equivalence classes (used to index templates with) */ - - if ( trace ) - fputs( "\n\nMeta-Equivalence Classes:\n", stderr ); - - printf( C_char_decl, "yy_meta", numecs + 1 ); - - for ( i = 1; i <= numecs; ++i ) - { - if ( trace ) - fprintf( stderr, "%d = %d\n", i, abs( tecbck[i] ) ); - - mkdata( abs( tecbck[i] ) ); - } - - dataend(); - } - - total_states = lastdfa + numtemps; - - printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl, - "yy_base", total_states + 1 ); - - for ( i = 1; i <= lastdfa; ++i ) - { - int d = def[i]; - - if ( base[i] == JAMSTATE ) - base[i] = jambase; - - if ( d == JAMSTATE ) - def[i] = jamstate; - - else if ( d < 0 ) - { - /* template reference */ - ++tmpuses; - def[i] = lastdfa - d + 1; - } - - mkdata( base[i] ); - } - - /* generate jam state's base index */ - mkdata( base[i] ); - - for ( ++i /* skip jam state */; i <= total_states; ++i ) - { - mkdata( base[i] ); - def[i] = jamstate; - } - - dataend(); - - printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl, - "yy_def", total_states + 1 ); - - for ( i = 1; i <= total_states; ++i ) - mkdata( def[i] ); - - dataend(); - - printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl, - "yy_nxt", tblend + 1 ); - - for ( i = 1; i <= tblend; ++i ) - { - if ( nxt[i] == 0 || chk[i] == 0 ) - nxt[i] = jamstate; /* new state is the JAM state */ - - mkdata( nxt[i] ); - } - - dataend(); - - printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl, - "yy_chk", tblend + 1 ); - - for ( i = 1; i <= tblend; ++i ) - { - if ( chk[i] == 0 ) - ++nummt; - - mkdata( chk[i] ); - } - - dataend(); - } - - -/* write out a formatted string (with a secondary string argument) at the - * current indentation level, adding a final newline - */ - -void indent_put2s(char *fmt, char *arg) -{ - do_indent(); - printf( fmt, arg ); - putchar( '\n' ); - } - - -/* write out a string at the current indentation level, adding a final - * newline - */ - -void indent_puts(char *str) -{ - do_indent(); - puts( str ); - } - - -/* make_tables - generate transition tables - * - * synopsis - * make_tables(); - * - * Generates transition tables and finishes generating output file - */ - -void make_tables(void) -{ - int i; - int did_eof_rule = false; - - skelout(); - - /* first, take care of YY_DO_BEFORE_ACTION depending on yymore being used */ - set_indent( 2 ); - - if ( yymore_used ) - { - indent_puts( "yytext -= yy_more_len; \\" ); - indent_puts( "yyleng = yy_cp - yytext; \\" ); - } - - else - indent_puts( "yyleng = yy_cp - yy_bp; \\" ); - - set_indent( 0 ); - - skelout(); - - - printf( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 ); - - if ( fullspd ) - { /* need to define the transet type as a size large - * enough to hold the biggest offset - */ - int total_table_size = tblend + numecs + 1; - char *trans_offset_type = - total_table_size > MAX_SHORT ? "long" : "short"; - - set_indent( 0 ); - indent_puts( "struct yy_trans_info" ); - indent_up(); - indent_puts( "{" ); - indent_puts( "short yy_verify;" ); - - /* in cases where its sister yy_verify *is* a "yes, there is a - * transition", yy_nxt is the offset (in records) to the next state. - * In most cases where there is no transition, the value of yy_nxt - * is irrelevant. If yy_nxt is the -1th record of a state, though, - * then yy_nxt is the action number for that state - */ - - indent_put2s( "%s yy_nxt;", trans_offset_type ); - indent_puts( "};" ); - indent_down(); - - indent_puts( "typedef const struct yy_trans_info *yy_state_type;" ); - } - - else - indent_puts( "typedef int yy_state_type;" ); - - if ( fullspd ) - genctbl(); - - else if ( fulltbl ) - genftbl(); - - else - gentabs(); - - if ( num_backtracking > 0 ) - { - indent_puts( "static yy_state_type yy_last_accepting_state;" ); - indent_puts( "static YY_CHAR *yy_last_accepting_cpos;\n" ); - } - - if ( nultrans ) - { - printf( C_state_decl, "yy_NUL_trans", lastdfa + 1 ); - - for ( i = 1; i <= lastdfa; ++i ) - { - if ( fullspd ) - { - if ( nultrans ) - printf( " &yy_transition[%d],\n", base[i] ); - else - printf( " 0,\n" ); - } - - else - mkdata( nultrans[i] ); - } - - dataend(); - } - - if ( ddebug ) - { /* spit out table mapping rules to line numbers */ - indent_puts( "extern int yy_flex_debug;" ); - indent_puts( "int yy_flex_debug = 1;\n" ); - - printf( C_short_decl, "yy_rule_linenum", num_rules ); - for ( i = 1; i < num_rules; ++i ) - mkdata( rule_linenum[i] ); - dataend(); - } - - if ( reject ) - { - /* declare state buffer variables */ - puts( - "static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" ); - puts( "static YY_CHAR *yy_full_match;" ); - puts( "static int yy_lp;" ); - - if ( variable_trailing_context_rules ) - { - puts( "static int yy_looking_for_trail_begin = 0;" ); - puts( "static int yy_full_lp;" ); - puts( "static int *yy_full_state;" ); - printf( "#define YY_TRAILING_MASK 0x%x\n", YY_TRAILING_MASK ); - printf( "#define YY_TRAILING_HEAD_MASK 0x%x\n", - YY_TRAILING_HEAD_MASK ); - } - - puts( "#define REJECT \\" ); - puts( "{ \\" ); - puts( - "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" ); - puts( - "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" ); - - if ( variable_trailing_context_rules ) - { - puts( "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" ); - puts( - "yy_state_ptr = yy_full_state; /* restore orig. state */ \\" ); - puts( - "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" ); - } - - puts( "++yy_lp; \\" ); - puts( "goto find_rule; \\" ); - puts( "}" ); - } - - else - { - puts( "/* the intent behind this definition is that it'll catch" ); - puts( " * any uses of REJECT which flex missed" ); - puts( " */" ); - puts( "#define REJECT reject_used_but_not_detected" ); - } - - if ( yymore_used ) - { - indent_puts( "static int yy_more_flag = 0;" ); - indent_puts( "static int yy_doing_yy_more = 0;" ); - indent_puts( "static int yy_more_len = 0;" ); - indent_puts( - "#define yymore() { yy_more_flag = 1; }" ); - indent_puts( - "#define YY_MORE_ADJ (yy_doing_yy_more ? yy_more_len : 0)" ); - } - - else - { - indent_puts( "#define yymore() yymore_used_but_not_detected" ); - indent_puts( "#define YY_MORE_ADJ 0" ); - } - - skelout(); - - if ( ferror( temp_action_file ) ) - flexfatal( "error occurred when writing temporary action file" ); - - else if ( fclose( temp_action_file ) ) - flexfatal( "error occurred when closing temporary action file" ); - - temp_action_file = fopen( action_file_name, "r" ); - - if ( temp_action_file == NULL ) - flexfatal( "could not re-open temporary action file" ); - - /* copy prolog from action_file to output file */ - action_out(); - - skelout(); - - set_indent( 2 ); - - if ( yymore_used ) - { - indent_puts( "yy_more_len = 0;" ); - indent_puts( "yy_doing_yy_more = yy_more_flag;" ); - indent_puts( "if ( yy_doing_yy_more )" ); - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_more_len = yyleng;" ); - indent_puts( "yy_more_flag = 0;" ); - indent_puts( "}" ); - indent_down(); - } - - skelout(); - - gen_start_state(); - - /* note, don't use any indentation */ - puts( "yy_match:" ); - gen_next_match(); - - skelout(); - set_indent( 2 ); - gen_find_action(); - - skelout(); - if ( ddebug ) - { - indent_puts( "if ( yy_flex_debug )" ); - indent_up(); - - indent_puts( "{" ); - indent_puts( "if ( yy_act == 0 )" ); - indent_up(); - indent_puts( "fprintf( stderr, \"--scanner backtracking\\n\" );" ); - indent_down(); - - do_indent(); - printf( "else if ( yy_act < %d )\n", num_rules ); - indent_up(); - indent_puts( - "fprintf( stderr, \"--accepting rule at line %d (\\\"%s\\\")\\n\"," ); - indent_puts( " yy_rule_linenum[yy_act], yytext );" ); - indent_down(); - - do_indent(); - printf( "else if ( yy_act == %d )\n", num_rules ); - indent_up(); - indent_puts( - "fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\"," ); - indent_puts( " yytext );" ); - indent_down(); - - do_indent(); - printf( "else if ( yy_act == %d )\n", num_rules + 1 ); - indent_up(); - indent_puts( "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );" ); - indent_down(); - - do_indent(); - printf( "else\n" ); - indent_up(); - indent_puts( "fprintf( stderr, \"--EOF\\n\" );" ); - indent_down(); - - indent_puts( "}" ); - indent_down(); - } - - /* copy actions from action_file to output file */ - skelout(); - indent_up(); - gen_bt_action(); - action_out(); - - /* generate cases for any missing EOF rules */ - for ( i = 1; i <= lastsc; ++i ) - if ( ! sceof[i] ) - { - do_indent(); - printf( "case YY_STATE_EOF(%s):\n", scname[i] ); - did_eof_rule = true; - } - - if ( did_eof_rule ) - { - indent_up(); - indent_puts( "yyterminate();" ); - indent_down(); - } - - - /* generate code for handling NUL's, if needed */ - - /* first, deal with backtracking and setting up yy_cp if the scanner - * finds that it should JAM on the NUL - */ - skelout(); - set_indent( 7 ); - - if ( fullspd || fulltbl ) - indent_puts( "yy_cp = yy_c_buf_p;" ); - - else - { /* compressed table */ - if ( ! reject && ! interactive ) - { - /* do the guaranteed-needed backtrack to figure out the match */ - indent_puts( "yy_cp = yy_last_accepting_cpos;" ); - indent_puts( "yy_current_state = yy_last_accepting_state;" ); - } - } - - - /* generate code for yy_get_previous_state() */ - set_indent( 1 ); - skelout(); - - if ( bol_needed ) - indent_puts( "YY_CHAR *yy_bp = yytext;\n" ); - - gen_start_state(); - - set_indent( 2 ); - skelout(); - gen_next_state( true ); - - set_indent( 1 ); - skelout(); - gen_NUL_trans(); - - skelout(); - - /* copy remainder of input to output */ - - line_directive_out( stdout ); - (void) flexscan(); /* copy remainder of input to output */ - } diff --git a/src/libCom/flex/libmain.c b/src/libCom/flex/libmain.c deleted file mode 100644 index 878aa21dc..000000000 --- a/src/libCom/flex/libmain.c +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* libmain - flex run-time support library "main" function */ - -extern int yylex(); - -int main(int argc, char *argv[]) -{ - return yylex(); -} diff --git a/src/libCom/flex/misc.c b/src/libCom/flex/misc.c deleted file mode 100644 index b8a7a0399..000000000 --- a/src/libCom/flex/misc.c +++ /dev/null @@ -1,771 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* misc - miscellaneous flex routines */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include -#include "flexdef.h" -#include - -/* ANSI C does not guarantee that isascii() is defined */ -#ifndef isascii -#define isascii(c) ((c) <= 0177) -#endif - - - -/* declare functions that have forward references */ - -void dataflush (void); -int otoi (Char []); - - -/* action_out - write the actions from the temporary file to lex.yy.c - * - * synopsis - * action_out(); - * - * Copies the action file up to %% (or end-of-file) to lex.yy.c - */ - -void action_out(void) -{ - char buf[MAXLINE]; - - while ( fgets( buf, MAXLINE, temp_action_file ) != NULL ) - if ( buf[0] == '%' && buf[1] == '%' ) - break; - else - fputs( buf, stdout ); - } - - -/* allocate_array - allocate memory for an integer array of the given size */ - -void *allocate_array(int size, int element_size) -{ - void *mem; - - /* on 16-bit int machines (e.g., 80286) we might be trying to - * allocate more than a signed int can hold, and that won't - * work. Cheap test: - */ - if ( element_size * size <= 0 ) - flexfatal( "request for < 1 byte in allocate_array()" ); - - mem = (void *) malloc( (unsigned) (element_size * size) ); - - if ( mem == NULL ) - flexfatal( "memory allocation failed in allocate_array()" ); - - return ( mem ); - } - - -/* all_lower - true if a string is all lower-case - * - * synopsis: - * Char *str; - * int all_lower(); - * true/false = all_lower( str ); - */ - -int all_lower(Char *str) -{ - while ( *str ) - { - if ( ! isascii( (int) *str ) || ! islower( (int) *str ) ) - return ( 0 ); - ++str; - } - - return ( 1 ); - } - - -/* all_upper - true if a string is all upper-case - * - * synopsis: - * Char *str; - * int all_upper(); - * true/false = all_upper( str ); - */ - -int all_upper(Char *str) -{ - while ( *str ) - { - if ( ! isascii( (int) *str ) || ! isupper( (int) *str ) ) - return ( 0 ); - ++str; - } - - return ( 1 ); - } - - -/* bubble - bubble sort an integer array in increasing order - * - * synopsis - * int v[n], n; - * bubble( v, n ); - * - * description - * sorts the first n elements of array v and replaces them in - * increasing order. - * - * passed - * v - the array to be sorted - * n - the number of elements of 'v' to be sorted */ - -void bubble(int v[], int n) -{ - int i, j, k; - - for ( i = n; i > 1; --i ) - for ( j = 1; j < i; ++j ) - if ( v[j] > v[j + 1] ) /* compare */ - { - k = v[j]; /* exchange */ - v[j] = v[j + 1]; - v[j + 1] = k; - } - } - - -/* clower - replace upper-case letter to lower-case - * - * synopsis: - * Char clower(); - * int c; - * c = clower( c ); - */ - -Char clower(int c) -{ - return ( (isascii( c ) && isupper( c )) ? tolower( c ) : c ); - } - - -/* copy_string - returns a dynamically allocated copy of a string - * - * synopsis - * char *str, *copy, *copy_string(); - * copy = copy_string( str ); - */ - -char *copy_string(char *str) -{ - char *c; - char *copy; - - /* find length */ - for ( c = str; *c; ++c ) - ; - - copy = malloc( (unsigned) ((c - str + 1) * sizeof( char )) ); - - if ( copy == NULL ) - flexfatal( "dynamic memory failure in copy_string()" ); - - for ( c = copy; (*c++ = *str++); ) - ; - - return ( copy ); - } - - -/* copy_unsigned_string - - * returns a dynamically allocated copy of a (potentially) unsigned string - * - * synopsis - * Char *str, *copy, *copy_unsigned_string(); - * copy = copy_unsigned_string( str ); - */ - -Char *copy_unsigned_string(Char *str) -{ - Char *c; - Char *copy; - - /* find length */ - for ( c = str; *c; ++c ) - ; - - copy = (Char *) malloc( (unsigned) ((c - str + 1) * sizeof( Char )) ); - - if ( copy == NULL ) - flexfatal( "dynamic memory failure in copy_unsigned_string()" ); - - for ( c = copy; (*c++ = *str++); ) - ; - - return ( copy ); - } - - -/* cshell - shell sort a character array in increasing order - * - * synopsis - * - * Char v[n]; - * int n, special_case_0; - * cshell( v, n, special_case_0 ); - * - * description - * does a shell sort of the first n elements of array v. - * If special_case_0 is true, then any element equal to 0 - * is instead assumed to have infinite weight. - * - * passed - * v - array to be sorted - * n - number of elements of v to be sorted - */ - -void cshell(Char *v, int n, int special_case_0) -{ - int gap, i, j, jg; - Char k; - - for ( gap = n / 2; gap > 0; gap = gap / 2 ) - for ( i = gap; i < n; ++i ) - for ( j = i - gap; j >= 0; j = j - gap ) - { - jg = j + gap; - - if ( special_case_0 ) - { - if ( v[jg] == 0 ) - break; - - else if ( v[j] != 0 && v[j] <= v[jg] ) - break; - } - - else if ( v[j] <= v[jg] ) - break; - - k = v[j]; - v[j] = v[jg]; - v[jg] = k; - } - } - - -/* dataend - finish up a block of data declarations - * - * synopsis - * dataend(); - */ - -void dataend(void) -{ - if ( datapos > 0 ) - dataflush(); - - /* add terminator for initialization */ - puts( " } ;\n" ); - - dataline = 0; - datapos = 0; - } - - - -/* dataflush - flush generated data statements - * - * synopsis - * dataflush(); - */ - -void dataflush(void) -{ - putchar( '\n' ); - - if ( ++dataline >= NUMDATALINES ) - { - /* put out a blank line so that the table is grouped into - * large blocks that enable the user to find elements easily - */ - putchar( '\n' ); - dataline = 0; - } - - /* reset the number of characters written on the current line */ - datapos = 0; - } - - -/* flexerror - report an error message and terminate - * - * synopsis - * char msg[]; - * flexerror( msg ); - */ - -void flexerror(char *msg) -{ - fprintf( stderr, "%s: %s\n", program_name, msg ); - - flexend( 1 ); - } - - -/* flexfatal - report a fatal error message and terminate - * - * synopsis - * char msg[]; - * flexfatal( msg ); - */ - -void flexfatal(char *msg) -{ - fprintf( stderr, "%s: fatal internal error, %s\n", program_name, msg ); - flexend( 1 ); - } - - -/* flex_gettime - return current time - * - * synopsis - * char *flex_gettime(), *time_str; - * time_str = flex_gettime(); - * - * note - * the routine name has the "flex_" prefix because of name clashes - * with Turbo-C - */ - -/* include sys/types.h to use time_t and make lint happy */ - -#ifndef MS_DOS -#include -#endif - -#ifdef MS_DOS -#include -typedef long time_t; -#endif - -char *flex_gettime(void) -{ - time_t t, time(time_t *); - char *result, *ctime(const time_t *), *copy_string(char *str); - - t = time( NULL ); - - result = copy_string( ctime( &t ) ); - - /* get rid of trailing newline */ - result[24] = '\0'; - - return ( result ); - } - - -/* lerrif - report an error message formatted with one integer argument - * - * synopsis - * char msg[]; - * int arg; - * lerrif( msg, arg ); - */ - -void lerrif(char *msg, int arg) -{ - char errmsg[MAXLINE]; - (void) sprintf( errmsg, msg, arg ); - flexerror( errmsg ); - } - - -/* lerrsf - report an error message formatted with one string argument - * - * synopsis - * char msg[], arg[]; - * lerrsf( msg, arg ); - */ - -void lerrsf(char *msg, char *arg) -{ - char errmsg[MAXLINE]; - - (void) sprintf( errmsg, msg, arg ); - flexerror( errmsg ); - } - - -/* htoi - convert a hexadecimal digit string to an integer value - * - * synopsis: - * int val, htoi(); - * Char str[]; - * val = htoi( str ); - */ - -int htoi(unsigned char *str) -{ - int result; - - (void) sscanf( (char *) str, "%x", &result ); - - return ( result ); - } - - -/* is_hex_digit - returns true if a character is a valid hex digit, false - * otherwise - * - * synopsis: - * int true_or_false, is_hex_digit(); - * int ch; - * val = is_hex_digit( ch ); - */ - -int is_hex_digit(int ch) -{ - if ( isdigit( ch ) ) - return ( 1 ); - - switch ( clower( ch ) ) - { - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - return ( 1 ); - - default: - return ( 0 ); - } - } - - -/* line_directive_out - spit out a "# line" statement */ - -void line_directive_out(FILE *output_file_name) -{ - if ( infilename && gen_line_dirs ) - fprintf( output_file_name, "# line %d \"%s\"\n", linenum, infilename ); - } - - -/* mk2data - generate a data statement for a two-dimensional array - * - * synopsis - * int value; - * mk2data( value ); - * - * generates a data statement initializing the current 2-D array to "value" - */ -void mk2data(int value) -{ - if ( datapos >= NUMDATAITEMS ) - { - putchar( ',' ); - dataflush(); - } - - if ( datapos == 0 ) - /* indent */ - fputs( " ", stdout ); - - else - putchar( ',' ); - - ++datapos; - - printf( "%5d", value ); - } - - -/* mkdata - generate a data statement - * - * synopsis - * int value; - * mkdata( value ); - * - * generates a data statement initializing the current array element to - * "value" - */ -void mkdata(int value) -{ - if ( datapos >= NUMDATAITEMS ) - { - putchar( ',' ); - dataflush(); - } - - if ( datapos == 0 ) - /* indent */ - fputs( " ", stdout ); - - else - putchar( ',' ); - - ++datapos; - - printf( "%5d", value ); - } - - -/* myctoi - return the integer represented by a string of digits - * - * synopsis - * Char array[]; - * int val, myctoi(); - * val = myctoi( array ); - * - */ - -int myctoi(Char *array) -{ - int val = 0; - - (void) sscanf( (char *) array, "%d", &val ); - - return ( val ); - } - - -/* myesc - return character corresponding to escape sequence - * - * synopsis - * Char array[], c, myesc(); - * c = myesc( array ); - * - */ - -Char myesc(Char *array) -{ - Char c, esc_char; - int sptr; - - switch ( array[1] ) - { - case 'a': return ( '\a' ); - case 'b': return ( '\b' ); - case 'f': return ( '\f' ); - case 'n': return ( '\n' ); - case 'r': return ( '\r' ); - case 't': return ( '\t' ); - case 'v': return ( '\v' ); - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { /* \ */ - sptr = 1; - - while ( isascii( array[sptr] ) && isdigit( array[sptr] ) ) - /* don't increment inside loop control because if - * isdigit() is a macro it might expand into multiple - * increments ... - */ - ++sptr; - - c = array[sptr]; - array[sptr] = '\0'; - - esc_char = otoi( array + 1 ); - - array[sptr] = c; - - return ( esc_char ); - } - - case 'x': - { /* \x */ - int sptr = 2; - - while ( isascii( array[sptr] ) && is_hex_digit( array[sptr] ) ) - /* don't increment inside loop control because if - * isdigit() is a macro it might expand into multiple - * increments ... - */ - ++sptr; - - c = array[sptr]; - array[sptr] = '\0'; - - esc_char = htoi( array + 2 ); - - array[sptr] = c; - - return ( esc_char ); - } - - default: - return ( array[1] ); - } - } - - -/* otoi - convert an octal digit string to an integer value - * - * synopsis: - * int val, otoi(); - * Char str[]; - * val = otoi( str ); - */ - -int otoi(Char *str) -{ - int result; - - (void) sscanf( (char *) str, "%o", &result ); - - return ( result ); - } - - -/* readable_form - return the the human-readable form of a character - * - * synopsis: - * int c; - * char *readable_form(); - * = readable_form( c ); - * - * The returned string is in static storage. - */ - -char *readable_form(int c) -{ - static char rform[10]; - - if ( (c >= 0 && c < 32) || c >= 127 ) - { - switch ( c ) - { - case '\n': return ( "\\n" ); - case '\t': return ( "\\t" ); - case '\f': return ( "\\f" ); - case '\r': return ( "\\r" ); - case '\b': return ( "\\b" ); - - default: - (void) sprintf( rform, "\\%.3o", c ); - return ( rform ); - } - } - - else if ( c == ' ' ) - return ( "' '" ); - - else - { - rform[0] = c; - rform[1] = '\0'; - - return ( rform ); - } - } - - -/* reallocate_array - increase the size of a dynamic array */ - -void *reallocate_array(void *array, int size, int element_size) -{ - void *new_array; - - /* same worry as in allocate_array(): */ - if ( size * element_size <= 0 ) - flexfatal( "attempt to increase array size by less than 1 byte" ); - - new_array = - (void *) realloc( (char *)array, (unsigned) (size * element_size )); - - if ( new_array == NULL ) - flexfatal( "attempt to increase array size failed" ); - - return ( new_array ); - } - - -/* skelout - write out one section of the skeleton file - * - * synopsis - * skelout(); - * - * DESCRIPTION - * Copies from skelfile to stdout until a line beginning with "%%" or - * EOF is found. - */ -void skelout(void) -{ - char buf[MAXLINE]; - - while ( fgets( buf, MAXLINE, skelfile ) != NULL ) - if ( buf[0] == '%' && buf[1] == '%' ) - break; - else - fputs( buf, stdout ); - } - - -/* transition_struct_out - output a yy_trans_info structure - * - * synopsis - * int element_v, element_n; - * transition_struct_out( element_v, element_n ); - * - * outputs the yy_trans_info structure with the two elements, element_v and - * element_n. Formats the output with spaces and carriage returns. - */ - -void transition_struct_out(int element_v, int element_n) -{ - printf( "%7d, %5d,", element_v, element_n ); - - datapos += TRANS_STRUCT_PRINT_LENGTH; - - if ( datapos >= 75 ) - { - putchar( '\n' ); - - if ( ++dataline % 10 == 0 ) - putchar( '\n' ); - - datapos = 0; - } - } diff --git a/src/libCom/flex/nfa.c b/src/libCom/flex/nfa.c deleted file mode 100644 index b57c6d646..000000000 --- a/src/libCom/flex/nfa.c +++ /dev/null @@ -1,689 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* nfa - NFA construction routines */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - - -/* declare functions that have forward references */ - -int dupmachine (int); -void mkxtion (int, int); - - -/* add_accept - add an accepting state to a machine - * - * synopsis - * - * add_accept( mach, accepting_number ); - * - * accepting_number becomes mach's accepting number. - */ - -void add_accept(int mach, int accepting_number) -{ - /* hang the accepting number off an epsilon state. if it is associated - * with a state that has a non-epsilon out-transition, then the state - * will accept BEFORE it makes that transition, i.e., one character - * too soon - */ - - if ( transchar[finalst[mach]] == SYM_EPSILON ) - accptnum[finalst[mach]] = accepting_number; - - else - { - int astate = mkstate( SYM_EPSILON ); - accptnum[astate] = accepting_number; - mach = link_machines( mach, astate ); - } - } - - -/* copysingl - make a given number of copies of a singleton machine - * - * synopsis - * - * newsng = copysingl( singl, num ); - * - * newsng - a new singleton composed of num copies of singl - * singl - a singleton machine - * num - the number of copies of singl to be present in newsng - */ - -int copysingl(int singl, int num) -{ - int copy, i; - - copy = mkstate( SYM_EPSILON ); - - for ( i = 1; i <= num; ++i ) - copy = link_machines( copy, dupmachine( singl ) ); - - return ( copy ); - } - - -/* dumpnfa - debugging routine to write out an nfa - * - * synopsis - * int state1; - * dumpnfa( state1 ); - */ - -void dumpnfa(int state1) -{ - int sym, tsp1, tsp2, anum, ns; - - fprintf( stderr, "\n\n********** beginning dump of nfa with start state %d\n", - state1 ); - - /* we probably should loop starting at firstst[state1] and going to - * lastst[state1], but they're not maintained properly when we "or" - * all of the rules together. So we use our knowledge that the machine - * starts at state 1 and ends at lastnfa. - */ - - /* for ( ns = firstst[state1]; ns <= lastst[state1]; ++ns ) */ - for ( ns = 1; ns <= lastnfa; ++ns ) - { - fprintf( stderr, "state # %4d\t", ns ); - - sym = transchar[ns]; - tsp1 = trans1[ns]; - tsp2 = trans2[ns]; - anum = accptnum[ns]; - - fprintf( stderr, "%3d: %4d, %4d", sym, tsp1, tsp2 ); - - if ( anum != NIL ) - fprintf( stderr, " [%d]", anum ); - - fprintf( stderr, "\n" ); - } - - fprintf( stderr, "********** end of dump\n" ); - } - - -/* dupmachine - make a duplicate of a given machine - * - * synopsis - * - * copy = dupmachine( mach ); - * - * copy - holds duplicate of mach - * mach - machine to be duplicated - * - * note that the copy of mach is NOT an exact duplicate; rather, all the - * transition states values are adjusted so that the copy is self-contained, - * as the original should have been. - * - * also note that the original MUST be contiguous, with its low and high - * states accessible by the arrays firstst and lastst - */ - -int dupmachine(int mach) -{ - int i, init, state_offset; - int state = 0; - int last = lastst[mach]; - - for ( i = firstst[mach]; i <= last; ++i ) - { - state = mkstate( transchar[i] ); - - if ( trans1[i] != NO_TRANSITION ) - { - mkxtion( finalst[state], trans1[i] + state - i ); - - if ( transchar[i] == SYM_EPSILON && trans2[i] != NO_TRANSITION ) - mkxtion( finalst[state], trans2[i] + state - i ); - } - - accptnum[state] = accptnum[i]; - } - - if ( state == 0 ) - flexfatal( "empty machine in dupmachine()" ); - - state_offset = state - i + 1; - - init = mach + state_offset; - firstst[init] = firstst[mach] + state_offset; - finalst[init] = finalst[mach] + state_offset; - lastst[init] = lastst[mach] + state_offset; - - return ( init ); - } - - -/* finish_rule - finish up the processing for a rule - * - * synopsis - * - * finish_rule( mach, variable_trail_rule, headcnt, trailcnt ); - * - * An accepting number is added to the given machine. If variable_trail_rule - * is true then the rule has trailing context and both the head and trail - * are variable size. Otherwise if headcnt or trailcnt is non-zero then - * the machine recognizes a pattern with trailing context and headcnt is - * the number of characters in the matched part of the pattern, or zero - * if the matched part has variable length. trailcnt is the number of - * trailing context characters in the pattern, or zero if the trailing - * context has variable length. - */ - -void finish_rule(int mach, int variable_trail_rule, int headcnt, int trailcnt) -{ - add_accept( mach, num_rules ); - - /* we did this in new_rule(), but it often gets the wrong - * number because we do it before we start parsing the current rule - */ - rule_linenum[num_rules] = linenum; - - /* if this is a continued action, then the line-number has - * already been updated, giving us the wrong number - */ - if ( continued_action ) - --rule_linenum[num_rules]; - - fprintf( temp_action_file, "case %d:\n", num_rules ); - - if ( variable_trail_rule ) - { - rule_type[num_rules] = RULE_VARIABLE; - - if ( performance_report ) - fprintf( stderr, "Variable trailing context rule at line %d\n", - rule_linenum[num_rules] ); - - variable_trailing_context_rules = true; - } - - else - { - rule_type[num_rules] = RULE_NORMAL; - - if ( headcnt > 0 || trailcnt > 0 ) - { - /* do trailing context magic to not match the trailing characters */ - char *scanner_cp = "yy_c_buf_p = yy_cp"; - char *scanner_bp = "yy_bp"; - - fprintf( temp_action_file, - "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */\n" ); - - if ( headcnt > 0 ) - fprintf( temp_action_file, "%s = %s + %d;\n", - scanner_cp, scanner_bp, headcnt ); - - else - fprintf( temp_action_file, - "%s -= %d;\n", scanner_cp, trailcnt ); - - fprintf( temp_action_file, - "YY_DO_BEFORE_ACTION; /* set up yytext again */\n" ); - } - } - - line_directive_out( temp_action_file ); - } - - -/* link_machines - connect two machines together - * - * synopsis - * - * new = link_machines( first, last ); - * - * new - a machine constructed by connecting first to last - * first - the machine whose successor is to be last - * last - the machine whose predecessor is to be first - * - * note: this routine concatenates the machine first with the machine - * last to produce a machine new which will pattern-match first first - * and then last, and will fail if either of the sub-patterns fails. - * FIRST is set to new by the operation. last is unmolested. - */ - -int link_machines(int first, int last) -{ - if ( first == NIL ) - return ( last ); - - else if ( last == NIL ) - return ( first ); - - else - { - mkxtion( finalst[first], last ); - finalst[first] = finalst[last]; - lastst[first] = max( lastst[first], lastst[last] ); - firstst[first] = min( firstst[first], firstst[last] ); - - return ( first ); - } - } - - -/* mark_beginning_as_normal - mark each "beginning" state in a machine - * as being a "normal" (i.e., not trailing context- - * associated) states - * - * synopsis - * - * mark_beginning_as_normal( mach ) - * - * mach - machine to mark - * - * The "beginning" states are the epsilon closure of the first state - */ - -void mark_beginning_as_normal(int mach) -{ - switch ( state_type[mach] ) - { - case STATE_NORMAL: - /* oh, we've already visited here */ - return; - - case STATE_TRAILING_CONTEXT: - state_type[mach] = STATE_NORMAL; - - if ( transchar[mach] == SYM_EPSILON ) - { - if ( trans1[mach] != NO_TRANSITION ) - mark_beginning_as_normal( trans1[mach] ); - - if ( trans2[mach] != NO_TRANSITION ) - mark_beginning_as_normal( trans2[mach] ); - } - break; - - default: - flexerror( "bad state type in mark_beginning_as_normal()" ); - break; - } - } - - -/* mkbranch - make a machine that branches to two machines - * - * synopsis - * - * branch = mkbranch( first, second ); - * - * branch - a machine which matches either first's pattern or second's - * first, second - machines whose patterns are to be or'ed (the | operator) - * - * note that first and second are NEITHER destroyed by the operation. Also, - * the resulting machine CANNOT be used with any other "mk" operation except - * more mkbranch's. Compare with mkor() - */ - -int mkbranch(int first, int second) -{ - int eps; - - if ( first == NO_TRANSITION ) - return ( second ); - - else if ( second == NO_TRANSITION ) - return ( first ); - - eps = mkstate( SYM_EPSILON ); - - mkxtion( eps, first ); - mkxtion( eps, second ); - - return ( eps ); - } - - -/* mkclos - convert a machine into a closure - * - * synopsis - * new = mkclos( state ); - * - * new - a new state which matches the closure of "state" - */ - -int mkclos(int state) -{ - return ( mkopt( mkposcl( state ) ) ); - } - - -/* mkopt - make a machine optional - * - * synopsis - * - * new = mkopt( mach ); - * - * new - a machine which optionally matches whatever mach matched - * mach - the machine to make optional - * - * notes: - * 1. mach must be the last machine created - * 2. mach is destroyed by the call - */ - -int mkopt(int mach) -{ - int eps; - - if ( ! SUPER_FREE_EPSILON(finalst[mach]) ) - { - eps = mkstate( SYM_EPSILON ); - mach = link_machines( mach, eps ); - } - - /* can't skimp on the following if FREE_EPSILON(mach) is true because - * some state interior to "mach" might point back to the beginning - * for a closure - */ - eps = mkstate( SYM_EPSILON ); - mach = link_machines( eps, mach ); - - mkxtion( mach, finalst[mach] ); - - return ( mach ); - } - - -/* mkor - make a machine that matches either one of two machines - * - * synopsis - * - * new = mkor( first, second ); - * - * new - a machine which matches either first's pattern or second's - * first, second - machines whose patterns are to be or'ed (the | operator) - * - * note that first and second are both destroyed by the operation - * the code is rather convoluted because an attempt is made to minimize - * the number of epsilon states needed - */ - -int mkor(int first, int second) -{ - int eps, orend; - - if ( first == NIL ) - return ( second ); - - else if ( second == NIL ) - return ( first ); - - else - { - /* see comment in mkopt() about why we can't use the first state - * of "first" or "second" if they satisfy "FREE_EPSILON" - */ - eps = mkstate( SYM_EPSILON ); - - first = link_machines( eps, first ); - - mkxtion( first, second ); - - if ( SUPER_FREE_EPSILON(finalst[first]) && - accptnum[finalst[first]] == NIL ) - { - orend = finalst[first]; - mkxtion( finalst[second], orend ); - } - - else if ( SUPER_FREE_EPSILON(finalst[second]) && - accptnum[finalst[second]] == NIL ) - { - orend = finalst[second]; - mkxtion( finalst[first], orend ); - } - - else - { - eps = mkstate( SYM_EPSILON ); - - first = link_machines( first, eps ); - orend = finalst[first]; - - mkxtion( finalst[second], orend ); - } - } - - finalst[first] = orend; - return ( first ); - } - - -/* mkposcl - convert a machine into a positive closure - * - * synopsis - * new = mkposcl( state ); - * - * new - a machine matching the positive closure of "state" - */ - -int mkposcl(int state) -{ - int eps; - - if ( SUPER_FREE_EPSILON(finalst[state]) ) - { - mkxtion( finalst[state], state ); - return ( state ); - } - - else - { - eps = mkstate( SYM_EPSILON ); - mkxtion( eps, state ); - return ( link_machines( state, eps ) ); - } - } - - -/* mkrep - make a replicated machine - * - * synopsis - * new = mkrep( mach, lb, ub ); - * - * new - a machine that matches whatever "mach" matched from "lb" - * number of times to "ub" number of times - * - * note - * if "ub" is INFINITY then "new" matches "lb" or more occurrences of "mach" - */ - -int mkrep(int mach, int lb, int ub) -{ - int base_mach, tail, copy, i; - - base_mach = copysingl( mach, lb - 1 ); - - if ( ub == INFINITY ) - { - copy = dupmachine( mach ); - mach = link_machines( mach, - link_machines( base_mach, mkclos( copy ) ) ); - } - - else - { - tail = mkstate( SYM_EPSILON ); - - for ( i = lb; i < ub; ++i ) - { - copy = dupmachine( mach ); - tail = mkopt( link_machines( copy, tail ) ); - } - - mach = link_machines( mach, link_machines( base_mach, tail ) ); - } - - return ( mach ); - } - - -/* mkstate - create a state with a transition on a given symbol - * - * synopsis - * - * state = mkstate( sym ); - * - * state - a new state matching sym - * sym - the symbol the new state is to have an out-transition on - * - * note that this routine makes new states in ascending order through the - * state array (and increments LASTNFA accordingly). The routine DUPMACHINE - * relies on machines being made in ascending order and that they are - * CONTIGUOUS. Change it and you will have to rewrite DUPMACHINE (kludge - * that it admittedly is) - */ - -int mkstate(int sym) -{ - if ( ++lastnfa >= current_mns ) - { - if ( (current_mns += MNS_INCREMENT) >= MAXIMUM_MNS ) - lerrif( "input rules are too complicated (>= %d NFA states)", - current_mns ); - - ++num_reallocs; - - firstst = reallocate_integer_array( firstst, current_mns ); - lastst = reallocate_integer_array( lastst, current_mns ); - finalst = reallocate_integer_array( finalst, current_mns ); - transchar = reallocate_integer_array( transchar, current_mns ); - trans1 = reallocate_integer_array( trans1, current_mns ); - trans2 = reallocate_integer_array( trans2, current_mns ); - accptnum = reallocate_integer_array( accptnum, current_mns ); - assoc_rule = reallocate_integer_array( assoc_rule, current_mns ); - state_type = reallocate_integer_array( state_type, current_mns ); - } - - firstst[lastnfa] = lastnfa; - finalst[lastnfa] = lastnfa; - lastst[lastnfa] = lastnfa; - transchar[lastnfa] = sym; - trans1[lastnfa] = NO_TRANSITION; - trans2[lastnfa] = NO_TRANSITION; - accptnum[lastnfa] = NIL; - assoc_rule[lastnfa] = num_rules; - state_type[lastnfa] = current_state_type; - - /* fix up equivalence classes base on this transition. Note that any - * character which has its own transition gets its own equivalence class. - * Thus only characters which are only in character classes have a chance - * at being in the same equivalence class. E.g. "a|b" puts 'a' and 'b' - * into two different equivalence classes. "[ab]" puts them in the same - * equivalence class (barring other differences elsewhere in the input). - */ - - if ( sym < 0 ) - { - /* we don't have to update the equivalence classes since that was - * already done when the ccl was created for the first time - */ - } - - else if ( sym == SYM_EPSILON ) - ++numeps; - - else - { - if ( useecs ) - /* map NUL's to csize */ - mkechar( sym ? sym : csize, nextecm, ecgroup ); - } - - return ( lastnfa ); - } - - -/* mkxtion - make a transition from one state to another - * - * synopsis - * - * mkxtion( statefrom, stateto ); - * - * statefrom - the state from which the transition is to be made - * stateto - the state to which the transition is to be made - */ - -void mkxtion(int statefrom, int stateto) -{ - if ( trans1[statefrom] == NO_TRANSITION ) - trans1[statefrom] = stateto; - - else if ( (transchar[statefrom] != SYM_EPSILON) || - (trans2[statefrom] != NO_TRANSITION) ) - flexfatal( "found too many transitions in mkxtion()" ); - - else - { /* second out-transition for an epsilon state */ - ++eps2; - trans2[statefrom] = stateto; - } - } - -/* new_rule - initialize for a new rule - * - * synopsis - * - * new_rule(); - * - * the global num_rules is incremented and the any corresponding dynamic - * arrays (such as rule_type[]) are grown as needed. - */ - -void new_rule(void) -{ - if ( ++num_rules >= current_max_rules ) - { - ++num_reallocs; - current_max_rules += MAX_RULES_INCREMENT; - rule_type = reallocate_integer_array( rule_type, current_max_rules ); - rule_linenum = - reallocate_integer_array( rule_linenum, current_max_rules ); - } - - if ( num_rules > MAX_RULE ) - lerrif( "too many rules (> %d)!", MAX_RULE ); - - rule_linenum[num_rules] = linenum; - } diff --git a/src/libCom/flex/parse.y b/src/libCom/flex/parse.y deleted file mode 100644 index dff931578..000000000 --- a/src/libCom/flex/parse.y +++ /dev/null @@ -1,702 +0,0 @@ - -/* parse.y - parser for flex input */ - -%token CHAR NUMBER SECTEND SCDECL XSCDECL WHITESPACE NAME PREVCCL EOF_OP - -%{ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - -int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen; -int trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule; -Char clower(); - -static int madeany = false; /* whether we've made the '.' character class */ -int previous_continued_action; /* whether the previous rule's action was '|' */ - -%} - -%% -goal : initlex sect1 sect1end sect2 initforrule - { /* add default rule */ - int def_rule; - - pat = cclinit(); - cclnegate( pat ); - - def_rule = mkstate( -pat ); - - finish_rule( def_rule, false, 0, 0 ); - - for ( i = 1; i <= lastsc; ++i ) - scset[i] = mkbranch( scset[i], def_rule ); - - if ( spprdflt ) - fputs( "YY_FATAL_ERROR( \"flex scanner jammed\" )", - temp_action_file ); - else - fputs( "ECHO", temp_action_file ); - - fputs( ";\n\tYY_BREAK\n", temp_action_file ); - } - ; - -initlex : - { - /* initialize for processing rules */ - - /* create default DFA start condition */ - scinstal( "INITIAL", false ); - } - ; - -sect1 : sect1 startconddecl WHITESPACE namelist1 '\n' - | - | error '\n' - { synerr( "unknown error processing section 1" ); } - ; - -sect1end : SECTEND - ; - -startconddecl : SCDECL - { - /* these productions are separate from the s1object - * rule because the semantics must be done before - * we parse the remainder of an s1object - */ - - xcluflg = false; - } - - | XSCDECL - { xcluflg = true; } - ; - -namelist1 : namelist1 WHITESPACE NAME - { scinstal( nmstr, xcluflg ); } - - | NAME - { scinstal( nmstr, xcluflg ); } - - | error - { synerr( "bad start condition list" ); } - ; - -sect2 : sect2 initforrule flexrule '\n' - | - ; - -initforrule : - { - /* initialize for a parse of one rule */ - trlcontxt = variable_trail_rule = varlength = false; - trailcnt = headcnt = rulelen = 0; - current_state_type = STATE_NORMAL; - previous_continued_action = continued_action; - new_rule(); - } - ; - -flexrule : scon '^' rule - { - pat = $3; - finish_rule( pat, variable_trail_rule, - headcnt, trailcnt ); - - for ( i = 1; i <= actvp; ++i ) - scbol[actvsc[i]] = - mkbranch( scbol[actvsc[i]], pat ); - - if ( ! bol_needed ) - { - bol_needed = true; - - if ( performance_report ) - pinpoint_message( - "'^' operator results in sub-optimal performance" ); - } - } - - | scon rule - { - pat = $2; - finish_rule( pat, variable_trail_rule, - headcnt, trailcnt ); - - for ( i = 1; i <= actvp; ++i ) - scset[actvsc[i]] = - mkbranch( scset[actvsc[i]], pat ); - } - - | '^' rule - { - pat = $2; - finish_rule( pat, variable_trail_rule, - headcnt, trailcnt ); - - /* add to all non-exclusive start conditions, - * including the default (0) start condition - */ - - for ( i = 1; i <= lastsc; ++i ) - if ( ! scxclu[i] ) - scbol[i] = mkbranch( scbol[i], pat ); - - if ( ! bol_needed ) - { - bol_needed = true; - - if ( performance_report ) - pinpoint_message( - "'^' operator results in sub-optimal performance" ); - } - } - - | rule - { - pat = $1; - finish_rule( pat, variable_trail_rule, - headcnt, trailcnt ); - - for ( i = 1; i <= lastsc; ++i ) - if ( ! scxclu[i] ) - scset[i] = mkbranch( scset[i], pat ); - } - - | scon EOF_OP - { build_eof_action(); } - - | EOF_OP - { - /* this EOF applies to all start conditions - * which don't already have EOF actions - */ - actvp = 0; - - for ( i = 1; i <= lastsc; ++i ) - if ( ! sceof[i] ) - actvsc[++actvp] = i; - - if ( actvp == 0 ) - pinpoint_message( - "warning - all start conditions already have <> rules" ); - - else - build_eof_action(); - } - - | error - { synerr( "unrecognized rule" ); } - ; - -scon : '<' namelist2 '>' - ; - -namelist2 : namelist2 ',' NAME - { - if ( (scnum = sclookup( nmstr )) == 0 ) - format_pinpoint_message( - "undeclared start condition %s", nmstr ); - - else - actvsc[++actvp] = scnum; - } - - | NAME - { - if ( (scnum = sclookup( nmstr )) == 0 ) - format_pinpoint_message( - "undeclared start condition %s", nmstr ); - else - actvsc[actvp = 1] = scnum; - } - - | error - { synerr( "bad start condition list" ); } - ; - -rule : re2 re - { - if ( transchar[lastst[$2]] != SYM_EPSILON ) - /* provide final transition \now/ so it - * will be marked as a trailing context - * state - */ - $2 = link_machines( $2, mkstate( SYM_EPSILON ) ); - - mark_beginning_as_normal( $2 ); - current_state_type = STATE_NORMAL; - - if ( previous_continued_action ) - { - /* we need to treat this as variable trailing - * context so that the backup does not happen - * in the action but before the action switch - * statement. If the backup happens in the - * action, then the rules "falling into" this - * one's action will *also* do the backup, - * erroneously. - */ - if ( ! varlength || headcnt != 0 ) - { - fprintf( stderr, - "%s: warning - trailing context rule at line %d made variable because\n", - program_name, linenum ); - fprintf( stderr, - " of preceding '|' action\n" ); - } - - /* mark as variable */ - varlength = true; - headcnt = 0; - } - - if ( varlength && headcnt == 0 ) - { /* variable trailing context rule */ - /* mark the first part of the rule as the accepting - * "head" part of a trailing context rule - */ - /* by the way, we didn't do this at the beginning - * of this production because back then - * current_state_type was set up for a trail - * rule, and add_accept() can create a new - * state ... - */ - add_accept( $1, num_rules | YY_TRAILING_HEAD_MASK ); - variable_trail_rule = true; - } - - else - trailcnt = rulelen; - - $$ = link_machines( $1, $2 ); - } - - | re2 re '$' - { synerr( "trailing context used twice" ); } - - | re '$' - { - if ( trlcontxt ) - { - synerr( "trailing context used twice" ); - $$ = mkstate( SYM_EPSILON ); - } - - else if ( previous_continued_action ) - { - /* see the comment in the rule for "re2 re" - * above - */ - if ( ! varlength || headcnt != 0 ) - { - fprintf( stderr, - "%s: warning - trailing context rule at line %d made variable because\n", - program_name, linenum ); - fprintf( stderr, - " of preceding '|' action\n" ); - } - - /* mark as variable */ - varlength = true; - headcnt = 0; - } - - trlcontxt = true; - - if ( ! varlength ) - headcnt = rulelen; - - ++rulelen; - trailcnt = 1; - - eps = mkstate( SYM_EPSILON ); - $$ = link_machines( $1, - link_machines( eps, mkstate( '\n' ) ) ); - } - - | re - { - $$ = $1; - - if ( trlcontxt ) - { - if ( varlength && headcnt == 0 ) - /* both head and trail are variable-length */ - variable_trail_rule = true; - else - trailcnt = rulelen; - } - } - ; - - -re : re '|' series - { - varlength = true; - $$ = mkor( $1, $3 ); - } - - | series - { $$ = $1; } - ; - - -re2 : re '/' - { - /* this rule is written separately so - * the reduction will occur before the trailing - * series is parsed - */ - - if ( trlcontxt ) - synerr( "trailing context used twice" ); - else - trlcontxt = true; - - if ( varlength ) - /* we hope the trailing context is fixed-length */ - varlength = false; - else - headcnt = rulelen; - - rulelen = 0; - - current_state_type = STATE_TRAILING_CONTEXT; - $$ = $1; - } - ; - -series : series singleton - { - /* this is where concatenation of adjacent patterns - * gets done - */ - $$ = link_machines( $1, $2 ); - } - - | singleton - { $$ = $1; } - ; - -singleton : singleton '*' - { - varlength = true; - - $$ = mkclos( $1 ); - } - - | singleton '+' - { - varlength = true; - - $$ = mkposcl( $1 ); - } - - | singleton '?' - { - varlength = true; - - $$ = mkopt( $1 ); - } - - | singleton '{' NUMBER ',' NUMBER '}' - { - varlength = true; - - if ( $3 > $5 || $3 < 0 ) - { - synerr( "bad iteration values" ); - $$ = $1; - } - else - { - if ( $3 == 0 ) - $$ = mkopt( mkrep( $1, $3, $5 ) ); - else - $$ = mkrep( $1, $3, $5 ); - } - } - - | singleton '{' NUMBER ',' '}' - { - varlength = true; - - if ( $3 <= 0 ) - { - synerr( "iteration value must be positive" ); - $$ = $1; - } - - else - $$ = mkrep( $1, $3, INFINITY ); - } - - | singleton '{' NUMBER '}' - { - /* the singleton could be something like "(foo)", - * in which case we have no idea what its length - * is, so we punt here. - */ - varlength = true; - - if ( $3 <= 0 ) - { - synerr( "iteration value must be positive" ); - $$ = $1; - } - - else - $$ = link_machines( $1, copysingl( $1, $3 - 1 ) ); - } - - | '.' - { - if ( ! madeany ) - { - /* create the '.' character class */ - anyccl = cclinit(); - ccladd( anyccl, '\n' ); - cclnegate( anyccl ); - - if ( useecs ) - mkeccl( ccltbl + cclmap[anyccl], - ccllen[anyccl], nextecm, - ecgroup, csize, csize ); - - madeany = true; - } - - ++rulelen; - - $$ = mkstate( -anyccl ); - } - - | fullccl - { - if ( ! cclsorted ) - /* sort characters for fast searching. We use a - * shell sort since this list could be large. - */ - cshell( ccltbl + cclmap[$1], ccllen[$1], true ); - - if ( useecs ) - mkeccl( ccltbl + cclmap[$1], ccllen[$1], - nextecm, ecgroup, csize, csize ); - - ++rulelen; - - $$ = mkstate( -$1 ); - } - - | PREVCCL - { - ++rulelen; - - $$ = mkstate( -$1 ); - } - - | '"' string '"' - { $$ = $2; } - - | '(' re ')' - { $$ = $2; } - - | CHAR - { - ++rulelen; - - if ( caseins && $1 >= 'A' && $1 <= 'Z' ) - $1 = clower( $1 ); - - $$ = mkstate( $1 ); - } - ; - -fullccl : '[' ccl ']' - { $$ = $2; } - - | '[' '^' ccl ']' - { - /* *Sigh* - to be compatible Unix lex, negated ccls - * match newlines - */ -#ifdef NOTDEF - ccladd( $3, '\n' ); /* negated ccls don't match '\n' */ - cclsorted = false; /* because we added the newline */ -#endif - cclnegate( $3 ); - $$ = $3; - } - ; - -ccl : ccl CHAR '-' CHAR - { - if ( $2 > $4 ) - synerr( "negative range in character class" ); - - else - { - if ( caseins ) - { - if ( $2 >= 'A' && $2 <= 'Z' ) - $2 = clower( $2 ); - if ( $4 >= 'A' && $4 <= 'Z' ) - $4 = clower( $4 ); - } - - for ( i = $2; i <= $4; ++i ) - ccladd( $1, i ); - - /* keep track if this ccl is staying in alphabetical - * order - */ - cclsorted = cclsorted && ($2 > lastchar); - lastchar = $4; - } - - $$ = $1; - } - - | ccl CHAR - { - if ( caseins ) - if ( $2 >= 'A' && $2 <= 'Z' ) - $2 = clower( $2 ); - - ccladd( $1, $2 ); - cclsorted = cclsorted && ($2 > lastchar); - lastchar = $2; - $$ = $1; - } - - | - { - cclsorted = true; - lastchar = 0; - $$ = cclinit(); - } - ; - -string : string CHAR - { - if ( caseins ) - if ( $2 >= 'A' && $2 <= 'Z' ) - $2 = clower( $2 ); - - ++rulelen; - - $$ = link_machines( $1, mkstate( $2 ) ); - } - - | - { $$ = mkstate( SYM_EPSILON ); } - ; - -%% - - -/* build_eof_action - build the "<>" action for the active start - * conditions - */ - -void build_eof_action() - - { - int i; - - for ( i = 1; i <= actvp; ++i ) - { - if ( sceof[actvsc[i]] ) - format_pinpoint_message( - "multiple <> rules for start condition %s", - scname[actvsc[i]] ); - - else - { - sceof[actvsc[i]] = true; - fprintf( temp_action_file, "case YY_STATE_EOF(%s):\n", - scname[actvsc[i]] ); - } - } - - line_directive_out( temp_action_file ); - } - - -/* synerr - report a syntax error */ - -void synerr( str ) -char str[]; - - { - syntaxerror = true; - pinpoint_message( str ); - } - - -/* format_pinpoint_message - write out a message formatted with one string, - * pinpointing its location - */ - -void format_pinpoint_message( msg, arg ) -char msg[], arg[]; - - { - char errmsg[MAXLINE]; - - (void) sprintf( errmsg, msg, arg ); - pinpoint_message( errmsg ); - } - - -/* pinpoint_message - write out a message, pinpointing its location */ - -void pinpoint_message( str ) -char str[]; - - { - fprintf( stderr, "\"%s\", line %d: %s\n", infilename, linenum, str ); - } - - -/* yyerror - eat up an error message from the parser; - * currently, messages are ignore - */ - -void yyerror( msg ) -char msg[]; - - { - } - -#include "scan.c" -#include "yylex.c" -#include "flex.c" - diff --git a/src/libCom/flex/scan.c b/src/libCom/flex/scan.c deleted file mode 100644 index a12c020bf..000000000 --- a/src/libCom/flex/scan.c +++ /dev/null @@ -1,2251 +0,0 @@ -/* A lexical scanner generated by flex */ - -/* scanner skeleton */ - -#define FLEX_SCANNER - -#include - - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - - -#ifdef __cplusplus - -#include -#include - -#else /* ! __cplusplus */ -#ifdef __GNUC__ -#include -void *malloc( size_t ); -void free( void* ); -#else -#include -#endif /* __GNUC__ */ - -#endif /* ! __cplusplus */ - - -/* amount of stuff to slurp up with each read */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* returned upon end-of-file */ -#define YY_END_TOK 0 - -/* copy whatever the last rule matched to the standard output */ - -/* cast to (char *) is because for 8-bit chars, yytext is (unsigned char *) */ -/* this used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite() - */ -#define ECHO (void) fwrite( (char *) yytext, yyleng, 1, yyout ) - -/* gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#define YY_INPUT(buf,result,max_size) \ - if ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \ - YY_FATAL_ERROR( "read() in flex scanner failed" ); -#define YY_NULL 0 - -/* no semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#define yyterminate() return ( YY_NULL ) - -/* report a fatal error */ - -/* The funky do-while is used to turn this macro definition into - * a single C statement (which needs a semi-colon terminator). - * This avoids problems with code like: - * - * if ( something_happens ) - * YY_FATAL_ERROR( "oops, the something happened" ); - * else - * everything_okay(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the YY_FATAL_ERROR() call. - */ - -#define YY_FATAL_ERROR(msg) \ - do \ - { \ - (void) fputs( msg, stderr ); \ - (void) putc( '\n', stderr ); \ - exit( 1 ); \ - } \ - while ( 0 ) - -/* default yywrap function - always treat EOF as an EOF */ -#define yywrap() 1 - -/* enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN - */ -#define BEGIN yy_start = 1 + 2 * - -/* action number for EOF rule of a given start state */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* special action meaning "start processing a new file" */ -#define YY_NEW_FILE \ - do \ - { \ - yy_init_buffer( yy_current_buffer, yyin ); \ - yy_load_buffer_state(); \ - } \ - while ( 0 ) - -/* default declaration of generated scanner - a define so the user can - * easily add parameters - */ -#define YY_DECL int yylex ( void ) - -/* code executed at the end of each rule */ -#define YY_BREAK break; - -#define YY_END_OF_BUFFER_CHAR 0 - -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of default input buffer */ -#endif - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -#define YY_CHAR unsigned char -# line 1 "scan.l" -#define INITIAL 0 -/* scan.l - scanner for flex input */ -# line 5 "scan.l" -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#undef yywrap - -#define ACTION_ECHO fprintf( temp_action_file, "%s", yytext ) -#define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" ); - -#undef YY_DECL -#define YY_DECL \ - int flexscan() - -#define RETURNCHAR \ - yylval = yytext[0]; \ - return ( CHAR ); - -#define RETURNNAME \ - (void) strcpy( nmstr, (char *) yytext ); \ - return ( NAME ); - -#define PUT_BACK_STRING(str, start) \ - for ( i = strlen( (char *) (str) ) - 1; i >= start; --i ) \ - unput((str)[i]) - -#define CHECK_REJECT(str) \ - if ( all_upper( str ) ) \ - reject = true; - -#define CHECK_YYMORE(str) \ - if ( all_lower( str ) ) \ - yymore_used = true; -#define SECT2 1 -#define SECT2PROLOG 2 -#define SECT3 3 -#define CODEBLOCK 4 -#define PICKUPDEF 5 -#define SC 6 -#define CARETISBOL 7 -#define NUM 8 -#define QUOTE 9 -#define FIRSTCCL 10 -#define CCL 11 -#define ACTION 12 -#define RECOVER 13 -#define BRACEERROR 14 -#define C_COMMENT 15 -#define ACTION_COMMENT 16 -#define ACTION_STRING 17 -#define PERCENT_BRACE_ACTION 18 -#define USED_LIST 19 -#define CODEBLOCK_2 20 -#define XLATION 21 -# line 76 "scan.l" - -/* done after the current pattern has been matched and before the - * corresponding action - sets up yytext - */ -#define YY_DO_BEFORE_ACTION \ - yytext = yy_bp; \ - yyleng = yy_cp - yy_bp; \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* return all but the first 'n' matched characters back to the input stream */ -#define yyless(n) \ - do \ - { \ - /* undo effects of setting up yytext */ \ - *yy_cp = yy_hold_char; \ - yy_c_buf_p = yy_cp = yy_bp + n; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext ) - - -struct yy_buffer_state - { - FILE *yy_input_file; - - YY_CHAR *yy_ch_buf; /* input buffer */ - YY_CHAR *yy_buf_pos; /* current position in input buffer */ - - /* size of input buffer in bytes, not including room for EOB characters*/ - int yy_buf_size; - - /* number of characters read into yy_ch_buf, not including EOB characters */ - int yy_n_chars; - - int yy_eof_status; /* whether we've seen an EOF on this buffer */ -#define EOF_NOT_SEEN 0 - /* "pending" happens when the EOF has been seen but there's still - * some text process - */ -#define EOF_PENDING 1 -#define EOF_DONE 2 - }; - -static YY_BUFFER_STATE yy_current_buffer; - -/* we provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state" - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - -/* yy_hold_char holds the character lost when yytext is formed */ -static YY_CHAR yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - - -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -#ifndef YY_USER_INIT -#define YY_USER_INIT -#endif - -extern YY_CHAR *yytext; -extern int yyleng; -extern FILE *yyin, *yyout; - -YY_CHAR *yytext; -int yyleng; - -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; - -#define YY_END_OF_BUFFER 121 -typedef int yy_state_type; -static const short int yy_acclist[482] = - { 0, - 16444,16444, 119, 119, 121, 19, 120, 7, 19, 120, - 18, 120, 19, 120, 19, 120, 16, 19, 120, 1, - 7, 19, 120, 17, 18, 120, 19, 120, 19, 120, - 19, 120, 19, 120, 15, 16, 19, 120, 67, 120, - 59, 67, 120,16444, 8252, 68, 120, 67, 120, 53, - 67, 120, 67, 120, 66, 67, 120, 51, 67, 120, - 67, 120, 67, 120, 67, 120, 50, 59, 67, 120, - 16444, 49, 8252, 61, 68, 120, 67, 120, 67, 120, - 52, 67, 120, 120, 47, 120, 120, 119, 120, 119, - 120, 119, 120, 28, 120, 29, 120, 28, 120, 28, - - 120, 28, 120, 28, 120, 28, 120, 31, 120, 30, - 120, 32, 120, 120, 73, 120, 120, 69, 73, 120, - 70, 73, 120, 72, 73, 120, 74, 120, 88, 120, - 89, 120, 88, 120, 86, 88, 120, 85, 88, 120, - 87, 88, 120, 75, 120, 77, 120, 120, 76, 120, - 75, 120, 81, 120, 80, 81, 120, 81, 120, 81, - 120, 83, 120, 83, 120, 83, 120, 84, 120, 99, - 105, 120, 104, 120, 105, 120, 103, 105, 120, 105, - 120, 105, 120, 100, 105, 120, 100, 105, 120, 100, - 105, 120, 97, 105, 120, 98, 105, 120, 120, 33, - - 120, 120, 91, 120, 120, 90, 120, 22, 120, 24, - 120, 120, 23, 120, 107, 110, 120, 109, 120, 110, - 120, 108, 110, 120, 111, 115, 120, 113, 120, 115, - 120, 114, 115, 120, 115, 120, 95, 120, 95, 120, - 96, 120, 95, 120, 95, 120, 95, 120, 95, 120, - 95, 120, 38, 120, 35, 120, 34, 120, 120, 38, - 120, 38, 120, 44, 120, 42, 44, 120, 45, 120, - 44, 120, 44, 120, 44, 120, 41, 44, 120, 41, - 42, 44, 120, 41, 44, 120, 41, 44, 120, 40, - 41, 44, 120, 41, 44, 120, 7, 18, 16, 1, - - 7, 17, 18, 2, 14, 8, 14, 12, 4, 5, - 3, 15, 16, 59,16444, 8252, 8252, 68, 56, 117, - 117, 117, 55, 54, 55, 50, 59,16444, 49, 8252, - 61, 49, 8252, 61, 68, 63, 50, 47, 46, 119, - 119, 119, 28, 29, 28, 28, 28, 28, 31, 30, - 32, 71, 72, 89, 85, 77, 118, 118, 118, 78, - 79, 82, 99, 104, 102, 101, 100, 100, 100, 33, - 91, 22, 24, 20, 107, 109, 106, 111, 113, 112, - 95, 95, 95, 96, 92, 95, 95, 95, 95, 38, - 35, 34, 38, 38, 42, 45, 43, 43, 43, 42, - - 40, 13, 14, 8, 8, 14, 12, 4, 5, 6, - 57, 58, 64, 117, 117, 55, 55, 65, 63, 28, - 28, 28, 25, 118, 118, 100, 100, 21, 92, 95, - 92, 95, 95, 38, 38, 39, 43, 43, 11, 4, - 11, 13, 5, 117, 28, 28, 118, 100, 100, 95, - 95, 38, 38, 43, 9, 28, 28, 100, 100, 95, - 95, 38, 38, 26, 28, 27, 28, 93, 100, 94, - 100, 93, 95, 94, 95, 36, 38, 37, 38, 10, - 62 - } ; - -static const short int yy_accept[392] = - { 0, - 1, 1, 1, 2, 3, 3, 3, 4, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 6, 8, 11, 13, 15, - 17, 20, 24, 27, 29, 31, 33, 35, 39, 41, - 45, 48, 50, 53, 55, 58, 61, 63, 65, 67, - 72, 77, 79, 81, 84, 85, 87, 88, 90, 92, - 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, - 114, 115, 117, 118, 121, 124, 127, 129, 131, 133, - - 135, 138, 141, 144, 146, 148, 149, 151, 153, 155, - 158, 160, 162, 164, 166, 168, 170, 173, 175, 177, - 180, 182, 184, 187, 190, 193, 196, 199, 200, 202, - 203, 205, 206, 208, 210, 212, 213, 215, 218, 220, - 222, 225, 228, 230, 232, 235, 237, 239, 241, 243, - 245, 247, 249, 251, 253, 255, 257, 259, 260, 262, - 264, 266, 269, 271, 273, 275, 277, 280, 284, 287, - 290, 294, 297, 298, 299, 299, 299, 300, 302, 304, - 304, 304, 305, 305, 306, 308, 308, 309, 310, 310, - 310, 311, 311, 312, 314, 316, 317, 317, 317, 317, - - 319, 320, 320, 320, 320, 321, 322, 323, 324, 325, - 326, 329, 332, 332, 336, 337, 338, 338, 339, 339, - 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 365, 366, 366, 367, - 368, 369, 370, 370, 371, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, - 397, 397, 398, 399, 400, 401, 402, 402, 403, 403, - 404, 405, 407, 407, 408, 409, 409, 409, 409, 410, - - 410, 411, 411, 412, 412, 413, 413, 413, 414, 414, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, - 424, 424, 424, 425, 426, 427, 428, 428, 429, 429, - 431, 432, 433, 434, 435, 436, 436, 437, 437, 438, - 439, 439, 440, 440, 441, 441, 443, 443, 443, 443, - 444, 444, 444, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 455, 456, 456, 456, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 464, 464, - 466, 468, 470, 472, 474, 476, 478, 480, 481, 482, - 482 - - } ; - -static const YY_CHAR yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 4, 5, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 6, 1, 7, 8, 9, 10, 1, 11, 12, - 12, 13, 12, 14, 15, 12, 16, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 1, 1, 18, - 1, 19, 12, 1, 25, 26, 27, 28, 29, 30, - 24, 24, 24, 31, 32, 24, 33, 34, 35, 32, - 24, 36, 37, 38, 39, 24, 24, 40, 41, 24, - 20, 21, 22, 23, 24, 1, 25, 26, 27, 28, - - 29, 30, 24, 24, 24, 31, 32, 24, 33, 34, - 35, 32, 24, 36, 37, 38, 39, 24, 24, 40, - 41, 24, 42, 43, 44, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static const YY_CHAR yy_meta[45] = - { 0, - 1, 2, 3, 2, 4, 2, 5, 1, 1, 1, - 6, 1, 7, 1, 8, 6, 9, 1, 1, 1, - 10, 11, 1, 12, 13, 13, 13, 13, 13, 13, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 6, 1, 14 - } ; - -static const short int yy_base[454] = - { 0, - 0, 44, 87, 129, 92, 99, 106, 107, 172, 1520, - 111, 116, 216, 0, 1506, 1464, 123, 258, 141, 148, - 259, 262, 266, 286, 308, 0, 120, 151, 261, 350, - 155, 265, 281, 287, 351, 354, 394, 0, 437, 477, - 0, 0, 517, 537, 1475, 1567, 293, 1567, 1471, 1394, - 0, 360, 1567, 1416, 154, 549, 1405, 0, 1567, 590, - 1567, 1402, 1567, 365, 1567, 1386, 1382, 84, 633, 676, - 1567, 1396, 350, 1567, 158, 0, 161, 301, 1567, 371, - 0, 1567, 1395, 0, 1365, 1352, 1341, 0, 375, 1567, - 1381, 1567, 1567, 1567, 1347, 0, 1567, 1567, 1567, 1360, - - 1567, 1341, 1567, 1567, 1567, 1354, 1567, 427, 1567, 1567, - 428, 1341, 1567, 0, 429, 1567, 0, 1567, 1343, 1567, - 282, 1330, 0, 1313, 1291, 1567, 1567, 375, 1567, 379, - 1567, 1326, 1567, 0, 1567, 1325, 1293, 0, 1567, 1305, - 1279, 0, 1567, 1291, 1567, 0, 0, 381, 1567, 1283, - 1241, 0, 1255, 1242, 0, 384, 1567, 1274, 1241, 1228, - 1567, 445, 1567, 1253, 1217, 431, 1567, 448, 1239, 1203, - 1219, 436, 453, 1567, 1232, 458, 0, 482, 1567, 1218, - 467, 1567, 472, 487, 488, 1210, 493, 0, 498, 239, - 0, 493, 1567, 0, 0, 1567, 1212, 1169, 502, 1567, - - 1567, 1181, 487, 489, 1567, 1185, 0, 0, 1567, 705, - 0, 1567, 1198, 1567, 0, 1567, 507, 0, 511, 1567, - 512, 1567, 521, 0, 1567, 0, 1143, 1140, 749, 0, - 526, 1567, 1567, 0, 1567, 1155, 1567, 1567, 1129, 0, - 1567, 1567, 1567, 0, 1567, 514, 1567, 1140, 1567, 0, - 1108, 1099, 528, 1567, 531, 1567, 0, 1567, 541, 0, - 1567, 1567, 0, 1567, 1567, 0, 546, 1087, 1567, 793, - 0, 1095, 1092, 0, 547, 1567, 1062, 1059, 558, 1567, - 563, 1567, 842, 0, 573, 841, 599, 1567, 854, 604, - 0, 605, 552, 610, 0, 615, 817, 826, 0, 558, - - 1567, 567, 1567, 568, 1567, 577, 819, 1567, 605, 821, - 836, 0, 0, 0, 1567, 0, 816, 809, 0, 1567, - 594, 610, 824, 0, 811, 804, 620, 1567, 625, 0, - 0, 767, 713, 718, 693, 685, 1567, 724, 709, 0, - 626, 1567, 633, 0, 690, 1567, 680, 688, 696, 0, - 693, 680, 835, 1567, 694, 682, 1567, 690, 664, 657, - 596, 597, 562, 1567, 516, 1567, 518, 677, 682, 436, - 437, 241, 238, 132, 136, 105, 98, 78, 79, 0, - 0, 0, 0, 0, 0, 0, 0, 1567, 1567, 1567, - 865, 879, 893, 907, 921, 935, 949, 963, 977, 991, - - 1005, 1019, 1033, 1047, 1061, 1075, 1082, 1095, 1109, 1115, - 1128, 1142, 1156, 1170, 1184, 1198, 1205, 1218, 1225, 1238, - 1252, 1266, 1280, 1291, 1298, 1311, 1325, 1339, 1353, 1367, - 1381, 1388, 1401, 1415, 1429, 693, 695, 1443, 1457, 360, - 1471, 1484, 380, 1498, 700, 1512, 1519, 1525, 701, 1538, - 702, 1552, 703 - } ; - -static const short int yy_def[454] = - { 0, - 390, 390, 391, 391, 392, 392, 393, 393, 390, 9, - 394, 394, 390, 13, 395, 395, 396, 396, 397, 397, - 398, 398, 399, 399, 390, 25, 400, 400, 395, 395, - 401, 401, 402, 402, 403, 403, 390, 37, 404, 404, - 37, 37, 405, 406, 390, 390, 390, 390, 390, 390, - 407, 390, 390, 390, 408, 409, 390, 410, 390, 390, - 390, 390, 390, 390, 390, 390, 411, 412, 390, 390, - 390, 390, 390, 390, 413, 414, 413, 415, 390, 415, - 416, 390, 390, 417, 417, 417, 416, 418, 390, 390, - 390, 390, 390, 390, 390, 419, 390, 390, 390, 390, - - 390, 390, 390, 390, 390, 390, 390, 412, 390, 390, - 420, 421, 390, 422, 412, 390, 423, 390, 390, 390, - 424, 390, 425, 425, 425, 390, 390, 426, 390, 426, - 390, 390, 390, 427, 390, 390, 390, 428, 390, 390, - 390, 429, 390, 390, 390, 430, 431, 431, 390, 390, - 431, 432, 432, 432, 433, 390, 390, 390, 433, 433, - 390, 390, 390, 390, 390, 434, 390, 390, 390, 390, - 390, 434, 390, 390, 390, 390, 407, 390, 390, 390, - 408, 390, 408, 390, 435, 390, 390, 436, 390, 390, - 437, 438, 390, 410, 60, 390, 390, 390, 439, 390, - - 390, 390, 411, 411, 390, 390, 440, 441, 390, 441, - 70, 390, 390, 390, 442, 390, 413, 414, 413, 390, - 415, 390, 415, 416, 390, 417, 417, 417, 390, 418, - 390, 390, 390, 419, 390, 390, 390, 390, 390, 443, - 390, 390, 390, 423, 390, 424, 390, 424, 390, 425, - 425, 425, 426, 390, 426, 390, 427, 390, 444, 428, - 390, 390, 429, 390, 390, 431, 431, 431, 390, 390, - 432, 432, 432, 433, 390, 390, 433, 433, 390, 390, - 390, 390, 390, 445, 390, 390, 390, 390, 390, 390, - 435, 435, 446, 390, 447, 446, 390, 390, 448, 438, - - 390, 438, 390, 439, 390, 439, 390, 390, 411, 411, - 390, 449, 441, 210, 390, 442, 417, 417, 229, 390, - 450, 450, 390, 451, 425, 425, 444, 390, 444, 270, - 452, 432, 432, 433, 433, 390, 390, 390, 390, 453, - 446, 390, 446, 447, 446, 390, 446, 390, 390, 448, - 390, 411, 310, 390, 417, 417, 390, 425, 425, 432, - 432, 433, 433, 390, 390, 390, 390, 411, 411, 417, - 417, 425, 425, 432, 432, 433, 433, 390, 390, 417, - 417, 425, 425, 432, 432, 433, 433, 390, 390, 0, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390 - } ; - -static const short int yy_nxt[1612] = - { 0, - 46, 47, 48, 47, 49, 47, 46, 46, 46, 50, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 46, 46, 46, 46, 52, 53, 52, 54, 52, - 46, 55, 46, 56, 46, 46, 46, 46, 46, 57, - 46, 46, 46, 46, 46, 46, 46, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 46, 46, 46, 60, 61, - 60, 62, 60, 63, 76, 64, 77, 389, 65, 65, - - 206, 76, 65, 77, 66, 388, 67, 68, 79, 79, - 80, 80, 89, 90, 89, 91, 89, 89, 90, 89, - 91, 89, 129, 207, 130, 99, 387, 100, 69, 65, - 70, 71, 70, 72, 70, 63, 101, 64, 73, 102, - 65, 65, 386, 105, 65, 106, 66, 107, 67, 68, - 105, 74, 106, 129, 107, 130, 182, 135, 183, 136, - 218, 108, 219, 218, 385, 219, 103, 137, 108, 384, - 69, 65, 81, 81, 82, 81, 83, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 84, 84, 84, 84, 84, - - 84, 84, 84, 84, 84, 84, 84, 85, 84, 84, - 84, 84, 86, 81, 81, 81, 92, 92, 93, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 94, - 92, 92, 92, 92, 95, 92, 92, 92, 92, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 92, 92, 92, - 99, 93, 100, 131, 93, 132, 383, 135, 93, 136, - 93, 101, 297, 110, 102, 298, 110, 137, 382, 111, - 114, 112, 111, 139, 112, 140, 115, 116, 93, 139, - 93, 140, 247, 141, 173, 174, 173, 175, 173, 141, - - 114, 103, 248, 222, 133, 223, 115, 116, 117, 117, - 118, 117, 119, 117, 120, 117, 117, 117, 121, 117, - 117, 117, 117, 122, 117, 117, 117, 117, 117, 117, - 117, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 124, 123, 123, 123, 123, 125, 126, - 117, 127, 131, 143, 132, 144, 143, 145, 144, 215, - 145, 178, 179, 178, 180, 178, 201, 201, 312, 201, - 201, 146, 312, 222, 146, 223, 231, 254, 231, 255, - 231, 254, 267, 255, 267, 275, 267, 275, 324, 275, - 268, 216, 324, 133, 147, 148, 149, 148, 150, 148, - - 147, 147, 147, 151, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, 152, 153, - 152, 152, 152, 152, 154, 147, 147, 147, 156, 157, - 156, 158, 156, 206, 239, 206, 279, 283, 279, 285, - 279, 285, 283, 285, 173, 174, 173, 175, 173, 287, - 288, 287, 289, 287, 286, 381, 207, 240, 207, 182, - 284, 183, 159, 380, 182, 284, 183, 160, 156, 157, - 156, 158, 156, 178, 179, 178, 180, 178, 290, 292, - 290, 292, 290, 292, 294, 301, 294, 302, 294, 287, - - 288, 287, 289, 296, 305, 309, 306, 204, 308, 218, - 203, 219, 159, 218, 222, 219, 223, 160, 162, 163, - 162, 164, 162, 222, 247, 223, 165, 231, 310, 231, - 254, 231, 255, 254, 248, 255, 379, 166, 168, 163, - 168, 169, 168, 328, 378, 329, 170, 267, 275, 267, - 275, 267, 275, 171, 342, 268, 343, 172, 185, 279, - 301, 279, 302, 279, 336, 337, 336, 338, 336, 301, - 305, 302, 306, 186, 285, 187, 285, 186, 285, 305, - 186, 306, 186, 186, 187, 188, 189, 190, 191, 286, - 192, 195, 196, 195, 197, 195, 320, 377, 321, 198, - - 287, 288, 287, 289, 287, 290, 292, 290, 292, 290, - 292, 294, 320, 294, 321, 294, 345, 346, 345, 347, - 345, 352, 328, 376, 329, 204, 308, 328, 342, 329, - 343, 375, 199, 208, 208, 342, 208, 343, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 209, - 208, 208, 208, 208, 208, 208, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 208, 208, 208, 211, 212, 211, - 213, 211, 346, 374, 343, 198, 336, 337, 336, 338, - 336, 345, 346, 345, 347, 345, 368, 204, 308, 373, - - 204, 308, 204, 308, 295, 295, 299, 299, 340, 354, - 357, 364, 340, 354, 357, 364, 372, 371, 199, 314, - 370, 314, 367, 366, 365, 282, 337, 363, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 362, 361, 315, 319, - 319, 320, 319, 321, 319, 319, 319, 319, 319, 319, - 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - 319, 319, 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - 319, 319, 319, 330, 330, 360, 330, 331, 330, 330, - - 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 330, 330, 330, 330, 330, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 330, 330, 330, 353, 359, 358, - 238, 204, 308, 356, 355, 353, 353, 353, 353, 353, - 353, 369, 205, 351, 349, 348, 288, 286, 339, 369, - 369, 369, 369, 369, 369, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 78, 78, 78, 78, 78, 78, 78, - - 78, 78, 78, 78, 78, 78, 78, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, - 88, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 128, 128, 128, 128, 128, 128, 128, 128, 128, - - 128, 128, 128, 128, 128, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 177, - 177, 335, 334, 177, 177, 181, 181, 181, 181, 181, - - 181, 181, 181, 181, 181, 181, 181, 181, 181, 184, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 194, 194, 333, 332, 194, 194, 203, 203, - 270, 326, 203, 203, 203, 203, 203, 203, 325, 203, - 203, 203, 205, 205, 246, 323, 205, 205, 205, 205, - 205, 205, 205, 205, 205, 205, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 220, 236, 318, 317, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, 224, 224, - - 212, 311, 224, 224, 224, 224, 224, 224, 224, 307, - 303, 224, 226, 226, 196, 293, 226, 226, 230, 230, - 179, 230, 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 234, 234, 174, 286, 234, 234, 238, 238, - 281, 280, 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 241, 241, 281, 280, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 243, 243, 278, 277, - 243, 243, 243, 243, 243, 243, 276, 243, 243, 243, - 244, 244, 273, 272, 270, 269, 244, 244, 244, 244, - 244, 246, 246, 264, 262, 246, 246, 246, 246, 246, - - 246, 246, 246, 246, 246, 250, 250, 261, 259, 250, - 250, 253, 253, 253, 253, 253, 253, 253, 253, 253, - 253, 253, 253, 253, 253, 257, 257, 258, 256, 257, - 257, 252, 257, 257, 257, 257, 257, 257, 257, 260, - 260, 251, 249, 260, 260, 245, 260, 260, 260, 260, - 260, 260, 260, 263, 263, 242, 237, 236, 263, 263, - 263, 263, 235, 263, 263, 263, 263, 265, 265, 233, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 266, 266, 232, 229, 266, 266, 266, 266, 266, - 266, 266, 228, 227, 266, 271, 271, 225, 214, 271, - - 271, 274, 204, 202, 200, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 282, 282, 193, 179, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 291, - 291, 176, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 313, 313, 174, 390, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 316, 316, 97, 316, 316, 316, - 316, 316, 316, 316, 316, 316, 316, 316, 327, 327, - - 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, - 327, 327, 341, 341, 341, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 344, 344, 97, 87, - 344, 344, 350, 350, 390, 390, 350, 350, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 331, 331, 390, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 45, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390 - } ; - -static const short int yy_chk[1612] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 5, 3, 5, 379, 3, 3, - - 68, 6, 3, 6, 3, 378, 3, 3, 7, 8, - 7, 8, 11, 11, 11, 11, 11, 12, 12, 12, - 12, 12, 27, 68, 27, 17, 377, 17, 3, 3, - 4, 4, 4, 4, 4, 4, 17, 4, 4, 17, - 4, 4, 376, 19, 4, 19, 4, 19, 4, 4, - 20, 4, 20, 28, 20, 28, 55, 31, 55, 31, - 75, 19, 75, 77, 375, 77, 17, 31, 20, 374, - 4, 4, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 18, 21, 18, 29, 22, 29, 373, 32, 23, 32, - 23, 18, 190, 21, 18, 190, 22, 32, 372, 21, - 23, 21, 22, 33, 22, 33, 23, 23, 24, 34, - 24, 34, 121, 33, 47, 47, 47, 47, 47, 34, - - 24, 18, 121, 78, 29, 78, 24, 24, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 30, 35, 30, 35, 36, 35, 36, 73, - 36, 52, 52, 52, 52, 52, 64, 64, 440, 64, - 64, 35, 440, 80, 36, 80, 89, 128, 89, 128, - 89, 130, 148, 130, 148, 156, 148, 156, 443, 156, - 148, 73, 443, 30, 37, 37, 37, 37, 37, 37, - - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 39, 39, - 39, 39, 39, 108, 111, 115, 162, 166, 162, 168, - 162, 168, 172, 168, 173, 173, 173, 173, 173, 176, - 176, 176, 176, 176, 168, 371, 108, 111, 115, 181, - 166, 181, 39, 370, 183, 172, 183, 39, 40, 40, - 40, 40, 40, 178, 178, 178, 178, 178, 184, 185, - 184, 185, 184, 185, 187, 192, 187, 192, 187, 189, - - 189, 189, 189, 189, 199, 204, 199, 203, 203, 217, - 204, 217, 40, 219, 221, 219, 221, 40, 43, 43, - 43, 43, 43, 223, 246, 223, 43, 231, 204, 231, - 253, 231, 253, 255, 246, 255, 367, 43, 44, 44, - 44, 44, 44, 259, 365, 259, 44, 267, 275, 267, - 275, 267, 275, 44, 293, 267, 293, 44, 56, 279, - 300, 279, 300, 279, 281, 281, 281, 281, 281, 302, - 304, 302, 304, 56, 285, 56, 285, 56, 285, 306, - 56, 306, 56, 56, 56, 56, 56, 56, 56, 285, - 56, 60, 60, 60, 60, 60, 321, 363, 321, 60, - - 287, 287, 287, 287, 287, 290, 292, 290, 292, 290, - 292, 294, 322, 294, 322, 294, 296, 296, 296, 296, - 296, 309, 327, 362, 327, 309, 309, 329, 341, 329, - 341, 361, 60, 69, 69, 343, 69, 343, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 70, 70, 70, - 70, 70, 347, 360, 347, 70, 336, 336, 336, 336, - 336, 345, 345, 345, 345, 345, 352, 368, 368, 359, - - 352, 352, 369, 369, 436, 436, 437, 437, 445, 449, - 451, 453, 445, 449, 451, 453, 358, 356, 70, 210, - 355, 210, 351, 349, 348, 339, 338, 335, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 334, 333, 210, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 270, 270, 332, 270, 270, 270, 270, - - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 310, 326, 325, - 323, 310, 310, 318, 317, 310, 310, 310, 310, 310, - 310, 353, 311, 307, 298, 297, 289, 286, 283, 353, - 353, 353, 353, 353, 353, 391, 391, 391, 391, 391, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 392, - 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 393, 393, 393, 393, 393, 393, 393, - - 393, 393, 393, 393, 393, 393, 393, 394, 394, 394, - 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, - 394, 395, 395, 395, 395, 395, 395, 395, 395, 395, - 395, 395, 395, 395, 395, 396, 396, 396, 396, 396, - 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 399, 399, 399, - 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, - 399, 400, 400, 400, 400, 400, 400, 400, 400, 400, - - 400, 400, 400, 400, 400, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 402, - 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, - 402, 402, 402, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 404, 404, 404, - 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, - 404, 405, 405, 405, 405, 405, 405, 405, 405, 405, - 405, 405, 405, 405, 405, 406, 406, 406, 406, 406, - 406, 406, 406, 406, 406, 406, 406, 406, 406, 407, - 407, 278, 277, 407, 407, 408, 408, 408, 408, 408, - - 408, 408, 408, 408, 408, 408, 408, 408, 408, 409, - 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, - 409, 409, 410, 410, 273, 272, 410, 410, 411, 411, - 268, 252, 411, 411, 411, 411, 411, 411, 251, 411, - 411, 411, 412, 412, 248, 239, 412, 412, 412, 412, - 412, 412, 412, 412, 412, 412, 413, 413, 413, 413, - 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, - 414, 236, 228, 227, 414, 414, 414, 414, 414, 414, - 414, 414, 414, 414, 415, 415, 415, 415, 415, 415, - 415, 415, 415, 415, 415, 415, 415, 415, 416, 416, - - 213, 206, 416, 416, 416, 416, 416, 416, 416, 202, - 198, 416, 417, 417, 197, 186, 417, 417, 418, 418, - 180, 418, 418, 418, 418, 418, 418, 418, 418, 418, - 418, 418, 419, 419, 175, 171, 419, 419, 420, 420, - 170, 169, 420, 420, 420, 420, 420, 420, 420, 420, - 420, 420, 421, 421, 165, 164, 421, 421, 421, 421, - 421, 421, 421, 421, 421, 421, 422, 422, 160, 159, - 422, 422, 422, 422, 422, 422, 158, 422, 422, 422, - 423, 423, 154, 153, 151, 150, 423, 423, 423, 423, - 423, 424, 424, 144, 141, 424, 424, 424, 424, 424, - - 424, 424, 424, 424, 424, 425, 425, 140, 137, 425, - 425, 426, 426, 426, 426, 426, 426, 426, 426, 426, - 426, 426, 426, 426, 426, 427, 427, 136, 132, 427, - 427, 125, 427, 427, 427, 427, 427, 427, 427, 428, - 428, 124, 122, 428, 428, 119, 428, 428, 428, 428, - 428, 428, 428, 429, 429, 112, 106, 102, 429, 429, - 429, 429, 100, 429, 429, 429, 429, 430, 430, 95, - 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, - 430, 431, 431, 91, 87, 431, 431, 431, 431, 431, - 431, 431, 86, 85, 431, 432, 432, 83, 72, 432, - - 432, 433, 67, 66, 62, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 434, 434, 57, 54, 434, - 434, 434, 434, 434, 434, 434, 434, 434, 434, 435, - 435, 50, 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 438, 438, 438, 438, 438, 438, 438, - 438, 438, 438, 438, 438, 438, 438, 439, 439, 439, - 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, - 439, 441, 441, 49, 45, 441, 441, 441, 441, 441, - 441, 441, 441, 441, 442, 442, 16, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 444, 444, - - 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, - 444, 444, 446, 446, 446, 446, 446, 446, 446, 446, - 446, 446, 446, 446, 446, 446, 447, 447, 15, 10, - 447, 447, 448, 448, 0, 0, 448, 448, 450, 450, - 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, - 450, 450, 452, 452, 0, 452, 452, 452, 452, 452, - 452, 452, 452, 452, 452, 452, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390 - } ; - -static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr; -static YY_CHAR *yy_full_match; -static int yy_lp; -static int yy_looking_for_trail_begin = 0; -static int yy_full_lp; -static int *yy_full_state; -#define YY_TRAILING_MASK 0x2000 -#define YY_TRAILING_HEAD_MASK 0x4000 -#define REJECT \ -{ \ -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \ -yy_cp = yy_full_match; /* restore poss. backed-over text */ \ -yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \ -yy_state_ptr = yy_full_state; /* restore orig. state */ \ -yy_current_state = *yy_state_ptr; /* restore curr. state */ \ -++yy_lp; \ -goto find_rule; \ -} -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 - -/* these variables are all declared out here so that section 3 code can - * manipulate them - */ -/* points to current character in buffer */ -static YY_CHAR *yy_c_buf_p = (YY_CHAR *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -static yy_state_type yy_get_previous_state ( void ); -static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); -static int yy_get_next_buffer ( void ); -static void yyunput ( YY_CHAR c, YY_CHAR *buf_ptr ); -void yyrestart ( FILE *input_file ); -void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); -void yy_load_buffer_state ( void ); -YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); -void yy_delete_buffer ( YY_BUFFER_STATE b ); -void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); - -#define yy_new_buffer yy_create_buffer - -YY_DECL - { - yy_state_type yy_current_state; - YY_CHAR *yy_cp, *yy_bp; - int yy_act; - - - static int bracelevel, didadef; - int i, indented_code = false, checking_used = false, new_xlation = false; - int doing_codeblock = false; - Char nmdef[MAXLINE], myesc(); - - - if ( yy_init ) - { - YY_USER_INIT; - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( yy_current_buffer ) - yy_init_buffer( yy_current_buffer, yyin ); - else - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - - yy_init = 0; - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; - - /* support of yytext */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of the - * current run. - */ - yy_bp = yy_cp; - - yy_current_state = yy_start; - if ( yy_bp[-1] == '\n' ) - ++yy_current_state; - yy_state_ptr = yy_state_buf; - *yy_state_ptr++ = yy_current_state; -yy_match: - do - { - YY_CHAR yy_c = yy_ec[(int)*yy_cp]; - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = yy_def[yy_current_state]; - if ( yy_current_state >= 391 ) - yy_c = yy_meta[(int)yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - *yy_state_ptr++ = yy_current_state; - ++yy_cp; - } - while ( yy_current_state != 390 ); - -yy_find_action: - yy_current_state = *--yy_state_ptr; - yy_lp = yy_accept[yy_current_state]; -find_rule: /* we branch to this label when backtracking */ - for ( ; ; ) /* until we find what rule we matched */ - { - if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] ) - { - yy_act = yy_acclist[yy_lp]; - if ( yy_act & YY_TRAILING_HEAD_MASK || - yy_looking_for_trail_begin ) - { - if ( yy_act == yy_looking_for_trail_begin ) - { - yy_looking_for_trail_begin = 0; - yy_act &= ~YY_TRAILING_HEAD_MASK; - break; - } - } - else if ( yy_act & YY_TRAILING_MASK ) - { - yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK; - yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK; - } - else - { - yy_full_match = yy_cp; - yy_full_state = yy_state_ptr; - yy_full_lp = yy_lp; - break; - } - ++yy_lp; - goto find_rule; - } - --yy_cp; - yy_current_state = *--yy_state_ptr; - yy_lp = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - YY_USER_ACTION; - -do_action: /* this label is used only to access EOF actions */ - - - switch ( yy_act ) - { -case 1: -# line 82 "scan.l" -indented_code = true; BEGIN(CODEBLOCK); - YY_BREAK -case 2: -# line 83 "scan.l" -++linenum; /* treat as a comment */ - YY_BREAK -case 3: -# line 84 "scan.l" -ECHO; BEGIN(C_COMMENT); - YY_BREAK -case 4: -# line 85 "scan.l" -return ( SCDECL ); - YY_BREAK -case 5: -# line 86 "scan.l" -return ( XSCDECL ); - YY_BREAK -case 6: -# line 87 "scan.l" -{ - ++linenum; - line_directive_out( stdout ); - indented_code = false; - BEGIN(CODEBLOCK); - } - YY_BREAK -case 7: -# line 94 "scan.l" -return ( WHITESPACE ); - YY_BREAK -case 8: -# line 96 "scan.l" -{ - sectnum = 2; - line_directive_out( stdout ); - BEGIN(SECT2PROLOG); - return ( SECTEND ); - } - YY_BREAK -case 9: -# line 103 "scan.l" -{ - pinpoint_message( "warning - %%used/%%unused have been deprecated" ); - checking_used = REALLY_USED; BEGIN(USED_LIST); - } - YY_BREAK -case 10: -# line 107 "scan.l" -{ - checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); - pinpoint_message( "warning - %%used/%%unused have been deprecated" ); - checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); - } - YY_BREAK -case 11: -# line 114 "scan.l" -{ -#ifdef NOTDEF - fprintf( stderr, - "old-style lex command at line %d ignored:\n\t%s", - linenum, yytext ); -#endif - ++linenum; - } - YY_BREAK -case 12: -# line 123 "scan.l" -/* ignore old lex directive */ - YY_BREAK -case 13: -# line 125 "scan.l" -{ - ++linenum; - xlation = - (int *) malloc( sizeof( int ) * (unsigned) csize ); - - if ( ! xlation ) - flexfatal( - "dynamic memory failure building %t table" ); - - for ( i = 0; i < csize; ++i ) - xlation[i] = 0; - - num_xlations = 0; - - BEGIN(XLATION); - } - YY_BREAK -case 14: -# line 142 "scan.l" -synerr( "unrecognized '%' directive" ); - YY_BREAK -case 15: -# line 144 "scan.l" -{ - (void) strcpy( nmstr, (char *) yytext ); - didadef = false; - BEGIN(PICKUPDEF); - } - YY_BREAK -case 16: -# line 150 "scan.l" -RETURNNAME; - YY_BREAK -case 17: -# line 151 "scan.l" -++linenum; /* allows blank lines in section 1 */ - YY_BREAK -case 18: -# line 152 "scan.l" -++linenum; return ( '\n' ); - YY_BREAK -case 19: -# line 153 "scan.l" -synerr( "illegal character" ); BEGIN(RECOVER); - YY_BREAK -case 20: -# line 156 "scan.l" -ECHO; BEGIN(INITIAL); - YY_BREAK -case 21: -# line 157 "scan.l" -++linenum; ECHO; BEGIN(INITIAL); - YY_BREAK -case 22: -# line 158 "scan.l" -ECHO; - YY_BREAK -case 23: -# line 159 "scan.l" -ECHO; - YY_BREAK -case 24: -# line 160 "scan.l" -++linenum; ECHO; - YY_BREAK -case 25: -# line 163 "scan.l" -++linenum; BEGIN(INITIAL); - YY_BREAK -case 26: -# line 164 "scan.l" -ECHO; CHECK_REJECT(yytext); - YY_BREAK -case 27: -# line 165 "scan.l" -ECHO; CHECK_YYMORE(yytext); - YY_BREAK -case 28: -# line 166 "scan.l" -ECHO; - YY_BREAK -case 29: -# line 167 "scan.l" -{ - ++linenum; - ECHO; - if ( indented_code ) - BEGIN(INITIAL); - } - YY_BREAK -case 30: -# line 175 "scan.l" -/* separates name and definition */ - YY_BREAK -case 31: -# line 177 "scan.l" -{ - (void) strcpy( (char *) nmdef, (char *) yytext ); - - for ( i = strlen( (char *) nmdef ) - 1; - i >= 0 && - (nmdef[i] == ' ' || nmdef[i] == '\t'); - --i ) - ; - - nmdef[i + 1] = '\0'; - - ndinstal( nmstr, nmdef ); - didadef = true; - } - YY_BREAK -case 32: -# line 192 "scan.l" -{ - if ( ! didadef ) - synerr( "incomplete name definition" ); - BEGIN(INITIAL); - ++linenum; - } - YY_BREAK -case 33: -# line 199 "scan.l" -++linenum; BEGIN(INITIAL); RETURNNAME; - YY_BREAK -case 34: -# line 202 "scan.l" -++linenum; BEGIN(INITIAL); - YY_BREAK -case 35: -# line 203 "scan.l" - - YY_BREAK -case 36: -# line 204 "scan.l" -{ - if ( all_upper( yytext ) ) - reject_really_used = checking_used; - else - synerr( "unrecognized %used/%unused construct" ); - } - YY_BREAK -case 37: -# line 210 "scan.l" -{ - if ( all_lower( yytext ) ) - yymore_really_used = checking_used; - else - synerr( "unrecognized %used/%unused construct" ); - } - YY_BREAK -case 38: -# line 216 "scan.l" -synerr( "unrecognized %used/%unused construct" ); - YY_BREAK -case 39: -# line 219 "scan.l" -++linenum; BEGIN(INITIAL); - YY_BREAK -case 40: -# line 220 "scan.l" -++num_xlations; new_xlation = true; - YY_BREAK -case 41: -# line 221 "scan.l" -synerr( "bad row in translation table" ); - YY_BREAK -case 42: -# line 222 "scan.l" -/* ignore whitespace */ - YY_BREAK -case 43: -# line 224 "scan.l" -{ - xlation[myesc( yytext )] = - (new_xlation ? num_xlations : -num_xlations); - new_xlation = false; - } - YY_BREAK -case 44: -# line 229 "scan.l" -{ - xlation[yytext[0]] = - (new_xlation ? num_xlations : -num_xlations); - new_xlation = false; - } - YY_BREAK -case 45: -# line 235 "scan.l" -++linenum; - YY_BREAK -case 46: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 238 "scan.l" -{ - ++linenum; - ACTION_ECHO; - MARK_END_OF_PROLOG; - BEGIN(SECT2); - } - YY_BREAK -case 47: -# line 245 "scan.l" -++linenum; ACTION_ECHO; - YY_BREAK -case YY_STATE_EOF(SECT2PROLOG): -# line 247 "scan.l" -MARK_END_OF_PROLOG; yyterminate(); - YY_BREAK -case 49: -# line 249 "scan.l" -++linenum; /* allow blank lines in section 2 */ - YY_BREAK -case 50: -# line 251 "scan.l" -{ - indented_code = (yytext[0] != '%'); - doing_codeblock = true; - bracelevel = 1; - - if ( indented_code ) - ACTION_ECHO; - - BEGIN(CODEBLOCK_2); - } - YY_BREAK -case 51: -# line 262 "scan.l" -BEGIN(SC); return ( '<' ); - YY_BREAK -case 52: -# line 263 "scan.l" -return ( '^' ); - YY_BREAK -case 53: -# line 264 "scan.l" -BEGIN(QUOTE); return ( '"' ); - YY_BREAK -case 54: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 265 "scan.l" -BEGIN(NUM); return ( '{' ); - YY_BREAK -case 55: -# line 266 "scan.l" -BEGIN(BRACEERROR); - YY_BREAK -case 56: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 267 "scan.l" -return ( '$' ); - YY_BREAK -case 57: -# line 269 "scan.l" -{ - bracelevel = 1; - BEGIN(PERCENT_BRACE_ACTION); - return ( '\n' ); - } - YY_BREAK -case 58: -# line 274 "scan.l" -continued_action = true; ++linenum; return ( '\n' ); - YY_BREAK -case 59: -# line 276 "scan.l" -{ - /* this rule is separate from the one below because - * otherwise we get variable trailing context, so - * we can't build the scanner using -{f,F} - */ - bracelevel = 0; - continued_action = false; - BEGIN(ACTION); - return ( '\n' ); - } - YY_BREAK -case 60: -# line 287 "scan.l" -{ - bracelevel = 0; - continued_action = false; - BEGIN(ACTION); - return ( '\n' ); - } - YY_BREAK -case 61: -# line 294 "scan.l" -++linenum; return ( '\n' ); - YY_BREAK -case 62: -# line 296 "scan.l" -return ( EOF_OP ); - YY_BREAK -case 63: -# line 298 "scan.l" -{ - sectnum = 3; - BEGIN(SECT3); - return ( EOF ); /* to stop the parser */ - } - YY_BREAK -case 64: -# line 304 "scan.l" -{ - int cclval; - - (void) strcpy( nmstr, (char *) yytext ); - - /* check to see if we've already encountered this ccl */ - if ( (cclval = ccllookup( (Char *) nmstr )) ) - { - yylval = cclval; - ++cclreuse; - return ( PREVCCL ); - } - else - { - /* we fudge a bit. We know that this ccl will - * soon be numbered as lastccl + 1 by cclinit - */ - cclinstal( (Char *) nmstr, lastccl + 1 ); - - /* push back everything but the leading bracket - * so the ccl can be rescanned - */ - PUT_BACK_STRING((Char *) nmstr, 1); - - BEGIN(FIRSTCCL); - return ( '[' ); - } - } - YY_BREAK -case 65: -# line 333 "scan.l" -{ - Char *nmdefptr; - Char *ndlookup(); - - (void) strcpy( nmstr, (char *) yytext ); - nmstr[yyleng - 1] = '\0'; /* chop trailing brace */ - - /* lookup from "nmstr + 1" to chop leading brace */ - if ( ! (nmdefptr = ndlookup( nmstr + 1 )) ) - synerr( "undefined {name}" ); - - else - { /* push back name surrounded by ()'s */ - unput(')'); - PUT_BACK_STRING(nmdefptr, 0); - unput('('); - } - } - YY_BREAK -case 66: -# line 352 "scan.l" -return ( yytext[0] ); - YY_BREAK -case 67: -# line 353 "scan.l" -RETURNCHAR; - YY_BREAK -case 68: -# line 354 "scan.l" -++linenum; return ( '\n' ); - YY_BREAK -case 69: -# line 357 "scan.l" -return ( ',' ); - YY_BREAK -case 70: -# line 358 "scan.l" -BEGIN(SECT2); return ( '>' ); - YY_BREAK -case 71: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 359 "scan.l" -BEGIN(CARETISBOL); return ( '>' ); - YY_BREAK -case 72: -# line 360 "scan.l" -RETURNNAME; - YY_BREAK -case 73: -# line 361 "scan.l" -synerr( "bad start condition name" ); - YY_BREAK -case 74: -# line 363 "scan.l" -BEGIN(SECT2); return ( '^' ); - YY_BREAK -case 75: -# line 366 "scan.l" -RETURNCHAR; - YY_BREAK -case 76: -# line 367 "scan.l" -BEGIN(SECT2); return ( '"' ); - YY_BREAK -case 77: -# line 369 "scan.l" -{ - synerr( "missing quote" ); - BEGIN(SECT2); - ++linenum; - return ( '"' ); - } - YY_BREAK -case 78: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 377 "scan.l" -BEGIN(CCL); return ( '^' ); - YY_BREAK -case 79: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 378 "scan.l" -return ( '^' ); - YY_BREAK -case 80: -# line 379 "scan.l" -BEGIN(CCL); yylval = '-'; return ( CHAR ); - YY_BREAK -case 81: -# line 380 "scan.l" -BEGIN(CCL); RETURNCHAR; - YY_BREAK -case 82: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 382 "scan.l" -return ( '-' ); - YY_BREAK -case 83: -# line 383 "scan.l" -RETURNCHAR; - YY_BREAK -case 84: -# line 384 "scan.l" -BEGIN(SECT2); return ( ']' ); - YY_BREAK -case 85: -# line 387 "scan.l" -{ - yylval = myctoi( yytext ); - return ( NUMBER ); - } - YY_BREAK -case 86: -# line 392 "scan.l" -return ( ',' ); - YY_BREAK -case 87: -# line 393 "scan.l" -BEGIN(SECT2); return ( '}' ); - YY_BREAK -case 88: -# line 395 "scan.l" -{ - synerr( "bad character inside {}'s" ); - BEGIN(SECT2); - return ( '}' ); - } - YY_BREAK -case 89: -# line 401 "scan.l" -{ - synerr( "missing }" ); - BEGIN(SECT2); - ++linenum; - return ( '}' ); - } - YY_BREAK -case 90: -# line 409 "scan.l" -synerr( "bad name in {}'s" ); BEGIN(SECT2); - YY_BREAK -case 91: -# line 410 "scan.l" -synerr( "missing }" ); ++linenum; BEGIN(SECT2); - YY_BREAK -case 92: -# line 413 "scan.l" -bracelevel = 0; - YY_BREAK -case 93: -# line 414 "scan.l" -{ - ACTION_ECHO; - CHECK_REJECT(yytext); - } - YY_BREAK -case 94: -# line 418 "scan.l" -{ - ACTION_ECHO; - CHECK_YYMORE(yytext); - } - YY_BREAK -case 95: -# line 422 "scan.l" -ACTION_ECHO; - YY_BREAK -case 96: -# line 423 "scan.l" -{ - ++linenum; - ACTION_ECHO; - if ( bracelevel == 0 || - (doing_codeblock && indented_code) ) - { - if ( ! doing_codeblock ) - fputs( "\tYY_BREAK\n", temp_action_file ); - - doing_codeblock = false; - BEGIN(SECT2); - } - } - YY_BREAK - /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */ -case 97: -# line 439 "scan.l" -ACTION_ECHO; ++bracelevel; - YY_BREAK -case 98: -# line 440 "scan.l" -ACTION_ECHO; --bracelevel; - YY_BREAK -case 99: -# line 441 "scan.l" -ACTION_ECHO; - YY_BREAK -case 100: -# line 442 "scan.l" -ACTION_ECHO; - YY_BREAK -case 101: -# line 443 "scan.l" -ACTION_ECHO; BEGIN(ACTION_COMMENT); - YY_BREAK -case 102: -# line 444 "scan.l" -ACTION_ECHO; /* character constant */ - YY_BREAK -case 103: -# line 445 "scan.l" -ACTION_ECHO; BEGIN(ACTION_STRING); - YY_BREAK -case 104: -# line 446 "scan.l" -{ - ++linenum; - ACTION_ECHO; - if ( bracelevel == 0 ) - { - fputs( "\tYY_BREAK\n", temp_action_file ); - BEGIN(SECT2); - } - } - YY_BREAK -case 105: -# line 455 "scan.l" -ACTION_ECHO; - YY_BREAK -case 106: -# line 457 "scan.l" -ACTION_ECHO; BEGIN(ACTION); - YY_BREAK -case 107: -# line 458 "scan.l" -ACTION_ECHO; - YY_BREAK -case 108: -# line 459 "scan.l" -ACTION_ECHO; - YY_BREAK -case 109: -# line 460 "scan.l" -++linenum; ACTION_ECHO; - YY_BREAK -case 110: -# line 461 "scan.l" -ACTION_ECHO; - YY_BREAK -case 111: -# line 463 "scan.l" -ACTION_ECHO; - YY_BREAK -case 112: -# line 464 "scan.l" -ACTION_ECHO; - YY_BREAK -case 113: -# line 465 "scan.l" -++linenum; ACTION_ECHO; - YY_BREAK -case 114: -# line 466 "scan.l" -ACTION_ECHO; BEGIN(ACTION); - YY_BREAK -case 115: -# line 467 "scan.l" -ACTION_ECHO; - YY_BREAK -case YY_STATE_EOF(ACTION): -case YY_STATE_EOF(ACTION_COMMENT): -case YY_STATE_EOF(ACTION_STRING): -# line 469 "scan.l" -{ - synerr( "EOF encountered inside an action" ); - yyterminate(); - } - YY_BREAK -case 117: -# line 475 "scan.l" -{ - yylval = myesc( yytext ); - return ( CHAR ); - } - YY_BREAK -case 118: -# line 480 "scan.l" -{ - yylval = myesc( yytext ); - BEGIN(CCL); - return ( CHAR ); - } - YY_BREAK -case 119: -# line 487 "scan.l" -ECHO; - YY_BREAK -case 120: -# line 488 "scan.l" -ECHO; - YY_BREAK - case YY_STATE_EOF(INITIAL): - case YY_STATE_EOF(SECT2): - case YY_STATE_EOF(SECT3): - case YY_STATE_EOF(CODEBLOCK): - case YY_STATE_EOF(PICKUPDEF): - case YY_STATE_EOF(SC): - case YY_STATE_EOF(CARETISBOL): - case YY_STATE_EOF(NUM): - case YY_STATE_EOF(QUOTE): - case YY_STATE_EOF(FIRSTCCL): - case YY_STATE_EOF(CCL): - case YY_STATE_EOF(RECOVER): - case YY_STATE_EOF(BRACEERROR): - case YY_STATE_EOF(C_COMMENT): - case YY_STATE_EOF(PERCENT_BRACE_ACTION): - case YY_STATE_EOF(USED_LIST): - case YY_STATE_EOF(CODEBLOCK_2): - case YY_STATE_EOF(XLATION): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* amount of text matched not including the EOB char */ - int yy_amount_of_matched_text = yy_cp - yytext - 1; - - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - - /* note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the end- - * of-buffer state). Contrast this with the test in yyinput(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* this was really a NUL */ - { - yy_state_type yy_next_state; - - yy_c_buf_p = yytext + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* okay, we're now positioned to make the - * NUL transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we - * don't want to build jamming into it because - * then it will run more slowly) - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* consume the NUL */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* note: because we've taken care in - * yy_get_next_buffer() to have set up yytext, - * we can now set up yy_c_buf_p so that if some - * total hoser (like flex itself) wants - * to call the scanner after we return the - * YY_NULL, it'll still work - another YY_NULL - * will get returned. - */ - yy_c_buf_p = yytext + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF((yy_start - 1) / 2); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - } - break; - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: -#ifdef FLEX_DEBUG - printf( "action # %d\n", yy_act ); -#endif - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } - } - } - - -/* yy_get_next_buffer - try to read in a new buffer - * - * synopsis - * int yy_get_next_buffer(); - * - * returns a code representing an action - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -static int yy_get_next_buffer() - - { - YY_CHAR *dest = yy_current_buffer->yy_ch_buf; - YY_CHAR *source = yytext - 1; /* copy prev. char, too */ - int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - /* try to read more data */ - - /* first move last chars to start of buffer */ - number_to_move = yy_c_buf_p - yytext; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_eof_status != EOF_NOT_SEEN ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_n_chars = 0; - - else - { - int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1; - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - else if ( num_to_read <= 0 ) - YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); - - /* read in more data */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move == 1 ) - { - ret_val = EOB_ACT_END_OF_FILE; - yy_current_buffer->yy_eof_status = EOF_DONE; - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_eof_status = EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - /* yytext begins at the second character in yy_ch_buf; the first - * character is the one which preceded it before reading in the latest - * buffer; it needs to be kept around in case it's a newline, so - * yy_get_previous_state() will have with '^' rules active - */ - - yytext = &yy_current_buffer->yy_ch_buf[1]; - - return ( ret_val ); - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached - * - * synopsis - * yy_state_type yy_get_previous_state(); - */ - -static yy_state_type yy_get_previous_state() - - { - yy_state_type yy_current_state; - YY_CHAR *yy_cp; - - YY_CHAR *yy_bp = yytext; - - yy_current_state = yy_start; - if ( yy_bp[-1] == '\n' ) - ++yy_current_state; - yy_state_ptr = yy_state_buf; - *yy_state_ptr++ = yy_current_state; - - for ( yy_cp = yytext + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - YY_CHAR yy_c = (*yy_cp ? yy_ec[(int)*yy_cp] : 1); - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = yy_def[yy_current_state]; - if ( yy_current_state >= 391 ) - yy_c = yy_meta[(int)yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - *yy_state_ptr++ = yy_current_state; - } - - return ( yy_current_state ); - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) - { - int yy_is_jam; - - YY_CHAR yy_c = 1; - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = yy_def[yy_current_state]; - if ( yy_current_state >= 391 ) - yy_c = yy_meta[(int)yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - *yy_state_ptr++ = yy_current_state; - yy_is_jam = (yy_current_state == 390); - - return ( yy_is_jam ? 0 : yy_current_state ); - } - - -static void yyunput( YY_CHAR c, YY_CHAR *yy_bp ) - { - YY_CHAR *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */ - YY_CHAR *dest = - &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size + 2]; - YY_CHAR *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += dest - source; - yy_bp += dest - source; - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - if ( yy_cp > yy_bp && yy_cp[-1] == '\n' ) - yy_cp[-2] = '\n'; - - *--yy_cp = c; - - /* note: the formal parameter *must* be called "yy_bp" for this - * macro to now work correctly - */ - YY_DO_BEFORE_ACTION; /* set up yytext again */ - } - - -void yyrestart( FILE *input_file ) - { - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* flush out information for old buffer */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* we don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -void yy_load_buffer_state( void ) - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) malloc( sizeof( struct yy_buffer_state ) ); - - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (YY_CHAR *) malloc( (unsigned) (b->yy_buf_size + 2) ); - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - yy_init_buffer( b, file ); - - return ( b ); - } - - -void yy_delete_buffer( YY_BUFFER_STATE b ) - { - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - free( (char *) b->yy_ch_buf ); - free( (char *) b ); - } - - -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) - { - b->yy_input_file = file; - - /* we put in the '\n' and start reading from [1] so that an - * initial match-at-newline will be true. - */ - - b->yy_ch_buf[0] = '\n'; - b->yy_n_chars = 1; - - /* we always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[1]; - - b->yy_eof_status = EOF_NOT_SEEN; - } -# line 488 "scan.l" - - - -int yywrap() - - { - if ( --num_input_files > 0 ) - { - set_input_file( *++input_files ); - return ( 0 ); - } - - else - return ( 1 ); - } - - -/* set_input_file - open the given file (if NULL, stdin) for scanning */ - -void set_input_file( file ) -char *file; - - { - if ( file ) - { - infilename = file; - yyin = fopen( infilename, "r" ); - - if ( yyin == NULL ) - lerrsf( "can't open %s", file ); - } - - else - { - yyin = stdin; - infilename = ""; - } - } diff --git a/src/libCom/flex/scan.l.DISTRIB b/src/libCom/flex/scan.l.DISTRIB deleted file mode 100644 index a566181d3..000000000 --- a/src/libCom/flex/scan.l.DISTRIB +++ /dev/null @@ -1,525 +0,0 @@ - -/* scan.l - scanner for flex input */ - -%{ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#undef yywrap - -#define ACTION_ECHO fprintf( temp_action_file, "%s", yytext ) -#define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" ); - -#undef YY_DECL -#define YY_DECL \ - int flexscan() - -#define RETURNCHAR \ - yylval = yytext[0]; \ - return ( CHAR ); - -#define RETURNNAME \ - (void) strcpy( nmstr, (char *) yytext ); \ - return ( NAME ); - -#define PUT_BACK_STRING(str, start) \ - for ( i = strlen( (char *) (str) ) - 1; i >= start; --i ) \ - unput((str)[i]) - -#define CHECK_REJECT(str) \ - if ( all_upper( str ) ) \ - reject = true; - -#define CHECK_YYMORE(str) \ - if ( all_lower( str ) ) \ - yymore_used = true; -%} - -%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE -%x FIRSTCCL CCL ACTION RECOVER BRACEERROR C_COMMENT ACTION_COMMENT -%x ACTION_STRING PERCENT_BRACE_ACTION USED_LIST CODEBLOCK_2 XLATION - -WS [ \t\f]+ -OPTWS [ \t\f]* -NOT_WS [^ \t\f\r\n] - -NAME [a-z_][a-z_0-9-]* -NOT_NAME [^a-z_\r\n]+ - -SCNAME {NAME} - -ESCSEQ \\([^\r\n]|[0-9]{1,3}|x[0-9a-f]{1,2}) - -%% - static int bracelevel, didadef; - int i, indented_code = false, checking_used = false, new_xlation = false; - int doing_codeblock = false; - Char nmdef[MAXLINE], myesc(); - -^{WS} indented_code = true; BEGIN(CODEBLOCK); -^#.*\r?\n ++linenum; /* treat as a comment */ -^"/*" ECHO; BEGIN(C_COMMENT); -^"%s"{NAME}? return ( SCDECL ); -^"%x"{NAME}? return ( XSCDECL ); -^"%{".*\r?\n { - ++linenum; - line_directive_out( stdout ); - indented_code = false; - BEGIN(CODEBLOCK); - } - -{WS} return ( WHITESPACE ); - -^"%%".* { - sectnum = 2; - line_directive_out( stdout ); - BEGIN(SECT2PROLOG); - return ( SECTEND ); - } - -^"%used" { - pinpoint_message( "warning - %%used/%%unused have been deprecated" ); - checking_used = REALLY_USED; BEGIN(USED_LIST); - } -^"%unused" { - checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); - pinpoint_message( "warning - %%used/%%unused have been deprecated" ); - checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); - } - - -^"%"[aeknopt]" ".*\r?\n { -#ifdef NOTDEF - fprintf( stderr, - "old-style lex command at line %d ignored:\n\t%s", - linenum, yytext ); -#endif - ++linenum; - } - -^"%"[cr]{OPTWS} /* ignore old lex directive */ - -%t{OPTWS}\r?\n { - ++linenum; - xlation = - (int *) malloc( sizeof( int ) * (unsigned) csize ); - - if ( ! xlation ) - flexfatal( - "dynamic memory failure building %t table" ); - - for ( i = 0; i < csize; ++i ) - xlation[i] = 0; - - num_xlations = 0; - - BEGIN(XLATION); - } - -^"%"[^sxanpekotcru{}]{OPTWS} synerr( "unrecognized '%' directive" ); - -^{NAME} { - (void) strcpy( nmstr, (char *) yytext ); - didadef = false; - BEGIN(PICKUPDEF); - } - -{SCNAME} RETURNNAME; -^{OPTWS}\r?\n ++linenum; /* allows blank lines in section 1 */ -{OPTWS}\r?\n ++linenum; return ( '\n' ); -. synerr( "illegal character" ); BEGIN(RECOVER); - - -"*/" ECHO; BEGIN(INITIAL); -"*/".*\r?\n ++linenum; ECHO; BEGIN(INITIAL); -[^*\r\n]+ ECHO; -"*" ECHO; -\r?\n ++linenum; ECHO; - - -^"%}".*\r?\n ++linenum; BEGIN(INITIAL); -"reject" ECHO; CHECK_REJECT(yytext); -"yymore" ECHO; CHECK_YYMORE(yytext); -{NAME}|{NOT_NAME}|. ECHO; -\r?\n { - ++linenum; - ECHO; - if ( indented_code ) - BEGIN(INITIAL); - } - - -{WS} /* separates name and definition */ - -{NOT_WS}.* { - (void) strcpy( (char *) nmdef, (char *) yytext ); - - for ( i = strlen( (char *) nmdef ) - 1; - i >= 0 && - (nmdef[i] == ' ' || nmdef[i] == '\t'); - --i ) - ; - - nmdef[i + 1] = '\0'; - - ndinstal( nmstr, nmdef ); - didadef = true; - } - -\r?\n { - if ( ! didadef ) - synerr( "incomplete name definition" ); - BEGIN(INITIAL); - ++linenum; - } - -.*\r?\n ++linenum; BEGIN(INITIAL); RETURNNAME; - - -\r?\n ++linenum; BEGIN(INITIAL); -{WS} -"reject" { - if ( all_upper( yytext ) ) - reject_really_used = checking_used; - else - synerr( "unrecognized %used/%unused construct" ); - } -"yymore" { - if ( all_lower( yytext ) ) - yymore_really_used = checking_used; - else - synerr( "unrecognized %used/%unused construct" ); - } -{NOT_WS}+ synerr( "unrecognized %used/%unused construct" ); - - -"%t"{OPTWS}\r?\n ++linenum; BEGIN(INITIAL); -^{OPTWS}[0-9]+ ++num_xlations; new_xlation = true; -^. synerr( "bad row in translation table" ); -{WS} /* ignore whitespace */ - -{ESCSEQ} { - xlation[myesc( yytext )] = - (new_xlation ? num_xlations : -num_xlations); - new_xlation = false; - } -. { - xlation[yytext[0]] = - (new_xlation ? num_xlations : -num_xlations); - new_xlation = false; - } - -\r?\n ++linenum; - - -.*\r?\n/{NOT_WS} { - ++linenum; - ACTION_ECHO; - MARK_END_OF_PROLOG; - BEGIN(SECT2); - } - -.*\r?\n ++linenum; ACTION_ECHO; - -<> MARK_END_OF_PROLOG; yyterminate(); - -^{OPTWS}\r?\n ++linenum; /* allow blank lines in section 2 */ - -^({WS}|"%{") { - indented_code = (yytext[0] != '%'); - doing_codeblock = true; - bracelevel = 1; - - if ( indented_code ) - ACTION_ECHO; - - BEGIN(CODEBLOCK_2); - } - -"<" BEGIN(SC); return ( '<' ); -^"^" return ( '^' ); -\" BEGIN(QUOTE); return ( '"' ); -"{"/[0-9] BEGIN(NUM); return ( '{' ); -"{"[^0-9\r\n][^}\r\n]* BEGIN(BRACEERROR); -"$"/[ \t\r\n] return ( '$' ); - -{WS}"%{" { - bracelevel = 1; - BEGIN(PERCENT_BRACE_ACTION); - return ( '\n' ); - } -{WS}"|".*\r?\n continued_action = true; ++linenum; return ( '\n' ); - -{WS} { - /* this rule is separate from the one below because - * otherwise we get variable trailing context, so - * we can't build the scanner using -{f,F} - */ - bracelevel = 0; - continued_action = false; - BEGIN(ACTION); - return ( '\n' ); - } - -{OPTWS}/\r?\n { - bracelevel = 0; - continued_action = false; - BEGIN(ACTION); - return ( '\n' ); - } - -^{OPTWS}\r?\n ++linenum; return ( '\n' ); - -"<>" return ( EOF_OP ); - -^"%%".* { - sectnum = 3; - BEGIN(SECT3); - return ( EOF ); /* to stop the parser */ - } - -"["([^\\\]\r\n]|{ESCSEQ})+"]" { - int cclval; - - (void) strcpy( nmstr, (char *) yytext ); - - /* check to see if we've already encountered this ccl */ - if ( (cclval = ccllookup( (Char *) nmstr )) ) - { - yylval = cclval; - ++cclreuse; - return ( PREVCCL ); - } - else - { - /* we fudge a bit. We know that this ccl will - * soon be numbered as lastccl + 1 by cclinit - */ - cclinstal( (Char *) nmstr, lastccl + 1 ); - - /* push back everything but the leading bracket - * so the ccl can be rescanned - */ - PUT_BACK_STRING((Char *) nmstr, 1); - - BEGIN(FIRSTCCL); - return ( '[' ); - } - } - -"{"{NAME}"}" { - register Char *nmdefptr; - Char *ndlookup(); - - (void) strcpy( nmstr, (char *) yytext ); - nmstr[yyleng - 1] = '\0'; /* chop trailing brace */ - - /* lookup from "nmstr + 1" to chop leading brace */ - if ( ! (nmdefptr = ndlookup( nmstr + 1 )) ) - synerr( "undefined {name}" ); - - else - { /* push back name surrounded by ()'s */ - unput(')'); - PUT_BACK_STRING(nmdefptr, 0); - unput('('); - } - } - -[/|*+?.()] return ( yytext[0] ); -. RETURNCHAR; -\r?\n ++linenum; return ( '\n' ); - - -"," return ( ',' ); -">" BEGIN(SECT2); return ( '>' ); -">"/"^" BEGIN(CARETISBOL); return ( '>' ); -{SCNAME} RETURNNAME; -. synerr( "bad start condition name" ); - -"^" BEGIN(SECT2); return ( '^' ); - - -[^"\r\n] RETURNCHAR; -\" BEGIN(SECT2); return ( '"' ); - -\r?\n { - synerr( "missing quote" ); - BEGIN(SECT2); - ++linenum; - return ( '"' ); - } - - -"^"/[^-\r\n] BEGIN(CCL); return ( '^' ); -"^"/- return ( '^' ); -- BEGIN(CCL); yylval = '-'; return ( CHAR ); -. BEGIN(CCL); RETURNCHAR; - --/[^\]\r\n] return ( '-' ); -[^\]\r\n] RETURNCHAR; -"]" BEGIN(SECT2); return ( ']' ); - - -[0-9]+ { - yylval = myctoi( yytext ); - return ( NUMBER ); - } - -"," return ( ',' ); -"}" BEGIN(SECT2); return ( '}' ); - -. { - synerr( "bad character inside {}'s" ); - BEGIN(SECT2); - return ( '}' ); - } - -\r?\n { - synerr( "missing }" ); - BEGIN(SECT2); - ++linenum; - return ( '}' ); - } - - -"}" synerr( "bad name in {}'s" ); BEGIN(SECT2); -\r?\n synerr( "missing }" ); ++linenum; BEGIN(SECT2); - - -{OPTWS}"%}".* bracelevel = 0; -"reject" { - ACTION_ECHO; - CHECK_REJECT(yytext); - } -"yymore" { - ACTION_ECHO; - CHECK_YYMORE(yytext); - } -{NAME}|{NOT_NAME}|. ACTION_ECHO; -\r?\n { - ++linenum; - ACTION_ECHO; - if ( bracelevel == 0 || - (doing_codeblock && indented_code) ) - { - if ( ! doing_codeblock ) - fputs( "\tYY_BREAK\n", temp_action_file ); - - doing_codeblock = false; - BEGIN(SECT2); - } - } - - - /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */ -"{" ACTION_ECHO; ++bracelevel; -"}" ACTION_ECHO; --bracelevel; -[^a-z_{}"'/\r\n]+ ACTION_ECHO; -{NAME} ACTION_ECHO; -"/*" ACTION_ECHO; BEGIN(ACTION_COMMENT); -"'"([^'\\\r\n]|\\.)*"'" ACTION_ECHO; /* character constant */ -\" ACTION_ECHO; BEGIN(ACTION_STRING); -\r?\n { - ++linenum; - ACTION_ECHO; - if ( bracelevel == 0 ) - { - fputs( "\tYY_BREAK\n", temp_action_file ); - BEGIN(SECT2); - } - } -. ACTION_ECHO; - -"*/" ACTION_ECHO; BEGIN(ACTION); -[^*\r\n]+ ACTION_ECHO; -"*" ACTION_ECHO; -\r?\n ++linenum; ACTION_ECHO; -. ACTION_ECHO; - -[^"\\\r\n]+ ACTION_ECHO; -\\. ACTION_ECHO; -\r?\n ++linenum; ACTION_ECHO; -\" ACTION_ECHO; BEGIN(ACTION); -. ACTION_ECHO; - -<> { - synerr( "EOF encountered inside an action" ); - yyterminate(); - } - - -{ESCSEQ} { - yylval = myesc( yytext ); - return ( CHAR ); - } - -{ESCSEQ} { - yylval = myesc( yytext ); - BEGIN(CCL); - return ( CHAR ); - } - - -.*(\r?\n?) ECHO; -%% - - -int yywrap() - - { - if ( --num_input_files > 0 ) - { - set_input_file( *++input_files ); - return ( 0 ); - } - - else - return ( 1 ); - } - - -/* set_input_file - open the given file (if NULL, stdin) for scanning */ - -void set_input_file( file ) -char *file; - - { - if ( file ) - { - infilename = file; - yyin = fopen( infilename, "r" ); - - if ( yyin == NULL ) - lerrsf( "can't open %s", file ); - } - - else - { - yyin = stdin; - infilename = ""; - } - } diff --git a/src/libCom/flex/sym.c b/src/libCom/flex/sym.c deleted file mode 100644 index 45e1c5409..000000000 --- a/src/libCom/flex/sym.c +++ /dev/null @@ -1,290 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* sym - symbol table routines */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - - -/* declare functions that have forward references */ - -int hashfunct (char[], int); - - -struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE]; -struct hash_entry *sctbl[START_COND_HASH_SIZE]; -struct hash_entry *ccltab[CCL_HASH_SIZE]; - -struct hash_entry *findsym(char *sym, struct hash_entry **table, int table_size); - - -/* addsym - add symbol and definitions to symbol table - * - * synopsis - * char sym[], *str_def; - * int int_def; - * hash_table table; - * int table_size; - * 0 / -1 = addsym( sym, def, int_def, table, table_size ); - * - * -1 is returned if the symbol already exists, and the change not made. - */ - -int addsym(char *sym, char *str_def, int int_def, struct hash_entry **table, int table_size) -{ - int hash_val = hashfunct( sym, table_size ); - struct hash_entry *sym_entry = table[hash_val]; - struct hash_entry *new_entry; - struct hash_entry *successor; - - while ( sym_entry ) - { - if ( ! strcmp( sym, sym_entry->name ) ) - { /* entry already exists */ - return ( -1 ); - } - - sym_entry = sym_entry->next; - } - - /* create new entry */ - new_entry = (struct hash_entry *) malloc( sizeof( struct hash_entry ) ); - - if ( new_entry == NULL ) - flexfatal( "symbol table memory allocation failed" ); - - if ( (successor = table[hash_val]) ) - { - new_entry->next = successor; - successor->prev = new_entry; - } - else - new_entry->next = NULL; - - new_entry->prev = NULL; - new_entry->name = sym; - new_entry->str_val = str_def; - new_entry->int_val = int_def; - - table[hash_val] = new_entry; - - return ( 0 ); - } - - -/* cclinstal - save the text of a character class - * - * synopsis - * Char ccltxt[]; - * int cclnum; - * cclinstal( ccltxt, cclnum ); - */ - -void cclinstal(Char *ccltxt, int cclnum) -{ - /* we don't bother checking the return status because we are not called - * unless the symbol is new - */ - Char *copy_unsigned_string(); - - (void) addsym( (char *) copy_unsigned_string( ccltxt ), (char *) 0, cclnum, - ccltab, CCL_HASH_SIZE ); - } - - -/* ccllookup - lookup the number associated with character class text - * - * synopsis - * Char ccltxt[]; - * int ccllookup, cclval; - * cclval/0 = ccllookup( ccltxt ); - */ - -int ccllookup(Char *ccltxt) -{ - return ( findsym( (char *) ccltxt, ccltab, CCL_HASH_SIZE )->int_val ); - } - - -/* findsym - find symbol in symbol table - * - * synopsis - * char sym[]; - * hash_table table; - * int table_size; - * struct hash_entry *sym_entry, *findsym(); - * sym_entry = findsym( sym, table, table_size ); - */ - -struct hash_entry *findsym(char *sym, struct hash_entry **table, int table_size) -{ - struct hash_entry *sym_entry = table[hashfunct( sym, table_size )]; - static struct hash_entry empty_entry = - { - (struct hash_entry *) 0, (struct hash_entry *) 0, NULL, NULL, 0, - } ; - - while ( sym_entry ) - { - if ( ! strcmp( sym, sym_entry->name ) ) - return ( sym_entry ); - sym_entry = sym_entry->next; - } - - return ( &empty_entry ); - } - - -/* hashfunct - compute the hash value for "str" and hash size "hash_size" - * - * synopsis - * char str[]; - * int hash_size, hash_val; - * hash_val = hashfunct( str, hash_size ); - */ - -int hashfunct(char *str, int hash_size) -{ - int hashval; - int locstr; - - hashval = 0; - locstr = 0; - - while ( str[locstr] ) - hashval = ((hashval << 1) + str[locstr++]) % hash_size; - - return ( hashval ); - } - - -/* ndinstal - install a name definition - * - * synopsis - * char nd[]; - * Char def[]; - * ndinstal( nd, def ); - */ - -void ndinstal(char *nd, Char *def) -{ - char *copy_string(); - Char *copy_unsigned_string(); - - if ( addsym( copy_string( nd ), (char *) copy_unsigned_string( def ), 0, - ndtbl, NAME_TABLE_HASH_SIZE ) ) - synerr( "name defined twice" ); - } - - -/* ndlookup - lookup a name definition - * - * synopsis - * char nd[], *def; - * char *ndlookup(); - * def/NULL = ndlookup( nd ); - */ - -Char *ndlookup(char *nd) -{ - return ( (Char *) findsym( nd, ndtbl, NAME_TABLE_HASH_SIZE )->str_val ); - } - - -/* scinstal - make a start condition - * - * synopsis - * char str[]; - * int xcluflg; - * scinstal( str, xcluflg ); - * - * NOTE - * the start condition is Exclusive if xcluflg is true - */ - -void scinstal(char *str, int xcluflg) -{ - char *copy_string(); - - /* bit of a hack. We know how the default start-condition is - * declared, and don't put out a define for it, because it - * would come out as "#define 0 1" - */ - /* actually, this is no longer the case. The default start-condition - * is now called "INITIAL". But we keep the following for the sake - * of future robustness. - */ - - if ( strcmp( str, "0" ) ) - printf( "#define %s %d\n", str, lastsc ); - - if ( ++lastsc >= current_max_scs ) - { - current_max_scs += MAX_SCS_INCREMENT; - - ++num_reallocs; - - scset = reallocate_integer_array( scset, current_max_scs ); - scbol = reallocate_integer_array( scbol, current_max_scs ); - scxclu = reallocate_integer_array( scxclu, current_max_scs ); - sceof = reallocate_integer_array( sceof, current_max_scs ); - scname = reallocate_char_ptr_array( scname, current_max_scs ); - actvsc = reallocate_integer_array( actvsc, current_max_scs ); - } - - scname[lastsc] = copy_string( str ); - - if ( addsym( scname[lastsc], (char *) 0, lastsc, - sctbl, START_COND_HASH_SIZE ) ) - format_pinpoint_message( "start condition %s declared twice", str ); - - scset[lastsc] = mkstate( SYM_EPSILON ); - scbol[lastsc] = mkstate( SYM_EPSILON ); - scxclu[lastsc] = xcluflg; - sceof[lastsc] = false; - } - - -/* sclookup - lookup the number associated with a start condition - * - * synopsis - * char str[], scnum; - * int sclookup; - * scnum/0 = sclookup( str ); - */ - -int sclookup(char *str) -{ - return ( findsym( str, sctbl, START_COND_HASH_SIZE )->int_val ); - } diff --git a/src/libCom/flex/tblcmp.c b/src/libCom/flex/tblcmp.c deleted file mode 100644 index 3e4c4744b..000000000 --- a/src/libCom/flex/tblcmp.c +++ /dev/null @@ -1,904 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* tblcmp - table compression routines */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - - -/* declarations for functions that have forward references */ - -void mkentry (int*, int, int, int, int); -void mkprot (int[], int, int); -void mktemplate (int[], int, int); -void mv2front (int); -int tbldiff (int[], int, int[]); - - -/* bldtbl - build table entries for dfa state - * - * synopsis - * int state[numecs], statenum, totaltrans, comstate, comfreq; - * bldtbl( state, statenum, totaltrans, comstate, comfreq ); - * - * State is the statenum'th dfa state. It is indexed by equivalence class and - * gives the number of the state to enter for a given equivalence class. - * totaltrans is the total number of transitions out of the state. Comstate - * is that state which is the destination of the most transitions out of State. - * Comfreq is how many transitions there are out of State to Comstate. - * - * A note on terminology: - * "protos" are transition tables which have a high probability of - * either being redundant (a state processed later will have an identical - * transition table) or nearly redundant (a state processed later will have - * many of the same out-transitions). A "most recently used" queue of - * protos is kept around with the hope that most states will find a proto - * which is similar enough to be usable, and therefore compacting the - * output tables. - * "templates" are a special type of proto. If a transition table is - * homogeneous or nearly homogeneous (all transitions go to the same - * destination) then the odds are good that future states will also go - * to the same destination state on basically the same character set. - * These homogeneous states are so common when dealing with large rule - * sets that they merit special attention. If the transition table were - * simply made into a proto, then (typically) each subsequent, similar - * state will differ from the proto for two out-transitions. One of these - * out-transitions will be that character on which the proto does not go - * to the common destination, and one will be that character on which the - * state does not go to the common destination. Templates, on the other - * hand, go to the common state on EVERY transition character, and therefore - * cost only one difference. - */ - -void bldtbl(int *state, int statenum, int totaltrans, int comstate, int comfreq) -{ - int extptr, extrct[2][CSIZE + 1]; - int mindiff, minprot, i, d; - int checkcom; - - /* If extptr is 0 then the first array of extrct holds the result of the - * "best difference" to date, which is those transitions which occur in - * "state" but not in the proto which, to date, has the fewest differences - * between itself and "state". If extptr is 1 then the second array of - * extrct hold the best difference. The two arrays are toggled - * between so that the best difference to date can be kept around and - * also a difference just created by checking against a candidate "best" - * proto. - */ - - extptr = 0; - - /* if the state has too few out-transitions, don't bother trying to - * compact its tables - */ - - if ( (totaltrans * 100) < (numecs * PROTO_SIZE_PERCENTAGE) ) - mkentry( state, numecs, statenum, JAMSTATE, totaltrans ); - - else - { - /* checkcom is true if we should only check "state" against - * protos which have the same "comstate" value - */ - - checkcom = comfreq * 100 > totaltrans * CHECK_COM_PERCENTAGE; - - minprot = firstprot; - mindiff = totaltrans; - - if ( checkcom ) - { - /* find first proto which has the same "comstate" */ - for ( i = firstprot; i != NIL; i = protnext[i] ) - if ( protcomst[i] == comstate ) - { - minprot = i; - mindiff = tbldiff( state, minprot, extrct[extptr] ); - break; - } - } - - else - { - /* since we've decided that the most common destination out - * of "state" does not occur with a high enough frequency, - * we set the "comstate" to zero, assuring that if this state - * is entered into the proto list, it will not be considered - * a template. - */ - comstate = 0; - - if ( firstprot != NIL ) - { - minprot = firstprot; - mindiff = tbldiff( state, minprot, extrct[extptr] ); - } - } - - /* we now have the first interesting proto in "minprot". If - * it matches within the tolerances set for the first proto, - * we don't want to bother scanning the rest of the proto list - * to see if we have any other reasonable matches. - */ - - if ( mindiff * 100 > totaltrans * FIRST_MATCH_DIFF_PERCENTAGE ) - { /* not a good enough match. Scan the rest of the protos */ - for ( i = minprot; i != NIL; i = protnext[i] ) - { - d = tbldiff( state, i, extrct[1 - extptr] ); - if ( d < mindiff ) - { - extptr = 1 - extptr; - mindiff = d; - minprot = i; - } - } - } - - /* check if the proto we've decided on as our best bet is close - * enough to the state we want to match to be usable - */ - - if ( mindiff * 100 > totaltrans * ACCEPTABLE_DIFF_PERCENTAGE ) - { - /* no good. If the state is homogeneous enough, we make a - * template out of it. Otherwise, we make a proto. - */ - - if ( comfreq * 100 >= totaltrans * TEMPLATE_SAME_PERCENTAGE ) - mktemplate( state, statenum, comstate ); - - else - { - mkprot( state, statenum, comstate ); - mkentry( state, numecs, statenum, JAMSTATE, totaltrans ); - } - } - - else - { /* use the proto */ - mkentry( extrct[extptr], numecs, statenum, - prottbl[minprot], mindiff ); - - /* if this state was sufficiently different from the proto - * we built it from, make it, too, a proto - */ - - if ( mindiff * 100 >= totaltrans * NEW_PROTO_DIFF_PERCENTAGE ) - mkprot( state, statenum, comstate ); - - /* since mkprot added a new proto to the proto queue, it's possible - * that "minprot" is no longer on the proto queue (if it happened - * to have been the last entry, it would have been bumped off). - * If it's not there, then the new proto took its physical place - * (though logically the new proto is at the beginning of the - * queue), so in that case the following call will do nothing. - */ - - mv2front( minprot ); - } - } - } - - -/* cmptmps - compress template table entries - * - * synopsis - * cmptmps(); - * - * template tables are compressed by using the 'template equivalence - * classes', which are collections of transition character equivalence - * classes which always appear together in templates - really meta-equivalence - * classes. until this point, the tables for templates have been stored - * up at the top end of the nxt array; they will now be compressed and have - * table entries made for them. - */ - -void cmptmps(void) -{ - int tmpstorage[CSIZE + 1]; - int *tmp = tmpstorage, i, j; - int totaltrans, trans; - - peakpairs = numtemps * numecs + tblend; - - if ( usemecs ) - { - /* create equivalence classes base on data gathered on template - * transitions - */ - - nummecs = cre8ecs( tecfwd, tecbck, numecs ); - } - - else - nummecs = numecs; - - if ( lastdfa + numtemps + 1 >= current_max_dfas ) - increase_max_dfas(); - - /* loop through each template */ - - for ( i = 1; i <= numtemps; ++i ) - { - totaltrans = 0; /* number of non-jam transitions out of this template */ - - for ( j = 1; j <= numecs; ++j ) - { - trans = tnxt[numecs * i + j]; - - if ( usemecs ) - { - /* the absolute value of tecbck is the meta-equivalence class - * of a given equivalence class, as set up by cre8ecs - */ - if ( tecbck[j] > 0 ) - { - tmp[tecbck[j]] = trans; - - if ( trans > 0 ) - ++totaltrans; - } - } - - else - { - tmp[j] = trans; - - if ( trans > 0 ) - ++totaltrans; - } - } - - /* it is assumed (in a rather subtle way) in the skeleton that - * if we're using meta-equivalence classes, the def[] entry for - * all templates is the jam template, i.e., templates never default - * to other non-jam table entries (e.g., another template) - */ - - /* leave room for the jam-state after the last real state */ - mkentry( tmp, nummecs, lastdfa + i + 1, JAMSTATE, totaltrans ); - } - } - - - -/* expand_nxt_chk - expand the next check arrays */ - -void expand_nxt_chk(void) -{ - int old_max = current_max_xpairs; - - current_max_xpairs += MAX_XPAIRS_INCREMENT; - - ++num_reallocs; - - nxt = reallocate_integer_array( nxt, current_max_xpairs ); - chk = reallocate_integer_array( chk, current_max_xpairs ); - - memset( (char *) (chk + old_max), 0, - MAX_XPAIRS_INCREMENT * sizeof( int ) / sizeof( char ) ); - } - - -/* find_table_space - finds a space in the table for a state to be placed - * - * synopsis - * int *state, numtrans, block_start; - * int find_table_space(); - * - * block_start = find_table_space( state, numtrans ); - * - * State is the state to be added to the full speed transition table. - * Numtrans is the number of out-transitions for the state. - * - * find_table_space() returns the position of the start of the first block (in - * chk) able to accommodate the state - * - * In determining if a state will or will not fit, find_table_space() must take - * into account the fact that an end-of-buffer state will be added at [0], - * and an action number will be added in [-1]. - */ - -int find_table_space(int *state, int numtrans) -{ - /* firstfree is the position of the first possible occurrence of two - * consecutive unused records in the chk and nxt arrays - */ - int i; - int *state_ptr, *chk_ptr; - int *ptr_to_last_entry_in_state; - - /* if there are too many out-transitions, put the state at the end of - * nxt and chk - */ - if ( numtrans > MAX_XTIONS_FULL_INTERIOR_FIT ) - { - /* if table is empty, return the first available spot in chk/nxt, - * which should be 1 - */ - if ( tblend < 2 ) - return ( 1 ); - - i = tblend - numecs; /* start searching for table space near the - * end of chk/nxt arrays - */ - } - - else - i = firstfree; /* start searching for table space from the - * beginning (skipping only the elements - * which will definitely not hold the new - * state) - */ - - while ( 1 ) /* loops until a space is found */ - { - if ( i + numecs > current_max_xpairs ) - expand_nxt_chk(); - - /* loops until space for end-of-buffer and action number are found */ - while ( 1 ) - { - if ( chk[i - 1] == 0 ) /* check for action number space */ - { - if ( chk[i] == 0 ) /* check for end-of-buffer space */ - break; - - else - i += 2; /* since i != 0, there is no use checking to - * see if (++i) - 1 == 0, because that's the - * same as i == 0, so we skip a space - */ - } - - else - ++i; - - if ( i + numecs > current_max_xpairs ) - expand_nxt_chk(); - } - - /* if we started search from the beginning, store the new firstfree for - * the next call of find_table_space() - */ - if ( numtrans <= MAX_XTIONS_FULL_INTERIOR_FIT ) - firstfree = i + 1; - - /* check to see if all elements in chk (and therefore nxt) that are - * needed for the new state have not yet been taken - */ - - state_ptr = &state[1]; - ptr_to_last_entry_in_state = &chk[i + numecs + 1]; - - for ( chk_ptr = &chk[i + 1]; chk_ptr != ptr_to_last_entry_in_state; - ++chk_ptr ) - if ( *(state_ptr++) != 0 && *chk_ptr != 0 ) - break; - - if ( chk_ptr == ptr_to_last_entry_in_state ) - return ( i ); - - else - ++i; - } - } - - -/* inittbl - initialize transition tables - * - * synopsis - * inittbl(); - * - * Initializes "firstfree" to be one beyond the end of the table. Initializes - * all "chk" entries to be zero. Note that templates are built in their - * own tbase/tdef tables. They are shifted down to be contiguous - * with the non-template entries during table generation. - */ -void inittbl(void) -{ - int i; - - memset( (char *) chk, 0, - current_max_xpairs * sizeof( int ) / sizeof( char ) ); - - tblend = 0; - firstfree = tblend + 1; - numtemps = 0; - - if ( usemecs ) - { - /* set up doubly-linked meta-equivalence classes - * these are sets of equivalence classes which all have identical - * transitions out of TEMPLATES - */ - - tecbck[1] = NIL; - - for ( i = 2; i <= numecs; ++i ) - { - tecbck[i] = i - 1; - tecfwd[i - 1] = i; - } - - tecfwd[numecs] = NIL; - } - } - - -/* mkdeftbl - make the default, "jam" table entries - * - * synopsis - * mkdeftbl(); - */ - -void mkdeftbl(void) -{ - int i; - - jamstate = lastdfa + 1; - - ++tblend; /* room for transition on end-of-buffer character */ - - if ( tblend + numecs > current_max_xpairs ) - expand_nxt_chk(); - - /* add in default end-of-buffer transition */ - nxt[tblend] = end_of_buffer_state; - chk[tblend] = jamstate; - - for ( i = 1; i <= numecs; ++i ) - { - nxt[tblend + i] = 0; - chk[tblend + i] = jamstate; - } - - jambase = tblend; - - base[jamstate] = jambase; - def[jamstate] = 0; - - tblend += numecs; - ++numtemps; - } - - -/* mkentry - create base/def and nxt/chk entries for transition array - * - * synopsis - * int state[numchars + 1], numchars, statenum, deflink, totaltrans; - * mkentry( state, numchars, statenum, deflink, totaltrans ); - * - * "state" is a transition array "numchars" characters in size, "statenum" - * is the offset to be used into the base/def tables, and "deflink" is the - * entry to put in the "def" table entry. If "deflink" is equal to - * "JAMSTATE", then no attempt will be made to fit zero entries of "state" - * (i.e., jam entries) into the table. It is assumed that by linking to - * "JAMSTATE" they will be taken care of. In any case, entries in "state" - * marking transitions to "SAME_TRANS" are treated as though they will be - * taken care of by whereever "deflink" points. "totaltrans" is the total - * number of transitions out of the state. If it is below a certain threshold, - * the tables are searched for an interior spot that will accommodate the - * state array. - */ - -void mkentry(int *state, int numchars, int statenum, int deflink, int totaltrans) -{ - int minec, maxec, i, baseaddr; - int tblbase, tbllast; - - if ( totaltrans == 0 ) - { /* there are no out-transitions */ - if ( deflink == JAMSTATE ) - base[statenum] = JAMSTATE; - else - base[statenum] = 0; - - def[statenum] = deflink; - return; - } - - for ( minec = 1; minec <= numchars; ++minec ) - { - if ( state[minec] != SAME_TRANS ) - if ( state[minec] != 0 || deflink != JAMSTATE ) - break; - } - - if ( totaltrans == 1 ) - { - /* there's only one out-transition. Save it for later to fill - * in holes in the tables. - */ - stack1( statenum, minec, state[minec], deflink ); - return; - } - - for ( maxec = numchars; maxec > 0; --maxec ) - { - if ( state[maxec] != SAME_TRANS ) - if ( state[maxec] != 0 || deflink != JAMSTATE ) - break; - } - - /* Whether we try to fit the state table in the middle of the table - * entries we have already generated, or if we just take the state - * table at the end of the nxt/chk tables, we must make sure that we - * have a valid base address (i.e., non-negative). Note that not only are - * negative base addresses dangerous at run-time (because indexing the - * next array with one and a low-valued character might generate an - * array-out-of-bounds error message), but at compile-time negative - * base addresses denote TEMPLATES. - */ - - /* find the first transition of state that we need to worry about. */ - if ( totaltrans * 100 <= numchars * INTERIOR_FIT_PERCENTAGE ) - { /* attempt to squeeze it into the middle of the tabls */ - baseaddr = firstfree; - - while ( baseaddr < minec ) - { - /* using baseaddr would result in a negative base address below - * find the next free slot - */ - for ( ++baseaddr; chk[baseaddr] != 0; ++baseaddr ) - ; - } - - if ( baseaddr + maxec - minec >= current_max_xpairs ) - expand_nxt_chk(); - - for ( i = minec; i <= maxec; ++i ) - if ( state[i] != SAME_TRANS ) - if ( state[i] != 0 || deflink != JAMSTATE ) - if ( chk[baseaddr + i - minec] != 0 ) - { /* baseaddr unsuitable - find another */ - for ( ++baseaddr; - baseaddr < current_max_xpairs && - chk[baseaddr] != 0; - ++baseaddr ) - ; - - if ( baseaddr + maxec - minec >= current_max_xpairs ) - expand_nxt_chk(); - - /* reset the loop counter so we'll start all - * over again next time it's incremented - */ - - i = minec - 1; - } - } - - else - { - /* ensure that the base address we eventually generate is - * non-negative - */ - baseaddr = max( tblend + 1, minec ); - } - - tblbase = baseaddr - minec; - tbllast = tblbase + maxec; - - if ( tbllast >= current_max_xpairs ) - expand_nxt_chk(); - - base[statenum] = tblbase; - def[statenum] = deflink; - - for ( i = minec; i <= maxec; ++i ) - if ( state[i] != SAME_TRANS ) - if ( state[i] != 0 || deflink != JAMSTATE ) - { - nxt[tblbase + i] = state[i]; - chk[tblbase + i] = statenum; - } - - if ( baseaddr == firstfree ) - /* find next free slot in tables */ - for ( ++firstfree; chk[firstfree] != 0; ++firstfree ) - ; - - tblend = max( tblend, tbllast ); - } - - -/* mk1tbl - create table entries for a state (or state fragment) which - * has only one out-transition - * - * synopsis - * int state, sym, onenxt, onedef; - * mk1tbl( state, sym, onenxt, onedef ); - */ - -void mk1tbl(int state, int sym, int onenxt, int onedef) -{ - if ( firstfree < sym ) - firstfree = sym; - - while ( chk[firstfree] != 0 ) - if ( ++firstfree >= current_max_xpairs ) - expand_nxt_chk(); - - base[state] = firstfree - sym; - def[state] = onedef; - chk[firstfree] = state; - nxt[firstfree] = onenxt; - - if ( firstfree > tblend ) - { - tblend = firstfree++; - - if ( firstfree >= current_max_xpairs ) - expand_nxt_chk(); - } - } - - -/* mkprot - create new proto entry - * - * synopsis - * int state[], statenum, comstate; - * mkprot( state, statenum, comstate ); - */ - -void mkprot(int *state, int statenum, int comstate) -{ - int i, slot, tblbase; - - if ( ++numprots >= MSP || numecs * numprots >= PROT_SAVE_SIZE ) - { - /* gotta make room for the new proto by dropping last entry in - * the queue - */ - slot = lastprot; - lastprot = protprev[lastprot]; - protnext[lastprot] = NIL; - } - - else - slot = numprots; - - protnext[slot] = firstprot; - - if ( firstprot != NIL ) - protprev[firstprot] = slot; - - firstprot = slot; - prottbl[slot] = statenum; - protcomst[slot] = comstate; - - /* copy state into save area so it can be compared with rapidly */ - tblbase = numecs * (slot - 1); - - for ( i = 1; i <= numecs; ++i ) - protsave[tblbase + i] = state[i]; - } - - -/* mktemplate - create a template entry based on a state, and connect the state - * to it - * - * synopsis - * int state[], statenum, comstate, totaltrans; - * mktemplate( state, statenum, comstate, totaltrans ); - */ - -void mktemplate(int *state, int statenum, int comstate) -{ - int i, numdiff, tmpbase, tmp[CSIZE + 1]; - Char transset[CSIZE + 1]; - int tsptr; - - ++numtemps; - - tsptr = 0; - - /* calculate where we will temporarily store the transition table - * of the template in the tnxt[] array. The final transition table - * gets created by cmptmps() - */ - - tmpbase = numtemps * numecs; - - if ( tmpbase + numecs >= current_max_template_xpairs ) - { - current_max_template_xpairs += MAX_TEMPLATE_XPAIRS_INCREMENT; - - ++num_reallocs; - - tnxt = reallocate_integer_array( tnxt, current_max_template_xpairs ); - } - - for ( i = 1; i <= numecs; ++i ) - if ( state[i] == 0 ) - tnxt[tmpbase + i] = 0; - else - { - transset[tsptr++] = i; - tnxt[tmpbase + i] = comstate; - } - - if ( usemecs ) - mkeccl( transset, tsptr, tecfwd, tecbck, numecs, 0 ); - - mkprot( tnxt + tmpbase, -numtemps, comstate ); - - /* we rely on the fact that mkprot adds things to the beginning - * of the proto queue - */ - - numdiff = tbldiff( state, firstprot, tmp ); - mkentry( tmp, numecs, statenum, -numtemps, numdiff ); - } - - -/* mv2front - move proto queue element to front of queue - * - * synopsis - * int qelm; - * mv2front( qelm ); - */ - -void mv2front(int qelm) -{ - if ( firstprot != qelm ) - { - if ( qelm == lastprot ) - lastprot = protprev[lastprot]; - - protnext[protprev[qelm]] = protnext[qelm]; - - if ( protnext[qelm] != NIL ) - protprev[protnext[qelm]] = protprev[qelm]; - - protprev[qelm] = NIL; - protnext[qelm] = firstprot; - protprev[firstprot] = qelm; - firstprot = qelm; - } - } - - -/* place_state - place a state into full speed transition table - * - * synopsis - * int *state, statenum, transnum; - * place_state( state, statenum, transnum ); - * - * State is the statenum'th state. It is indexed by equivalence class and - * gives the number of the state to enter for a given equivalence class. - * Transnum is the number of out-transitions for the state. - */ - -void place_state(int *state, int statenum, int transnum) -{ - int i; - int *state_ptr; - int position = find_table_space( state, transnum ); - - /* base is the table of start positions */ - base[statenum] = position; - - /* put in action number marker; this non-zero number makes sure that - * find_table_space() knows that this position in chk/nxt is taken - * and should not be used for another accepting number in another state - */ - chk[position - 1] = 1; - - /* put in end-of-buffer marker; this is for the same purposes as above */ - chk[position] = 1; - - /* place the state into chk and nxt */ - state_ptr = &state[1]; - - for ( i = 1; i <= numecs; ++i, ++state_ptr ) - if ( *state_ptr != 0 ) - { - chk[position + i] = i; - nxt[position + i] = *state_ptr; - } - - if ( position + numecs > tblend ) - tblend = position + numecs; - } - - -/* stack1 - save states with only one out-transition to be processed later - * - * synopsis - * int statenum, sym, nextstate, deflink; - * stack1( statenum, sym, nextstate, deflink ); - * - * if there's room for another state one the "one-transition" stack, the - * state is pushed onto it, to be processed later by mk1tbl. If there's - * no room, we process the sucker right now. - */ - -void stack1(int statenum, int sym, int nextstate, int deflink) -{ - if ( onesp >= ONE_STACK_SIZE - 1 ) - mk1tbl( statenum, sym, nextstate, deflink ); - - else - { - ++onesp; - onestate[onesp] = statenum; - onesym[onesp] = sym; - onenext[onesp] = nextstate; - onedef[onesp] = deflink; - } - } - - -/* tbldiff - compute differences between two state tables - * - * synopsis - * int state[], pr, ext[]; - * int tbldiff, numdifferences; - * numdifferences = tbldiff( state, pr, ext ) - * - * "state" is the state array which is to be extracted from the pr'th - * proto. "pr" is both the number of the proto we are extracting from - * and an index into the save area where we can find the proto's complete - * state table. Each entry in "state" which differs from the corresponding - * entry of "pr" will appear in "ext". - * Entries which are the same in both "state" and "pr" will be marked - * as transitions to "SAME_TRANS" in "ext". The total number of differences - * between "state" and "pr" is returned as function value. Note that this - * number is "numecs" minus the number of "SAME_TRANS" entries in "ext". - */ - -int tbldiff(int *state, int pr, int *ext) -{ - int i, *sp = state, *ep = ext, *protp; - int numdiff = 0; - - protp = &protsave[numecs * (pr - 1)]; - - for ( i = numecs; i > 0; --i ) - { - if ( *++protp == *++sp ) - *++ep = SAME_TRANS; - else - { - *++ep = *sp; - ++numdiff; - } - } - - return ( numdiff ); - } diff --git a/src/libCom/flex/yylex.c b/src/libCom/flex/yylex.c deleted file mode 100644 index 28f487d6b..000000000 --- a/src/libCom/flex/yylex.c +++ /dev/null @@ -1,218 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* yylex - scanner front-end for flex */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include -#include "flexdef.h" -#include "parse.h" - -/* ANSI C does not guarantee that isascii() is defined */ -#ifndef isascii -#define isascii(c) ((c) <= 0177) -#endif - - -/* yylex - scan for a regular expression token - * - * synopsis - * - * token = yylex(); - * - * token - return token found - */ - -int yylex(void) -{ - int toktype; - static int beglin = false; - - if ( eofseen ) - toktype = EOF; - else - toktype = flexscan(); - - if ( toktype == EOF || toktype == 0 ) - { - eofseen = 1; - - if ( sectnum == 1 ) - { - synerr( "premature EOF" ); - sectnum = 2; - toktype = SECTEND; - } - - else if ( sectnum == 2 ) - { - sectnum = 3; - toktype = 0; - } - - else - toktype = 0; - } - - if ( trace ) - { - if ( beglin ) - { - fprintf( stderr, "%d\t", num_rules + 1 ); - beglin = 0; - } - - switch ( toktype ) - { - case '<': - case '>': - case '^': - case '$': - case '"': - case '[': - case ']': - case '{': - case '}': - case '|': - case '(': - case ')': - case '-': - case '/': - case '\\': - case '?': - case '.': - case '*': - case '+': - case ',': - (void) putc( toktype, stderr ); - break; - - case '\n': - (void) putc( '\n', stderr ); - - if ( sectnum == 2 ) - beglin = 1; - - break; - - case SCDECL: - fputs( "%s", stderr ); - break; - - case XSCDECL: - fputs( "%x", stderr ); - break; - - case WHITESPACE: - (void) putc( ' ', stderr ); - break; - - case SECTEND: - fputs( "%%\n", stderr ); - - /* we set beglin to be true so we'll start - * writing out numbers as we echo rules. flexscan() has - * already assigned sectnum - */ - - if ( sectnum == 2 ) - beglin = 1; - - break; - - case NAME: - fprintf( stderr, "'%s'", nmstr ); - break; - - case CHAR: - switch ( yylval ) - { - case '<': - case '>': - case '^': - case '$': - case '"': - case '[': - case ']': - case '{': - case '}': - case '|': - case '(': - case ')': - case '-': - case '/': - case '\\': - case '?': - case '.': - case '*': - case '+': - case ',': - fprintf( stderr, "\\%c", yylval ); - break; - - default: - if ( ! isascii( yylval ) || ! isprint( yylval ) ) - fprintf( stderr, "\\%.3o", yylval ); - else - (void) putc( yylval, stderr ); - break; - } - - break; - - case NUMBER: - fprintf( stderr, "%d", yylval ); - break; - - case PREVCCL: - fprintf( stderr, "[%d]", yylval ); - break; - - case EOF_OP: - fprintf( stderr, "<>" ); - break; - - case 0: - fprintf( stderr, "End Marker" ); - break; - - default: - fprintf( stderr, "*Something Weird* - tok: %d val: %d\n", - toktype, yylval ); - break; - } - } - - return ( toktype ); -} - diff --git a/src/libCom/freeList/Makefile b/src/libCom/freeList/Makefile deleted file mode 100644 index 3a1e25182..000000000 --- a/src/libCom/freeList/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/freeList - -INC += freeList.h - -Com_SRCS += freeListLib.c diff --git a/src/libCom/freeList/freeList.h b/src/libCom/freeList/freeList.h deleted file mode 100644 index 77ebfb82e..000000000 --- a/src/libCom/freeList/freeList.h +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 04-19-94 */ - -#ifndef INCfreeListh -#define INCfreeListh - -#include -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void epicsShareAPI freeListInitPvt(void **ppvt,int size,int nmalloc); -epicsShareFunc void * epicsShareAPI freeListCalloc(void *pvt); -epicsShareFunc void * epicsShareAPI freeListMalloc(void *pvt); -epicsShareFunc void epicsShareAPI freeListFree(void *pvt,void*pmem); -epicsShareFunc void epicsShareAPI freeListCleanup(void *pvt); -epicsShareFunc size_t epicsShareAPI freeListItemsAvail(void *pvt); - -#ifdef __cplusplus -} -#endif - -#endif /*INCfreeListh*/ diff --git a/src/libCom/freeList/freeListLib.c b/src/libCom/freeList/freeListLib.c deleted file mode 100755 index b489a476d..000000000 --- a/src/libCom/freeList/freeListLib.c +++ /dev/null @@ -1,181 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 04-19-94 */ - -#include -#include -#include - -#include "valgrind/valgrind.h" - -#ifndef NVALGRIND -/* buffer around allocations to detect out of bounds access */ -#define REDZONE sizeof(double) -#else -#define REDZONE 0 -#endif - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsMutex.h" -#include "freeList.h" -#include "adjustment.h" - -typedef struct allocMem { - struct allocMem *next; - void *memory; -}allocMem; -typedef struct { - int size; - int nmalloc; - void *head; - allocMem *mallochead; - size_t nBlocksAvailable; - epicsMutexId lock; -}FREELISTPVT; - -epicsShareFunc void epicsShareAPI - freeListInitPvt(void **ppvt,int size,int nmalloc) -{ - FREELISTPVT *pfl; - - pfl = callocMustSucceed(1,sizeof(FREELISTPVT), "freeListInitPvt"); - pfl->size = adjustToWorstCaseAlignment(size); - pfl->nmalloc = nmalloc; - pfl->head = NULL; - pfl->mallochead = NULL; - pfl->nBlocksAvailable = 0u; - pfl->lock = epicsMutexMustCreate(); - *ppvt = (void *)pfl; - VALGRIND_CREATE_MEMPOOL(pfl, REDZONE, 0); - return; -} - -epicsShareFunc void * epicsShareAPI freeListCalloc(void *pvt) -{ - FREELISTPVT *pfl = pvt; -# ifdef EPICS_FREELIST_DEBUG - return callocMustSucceed(1,pfl->size,"freeList Debug Calloc"); -# else - void *ptemp; - - ptemp = freeListMalloc(pvt); - if(ptemp) memset((char *)ptemp,0,pfl->size); - return(ptemp); -# endif -} - -epicsShareFunc void * epicsShareAPI freeListMalloc(void *pvt) -{ - FREELISTPVT *pfl = pvt; -# ifdef EPICS_FREELIST_DEBUG - return callocMustSucceed(1,pfl->size,"freeList Debug Malloc"); -# else - void *ptemp; - void **ppnext; - allocMem *pallocmem; - int i; - - epicsMutexMustLock(pfl->lock); - ptemp = pfl->head; - if(ptemp==0) { - /* layout of each block. nmalloc+1 REDZONEs for nmallocs. - * The first sizeof(void*) bytes are used to store a pointer - * to the next free block. - * - * | RED | size0 ------ | RED | size1 | ... | RED | - * | | next | ----- | - */ - ptemp = (void *)malloc(pfl->nmalloc*(pfl->size+REDZONE)+REDZONE); - if(ptemp==0) { - epicsMutexUnlock(pfl->lock); - return(0); - } - pallocmem = (allocMem *)calloc(1,sizeof(allocMem)); - if(pallocmem==0) { - epicsMutexUnlock(pfl->lock); - free(ptemp); - return(0); - } - pallocmem->memory = ptemp; /* real allocation */ - ptemp = REDZONE + (char *) ptemp; /* skip first REDZONE */ - if(pfl->mallochead) - pallocmem->next = pfl->mallochead; - pfl->mallochead = pallocmem; - for(i=0; inmalloc; i++) { - ppnext = ptemp; - VALGRIND_MEMPOOL_ALLOC(pfl, ptemp, sizeof(void*)); - *ppnext = pfl->head; - pfl->head = ptemp; - ptemp = ((char *)ptemp) + pfl->size+REDZONE; - } - ptemp = pfl->head; - pfl->nBlocksAvailable += pfl->nmalloc; - } - ppnext = pfl->head; - pfl->head = *ppnext; - pfl->nBlocksAvailable--; - epicsMutexUnlock(pfl->lock); - VALGRIND_MEMPOOL_FREE(pfl, ptemp); - VALGRIND_MEMPOOL_ALLOC(pfl, ptemp, pfl->size); - return(ptemp); -# endif -} - -epicsShareFunc void epicsShareAPI freeListFree(void *pvt,void*pmem) -{ - FREELISTPVT *pfl = pvt; -# ifdef EPICS_FREELIST_DEBUG - memset ( pmem, 0xdd, pfl->size ); - free(pmem); -# else - void **ppnext; - - VALGRIND_MEMPOOL_FREE(pvt, pmem); - VALGRIND_MEMPOOL_ALLOC(pvt, pmem, sizeof(void*)); - - epicsMutexMustLock(pfl->lock); - ppnext = pmem; - *ppnext = pfl->head; - pfl->head = pmem; - pfl->nBlocksAvailable++; - epicsMutexUnlock(pfl->lock); -# endif -} - -epicsShareFunc void epicsShareAPI freeListCleanup(void *pvt) -{ - FREELISTPVT *pfl = pvt; - allocMem *phead; - allocMem *pnext; - - VALGRIND_DESTROY_MEMPOOL(pvt); - - phead = pfl->mallochead; - while(phead) { - pnext = phead->next; - free(phead->memory); - free(phead); - phead = pnext; - } - epicsMutexDestroy(pfl->lock); - free(pvt); -} - -epicsShareFunc size_t epicsShareAPI freeListItemsAvail(void *pvt) -{ - FREELISTPVT *pfl = pvt; - size_t nBlocksAvailable; - epicsMutexMustLock(pfl->lock); - nBlocksAvailable = pfl->nBlocksAvailable; - epicsMutexUnlock(pfl->lock); - return nBlocksAvailable; -} - diff --git a/src/libCom/gpHash/Makefile b/src/libCom/gpHash/Makefile deleted file mode 100644 index 6fcd3f8a7..000000000 --- a/src/libCom/gpHash/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/gpHash - -INC += gpHash.h - -Com_SRCS += gpHashLib.c diff --git a/src/libCom/gpHash/gpHash.h b/src/libCom/gpHash/gpHash.h deleted file mode 100644 index d9c0dd204..000000000 --- a/src/libCom/gpHash/gpHash.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 04-07-94 */ - -/* gph provides a general purpose directory accessed via a hash table*/ - -#ifndef INC_gpHash_H -#define INC_gpHash_H - -#include "shareLib.h" - -#include "ellLib.h" - -typedef struct{ - ELLNODE node; - const char *name; /*address of name placed in directory*/ - void *pvtid; /*private name for subsystem user*/ - void *userPvt; /*private for user*/ -} GPHENTRY; - -struct gphPvt; - -#ifdef __cplusplus -extern "C" { -#endif - -/*tableSize must be power of 2 in range 256 to 65536*/ -epicsShareFunc void epicsShareAPI - gphInitPvt(struct gphPvt **ppvt, int tableSize); -epicsShareFunc GPHENTRY * epicsShareAPI - gphFind(struct gphPvt *pvt, const char *name, void *pvtid); -epicsShareFunc GPHENTRY * epicsShareAPI - gphFindParse(struct gphPvt *pvt, const char *name, size_t len, void *pvtid); -epicsShareFunc GPHENTRY * epicsShareAPI - gphAdd(struct gphPvt *pvt, const char *name, void *pvtid); -epicsShareFunc void epicsShareAPI - gphDelete(struct gphPvt *pvt, const char *name, void *pvtid); -epicsShareFunc void epicsShareAPI gphFreeMem(struct gphPvt *pvt); -epicsShareFunc void epicsShareAPI gphDump(struct gphPvt *pvt); -epicsShareFunc void epicsShareAPI gphDumpFP(FILE *fp, struct gphPvt *pvt); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_gpHash_H */ diff --git a/src/libCom/gpHash/gpHashLib.c b/src/libCom/gpHash/gpHashLib.c deleted file mode 100644 index a56f00a0c..000000000 --- a/src/libCom/gpHash/gpHashLib.c +++ /dev/null @@ -1,244 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 04-07-94 */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsMutex.h" -#include "epicsStdioRedirect.h" -#include "epicsString.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsPrint.h" -#include "gpHash.h" - -typedef struct gphPvt { - int size; - unsigned int mask; - ELLLIST **paplist; /*pointer to array of pointers to ELLLIST */ - epicsMutexId lock; -} gphPvt; - -#define MIN_SIZE 256 -#define DEFAULT_SIZE 512 -#define MAX_SIZE 65536 - - -void epicsShareAPI gphInitPvt(gphPvt **ppvt, int size) -{ - gphPvt *pgphPvt; - - if (size & (size - 1)) { - fprintf(stderr, "gphInitPvt: %d is not a power of 2\n", size); - size = DEFAULT_SIZE; - } - - if (size < MIN_SIZE) - size = MIN_SIZE; - - if (size > MAX_SIZE) - size = MAX_SIZE; - - pgphPvt = callocMustSucceed(1, sizeof(gphPvt), "gphInitPvt"); - pgphPvt->size = size; - pgphPvt->mask = size - 1; - pgphPvt->paplist = callocMustSucceed(size, sizeof(ELLLIST *), "gphInitPvt"); - pgphPvt->lock = epicsMutexMustCreate(); - *ppvt = pgphPvt; - return; -} - -GPHENTRY * epicsShareAPI gphFindParse(gphPvt *pgphPvt, const char *name, size_t len, void *pvtid) -{ - ELLLIST **paplist; - ELLLIST *gphlist; - GPHENTRY *pgphNode; - int hash; - - if (pgphPvt == NULL) return NULL; - paplist = pgphPvt->paplist; - hash = epicsMemHash((char *)&pvtid, sizeof(void *), 0); - hash = epicsMemHash(name, len, hash) & pgphPvt->mask; - - epicsMutexMustLock(pgphPvt->lock); - gphlist = paplist[hash]; - if (gphlist == NULL) { - pgphNode = NULL; - } else { - pgphNode = (GPHENTRY *) ellFirst(gphlist); - } - - while (pgphNode) { - if (pvtid == pgphNode->pvtid && - strlen(pgphNode->name) == len && - strncmp(name, pgphNode->name, len) == 0) break; - pgphNode = (GPHENTRY *) ellNext((ELLNODE *)pgphNode); - } - - epicsMutexUnlock(pgphPvt->lock); - return pgphNode; -} - -GPHENTRY * epicsShareAPI gphFind(gphPvt *pgphPvt, const char *name, void *pvtid) -{ - return gphFindParse(pgphPvt, name, strlen(name), pvtid); -} - -GPHENTRY * epicsShareAPI gphAdd(gphPvt *pgphPvt, const char *name, void *pvtid) -{ - ELLLIST **paplist; - ELLLIST *plist; - GPHENTRY *pgphNode; - int hash; - - if (pgphPvt == NULL) return NULL; - paplist = pgphPvt->paplist; - hash = epicsMemHash((char *)&pvtid, sizeof(void *), 0); - hash = epicsStrHash(name, hash) & pgphPvt->mask; - - epicsMutexMustLock(pgphPvt->lock); - plist = paplist[hash]; - if (plist == NULL) { - plist = calloc(1, sizeof(ELLLIST)); - if(!plist){ - epicsMutexUnlock(pgphPvt->lock); - return NULL; - } - ellInit(plist); - paplist[hash] = plist; - } - - pgphNode = (GPHENTRY *) ellFirst(plist); - while (pgphNode) { - if (pvtid == pgphNode->pvtid && - strcmp(name, pgphNode->name) == 0) { - epicsMutexUnlock(pgphPvt->lock); - return NULL; - } - pgphNode = (GPHENTRY *) ellNext((ELLNODE *)pgphNode); - } - - pgphNode = calloc(1, sizeof(GPHENTRY)); - if(pgphNode) { - pgphNode->name = name; - pgphNode->pvtid = pvtid; - ellAdd(plist, (ELLNODE *)pgphNode); - } - - epicsMutexUnlock(pgphPvt->lock); - return (pgphNode); -} - -void epicsShareAPI gphDelete(gphPvt *pgphPvt, const char *name, void *pvtid) -{ - ELLLIST **paplist; - ELLLIST *plist = NULL; - GPHENTRY *pgphNode; - int hash; - - if (pgphPvt == NULL) return; - paplist = pgphPvt->paplist; - hash = epicsMemHash((char *)&pvtid, sizeof(void *), 0); - hash = epicsStrHash(name, hash) & pgphPvt->mask; - - epicsMutexMustLock(pgphPvt->lock); - if (paplist[hash] == NULL) { - pgphNode = NULL; - } else { - plist = paplist[hash]; - pgphNode = (GPHENTRY *) ellFirst(plist); - } - - while(pgphNode) { - if (pvtid == pgphNode->pvtid && - strcmp(name, pgphNode->name) == 0) { - ellDelete(plist, (ELLNODE*)pgphNode); - free((void *)pgphNode); - break; - } - pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode); - } - - epicsMutexUnlock(pgphPvt->lock); - return; -} - -void epicsShareAPI gphFreeMem(gphPvt *pgphPvt) -{ - ELLLIST **paplist; - int h; - - /* Caller must ensure that no other thread is using *pvt */ - if (pgphPvt == NULL) return; - - paplist = pgphPvt->paplist; - for (h = 0; h < pgphPvt->size; h++) { - ELLLIST *plist = paplist[h]; - GPHENTRY *pgphNode; - GPHENTRY *next; - - if (plist == NULL) continue; - pgphNode = (GPHENTRY *) ellFirst(plist); - - while (pgphNode) { - next = (GPHENTRY *) ellNext((ELLNODE*)pgphNode); - ellDelete(plist, (ELLNODE*)pgphNode); - free(pgphNode); - pgphNode = next; - } - free(paplist[h]); - } - epicsMutexDestroy(pgphPvt->lock); - free(paplist); - free(pgphPvt); -} - -void epicsShareAPI gphDump(gphPvt *pgphPvt) -{ - gphDumpFP(stdout, pgphPvt); -} - -void epicsShareAPI gphDumpFP(FILE *fp, gphPvt *pgphPvt) -{ - unsigned int empty = 0; - ELLLIST **paplist; - int h; - - if (pgphPvt == NULL) - return; - - fprintf(fp, "Hash table has %d buckets", pgphPvt->size); - - paplist = pgphPvt->paplist; - for (h = 0; h < pgphPvt->size; h++) { - ELLLIST *plist = paplist[h]; - GPHENTRY *pgphNode; - int i = 0; - - if (plist == NULL) { - empty++; - continue; - } - pgphNode = (GPHENTRY *) ellFirst(plist); - - fprintf(fp, "\n [%3d] %3d ", h, ellCount(plist)); - while (pgphNode) { - if (!(++i % 3)) - fprintf(fp, "\n "); - fprintf(fp, " %s %p", pgphNode->name, pgphNode->pvtid); - pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode); - } - } - fprintf(fp, "\n%u buckets empty.\n", empty); -} diff --git a/src/libCom/iocsh/Makefile b/src/libCom/iocsh/Makefile deleted file mode 100644 index 766577354..000000000 --- a/src/libCom/iocsh/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/iocsh -INC += iocsh.h -INC += registry.h -INC += libComRegister.h -Com_SRCS += iocsh.cpp -Com_SRCS += registry.c -Com_SRCS += libComRegister.c diff --git a/src/libCom/iocsh/iocsh.cpp b/src/libCom/iocsh/iocsh.cpp deleted file mode 100644 index d6626de89..000000000 --- a/src/libCom/iocsh/iocsh.cpp +++ /dev/null @@ -1,1097 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* iocsh.cpp */ -/* Author: Marty Kraimer Date: 27APR2000 */ -/* Heavily modified by Eric Norum Date: 03MAY2000 */ -/* Adapted to C++ by Eric Norum Date: 18DEC2000 */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "errlog.h" -#include "macLib.h" -#include "epicsStdio.h" -#include "epicsString.h" -#include "epicsStdlib.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "envDefs.h" -#include "registry.h" -#include "epicsReadline.h" -#include "cantProceed.h" -#include "iocsh.h" - -extern "C" { - -/* - * Global link to pdbbase - */ -epicsShareDef struct dbBase **iocshPpdbbase; - -/* - * File-local information - */ -struct iocshCommand { - iocshCmdDef def; - struct iocshCommand *next; -}; -static struct iocshCommand *iocshCommandHead; -static char iocshCmdID[] = "iocshCmd"; -struct iocshVariable { - iocshVarDef const *pVarDef; - struct iocshVariable *next; -}; -static struct iocshVariable *iocshVariableHead; -static char iocshVarID[] = "iocshVar"; -extern "C" { static void varCallFunc(const iocshArgBuf *); } -static epicsMutexId iocshTableMutex; -static epicsThreadOnceId iocshOnceId = EPICS_THREAD_ONCE_INIT; -static epicsThreadPrivateId iocshMacroHandleId; - -/* - * I/O redirection - */ -#define NREDIRECTS 5 -struct iocshRedirect { - const char *name; - const char *mode; - FILE *fp; - FILE *oldFp; - int mustRestore; -}; - -/* - * Set up module variables - */ -static void iocshOnce (void *) -{ - iocshTableMutex = epicsMutexMustCreate (); - iocshMacroHandleId = epicsThreadPrivateCreate(); -} - -static void iocshInit (void) -{ - epicsThreadOnce (&iocshOnceId, iocshOnce, NULL); -} - -/* - * Lock the table mutex - */ -static void -iocshTableLock (void) -{ - iocshInit(); - epicsMutexMustLock (iocshTableMutex); -} - -/* - * Unlock the table mutex - */ -static void -iocshTableUnlock (void) -{ - epicsMutexUnlock (iocshTableMutex); -} - -/* - * Register a command - */ -void epicsShareAPI iocshRegister (const iocshFuncDef *piocshFuncDef, - iocshCallFunc func) -{ - struct iocshCommand *l, *p, *n; - int i; - - iocshTableLock (); - for (l = NULL, p = iocshCommandHead ; p != NULL ; l = p, p = p->next) { - i = strcmp (piocshFuncDef->name, p->def.pFuncDef->name); - if (i == 0) { - p->def.pFuncDef = piocshFuncDef; - p->def.func = func; - iocshTableUnlock (); - return; - } - if (i < 0) - break; - } - n = (struct iocshCommand *) callocMustSucceed (1, sizeof *n, - "iocshRegister"); - if (!registryAdd(iocshCmdID, piocshFuncDef->name, (void *)n)) { - free (n); - iocshTableUnlock (); - errlogPrintf ("iocshRegister failed to add %s\n", piocshFuncDef->name); - return; - } - if (l == NULL) { - n->next = iocshCommandHead; - iocshCommandHead = n; - } - else { - n->next = l->next; - l->next = n; - } - n->def.pFuncDef = piocshFuncDef; - n->def.func = func; - iocshTableUnlock (); -} - - -/* - * Retrieves a previously registered function with the given name. - */ -const iocshCmdDef * epicsShareAPI iocshFindCommand(const char *name) -{ - return (iocshCmdDef *) registryFind(iocshCmdID, name); -} - -/* - * Register the "var" command and any variable(s) - */ -static const iocshArg varCmdArg0 = { "[variable", iocshArgString}; -static const iocshArg varCmdArg1 = { "[value]]", iocshArgString}; -static const iocshArg *varCmdArgs[2] = {&varCmdArg0, &varCmdArg1}; -static const iocshFuncDef varFuncDef = {"var", 2, varCmdArgs}; - -void epicsShareAPI iocshRegisterVariable (const iocshVarDef *piocshVarDef) -{ - struct iocshVariable *l, *p, *n; - int i; - int found; - - iocshTableLock (); - while ((piocshVarDef != NULL) - && (piocshVarDef->name != NULL) - && (*piocshVarDef->name != '\0')) { - if (iocshVariableHead == NULL) - iocshRegister(&varFuncDef,varCallFunc); - found = 0; - for (l = NULL, p = iocshVariableHead ; p != NULL ; l = p, p = p->next) { - i = strcmp (piocshVarDef->name, p->pVarDef->name); - if (i == 0) { - errlogPrintf("Warning: iocshRegisterVariable redefining %s.\n", - piocshVarDef->name); - p->pVarDef = piocshVarDef; - found = 1; - break; - } - if (i < 0) - break; - } - if (!found) { - n = (struct iocshVariable *) callocMustSucceed(1, sizeof *n, - "iocshRegisterVariable"); - if (!registryAdd(iocshVarID, piocshVarDef->name, (void *)n)) { - free(n); - iocshTableUnlock(); - errlogPrintf("iocshRegisterVariable failed to add %s.\n", - piocshVarDef->name); - return; - } - if (l == NULL) { - n->next = iocshVariableHead; - iocshVariableHead = n; - } - else { - n->next = l->next; - l->next = n; - } - n->pVarDef = piocshVarDef; - } - piocshVarDef++; - } - iocshTableUnlock (); -} - -/* - * Retrieves a previously registered variable with the given name. - */ -const iocshVarDef * epicsShareAPI iocshFindVariable(const char *name) -{ - struct iocshVariable *temp = (iocshVariable *) registryFind(iocshVarID, name); - return temp->pVarDef; -} - -/* - * Free storage created by iocshRegister/iocshRegisterVariable - */ -void epicsShareAPI iocshFree(void) -{ - struct iocshCommand *pc; - struct iocshVariable *pv; - - iocshTableLock (); - for (pc = iocshCommandHead ; pc != NULL ; ) { - struct iocshCommand * nc = pc->next; - free (pc); - pc = nc; - } - for (pv = iocshVariableHead ; pv != NULL ; ) { - struct iocshVariable *nv = pv->next; - free (pv); - pv = nv; - } - iocshCommandHead = NULL; - iocshVariableHead = NULL; - iocshTableUnlock (); -} - -/* - * Report an error - */ -static void -showError (const char *filename, int lineno, const char *msg, ...) -{ - va_list ap; - - va_start (ap, msg); - if (filename) - fprintf(epicsGetStderr(), "%s line %d: ", filename, lineno); - vfprintf (epicsGetStderr(), msg, ap); - fputc ('\n', epicsGetStderr()); - va_end (ap); -} - -static int -cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, - const iocshArg *piocshArg) -{ - char *endp; - - switch (piocshArg->type) { - case iocshArgInt: - if (arg && *arg) { - errno = 0; - argBuf->ival = strtol (arg, &endp, 0); - if (errno == ERANGE) { - errno = 0; - argBuf->ival = strtoul (arg, &endp, 0); - if (errno == ERANGE) { - showError(filename, lineno, "Integer '%s' out of range", - arg); - return 0; - } - } - if (*endp) { - showError(filename, lineno, "Illegal integer '%s'", arg); - return 0; - } - } - else { - argBuf->ival = 0; - } - break; - - case iocshArgDouble: - if (arg && *arg) { - argBuf->dval = epicsStrtod (arg, &endp); - if (*endp) { - showError(filename, lineno, "Illegal double '%s'", arg); - return 0; - } - } - else { - argBuf->dval = 0.0; - } - break; - - case iocshArgString: - argBuf->sval = arg; - break; - - case iocshArgPersistentString: - argBuf->sval = (char *) malloc(strlen(arg) + 1); - if (argBuf->sval == NULL) { - showError(filename, lineno, "Out of memory"); - return 0; - } - strcpy(argBuf->sval, arg); - break; - - case iocshArgPdbbase: - /* Argument must be missing or 0 or pdbbase */ - if(!arg || !*arg || (*arg == '0') || (strcmp(arg, "pdbbase") == 0)) { - if(!iocshPpdbbase || !*iocshPpdbbase) { - showError(filename, lineno, "pdbbase not present"); - return 0; - } - argBuf->vval = *iocshPpdbbase; - break; - } - showError(filename, lineno, "Expecting 'pdbbase' got '%s'", arg); - return 0; - - default: - showError(filename, lineno, "Illegal argument type %d", - piocshArg->type); - return 0; - } - return 1; -} - -/* - * Open redirected I/O - */ -static int -openRedirect(const char *filename, int lineno, struct iocshRedirect *redirect) -{ - int i; - - for (i = 0 ; i < NREDIRECTS ; i++, redirect++) { - if (redirect->name != NULL) { - redirect->fp = fopen(redirect->name, redirect->mode); - if (redirect->fp == NULL) { - showError(filename, lineno, "Can't open \"%s\": %s.", - redirect->name, strerror(errno)); - redirect->name = NULL; - while (i--) { - redirect--; - if (redirect->fp) { - fclose(redirect->fp); - redirect->fp = NULL; - } - redirect->name = NULL; - } - return -1; - } - redirect->mustRestore = 0; - } - } - return 0; -} - -/* - * Start I/O redirection - */ -static void -startRedirect(const char * /*filename*/, int /*lineno*/, - struct iocshRedirect *redirect) -{ - int i; - - for (i = 0 ; i < NREDIRECTS ; i++, redirect++) { - if (redirect->fp != NULL) { - switch(i) { - case 0: - redirect->oldFp = epicsGetThreadStdin(); - epicsSetThreadStdin(redirect->fp); - redirect->mustRestore = 1; - break; - case 1: - redirect->oldFp = epicsGetThreadStdout(); - epicsSetThreadStdout(redirect->fp); - redirect->mustRestore = 1; - break; - case 2: - redirect->oldFp = epicsGetThreadStderr(); - epicsSetThreadStderr(redirect->fp); - redirect->mustRestore = 1; - break; - } - } - } -} - -/* - * Finish up I/O redirection - */ -static void -stopRedirect(const char *filename, int lineno, struct iocshRedirect *redirect) -{ - int i; - - for (i = 0 ; i < NREDIRECTS ; i++, redirect++) { - if (redirect->fp != NULL) { - if (fclose(redirect->fp) != 0) - showError(filename, lineno, "Error closing \"%s\": %s.", - redirect->name, strerror(errno)); - redirect->fp = NULL; - if (redirect->mustRestore) { - switch(i) { - case 0: epicsSetThreadStdin(redirect->oldFp); break; - case 1: epicsSetThreadStdout(redirect->oldFp); break; - case 2: epicsSetThreadStderr(redirect->oldFp); break; - } - } - } - redirect->name = NULL; - } -} - -/* - * "help" command - */ -static const iocshArg helpArg0 = { "[command ...]",iocshArgArgv}; -static const iocshArg *helpArgs[1] = {&helpArg0}; -static const iocshFuncDef helpFuncDef = - {"help",1,helpArgs}; -static void helpCallFunc(const iocshArgBuf *args) -{ - int argc = args[0].aval.ac; - const char * const * argv = args[0].aval.av; - struct iocshFuncDef const *piocshFuncDef; - struct iocshCommand *pcmd; - - if (argc == 1) { - int l, col = 0; - - fprintf(epicsGetStdout(), - "Type 'help ' to see the arguments of .\n"); - iocshTableLock (); - for (pcmd = iocshCommandHead ; pcmd != NULL ; pcmd = pcmd->next) { - piocshFuncDef = pcmd->def.pFuncDef; - l = strlen (piocshFuncDef->name); - if ((l + col) >= 79) { - fputc('\n', epicsGetStdout()); - col = 0; - } - fputs(piocshFuncDef->name, epicsGetStdout()); - col += l; - if (col >= 64) { - fputc('\n', epicsGetStdout()); - col = 0; - } - else { - do { - fputc(' ', epicsGetStdout()); - col++; - } while ((col % 16) != 0); - } - } - if (col) - fputc('\n', epicsGetStdout()); - iocshTableUnlock (); - } - else { - for (int iarg = 1 ; iarg < argc ; iarg++) { - for (pcmd = iocshCommandHead ; pcmd != NULL ; pcmd = pcmd->next) { - piocshFuncDef = pcmd->def.pFuncDef; - if (epicsStrGlobMatch(piocshFuncDef->name, argv[iarg]) != 0) { - fputs(piocshFuncDef->name, epicsGetStdout()); - for (int a = 0 ; a < piocshFuncDef->nargs ; a++) { - const char *cp = piocshFuncDef->arg[a]->name; - if ((piocshFuncDef->arg[a]->type == iocshArgArgv) - || (strchr (cp, ' ') == NULL)) { - fprintf(epicsGetStdout(), " %s", cp); - } - else { - fprintf(epicsGetStdout(), " '%s'", cp); - } - } - fprintf(epicsGetStdout(),"\n");; - } - } - } - } -} - -/* - * The body of the command interpreter - */ -static int -iocshBody (const char *pathname, const char *commandLine, const char *macros) -{ - FILE *fp = NULL; - const char *filename = NULL; - int icin, icout; - char c; - int quote, inword, backslash; - const char *raw = NULL;; - char *line = NULL; - int lineno = 0; - int argc; - char **argv = NULL; - int argvCapacity = 0; - struct iocshRedirect *redirects = NULL; - struct iocshRedirect *redirect = NULL; - int sep; - const char *prompt = NULL; - const char *ifs = " \t(),\r"; - iocshArgBuf *argBuf = NULL; - int argBufCapacity = 0; - struct iocshCommand *found; - void *readlineContext = NULL; - int wasOkToBlock; - static const char * pairs[] = {"", "environ", NULL, NULL}; - MAC_HANDLE *handle; - char ** defines = NULL; - - iocshInit(); - - /* - * See if command interpreter is interactive - */ - if (commandLine == NULL) { - if ((pathname == NULL) || (strcmp (pathname, "") == 0)) { - if ((prompt = envGetConfigParamPtr(&IOCSH_PS1)) == NULL) - prompt = "epics> "; - } - else { - fp = fopen (pathname, "r"); - if (fp == NULL) { - fprintf(epicsGetStderr(), "Can't open %s: %s\n", pathname, - strerror (errno)); - return -1; - } - if ((filename = strrchr (pathname, '/')) == NULL) - filename = pathname; - else - filename++; - prompt = NULL; - } - - /* - * Create a command-line input context - */ - if ((readlineContext = epicsReadlineBegin(fp)) == NULL) { - fprintf(epicsGetStderr(), "Can't allocate command-line object.\n"); - if (fp) - fclose(fp); - return -1; - } - } - - /* - * Set up redirection - */ - redirects = (struct iocshRedirect *)calloc(NREDIRECTS, sizeof *redirects); - if (redirects == NULL) { - fprintf(epicsGetStderr(), "Out of memory!\n"); - return -1; - } - - /* - * Parse macro definitions, this check occurs before creating the - * macro handle to simplify cleanup. - */ - - if (macros) { - if (macParseDefns(NULL, macros, &defines) < 0) { - free(redirects); - return -1; - } - } - - /* - * Check for existing macro context or construct a new one. - */ - handle = (MAC_HANDLE *) epicsThreadPrivateGet(iocshMacroHandleId); - - if (handle == NULL) { - if (macCreateHandle(&handle, pairs)) { - errlogMessage("iocsh: macCreateHandle failed."); - free(redirects); - return -1; - } - - epicsThreadPrivateSet(iocshMacroHandleId, (void *) handle); - } - - macPushScope(handle); - macInstallMacros(handle, defines); - - /* - * Read commands till EOF or exit - */ - argc = 0; - wasOkToBlock = epicsThreadIsOkToBlock(); - epicsThreadSetOkToBlock(1); - for (;;) { - /* - * Read a line - */ - if (commandLine) { - if (raw != NULL) - break; - raw = commandLine; - } - else { - if ((raw = epicsReadline(prompt, readlineContext)) == NULL) - break; - } - lineno++; - - /* - * Skip leading white-space - */ - icin = 0; - while ((c = raw[icin]) && isspace(c)) { - icin++; - } - - /* - * Ignore comment lines other than to echo - * them if they came from a script (disable echoing - * with '#-'). This avoids macLib errors from comments. - */ - if (c == '#') { - if ((prompt == NULL) && (commandLine == NULL)) - if (raw[icin + 1] != '-') - puts(raw); - continue; - } - - /* - * Expand macros - */ - free(line); - if ((line = macDefExpand(raw, handle)) == NULL) - continue; - - /* - * Skip leading white-space coming from a macro - */ - while ((c = line[icin]) && isspace(c)) { - icin++; - } - - /* - * Echo non-empty lines read from a script. - * Comments delineated with '#-' aren't echoed. - */ - if ((prompt == NULL) && *line && (commandLine == NULL)) - if ((c != '#') || (line[icin + 1] != '-')) - puts(line); - - /* - * Ignore lines that became a comment or empty after macro expansion - */ - if (!c || c == '#') - continue; - - /* - * Break line into words - */ - icout = 0; - inword = 0; - argc = 0; - quote = EOF; - backslash = 0; - redirect = NULL; - for (;;) { - if (argc >= argvCapacity) { - char **av; - argvCapacity += 50; - av = (char **)realloc (argv, argvCapacity * sizeof *argv); - if (av == NULL) { - fprintf (epicsGetStderr(), "Out of memory!\n"); - argc = -1; - break; - } - argv = av; - } - c = line[icin++]; - if (c == '\0') - break; - if ((quote == EOF) && !backslash && (strchr (ifs, c))) - sep = 1; - else - sep = 0; - if ((quote == EOF) && !backslash) { - int redirectFd = 1; - if (c == '\\') { - backslash = 1; - continue; - } - if (c == '<') { - if (redirect != NULL) { - break; - } - redirect = &redirects[0]; - sep = 1; - redirect->mode = "r"; - } - if ((c >= '1') && (c <= '9') && (line[icin] == '>')) { - redirectFd = c - '0'; - c = '>'; - icin++; - } - if (c == '>') { - if (redirect != NULL) - break; - if (redirectFd >= NREDIRECTS) { - redirect = &redirects[1]; - break; - } - redirect = &redirects[redirectFd]; - sep = 1; - if (line[icin] == '>') { - icin++; - redirect->mode = "a"; - } - else { - redirect->mode = "w"; - } - } - } - if (inword) { - if (c == quote) { - quote = EOF; - } - else { - if ((quote == EOF) && !backslash) { - if (sep) { - inword = 0; - line[icout++] = '\0'; - } - else if ((c == '"') || (c == '\'')) { - quote = c; - } - else { - line[icout++] = c; - } - } - else { - line[icout++] = c; - } - } - } - else { - if (!sep) { - if (((c == '"') || (c == '\'')) && !backslash) - quote = c; - if (redirect != NULL) { - if (redirect->name != NULL) { - argc = -1; - break; - } - redirect->name = line + icout; - redirect = NULL; - } - else { - argv[argc++] = line + icout; - } - if (quote == EOF) - line[icout++] = c; - inword = 1; - } - } - backslash = 0; - } - if (redirect != NULL) { - showError(filename, lineno, "Illegal redirection."); - continue; - } - if (argc < 0) - break; - if (quote != EOF) { - showError(filename, lineno, "Unbalanced quote."); - continue; - } - if (backslash) { - showError(filename, lineno, "Trailing backslash."); - continue; - } - if (inword) - line[icout++] = '\0'; - argv[argc] = NULL; - - /* - * Special case -- Redirected input but no command - * Treat as if 'iocsh filename'. - */ - if ((argc == 0) && (redirects[0].name != NULL)) { - const char *commandFile = redirects[0].name; - redirects[0].name = NULL; - if (openRedirect(filename, lineno, redirects) < 0) - continue; - startRedirect(filename, lineno, redirects); - iocshBody(commandFile, NULL, macros); - stopRedirect(filename, lineno, redirects); - continue; - } - - /* - * Special command? - */ - if ((argc > 0) && (strcmp(argv[0], "exit") == 0)) - break; - - /* - * Set up redirection - */ - if ((openRedirect(filename, lineno, redirects) == 0) && (argc > 0)) { - /* - * Look up command - */ - found = (iocshCommand *)registryFind (iocshCmdID, argv[0]); - if (found) { - /* - * Process arguments and call function - */ - struct iocshFuncDef const *piocshFuncDef = found->def.pFuncDef; - for (int iarg = 0 ; ; ) { - if (iarg == piocshFuncDef->nargs) { - startRedirect(filename, lineno, redirects); - (*found->def.func)(argBuf); - break; - } - if (iarg >= argBufCapacity) { - void *np; - - argBufCapacity += 20; - np = realloc (argBuf, argBufCapacity * sizeof *argBuf); - if (np == NULL) { - fprintf (epicsGetStderr(), "Out of memory!\n"); - argBufCapacity -= 20; - break; - } - argBuf = (iocshArgBuf *)np; - } - if (piocshFuncDef->arg[iarg]->type == iocshArgArgv) { - argBuf[iarg].aval.ac = argc-iarg; - argBuf[iarg].aval.av = argv+iarg; - iarg = piocshFuncDef->nargs; - } - else { - if (!cvtArg (filename, lineno, - ((iarg < argc) ? argv[iarg+1] : NULL), - &argBuf[iarg], piocshFuncDef->arg[iarg])) - break; - iarg++; - } - } - if ((prompt != NULL) && (strcmp(argv[0], "epicsEnvSet") == 0)) { - const char *newPrompt; - if ((newPrompt = envGetConfigParamPtr(&IOCSH_PS1)) != NULL) - prompt = newPrompt; - } - } - else { - showError(filename, lineno, "Command %s not found.", argv[0]); - } - } - stopRedirect(filename, lineno, redirects); - } - macPopScope(handle); - - if (handle->level == 0) { - macDeleteHandle(handle); - epicsThreadPrivateSet(iocshMacroHandleId, NULL); - } - if (fp && (fp != stdin)) - fclose (fp); - if (redirects != NULL) { - stopRedirect(filename, lineno, redirects); - free (redirects); - } - free(line); - free (argv); - free (argBuf); - errlogFlush(); - if (readlineContext) - epicsReadlineEnd(readlineContext); - epicsThreadSetOkToBlock( wasOkToBlock); - return 0; -} - -/* - * External access to the command interpreter - */ -int epicsShareAPI -iocsh (const char *pathname) -{ - return iocshLoad(pathname, NULL); -} - -int epicsShareAPI -iocshCmd (const char *cmd) -{ - return iocshRun(cmd, NULL); -} - -int epicsShareAPI -iocshLoad(const char *pathname, const char *macros) -{ - if (pathname) - epicsEnvSet("IOCSH_STARTUP_SCRIPT", pathname); - return iocshBody(pathname, NULL, macros); -} - -int epicsShareAPI -iocshRun(const char *cmd, const char *macros) -{ - if (cmd == NULL) - return 0; - return iocshBody(NULL, cmd, macros); -} - -/* - * Needed to work around the necessary limitations of macLib and - * environment variables. In every other case of macro expansion - * it is the expected outcome that defined macros override any - * environment variables. - * - * iocshLoad/Run turn this on its head as it is very likely that - * an epicsEnvSet command may be run within the context of their - * calls. Thus, it would be expected that the new value would be - * returned in any future macro expansion. - * - * To do so, the epicsEnvSet command needs to be able to access - * and update the shared MAC_HANDLE that the iocsh uses. Which is - * what this function is provided for. - */ -void epicsShareAPI -iocshEnvClear(const char *name) -{ - MAC_HANDLE *handle; - - if (iocshMacroHandleId) { - handle = (MAC_HANDLE *) epicsThreadPrivateGet(iocshMacroHandleId); - - if (handle != NULL) { - macPutValue(handle, name, NULL); - } - } -} - -/* - * Internal commands - */ -static void varHandler(const iocshVarDef *v, const char *setString) -{ - switch(v->type) { - default: - fprintf(epicsGetStderr(), "Can't handle variable %s of type %d.\n", - v->name, v->type); - return; - case iocshArgInt: break; - case iocshArgDouble: break; - } - if(setString == NULL) { - switch(v->type) { - default: break; - case iocshArgInt: - fprintf(epicsGetStdout(), "%s = %d\n", v->name, *(int *)v->pval); - break; - case iocshArgDouble: - fprintf(epicsGetStdout(), "%s = %g\n", v->name, *(double *)v->pval); - break; - } - } - else { - switch(v->type) { - default: break; - case iocshArgInt: - { - char *endp; - long ltmp = strtol(setString, &endp, 0); - if((*setString != '\0') && (*endp == '\0')) - *(int *)v->pval = ltmp; - else - fprintf(epicsGetStderr(), - "Invalid integer value. Var %s not changed.\n", v->name); - break; - } - case iocshArgDouble: - { - char *endp; - double dtmp = epicsStrtod(setString, &endp); - if((*setString != '\0') && (*endp == '\0')) - *(double *)v->pval = dtmp; - else - fprintf(epicsGetStderr(), - "Invalid double value. Var %s not changed.\n", v->name); - break; - } - } - } -} - -static void varCallFunc(const iocshArgBuf *args) -{ - struct iocshVariable *v; - if(args[0].sval == NULL) { - for (v = iocshVariableHead ; v != NULL ; v = v->next) - varHandler(v->pVarDef, args[1].sval); - } - else { - v = (iocshVariable *)registryFind(iocshVarID, args[0].sval); - if (v == NULL) { - fprintf(epicsGetStderr(), "Var %s not found.\n", args[0].sval); - } - else { - varHandler(v->pVarDef, args[1].sval); - } - } -} - -/* iocshCmd */ -static const iocshArg iocshCmdArg0 = { "command",iocshArgString}; -static const iocshArg *iocshCmdArgs[1] = {&iocshCmdArg0}; -static const iocshFuncDef iocshCmdFuncDef = {"iocshCmd",1,iocshCmdArgs}; -static void iocshCmdCallFunc(const iocshArgBuf *args) -{ - iocshCmd(args[0].sval); -} - -/* iocshLoad */ -static const iocshArg iocshLoadArg0 = { "pathname",iocshArgString}; -static const iocshArg iocshLoadArg1 = { "macros", iocshArgString}; -static const iocshArg *iocshLoadArgs[2] = {&iocshLoadArg0, &iocshLoadArg1}; -static const iocshFuncDef iocshLoadFuncDef = {"iocshLoad",2,iocshLoadArgs}; -static void iocshLoadCallFunc(const iocshArgBuf *args) -{ - iocshLoad(args[0].sval, args[1].sval); -} - -/* iocshRun */ -static const iocshArg iocshRunArg0 = { "command",iocshArgString}; -static const iocshArg iocshRunArg1 = { "macros", iocshArgString}; -static const iocshArg *iocshRunArgs[2] = {&iocshRunArg0, &iocshRunArg1}; -static const iocshFuncDef iocshRunFuncDef = {"iocshRun",2,iocshRunArgs}; -static void iocshRunCallFunc(const iocshArgBuf *args) -{ - iocshRun(args[0].sval, args[1].sval); -} - -/* - * Dummy internal commands -- register and install in command table - * so they show up in the help display - */ - -/* comment */ -static const iocshArg commentArg0 = { "newline-terminated comment", - iocshArgArgv}; -static const iocshArg *commentArgs[1] = {&commentArg0}; -static const iocshFuncDef commentFuncDef = {"#",1,commentArgs}; -static void commentCallFunc(const iocshArgBuf *) -{ -} - -/* exit */ -static const iocshFuncDef exitFuncDef = - {"exit",0,0}; -static void exitCallFunc(const iocshArgBuf *) -{ -} - -static void localRegister (void) -{ - iocshRegister(&commentFuncDef,commentCallFunc); - iocshRegister(&exitFuncDef,exitCallFunc); - iocshRegister(&helpFuncDef,helpCallFunc); - iocshRegister(&iocshCmdFuncDef,iocshCmdCallFunc); - iocshRegister(&iocshLoadFuncDef,iocshLoadCallFunc); - iocshRegister(&iocshRunFuncDef,iocshRunCallFunc); -} - -} /* extern "C" */ - -/* - * Register local commands on application startup - */ -class IocshRegister { - public: - IocshRegister() { localRegister(); } -}; -static IocshRegister iocshRegisterObj; diff --git a/src/libCom/iocsh/iocsh.h b/src/libCom/iocsh/iocsh.h deleted file mode 100644 index 3ef3d952b..000000000 --- a/src/libCom/iocsh/iocsh.h +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* iocsh.h ioc: call registered function*/ -/* Author: Marty Kraimer Date: 27APR2000 */ - -#ifndef INCiocshH -#define INCiocshH - -#include -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - iocshArgInt, - iocshArgDouble, - iocshArgString, - iocshArgPdbbase, - iocshArgArgv, - iocshArgPersistentString -}iocshArgType; - -typedef union iocshArgBuf { - int ival; - double dval; - char *sval; - void *vval; - struct { - int ac; - char **av; - } aval; -}iocshArgBuf; - -typedef struct iocshVarDef { - const char *name; - iocshArgType type; - void * pval; -}iocshVarDef; - -typedef struct iocshArg { - const char *name; - iocshArgType type; -}iocshArg; - -typedef struct iocshFuncDef { - const char *name; - int nargs; - const iocshArg * const *arg; -}iocshFuncDef; - -typedef void (*iocshCallFunc)(const iocshArgBuf *argBuf); - -typedef struct iocshCmdDef { - iocshFuncDef const *pFuncDef; - iocshCallFunc func; -}iocshCmdDef; - -epicsShareFunc void epicsShareAPI iocshRegister( - const iocshFuncDef *piocshFuncDef, iocshCallFunc func); -epicsShareFunc void epicsShareAPI iocshRegisterVariable ( - const iocshVarDef *piocshVarDef); -epicsShareFunc const iocshCmdDef * epicsShareAPI iocshFindCommand( - const char* name); -epicsShareFunc const iocshVarDef * epicsShareAPI iocshFindVariable( - const char* name); - -/* iocshFree frees storage used by iocshRegister*/ -/* This should only be called when iocsh is no longer needed*/ -epicsShareFunc void epicsShareAPI iocshFree(void); - -epicsShareFunc int epicsShareAPI iocsh(const char *pathname); -epicsShareFunc int epicsShareAPI iocshCmd(const char *cmd); -epicsShareFunc int epicsShareAPI iocshLoad(const char *pathname, const char* macros); -epicsShareFunc int epicsShareAPI iocshRun(const char *cmd, const char* macros); - -/* Makes macros that shadow environment variables work correctly with epicsEnvSet */ -epicsShareFunc void epicsShareAPI iocshEnvClear(const char *name); - -/* 'weak' link to pdbbase */ -epicsShareExtern struct dbBase **iocshPpdbbase; - -#ifdef __cplusplus -} -#endif - -#endif /*INCiocshH*/ diff --git a/src/libCom/iocsh/libComRegister.c b/src/libCom/iocsh/libComRegister.c deleted file mode 100644 index d3a5cfac4..000000000 --- a/src/libCom/iocsh/libComRegister.c +++ /dev/null @@ -1,393 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#define epicsExportSharedSymbols -#include "iocsh.h" -#include "epicsStdioRedirect.h" -#include "epicsString.h" -#include "epicsTime.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "envDefs.h" -#include "osiUnistd.h" -#include "logClient.h" -#include "errlog.h" -#include "taskwd.h" -#include "registry.h" -#include "epicsGeneralTime.h" -#include "libComRegister.h" - - -void date(const char *format) -{ - epicsTimeStamp now; - char nowText[80] = {'\0'}; - - if (epicsTimeGetCurrent(&now)) { - puts("Current time not available."); - return; - } - if (format == NULL || format[0] == '\0') - format = "%Y/%m/%d %H:%M:%S.%06f"; - epicsTimeToStrftime(nowText, sizeof(nowText), format, &now); - puts(nowText); -} - -/* date */ -static const iocshArg dateArg0 = { "format",iocshArgString}; -static const iocshArg * const dateArgs[] = {&dateArg0}; -static const iocshFuncDef dateFuncDef = {"date", 1, dateArgs}; -static void dateCallFunc (const iocshArgBuf *args) -{ - date(args[0].sval); -} - -/* echo */ -static const iocshArg echoArg0 = { "string",iocshArgString}; -static const iocshArg * const echoArgs[1] = {&echoArg0}; -static const iocshFuncDef echoFuncDef = {"echo",1,echoArgs}; -static void echoCallFunc(const iocshArgBuf *args) -{ - char *str = args[0].sval; - - if (str) - dbTranslateEscape(str, str); /* in-place is safe */ - else - str = ""; - printf("%s\n", str); -} - -/* chdir */ -static const iocshArg chdirArg0 = { "directory name",iocshArgString}; -static const iocshArg * const chdirArgs[1] = {&chdirArg0}; -static const iocshFuncDef chdirFuncDef = {"cd",1,chdirArgs}; -static void chdirCallFunc(const iocshArgBuf *args) -{ - if (args[0].sval == NULL || - chdir(args[0].sval)) { - fprintf(stderr, "Invalid directory path, ignored\n"); - } -} - -/* print current working directory */ -static const iocshFuncDef pwdFuncDef = { "pwd", 0, 0 }; -static void pwdCallFunc (const iocshArgBuf *args) -{ - char buf[256]; - char *pwd = getcwd ( buf, sizeof(buf) - 1 ); - if ( pwd ) { - printf ( "%s\n", pwd ); - } -} - -/* epicsEnvSet */ -static const iocshArg epicsEnvSetArg0 = { "name",iocshArgString}; -static const iocshArg epicsEnvSetArg1 = { "value",iocshArgString}; -static const iocshArg * const epicsEnvSetArgs[2] = {&epicsEnvSetArg0,&epicsEnvSetArg1}; -static const iocshFuncDef epicsEnvSetFuncDef = {"epicsEnvSet",2,epicsEnvSetArgs}; -static void epicsEnvSetCallFunc(const iocshArgBuf *args) -{ - char *name = args[0].sval; - char *value = args[1].sval; - - if (name == NULL) { - fprintf(stderr, "Missing environment variable name argument.\n"); - return; - } - if (value == NULL) { - fprintf(stderr, "Missing environment variable value argument.\n"); - return; - } - epicsEnvSet (name, value); -} - -/* epicsParamShow */ -static const iocshFuncDef epicsParamShowFuncDef = {"epicsParamShow",0,NULL}; -static void epicsParamShowCallFunc(const iocshArgBuf *args) -{ - epicsPrtEnvParams (); -} - -/* epicsPrtEnvParams */ -static const iocshFuncDef epicsPrtEnvParamsFuncDef = {"epicsPrtEnvParams",0,0}; -static void epicsPrtEnvParamsCallFunc(const iocshArgBuf *args) -{ - epicsPrtEnvParams (); -} - -/* epicsEnvShow */ -static const iocshArg epicsEnvShowArg0 = { "[name]",iocshArgString}; -static const iocshArg * const epicsEnvShowArgs[1] = {&epicsEnvShowArg0}; -static const iocshFuncDef epicsEnvShowFuncDef = {"epicsEnvShow",1,epicsEnvShowArgs}; -static void epicsEnvShowCallFunc(const iocshArgBuf *args) -{ - epicsEnvShow (args[0].sval); -} - -/* registryDump */ -static const iocshFuncDef registryDumpFuncDef = {"registryDump",0,NULL}; -static void registryDumpCallFunc(const iocshArgBuf *args) -{ - registryDump (); -} - -/* iocLogInit */ -static const iocshFuncDef iocLogInitFuncDef = {"iocLogInit",0}; -static void iocLogInitCallFunc(const iocshArgBuf *args) -{ - iocLogInit (); -} - -/* iocLogDisable */ -static const iocshArg iocLogDisableArg0 = {"(0,1)=>(false,true)",iocshArgInt}; -static const iocshArg * const iocLogDisableArgs[1] = {&iocLogDisableArg0}; -static const iocshFuncDef iocLogDisableFuncDef = {"setIocLogDisable",1,iocLogDisableArgs}; -static void iocLogDisableCallFunc(const iocshArgBuf *args) -{ - iocLogDisable = args[0].ival; -} - -/* iocLogShow */ -static const iocshArg iocLogShowArg0 = {"level",iocshArgInt}; -static const iocshArg * const iocLogShowArgs[1] = {&iocLogShowArg0}; -static const iocshFuncDef iocLogShowFuncDef = {"iocLogShow",1,iocLogShowArgs}; -static void iocLogShowCallFunc(const iocshArgBuf *args) -{ - iocLogShow (args[0].ival); -} - -/* eltc */ -static const iocshArg eltcArg0 = {"(0,1)=>(false,true)",iocshArgInt}; -static const iocshArg * const eltcArgs[1] = {&eltcArg0}; -static const iocshFuncDef eltcFuncDef = {"eltc",1,eltcArgs}; -static void eltcCallFunc(const iocshArgBuf *args) -{ - eltc(args[0].ival); -} - -/* errlogInit */ -static const iocshArg errlogInitArg0 = { "bufsize",iocshArgInt}; -static const iocshArg * const errlogInitArgs[1] = {&errlogInitArg0}; -static const iocshFuncDef errlogInitFuncDef = - {"errlogInit",1,errlogInitArgs}; -static void errlogInitCallFunc(const iocshArgBuf *args) -{ - errlogInit(args[0].ival); -} - -/* errlogInit2 */ -static const iocshArg errlogInit2Arg0 = { "bufSize",iocshArgInt}; -static const iocshArg errlogInit2Arg1 = { "maxMsgSize",iocshArgInt}; -static const iocshArg * const errlogInit2Args[] = - {&errlogInit2Arg0, &errlogInit2Arg1}; -static const iocshFuncDef errlogInit2FuncDef = - {"errlogInit2", 2, errlogInit2Args}; -static void errlogInit2CallFunc(const iocshArgBuf *args) -{ - errlogInit2(args[0].ival, args[1].ival); -} - -/* errlog */ -static const iocshArg errlogArg0 = { "message",iocshArgString}; -static const iocshArg * const errlogArgs[1] = {&errlogArg0}; -static const iocshFuncDef errlogFuncDef = {"errlog",1,errlogArgs}; -static void errlogCallFunc(const iocshArgBuf *args) -{ - errlogPrintfNoConsole("%s\n", args[0].sval); -} - -/* iocLogPrefix */ -static const iocshArg iocLogPrefixArg0 = { "prefix",iocshArgString}; -static const iocshArg * const iocLogPrefixArgs[1] = {&iocLogPrefixArg0}; -static const iocshFuncDef iocLogPrefixFuncDef = {"iocLogPrefix",1,iocLogPrefixArgs}; -static void iocLogPrefixCallFunc(const iocshArgBuf *args) -{ - iocLogPrefix(args[0].sval); -} - -/* epicsThreadShowAll */ -static const iocshArg epicsThreadShowAllArg0 = { "level",iocshArgInt}; -static const iocshArg * const epicsThreadShowAllArgs[1] = {&epicsThreadShowAllArg0}; -static const iocshFuncDef epicsThreadShowAllFuncDef = - {"epicsThreadShowAll",1,epicsThreadShowAllArgs}; -static void epicsThreadShowAllCallFunc(const iocshArgBuf *args) -{ - epicsThreadShowAll(args[0].ival); -} - -/* epicsThreadShow */ -static const iocshArg threadArg0 = { "[-level] [thread ...]", iocshArgArgv}; -static const iocshArg * const threadArgs[1] = { &threadArg0 }; -static const iocshFuncDef threadFuncDef = {"epicsThreadShow",1,threadArgs}; -static void threadCallFunc(const iocshArgBuf *args) -{ - int i = 1; - int first = 1; - int level = 0; - const char *cp; - epicsThreadId tid; - unsigned long ltmp; - int argc = args[0].aval.ac; - char **argv = args[0].aval.av; - char *endp; - - if ((i < argc) && (*(cp = argv[i]) == '-')) { - level = atoi (cp + 1); - i++; - } - if (i >= argc) { - epicsThreadShowAll (level); - return; - } - for ( ; i < argc ; i++) { - cp = argv[i]; - ltmp = strtoul (cp, &endp, 0); - if (*endp) { - tid = epicsThreadGetId (cp); - if (!tid) { - fprintf(stderr, "\t'%s' is not a known thread name\n", cp); - continue; - } - } - else { - tid = (epicsThreadId)ltmp; - } - if (first) { - epicsThreadShow (0, level); - first = 0; - } - epicsThreadShow (tid, level); - } -} - -/* taskwdShow */ -static const iocshArg taskwdShowArg0 = { "level",iocshArgInt}; -static const iocshArg * const taskwdShowArgs[1] = {&taskwdShowArg0}; -static const iocshFuncDef taskwdShowFuncDef = - {"taskwdShow",1,taskwdShowArgs}; -static void taskwdShowCallFunc(const iocshArgBuf *args) -{ - taskwdShow(args[0].ival); -} - -/* epicsMutexShowAll */ -static const iocshArg epicsMutexShowAllArg0 = { "onlyLocked",iocshArgInt}; -static const iocshArg epicsMutexShowAllArg1 = { "level",iocshArgInt}; -static const iocshArg * const epicsMutexShowAllArgs[2] = - {&epicsMutexShowAllArg0,&epicsMutexShowAllArg1}; -static const iocshFuncDef epicsMutexShowAllFuncDef = - {"epicsMutexShowAll",1,epicsMutexShowAllArgs}; -static void epicsMutexShowAllCallFunc(const iocshArgBuf *args) -{ - epicsMutexShowAll(args[0].ival,args[1].ival); -} - -/* epicsThreadSleep */ -static const iocshArg epicsThreadSleepArg0 = { "seconds",iocshArgDouble}; -static const iocshArg * const epicsThreadSleepArgs[1] = {&epicsThreadSleepArg0}; -static const iocshFuncDef epicsThreadSleepFuncDef = - {"epicsThreadSleep",1,epicsThreadSleepArgs}; -static void epicsThreadSleepCallFunc(const iocshArgBuf *args) -{ - epicsThreadSleep(args[0].dval); -} - -/* epicsThreadResume */ -static const iocshArg epicsThreadResumeArg0 = { "[thread ...]", iocshArgArgv}; -static const iocshArg * const epicsThreadResumeArgs[1] = { &epicsThreadResumeArg0 }; -static const iocshFuncDef epicsThreadResumeFuncDef = {"epicsThreadResume",1,epicsThreadResumeArgs}; -static void epicsThreadResumeCallFunc(const iocshArgBuf *args) -{ - int i; - const char *cp; - epicsThreadId tid; - unsigned long ltmp; - char nameBuf[64]; - int argc = args[0].aval.ac; - char **argv = args[0].aval.av; - char *endp; - - for (i = 1 ; i < argc ; i++) { - cp = argv[i]; - ltmp = strtoul(cp, &endp, 0); - if (*endp) { - tid = epicsThreadGetId(cp); - if (!tid) { - fprintf(stderr, "'%s' is not a valid thread name\n", cp); - continue; - } - } - else { - tid =(epicsThreadId)ltmp; - epicsThreadGetName(tid, nameBuf, sizeof nameBuf); - if (nameBuf[0] == '\0') { - fprintf(stderr, "'%s' is not a valid thread id\n", cp); - continue; - } - - } - if (!epicsThreadIsSuspended(tid)) { - fprintf(stderr, "Thread %s is not suspended\n", cp); - continue; - } - epicsThreadResume(tid); - } -} - -/* generalTimeReport */ -static const iocshArg generalTimeReportArg0 = { "interest_level", iocshArgArgv}; -static const iocshArg * const generalTimeReportArgs[1] = { &generalTimeReportArg0 }; -static const iocshFuncDef generalTimeReportFuncDef = {"generalTimeReport",1,generalTimeReportArgs}; -static void generalTimeReportCallFunc(const iocshArgBuf *args) -{ - generalTimeReport(args[0].ival); -} - -/* installLastResortEventProvider */ -static const iocshFuncDef installLastResortEventProviderFuncDef = {"installLastResortEventProvider", 0, NULL}; -static void installLastResortEventProviderCallFunc(const iocshArgBuf *args) -{ - installLastResortEventProvider(); -} - -void epicsShareAPI libComRegister(void) -{ - iocshRegister(&dateFuncDef, dateCallFunc); - iocshRegister(&echoFuncDef, echoCallFunc); - iocshRegister(&chdirFuncDef, chdirCallFunc); - iocshRegister(&pwdFuncDef, pwdCallFunc); - - iocshRegister(&epicsEnvSetFuncDef, epicsEnvSetCallFunc); - iocshRegister(&epicsParamShowFuncDef, epicsParamShowCallFunc); - iocshRegister(&epicsPrtEnvParamsFuncDef, epicsPrtEnvParamsCallFunc); - iocshRegister(&epicsEnvShowFuncDef, epicsEnvShowCallFunc); - iocshRegister(®istryDumpFuncDef, registryDumpCallFunc); - - iocshRegister(&iocLogInitFuncDef, iocLogInitCallFunc); - iocshRegister(&iocLogDisableFuncDef, iocLogDisableCallFunc); - iocshRegister(&iocLogShowFuncDef, iocLogShowCallFunc); - iocshRegister(&eltcFuncDef, eltcCallFunc); - iocshRegister(&errlogInitFuncDef,errlogInitCallFunc); - iocshRegister(&errlogInit2FuncDef,errlogInit2CallFunc); - iocshRegister(&errlogFuncDef, errlogCallFunc); - iocshRegister(&iocLogPrefixFuncDef, iocLogPrefixCallFunc); - - iocshRegister(&epicsThreadShowAllFuncDef,epicsThreadShowAllCallFunc); - iocshRegister(&threadFuncDef, threadCallFunc); - iocshRegister(&taskwdShowFuncDef,taskwdShowCallFunc); - iocshRegister(&epicsMutexShowAllFuncDef,epicsMutexShowAllCallFunc); - iocshRegister(&epicsThreadSleepFuncDef,epicsThreadSleepCallFunc); - iocshRegister(&epicsThreadResumeFuncDef,epicsThreadResumeCallFunc); - - iocshRegister(&generalTimeReportFuncDef,generalTimeReportCallFunc); - iocshRegister(&installLastResortEventProviderFuncDef, installLastResortEventProviderCallFunc); -} diff --git a/src/libCom/iocsh/libComRegister.h b/src/libCom/iocsh/libComRegister.h deleted file mode 100644 index ef93f4a8d..000000000 --- a/src/libCom/iocsh/libComRegister.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_libComRegister_H -#define INC_libComRegister_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void epicsShareAPI libComRegister(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_libComRegister_H */ diff --git a/src/libCom/iocsh/registry.c b/src/libCom/iocsh/registry.c deleted file mode 100644 index 0b2e312e3..000000000 --- a/src/libCom/iocsh/registry.c +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*registry.c */ - -/* Author: Marty Kraimer Date: 08JUN99 */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "cantProceed.h" -#include "epicsFindSymbol.h" -#include "gpHash.h" -#include "registry.h" - -static struct gphPvt *gphPvt = 0; - -static void registryInit(int tableSize) -{ - if(tableSize==0) tableSize = DEFAULT_TABLE_SIZE; - gphInitPvt(&gphPvt,tableSize); - if(!gphPvt) cantProceed("registry why did gphInitPvt fail\n"); -} - -epicsShareFunc int epicsShareAPI registrySetTableSize(int size) -{ - if(gphPvt) { - printf("registryInit already called\n"); - return(-1); - } - registryInit(size); - return(0); -} - - -epicsShareFunc int epicsShareAPI registryAdd( - void *registryID,const char *name,void *data) -{ - GPHENTRY *pentry; - if(!gphPvt) registryInit(0); - pentry = gphAdd(gphPvt,name,registryID); - if(!pentry) return(FALSE); - pentry->userPvt = data; - return(TRUE); -} - -epicsShareFunc int epicsShareAPI registryChange( - void *registryID,const char *name,void *data) -{ - GPHENTRY *pentry; - if(!gphPvt) registryInit(0); - pentry = gphFind(gphPvt,(char *)name,registryID); - if(!pentry) return(FALSE); - pentry->userPvt = data; - return(TRUE); -} - -epicsShareFunc void * epicsShareAPI registryFind( - void *registryID,const char *name) -{ - GPHENTRY *pentry; - if(name==0) return(0); - if(registryID==0) return(epicsFindSymbol(name)); - if(!gphPvt) registryInit(0); - pentry = gphFind(gphPvt,(char *)name,registryID); - if(!pentry) return(0); - return(pentry->userPvt); -} - -epicsShareFunc void epicsShareAPI registryFree(void) -{ - if(!gphPvt) return; - gphFreeMem(gphPvt); - gphPvt = 0; -} - -epicsShareFunc int epicsShareAPI registryDump(void) -{ - if(!gphPvt) return(0); - gphDump(gphPvt); - return(0); -} diff --git a/src/libCom/iocsh/registry.h b/src/libCom/iocsh/registry.h deleted file mode 100644 index ea1bb7ce7..000000000 --- a/src/libCom/iocsh/registry.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef INCregistryh -#define INCregistryh - -#include "shareLib.h" -#ifdef __cplusplus -extern "C" { -#endif - -#define DEFAULT_TABLE_SIZE 1024 - -epicsShareFunc int epicsShareAPI registryAdd( - void *registryID,const char *name,void *data); -epicsShareFunc void *epicsShareAPI registryFind( - void *registryID,const char *name); -epicsShareFunc int epicsShareAPI registryChange( - void *registryID,const char *name,void *data); - -epicsShareFunc int epicsShareAPI registrySetTableSize(int size); -epicsShareFunc void epicsShareAPI registryFree(void); -epicsShareFunc int epicsShareAPI registryDump(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INCregistryh */ diff --git a/src/libCom/log/Makefile b/src/libCom/log/Makefile deleted file mode 100644 index 7d7a6b620..000000000 --- a/src/libCom/log/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/log -INC += iocLog.h -INC += logClient.h -Com_SRCS += iocLog.c -Com_SRCS += logClient.c - -PROD_HOST += iocLogServer - -iocLogServer_SRCS = iocLogServer.c -iocLogServer_LIBS = Com - -iocLogServer_SYS_LIBS_solaris += socket -iocLogServer_SYS_LIBS_WIN32 += user32 ws2_32 - -SCRIPTS_HOST = S99logServer - -EXPAND += S99logServer@ -EXPAND_VARS = INSTALL_BIN=$(abspath $(INSTALL_BIN)) - diff --git a/src/libCom/log/S99logServer@ b/src/libCom/log/S99logServer@ deleted file mode 100644 index 294b2ec01..000000000 --- a/src/libCom/log/S99logServer@ +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh -# -# System-V init script for the EPICS IOC Log Server. -# - -INSTALL_BIN=@INSTALL_BIN@ - -# To change the default values for the EPICS Environment parameters, -# uncomment and modify the relevant lines below. - -# EPICS_IOC_LOG_PORT="6500" export EPICS_IOC_LOG_PORT -# EPICS_IOC_LOG_FILE_NAME="/path/to/iocLog" export EPICS_IOC_LOG_FILE_NAME -# EPICS_IOC_LOG_FILE_LIMIT="1000000" export EPICS_IOC_LOG_FILE_LIMIT - -if [ $1 = "start" ]; then - if [ -x $INSTALL_BIN/iocLogServer ]; then - echo "Starting EPICS Log Server " - $INSTALL_BIN/iocLogServer & - fi -else - if [ $1 = "stop" ]; then - pid=`ps -e | sed -ne '/iocLogSe/s/^ *\([1-9][0-9]*\).*$/\1/p'` - if [ "${pid}" != "" ]; then - echo "Stopping EPICS Log Server " - kill ${pid} - fi - fi -fi - diff --git a/src/libCom/log/iocLog.c b/src/libCom/log/iocLog.c deleted file mode 100644 index e62da2050..000000000 --- a/src/libCom/log/iocLog.c +++ /dev/null @@ -1,137 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* logClient.c,v 1.25.2.6 2004/10/07 13:37:34 mrk Exp */ -/* - * Author: Jeffrey O. Hill - * Date: 080791 - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "envDefs.h" -#include "logClient.h" -#include "iocLog.h" - -int iocLogDisable = 0; - -static const int iocLogSuccess = 0; -static const int iocLogError = -1; - -static logClientId iocLogClient; - -/* - * getConfig() - * Get Server Configuration - */ -static int getConfig (struct in_addr *pserver_addr, unsigned short *pserver_port) -{ - long status; - long epics_port; - - status = envGetLongConfigParam (&EPICS_IOC_LOG_PORT, &epics_port); - if (status<0) { - fprintf (stderr, - "iocLog: EPICS environment variable \"%s\" undefined\n", - EPICS_IOC_LOG_PORT.name); - return iocLogError; - } - - if (epics_port<0 || epics_port>USHRT_MAX) { - fprintf (stderr, - "iocLog: EPICS environment variable \"%s\" out of range\n", - EPICS_IOC_LOG_PORT.name); - return iocLogError; - } - *pserver_port = (unsigned short) epics_port; - - status = envGetInetAddrConfigParam (&EPICS_IOC_LOG_INET, pserver_addr); - if (status<0) { - fprintf (stderr, - "iocLog: EPICS environment variable \"%s\" undefined\n", - EPICS_IOC_LOG_INET.name); - return iocLogError; - } - - return iocLogSuccess; -} - -/* - * iocLogFlush () - */ -void epicsShareAPI epicsShareAPI iocLogFlush (void) -{ - if (iocLogClient!=NULL) { - logClientFlush (iocLogClient); - } -} - -/* - * iocLogClientInit() - */ -static logClientId iocLogClientInit (void) -{ - int status; - logClientId id; - struct in_addr addr; - unsigned short port; - - status = getConfig (&addr, &port); - if (status) { - return NULL; - } - id = logClientCreate (addr, port); - return id; -} - -/* - * iocLogInit() - */ -int epicsShareAPI iocLogInit (void) -{ - /* - * check for global disable - */ - if (iocLogDisable) { - return iocLogSuccess; - } - /* - * dont init twice - */ - if (iocLogClient!=NULL) { - return iocLogSuccess; - } - iocLogClient = iocLogClientInit (); - if (iocLogClient) { - return iocLogSuccess; - } - else { - return iocLogError; - } -} - -/* - * iocLogShow () - */ -void epicsShareAPI iocLogShow (unsigned level) -{ - if (iocLogClient!=NULL) { - logClientShow (iocLogClient, level); - } -} - -/* - * logClientInit(); deprecated - */ -logClientId epicsShareAPI logClientInit (void) -{ - return iocLogClientInit (); -} diff --git a/src/libCom/log/iocLog.h b/src/libCom/log/iocLog.h deleted file mode 100644 index b6f7ddf6e..000000000 --- a/src/libCom/log/iocLog.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* logClient.h,v 1.5.2.1 2003/07/08 00:08:06 jhill Exp */ -/* - * - * Author: Jeffrey O. Hill - * Date: 080791 - */ - -#ifndef INCiocLogh -#define INCiocLogh 1 -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * ioc log client interface - */ -epicsShareExtern int iocLogDisable; -epicsShareFunc int epicsShareAPI iocLogInit (void); -epicsShareFunc void epicsShareAPI iocLogShow (unsigned level); -epicsShareFunc void epicsShareAPI iocLogFlush (void); - -#ifdef __cplusplus -} -#endif - -#endif /*INCiocLogh*/ diff --git a/src/libCom/log/iocLogServer.c b/src/libCom/log/iocLogServer.c deleted file mode 100644 index f5694fc0f..000000000 --- a/src/libCom/log/iocLogServer.c +++ /dev/null @@ -1,999 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* iocLogServer.c */ - -/* - * archive logMsg() from several IOC's to a common rotating file - * - * - * Author: Jeffrey O. Hill - * Date: 080791 - */ - -#include -#include -#include -#include -#include -#include - -#ifdef UNIX -#include -#include -#endif - -#include "dbDefs.h" -#include "epicsAssert.h" -#include "fdmgr.h" -#include "envDefs.h" -#include "osiSock.h" -#include "epicsStdio.h" - -static unsigned short ioc_log_port; -static long ioc_log_file_limit; -static char ioc_log_file_name[256]; -static char ioc_log_file_command[256]; - - -struct iocLogClient { - int insock; - struct ioc_log_server *pserver; - size_t nChar; - char recvbuf[1024]; - char name[32]; - char ascii_time[32]; -}; - -struct ioc_log_server { - char outfile[256]; - long filePos; - FILE *poutfile; - void *pfdctx; - SOCKET sock; - long max_file_size; -}; - -#define IOCLS_ERROR (-1) -#define IOCLS_OK 0 - -static void acceptNewClient (void *pParam); -static void readFromClient(void *pParam); -static void logTime (struct iocLogClient *pclient); -static int getConfig(void); -static int openLogFile(struct ioc_log_server *pserver); -static void handleLogFileError(void); -static void envFailureNotify(const ENV_PARAM *pparam); -static void freeLogClient(struct iocLogClient *pclient); -static void writeMessagesToLog (struct iocLogClient *pclient); - -#ifdef UNIX -static int setupSIGHUP(struct ioc_log_server *); -static void sighupHandler(int); -static void serviceSighupRequest(void *pParam); -static int getDirectory(void); -static int sighupPipe[2]; -#endif - - - -/* - * - * main() - * - */ -int main(void) -{ - struct sockaddr_in serverAddr; /* server's address */ - struct timeval timeout; - int status; - struct ioc_log_server *pserver; - - osiSockIoctl_t optval; - - status = getConfig(); - if (status<0) { - fprintf(stderr, "iocLogServer: EPICS environment underspecified\n"); - fprintf(stderr, "iocLogServer: failed to initialize\n"); - return IOCLS_ERROR; - } - - pserver = (struct ioc_log_server *) - calloc(1, sizeof *pserver); - if (!pserver) { - fprintf(stderr, "iocLogServer: %s\n", strerror(errno)); - return IOCLS_ERROR; - } - - pserver->pfdctx = (void *) fdmgr_init(); - if (!pserver->pfdctx) { - fprintf(stderr, "iocLogServer: %s\n", strerror(errno)); - return IOCLS_ERROR; - } - - /* - * Open the socket. Use ARPA Internet address format and stream - * sockets. Format described in . - */ - pserver->sock = epicsSocketCreate(AF_INET, SOCK_STREAM, 0); - if (pserver->sock == INVALID_SOCKET) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf(stderr, "iocLogServer: sock create err: %s\n", sockErrBuf); - free(pserver); - return IOCLS_ERROR; - } - - epicsSocketEnableAddressReuseDuringTimeWaitState ( pserver->sock ); - - /* Zero the sock_addr structure */ - memset((void *)&serverAddr, 0, sizeof serverAddr); - serverAddr.sin_family = AF_INET; - serverAddr.sin_port = htons(ioc_log_port); - - /* get server's Internet address */ - status = bind ( pserver->sock, - (struct sockaddr *)&serverAddr, - sizeof (serverAddr) ); - if (status < 0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf(stderr, "iocLogServer: bind err: %s\n", sockErrBuf ); - fprintf (stderr, - "iocLogServer: a server is already installed on port %u?\n", - (unsigned)ioc_log_port); - return IOCLS_ERROR; - } - - /* listen and accept new connections */ - status = listen(pserver->sock, 10); - if (status < 0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf(stderr, "iocLogServer: listen err %s\n", sockErrBuf); - return IOCLS_ERROR; - } - - /* - * Set non blocking IO - * to prevent dead locks - */ - optval = TRUE; - status = socket_ioctl( - pserver->sock, - FIONBIO, - &optval); - if (status < 0){ - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf(stderr, "iocLogServer: ioctl FIONBIO err %s\n", sockErrBuf); - return IOCLS_ERROR; - } - -# ifdef UNIX - status = setupSIGHUP(pserver); - if (status < 0) { - return IOCLS_ERROR; - } -# endif - - status = openLogFile(pserver); - if (status < 0) { - fprintf(stderr, - "File access problems to `%s' because `%s'\n", - ioc_log_file_name, - strerror(errno)); - return IOCLS_ERROR; - } - - status = fdmgr_add_callback( - pserver->pfdctx, - pserver->sock, - fdi_read, - acceptNewClient, - pserver); - if (status < 0) { - fprintf(stderr, - "iocLogServer: failed to add read callback\n"); - return IOCLS_ERROR; - } - - - while (TRUE) { - timeout.tv_sec = 60; /* 1 min */ - timeout.tv_usec = 0; - fdmgr_pend_event(pserver->pfdctx, &timeout); - fflush(pserver->poutfile); - } -} - -/* - * seekLatestLine (struct ioc_log_server *pserver) - */ -static int seekLatestLine (struct ioc_log_server *pserver) -{ - static const time_t invalidTime = (time_t) -1; - time_t theLatestTime = invalidTime; - long latestFilePos = -1; - int status; - - /* - * start at the beginning - */ - rewind (pserver->poutfile); - - while (1) { - struct tm theDate; - int convertStatus; - char month[16]; - - /* - * find the line in the file with the latest date - * - * this assumes ctime() produces dates of the form: - * DayName MonthName dayNum 24hourHourNum:minNum:secNum yearNum - */ - convertStatus = fscanf ( - pserver->poutfile, " %*s %*s %15s %d %d:%d:%d %d %*[^\n] ", - month, &theDate.tm_mday, &theDate.tm_hour, - &theDate.tm_min, &theDate.tm_sec, &theDate.tm_year); - if (convertStatus==6) { - static const char *pMonths[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - static const unsigned nMonths = sizeof(pMonths)/sizeof(pMonths[0]); - time_t lineTime = (time_t) -1; - unsigned iMonth; - - for (iMonth=0; iMonthtm_epoch_year) { - theDate.tm_year -= tm_epoch_year; - theDate.tm_isdst = -1; /* dont know */ - lineTime = mktime (&theDate); - if ( lineTime != invalidTime ) { - if (theLatestTime == invalidTime || - difftime(lineTime, theLatestTime)>=0) { - latestFilePos = ftell (pserver->poutfile); - theLatestTime = lineTime; - } - } - else { - char date[128]; - size_t nChar; - nChar = strftime (date, sizeof(date), "%a %b %d %H:%M:%S %Y\n", &theDate); - if (nChar>0) { - fprintf (stderr, "iocLogServer: strange date in log file: %s\n", date); - } - else { - fprintf (stderr, "iocLogServer: strange date in log file\n"); - } - } - } - else { - fprintf (stderr, "iocLogServer: strange year in log file: %d\n", theDate.tm_year); - } - } - else { - fprintf (stderr, "iocLogServer: strange month in log file: %s\n", month); - } - } - else { - int c = fgetc (pserver->poutfile); - - /* - * bypass the line if it does not match the expected format - */ - while ( c!=EOF && c!='\n' ) { - c = fgetc (pserver->poutfile); - } - - if (c==EOF) { - break; - } - } - } - - /* - * move to the proper location in the file - */ - if (latestFilePos != -1) { - status = fseek (pserver->poutfile, latestFilePos, SEEK_SET); - if (status!=IOCLS_OK) { - fclose (pserver->poutfile); - pserver->poutfile = stderr; - return IOCLS_ERROR; - } - } - else { - status = fseek (pserver->poutfile, 0L, SEEK_END); - if (status!=IOCLS_OK) { - fclose (pserver->poutfile); - pserver->poutfile = stderr; - return IOCLS_ERROR; - } - } - - pserver->filePos = ftell (pserver->poutfile); - - if (theLatestTime==invalidTime) { - if (pserver->filePos!=0) { - fprintf (stderr, "iocLogServer: **** Warning ****\n"); - fprintf (stderr, "iocLogServer: no recognizable dates in \"%s\"\n", - ioc_log_file_name); - fprintf (stderr, "iocLogServer: logging at end of file\n"); - } - } - - return IOCLS_OK; -} - - -/* - * openLogFile() - * - */ -static int openLogFile (struct ioc_log_server *pserver) -{ - enum TF_RETURN ret; - - if (ioc_log_file_limit==0u) { - pserver->poutfile = stderr; - return IOCLS_ERROR; - } - - if (pserver->poutfile && pserver->poutfile != stderr){ - fclose (pserver->poutfile); - pserver->poutfile = NULL; - } - - pserver->poutfile = fopen(ioc_log_file_name, "r+"); - if (pserver->poutfile) { - fclose (pserver->poutfile); - pserver->poutfile = NULL; - ret = truncateFile (ioc_log_file_name, ioc_log_file_limit); - if (ret==TF_ERROR) { - return IOCLS_ERROR; - } - pserver->poutfile = fopen(ioc_log_file_name, "r+"); - } - else { - pserver->poutfile = fopen(ioc_log_file_name, "w"); - } - - if (!pserver->poutfile) { - pserver->poutfile = stderr; - return IOCLS_ERROR; - } - strcpy (pserver->outfile, ioc_log_file_name); - pserver->max_file_size = ioc_log_file_limit; - - return seekLatestLine (pserver); -} - - -/* - * handleLogFileError() - * - */ -static void handleLogFileError(void) -{ - fprintf(stderr, - "iocLogServer: log file access problem (errno=%s)\n", - strerror(errno)); - exit(IOCLS_ERROR); -} - - - -/* - * acceptNewClient() - * - */ -static void acceptNewClient ( void *pParam ) -{ - struct ioc_log_server *pserver = (struct ioc_log_server *) pParam; - struct iocLogClient *pclient; - osiSocklen_t addrSize; - struct sockaddr_in addr; - int status; - osiSockIoctl_t optval; - - pclient = ( struct iocLogClient * ) malloc ( sizeof ( *pclient ) ); - if ( ! pclient ) { - return; - } - - addrSize = sizeof ( addr ); - pclient->insock = epicsSocketAccept ( pserver->sock, (struct sockaddr *)&addr, &addrSize ); - if ( pclient->insock==INVALID_SOCKET || addrSize < sizeof (addr) ) { - static unsigned acceptErrCount; - static int lastErrno; - int thisErrno; - - free ( pclient ); - if ( SOCKERRNO == SOCK_EWOULDBLOCK || SOCKERRNO == SOCK_EINTR ) { - return; - } - - thisErrno = SOCKERRNO; - if ( acceptErrCount % 1000 || lastErrno != thisErrno ) { - fprintf ( stderr, "Accept Error %d\n", SOCKERRNO ); - } - acceptErrCount++; - lastErrno = thisErrno; - - return; - } - - /* - * Set non blocking IO - * to prevent dead locks - */ - optval = TRUE; - status = socket_ioctl( - pclient->insock, - FIONBIO, - &optval); - if(status<0){ - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf(stderr, "%s:%d ioctl FBIO client er %s\n", - __FILE__, __LINE__, sockErrBuf); - epicsSocketDestroy ( pclient->insock ); - free(pclient); - return; - } - - pclient->pserver = pserver; - pclient->nChar = 0u; - - ipAddrToA (&addr, pclient->name, sizeof(pclient->name)); - - logTime(pclient); - -#if 0 - status = fprintf( - pclient->pserver->poutfile, - "%s %s ----- Client Connect -----\n", - pclient->name, - pclient->ascii_time); - if(status<0){ - handleLogFileError(); - } -#endif - - /* - * turn on KEEPALIVE so if the client crashes - * this task will find out and exit - */ - { - long true = 1; - - status = setsockopt( - pclient->insock, - SOL_SOCKET, - SO_KEEPALIVE, - (char *)&true, - sizeof(true) ); - if(status<0){ - fprintf(stderr, "Keepalive option set failed\n"); - } - } - - status = shutdown(pclient->insock, SHUT_WR); - if(status<0){ - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf (stderr, "%s:%d shutdown err %s\n", __FILE__, __LINE__, - sockErrBuf); - epicsSocketDestroy ( pclient->insock ); - free(pclient); - - return; - } - - status = fdmgr_add_callback( - pserver->pfdctx, - pclient->insock, - fdi_read, - readFromClient, - pclient); - if (status<0) { - epicsSocketDestroy ( pclient->insock ); - free(pclient); - fprintf(stderr, "%s:%d client fdmgr_add_callback() failed\n", - __FILE__, __LINE__); - return; - } -} - - - -/* - * readFromClient() - * - */ -#define NITEMS 1 - -static void readFromClient(void *pParam) -{ - struct iocLogClient *pclient = (struct iocLogClient *)pParam; - int recvLength; - int size; - - logTime(pclient); - - size = (int) (sizeof(pclient->recvbuf) - pclient->nChar); - recvLength = recv(pclient->insock, - &pclient->recvbuf[pclient->nChar], - size, - 0); - if (recvLength <= 0) { - if (recvLength<0) { - int errnoCpy = SOCKERRNO; - if (errnoCpy==SOCK_EWOULDBLOCK || errnoCpy==SOCK_EINTR) { - return; - } - if (errnoCpy != SOCK_ECONNRESET && - errnoCpy != SOCK_ECONNABORTED && - errnoCpy != SOCK_EPIPE && - errnoCpy != SOCK_ETIMEDOUT - ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf(stderr, - "%s:%d socket=%d size=%d read error=%s\n", - __FILE__, __LINE__, pclient->insock, - size, sockErrBuf); - } - } - /* - * disconnect - */ - freeLogClient (pclient); - return; - } - - pclient->nChar += (size_t) recvLength; - - writeMessagesToLog (pclient); -} - -/* - * writeMessagesToLog() - */ -static void writeMessagesToLog (struct iocLogClient *pclient) -{ - int status; - size_t lineIndex = 0; - - while (TRUE) { - size_t nchar; - size_t nTotChar; - size_t crIndex; - int ntci; - - if ( lineIndex >= pclient->nChar ) { - pclient->nChar = 0u; - break; - } - - /* - * find the first carrage return and create - * an entry in the log for the message associated - * with it. If a carrage return does not exist and - * the buffer isnt full then move the partial message - * to the front of the buffer and wait for a carrage - * return to arrive. If the buffer is full and there - * is no carrage return then force the message out and - * insert an artificial carrage return. - */ - nchar = pclient->nChar - lineIndex; - for ( crIndex = lineIndex; crIndex < pclient->nChar; crIndex++ ) { - if ( pclient->recvbuf[crIndex] == '\n' ) { - break; - } - } - if ( crIndex < pclient->nChar ) { - nchar = crIndex - lineIndex; - } - else { - nchar = pclient->nChar - lineIndex; - if ( nchar < sizeof ( pclient->recvbuf ) ) { - if ( lineIndex != 0 ) { - pclient->nChar = nchar; - memmove ( pclient->recvbuf, - & pclient->recvbuf[lineIndex], nchar); - } - break; - } - } - - /* - * reset the file pointer if we hit the end of the file - */ - nTotChar = strlen(pclient->name) + - strlen(pclient->ascii_time) + nchar + 3u; - assert (nTotChar <= INT_MAX); - ntci = (int) nTotChar; - if ( pclient->pserver->filePos+ntci >= pclient->pserver->max_file_size ) { - if ( pclient->pserver->max_file_size >= pclient->pserver->filePos ) { - unsigned nPadChar; - /* - * this gets rid of leftover junk at the end of the file - */ - nPadChar = pclient->pserver->max_file_size - pclient->pserver->filePos; - while (nPadChar--) { - status = putc ( ' ', pclient->pserver->poutfile ); - if ( status == EOF ) { - handleLogFileError(); - } - } - } - -# ifdef DEBUG - fprintf ( stderr, - "ioc log server: resetting the file pointer\n" ); -# endif - fflush ( pclient->pserver->poutfile ); - rewind ( pclient->pserver->poutfile ); - pclient->pserver->filePos = ftell ( pclient->pserver->poutfile ); - } - - /* - * NOTE: !! change format string here then must - * change nTotChar calc above !! - */ - assert (ncharpserver->poutfile, - "%s %s %.*s\n", - pclient->name, - pclient->ascii_time, - (int) nchar, - &pclient->recvbuf[lineIndex]); - if (status<0) { - handleLogFileError(); - } - else { - if (status != ntci) { - fprintf(stderr, "iocLogServer: didnt calculate number of characters correctly?\n"); - } - pclient->pserver->filePos += status; - } - lineIndex += nchar+1u; - } -} - - -/* - * freeLogClient () - */ -static void freeLogClient(struct iocLogClient *pclient) -{ - int status; - -# ifdef DEBUG - if(length == 0){ - fprintf(stderr, "iocLogServer: nil message disconnect\n"); - } -# endif - - /* - * flush any left overs - */ - if (pclient->nChar) { - /* - * this forces a flush - */ - if (pclient->nCharrecvbuf)) { - pclient->recvbuf[pclient->nChar] = '\n'; - } - writeMessagesToLog (pclient); - } - - status = fdmgr_clear_callback( - pclient->pserver->pfdctx, - pclient->insock, - fdi_read); - if (status!=IOCLS_OK) { - fprintf(stderr, "%s:%d fdmgr_clear_callback() failed\n", - __FILE__, __LINE__); - } - - epicsSocketDestroy ( pclient->insock ); - - free (pclient); - - return; -} - - -/* - * - * logTime() - * - */ -static void logTime(struct iocLogClient *pclient) -{ - time_t sec; - char *pcr; - char *pTimeString; - - sec = time (NULL); - pTimeString = ctime (&sec); - strncpy (pclient->ascii_time, - pTimeString, - sizeof (pclient->ascii_time) ); - pclient->ascii_time[sizeof(pclient->ascii_time)-1] = '\0'; - pcr = strchr(pclient->ascii_time, '\n'); - if (pcr) { - *pcr = '\0'; - } -} - - -/* - * - * getConfig() - * Get Server Configuration - * - * - */ -static int getConfig(void) -{ - int status; - char *pstring; - long param; - - status = envGetLongConfigParam( - &EPICS_IOC_LOG_PORT, - ¶m); - if(status>=0){ - ioc_log_port = (unsigned short) param; - } - else { - ioc_log_port = 7004U; - } - - status = envGetLongConfigParam( - &EPICS_IOC_LOG_FILE_LIMIT, - &ioc_log_file_limit); - if(status>=0){ - if (ioc_log_file_limit<=0) { - envFailureNotify (&EPICS_IOC_LOG_FILE_LIMIT); - return IOCLS_ERROR; - } - } - else { - ioc_log_file_limit = 10000; - } - - pstring = envGetConfigParam( - &EPICS_IOC_LOG_FILE_NAME, - sizeof ioc_log_file_name, - ioc_log_file_name); - if(pstring == NULL){ - envFailureNotify(&EPICS_IOC_LOG_FILE_NAME); - return IOCLS_ERROR; - } - - /* - * its ok to not specify the IOC_LOG_FILE_COMMAND - */ - pstring = envGetConfigParam( - &EPICS_IOC_LOG_FILE_COMMAND, - sizeof ioc_log_file_command, - ioc_log_file_command); - return IOCLS_OK; -} - - - -/* - * - * failureNotify() - * - * - */ -static void envFailureNotify(const ENV_PARAM *pparam) -{ - fprintf(stderr, - "iocLogServer: EPICS environment variable `%s' undefined\n", - pparam->name); -} - - - -#ifdef UNIX -static int setupSIGHUP(struct ioc_log_server *pserver) -{ - int status; - struct sigaction sigact; - - status = getDirectory(); - if (status<0){ - fprintf(stderr, "iocLogServer: failed to determine log file " - "directory\n"); - return IOCLS_ERROR; - } - - /* - * Set up SIGHUP handler. SIGHUP will cause the log file to be - * closed and re-opened, possibly with a different name. - */ - sigact.sa_handler = sighupHandler; - sigemptyset (&sigact.sa_mask); - sigact.sa_flags = 0; - if (sigaction(SIGHUP, &sigact, NULL)){ - fprintf(stderr, "iocLogServer: %s\n", strerror(errno)); - return IOCLS_ERROR; - } - - status = pipe(sighupPipe); - if(status<0){ - fprintf(stderr, - "iocLogServer: failed to create pipe because `%s'\n", - strerror(errno)); - return IOCLS_ERROR; - } - - status = fdmgr_add_callback( - pserver->pfdctx, - sighupPipe[0], - fdi_read, - serviceSighupRequest, - pserver); - if(status<0){ - fprintf(stderr, - "iocLogServer: failed to add SIGHUP callback\n"); - return IOCLS_ERROR; - } - return IOCLS_OK; -} - -/* - * - * sighupHandler() - * - * - */ -static void sighupHandler(int signo) -{ - (void) write(sighupPipe[1], "SIGHUP\n", 7); -} - - - -/* - * serviceSighupRequest() - * - */ -static void serviceSighupRequest(void *pParam) -{ - struct ioc_log_server *pserver = (struct ioc_log_server *)pParam; - char buff[256]; - int status; - - /* - * Read and discard message from pipe. - */ - (void) read(sighupPipe[0], buff, sizeof buff); - - /* - * Determine new log file name. - */ - status = getDirectory(); - if (status<0){ - fprintf(stderr, "iocLogServer: failed to determine new log " - "file name\n"); - return; - } - - /* - * Try (re)opening the file. - */ - status = openLogFile(pserver); - if(status<0){ - fprintf(stderr, - "File access problems to `%s' because `%s'\n", - ioc_log_file_name, - strerror(errno)); - /* Revert to old filename */ - strcpy(ioc_log_file_name, pserver->outfile); - status = openLogFile(pserver); - if(status<0){ - fprintf(stderr, - "File access problems to `%s' because `%s'\n", - ioc_log_file_name, - strerror(errno)); - return; - } - else { - fprintf(stderr, - "iocLogServer: re-opened old log file %s\n", - ioc_log_file_name); - } - } - else { - fprintf(stderr, - "iocLogServer: opened new log file %s\n", - ioc_log_file_name); - } -} - - - -/* - * - * getDirectory() - * - * - */ -static int getDirectory(void) -{ - FILE *pipe; - char dir[256]; - int i; - - if (ioc_log_file_command[0] != '\0') { - - /* - * Use popen() to execute command and grab output. - */ - pipe = popen(ioc_log_file_command, "r"); - if (pipe == NULL) { - fprintf(stderr, - "Problem executing `%s' because `%s'\n", - ioc_log_file_command, - strerror(errno)); - return IOCLS_ERROR; - } - if (fgets(dir, sizeof(dir), pipe) == NULL) { - fprintf(stderr, - "Problem reading o/p from `%s' because `%s'\n", - ioc_log_file_command, - strerror(errno)); - (void) pclose(pipe); - return IOCLS_ERROR; - } - (void) pclose(pipe); - - /* - * Terminate output at first newline and discard trailing - * slash character if present.. - */ - for (i=0; dir[i] != '\n' && dir[i] != '\0'; i++) - ; - dir[i] = '\0'; - - i = strlen(dir); - if (i > 1 && dir[i-1] == '/') dir[i-1] = '\0'; - - /* - * Use output as directory part of file name. - */ - if (dir[0] != '\0') { - char *name = ioc_log_file_name; - char *slash = strrchr(ioc_log_file_name, '/'); - char temp[256]; - - if (slash != NULL) name = slash + 1; - strcpy(temp,name); - sprintf(ioc_log_file_name,"%s/%s",dir,temp); - } - } - return IOCLS_OK; -} -#endif diff --git a/src/libCom/log/logClient.c b/src/libCom/log/logClient.c deleted file mode 100644 index 99ee671d9..000000000 --- a/src/libCom/log/logClient.c +++ /dev/null @@ -1,618 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* logClient.c,v 1.25.2.6 2004/10/07 13:37:34 mrk Exp */ -/* - * Author: Jeffrey O. Hill - * Date: 080791 - */ - -/* - * ANSI C - */ -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "epicsEvent.h" -#include "iocLog.h" -#include "errlog.h" -#include "epicsMutex.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "osiSock.h" -#include "epicsAssert.h" -#include "epicsExit.h" -#include "epicsSignal.h" - -#include "logClient.h" - -typedef struct { - char msgBuf[0x4000]; - struct sockaddr_in addr; - char name[64]; - epicsMutexId mutex; - SOCKET sock; - epicsThreadId restartThreadId; - epicsEventId stateChangeNotify; - unsigned connectCount; - unsigned nextMsgIndex; - unsigned connected; - unsigned shutdown; - unsigned shutdownConfirm; - int connFailStatus; -} logClient; - -static const double LOG_RESTART_DELAY = 5.0; /* sec */ -static const double LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT = 5.0; /* sec */ -static const double LOG_SERVER_SHUTDOWN_TIMEOUT = 30.0; /* sec */ - -/* - * If set using iocLogPrefix() this string is prepended to all log messages: - */ -static char* logClientPrefix = NULL; - -/* - * logClientClose () - */ -static void logClientClose ( logClient *pClient ) -{ -# ifdef DEBUG - fprintf (stderr, "log client: lingering for connection close..."); - fflush (stderr); -# endif - - /* - * mutex on - */ - epicsMutexMustLock (pClient->mutex); - - /* - * close any preexisting connection to the log server - */ - if ( pClient->sock != INVALID_SOCKET ) { - epicsSocketDestroy ( pClient->sock ); - pClient->sock = INVALID_SOCKET; - } - - pClient->nextMsgIndex = 0u; - memset ( pClient->msgBuf, '\0', sizeof ( pClient->msgBuf ) ); - pClient->connected = 0u; - - /* - * mutex off - */ - epicsMutexUnlock (pClient->mutex); - -# ifdef DEBUG - fprintf (stderr, "done\n"); -# endif -} - -/* - * logClientDestroy - */ -static void logClientDestroy (logClientId id) -{ - enum epicsSocketSystemCallInterruptMechanismQueryInfo interruptInfo; - logClient *pClient = (logClient *) id; - epicsTimeStamp begin, current; - double diff; - - /* command log client thread to shutdown - taking mutex here */ - /* forces cache flush on SMP machines */ - epicsMutexMustLock ( pClient->mutex ); - pClient->shutdown = 1u; - epicsMutexUnlock ( pClient->mutex ); - - /* unblock log client thread blocking in send() or connect() */ - interruptInfo = - epicsSocketSystemCallInterruptMechanismQuery (); - switch ( interruptInfo ) { - case esscimqi_socketCloseRequired: - logClientClose ( pClient ); - break; - case esscimqi_socketBothShutdownRequired: - shutdown ( pClient->sock, SHUT_WR ); - break; - case esscimqi_socketSigAlarmRequired: - epicsSignalRaiseSigAlarm ( pClient->restartThreadId ); - break; - default: - break; - }; - - /* wait for confirmation that the thread exited - taking */ - /* mutex here forces cache update on SMP machines */ - epicsTimeGetCurrent ( & begin ); - epicsMutexMustLock ( pClient->mutex ); - do { - epicsMutexUnlock ( pClient->mutex ); - epicsEventWaitWithTimeout ( - pClient->stateChangeNotify, - LOG_SERVER_SHUTDOWN_TIMEOUT / 10.0 ); - epicsTimeGetCurrent ( & current ); - diff = epicsTimeDiffInSeconds ( & current, & begin ); - epicsMutexMustLock ( pClient->mutex ); - } - while ( ! pClient->shutdownConfirm && diff < LOG_SERVER_SHUTDOWN_TIMEOUT ); - epicsMutexUnlock ( pClient->mutex ); - - if ( ! pClient->shutdownConfirm ) { - fprintf ( stderr, "log client shutdown: timed out stopping" - " reconnect thread for \"%s\" after %.1f seconds - cleanup aborted\n", - pClient->name, LOG_SERVER_SHUTDOWN_TIMEOUT ); - return; - } - - errlogRemoveListeners ( logClientSendMessage, (void *) pClient ); - - logClientClose ( pClient ); - - epicsMutexDestroy ( pClient->mutex ); - - epicsEventDestroy ( pClient->stateChangeNotify ); - - free ( pClient ); -} - -/* - * This method requires the pClient->mutex be owned already. - */ -static void sendMessageChunk(logClient * pClient, const char * message) { - unsigned strSize; - - strSize = strlen ( message ); - while ( strSize ) { - unsigned msgBufBytesLeft = - sizeof ( pClient->msgBuf ) - pClient->nextMsgIndex; - - if ( strSize > msgBufBytesLeft ) { - int status; - - if ( ! pClient->connected ) { - break; - } - - if ( msgBufBytesLeft > 0u ) { - memcpy ( & pClient->msgBuf[pClient->nextMsgIndex], - message, msgBufBytesLeft ); - pClient->nextMsgIndex += msgBufBytesLeft; - strSize -= msgBufBytesLeft; - message += msgBufBytesLeft; - } - - status = send ( pClient->sock, pClient->msgBuf, - pClient->nextMsgIndex, 0 ); - if ( status > 0 ) { - unsigned nSent = (unsigned) status; - if ( nSent < pClient->nextMsgIndex ) { - unsigned newNextMsgIndex = pClient->nextMsgIndex - nSent; - memmove ( pClient->msgBuf, & pClient->msgBuf[nSent], - newNextMsgIndex ); - pClient->nextMsgIndex = newNextMsgIndex; - } - else { - pClient->nextMsgIndex = 0u; - } - } - else { - if ( ! pClient->shutdown ) { - char sockErrBuf[64]; - if ( status ) { - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - } - else { - strcpy ( sockErrBuf, "server initiated disconnect" ); - } - fprintf ( stderr, "log client: lost contact with log server at \"%s\" because \"%s\"\n", - pClient->name, sockErrBuf ); - } - logClientClose ( pClient ); - break; - } - } - else { - memcpy ( & pClient->msgBuf[pClient->nextMsgIndex], - message, strSize ); - pClient->nextMsgIndex += strSize; - break; - } - } -} - - -/* - * logClientSend () - */ -void epicsShareAPI logClientSend ( logClientId id, const char * message ) -{ - logClient * pClient = ( logClient * ) id; - - if ( ! pClient || ! message ) { - return; - } - - epicsMutexMustLock ( pClient->mutex ); - - if (logClientPrefix) { - sendMessageChunk(pClient, logClientPrefix); - } - sendMessageChunk(pClient, message); - - epicsMutexUnlock (pClient->mutex); -} - - -void epicsShareAPI logClientFlush ( logClientId id ) -{ - logClient * pClient = ( logClient * ) id; - - if ( ! pClient ) { - return; - } - - epicsMutexMustLock ( pClient->mutex ); - - while ( pClient->nextMsgIndex && pClient->connected ) { - int status = send ( pClient->sock, pClient->msgBuf, - pClient->nextMsgIndex, 0 ); - if ( status > 0 ) { - unsigned nSent = (unsigned) status; - if ( nSent < pClient->nextMsgIndex ) { - unsigned newNextMsgIndex = pClient->nextMsgIndex - nSent; - memmove ( pClient->msgBuf, & pClient->msgBuf[nSent], - newNextMsgIndex ); - pClient->nextMsgIndex = newNextMsgIndex; - } - else { - pClient->nextMsgIndex = 0u; - } - } - else { - if ( ! pClient->shutdown ) { - char sockErrBuf[64]; - if ( status ) { - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - } - else { - strcpy ( sockErrBuf, "server initiated disconnect" ); - } - fprintf ( stderr, "log client: lost contact with log server at \"%s\" because \"%s\"\n", - pClient->name, sockErrBuf ); - } - logClientClose ( pClient ); - break; - } - } - epicsMutexUnlock ( pClient->mutex ); -} - -/* - * logClientMakeSock () - */ -static void logClientMakeSock (logClient *pClient) -{ - -# ifdef DEBUG - fprintf (stderr, "log client: creating socket..."); -# endif - - epicsMutexMustLock (pClient->mutex); - - /* - * allocate a socket - */ - pClient->sock = epicsSocketCreate ( AF_INET, SOCK_STREAM, 0 ); - if ( pClient->sock == INVALID_SOCKET ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf ( stderr, "log client: no socket error %s\n", - sockErrBuf ); - } - - epicsMutexUnlock (pClient->mutex); - -# ifdef DEBUG - fprintf (stderr, "done\n"); -# endif - -} - -/* - * logClientConnect() - */ -static void logClientConnect (logClient *pClient) -{ - osiSockIoctl_t optval; - int errnoCpy; - int status; - - if ( pClient->sock == INVALID_SOCKET ) { - logClientMakeSock ( pClient ); - if ( pClient->sock == INVALID_SOCKET ) { - return; - } - } - - while ( 1 ) { - status = connect (pClient->sock, - (struct sockaddr *)&pClient->addr, sizeof(pClient->addr)); - if ( status >= 0 ) { - break; - } - else { - errnoCpy = SOCKERRNO; - if ( errnoCpy == SOCK_EINTR ) { - continue; - } - else if ( - errnoCpy==SOCK_EINPROGRESS || - errnoCpy==SOCK_EWOULDBLOCK ) { - return; - } - else if ( errnoCpy==SOCK_EALREADY ) { - break; - } - else { - if ( pClient->connFailStatus != errnoCpy && ! pClient->shutdown ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf (stderr, - "log client: failed to connect to \"%s\" because %d=\"%s\"\n", - pClient->name, errnoCpy, sockErrBuf); - pClient->connFailStatus = errnoCpy; - } - logClientClose ( pClient ); - return; - } - } - } - - epicsMutexMustLock (pClient->mutex); - - pClient->connected = 1u; - pClient->connFailStatus = 0; - - /* - * discover that the connection has expired - * (after a long delay) - */ - optval = TRUE; - status = setsockopt (pClient->sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)); - if (status<0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf (stderr, "log client: unable to enable keepalive option because \"%s\"\n", sockErrBuf); - } - - /* - * we don't need full-duplex (clients only write), so we shutdown - * the read end of our socket - */ - status = shutdown (pClient->sock, SHUT_RD); - if (status < 0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf (stderr, "%s:%d shutdown(%d,SHUT_RD) error was \"%s\"\n", - __FILE__, __LINE__, pClient->sock, sockErrBuf); - /* not fatal (although it shouldn't happen) */ - } - - /* - * set how long we will wait for the TCP state machine - * to clean up when we issue a close(). This - * guarantees that messages are serialized when we - * switch connections. - */ - { - struct linger lingerval; - - lingerval.l_onoff = TRUE; - lingerval.l_linger = 60*5; - status = setsockopt (pClient->sock, SOL_SOCKET, SO_LINGER, (char *) &lingerval, sizeof(lingerval)); - if (status<0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf (stderr, "log client: unable to set linger options because \"%s\"\n", sockErrBuf); - } - } - - pClient->connectCount++; - - epicsMutexUnlock ( pClient->mutex ); - - epicsEventSignal ( pClient->stateChangeNotify ); - - fprintf ( stderr, "log client: connected to log server at \"%s\"\n", pClient->name ); -} - -/* - * logClientRestart () - */ -static void logClientRestart ( logClientId id ) -{ - logClient *pClient = (logClient *)id; - - /* SMP safe state inspection */ - epicsMutexMustLock ( pClient->mutex ); - while ( ! pClient->shutdown ) { - unsigned isConn; - - isConn = pClient->connected; - - epicsMutexUnlock ( pClient->mutex ); - - if ( isConn ) { - logClientFlush ( pClient ); - } - else { - logClientConnect ( pClient ); - } - - epicsThreadSleep ( LOG_RESTART_DELAY ); - - epicsMutexMustLock ( pClient->mutex ); - } - epicsMutexUnlock ( pClient->mutex ); - - pClient->shutdownConfirm = 1u; - epicsEventSignal ( pClient->stateChangeNotify ); -} - -/* - * logClientCreate() - */ -logClientId epicsShareAPI logClientCreate ( - struct in_addr server_addr, unsigned short server_port) -{ - epicsTimeStamp begin, current; - logClient *pClient; - double diff; - - pClient = calloc (1, sizeof (*pClient)); - if (pClient==NULL) { - return NULL; - } - - pClient->addr.sin_family = AF_INET; - pClient->addr.sin_addr = server_addr; - pClient->addr.sin_port = htons(server_port); - ipAddrToDottedIP (&pClient->addr, pClient->name, sizeof(pClient->name)); - - pClient->mutex = epicsMutexCreate (); - if ( ! pClient->mutex ) { - free ( pClient ); - return NULL; - } - - pClient->sock = INVALID_SOCKET; - pClient->connected = 0u; - pClient->connFailStatus = 0; - pClient->shutdown = 0; - pClient->shutdownConfirm = 0; - - epicsAtExit (logClientDestroy, (void*) pClient); - - pClient->stateChangeNotify = epicsEventCreate (epicsEventEmpty); - if ( ! pClient->stateChangeNotify ) { - epicsMutexDestroy ( pClient->mutex ); - free ( pClient ); - return NULL; - } - - pClient->restartThreadId = epicsThreadCreate ( - "logRestart", epicsThreadPriorityLow, - epicsThreadGetStackSize(epicsThreadStackSmall), - logClientRestart, pClient ); - if ( pClient->restartThreadId == NULL ) { - epicsMutexDestroy ( pClient->mutex ); - epicsEventDestroy ( pClient->stateChangeNotify ); - free (pClient); - fprintf(stderr, "log client: unable to start log client connection watch dog thread\n"); - return NULL; - } - - /* - * attempt to synchronize with circuit connect - */ - epicsTimeGetCurrent ( & begin ); - epicsMutexMustLock ( pClient->mutex ); - do { - epicsMutexUnlock ( pClient->mutex ); - epicsEventWaitWithTimeout ( - pClient->stateChangeNotify, - LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT / 10.0 ); - epicsTimeGetCurrent ( & current ); - diff = epicsTimeDiffInSeconds ( & current, & begin ); - epicsMutexMustLock ( pClient->mutex ); - } - while ( ! pClient->connected && diff < LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT ); - epicsMutexUnlock ( pClient->mutex ); - - if ( ! pClient->connected ) { - fprintf (stderr, "log client create: timed out synchronizing with circuit connect to \"%s\" after %.1f seconds\n", - pClient->name, LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT ); - } - - errlogAddListener ( logClientSendMessage, (void *) pClient ); - - return (void *) pClient; -} - -/* - * logClientShow () - */ -void epicsShareAPI logClientShow (logClientId id, unsigned level) -{ - logClient *pClient = (logClient *) id; - - if ( pClient->connected ) { - printf ("log client: connected to log server at \"%s\"\n", pClient->name); - } - else { - printf ("log client: disconnected from log server at \"%s\"\n", pClient->name); - } - - if (level>1) { - printf ("log client: sock=%s, connect cycles = %u\n", - pClient->sock==INVALID_SOCKET?"INVALID":"OK", - pClient->connectCount); - } - - if (logClientPrefix) { - printf ("log client: prefix is \"%s\"\n", logClientPrefix); - } -} - -/* - * logClientSendMessage (); deprecated - */ -void logClientSendMessage ( logClientId id, const char * message ) -{ - if ( !iocLogDisable ) { - logClientSend (id, message); - } -} - -/* - * iocLogPrefix() - */ -void epicsShareAPI iocLogPrefix(const char * prefix) -{ - - /* If we have already established a log prefix, don't let the user change - * it. The iocLogPrefix command is expected to be run from the IOC startup - * script during initialization; the prefix can't be changed once it has - * been set. - */ - - if (logClientPrefix) { - printf ("iocLogPrefix: The prefix was already set to \"%s\" " - "and can't be changed.\n", logClientPrefix); - return; - } - - if (prefix) { - unsigned prefixLen = strlen(prefix); - if (prefixLen > 0) { - char * localCopy = malloc(prefixLen+1); - strcpy(localCopy, prefix); - logClientPrefix = localCopy; - } - } -} diff --git a/src/libCom/log/logClient.h b/src/libCom/log/logClient.h deleted file mode 100644 index 1797bbb20..000000000 --- a/src/libCom/log/logClient.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* logClient.h,v 1.5.2.1 2003/07/08 00:08:06 jhill Exp */ -/* - * - * Author: Jeffrey O. Hill - * Date: 080791 - */ - -#ifndef INClogClienth -#define INClogClienth 1 -#include "shareLib.h" -#include "osiSock.h" /* for 'struct in_addr' */ - -/* include default log client interface for backward compatibility */ -#include "iocLog.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *logClientId; -epicsShareFunc logClientId epicsShareAPI logClientCreate ( - struct in_addr server_addr, unsigned short server_port); -epicsShareFunc void epicsShareAPI logClientSend (logClientId id, const char *message); -epicsShareFunc void epicsShareAPI logClientShow (logClientId id, unsigned level); -epicsShareFunc void epicsShareAPI logClientFlush (logClientId id); -epicsShareFunc void epicsShareAPI iocLogPrefix(const char* prefix); - -/* deprecated interface; retained for backward compatibility */ -/* note: implementations are in iocLog.c, not logClient.c */ -epicsShareFunc logClientId epicsShareAPI logClientInit (void); -epicsShareFunc void logClientSendMessage (logClientId id, const char *message); - -#ifdef __cplusplus -} -#endif - -#endif /*INClogClienth*/ diff --git a/src/libCom/macLib/Makefile b/src/libCom/macLib/Makefile deleted file mode 100644 index c0be82af8..000000000 --- a/src/libCom/macLib/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/macLib -INC += macLib.h -Com_SRCS += macCore.c -Com_SRCS += macEnv.c -Com_SRCS += macUtil.c diff --git a/src/libCom/macLib/macCore.c b/src/libCom/macLib/macCore.c deleted file mode 100644 index 55d31719e..000000000 --- a/src/libCom/macLib/macCore.c +++ /dev/null @@ -1,950 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Implementation of core macro substitution library (macLib) - * - * The implementation is fairly unsophisticated and linked lists are - * used to store macro values. Typically there will will be only a - * small number of macros and performance won't be a problem. Special - * measures are taken to avoid unnecessary expansion of macros whose - * definitions reference other macros. Whenever a macro is created, - * modified or deleted, a "dirty" flag is set; this causes a full - * expansion of all macros the next time a macro value is read - * - * Original Author: William Lupton, W. M. Keck Observatory - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "errlog.h" -#include "dbmf.h" -#include "macLib.h" - - -/*** Local structure definitions ***/ - -/* - * Entry in linked list of macro definitions - */ -typedef struct mac_entry { - ELLNODE node; /* prev and next pointers */ - char *name; /* entry name */ - char *type; /* entry type */ - char *rawval; /* raw (unexpanded) value */ - char *value; /* expanded macro value */ - size_t length; /* length of value */ - int error; /* error expanding value? */ - int visited; /* ever been visited? */ - int special; /* special (internal) entry? */ - int level; /* scoping level */ -} MAC_ENTRY; - - -/*** Local function prototypes ***/ - -/* - * These static functions peform low-level operations on macro entries - */ -static MAC_ENTRY *first ( MAC_HANDLE *handle ); -static MAC_ENTRY *last ( MAC_HANDLE *handle ); -static MAC_ENTRY *next ( MAC_ENTRY *entry ); -static MAC_ENTRY *previous( MAC_ENTRY *entry ); - -static MAC_ENTRY *create( MAC_HANDLE *handle, const char *name, int special ); -static MAC_ENTRY *lookup( MAC_HANDLE *handle, const char *name, int special ); -static char *rawval( MAC_HANDLE *handle, MAC_ENTRY *entry, const char *value ); -static void delete( MAC_HANDLE *handle, MAC_ENTRY *entry ); -static long expand( MAC_HANDLE *handle ); -static void trans ( MAC_HANDLE *handle, MAC_ENTRY *entry, int level, - const char *term, const char **rawval, char **value, - char *valend ); -static void refer ( MAC_HANDLE *handle, MAC_ENTRY *entry, int level, - const char **rawval, char **value, char *valend ); - -static void cpy2val( const char *src, char **value, char *valend ); -static char *Strdup( const char *string ); - - -/*** Constants ***/ - -/* - * Magic number for validating context. - */ -#define MAC_MAGIC 0xbadcafe /* ...sells sub-standard coffee? */ - -/* - * Flag bits - */ -#define FLAG_SUPPRESS_WARNINGS 0x1 -#define FLAG_USE_ENVIRONMENT 0x80 - - -/*** Library routines ***/ - -/* - * Create a new macro substitution context and return an opaque handle - * associated with the new context. Also optionally load an initial set - * of macro definitions - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macCreateHandle( - MAC_HANDLE **pHandle, /* address of variable to receive pointer */ - /* to new macro substitution context */ - - const char * pairs[] ) /* pointer to NULL-terminated array of */ - /* {name,value} pair strings; a NULL */ - /* value implies undefined; a NULL */ - /* argument implies no macros */ -{ - MAC_HANDLE *handle; /* pointer to macro substitution context */ - - /* ensure NULL handle pointer is returned on error */ - *pHandle = NULL; - - /* allocate macro substitution context */ - handle = ( MAC_HANDLE * ) dbmfMalloc( sizeof( MAC_HANDLE ) ); - if ( handle == NULL ) { - errlogPrintf( "macCreateHandle: failed to allocate context\n" ); - return -1; - } - - /* initialize context */ - handle->magic = MAC_MAGIC; - handle->dirty = FALSE; - handle->level = 0; - handle->debug = 0; - handle->flags = 0; - ellInit( &handle->list ); - - /* use environment variables if so specified */ - if (pairs && pairs[0] && !strcmp(pairs[0],"") && pairs[1] && !strcmp(pairs[1],"environ") && !pairs[3]) { - handle->flags |= FLAG_USE_ENVIRONMENT; - } - else { - /* if supplied, load macro definitions */ - for ( ; pairs && pairs[0]; pairs += 2 ) { - if ( macPutValue( handle, pairs[0], pairs[1] ) < 0 ) { - dbmfFree( handle ); - return -1; - } - } - } - - /* set returned handle pointer */ - *pHandle = handle; - - return 0; -} - -/* - * Turn on/off suppression of printed warnings from macLib calls - * for the given handle - */ -void -epicsShareAPI macSuppressWarning( - MAC_HANDLE *handle, /* opaque handle */ - int suppress /* 0 means issue, 1 means suppress */ -) -{ - if ( handle && handle->magic == MAC_MAGIC ) { - handle->flags = (handle->flags & ~FLAG_SUPPRESS_WARNINGS) | - (suppress ? FLAG_SUPPRESS_WARNINGS : 0); - } -} - -/* - * Expand a string that may contain macro references and return the - * expanded string - * - * This is a very basic and powerful routine. It's basically a wrapper - * around the the translation "engine" trans() - */ -long /* strlen(dest), <0 if any macros are */ - /* undefined */ -epicsShareAPI macExpandString( - MAC_HANDLE *handle, /* opaque handle */ - - const char *src, /* source string */ - - char *dest, /* destination string */ - - long capacity ) /* capacity of destination buffer (dest) */ -{ - MAC_ENTRY entry; - const char *s; - char *d; - long length; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macExpandString: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macExpandString( %s, capacity = %ld )\n", src, capacity ); - - /* Check size */ - if (capacity <= 1) - return -1; - - /* expand raw values if necessary */ - if ( expand( handle ) < 0 ) - errlogPrintf( "macExpandString: failed to expand raw values\n" ); - - /* fill in necessary fields in fake macro entry structure */ - entry.name = (char *) src; - entry.type = "string"; - entry.error = FALSE; - - /* expand the string */ - s = src; - d = dest; - *d = '\0'; - trans( handle, &entry, 0, "", &s, &d, d + capacity - 1 ); - - /* return +/- #chars copied depending on successful expansion */ - length = d - dest; - length = ( entry.error ) ? -length : length; - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macExpandString() -> %ld\n", length ); - - return length; -} - -/* - * Define the value of a macro. A NULL value deletes the macro if it - * already existed - */ -long /* strlen(value) */ -epicsShareAPI macPutValue( - MAC_HANDLE *handle, /* opaque handle */ - - const char *name, /* macro name */ - - const char *value ) /* macro value */ -{ - MAC_ENTRY *entry; /* pointer to this macro's entry structure */ - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macPutValue: NULL or invalid handle\n" ); - return -1; - } - - if ( handle->debug & 1 ) - printf( "macPutValue( %s, %s )\n", name, value ? value : "NULL" ); - - /* handle NULL value case: if name was found, delete entry (may be - several entries at different scoping levels) */ - if ( value == NULL ) { - /* - * FIXME: shouldn't be able to delete entries from lower scopes - * NOTE: when this is changed, this functionality of removing - * a macro from all scopes will still be needed by iocshEnvClear - */ - while ( ( entry = lookup( handle, name, FALSE ) ) != NULL ) { - int done = strcmp(entry->type, "environment variable") == 0; - delete( handle, entry ); - - if (done) - break; - } - - return 0; - } - - /* look up macro name */ - entry = lookup( handle, name, FALSE ); - - /* new entry must be created if macro doesn't exist or if it only - exists at a lower scoping level */ - if ( entry == NULL || entry->level < handle->level ) { - entry = create( handle, name, FALSE ); - if ( entry == NULL ) { - errlogPrintf( "macPutValue: failed to create macro %s = %s\n", - name, value ); - return -1; - } else { - entry->type = "macro"; - } - } - - /* copy raw value */ - if ( rawval( handle, entry, value ) == NULL ) { - errlogPrintf( "macPutValue: failed to copy macro %s = %s\n", - name, value ) ; - return -1; - } - - /* return length of value */ - return strlen( value ); -} - -/* - * Return the value of a macro - */ -long /* strlen(value), <0 if undefined */ -epicsShareAPI macGetValue( - MAC_HANDLE *handle, /* opaque handle */ - - const char *name, /* macro name or reference */ - - char *value, /* string to receive macro value or name */ - /* argument if macro is undefined */ - - long capacity ) /* capacity of destination buffer (value) */ -{ - MAC_ENTRY *entry; /* pointer to this macro's entry structure */ - long length; /* number of characters returned */ - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macGetValue: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macGetValue( %s )\n", name ); - - /* look up macro name */ - entry = lookup( handle, name, FALSE ); - - /* if capacity <= 1 or VALUE == NULL just return -1 / 0 for undefined / - defined macro */ - if ( capacity <= 1 || value == NULL ) { - return ( entry == NULL ) ? -1 : 0; - } - - /* if not found, copy name to value and return minus #chars copied */ - if ( entry == NULL ) { - strncpy( value, name, capacity ); - return ( value[capacity-1] == '\0' ) ? - (long) strlen( name ) : -capacity; - } - - /* expand raw values if necessary; if fail (can only fail because of - memory allocation failure), return same as if not found */ - if ( expand( handle ) < 0 ) { - errlogPrintf( "macGetValue: failed to expand raw values\n" ); - strncpy( value, name, capacity ); - return ( value[capacity-1] == '\0' ) ? - (long) strlen( name ) : -capacity; - } - - /* copy value and return +/- #chars copied depending on successful - expansion */ - strncpy( value, entry->value, capacity ); - length = ( value[capacity-1] == '\0' ) ? entry->length : capacity; - - return ( entry->error ) ? -length : length; -} - -/* - * Free up all storage associated with and delete a macro substitution - * context - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macDeleteHandle( - MAC_HANDLE *handle ) /* opaque handle */ -{ - MAC_ENTRY *entry, *nextEntry; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macDeleteHandle: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macDeleteHandle()\n" ); - - /* delete all entries */ - for ( entry = first( handle ); entry != NULL; entry = nextEntry ) { - nextEntry = next( entry ); - delete( handle, entry ); - } - - /* clear magic field and free context structure */ - handle->magic = 0; - dbmfFree( handle ); - - return 0; -} - -/* - * Mark the start of a new scoping level - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macPushScope( - MAC_HANDLE *handle ) /* opaque handle */ -{ - MAC_ENTRY *entry; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macPushScope: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macPushScope()\n" ); - - /* increment scoping level */ - handle->level++; - - /* create new "special" entry of name "" */ - entry = create( handle, "", TRUE ); - if ( entry == NULL ) { - handle->level--; - errlogPrintf( "macPushScope: failed to push scope\n" ); - return -1; - } else { - entry->type = "scope marker"; - } - - return 0; -} - -/* - * Pop all macros defined since the last call to macPushScope() - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macPopScope( - MAC_HANDLE *handle ) /* opaque handle */ -{ - MAC_ENTRY *entry, *nextEntry; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macPopScope: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macPopScope()\n" ); - - /* check scoping level isn't already zero */ - if ( handle->level == 0 ) { - errlogPrintf( "macPopScope: no scope to pop\n" ); - return -1; - } - - /* look up most recent scope entry */ - entry = lookup( handle, "", TRUE ); - if ( entry == NULL ) { - errlogPrintf( "macPopScope: no scope to pop\n" ); - return -1; - } - - /* delete scope entry and all macros defined since it */ - for ( ; entry != NULL; entry = nextEntry ) { - nextEntry = next( entry ); - delete( handle, entry ); - } - - /* decrement scoping level */ - handle->level--; - - return 0; -} - -/* - * Report macro details to standard output - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macReportMacros( - MAC_HANDLE *handle ) /* opaque handle */ -{ - const char *format = "%-1s %-16s %-16s %s\n"; - MAC_ENTRY *entry; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macReportMacros: NULL or invalid handle\n" ); - return -1; - } - - /* expand raw values if necessary; report but ignore failure */ - if ( expand( handle ) < 0 ) - errlogPrintf( "macGetValue: failed to expand raw values\n" ); - - /* loop through macros, reporting names and values */ - printf( format, "e", "name", "rawval", "value" ); - printf( format, "-", "----", "------", "-----" ); - for ( entry = first( handle ); entry != NULL; entry = next( entry ) ) { - - /* differentiate between "special" (scope marker) and ordinary - entries */ - if ( entry->special ) - printf( format, "s", "----", "------", "-----" ); - else - printf( format, entry->error ? "*" : " ", entry->name, - entry->rawval ? entry->rawval : "", - entry->value ? entry->value : ""); - } - - return 0; -} - -/******************** beginning of static functions ********************/ - -/* - * Return pointer to first macro entry (could be preprocessor macro) - */ -static MAC_ENTRY *first( MAC_HANDLE *handle ) -{ - return ( MAC_ENTRY * ) ellFirst( &handle->list ); -} - -/* - * Return pointer to last macro entry (could be preprocessor macro) - */ -static MAC_ENTRY *last( MAC_HANDLE *handle ) -{ - return ( MAC_ENTRY * ) ellLast( &handle->list ); -} - -/* - * Return pointer to next macro entry (could be preprocessor macro) - */ -static MAC_ENTRY *next( MAC_ENTRY *entry ) -{ - return ( MAC_ENTRY * ) ellNext( ( ELLNODE * ) entry ); -} - -/* - * Return pointer to previous macro entry (could be preprocessor macro) - */ -static MAC_ENTRY *previous( MAC_ENTRY *entry ) -{ - return ( MAC_ENTRY * ) ellPrevious( ( ELLNODE * ) entry ); -} - -/* - * Create new macro entry (can assume it doesn't exist) - */ -static MAC_ENTRY *create( MAC_HANDLE *handle, const char *name, int special ) -{ - ELLLIST *list = &handle->list; - MAC_ENTRY *entry = ( MAC_ENTRY * ) dbmfMalloc( sizeof( MAC_ENTRY ) ); - - if ( entry != NULL ) { - entry->name = Strdup( name ); - if ( entry->name == NULL ) { - dbmfFree( entry ); - entry = NULL; - } - else { - entry->type = ""; - entry->rawval = NULL; - entry->value = NULL; - entry->length = 0; - entry->error = FALSE; - entry->visited = FALSE; - entry->special = special; - entry->level = handle->level; - - ellAdd( list, ( ELLNODE * ) entry ); - } - } - - return entry; -} - -/* - * Look up macro entry with matching "special" attribute by name - */ -static MAC_ENTRY *lookup( MAC_HANDLE *handle, const char *name, int special ) -{ - MAC_ENTRY *entry; - - if ( handle->debug & 2 ) - printf( "lookup-> level = %d, name = %s, special = %d\n", - handle->level, name, special ); - - /* search backwards so scoping works */ - for ( entry = last( handle ); entry != NULL; entry = previous( entry ) ) { - if ( entry->special != special ) - continue; - if ( strcmp( name, entry->name ) == 0 ) - break; - } - if ( (special == FALSE) && (entry == NULL) && - (handle->flags & FLAG_USE_ENVIRONMENT) ) { - char *value = getenv(name); - if (value) { - entry = create( handle, name, FALSE ); - if ( entry ) { - entry->type = "environment variable"; - if ( rawval( handle, entry, value ) == NULL ) - entry = NULL; - } - } - } - - if ( handle->debug & 2 ) - printf( "<-lookup level = %d, name = %s, result = %p\n", - handle->level, name, entry ); - - return entry; -} - -/* - * Copy raw value to macro entry - */ -static char *rawval( MAC_HANDLE *handle, MAC_ENTRY *entry, const char *value ) -{ - if ( entry->rawval != NULL ) - dbmfFree( entry->rawval ); - entry->rawval = Strdup( value ); - - handle->dirty = TRUE; - - return entry->rawval; -} - -/* - * Delete a macro entry; requires re-expansion of macro values since this - * macro may be referenced by another one - */ -static void delete( MAC_HANDLE *handle, MAC_ENTRY *entry ) -{ - ELLLIST *list = &handle->list; - - ellDelete( list, ( ELLNODE * ) entry ); - - dbmfFree( entry->name ); - if ( entry->rawval != NULL ) - dbmfFree( entry->rawval ); - if ( entry->value != NULL ) - free( entry->value ); - dbmfFree( entry ); - - handle->dirty = TRUE; -} - -/* - * Expand macro definitions (expensive but done very infrequently) - */ -static long expand( MAC_HANDLE *handle ) -{ - MAC_ENTRY *entry; - const char *rawval; - char *value; - - if ( !handle->dirty ) - return 0; - - for ( entry = first( handle ); entry != NULL; entry = next( entry ) ) { - - if ( handle->debug & 2 ) - printf( "\nexpand %s = %s\n", entry->name, - entry->rawval ? entry->rawval : "" ); - - if ( entry->value == NULL ) { - if ( ( entry->value = malloc( MAC_SIZE + 1 ) ) == NULL ) { - return -1; - } - } - - /* start at level 1 so quotes and escapes will be removed from - expanded value */ - rawval = entry->rawval; - value = entry->value; - *value = '\0'; - entry->error = FALSE; - trans( handle, entry, 1, "", &rawval, &value, entry->value + MAC_SIZE ); - entry->length = value - entry->value; - entry->value[MAC_SIZE] = '\0'; - } - - handle->dirty = FALSE; - - return 0; -} - -/* - * Translate raw macro value (recursive). This is by far the most complicated - * of the macro routines and calls itself recursively both to translate any - * macros referenced in the name and to translate the resulting name - */ -static void trans( MAC_HANDLE *handle, MAC_ENTRY *entry, int level, - const char *term, const char **rawval, char **value, - char *valend ) -{ - char quote; - const char *r; - char *v; - int discard; - int macRef; - - /* return immediately if raw value is NULL */ - if ( *rawval == NULL ) return; - - /* discard quotes and escapes if level is > 0 (i.e. if these aren't - the user's quotes and escapes) */ - discard = ( level > 0 ); - - /* debug output */ - if ( handle->debug & 2 ) - printf( "trans-> entry = %p, level = %d, capacity = %u, discard = %s, " - "rawval = %s\n", entry, level, (unsigned int)(valend - *value), discard ? "T" : "F", *rawval ); - - /* initially not in quotes */ - quote = 0; - - /* scan characters until hit terminator or end of string */ - for ( r = *rawval, v = *value; strchr( term, *r ) == NULL; r++ ) { - - /* handle quoted characters (quotes are discarded if in name) */ - if ( quote ) { - if ( *r == quote ) { - quote = 0; - if ( discard ) continue; - } - } - else if ( *r == '"' || *r == '\'' ) { - quote = *r; - if ( discard ) continue; - } - - /* macro reference if '$' followed by '(' or '{' */ - macRef = ( *r == '$' && - *( r + 1 ) != '\0' && - strchr( "({", *( r + 1 ) ) != NULL ); - - /* macros are not expanded in single quotes */ - if ( macRef && quote != '\'' ) { - /* Handle macro reference */ - refer ( handle, entry, level, &r, &v, valend ); - } - - else { - /* handle escaped characters (escape is discarded if in name) */ - if ( *r == '\\' && *( r + 1 ) != '\0' ) { - if ( v < valend && !discard ) *v++ = '\\'; - if ( v < valend ) *v++ = *++r; - } - - /* copy character to output */ - else { - if ( v < valend ) *v++ = *r; - } - - /* ensure string remains properly terminated */ - if ( v <= valend ) *v = '\0'; - } - } - - /* debug output */ - if ( handle->debug & 2 ) - printf( "<-trans level = %d, length = %4u, value = %s\n", - level, (unsigned int)(v - *value), *value ); - - /* update pointers to next characters to scan in raw value and to fill - in in output value (if at end of input, step back so terminator is - still there to be seen) */ - *rawval = ( *r == '\0' ) ? r - 1 : r; - *value = v; - - return; -} - -/* - * Expand a macro reference, handling default values and defining scoped - * macros as encountered. This code used to part of trans(), but was - * pulled out for ease of understanding. - */ -static void refer ( MAC_HANDLE *handle, MAC_ENTRY *entry, int level, - const char **rawval, char **value, char *valend ) -{ - const char *r = *rawval; - char *v = *value; - char refname[MAC_SIZE + 1] = {'\0'}; - char *rn = refname; - MAC_ENTRY *refentry; - const char *defval = NULL; - const char *macEnd; - const char *errval = NULL; - int pop = FALSE; - - /* debug output */ - if ( handle->debug & 2 ) - printf( "refer-> entry = %p, level = %d, capacity = %u, rawval = %s\n", - entry, level, (unsigned int)(valend - *value), *rawval ); - - /* step over '$(' or '${' */ - r++; - macEnd = ( *r == '(' ) ? "=,)" : "=,}"; - r++; - - /* translate name (may contain macro references); truncated - quietly if too long but always guaranteed zero-terminated */ - trans( handle, entry, level + 1, macEnd, &r, &rn, rn + MAC_SIZE ); - refname[MAC_SIZE] = '\0'; - - /* Is there a default value? */ - if ( *r == '=' ) { - MAC_ENTRY dflt; - int flags = handle->flags; - handle->flags |= FLAG_SUPPRESS_WARNINGS; - - /* store its location in case we need it */ - defval = ++r; - - /* Find the end, discarding its value */ - dflt.name = refname; - dflt.type = "default value"; - dflt.error = FALSE; - trans( handle, &dflt, level + 1, macEnd+1, &r, &v, v); - - handle->flags = flags; - } - - /* extract and set values for any scoped macros */ - if ( *r == ',' ) { - MAC_ENTRY subs; - int flags = handle->flags; - handle->flags |= FLAG_SUPPRESS_WARNINGS; - - subs.type = "scoped macro"; - subs.error = FALSE; - - macPushScope( handle ); - pop = TRUE; - - while ( *r == ',' ) { - char subname[MAC_SIZE + 1] = {'\0'}; - char subval[MAC_SIZE + 1] = {'\0'}; - char *sn = subname; - char *sv = subval; - - /* translate the macro name */ - ++r; - subs.name = refname; - - trans( handle, &subs, level + 1, macEnd, &r, &sn, sn + MAC_SIZE ); - subname[MAC_SIZE] = '\0'; - - /* If it has a value, translate that and assign it */ - if ( *r == '=' ) { - ++r; - subs.name = subname; - - trans( handle, &subs, level + 1, macEnd+1, &r, &sv, - sv + MAC_SIZE); - subval[MAC_SIZE] = '\0'; - - macPutValue( handle, subname, subval ); - handle->dirty = TRUE; /* re-expand with new macro values */ - } - } - - handle->flags = flags; - } - - /* Now we can look up the translated name */ - refentry = lookup( handle, refname, FALSE ); - - if ( refentry ) { - if ( !refentry->visited ) { - /* reference is good, use it */ - if ( !handle->dirty ) { - /* copy the already-expanded value, merge any error status */ - cpy2val( refentry->value, &v, valend ); - entry->error = entry->error || refentry->error; - } else { - /* translate raw value */ - const char *rv = refentry->rawval; - refentry->visited = TRUE; - trans( handle, entry, level + 1, "", &rv, &v, valend ); - refentry->visited = FALSE; - } - goto cleanup; - } - /* reference is recursive */ - entry->error = TRUE; - errval = ",recursive)"; - if ( (handle->flags & FLAG_SUPPRESS_WARNINGS) == 0 ) { - errlogPrintf( "macLib: %s %s is recursive (expanding %s %s)\n", - entry->type, entry->name, - refentry->type, refentry->name ); - } - } else { - /* no macro found by this name */ - if ( defval ) { - /* there was a default value, translate that instead */ - trans( handle, entry, level + 1, macEnd+1, &defval, &v, valend ); - goto cleanup; - } - entry->error = TRUE; - errval = ",undefined)"; - if ( (handle->flags & FLAG_SUPPRESS_WARNINGS) == 0 ) { - errlogPrintf( "macLib: macro %s is undefined (expanding %s %s)\n", - refname, entry->type, entry->name ); - } - } - - /* Bad reference, insert $(name,errval) */ - if ( v < valend ) *v++ = '$'; - if ( v < valend ) *v++ = '('; - cpy2val( refname, &v, valend ); - cpy2val( errval, &v, valend ); - -cleanup: - if (pop) { - macPopScope( handle ); - } - - /* debug output */ - if ( handle->debug & 2 ) - printf( "<-refer level = %d, length = %4u, value = %s\n", - level, (unsigned int)(v - *value), *value ); - - *rawval = r; - *value = v; - return; -} - -/* - * Copy a string, honoring the 'end of destination string' pointer - * Returns with **value pointing to the '\0' terminator - */ -static void cpy2val(const char *src, char **value, char *valend) -{ - char *v = *value; - while ((v < valend) && (*v = *src++)) { v++; } - *v = '\0'; - *value = v; -} - -/* - * strdup() implementation which uses our own memory allocator - */ -static char *Strdup(const char *string ) -{ - char *copy = dbmfMalloc( strlen( string ) + 1 ); - - if ( copy != NULL ) - strcpy( copy, string ); - - return copy; -} - diff --git a/src/libCom/macLib/macEnv.c b/src/libCom/macLib/macEnv.c deleted file mode 100644 index f102748a8..000000000 --- a/src/libCom/macLib/macEnv.c +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Macro expansion of environment variables - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "errlog.h" -#include "epicsString.h" -#include "macLib.h" - -char * epicsShareAPI -macEnvExpand(const char *str) -{ - return macDefExpand(str, NULL); -} - -char * epicsShareAPI -macDefExpand(const char *str, MAC_HANDLE *macros) -{ - MAC_HANDLE *handle; - static const char * pairs[] = { "", "environ", NULL, NULL }; - long destCapacity = 128; - char *dest = NULL; - int n; - - if (macros) { - handle = macros; - } else { - if (macCreateHandle(&handle, pairs)){ - errlogMessage("macDefExpand: macCreateHandle failed."); - return NULL; - } - } - - do { - destCapacity *= 2; - /* - * Use free/malloc rather than realloc since there's no need to - * keep the original contents. - */ - free(dest); - dest = malloc(destCapacity); - if(!dest) - goto done; - - n = macExpandString(handle, str, dest, destCapacity); - } while (n >= (destCapacity - 1)); - - if (n < 0) { - free(dest); - dest = NULL; - } else { - size_t unused = destCapacity - ++n; - - if (unused >= 20) - dest = realloc(dest, n); - } - -done: - if (macros == NULL) { - if (macDeleteHandle(handle)) { - errlogMessage("macDefExpand: macDeleteHandle failed."); - } - } - return dest; -} diff --git a/src/libCom/macLib/macLib.h b/src/libCom/macLib/macLib.h deleted file mode 100644 index 14ecdaa3f..000000000 --- a/src/libCom/macLib/macLib.h +++ /dev/null @@ -1,164 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Definitions for macro substitution library (macLib) - * - * William Lupton, W. M. Keck Observatory - */ - -#ifndef INCmacLibH -#define INCmacLibH - -/* - * EPICS include files needed by this file - */ -#include "ellLib.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Maximum size of macro name or value string (simpler to make fixed) - */ -#define MAC_SIZE 256 - -/* - * Macro substitution context. One of these contexts is allocated each time - * macCreateHandle() is called - */ -typedef struct { - long magic; /* magic number (used for authentication) */ - int dirty; /* values need expanding from raw values? */ - int level; /* scoping level */ - int debug; /* debugging level */ - ELLLIST list; /* macro name / value list */ - int flags; /* operating mode flags */ -} MAC_HANDLE; - -/* - * Function prototypes (core library) - */ -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macCreateHandle( - MAC_HANDLE **handle, /* address of variable to receive pointer */ - /* to new macro substitution context */ - - const char * pairs[] /* pointer to NULL-terminated array of */ - /* {name,value} pair strings; a NULL */ - /* value implies undefined; a NULL */ - /* argument implies no macros */ -); - -epicsShareFunc void -epicsShareAPI macSuppressWarning( - MAC_HANDLE *handle, /* opaque handle */ - - int falseTrue /*0 means issue, 1 means suppress*/ -); - -epicsShareFunc long /* strlen(dest), <0 if any macros are */ - /* undefined */ -epicsShareAPI macExpandString( - MAC_HANDLE *handle, /* opaque handle */ - - const char *src, /* source string */ - - char *dest, /* destination string */ - - long capacity /* capacity of destination buffer (dest) */ -); - - -epicsShareFunc long /* strlen(value) */ -epicsShareAPI macPutValue( - MAC_HANDLE *handle, /* opaque handle */ - - const char *name, /* macro name */ - - const char *value /* macro value */ -); - -epicsShareFunc long /* strlen(value), <0 if undefined */ -epicsShareAPI macGetValue( - MAC_HANDLE *handle, /* opaque handle */ - - const char *name, /* macro name or reference */ - - char *value, /* string to receive macro value or name */ - /* argument if macro is undefined */ - - long capacity /* capacity of destination buffer (value) */ -); - -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macDeleteHandle( - MAC_HANDLE *handle /* opaque handle */ -); - -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macPushScope( - MAC_HANDLE *handle /* opaque handle */ -); - -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macPopScope( - MAC_HANDLE *handle /* opaque handle */ -); - -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macReportMacros( - MAC_HANDLE *handle /* opaque handle */ -); - -/* - * Function prototypes (utility library) - */ -epicsShareFunc long /* #defns encountered; <0 = ERROR */ -epicsShareAPI macParseDefns( - MAC_HANDLE *handle, /* opaque handle; can be NULL if default */ - /* special characters are to be used */ - - const char *defns, /* macro definitions in "a=xxx,b=yyy" */ - /* format */ - - char **pairs[] /* address of variable to receive pointer */ - /* to NULL-terminated array of {name, */ - /* value} pair strings; all storage is */ - /* allocated contiguously */ -); - -epicsShareFunc long /* #macros defined; <0 = ERROR */ -epicsShareAPI macInstallMacros( - MAC_HANDLE *handle, /* opaque handle */ - - char *pairs[] /* pointer to NULL-terminated array of */ - /* {name,value} pair strings; a NULL */ - /* value implies undefined; a NULL */ - /* argument implies no macros */ -); - -epicsShareFunc char * /* expanded string; NULL if any undefined macros */ -epicsShareAPI macEnvExpand( - const char *str /* string to be expanded */ -); - -epicsShareFunc char * /* expanded string; NULL if any undefined macros */ -epicsShareAPI macDefExpand( - const char *str, /* string to be expanded */ - MAC_HANDLE *macros /* opaque handle; can be NULL if default */ - /* special characters are to be used */ -); - -#ifdef __cplusplus -} -#endif - -#endif /*INCmacLibH*/ diff --git a/src/libCom/macLib/macLibNOTES b/src/libCom/macLib/macLibNOTES deleted file mode 100644 index fc3606254..000000000 --- a/src/libCom/macLib/macLibNOTES +++ /dev/null @@ -1,158 +0,0 @@ -# Test input file for macTest filter, doubling as notes on usage of the -# macro library. Some special strings at start of line are supported: -# -# 1. '#' indicates a comment and is ignored -# -# 2. '%set' is followed by "a=b, c=d" style macro definitions which are -# passed through macParseDefs() and macInstallMacros() -# -# 3. '%push' pushes a scoping level by calling macPushScope() -# -# 4. '%pop' pops a scoping level by calling macPopScope() -# -# 5. '%report' reports macro definitions by calling macReportMacros() -# -# 6. all other lines are expanded by callins macExpandString() -# -introduction ------------- - -See the README file for the library specification and see the header -comments of macCore.c (the core library) for notes on what has been -implemented. - -This file contains tutorial information and examples. It's the -best documentation that there is. - - -simple examples ---------------- - -To define the a, b, c and d macros to be 1, 2, 3 and 4 (note optional -white space is ignored around '=' and ',' characters): - -%set a=1, b=2, c = 3 , d = 4 - -These macros can be dereferenced using '$(xxx)' or '${xxx}' notation: -a = $(a), b = $(b), c = ${c}, d = ${d}. - -Macro values can reference other macros in an arbitrarily complex way. -The only current restrictions are that a macro name or value cannot -exceed 256 characters in length. This restriction could fairly easily -be lifted. - -Here's an example: - -%set x = ${$(y$(z))} - -If this is expanded now: $(x), it won't work because the other macros -aren't defined yet. So: - -%set cash=lucre, ywork=cash, z=work - -Now expansion yields "$(x)" (work -> ywork -> cash -> lucre). - -One can inadvertently set up circular references. For example: - -%set mac1=$(mac2), mac2=$(mac3), mac3=$(mac1) - -An attempt to dereference mac1 gives $(mac1). When a macro expansion -fails, the translation that failed is replaced with the text that could -not be expanded. - -You can get a report of current macro definitions by doing -%report - -The '*' character in the first column indicates a problem expanding that -macro. We'll get rid of these problem macros: -%set mac1, mac2, mac3 - -You can also push a new scoping level by doing -%push - -and pop back to it by doing -%pop - -For example: -%set level = 0 -%push -%set level = 1 -%push -%set level = 2 -%push -%set level = 3 -%report -Level is $(level) -%pop -Level is $(level) -%pop -Level is $(level) -%pop -Level is $(level) -%pop -(That last error was deliberate) - - -quote and escape handling -------------------------- - -Both single and double quotes are supported, as are escapes. Some of the -implications are quite subtle and some of the design choices made may not -meet with universal approval. The basic idea is that a string in which -macro references have been expanded should look like the source string -apart from the where macros have been expanded. This implies that quote -and escape characters should not be removed from the string. - -Single and double quotes are different in that (as in most shells), -macros are substituted within double quotes but not within single -quotes. Back quotes are not special characters. Missing quotes at the -end of a string are automatically and quietly supplied. - -We've already seen some examples but what happens here: $(x)? -Should not that have been expanded? Why wasn't it? The answer is given -later on. As a clue, this is: $(x). This isn't: $(x)! - -Characters may be escaped by preceding them with a \ (back slash). -Escapes work even within quotes, which is more like C than most shells. -Thus, '\'' works, and it doesn't with the C shell. - -Quotes and escapes can also be used in "a=b, c=d" style assignments -but they are not part of macro names. For example: - -%set \= = equal, \' = quote - -defines macros called "=" and "'", not "\=" and "\'". To reference -these macros, "$(=)" ('$(=)') works because "=" is not special in -this context. However the quote must be escaped because quotes are -always special, as in "$(\')" ('$(\')'). - - -miscellaneous notes -------------------- - -In the "a=b, c=d" strings that are parsed by macParseDefns(), a macro -can be set to an empty value by putting nothing after the equals -sign, as in - -%set empty = -resulting in empty = "$(empty)". Omitting the equal sign gives the -macro a NULL rather than empty value (with the result that the macro -is deleted since this is how macPutValue() interprets a NULL value), so - -%set empty -deletes the empty macro, as can be seen when we try to de-reference -it: $(empty). - -The only special characters in these "a=b, c=d" strings are "=", "," -and white space surrounding these characters (plus quotes and escapes -of course). This means that - -%set fred 2 -actually sets a macro called "fred 2" to a NULL value (i.e. it deletes -it if it existed). This is probably wrong and the space should be -taken as an implicit '='. However, to do this and still to support -ignored white space around '=' and ',' characters is a bigger change -than I am prepared to make at present. - -What was the problem expanding "$(x)" before? It was single quotes -from words like "wasn't"! Is this a problem or a feature? diff --git a/src/libCom/macLib/macLibREADME b/src/libCom/macLib/macLibREADME deleted file mode 100644 index f3cda53c2..000000000 --- a/src/libCom/macLib/macLibREADME +++ /dev/null @@ -1,177 +0,0 @@ -1. Macro substitution library ------------------------------ - -This library could be used directly by applications which need to -support macro substitution. It will be implemented on all platforms. - -1.1 Core library ----------------- - -The core library provides a minimal set of basic operations. Some -utility routines, described later, use core routines to provide a more -convenient interface for some purposes. - -a) long macCreateHandle( MAC_HANDLE **handle, char *pairs[] ); - void macSuppressWarning(MAC_HANDLE *handle,int falseTrue); - - Creates a new macro substitution context and returns an opaque handle - to that context. An application can, if it desires, have several - active contexts, although most will not. - - If desired, an initial set of macro definitions may be loaded - ("pairs" is set to NULL to avoid this). The definitions are in the - "standard" pairs format, as described under macParseDefns(). - - Note that MAC_HANDLE is a typedef for the context structure. The - opaque handle is of type "MAC_HANDLE *", which is a pointer to the - context structure. The memory for this context is allocated by this - routine. - - macSuppressWarning can be called to suppress the marning message - when macExpandString cant expand a macro. A non zero value will - suppress the messages. - - -c) long macGetValue ( MAC_HANDLE *handle, char *name, - char *value, long maxlen ); - - Returns up to maxlen characters of the value of macro "name". "value" - will be zero-terminated if the length of the value is less than - maxlen. The function value will be the number of characters copied to - "value" (see below for behavior if the macro is undefined). If maxlen - is zero, no characters will be copied to "value" (which can be NULL) - and the call can be used to check whether the macro is defined. Note - that truncation of the value is therefore not reported. Is this a - problem? - - If the macro is undefined, the macro reference will be returned in - the value string (if permitted by maxlen) and the function value will - be _minus_ the number of characters copied. Note that treatment of - maxlen is intended to be consistent with what people are used to with - strncpy(). - - If the value contains macro references then the references will be - expanded recursively. This expansion will detect a direct or indirect - self reference. - - Macro references begin with a "$" immediately followed by either a - "(" or a "{" character. The macro name comes next, and may optionally - be succeeded by an "=" and a default value, which will be returned if - the named macro is undefined at the moment of expansion. The reference - is terminated by the matching ")" or "}" character. - -d) long macPutValue( MAC_HANDLE *handle, char *name, char *value ); - - Sets the value of the macro "name". If "value" is NULL, it undefines - all instances of "name" at all scoping levels (it's not an error if - "name" is not defined in this case). Macros referenced by "value" - need not be defined at this point. - - The function returns the length of the value string. - -e) long macDeleteHandle( MAC_HANDLE *handle ); - - Marks a handle invalid, and frees all storage associated with it. - - Note that this does not free any strings into which macro values have - been returned. Macro values are always returned into strings which - were pre-allocated by the caller. - -f) long macPushScope( MAC_HANDLE *handle ); - - Marks the start of a new scoping level such that all definitions made - up until the next macPopScope() call will be lost on macPopScope() - and those current at macPushScope() will be re-instated. - -g) long macPopScope( MAC_HANDLE *handle ); - - See macPushScope. - -h) Error handling - - These routines conform to 0 (=OK) for success, -1 (=ERROR) for - failure, and small positive values for extra info. I contravened this - for macGetValue() and macExpandString() because I felt that it was - worth returning information both on success / failure and on value - length. - - Errors and warnings are reported using errlogPrintf(). - - - -1.2 Utility library -------------------- - -These are convenience functions. If other useful functions emerge during -implementation, the list may grow. - -a) macParseDefns( MAC_HANDLE *handle, char *defns, char **pairs[] ); - - This takes a set of macro definitions in "a=xxx,b=yyy" format and - converts them into an array of pointers to character strings which - are, in order, "first name", "first value", "second name", "second - value" etc. The array is terminated with two NULL pointers and all - storage is allocated contiguously so that it can be freed with a - single call to free(). - - This routine is independent of any handle and provides a generally - useful service which may be used elsewhere. Any macro references in - values are not expanded at this point since the referenced macros may - be defined or redefined before the macro actually has to be - translated. - - Shell-style escapes and quotes are supported, as are things like - "A=B,B=$(C$(A)),CA=CA,CB=CB" (sets B to "CB"). White space is - significant within values but ignored elsewhere (i.e. surrounding "=" - and "," characters). - - Probably noone will ever want to, but the special meanings of "$", - "{", "}", "(", ")", "=" and "," can all be changed via macPutXxxx() - calls. This routine does not have a handle argument, so they must be - changed globally for it to use the new definitions. Should it have a - handle argument? This makes it more of a pain to use but guarantees - that there will be no conflicts. I think it should really. - - The function value is the number of definitions encountered, or -1 if - the supplied string is invalid. - -b) long macInstallMacros( MAC_HANDLE *handle, char *pairs[] ); - - This takes an array of pairs as defined above and installs them as - definitions by calling macPutValue(). The pairs array is terminated - by a NULL pointer. - - The function value is the number of macros defined. - -c) long macExpandString( MAC_HANDLE *handle, char *src, - char *dest, long maxlen ); - - This operates on a string which may contain macro references. It - parses the string looking for such references and passes them to - macGetValue() for translation. It returns the expanded string in the - supplied argument. - - The function value is similar to that of macGetValue(). Its absolute - value is the number of characters copied. If negative, at least one - undefined macro has been left unexpanded. - -d) char *macEnvExpand( char *src ); - - This operates on a string which may contain macros defined by - environment variables. It parses the string looking for such - references and passes them to macGetValue() for translation. It uses - malloc() to allocate space for the expanded string and returns a - pointer to this null-terminated string. It returns NULL if the source - string contains any undefined references. - -e) char *macDefExpand( char *src, MAC_HANDLE *macros ); - - This operates in the same manner as macEnvExpand, but takes an - optional macro handle that can contain a set of macro definitions. - These macros are appended to the set of macros from environment - variables when expanding the string. - -f) long macReportMacros( MAC_HANDLE *handle ); - - This reports details of current definitions to standard output, and is - intended purely for debugging purposes. diff --git a/src/libCom/macLib/macUtil.c b/src/libCom/macLib/macUtil.c deleted file mode 100644 index 7bf73542e..000000000 --- a/src/libCom/macLib/macUtil.c +++ /dev/null @@ -1,284 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Implementation of utility macro substitution library (macLib) - * - * William Lupton, W. M. Keck Observatory - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "errlog.h" -#include "macLib.h" - -/* - * Parse macros definitions in "a=xxx,b=yyy" format and convert them to - * a contiguously allocated array pointers to names and values, and the - * name and value strings, terminated with two NULL pointers. Quotes - * and escapes are honored but only removed from macro names (not - * values) - */ -long /* #defns encountered; <0 = ERROR */ -epicsShareAPI macParseDefns( - MAC_HANDLE *handle, /* opaque handle; can be NULL if default */ - /* special characters are to be used */ - - const char *defns, /* macro definitions in "a=xxx,b=yyy" */ - /* format */ - - char **pairs[] ) /* address of variable to receive pointer */ - /* to NULL-terminated array of {name, */ - /* value} pair strings; all storage is */ - /* allocated contiguously */ -{ - static const size_t altNumMax = 4; - size_t numMax; - int i; - int num; - int quote; - int escape; - size_t nbytes; - const char **ptr; - const char **end; - int *del; - char *memCp, **memCpp; - const char *c; - char *s, *d, **p; - enum { preName, inName, preValue, inValue } state; - - /* debug output */ - if ( handle && (handle->debug & 1) ) - printf( "macParseDefns( %s )\n", defns ); - - /* allocate temporary pointer arrays; in worst case they need to have - as many entries as the length of the defns string */ - numMax = strlen( defns ); - if ( numMax < altNumMax ) - numMax = altNumMax; - ptr = (const char **) calloc( numMax, sizeof( char * ) ); - end = (const char **) calloc( numMax, sizeof( char * ) ); - del = (int *) calloc( numMax, sizeof( int ) ); - if ( ptr == NULL || end == NULL || del == NULL ) goto error; - - /* go through definitions, noting pointers to starts and ends of macro - names and values; honor quotes and escapes; ignore white space - around assignment and separator characters */ - num = 0; - del[0] = FALSE; - quote = 0; - state = preName; - for ( c = (const char *) defns; *c != '\0'; c++ ) { - - /* handle quotes */ - if ( quote ) - quote = ( *c == quote ) ? 0 : quote; - else if ( *c == '\'' || *c == '"' ) - quote = *c; - - /* handle escapes (pointer incremented below) */ - escape = ( *c == '\\' && *( c + 1 ) != '\0' ); - - switch ( state ) { - case preName: - if ( !quote && !escape && ( isspace( (int) *c ) || *c == ',' ) ) break; - ptr[num] = c; - state = inName; - /* fall through (may be empty name) */ - - case inName: - if ( quote || escape || ( *c != '=' && *c != ',' ) ) break; - end[num] = c; - while ( end[num] > ptr[num] && isspace( (int) *( end[num] - 1 ) ) ) - end[num]--; - num++; - del[num] = FALSE; - state = preValue; - if ( *c != ',' ) break; - del[num] = TRUE; - /* fall through (','; will delete) */ - - case preValue: - if ( !quote && !escape && isspace( (int) *c ) ) break; - ptr[num] = c; - state = inValue; - /* fall through (may be empty value) */ - - case inValue: - if ( quote || escape || *c != ',' ) break; - end[num] = c; - while ( end[num] > ptr[num] && isspace( (int) *( end[num] - 1 ) ) ) - end[num]--; - num++; - del[num] = FALSE; - state = preName; - break; - } - - /* if this was escape, increment pointer now (couldn't do - before because could have ignored escape at start of name - or value) */ - if ( escape ) c++; - } - - /* tidy up from state at end of string */ - switch ( state ) { - case preName: - break; - case inName: - end[num] = c; - while ( end[num] > ptr[num] && isspace( (int) *( end[num] - 1 ) ) ) - end[num]--; - num++; - del[num] = TRUE; - case preValue: - ptr[num] = c; - case inValue: - end[num] = c; - while ( end[num] > ptr[num] && isspace( (int) *( end[num] - 1 ) ) ) - end[num]--; - num++; - del[num] = FALSE; - } - - /* debug output */ - if ( handle != NULL && handle->debug & 4 ) - for ( i = 0; i < num; i += 2 ) - printf( "[%ld] %.*s = [%ld] %.*s (%s) (%s)\n", - (long) (end[i+0] - ptr[i+0]), (int) (end[i+0] - ptr[i+0]), ptr[i+0], - (long) (end[i+1] - ptr[i+1]), (int) (end[i+1] - ptr[i+1]), ptr[i+1], - del[i+0] ? "del" : "nodel", - del[i+1] ? "del" : "nodel" ); - - /* calculate how much memory to allocate: pointers followed by - strings */ - nbytes = ( num + 2 ) * sizeof( char * ); - for ( i = 0; i < num; i++ ) - nbytes += end[i] - ptr[i] + 1; - - /* allocate memory and set returned pairs pointer */ - memCp = malloc( nbytes ); - if ( memCp == NULL ) goto error; - memCpp = ( char ** ) memCp; - *pairs = memCpp; - - /* copy pointers and strings (memCpp accesses the pointer section - and memCp accesses the string section) */ - memCp += ( num + 2 ) * sizeof( char * ); - for ( i = 0; i < num; i++ ) { - - /* if no '=' followed the name, macro will be deleted */ - if ( del[i] ) - *memCpp++ = NULL; - else - *memCpp++ = memCp; - - /* copy value regardless of the above */ - strncpy( memCp, (const char *) ptr[i], end[i] - ptr[i] ); - memCp += end[i] - ptr[i]; - *memCp++ = '\0'; - } - - /* add two NULL pointers */ - *memCpp++ = NULL; - *memCpp++ = NULL; - - /* remove quotes and escapes from names in place (unlike values, they - will not be re-parsed) */ - for ( p = *pairs; *p != NULL; p += 2 ) { - quote = 0; - for ( s = d = *p; *s != '\0'; s++ ) { - - /* quotes are not copied */ - if ( quote ) { - if ( *s == quote ) { - quote = 0; - continue; - } - } - else if ( *s == '\'' || *s == '"' ) { - quote = *s; - continue; - } - - /* escapes are not copied but next character is */ - if ( *s == '\\' && *( s + 1 ) != '\0' ) - s++; - - /* others are copied */ - *d++ = *s; - } - - /* need to terminate destination */ - *d++ = '\0'; - } - - /* free workspace */ - free( ( void * ) ptr ); - free( ( void * ) end ); - free( ( char * ) del ); - - /* debug output */ - if ( handle != NULL && handle->debug & 1 ) - printf( "macParseDefns() -> %d\n", num / 2 ); - - /* success exit; return number of definitions */ - return num / 2; - - /* error exit */ -error: - errlogPrintf( "macParseDefns: failed to allocate memory\n" ); - if ( ptr != NULL ) free( ( void * ) ptr ); - if ( end != NULL ) free( ( void * ) end ); - if ( del != NULL ) free( ( char * ) del ); - *pairs = NULL; - return -1; -} - -/* - * Install an array of name / value pairs as macro definitions. The - * array should have an even number of elements followed by at least - * one (preferably two) NULL pointers - */ -long /* #macros defined; <0 = ERROR */ -epicsShareAPI macInstallMacros( - MAC_HANDLE *handle, /* opaque handle */ - - char *pairs[] ) /* pointer to NULL-terminated array of */ - /* {name,value} pair strings; a NULL */ - /* value implies undefined; a NULL */ - /* argument implies no macros */ -{ - int n; - char **p; - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macInstallMacros( %s, %s, ... )\n", - pairs && pairs[0] ? pairs[0] : "NULL", - pairs && pairs[1] ? pairs[1] : "NULL" ); - - /* go through array defining macros */ - for ( n = 0, p = pairs; p != NULL && p[0] != NULL; n++, p += 2 ) { - if ( macPutValue( handle, p[0], p[1] ) < 0 ) - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macInstallMacros() -> %d\n", n ); - - /* return number of macros defined */ - return n; -} - diff --git a/src/libCom/misc/Makefile b/src/libCom/misc/Makefile deleted file mode 100644 index 3d5412dc3..000000000 --- a/src/libCom/misc/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/misc - -INC += alarm.h -INC += alarmString.h -INC += adjustment.h -INC += cantProceed.h -INC += dbDefs.h -INC += epicsConvert.h -INC += epicsExit.h -INC += epicsStdlib.h -INC += epicsString.h -INC += epicsTypes.h -INC += shareLib.h -INC += epicsExport.h -INC += unixFileName.h -INC += locationException.h -INC += ipAddrToAsciiAsynchronous.h -INC += compilerDependencies.h -INC += epicsUnitTest.h -INC += testMain.h - -# epicsVersion.h is created by this Makefile -INC += epicsVersion.h - -Com_SRCS += alarmString.c -Com_SRCS += aToIPAddr.c -Com_SRCS += adjustment.c -Com_SRCS += cantProceed.c -Com_SRCS += epicsConvert.c -Com_SRCS += epicsExit.c -Com_SRCS += epicsStdlib.c -Com_SRCS += epicsString.c -Com_SRCS += truncateFile.c -Com_SRCS += ipAddrToAsciiAsynchronous.cpp -Com_SRCS += epicsUnitTest.c diff --git a/src/libCom/misc/RULES b/src/libCom/misc/RULES deleted file mode 100644 index 2ba358675..000000000 --- a/src/libCom/misc/RULES +++ /dev/null @@ -1,18 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -MAKEVERSION = $(LIBCOM)/misc/makeEpicsVersion.pl -MAKEVERSION_FLAGS = -o $(notdir $@) $(QUIET_FLAG) -MAKEVERSION_FLAGS += $(if $(EPICS_SITE_VERSION),-v "$(EPICS_SITE_VERSION)") - -$(COMMON_DIR)/epicsVersion.h: $(CONFIG)/CONFIG_BASE_VERSION \ - $(CONFIG)/CONFIG_SITE $(MAKEVERSION) - @$(RM) $(notdir $@) - $(PERL) $(MAKEVERSION) $(MAKEVERSION_FLAGS) $< - @$(MV) $(notdir $@) $@ diff --git a/src/libCom/misc/aToIPAddr.c b/src/libCom/misc/aToIPAddr.c deleted file mode 100644 index c21b574f6..000000000 --- a/src/libCom/misc/aToIPAddr.c +++ /dev/null @@ -1,193 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * rational replacement for inet_addr() - * - * author: Jeff Hill - */ -#include -#include - -#define epicsExportSharedSymbols -#include "epicsTypes.h" -#include "osiSock.h" - -#ifndef NELEMENTS -#define NELEMENTS(A) (sizeof(A)/sizeof(A[0])) -#endif /*NELEMENTS*/ - -/* - * addrArrayToUL () - */ -static int addrArrayToUL ( const unsigned *pAddr, - unsigned nElements, struct in_addr *pIpAddr ) -{ - unsigned i; - epicsUInt32 addr = 0ul; - - for ( i=0u; i < nElements; i++ ) { - if ( pAddr[i] > 0xff ) { - return -1; - } - addr <<= 8; - addr |= ( epicsUInt32 ) pAddr[i]; - } - pIpAddr->s_addr = htonl ( addr ); - - return 0; -} - -/* - * initIPAddr() - * !! ipAddr should be passed in in network byte order !! - * !! port is passed in in host byte order !! - */ -static int initIPAddr ( struct in_addr ipAddr, unsigned port, - struct sockaddr_in *pIP ) -{ - if ( port > 0xffff ) { - return -1; - } - { - epicsUInt16 port_16 = (epicsUInt16) port; - memset (pIP, '\0', sizeof(*pIP)); - pIP->sin_family = AF_INET; - pIP->sin_port = htons(port_16); - pIP->sin_addr = ipAddr; - } - return 0; -} - -/* - * rational replacement for inet_addr() - * which allows the limited broadcast address - * 255.255.255.255, allows the user - * to specify a port number, and allows also a - * named host to be specified. - * - * Sets the port number to "defaultPort" only if - * "pAddrString" does not contain an address of the form - * "n.n.n.n:p or host:p" - */ -epicsShareFunc int epicsShareAPI -aToIPAddr( const char *pAddrString, unsigned short defaultPort, - struct sockaddr_in *pIP ) -{ - int status; - unsigned addr[4]; - unsigned long rawAddr; - /* - * !! change n elements here requires change in format below !! - */ - char hostName[512]; - char dummy[8]; - unsigned port; - struct in_addr ina; - - /* - * dotted ip addresses - */ - status = sscanf ( pAddrString, " %u . %u . %u . %u %7s ", - addr, addr+1u, addr+2u, addr+3u, dummy ); - if ( status == 4 ) { - if ( addrArrayToUL ( addr, NELEMENTS ( addr ), & ina ) < 0 ) { - return -1; - } - port = defaultPort; - return initIPAddr ( ina, port, pIP ); - } - - /* - * dotted ip addresses and port - */ - status = sscanf ( pAddrString, " %u . %u . %u . %u : %u %7s", - addr, addr+1u, addr+2u, addr+3u, &port, dummy ); - if ( status >= 5 ) { - if ( status > 5 ) { - /* - * valid at the start but detritus on the end - */ - return -1; - } - if ( addrArrayToUL ( addr, NELEMENTS ( addr ), &ina ) < 0 ) { - return -1; - } - return initIPAddr ( ina, port, pIP ); - } - - /* - * IP address as a raw number - */ - status = sscanf ( pAddrString, " %lu %7s ", &rawAddr, dummy ); - if ( status == 1 ) { - if ( rawAddr > 0xffffffff ) { - return -1; - } - port = defaultPort; - { - epicsUInt32 rawAddr_32 = ( epicsUInt32 ) rawAddr; - ina.s_addr = htonl ( rawAddr_32 ); - return initIPAddr ( ina, port, pIP ); - } - } - - /* - * IP address as a raw number, and port - */ - status = sscanf ( pAddrString, " %lu : %u %7s ", &rawAddr, &port, dummy ); - if ( status >= 2 ) { - if ( status > 2 ) { - /* - * valid at the start but detritus on the end - */ - return -1; - } - if ( rawAddr > 0xffffffff ) { - return -1; - } - { - epicsUInt32 rawAddr_32 = ( epicsUInt32 ) rawAddr; - ina.s_addr = htonl ( rawAddr_32 ); - return initIPAddr ( ina, port, pIP ); - } - } - - - /* - * host name string - */ - status = sscanf ( pAddrString, " %511[^:] %s ", hostName, dummy ); - if ( status == 1 ) { - port = defaultPort; - status = hostToIPAddr ( hostName, &ina ); - if ( status == 0 ) { - return initIPAddr ( ina, port, pIP ); - } - } - - /* - * host name string, and port - */ - status = sscanf ( pAddrString, " %511[^:] : %u %s ", hostName, - &port, dummy ); - if ( status >= 2 ) { - if ( status > 2 ) { - /* - * valid at the start but detritus on the end - */ - return -1; - } - status = hostToIPAddr ( hostName, &ina ); - if ( status == 0 ) { - return initIPAddr ( ina, port, pIP ); - } - } - - return -1; -} diff --git a/src/libCom/misc/adjustment.c b/src/libCom/misc/adjustment.c deleted file mode 100644 index ac10e28c9..000000000 --- a/src/libCom/misc/adjustment.c +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* src/libCom/adjustment.c */ - -/* Author: Peregrine McGehee */ - -#include -#include -#include - -/* Up to now epicsShareThings have been declared as imports - * (Appropriate for other stuff) - * After setting the following they will be declared as exports - * (Appropriate for what we implenment) - */ -#define epicsExportSharedSymbols -#include "adjustment.h" - -epicsShareFunc size_t adjustToWorstCaseAlignment(size_t size) -{ - int align_size, adjust; - struct test_long_word { char c; long lw; }; - struct test_double { char c; double d; }; - struct test_ptr { char c; void *p; }; - int test_long_size = sizeof(struct test_long_word) - sizeof(long); - int test_double_size = sizeof(struct test_double) - sizeof(double); - int test_ptr_size = sizeof(struct test_ptr) - sizeof(void *); - size_t adjusted_size = size; - - /* - * Use Jeff's alignment tests to determine worst case of long, - * double or pointer alignment requirements. - */ - align_size = test_long_size > test_ptr_size ? - test_long_size : test_ptr_size; - - align_size = align_size > test_double_size ? - align_size : test_double_size; - - /* - * Increase the size to fit worst case alignment if not already - * properly aligned. - */ - adjust = align_size - size%align_size; - if (adjust != align_size) adjusted_size += adjust; - - return (adjusted_size); -} diff --git a/src/libCom/misc/adjustment.h b/src/libCom/misc/adjustment.h deleted file mode 100644 index 3f152039f..000000000 --- a/src/libCom/misc/adjustment.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* src/libCom/adjustment.h */ - -#ifndef INCadjustmenth -#define INCadjustmenth -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc size_t adjustToWorstCaseAlignment(size_t size); - -#ifdef __cplusplus -} -#endif - - -#endif /*INCadjustmenth*/ - diff --git a/src/libCom/misc/alarm.h b/src/libCom/misc/alarm.h deleted file mode 100644 index 58e2b7313..000000000 --- a/src/libCom/misc/alarm.h +++ /dev/null @@ -1,108 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Alarm definitions, must match menuAlarmSevr.dbd and menuAlarmStat.dbd */ - -/* - * Authors: Bob Dalesio and Marty Kraimer - * Date: 11-7-90 - */ - -#ifndef INC_alarm_H -#define INC_alarm_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -#define NO_ALARM 0 - -/* ALARM SEVERITIES - must match menuAlarmSevr.dbd */ - -typedef enum { - epicsSevNone = NO_ALARM, - epicsSevMinor, - epicsSevMajor, - epicsSevInvalid, - ALARM_NSEV -} epicsAlarmSeverity; - -#define firstEpicsAlarmSev epicsSevNone -#define MINOR_ALARM epicsSevMinor -#define MAJOR_ALARM epicsSevMajor -#define INVALID_ALARM epicsSevInvalid -#define lastEpicsAlarmSev epicsSevInvalid - - -/* ALARM STATUS - must match menuAlarmStat.dbd */ - -typedef enum { - epicsAlarmNone = NO_ALARM, - epicsAlarmRead, - epicsAlarmWrite, - epicsAlarmHiHi, - epicsAlarmHigh, - epicsAlarmLoLo, - epicsAlarmLow, - epicsAlarmState, - epicsAlarmCos, - epicsAlarmComm, - epicsAlarmTimeout, - epicsAlarmHwLimit, - epicsAlarmCalc, - epicsAlarmScan, - epicsAlarmLink, - epicsAlarmSoft, - epicsAlarmBadSub, - epicsAlarmUDF, - epicsAlarmDisable, - epicsAlarmSimm, - epicsAlarmReadAccess, - epicsAlarmWriteAccess, - ALARM_NSTATUS -} epicsAlarmCondition; - -#define firstEpicsAlarmCond epicsAlarmNone -#define READ_ALARM epicsAlarmRead -#define WRITE_ALARM epicsAlarmWrite -#define HIHI_ALARM epicsAlarmHiHi -#define HIGH_ALARM epicsAlarmHigh -#define LOLO_ALARM epicsAlarmLoLo -#define LOW_ALARM epicsAlarmLow -#define STATE_ALARM epicsAlarmState -#define COS_ALARM epicsAlarmCos -#define COMM_ALARM epicsAlarmComm -#define TIMEOUT_ALARM epicsAlarmTimeout -#define HW_LIMIT_ALARM epicsAlarmHwLimit -#define CALC_ALARM epicsAlarmCalc -#define SCAN_ALARM epicsAlarmScan -#define LINK_ALARM epicsAlarmLink -#define SOFT_ALARM epicsAlarmSoft -#define BAD_SUB_ALARM epicsAlarmBadSub -#define UDF_ALARM epicsAlarmUDF -#define DISABLE_ALARM epicsAlarmDisable -#define SIMM_ALARM epicsAlarmSimm -#define READ_ACCESS_ALARM epicsAlarmReadAccess -#define WRITE_ACCESS_ALARM epicsAlarmWriteAccess -#define lastEpicsAlarmCond epicsAlarmWriteAccess - - -/* Name string arrays */ - -epicsShareExtern const char *epicsAlarmSeverityStrings [ALARM_NSEV]; -epicsShareExtern const char *epicsAlarmConditionStrings [ALARM_NSTATUS]; - - -#ifdef __cplusplus -} -#endif - -#endif /* INC_alarm_H */ diff --git a/src/libCom/misc/alarmString.c b/src/libCom/misc/alarmString.c deleted file mode 100644 index 4db179dcb..000000000 --- a/src/libCom/misc/alarmString.c +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* String names for alarm status and severity values */ - -#define epicsExportSharedSymbols -#include "alarm.h" - -/* ALARM SEVERITIES - must match menuAlarmSevr.dbd and alarm.h */ - -epicsShareDef const char * epicsAlarmSeverityStrings[ALARM_NSEV] = { - "NO_ALARM", - "MINOR", - "MAJOR", - "INVALID" -}; - - -/* ALARM STATUS - must match menuAlarmStat.dbd and alarm.h */ - -epicsShareDef const char * epicsAlarmConditionStrings[ALARM_NSTATUS] = { - "NO_ALARM", - "READ", - "WRITE", - "HIHI", - "HIGH", - "LOLO", - "LOW", - "STATE", - "COS", - "COMM", - "TIMEOUT", - "HWLIMIT", - "CALC", - "SCAN", - "LINK", - "SOFT", - "BAD_SUB", - "UDF", - "DISABLE", - "SIMM", - "READ_ACCESS", - "WRITE_ACCESS" -}; diff --git a/src/libCom/misc/alarmString.h b/src/libCom/misc/alarmString.h deleted file mode 100644 index ab320f058..000000000 --- a/src/libCom/misc/alarmString.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * This file is deprecated, use alarm.h instead. - * - * Old string names for alarm status and severity values - */ - -#ifndef INC_alarmString_H -#define INC_alarmString_H - -#include "alarm.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Old versions of alarmString.h defined these names: */ - -#define alarmSeverityString epicsAlarmSeverityStrings -#define alarmStatusString epicsAlarmConditionStrings - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/misc/cantProceed.c b/src/libCom/misc/cantProceed.c deleted file mode 100644 index 6c35796fd..000000000 --- a/src/libCom/misc/cantProceed.c +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 04JAN99 */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "errlog.h" -#include "cantProceed.h" -#include "epicsThread.h" -#include "epicsStackTrace.h" - -epicsShareFunc void * callocMustSucceed(size_t count, size_t size, const char *msg) -{ - void * mem = NULL; - if (count > 0 && size > 0) { - while ((mem = calloc(count, size)) == NULL) { - errlogPrintf("%s: callocMustSucceed(%lu, %lu) - calloc failed\n", - msg, (unsigned long)count, (unsigned long)size); - errlogPrintf("Thread %s (%p) suspending.\n", - epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf()); - errlogFlush(); - epicsThreadSuspendSelf(); - } - } - return mem; -} - -epicsShareFunc void * mallocMustSucceed(size_t size, const char *msg) -{ - void * mem = NULL; - if (size > 0) { - while ((mem = malloc(size)) == NULL) { - errlogPrintf("%s: mallocMustSucceed(%lu) - malloc failed\n", - msg, (unsigned long)size); - errlogPrintf("Thread %s (%p) suspending.\n", - epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf()); - errlogFlush(); - epicsThreadSuspendSelf(); - } - } - return mem; -} - -epicsShareFunc void cantProceed(const char *msg, ...) -{ - va_list pvar; - va_start(pvar, msg); - if (msg) - errlogVprintf(msg, pvar); - va_end(pvar); - - errlogPrintf("Thread %s (%p) can't proceed, suspending.\n", - epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf()); - - epicsStackTrace(); - - errlogFlush(); - - epicsThreadSleep(1.0); - while (1) - epicsThreadSuspendSelf(); -} diff --git a/src/libCom/misc/cantProceed.h b/src/libCom/misc/cantProceed.h deleted file mode 100644 index 437f96802..000000000 --- a/src/libCom/misc/cantProceed.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef INCcantProceedh -#define INCcantProceedh - -#include - -#include "compilerDependencies.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void cantProceed(const char *errorMessage, ...) EPICS_PRINTF_STYLE(1,2); -epicsShareFunc void * callocMustSucceed(size_t count, size_t size, const char *errorMessage); -epicsShareFunc void * mallocMustSucceed(size_t size, const char *errorMessage); - -#ifdef __cplusplus -} -#endif - -#endif /* cantProceedh */ diff --git a/src/libCom/misc/dbDefs.h b/src/libCom/misc/dbDefs.h deleted file mode 100644 index e1de3f200..000000000 --- a/src/libCom/misc/dbDefs.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Marty Kraimer - * Date: 6-1-90 - */ - -#ifndef INC_dbDefs_H -#define INC_dbDefs_H - -#include - -#ifdef TRUE -# undef TRUE -#endif -#define TRUE 1 - -#ifdef FALSE -# undef FALSE -#endif -#define FALSE 0 - -/* deprecated, use static */ -#ifndef LOCAL -# define LOCAL static -#endif - -/* number of elements in an array */ -#ifndef NELEMENTS -# define NELEMENTS(array) (sizeof (array) / sizeof ((array) [0])) -#endif - -/* byte offset of member in structure - deprecated, use offsetof */ -#ifndef OFFSET -# define OFFSET(structure, member) offsetof(structure, member) -#endif - -/* Subtract member byte offset, returning pointer to parent object */ -#ifndef CONTAINER -# ifdef __GNUC__ -# define CONTAINER(ptr, structure, member) ({ \ - const __typeof(((structure*)0)->member) *_ptr = (ptr); \ - (structure*)((char*)_ptr - offsetof(structure, member)); \ - }) -# else -# define CONTAINER(ptr, structure, member) \ - ((structure*)((char*)(ptr) - offsetof(structure, member))) -# endif -#endif - -/*Process Variable Name Size */ -/* PVNAME_STRINGSZ includes the nil terminator */ -#define PVNAME_STRINGSZ 61 -#define PVNAME_SZ (PVNAME_STRINGSZ - 1) - -/* Buffer size for the string representation of a DBF_*LINK field */ -#define PVLINK_STRINGSZ 1024 - -/* dbAccess enums/menus can have up to this many choices */ -#define DB_MAX_CHOICES 30 - -#endif /* INC_dbDefs_H */ diff --git a/src/libCom/misc/epicsConvert.c b/src/libCom/misc/epicsConvert.c deleted file mode 100644 index 9318ceb7e..000000000 --- a/src/libCom/misc/epicsConvert.c +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*epicsConvert.c*/ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMath.h" -#include "epicsConvert.h" -#include "cantProceed.h" - -epicsShareFunc float epicsConvertDoubleToFloat(double value) -{ - double abs; - - if (value == 0 || !finite(value)) - return (float) value; - - abs = fabs(value); - - if (abs >= FLT_MAX) - return (value > 0) ? FLT_MAX : -FLT_MAX; - - if (abs <= FLT_MIN) - return (value > 0) ? FLT_MIN : -FLT_MIN; - - return (float) value; -} diff --git a/src/libCom/misc/epicsConvert.h b/src/libCom/misc/epicsConvert.h deleted file mode 100644 index 1c38bc30a..000000000 --- a/src/libCom/misc/epicsConvert.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*epicsConvert.h*/ - -#ifndef INC_epicsConvert_H -#define INC_epicsConvert_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc float epicsConvertDoubleToFloat(double value); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsConvert_H */ diff --git a/src/libCom/misc/epicsExit.c b/src/libCom/misc/epicsExit.c deleted file mode 100644 index 266835eaa..000000000 --- a/src/libCom/misc/epicsExit.c +++ /dev/null @@ -1,212 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*epicsExit.c*/ -/* - * Author: Marty Kraimer - * Date: 23AUG2004 - * Thread exit revisions: Jeff Hill - * Date: 06Dec2006 - * - * Note that epicsExitCallAtThreadExits is currently called directly from the - * thread entry wrapper in OS dependent code. That approach might not work - * correctly if the thread exits indirectly instead of just returning from - * the function specified to epicsThreadCreate. For example the thread might - * exit via the exit() call. There might be OS dependent solutions for that - * weakness. - * - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "ellLib.h" -#include "errlog.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "cantProceed.h" -#include "epicsExit.h" - -void epicsMutexCleanup(void); - -typedef struct exitNode { - ELLNODE node; - epicsExitFunc func; - void *arg; - char name[1]; -}exitNode; - -typedef struct exitPvt { - ELLLIST list; -} exitPvt; - -int atExitDebug = 0; - -static epicsThreadOnceId exitPvtOnce = EPICS_THREAD_ONCE_INIT; -static epicsThreadOnceId exitLaterOnce = EPICS_THREAD_ONCE_INIT; -static exitPvt * pExitPvtPerProcess = 0; -static epicsMutexId exitPvtLock = 0; -static epicsThreadPrivateId exitPvtPerThread = 0; - -static int exitLaterStatus; - -static void destroyExitPvt(exitPvt * pep) -{ - ellFree ( &pep->list ); - free ( pep ); -} - -static exitPvt * createExitPvt(void) -{ - exitPvt * pep = calloc ( 1, sizeof ( * pep ) ); - if ( pep ) { - ellInit ( &pep->list ); - } - return pep; -} - -static void exitPvtOnceFunc(void *pParm) -{ - exitPvtPerThread = epicsThreadPrivateCreate (); - assert ( exitPvtPerThread ); - exitPvtLock = epicsMutexMustCreate (); -} - -static void epicsExitInit(void) -{ - epicsThreadOnce ( & exitPvtOnce, exitPvtOnceFunc, 0 ); -} - -static void epicsExitCallAtExitsPvt(exitPvt *pep) -{ - exitNode *pexitNode; - - while ( ( pexitNode = (exitNode *) ellLast ( & pep->list ) ) ) { - if (atExitDebug && pexitNode->name[0]) - fprintf(stderr, "atExit %s(%p)\n", pexitNode->name, pexitNode->arg); - else if(atExitDebug) - fprintf(stderr, "atExit %p(%p)\n", pexitNode->func, pexitNode->arg); - pexitNode->func ( pexitNode->arg ); - ellDelete ( & pep->list, & pexitNode->node ); - free ( pexitNode ); - } -} - -epicsShareFunc void epicsExitCallAtExits(void) -{ - exitPvt * pep = 0; - - epicsExitInit (); - epicsMutexMustLock ( exitPvtLock ); - if ( pExitPvtPerProcess ) { - pep = pExitPvtPerProcess; - pExitPvtPerProcess = 0; - } - epicsMutexUnlock ( exitPvtLock ); - if ( pep ) { - epicsExitCallAtExitsPvt ( pep ); - destroyExitPvt ( pep ); - } - /* Handle specially to avoid circular reference */ - epicsMutexCleanup(); -} - -epicsShareFunc void epicsExitCallAtThreadExits(void) -{ - exitPvt * pep; - - epicsExitInit (); - pep = epicsThreadPrivateGet ( exitPvtPerThread ); - if ( pep ) { - epicsExitCallAtExitsPvt ( pep ); - destroyExitPvt ( pep ); - epicsThreadPrivateSet ( exitPvtPerThread, 0 ); - } -} - -static int epicsAtExitPvt(exitPvt *pep, epicsExitFunc func, void *arg, const char *name) -{ - int status = -1; - exitNode * pExitNode = calloc ( 1, sizeof( *pExitNode ) + (name?strlen(name):0) ); - - if ( pExitNode ) { - pExitNode->func = func; - pExitNode->arg = arg; - if(name) - strcpy(pExitNode->name, name); - ellAdd ( & pep->list, & pExitNode->node ); - status = 0; - } - return status; -} - -epicsShareFunc int epicsAtThreadExit(epicsExitFunc func, void *arg) -{ - exitPvt * pep; - - epicsExitInit (); - pep = epicsThreadPrivateGet ( exitPvtPerThread ); - if ( ! pep ) { - pep = createExitPvt (); - if ( ! pep ) { - return -1; - } - epicsThreadPrivateSet ( exitPvtPerThread, pep ); - } - return epicsAtExitPvt ( pep, func, arg, NULL ); -} - -epicsShareFunc int epicsAtExit3(epicsExitFunc func, void *arg, const char* name) -{ - int status = -1; - - epicsExitInit (); - epicsMutexMustLock ( exitPvtLock ); - if ( !pExitPvtPerProcess ) { - pExitPvtPerProcess = createExitPvt (); - } - if ( pExitPvtPerProcess ) { - status = epicsAtExitPvt ( pExitPvtPerProcess, func, arg, name ); - } - epicsMutexUnlock ( exitPvtLock ); - return status; -} - -epicsShareFunc void epicsExit(int status) -{ - epicsExitCallAtExits(); - epicsThreadSleep(0.1); - exit(status); -} - -static void exitNow(void *junk) -{ - epicsExit(exitLaterStatus); -} - -static void exitLaterOnceFunc(void *raw) -{ - int *status = raw; - exitLaterStatus = *status; - epicsThreadMustCreate("exitLater", - epicsThreadPriorityLow, - epicsThreadGetStackSize(epicsThreadStackSmall), - &exitNow, NULL); -} - -epicsShareFunc void epicsExitLater(int status) -{ - epicsThreadOnce(&exitLaterOnce, &exitLaterOnceFunc, &status); -} - -#include "epicsExport.h" - -epicsExportAddress(int,atExitDebug); diff --git a/src/libCom/misc/epicsExit.h b/src/libCom/misc/epicsExit.h deleted file mode 100644 index 3e961cbc1..000000000 --- a/src/libCom/misc/epicsExit.h +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*epicsExit.h*/ -#ifndef epicsExith -#define epicsExith -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*epicsExitFunc)(void *arg); - -epicsShareFunc void epicsExit(int status); -epicsShareFunc void epicsExitLater(int status); -epicsShareFunc void epicsExitCallAtExits(void); -epicsShareFunc int epicsAtExit3(epicsExitFunc func, void *arg, const char* name); -#define epicsAtExit(F,A) epicsAtExit3(F,A,#F) - -epicsShareFunc void epicsExitCallAtThreadExits(void); -epicsShareFunc int epicsAtThreadExit(epicsExitFunc func, void *arg); - - -#ifdef __cplusplus -} -#endif - -#endif /*epicsExith*/ diff --git a/src/libCom/misc/epicsExport.h b/src/libCom/misc/epicsExport.h deleted file mode 100644 index dea8dd67a..000000000 --- a/src/libCom/misc/epicsExport.h +++ /dev/null @@ -1,43 +0,0 @@ -/*epicsExport.h */ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef INCepicsExporth -#define INCepicsExporth - -#ifdef __cplusplus -extern "C" { -#endif - -#define epicsExportSharedSymbols -#include - -typedef void (*REGISTRAR)(void); - -#define EPICS_EXPORT_POBJ(typ,obj) pvar_ ## typ ## _ ## obj -#define EPICS_EXPORT_PFUNC(obj) pvar_func_ ## obj - -#define epicsExportAddress(typ,obj) \ -epicsShareExtern typ *EPICS_EXPORT_POBJ(typ,obj); \ -epicsShareDef typ *EPICS_EXPORT_POBJ(typ,obj) = (typ *)(char *)&obj - -#define epicsExportRegistrar(func) \ -epicsShareFunc REGISTRAR EPICS_EXPORT_PFUNC(func) = (REGISTRAR)(void*)&func - -#define epicsRegisterFunction(func) \ -static void register_func_ ## func(void) { \ - registryFunctionAdd(#func,(REGISTRYFUNCTION)func);} \ -epicsExportRegistrar(register_func_ ## func) - -#ifdef __cplusplus -} -#endif - -#endif /* epicsExporth */ diff --git a/src/libCom/misc/epicsStdlib.c b/src/libCom/misc/epicsStdlib.c deleted file mode 100644 index f4348981b..000000000 --- a/src/libCom/misc/epicsStdlib.c +++ /dev/null @@ -1,401 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonna LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Authors: Eric Norum & Andrew Johnson */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMath.h" -#include "epicsStdlib.h" -#include "epicsString.h" -#include "epicsConvert.h" - - -/* These are the conversion primitives */ - -epicsShareFunc int -epicsParseLong(const char *str, long *to, int base, char **units) -{ - int c; - char *endp; - long value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = strtol(str, &endp, base); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == EINVAL) /* Not universally supported */ - return S_stdlib_badBase; - if (errno == ERANGE) - return S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} - -epicsShareFunc int -epicsParseULong(const char *str, unsigned long *to, int base, char **units) -{ - int c; - char *endp; - unsigned long value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = strtoul(str, &endp, base); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == EINVAL) /* Not universally supported */ - return S_stdlib_badBase; - if (errno == ERANGE) - return S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} - -epicsShareFunc int -epicsParseLLong(const char *str, long long *to, int base, char **units) -{ - int c; - char *endp; - long long value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = strtoll(str, &endp, base); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == EINVAL) /* Not universally supported */ - return S_stdlib_badBase; - if (errno == ERANGE) - return S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} - -epicsShareFunc int -epicsParseULLong(const char *str, unsigned long long *to, int base, char **units) -{ - int c; - char *endp; - unsigned long long value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = strtoull(str, &endp, base); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == EINVAL) /* Not universally supported */ - return S_stdlib_badBase; - if (errno == ERANGE) - return S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} - -epicsShareFunc int -epicsParseDouble(const char *str, double *to, char **units) -{ - int c; - char *endp; - double value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = epicsStrtod(str, &endp); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == ERANGE) - return (value == 0) ? S_stdlib_underflow : S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} - - -/* These call the primitives */ - -epicsShareFunc int -epicsParseInt8(const char *str, epicsInt8 *to, int base, char **units) -{ - long value; - int status = epicsParseLong(str, &value, base, units); - - if (status) - return status; - - if (value < -0x80 || value > 0x7f) - return S_stdlib_overflow; - - *to = (epicsInt8) value; - return 0; -} - -epicsShareFunc int -epicsParseUInt8(const char *str, epicsUInt8 *to, int base, char **units) -{ - unsigned long value; - int status = epicsParseULong(str, &value, base, units); - - if (status) - return status; - - if (value > 0xff && value <= ~0xffUL) - return S_stdlib_overflow; - - *to = (epicsUInt8) value; - return 0; -} - -epicsShareFunc int -epicsParseInt16(const char *str, epicsInt16 *to, int base, char **units) -{ - long value; - int status = epicsParseLong(str, &value, base, units); - - if (status) - return status; - - if (value < -0x8000 || value > 0x7fff) - return S_stdlib_overflow; - - *to = (epicsInt16) value; - return 0; -} - -epicsShareFunc int -epicsParseUInt16(const char *str, epicsUInt16 *to, int base, char **units) -{ - unsigned long value; - int status = epicsParseULong(str, &value, base, units); - - if (status) - return status; - - if (value > 0xffff && value <= ~0xffffUL) - return S_stdlib_overflow; - - *to = (epicsUInt16) value; - return 0; -} - -epicsShareFunc int -epicsParseInt32(const char *str, epicsInt32 *to, int base, char **units) -{ - long value; - int status = epicsParseLong(str, &value, base, units); - - if (status) - return status; - -#if (LONG_MAX > 0x7fffffffLL) - if (value < -0x80000000L || value > 0x7fffffffL) - return S_stdlib_overflow; -#endif - - *to = (epicsInt32) value; - return 0; -} - -epicsShareFunc int -epicsParseUInt32(const char *str, epicsUInt32 *to, int base, char **units) -{ - unsigned long value; - int status = epicsParseULong(str, &value, base, units); - - if (status) - return status; - -#if (ULONG_MAX > 0xffffffffULL) - if (value > 0xffffffffUL && value <= ~0xffffffffUL) - return S_stdlib_overflow; -#endif - - *to = (epicsUInt32) value; - return 0; -} - -epicsShareFunc int -epicsParseInt64(const char *str, epicsInt64 *to, int base, char **units) -{ -#if (LONG_MAX == 0x7fffffffffffffffLL) - long value; - int status = epicsParseLong(str, &value, base, units); -#else - long long value; - int status = epicsParseLLong(str, &value, base, units); -#endif - - if (status) - return status; - - *to = (epicsInt64) value; - return 0; -} - -epicsShareFunc int -epicsParseUInt64(const char *str, epicsUInt64 *to, int base, char **units) -{ -#if (ULONG_MAX == 0xffffffffffffffffULL) - unsigned long value; - int status = epicsParseULong(str, &value, base, units); -#else - unsigned long long value; - int status = epicsParseULLong(str, &value, base, units); -#endif - - if (status) - return status; - - *to = (epicsUInt64) value; - return 0; -} - - -epicsShareFunc int -epicsParseFloat(const char *str, float *to, char **units) -{ - double value, abs; - int status = epicsParseDouble(str, &value, units); - - if (status) - return status; - - abs = fabs(value); - if (value > 0 && abs <= FLT_MIN) - return S_stdlib_underflow; - if (finite(value) && abs >= FLT_MAX) - return S_stdlib_overflow; - - *to = (float) value; - return 0; -} - - -/* If strtod() works properly, the OS-specific osdStrtod.h does: - * #define epicsStrtod strtod - * - * If strtod() is broken, osdStrtod.h defines this prototype: - * epicsShareFunc double epicsStrtod(const char *str, char **endp); - */ - -#ifndef epicsStrtod -epicsShareFunc double -epicsStrtod(const char *str, char **endp) -{ - const char *cp = str; - int negative = 0; - double res; - - while (isspace((int)*cp)) - cp++; - - if (*cp == '+') { - cp++; - } else if (*cp == '-') { - negative = 1; - cp++; - } - - if (epicsStrnCaseCmp("0x", cp, 2) == 0) { - if (negative) - return strtol(str, endp, 16); - else - return strtoul(str, endp, 16); - } - if (!isalpha((int)*cp)) { - res = strtod(str, endp); - if (isinf(res)) - errno = ERANGE; - return res; - } - - if (epicsStrnCaseCmp("NAN", cp, 3) == 0) { - res = epicsNAN; - cp += 3; - if (*cp == '(') { - cp++; - while (*cp && (*cp++ != ')')) - continue; - } - } - else if (epicsStrnCaseCmp("INF", cp, 3) == 0) { - res = negative ? -epicsINF : epicsINF; - cp += 3; - if (epicsStrnCaseCmp("INITY", cp, 5) == 0) { - cp += 5; - } - } else { - cp = str; - res = 0; - } - - if (endp) - *endp = (char *)cp; - - return res; -} -#endif diff --git a/src/libCom/misc/epicsStdlib.h b/src/libCom/misc/epicsStdlib.h deleted file mode 100644 index 20b7cd26f..000000000 --- a/src/libCom/misc/epicsStdlib.h +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsStdlib.h */ -/* Author: Eric Norum */ - -#ifndef INC_epicsStdlib_H -#define INC_epicsStdlib_H - -#include -#include - -#include "shareLib.h" -#include "osdStrtod.h" -#include "epicsTypes.h" -#include "errMdef.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define S_stdlib_noConversion (M_stdlib | 1) /* No digits to convert */ -#define S_stdlib_extraneous (M_stdlib | 2) /* Extraneous characters */ -#define S_stdlib_underflow (M_stdlib | 3) /* Too small to represent */ -#define S_stdlib_overflow (M_stdlib | 4) /* Too large to represent */ -#define S_stdlib_badBase (M_stdlib | 5) /* Number base not supported */ - - -epicsShareFunc int - epicsParseLong(const char *str, long *to, int base, char **units); -epicsShareFunc int - epicsParseULong(const char *str, unsigned long *to, int base, char **units); -epicsShareFunc int - epicsParseLLong(const char *str, long long *to, int base, char **units); -epicsShareFunc int - epicsParseULLong(const char *str, unsigned long long *to, int base, char **units); -epicsShareFunc int - epicsParseDouble(const char *str, double *to, char **units); - -epicsShareFunc int - epicsParseFloat(const char *str, float *to, char **units); - -epicsShareFunc int - epicsParseInt8(const char *str, epicsInt8 *to, int base, char **units); -epicsShareFunc int - epicsParseUInt8(const char *str, epicsUInt8 *to, int base, char **units); -epicsShareFunc int - epicsParseInt16(const char *str, epicsInt16 *to, int base, char **units); -epicsShareFunc int - epicsParseUInt16(const char *str, epicsUInt16 *to, int base, char **units); - -epicsShareFunc int - epicsParseInt32(const char *str, epicsInt32 *to, int base, char **units); -epicsShareFunc int - epicsParseUInt32(const char *str, epicsUInt32 *to, int base, char **units); - -epicsShareFunc int - epicsParseInt64(const char *str, epicsInt64 *to, int base, char **units); -epicsShareFunc int - epicsParseUInt64(const char *str, epicsUInt64 *to, int base, char **units); - -#define epicsParseFloat32(str, to, units) epicsParseFloat(str, to, units) -#define epicsParseFloat64(str, to, units) epicsParseDouble(str, to, units) - -/* These macros return 1 if successful, 0 on failure. - * This is analagous to the return value from sscanf() - */ -#define epicsScanLong(str, to, base) (!epicsParseLong(str, to, base, NULL)) -#define epicsScanULong(str, to, base) (!epicsParseULong(str, to, base, NULL)) -#define epicsScanLLong(str, to, base) (!epicsParseLLong(str, to, base, NULL)) -#define epicsScanULLong(str, to, base) (!epicsParseULLong(str, to, base, NULL)) -#define epicsScanFloat(str, to) (!epicsParseFloat(str, to, NULL)) -#define epicsScanDouble(str, to) (!epicsParseDouble(str, to, NULL)) - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsStdlib_H */ diff --git a/src/libCom/misc/epicsString.c b/src/libCom/misc/epicsString.c deleted file mode 100644 index e41e21b72..000000000 --- a/src/libCom/misc/epicsString.c +++ /dev/null @@ -1,380 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Authors: Jun-ichi Odagiri, Marty Kraimer, Eric Norum, - * Mark Rivers, Andrew Johnson, Ralph Lange - * - * Routines in this file should have corresponding test code in - * libCom/test/epicsStringTest.c - */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "cantProceed.h" -#include "epicsString.h" - -/* Deprecated, use epicsStrnRawFromEscaped() instead */ -int dbTranslateEscape(char *dst, const char *src) -{ - size_t big_enough = strlen(src) + 1; - - return epicsStrnRawFromEscaped(dst, big_enough, src, big_enough); -} - -int epicsStrnRawFromEscaped(char *dst, size_t dstlen, const char *src, - size_t srclen) -{ - int rem = dstlen; - int ndst = 0; - - while (srclen--) { - int c = *src++; - #define OUT(chr) if (--rem > 0) ndst++, *dst++ = chr - - if (!c) break; - - input: - if (c != '\\') { - OUT(c); - continue; - } - - if (!srclen-- || !(c = *src++)) break; - - switch (c) { - case 'a': OUT('\a'); break; - case 'b': OUT('\b'); break; - case 'f': OUT('\f'); break; - case 'n': OUT('\n'); break; - case 'r': OUT('\r'); break; - case 't': OUT('\t'); break; - case 'v': OUT('\v'); break; - case '\\': OUT('\\'); break; - case '\'': OUT('\''); break; - case '\"': OUT('\"'); break; - - case '0' :case '1' :case '2' :case '3' : - case '4' :case '5' :case '6' :case '7' : - { /* \ooo */ - unsigned int u = c - '0'; - - if (!srclen-- || !(c = *src++)) { - OUT(u); goto done; - } - if (c < '0' || c > '7') { - OUT(u); goto input; - } - u = u << 3 | (c - '0'); - - if (!srclen-- || !(c = *src++)) { - OUT(u); goto done; - } - if (c < '0' || c > '7') { - OUT(u); goto input; - } - u = u << 3 | (c - '0'); - - if (u > 0377) { - /* Undefined behaviour! */ - } - OUT(u); - } - break; - - case 'x' : - { /* \xXXX... */ - unsigned int u = 0; - - if (!srclen-- || !(c = *src++ & 0xff)) - goto done; - - while (isxdigit(c)) { - u = u << 4 | ((c > '9') ? toupper(c) - 'A' + 10 : c - '0'); - if (u > 0xff) { - /* Undefined behaviour! */ - } - if (!srclen-- || !(c = *src++ & 0xff)) { - OUT(u); - goto done; - } - } - OUT(u); - goto input; - } - - default: - OUT(c); - } - #undef OUT - } -done: - if (dstlen) - *dst = '\0'; - return ndst; -} - -int epicsStrnEscapedFromRaw(char *dst, size_t dstlen, const char *src, - size_t srclen) -{ - int rem = dstlen; - int ndst = 0; - - if (dst == src) - return -1; - - while (srclen--) { - int c = *src++; - #define OUT(chr) ndst++; if (--rem > 0) *dst++ = chr - - switch (c) { - case '\a': OUT('\\'); OUT('a'); break; - case '\b': OUT('\\'); OUT('b'); break; - case '\f': OUT('\\'); OUT('f'); break; - case '\n': OUT('\\'); OUT('n'); break; - case '\r': OUT('\\'); OUT('r'); break; - case '\t': OUT('\\'); OUT('t'); break; - case '\v': OUT('\\'); OUT('v'); break; - case '\\': OUT('\\'); OUT('\\'); break; - case '\'': OUT('\\'); OUT('\''); break; - case '\"': OUT('\\'); OUT('\"'); break; - default: - if (isprint(c & 0xff)) { - OUT(c); - break; - } - OUT('\\'); - OUT('0' + ((c & 0300) >> 6)); - OUT('0' + ((c & 0070) >> 3)); - OUT('0' + (c & 0007)); - } - #undef OUT - } - if (dstlen) - *dst = '\0'; - return ndst; -} - -size_t epicsStrnEscapedFromRawSize(const char *src, size_t srclen) -{ - size_t ndst = srclen; - - while (srclen--) { - int c = *src++; - - switch (c) { - case '\a': case '\b': case '\f': case '\n': - case '\r': case '\t': case '\v': case '\\': - case '\'': case '\"': - ndst++; - break; - default: - if (!isprint(c & 0xff)) - ndst += 3; - } - } - return ndst; -} - -int epicsStrCaseCmp(const char *s1, const char *s2) -{ - while (1) { - int ch1 = toupper((int) *s1); - int ch2 = toupper((int) *s2); - - if (ch2 == 0) return (ch1 != 0); - if (ch1 == 0) return -1; - if (ch1 < ch2) return -1; - if (ch1 > ch2) return 1; - s1++; - s2++; - } -} - -int epicsStrnCaseCmp(const char *s1, const char *s2, size_t len) -{ - size_t i = 0; - - while (i++ < len) { - int ch1 = toupper((int) *s1); - int ch2 = toupper((int) *s2); - - if (ch2 == 0) return (ch1 != 0); - if (ch1 == 0) return -1; - if (ch1 < ch2) return -1; - if (ch1 > ch2) return 1; - s1++; - s2++; - } - return 0; -} - -char * epicsStrnDup(const char *s, size_t len) -{ - char *buf = mallocMustSucceed(len + 1, "epicsStrnDup"); - - strncpy(buf, s, len); - buf[len] = '\0'; - return buf; -} - -char * epicsStrDup(const char *s) -{ - return strcpy(mallocMustSucceed(strlen(s)+1, "epicsStrDup"), s); -} - -int epicsStrPrintEscaped(FILE *fp, const char *s, size_t len) -{ - int nout = 0; - - while (len--) { - char c = *s++; - - switch (c) { - case '\a': nout += fprintf(fp, "\\a"); break; - case '\b': nout += fprintf(fp, "\\b"); break; - case '\f': nout += fprintf(fp, "\\f"); break; - case '\n': nout += fprintf(fp, "\\n"); break; - case '\r': nout += fprintf(fp, "\\r"); break; - case '\t': nout += fprintf(fp, "\\t"); break; - case '\v': nout += fprintf(fp, "\\v"); break; - case '\\': nout += fprintf(fp, "\\\\"); break; - case '\'': nout += fprintf(fp, "\\'"); break; - case '\"': nout += fprintf(fp, "\\\""); break; - default: - if (isprint(0xff & (int)c)) - nout += fprintf(fp, "%c", c); - else - nout += fprintf(fp, "\\%03o", (unsigned char)c); - break; - } - } - return nout; -} - -/* Until Base requires POSIX 2008 we must provide our own implementation */ -size_t epicsStrnLen(const char *s, size_t maxlen) -{ - size_t i; - - for (i=0; i> 5)); - if (!(c = *str++)) break; - hash ^= (hash << 7) ^ c ^ (hash >> 3); - } - return hash; -} - -unsigned int epicsMemHash(const char *str, size_t length, unsigned int seed) -{ - unsigned int hash = seed; - - while (length--) { - hash ^= ~((hash << 11) ^ *str++ ^ (hash >> 5)); - if (!length--) break; - hash ^= (hash << 7) ^ *str++ ^ (hash >> 3); - } - return hash; -} diff --git a/src/libCom/misc/epicsString.h b/src/libCom/misc/epicsString.h deleted file mode 100644 index 093c73df4..000000000 --- a/src/libCom/misc/epicsString.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Authors: Jun-ichi Odagiri, Marty Kraimer, Eric Norum, - * Mark Rivers, Andrew Johnson, Ralph Lange - */ - -#ifndef INC_epicsString_H -#define INC_epicsString_H - -#include -#include "epicsTypes.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int epicsStrnRawFromEscaped(char *outbuf, size_t outsize, - const char *inbuf, size_t inlen); -epicsShareFunc int epicsStrnEscapedFromRaw(char *outbuf, size_t outsize, - const char *inbuf, size_t inlen); -epicsShareFunc size_t epicsStrnEscapedFromRawSize(const char *buf, size_t len); -epicsShareFunc int epicsStrCaseCmp(const char *s1, const char *s2); -epicsShareFunc int epicsStrnCaseCmp(const char *s1, const char *s2, size_t len); -epicsShareFunc char * epicsStrDup(const char *s); -epicsShareFunc char * epicsStrnDup(const char *s, size_t len); -epicsShareFunc int epicsStrPrintEscaped(FILE *fp, const char *s, size_t n); -#define epicsStrSnPrintEscaped epicsStrnEscapedFromRaw -epicsShareFunc size_t epicsStrnLen(const char *s, size_t maxlen); -epicsShareFunc int epicsStrGlobMatch(const char *str, const char *pattern); -epicsShareFunc char * epicsStrtok_r(char *s, const char *delim, char **lasts); -epicsShareFunc unsigned int epicsStrHash(const char *str, unsigned int seed); -epicsShareFunc unsigned int epicsMemHash(const char *str, size_t length, - unsigned int seed); - -/* dbTranslateEscape is deprecated, use epicsStrnRawFromEscaped instead */ -epicsShareFunc int dbTranslateEscape(char *s, const char *ct); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsString_H */ diff --git a/src/libCom/misc/epicsTypes.h b/src/libCom/misc/epicsTypes.h deleted file mode 100644 index efc6a91cb..000000000 --- a/src/libCom/misc/epicsTypes.h +++ /dev/null @@ -1,231 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - * Date: 5-95 - */ - -#ifndef INC_epicsTypes_H -#define INC_epicsTypes_H - -#include "shareLib.h" -#include "compilerDependencies.h" - -#ifndef stringOf -# if defined (__STDC__ ) || defined (__cplusplus) -# define stringOf(TOKEN) #TOKEN -# else -# define stringOf(TOKEN) "TOKEN" -# endif -#endif - -typedef enum { - epicsFalse = 0, - epicsTrue = 1 -} epicsBoolean EPICS_DEPRECATED; - -/* - * Architecture Independent Data Types - * These are sufficient for all our current archs - */ -typedef char epicsInt8; -typedef unsigned char epicsUInt8; -typedef short epicsInt16; -typedef unsigned short epicsUInt16; -typedef int epicsInt32; -typedef unsigned int epicsUInt32; -typedef long long epicsInt64; -typedef unsigned long long epicsUInt64; - -typedef epicsUInt16 epicsEnum16; -typedef float epicsFloat32; -typedef double epicsFloat64; -typedef epicsInt32 epicsStatus; - - -typedef struct { - unsigned length; - char *pString; -} epicsString; - -/* - * !! Dont use this - it may vanish in the future !! - * - * Provided only for backwards compatibility with - * db_access.h - * - */ -#define MAX_STRING_SIZE 40 -typedef char epicsOldString[MAX_STRING_SIZE]; - -/* - * union of all types - * - * Strings included here as pointers only so that we support - * large string types. - * - * Arrays included here as pointers because large arrays will - * not fit in this union. - */ -typedef union epics_any { - epicsInt8 int8; - epicsUInt8 uInt8; - epicsInt16 int16; - epicsUInt16 uInt16; - epicsEnum16 enum16; - epicsInt32 int32; - epicsUInt32 uInt32; - epicsInt64 int64; - epicsUInt64 uInt64; - epicsFloat32 float32; - epicsFloat64 float64; - epicsString string; -} epicsAny; - -/* - * Corresponding Type Codes - * (this enum must start at zero) - * - * !! Update epicsTypeToDBR_XXXX[] and DBR_XXXXToEpicsType - * in db_access.h if you edit this enum !! - */ -typedef enum { - epicsInt8T, - epicsUInt8T, - epicsInt16T, - epicsUInt16T, - epicsEnum16T, - epicsInt32T, - epicsUInt32T, - epicsFloat32T, - epicsFloat64T, - epicsStringT, - epicsOldStringT -} epicsType; -#define firstEpicsType epicsInt8T -#define lastEpicsType epicsOldStringT -#define validEpicsType(x) ((x>=firstEpicsType) && (x<=lastEpicsType)) -#define invalidEpicsType(x) ((xlastEpicsType)) - - -/* - * The enumeration "epicsType" is an index to this array - * of type name strings. - */ -#ifdef epicsTypesGLOBAL -epicsShareDef const char *epicsTypeNames [lastEpicsType+1] = { - "epicsInt8", - "epicsUInt8", - "epicsInt16", - "epicsUInt16", - "epicsEnum16", - "epicsInt32", - "epicsUInt32", - "epicsFloat32", - "epicsFloat64", - "epicsString", - "epicsOldString", -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern const char *epicsTypeNames [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - -/* - * The enumeration "epicsType" is an index to this array - * of type code name strings. - */ -#ifdef epicsTypesGLOBAL -epicsShareDef const char *epicsTypeCodeNames [lastEpicsType+1] = { - "epicsInt8T", - "epicsUInt8T", - "epicsInt16T", - "epicsUInt16T", - "epicsEnum16T", - "epicsInt32T", - "epicsUInt32T", - "epicsFloat32T", - "epicsFloat64T", - "epicsStringT", - "epicsOldStringT", -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern const char *epicsTypeCodeNames [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - -#ifdef epicsTypesGLOBAL -epicsShareDef const unsigned epicsTypeSizes [lastEpicsType+1] = { - sizeof (epicsInt8), - sizeof (epicsUInt8), - sizeof (epicsInt16), - sizeof (epicsUInt16), - sizeof (epicsEnum16), - sizeof (epicsInt32), - sizeof (epicsUInt32), - sizeof (epicsFloat32), - sizeof (epicsFloat64), - sizeof (epicsString), - sizeof (epicsOldString), -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern const unsigned epicsTypeSizes [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - -/* - * The enumeration "epicsType" is an index to this array - * of type class identifiers. - */ -typedef enum { - epicsIntC, - epicsUIntC, - epicsEnumC, - epicsFloatC, - epicsStringC, - epicsOldStringC -} epicsTypeClass; - -#ifdef epicsTypesGLOBAL -epicsShareDef const epicsTypeClass epicsTypeClasses [lastEpicsType+1] = { - epicsIntC, - epicsUIntC, - epicsIntC, - epicsUIntC, - epicsEnumC, - epicsIntC, - epicsUIntC, - epicsFloatC, - epicsFloatC, - epicsStringC, - epicsOldStringC -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern const epicsTypeClass epicsTypeClasses [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - - -#ifdef epicsTypesGLOBAL -epicsShareDef const char *epicsTypeAnyFieldName [lastEpicsType+1] = { - "int8", - "uInt8", - "int16", - "uInt16", - "enum16", - "int32", - "uInt32", - "float32", - "float64", - "string", - "", /* Old Style Strings will not be in epicsAny type */ -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern const char *epicsTypeAnyFieldName [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - -#endif /* INC_epicsTypes_H */ - diff --git a/src/libCom/misc/epicsUnitTest.c b/src/libCom/misc/epicsUnitTest.c deleted file mode 100644 index 4ac18ea1c..000000000 --- a/src/libCom/misc/epicsUnitTest.c +++ /dev/null @@ -1,264 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Andrew Johnson - * - * Unit test module which generates output in the Test Anything Protocol - * format. See perldoc Test::Harness for details of output format. - * - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsThread.h" -#include "epicsMutex.h" -#include "epicsUnitTest.h" -#include "epicsExit.h" -#include "epicsTime.h" -#include "ellLib.h" -#include "errlog.h" -#include "cantProceed.h" - -typedef struct { - ELLNODE node; - const char *name; - int tests; - int failures; - int skips; -} testFailure; - -static epicsMutexId testLock = 0; -static int perlHarness; -static int planned; -static int tested; -static int passed; -static int failed; -static int skipped; -static int bonus; -static const char *todo; - -epicsTimeStamp started; -static int Harness; -static int Programs; -static int Tests; - -ELLLIST faults; -const char *testing = NULL; - -static epicsThreadOnceId onceFlag = EPICS_THREAD_ONCE_INIT; - -static void testOnce(void *dummy) { - testLock = epicsMutexMustCreate(); - perlHarness = (getenv("HARNESS_ACTIVE") != NULL); -} - -void testPlan(int plan) { - epicsThreadOnce(&onceFlag, testOnce, NULL); - epicsMutexMustLock(testLock); - planned = plan; - tested = passed = failed = skipped = bonus = 0; - todo = NULL; - if (plan) printf("1..%d\n", plan); - epicsMutexUnlock(testLock); -} - -int testOkV(int pass, const char *fmt, va_list pvar) { - const char *result = "not ok"; - epicsMutexMustLock(testLock); - tested++; - if (pass) { - result += 4; /* skip "not " */ - passed++; - if (todo) - bonus++; - } else { - if (todo) - passed++; - else - failed++; - } - printf("%s %2d - ", result, tested); - vprintf(fmt, pvar); - if (todo) - printf(" # TODO %s", todo); - putchar('\n'); - fflush(stdout); - epicsMutexUnlock(testLock); - return pass; -} - -int testOk(int pass, const char *fmt, ...) { - va_list pvar; - va_start(pvar, fmt); - testOkV(pass, fmt, pvar); - va_end(pvar); - return pass; -} - -void testPass(const char *fmt, ...) { - va_list pvar; - va_start(pvar, fmt); - testOkV(1, fmt, pvar); - va_end(pvar); -} - -void testFail(const char *fmt, ...) { - va_list pvar; - va_start(pvar, fmt); - testOkV(0, fmt, pvar); - va_end(pvar); -} - -void testSkip(int skip, const char *why) { - epicsMutexMustLock(testLock); - while (skip-- > 0) { - tested++; - passed++; - skipped++; - printf("ok %2d # SKIP %s\n", tested, why); - } - fflush(stdout); - epicsMutexUnlock(testLock); -} - -void testTodoBegin(const char *why) { - epicsMutexMustLock(testLock); - todo = why; - epicsMutexUnlock(testLock); -} - -void testTodoEnd(void) { - todo = NULL; -} - -int testDiag(const char *fmt, ...) { - va_list pvar; - va_start(pvar, fmt); - epicsMutexMustLock(testLock); - printf("# "); - vprintf(fmt, pvar); - putchar('\n'); - fflush(stdout); - epicsMutexUnlock(testLock); - va_end(pvar); - return 0; -} - -void testAbort(const char *fmt, ...) { - va_list pvar; - va_start(pvar, fmt); - printf("Bail out! "); - vprintf(fmt, pvar); - putchar('\n'); - fflush(stdout); - va_end(pvar); - abort(); -} - -static void testResult(const char *result, int count) { - printf("%12.12s: %3d = %5.2f%%\n", result, count, 100.0 * count / tested); -} - -int testDone(void) { - int status = 0; - - epicsMutexMustLock(testLock); - if (perlHarness) { - if (!planned) printf("1..%d\n", tested); - } else { - if (planned && tested > planned) { - printf("\nRan %d tests but only planned for %d!\n", tested, planned); - status = 2; - } else if (planned && tested < planned) { - printf("\nPlanned %d tests but only ran %d\n", planned, tested); - status = 2; - } - printf("\n Results\n =======\n Tests: %-3d\n", tested); - if (tested) { - testResult("Passed", passed); - if (bonus) testResult("Todo Passes", bonus); - if (failed) { - testResult("Failed", failed); - status = 1; - } - if (skipped) testResult("Skipped", skipped); - } - } - if (Harness) { - if (failed) { - testFailure *fault = callocMustSucceed(1, sizeof(testFailure), - "testDone calloc"); - fault->name = testing; - fault->tests = tested; - fault->failures = failed; - fault->skips = skipped; - ellAdd(&faults, &fault->node); - } - Programs++; - Tests += tested; - } - epicsMutexUnlock(testLock); - return (status); -} - - -/* Our test harness, for RTEMS and vxWorks */ - -void testHarnessExit(void *dummy) { - epicsTimeStamp ended; - int Faulty; - - if (!Harness) return; - - epicsTimeGetCurrent(&ended); - - printf("\n\n EPICS Test Harness Results" - "\n ==========================\n\n"); - - Faulty = ellCount(&faults); - if (!Faulty) - printf("All tests successful.\n"); - else { - int Failures = 0; - testFailure *f; - - printf("Failing Program Tests Faults\n" - "---------------------------------------\n"); - while ((f = (testFailure *)ellGet(&faults))) { - Failures += f->failures; - printf("%-25s %5d %5d\n", f->name, f->tests, f->failures); - if (f->skips) - printf("%d subtests skipped\n", f->skips); - free(f); - } - printf("\nFailed %d/%d test programs. %d/%d subtests failed.\n", - Faulty, Programs, Failures, Tests); - } - - printf("Programs=%d, Tests=%d, %.0f wallclock secs\n\n", - Programs, Tests, epicsTimeDiffInSeconds(&ended, &started)); -} - -void testHarness(void) { - epicsThreadOnce(&onceFlag, testOnce, NULL); - epicsAtExit(testHarnessExit, NULL); - Harness = 1; - Programs = 0; - Tests = 0; - ellInit(&faults); - epicsTimeGetCurrent(&started); -} - -void runTestFunc(const char *name, TESTFUNC func) { - printf("\n***** %s *****\n", name); - testing = name; - func(); /* May not return */ - epicsThreadSleep(1.0); -} diff --git a/src/libCom/misc/epicsUnitTest.h b/src/libCom/misc/epicsUnitTest.h deleted file mode 100644 index 9a119ad22..000000000 --- a/src/libCom/misc/epicsUnitTest.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Andrew Johnson - */ - -#ifndef INC_epicsUnitTest_H -#define INC_epicsUnitTest_H - -#include - -#include "compilerDependencies.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void testPlan(int tests); -epicsShareFunc int testOkV(int pass, const char *fmt, va_list pvar); -epicsShareFunc int testOk(int pass, const char *fmt, ...) - EPICS_PRINTF_STYLE(2, 3); -epicsShareFunc void testPass(const char *fmt, ...) - EPICS_PRINTF_STYLE(1, 2); -epicsShareFunc void testFail(const char *fmt, ...) - EPICS_PRINTF_STYLE(1, 2); -epicsShareFunc void testSkip(int skip, const char *why); -epicsShareFunc void testTodoBegin(const char *why); -epicsShareFunc void testTodoEnd(void); -epicsShareFunc int testDiag(const char *fmt, ...) - EPICS_PRINTF_STYLE(1, 2); -epicsShareFunc void testAbort(const char *fmt, ...) - EPICS_PRINTF_STYLE(1, 2); -epicsShareFunc int testDone(void); - -#define testOk1(cond) testOk(cond, "%s", #cond) - - -typedef int (*TESTFUNC)(void); -epicsShareFunc void testHarness(void); -epicsShareFunc void testHarnessExit(void *dummy); -epicsShareFunc void runTestFunc(const char *name, TESTFUNC func); - -#define runTest(func) runTestFunc(#func, func) -#define testHarnessDone() testHarnessExit(0) - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsUnitTest_H */ diff --git a/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp b/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp deleted file mode 100644 index 4301612c9..000000000 --- a/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp +++ /dev/null @@ -1,473 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#include -#include -#include -#include - -//#define EPICS_FREELIST_DEBUG -#define EPICS_PRIVATE_API - -#define epicsExportSharedSymbols -#include "ipAddrToAsciiAsynchronous.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "epicsGuard.h" -#include "epicsExit.h" -#include "tsDLList.h" -#include "tsFreeList.h" -#include "errlog.h" - -// - this class implements the asynchronous DNS query -// - it completes early with the host name in dotted IP address form -// if the ipAddrToAsciiEngine is destroyed before IO completion -// or if there are too many items already in the engine's queue. -class ipAddrToAsciiTransactionPrivate : - public ipAddrToAsciiTransaction, - public tsDLNode < ipAddrToAsciiTransactionPrivate > { -public: - ipAddrToAsciiTransactionPrivate ( class ipAddrToAsciiEnginePrivate & engineIn ); - virtual ~ipAddrToAsciiTransactionPrivate (); - osiSockAddr address () const; - void show ( unsigned level ) const; - void * operator new ( size_t size, tsFreeList - < ipAddrToAsciiTransactionPrivate, 0x80 > & ); - epicsPlacementDeleteOperator (( void *, tsFreeList - < ipAddrToAsciiTransactionPrivate, 0x80 > & )) - osiSockAddr addr; - ipAddrToAsciiEnginePrivate & engine; - ipAddrToAsciiCallBack * pCB; - bool pending; - void ipAddrToAscii ( const osiSockAddr &, ipAddrToAsciiCallBack & ); - void release (); - void operator delete ( void * ); -private: - ipAddrToAsciiTransactionPrivate & operator = ( const ipAddrToAsciiTransactionPrivate & ); - ipAddrToAsciiTransactionPrivate ( const ipAddrToAsciiTransactionPrivate & ); -}; - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template class tsFreeList - < ipAddrToAsciiTransactionPrivate, 0x80 >; - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - -extern "C" { -static void ipAddrToAsciiEngineGlobalMutexConstruct ( void * ); -} - -namespace { -struct ipAddrToAsciiGlobal : public epicsThreadRunable { - ipAddrToAsciiGlobal(); - virtual ~ipAddrToAsciiGlobal() {} - - virtual void run (); - - char nameTmp [1024]; - tsFreeList - < ipAddrToAsciiTransactionPrivate, 0x80 > - transactionFreeList; - tsDLList < ipAddrToAsciiTransactionPrivate > labor; - mutable epicsMutex mutex; - epicsEvent laborEvent; - epicsEvent destructorBlockEvent; - epicsThread thread; - // pCurrent may be changed by any thread (worker or other) - ipAddrToAsciiTransactionPrivate * pCurrent; - // pActive may only be changed by the worker - ipAddrToAsciiTransactionPrivate * pActive; - unsigned cancelPendingCount; - bool exitFlag; - bool callbackInProgress; -}; -} - -// - this class executes the synchronous DNS query -// - it creates one thread -class ipAddrToAsciiEnginePrivate : - public ipAddrToAsciiEngine { -public: - ipAddrToAsciiEnginePrivate() :refcount(1u), released(false) {} - virtual ~ipAddrToAsciiEnginePrivate () {} - void show ( unsigned level ) const; - - unsigned refcount; - bool released; - - static ipAddrToAsciiGlobal * pEngine; - ipAddrToAsciiTransaction & createTransaction (); - void release (); - -private: - ipAddrToAsciiEnginePrivate ( const ipAddrToAsciiEngine & ); - ipAddrToAsciiEnginePrivate & operator = ( const ipAddrToAsciiEngine & ); -}; - -ipAddrToAsciiGlobal * ipAddrToAsciiEnginePrivate :: pEngine = 0; -static epicsThreadOnceId ipAddrToAsciiEngineGlobalMutexOnceFlag = EPICS_THREAD_ONCE_INIT; - -// the users are not required to supply a show routine -// for there transaction callback class -void ipAddrToAsciiCallBack::show ( unsigned /* level */ ) const {} - -// some noop pure virtual destructures -ipAddrToAsciiCallBack::~ipAddrToAsciiCallBack () {} -ipAddrToAsciiTransaction::~ipAddrToAsciiTransaction () {} -ipAddrToAsciiEngine::~ipAddrToAsciiEngine () {} - -static void ipAddrToAsciiEngineGlobalMutexConstruct ( void * ) -{ - try { - ipAddrToAsciiEnginePrivate::pEngine = new ipAddrToAsciiGlobal (); - } catch (std::exception& e) { - errlogPrintf("ipAddrToAsciiEnginePrivate ctor fails with: %s\n", e.what()); - } -} - -void ipAddrToAsciiEngine::cleanup() -{ - { - epicsGuard G(ipAddrToAsciiEnginePrivate::pEngine->mutex); - ipAddrToAsciiEnginePrivate::pEngine->exitFlag = true; - } - ipAddrToAsciiEnginePrivate::pEngine->laborEvent.signal(); - ipAddrToAsciiEnginePrivate::pEngine->thread.exitWait(); - delete ipAddrToAsciiEnginePrivate::pEngine; - ipAddrToAsciiEnginePrivate::pEngine = 0; -} - -// for now its probably sufficent to allocate one -// DNS transaction thread for all codes sharing -// the same process that need DNS services but we -// leave our options open for the future -ipAddrToAsciiEngine & ipAddrToAsciiEngine::allocate () -{ - epicsThreadOnce ( - & ipAddrToAsciiEngineGlobalMutexOnceFlag, - ipAddrToAsciiEngineGlobalMutexConstruct, 0 ); - if(!ipAddrToAsciiEnginePrivate::pEngine) - throw std::runtime_error("ipAddrToAsciiEngine::allocate fails"); - return * new ipAddrToAsciiEnginePrivate(); -} - -ipAddrToAsciiGlobal::ipAddrToAsciiGlobal () : - thread ( *this, "ipToAsciiProxy", - epicsThreadGetStackSize(epicsThreadStackBig), - epicsThreadPriorityLow ), - pCurrent ( 0 ), pActive ( 0 ), cancelPendingCount ( 0u ), exitFlag ( false ), - callbackInProgress ( false ) -{ - this->thread.start (); // start the thread -} - - -void ipAddrToAsciiEnginePrivate::release () -{ - bool last; - { - epicsGuard < epicsMutex > guard ( this->pEngine->mutex ); - if(released) - throw std::logic_error("Engine release() called again!"); - - // released==true prevents new transactions - released = true; - - { - // cancel any pending transactions - tsDLIter < ipAddrToAsciiTransactionPrivate > it(pEngine->labor.firstIter()); - while(it.valid()) { - ipAddrToAsciiTransactionPrivate *trn = it.pointer(); - ++it; - - if(this==&trn->engine) { - trn->pending = false; - pEngine->labor.remove(*trn); - } - } - - // cancel transaction in lookup or callback - if (pEngine->pCurrent && this==&pEngine->pCurrent->engine) { - pEngine->pCurrent->pending = false; - pEngine->pCurrent = 0; - } - - // wait for completion of in-progress callback - pEngine->cancelPendingCount++; - while(pEngine->pActive && this==&pEngine->pActive->engine - && ! pEngine->thread.isCurrentThread()) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - pEngine->destructorBlockEvent.wait(); - } - pEngine->cancelPendingCount--; - if(pEngine->cancelPendingCount) - pEngine->destructorBlockEvent.signal(); - } - - assert(refcount>0); - last = 0==--refcount; - } - if(last) { - delete this; - } -} - -void ipAddrToAsciiEnginePrivate::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->pEngine->mutex ); - printf ( "ipAddrToAsciiEngine at %p with %u requests pending\n", - static_cast (this), this->pEngine->labor.count () ); - if ( level > 0u ) { - tsDLIter < ipAddrToAsciiTransactionPrivate > - pItem = this->pEngine->labor.firstIter (); - while ( pItem.valid () ) { - pItem->show ( level - 1u ); - pItem++; - } - } - if ( level > 1u ) { - printf ( "mutex:\n" ); - this->pEngine->mutex.show ( level - 2u ); - printf ( "laborEvent:\n" ); - this->pEngine->laborEvent.show ( level - 2u ); - printf ( "exitFlag boolean = %u\n", this->pEngine->exitFlag ); - printf ( "exit event:\n" ); - } -} - -inline void * ipAddrToAsciiTransactionPrivate::operator new ( size_t size, tsFreeList - < ipAddrToAsciiTransactionPrivate, 0x80 > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void ipAddrToAsciiTransactionPrivate::operator delete ( void * pTrans, tsFreeList - < ipAddrToAsciiTransactionPrivate, 0x80 > & freeList ) -{ - freeList.release ( pTrans ); -} -#endif - -void ipAddrToAsciiTransactionPrivate::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - - -ipAddrToAsciiTransaction & ipAddrToAsciiEnginePrivate::createTransaction () -{ - epicsGuard G(this->pEngine->mutex); - if(this->released) - throw std::logic_error("createTransaction() on release()'d ipAddrToAsciiEngine"); - - assert(this->refcount>0); - - ipAddrToAsciiTransactionPrivate *ret = new ( this->pEngine->transactionFreeList ) ipAddrToAsciiTransactionPrivate ( *this ); - - this->refcount++; - - return * ret; -} - -void ipAddrToAsciiGlobal::run () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - while ( ! this->exitFlag ) { - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->laborEvent.wait (); - } - while ( true ) { - ipAddrToAsciiTransactionPrivate * pItem = this->labor.get (); - if ( ! pItem ) { - break; - } - osiSockAddr addr = pItem->addr; - this->pCurrent = pItem; - - if ( this->exitFlag ) - { - sockAddrToDottedIP ( & addr.sa, this->nameTmp, - sizeof ( this->nameTmp ) ); - } - else { - epicsGuardRelease < epicsMutex > unguard ( guard ); - // depending on DNS configuration, this could take a very long time - // so we release the lock - sockAddrToA ( &addr.sa, this->nameTmp, sizeof ( this->nameTmp ) ); - } - - // the ipAddrToAsciiTransactionPrivate destructor is allowed to - // set pCurrent to nill and avoid blocking on a slow DNS - // operation - if ( ! this->pCurrent ) { - continue; - } - - // fix for lp:1580623 - // a destructing cac sets pCurrent to NULL, so - // make local copy to avoid race when releasing the guard - ipAddrToAsciiTransactionPrivate *pCur = pActive = pCurrent; - this->callbackInProgress = true; - - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - // dont call callback with lock applied - pCur->pCB->transactionComplete ( this->nameTmp ); - } - - this->callbackInProgress = false; - pActive = 0; - - if ( this->pCurrent ) { - this->pCurrent->pending = false; - this->pCurrent = 0; - } - if ( this->cancelPendingCount ) { - this->destructorBlockEvent.signal (); - } - } - } -} - -ipAddrToAsciiTransactionPrivate::ipAddrToAsciiTransactionPrivate - ( ipAddrToAsciiEnginePrivate & engineIn ) : - engine ( engineIn ), pCB ( 0 ), pending ( false ) -{ - memset ( & this->addr, '\0', sizeof ( this->addr ) ); - this->addr.sa.sa_family = AF_UNSPEC; -} - -void ipAddrToAsciiTransactionPrivate::release () -{ - this->~ipAddrToAsciiTransactionPrivate (); - this->engine.pEngine->transactionFreeList.release ( this ); -} - -ipAddrToAsciiTransactionPrivate::~ipAddrToAsciiTransactionPrivate () -{ - ipAddrToAsciiGlobal *pGlobal = this->engine.pEngine; - bool last; - { - epicsGuard < epicsMutex > guard ( pGlobal->mutex ); - while ( this->pending ) { - if ( pGlobal->pCurrent == this && - pGlobal->callbackInProgress && - ! pGlobal->thread.isCurrentThread() ) { - // cancel from another thread while callback in progress - // waits for callback to complete - assert ( pGlobal->cancelPendingCount < UINT_MAX ); - pGlobal->cancelPendingCount++; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - pGlobal->destructorBlockEvent.wait (); - } - assert ( pGlobal->cancelPendingCount > 0u ); - pGlobal->cancelPendingCount--; - if ( ! this->pending ) { - if ( pGlobal->cancelPendingCount ) { - pGlobal->destructorBlockEvent.signal (); - } - break; - } - } - else { - if ( pGlobal->pCurrent == this ) { - // cancel from callback, or while lookup in progress - pGlobal->pCurrent = 0; - } - else { - // cancel before lookup starts - pGlobal->labor.remove ( *this ); - } - this->pending = false; - } - } - assert(this->engine.refcount>0); - last = 0==--this->engine.refcount; - } - if(last) { - delete &this->engine; - } -} - -void ipAddrToAsciiTransactionPrivate::ipAddrToAscii ( - const osiSockAddr & addrIn, ipAddrToAsciiCallBack & cbIn ) -{ - bool success; - ipAddrToAsciiGlobal *pGlobal = this->engine.pEngine; - - { - epicsGuard < epicsMutex > guard ( pGlobal->mutex ); - - if (this->engine.released) { - errlogPrintf("Warning: ipAddrToAscii on transaction with release()'d ipAddrToAsciiEngine"); - success = false; - - } else if ( !this->pending && pGlobal->labor.count () < 16u ) { - // put some reasonable limit on queue expansion - this->addr = addrIn; - this->pCB = & cbIn; - this->pending = true; - pGlobal->labor.add ( *this ); - success = true; - } - else { - success = false; - } - } - - if ( success ) { - pGlobal->laborEvent.signal (); - } - else { - char autoNameTmp[256]; - sockAddrToDottedIP ( & addrIn.sa, autoNameTmp, - sizeof ( autoNameTmp ) ); - cbIn.transactionComplete ( autoNameTmp ); - } -} - -osiSockAddr ipAddrToAsciiTransactionPrivate::address () const -{ - return this->addr; -} - -void ipAddrToAsciiTransactionPrivate::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->engine.pEngine->mutex ); - char ipAddr [64]; - sockAddrToDottedIP ( &this->addr.sa, ipAddr, sizeof ( ipAddr ) ); - printf ( "ipAddrToAsciiTransactionPrivate for address %s\n", ipAddr ); - if ( level > 0u ) { - printf ( "\tengine %p\n", - static_cast ( & this->engine ) ); - this->pCB->show ( level - 1u ); - } -} diff --git a/src/libCom/misc/ipAddrToAsciiAsynchronous.h b/src/libCom/misc/ipAddrToAsciiAsynchronous.h deleted file mode 100644 index 9aefca44e..000000000 --- a/src/libCom/misc/ipAddrToAsciiAsynchronous.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef ipAddrToAsciiAsynchronous_h -#define ipAddrToAsciiAsynchronous_h - -#include "osiSock.h" -#include "shareLib.h" - -class epicsShareClass ipAddrToAsciiCallBack { -public: - virtual void transactionComplete ( const char * pHostName ) = 0; - virtual void show ( unsigned level ) const; - virtual ~ipAddrToAsciiCallBack () = 0; -}; - -class epicsShareClass ipAddrToAsciiTransaction { -public: - virtual void release () = 0; - virtual void ipAddrToAscii ( const osiSockAddr &, ipAddrToAsciiCallBack & ) = 0; - virtual osiSockAddr address () const = 0; - virtual void show ( unsigned level ) const = 0; -protected: - virtual ~ipAddrToAsciiTransaction () = 0; -}; - -class epicsShareClass ipAddrToAsciiEngine { -public: - virtual void release () = 0; - virtual ipAddrToAsciiTransaction & createTransaction () = 0; - virtual void show ( unsigned level ) const = 0; - static ipAddrToAsciiEngine & allocate (); -protected: - virtual ~ipAddrToAsciiEngine () = 0; -public: -#ifdef EPICS_PRIVATE_API - static void cleanup(); -#endif -}; - -#endif // ifdef ipAddrToAsciiAsynchronous_h diff --git a/src/libCom/misc/locationException.h b/src/libCom/misc/locationException.h deleted file mode 100644 index 30b187208..000000000 --- a/src/libCom/misc/locationException.h +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -// -// Author: Jeff Hill -// - -#ifndef locationException_h -#define locationException_h - -#include - -#include "cantProceed.h" -#include "errlog.h" - -template -class sourceFileLocation : public T { -public: - sourceFileLocation (const T &parm, const char *fileName, unsigned lineNumber); - sourceFileLocation ( const sourceFileLocation & ); - sourceFileLocation & operator = ( const sourceFileLocation & ); - const char *fileName () const; - unsigned lineNumber () const; -private: - const char *pFileName; - unsigned lineNumberCopy; -}; - -template -inline sourceFileLocation::sourceFileLocation (const T &parm, const char *fileName, unsigned lineNumber) : - T ( parm ), pFileName ( fileName ) , lineNumberCopy ( lineNumber ) {} - -template -inline sourceFileLocation::sourceFileLocation ( const sourceFileLocation &in ) : - T ( in ), pFileName ( in.pFileName ), lineNumberCopy ( in.lineNumberCopy ) -{ -} - -template < class T > -inline sourceFileLocation & sourceFileLocation::operator = ( const sourceFileLocation &in ) -{ - this->pFileName = in.pFileName; - this->lineNumberCopy = in.lineNumberCopy; - return *this; -} - -template < class T > -inline unsigned sourceFileLocation::lineNumber () const -{ - return this->lineNumberCopy; -} - -template -inline const char * sourceFileLocation::fileName () const -{ - return this->pFileName; -} - -#define throwWithLocation(parm) throwExceptionWithLocation (parm, __FILE__, __LINE__); - -template -inline void throwExceptionWithLocation (const T &parm, const char *pFileName, unsigned lineNo) -{ - throw sourceFileLocation (parm, pFileName, lineNo); -} - -#endif // ifdef locationException_h - diff --git a/src/libCom/misc/makeEpicsVersion.pl b/src/libCom/misc/makeEpicsVersion.pl deleted file mode 100644 index c7c9acc39..000000000 --- a/src/libCom/misc/makeEpicsVersion.pl +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/perl -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use strict; - -use Getopt::Std; -use File::Basename; - -my $tool = basename($0); - -our ($opt_h, $opt_q, $opt_v); -our $opt_o = 'epicsVersion.h'; - -$Getopt::Std::OUTPUT_HELP_VERSION = 1; - -HELP_MESSAGE() unless getopts('ho:qv:') && @ARGV == 1; -HELP_MESSAGE() if $opt_h; - -my ($infile) = @ARGV; - -print "Building $opt_o from $infile\n" unless $opt_q; - -open my $VARS, '<', $infile - or die "$tool: Can't open $infile: $!\n"; - -my ($ver, $rev, $mod, $patch, $snapshot); -while (<$VARS>) { - chomp; - next if m/^\s*#/; # Skip comments - if (m/^EPICS_VERSION\s*=\s*(\d+)/) { $ver = $1; } - if (m/^EPICS_REVISION\s*=\s*(\d+)/) { $rev = $1; } - if (m/^EPICS_MODIFICATION\s*=\s*(\d+)/) { $mod = $1; } - if (m/^EPICS_PATCH_LEVEL\s*=\s*(\d+)/) { $patch = $1; } - if (m/^EPICS_DEV_SNAPSHOT\s*=\s*([-\w]*)/) { $snapshot = $1; } -} -close $VARS; - -map { - die "$tool: Variable missing from $infile" unless defined $_; -} $ver, $rev, $mod, $patch, $snapshot; - -my $ver_str = "$ver.$rev.$mod"; -$ver_str .= ".$patch" if $patch > 0; -my $ver_short = $ver_str; -$ver_str .= $snapshot if $snapshot ne ''; -$ver_str .= "-$opt_v" if $opt_v; - -print "Found EPICS Version $ver_str\n" unless $opt_q; - -open my $OUT, '>', $opt_o - or die "$tool: Can't create $opt_o: $!\n"; - -my $obase = basename($opt_o, '.h'); - -print $OUT <<"END"; -/* Generated file $opt_o */ - -#ifndef INC_${obase}_H -#define INC_${obase}_H - -#define EPICS_VERSION $ver -#define EPICS_REVISION $rev -#define EPICS_MODIFICATION $mod -#define EPICS_PATCH_LEVEL $patch -#define EPICS_DEV_SNAPSHOT "$snapshot" -#define EPICS_SITE_VERSION "$opt_v" - -#define EPICS_VERSION_SHORT "$ver_short" -#define EPICS_VERSION_FULL "$ver_str" -#define EPICS_VERSION_STRING "EPICS $ver_str" -#define epicsReleaseVersion "EPICS R$ver_str" - -#ifndef VERSION_INT -# define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P)) -#endif -#define EPICS_VERSION_INT VERSION_INT($ver, $rev, $mod, $patch) - -#endif /* INC_${obase}_H */ -END - -close $OUT; - -sub HELP_MESSAGE { - print STDERR "Usage: $tool [options] CONFIG_BASE_VERSION\n", - " -h Help: Print this message\n", - " -q Quiet: Only print errors\n", - " -o file Output filename, default is $opt_o\n", - " -v vers Site-specific version string\n", - "\n"; - exit 1; -} diff --git a/src/libCom/misc/shareLib.h b/src/libCom/misc/shareLib.h deleted file mode 100644 index 0d376d64a..000000000 --- a/src/libCom/misc/shareLib.h +++ /dev/null @@ -1,214 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Compiler specific key words to set up external symbols and entry points - * - * USAGE: - * There are two distinct classes of keywords in this file: - * - * 1) epicsShareAPI - specifies a multi-language calling mechanism. On windows - * this is the pascal calling convention which is used by visual basic and other - * high level tools. This is only necessary if a C/C++ function needs to be called - * from other languages or from high level tools. The epicsShareAPI keyword - * must be present between the function's returned data type and the function's - * name. All compilers targeting windows accept the __stdcall keyword in this - * location. Functions with variable argument lists should not use the epicsShareAPI - * keyword because __stdcall (pascal) calling convention cannot support variable - * length ed argument lists. - * - * int epicsShareAPI myExtFunc ( int arg ); - * int epicsShareAPI myExtFunc ( int arg ) {} - * - * ** NOTE ** The epicsShareAPI attribute is deprecated and has been removed - * from all IOC-specific APIs. Most libCom APIs still use it, but - * it may get removed from these at some point in the future. - * - * 2) epicsShare{Func,Class,Extern,Def} - specifies shareable library (DLL) - * export/import related information in the source code. On windows these keywords - * allow faster dispatching of calls to DLLs because more is known at compile time. - * It is also not necessary to maintain a linker input files specifying the DLL - * entry points. This maintenance can be more laborious with C++ decorated symbol - * names. These keywords are only necessary if the address of a function or data - * internal to a shareable library (DLL) needs to be visible outside of this shareable - * library (DLL). All compilers targeting windows accept the __declspec(dllexport) - * and __declspec(dllimport) keywords. For GCC version 4 and above the first three - * keywords specify a visibility attribute of "default", which marks the symbol as - * exported even when gcc is given the option -fvisibility=hidden. Doing this can - * significantly reduce the number of symbols exported to a shared library. See the - * URL below for more information. - * - * In header files declare references to externally visible variables, classes and - * functions like this: - * - * #include "shareLib.h" - * epicsShareFunc int myExtFunc ( int arg ); - * epicsShareExtern int myExtVar; - * class epicsShareClass myClass { int func ( void ); }; - * - * In the implementation file, however, you write: - * - * #include - * #define epicsExportSharedSymbols - * #include - * - * epicsShareDef int myExtVar = 4; - * int myExtFunc ( int arg ) {} - * int myClass::func ( void ) {} - * - * By default shareLib.h sets the DLL import / export keywords to import from - * a DLL so that, for DLL consumers (users), nothing special must be done. However, - * DLL implementors must set epicsExportSharedSymbols as above to specify - * which functions are exported from the DLL and which of them are imported - * from other DLLs. - * - * You must first #include what you import and then define epicsExportSharedSymbols - * only right before you #include the prototypes for what you implement! You must - * include shareLib.h again each time that the state of the import/ export keywords - * changes, but this usually occurs as a side effect of including the shareable - * libraries header file(s). - * - * Frequently a header file for a shareable library exported interface will - * have some preprocessor switches like this if this header file must also - * include header files describing interfaces to other shareable libraries. - * - * #ifdef epicsExportSharedSymbols - * # define interfacePDQ_epicsExportSharedSymbols - * # undef epicsExportSharedSymbols - * #endif - * - * #include "epicsTypes.h" - * #include "epicsTime.h" - * - * #ifdef interfacePDQ_epicsExportSharedSymbols - * # define epicsExportSharedSymbols - * # include "shareLib.h" - * #endif - * - * epicsShareFunc int myExtFunc ( int arg ); - * epicsShareExtern int myExtVar; - * class epicsShareClass myClass {}; - * - * Fortunately, the above is only the concern of library authors and will have no - * impact on persons using functions and or external data from a library. - */ - -#undef epicsShareExtern -#undef epicsShareDef -#undef epicsShareClass -#undef epicsShareFunc -#undef epicsShareAPI -#undef READONLY - -#if defined(_WIN32) || defined(__CYGWIN__) -/* - * Check if EPICS_BUILD_DLL or EPICS_CALL_DLL defined and use the dllimport/ - * dllexport keywords if this is a shared library build of base under WIN32. - */ - -# if defined(epicsExportSharedSymbols) -# if defined(EPICS_BUILD_DLL) -# define epicsShareExtern __declspec(dllexport) extern -# define epicsShareClass __declspec(dllexport) -# define epicsShareFunc __declspec(dllexport) -# else -# define epicsShareExtern extern -# define epicsShareClass -# define epicsShareFunc -# endif -# else -# if defined(EPICS_CALL_DLL) -# define epicsShareExtern __declspec(dllimport) extern -# define epicsShareClass __declspec(dllimport) -# define epicsShareFunc __declspec(dllimport) -# else -# define epicsShareExtern extern -# define epicsShareClass -# define epicsShareFunc -# endif -# endif -# define epicsShareDef -# define epicsShareAPI __stdcall /* function removes arguments */ -# define READONLY const - -#elif __GNUC__ >= 4 -/* - * See http://gcc.gnu.org/wiki/Visibility - * For these to work, gcc must be given the flag - * -fvisibility=hidden - * and g++ the flags - * -fvisibility=hidden -fvisibility-inlines-hidden - */ - -# define epicsShareExtern __attribute__ ((visibility("default"))) extern -# define epicsShareClass __attribute__ ((visibility("default"))) -# define epicsShareFunc __attribute__ ((visibility("default"))) - -# define epicsShareDef -# define epicsShareAPI -# if defined(__STDC__) || defined (__cplusplus) -# define READONLY const -# else -# define READONLY -# endif - -/* - * if its the old VAX C Compiler (not DEC C) - */ -#elif defined(VAXC) - - /* - * VAXC creates FORTRAN common blocks when - * we use "extern int fred"/"int fred=4". Therefore, - * the initialization is not loaded unless we - * call a function in that object module. - * - * DEC CXX does not have this problem. - * We suspect (but do not know) that DEC C - * also does not have this problem. - */ -# define epicsShareExtern globalref -# define epicsShareDef globaldef -# define READONLY const -# define epicsShareClass -# define epicsShareFunc -# define epicsShareAPI - -#else - -/* else => no import/export specifiers */ - -# define epicsShareExtern extern -# define epicsShareAPI -# define epicsShareClass -# define epicsShareDef - -# define epicsShareFunc -# if defined(__STDC__) || defined (__cplusplus) -# define READONLY const -# else -# define READONLY -# endif - -#endif - -#ifndef INLINE_defs_EPICS -#define INLINE_defs_EPICS -# ifndef __cplusplus -# if defined (__GNUC__) -# define INLINE static __inline__ -# elif defined (_MSC_VER) -# define INLINE __inline -# elif defined (_SUNPRO_C) -# pragma error_messages (off, E_EXTERN_PRIOR_REDECL_STATIC) -# define INLINE static -# else -# define INLINE static -# endif -# endif /* ifndef __cplusplus */ -#endif /* ifdef INLINE_defs_EPICS */ diff --git a/src/libCom/misc/testMain.h b/src/libCom/misc/testMain.h deleted file mode 100644 index 4db72c39e..000000000 --- a/src/libCom/misc/testMain.h +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_testMain_H -#define INC_testMain_H - -/* This header defines a convenience macro for use by pure test programs. - * A pure test program cannot take any arguments since it must be fully - * automatable. If your program needs to use argv/argc, it may be doing - * measurements not unit and/or regression testing. On Host architectures - * these programs needs to be named main and take dummy argc/argv args, - * but on vxWorks and RTEMS they must be named as the test program. - * - * Use this macro as follows: - * - * #include "testMain.h" - * #include "epicsUnitTest.h" - * - * MAIN(myProgTest) { - * testPlan(...); - * testOk(...) - * return testDone(); - * } - */ - -#if defined(vxWorks) || defined(__rtems__) - #ifdef __cplusplus - #define MAIN(prog) extern "C" int prog(void) - #else - #define MAIN(prog) int prog() - #endif -#else - #ifdef __cplusplus - #define MAIN(prog) int main(int /*argc*/, char * /*argv*/ [] ) - #else - #define MAIN(prog) int main(int argc, char *argv[] ) - #endif -#endif - - -#endif /* INC_testMain_H */ diff --git a/src/libCom/misc/truncateFile.c b/src/libCom/misc/truncateFile.c deleted file mode 100644 index ccb1450c2..000000000 --- a/src/libCom/misc/truncateFile.c +++ /dev/null @@ -1,136 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -/* - * truncate to specified size (we dont use truncate() - * because it is not portable) - */ -epicsShareFunc enum TF_RETURN truncateFile (const char *pFileName, unsigned long size) -{ - char tmpName[256>L_tmpnam?256:L_tmpnam]; - long filePos; - FILE *pFile; - FILE *ptmp; - int status; - int c; - unsigned charNo; - - /* - * see cast of size to long below - */ - if (size>LONG_MAX) { - return TF_ERROR; - } - - pFile = fopen(pFileName, "r"); - if (!pFile) { - fprintf (stderr, - "File access problems to `%s' because `%s'\n", - pFileName, - strerror(errno)); - return TF_ERROR; - } - - /* - * This is not required under UNIX but does appear - * to be required under WIN32. - */ - status = fseek (pFile, 0L, SEEK_END); - if (status!=TF_OK) { - fclose (pFile); - return TF_ERROR; - } - - filePos = ftell(pFile); - if (filePos <= (long) size) { - fclose (pFile); - return TF_OK; - } - - epicsTempName ( tmpName, sizeof (tmpName) ); - if ( tmpName[0] == '\0' ) { - fprintf (stderr,"Unable to create tmp file name?\n"); - fclose (pFile); - return TF_ERROR; - } - - ptmp = fopen (tmpName, "w"); - if (!ptmp) { - fprintf (stderr, - "File access problems to `%s' because `%s'\n", - tmpName, - strerror(errno)); - fclose (pFile); - return TF_ERROR; - } - rewind (pFile); - charNo = 0u; - while (charNo 2 -# define EPICS_ALWAYS_INLINE __inline__ __attribute__((always_inline)) -#else -# define EPICS_ALWAYS_INLINE __inline__ -#endif - -/* Expands to a 'const char*' which describes the name of the current function scope */ -#define EPICS_FUNCTION __PRETTY_FUNCTION__ - -#ifdef __cplusplus - -/* - * in general we dont like ifdefs but they do allow us to check the - * compiler version and make the optimistic assumption that - * standards incompliance issues will be fixed by future compiler - * releases - */ - -/* - * CXX_PLACEMENT_DELETE - defined if compiler supports placement delete - * CXX_THROW_SPECIFICATION - defined if compiler supports throw specification - */ - -#if __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95 ) -# define CXX_THROW_SPECIFICATION -#endif - -#if __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 96 ) -# define CXX_PLACEMENT_DELETE -#endif - -#endif /* __cplusplus */ - -/* - * Enable format-string checking if possible - */ -#define EPICS_PRINTF_STYLE(f,a) __attribute__((format(__printf__,f,a))) - -/* - * Deprecation marker if possible - */ -#if (__GNUC__ > 2) -# define EPICS_DEPRECATED __attribute__((deprecated)) -#endif - -/* - * Unused marker - */ -#define EPICS_UNUSED __attribute__((unused)) - -#endif /* ifndef compilerSpecific_h */ diff --git a/src/libCom/osi/compiler/gcc/epicsAtomicCD.h b/src/libCom/osi/compiler/gcc/epicsAtomicCD.h deleted file mode 100644 index 15b9a6c9a..000000000 --- a/src/libCom/osi/compiler/gcc/epicsAtomicCD.h +++ /dev/null @@ -1,194 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicCD_h -#define epicsAtomicCD_h - -#ifndef __GNUC__ -# error this header is only for use with the gnu compiler -#endif - -#define EPICS_ATOMIC_CMPLR_NAME "GCC" - -#define GCC_ATOMIC_CONCAT( A, B ) GCC_ATOMIC_CONCATR(A,B) -#define GCC_ATOMIC_CONCATR( A, B ) ( A ## B ) - -#define GCC_ATOMIC_INTRINSICS_AVAIL_INT_T \ - GCC_ATOMIC_CONCAT ( \ - __GCC_HAVE_SYNC_COMPARE_AND_SWAP_, \ - __SIZEOF_INT__ ) - -#define GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T \ - GCC_ATOMIC_CONCAT ( \ - __GCC_HAVE_SYNC_COMPARE_AND_SWAP_, \ - __SIZEOF_SIZE_T__ ) - -#define GCC_ATOMIC_INTRINSICS_MIN_X86 \ - ( defined ( __i486 ) || defined ( __pentium ) || \ - defined ( __pentiumpro ) || defined ( __MMX__ ) ) - -#define GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER \ - ( ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 401 ) - -#define GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER \ - ( GCC_ATOMIC_INTRINSICS_MIN_X86 && \ - GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER ) - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * We are optimistic that __sync_synchronize is implemented - * in all version four gcc invariant of target. The gnu doc - * seems to say that when not supported by architecture a call - * to an external function is generated but in practice - * this isn`t the case for some of the atomic intrinsics, and - * so there is an undefined symbol. So far we have not seen - * that with __sync_synchronize, but we can only guess based - * on experimental evidence. - * - * For example we know that when generating object code for - * 386 most of the atomic intrinsics are not present and - * we see undefined symbols with mingw, but we don`t have - * troubles with __sync_synchronize. - */ -#if GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -#define EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - __sync_synchronize (); -} -#endif - -#ifndef EPICS_ATOMIC_WRITE_MEMORY_BARRIER -#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - __sync_synchronize (); -} -#endif - -#else - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -#if GCC_ATOMIC_INTRINSICS_MIN_X86 -#define EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - asm("mfence;"); -} -#endif -#endif - -#ifndef EPICS_ATOMIC_WRITE_MEMORY_BARRIER -#if GCC_ATOMIC_INTRINSICS_MIN_X86 -#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - asm("mfence;"); -} -#endif -#endif - -#endif /* if GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER */ - -#if GCC_ATOMIC_INTRINSICS_AVAIL_INT_T \ - || GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER - -#define EPICS_ATOMIC_INCR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget ) -{ - return __sync_add_and_fetch ( pTarget, 1 ); -} - -#define EPICS_ATOMIC_DECR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget ) -{ - return __sync_sub_and_fetch ( pTarget, 1 ); -} - -#define EPICS_ATOMIC_ADD_INTT -EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta ) -{ - return __sync_add_and_fetch ( pTarget, delta ); -} - -#define EPICS_ATOMIC_CAS_INTT -EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget, - int oldVal, int newVal ) -{ - return __sync_val_compare_and_swap ( pTarget, oldVal, newVal); -} - -#endif /* if GCC_ATOMIC_INTRINSICS_AVAIL_INT_T */ - -#if GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T \ - || GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER - -#define EPICS_ATOMIC_INCR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ) -{ - return __sync_add_and_fetch ( pTarget, 1u ); -} - -#define EPICS_ATOMIC_DECR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ) -{ - return __sync_sub_and_fetch ( pTarget, 1u ); -} - -#define EPICS_ATOMIC_ADD_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta ) -{ - return __sync_add_and_fetch ( pTarget, delta ); -} - -#define EPICS_ATOMIC_SUB_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta ) -{ - return __sync_sub_and_fetch ( pTarget, delta ); -} - -#define EPICS_ATOMIC_CAS_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget, - size_t oldVal, size_t newVal ) -{ - return __sync_val_compare_and_swap ( pTarget, oldVal, newVal); -} - -#define EPICS_ATOMIC_CAS_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( - EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal ) -{ - return __sync_val_compare_and_swap ( pTarget, oldVal, newVal); -} - -#endif /* if GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T */ - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -/* - * if currently unavailable as gcc intrinsics we - * will try for an os specific inline solution - */ -#include "epicsAtomicOSD.h" - -#endif /* epicsAtomicCD_h */ diff --git a/src/libCom/osi/compiler/msvc/compilerSpecific.h b/src/libCom/osi/compiler/msvc/compilerSpecific.h deleted file mode 100644 index 75bfa83fb..000000000 --- a/src/libCom/osi/compiler/msvc/compilerSpecific.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: - * Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef compilerSpecific_h -#define compilerSpecific_h - -#ifndef _MSC_VER -# error compiler/msvc/compilerSpecific.h is only for use with the Microsoft compiler -#endif - -#if _MSC_VER >= 1200 -#define EPICS_ALWAYS_INLINE __forceinline -#else -#define EPICS_ALWAYS_INLINE __inline -#endif - -/* Expands to a 'const char*' which describes the name of the current function scope */ -#define EPICS_FUNCTION __FUNCTION__ - -#ifdef __cplusplus - -/* - * in general we dont like ifdefs but they do allow us to check the - * compiler version and make the optimistic assumption that - * standards incompliance issues will be fixed by future compiler - * releases - */ - -/* - * CXX_PLACEMENT_DELETE - defined if compiler supports placement delete - * CXX_THROW_SPECIFICATION - defined if compiler supports throw specification - */ -#if _MSC_VER >= 1200 /* visual studio 6.0 or later */ -# define CXX_PLACEMENT_DELETE -#endif - -#if _MSC_VER > 1300 /* some release after visual studio 7 we hope */ -# define CXX_THROW_SPECIFICATION -#endif - -#endif /* __cplusplus */ - - -#endif /* ifndef compilerSpecific_h */ diff --git a/src/libCom/osi/compiler/msvc/epicsAtomicCD.h b/src/libCom/osi/compiler/msvc/epicsAtomicCD.h deleted file mode 100644 index e7d1c4b77..000000000 --- a/src/libCom/osi/compiler/msvc/epicsAtomicCD.h +++ /dev/null @@ -1,118 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicCD_h -#define epicsAtomicCD_h - -#include "epicsAssert.h" - -#ifndef _MSC_VER -# error this header file is only for use with with the Microsoft Compiler -#endif - -#ifdef _MSC_EXTENSIONS - -#define EPICS_ATOMIC_CMPLR_NAME "MSVC-INTRINSIC" - -#include - -#if defined ( _M_IX86 ) -# pragma warning( push ) -# pragma warning( disable : 4793 ) - EPICS_ATOMIC_INLINE void epicsAtomicMemoryBarrier (void) - { - long fence; - __asm { xchg fence, eax } - } -# pragma warning( pop ) -#elif defined ( _M_X64 ) -# define MS_ATOMIC_64 -# pragma intrinsic ( __faststorefence ) - EPICS_ATOMIC_INLINE void epicsAtomicMemoryBarrier (void) - { - __faststorefence (); - } -#elif defined ( _M_IA64 ) -# define MS_ATOMIC_64 -# pragma intrinsic ( __mf ) - EPICS_ATOMIC_INLINE void epicsAtomicMemoryBarrier (void) - { - __mf (); - } -#else -# error unexpected target architecture, msvc version of epicsAtomicCD.h -#endif - -/* - * The windows doc appears to recommend defining InterlockedExchange - * to be _InterlockedExchange to cause it to be an intrinsic, but that - * creates issues when later, in a windows os specific header, we include - * windows.h. Therefore, we except some code duplication between the msvc - * csAtomic.h and win32 osdAtomic.h to avoid problems, and to keep the - * os specific windows.h header file out of the msvc cdAtomic.h - */ -#define MS_LONG long -#define MS_InterlockedExchange _InterlockedExchange -#define MS_InterlockedCompareExchange _InterlockedCompareExchange -#define MS_InterlockedIncrement _InterlockedIncrement -#define MS_InterlockedDecrement _InterlockedDecrement -#define MS_InterlockedExchange _InterlockedExchange -#define MS_InterlockedExchangeAdd _InterlockedExchangeAdd -#if defined ( MS_ATOMIC_64 ) -# define MS_LONGLONG long long -# define MS_InterlockedIncrement64 _InterlockedIncrement64 -# define MS_InterlockedDecrement64 _InterlockedDecrement64 -# define MS_InterlockedExchange64 _InterlockedExchange64 -# define MS_InterlockedExchangeAdd64 _InterlockedExchangeAdd64 -# define MS_InterlockedCompareExchange64 _InterlockedCompareExchange64 -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - epicsAtomicMemoryBarrier (); -} - -#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - epicsAtomicMemoryBarrier (); -} - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#include "epicsAtomicMS.h" -#include "epicsAtomicDefault.h" - -#else /* ifdef _MSC_EXTENSIONS */ - -#define EPICS_ATOMIC_CMPLR_NAME "MSVC-DIRECT" - -/* - * if unavailable as an intrinsic we will try - * for os specific inline solution - */ -#include "epicsAtomicOSD.h" - -#endif /* ifdef _MSC_EXTENSIONS */ - -#endif /* epicsAtomicCD_h */ - diff --git a/src/libCom/osi/compiler/solStudio/compilerSpecific.h b/src/libCom/osi/compiler/solStudio/compilerSpecific.h deleted file mode 100644 index a9d59a5bf..000000000 --- a/src/libCom/osi/compiler/solStudio/compilerSpecific.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: - * Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef compilerSpecific_h -#define compilerSpecific_h - -#if !defined(__SUNPRO_C) && !defined (__SUNPRO_CC) -# error Not Solaris Studio -#endif - -#if (defined(__SUNPRO_C) && __SUNPRO_C < 0x590) || \ - (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) -# define EPICS_ALWAYS_INLINE inline -#else -# define EPICS_ALWAYS_INLINE inline __attribute__((always_inline)) -#endif - -#ifdef __cplusplus - -/* - * CXX_PLACEMENT_DELETE - defined if compiler supports placement delete - * CXX_THROW_SPECIFICATION - defined if compiler supports throw specification - * - * (our default guess is that the compiler implements the C++ 97 standard) - */ -#define CXX_THROW_SPECIFICATION -#define CXX_PLACEMENT_DELETE - -#endif /* __cplusplus */ - - -#endif /* ifndef compilerSpecific_h */ diff --git a/src/libCom/osi/compiler/solStudio/epicsAtomicCD.h b/src/libCom/osi/compiler/solStudio/epicsAtomicCD.h deleted file mode 100644 index 8a733a558..000000000 --- a/src/libCom/osi/compiler/solStudio/epicsAtomicCD.h +++ /dev/null @@ -1,23 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicCD_h -#define epicsAtomicCD_h - -#define EPICS_ATOMIC_CMPLR_NAME "SOLSTUDIO" - -#include "epicsAtomicOSD.h" - -#endif /* epicsAtomicCD_h */ diff --git a/src/libCom/osi/compilerDependencies.h b/src/libCom/osi/compilerDependencies.h deleted file mode 100644 index 3bd835c91..000000000 --- a/src/libCom/osi/compilerDependencies.h +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: - * Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef compilerDependencies_h -#define compilerDependencies_h - -#include "compilerSpecific.h" - -#ifdef __cplusplus - -/* - * usage: void func () epicsThrows (( std::bad_alloc, std::logic_error )) - * - * Note: now a widely accepted concensus (ref Meyers and C++ faq) is that - * one should avoid using throw specifications in C++ code - */ -#if defined ( CXX_THROW_SPECIFICATION ) -# define epicsThrows(X) throw X -#else -# define epicsThrows(X) -#endif - -/* - * usage: epicsPlacementDeleteOperator (( void *, myMemoryManager & )) - */ -#if defined ( CXX_PLACEMENT_DELETE ) -# define epicsPlacementDeleteOperator(X) void operator delete X; -#else -# define epicsPlacementDeleteOperator(X) -#endif - -#endif /* __cplusplus */ - - -#ifndef EPICS_PRINTF_STYLE -/* - * No format-string checking - */ -# define EPICS_PRINTF_STYLE(f,a) -#endif - -#ifndef EPICS_DEPRECATED -/* - * No deprecation markers - */ -#define EPICS_DEPRECATED -#endif - -#ifndef EPICS_UNUSED -# define EPICS_UNUSED -#endif - -#ifndef EPICS_FUNCTION -#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)) || (defined(__cplusplus) && __cplusplus>=201103L) -# define EPICS_FUNCTION __func__ -#else -/* Expands to a 'const char*' which describes the name of the current function scope */ -# define EPICS_FUNCTION ("") -#endif -#endif - -#endif /* ifndef compilerDependencies_h */ diff --git a/src/libCom/osi/devLib.h b/src/libCom/osi/devLib.h deleted file mode 100644 index 729f9b932..000000000 --- a/src/libCom/osi/devLib.h +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devLib.h */ - -/* - * Original Author: Marty Kraimer - * Author: Jeff Hill - * Date: 03-10-93 - */ -#ifndef EPICSDEVLIB_H -#define EPICSDEVLIB_H - -/* - * Support macros - */ - -/* - * Normalize a digital value and convert it to type TYPE - * - * Ex: - * float f; - * int d; - * f = devNormalizeDigital(d,12) - * - */ -#define devCreateMask(NBITS) ((1<<(NBITS))-1) -#define devDigToNml(DIGITAL,NBITS) \ - (((double)(DIGITAL))/devCreateMask(NBITS)) -#define devNmlToDig(NORMAL,NBITS) \ - (((long)(NORMAL)) * devCreateMask(NBITS)) - -/* - * - * Alignment mask - * (for use when testing to see if the proper number of least - * significant bits are zero) - * - */ -#define devCreateAlignmentMask(CTYPE)\ -(sizeof(CTYPE)>sizeof(double)?sizeof(double)-1:sizeof(CTYPE)-1) - -/* - * pointer aligned test - * (returns true if the pointer is on the worst case alignemnt - * boundary for its type) - */ -#define devPtrAlignTest(PTR) (!(devCreateAlignmentMask(*PTR)&(long)(PTR))) - -/* - * error codes (and messages) associated with devLib.c - */ -#define S_dev_success 0 -#define S_dev_vectorInUse (M_devLib| 1) /*interrupt vector in use*/ -#define S_dev_vecInstlFail (M_devLib| 2) /*interrupt vector install failed*/ -#define S_dev_uknIntType (M_devLib| 3) /*Unrecognized interrupt type*/ -#define S_dev_vectorNotInUse (M_devLib| 4) /*Interrupt vector not in use by caller*/ -#define S_dev_badA16 (M_devLib| 5) /*Invalid VME A16 address*/ -#define S_dev_badA24 (M_devLib| 6) /*Invalid VME A24 address*/ -#define S_dev_badA32 (M_devLib| 7) /*Invalid VME A32 address*/ -#define S_dev_uknAddrType (M_devLib| 8) /*Unrecognized address space type*/ -#define S_dev_addressOverlap (M_devLib| 9) /*Specified device address overlaps another device*/ -#define S_dev_identifyOverlap (M_devLib| 10) /*This device already owns the address range*/ -#define S_dev_addrMapFail (M_devLib| 11) /*unable to map address*/ -#define S_dev_intDisconnect (M_devLib| 12) /*Interrupt at vector disconnected from an EPICS device*/ -#define S_dev_internal (M_devLib| 13) /*Internal failure*/ -#define S_dev_intEnFail (M_devLib| 14) /*unable to enable interrupt level*/ -#define S_dev_intDissFail (M_devLib| 15) /*unable to disable interrupt level*/ -#define S_dev_noMemory (M_devLib| 16) /*Memory allocation failed*/ -#define S_dev_addressNotFound (M_devLib| 17) /*Specified device address unregistered*/ -#define S_dev_noDevice (M_devLib| 18) /*No device at specified address*/ -#define S_dev_wrongDevice (M_devLib| 19) /*Wrong device type found at specified address*/ -#define S_dev_badSignalNumber (M_devLib| 20) /*Signal number (offset) to large*/ -#define S_dev_badSignalCount (M_devLib| 21) /*Signal count to large*/ -#define S_dev_badRequest (M_devLib| 22) /*Device does not support requested operation*/ -#define S_dev_highValue (M_devLib| 23) /*Parameter to high*/ -#define S_dev_lowValue (M_devLib| 24) /*Parameter to low*/ -#define S_dev_multDevice (M_devLib| 25) /*Specified address is ambiguous (more than one device responds)*/ -#define S_dev_badSelfTest (M_devLib| 26) /*Device self test failed*/ -#define S_dev_badInit (M_devLib| 27) /*Device failed during initialization*/ -#define S_dev_hdwLimit (M_devLib| 28) /*Input exceeds Hardware Limit*/ -#define S_dev_deviceDoesNotFit (M_devLib| 29) /*Unable to locate address space for device*/ -#define S_dev_deviceTMO (M_devLib| 30) /*device timed out*/ -#define S_dev_badFunction (M_devLib| 31) /*bad function pointer*/ -#define S_dev_badVector (M_devLib| 32) /*bad interrupt vector*/ -#define S_dev_badArgument (M_devLib| 33) /*bad function argument*/ -#define S_dev_badISA (M_devLib| 34) /*Invalid ISA address*/ -#define S_dev_badCRCSR (M_devLib| 35) /*Invalid VME CR/CSR address*/ -#define S_dev_vxWorksIntEnFail S_dev_intEnFail - - -#endif /* EPICSDEVLIB_H */ - -/* - * Retain compatibility by including VME by default - */ -#ifndef NO_DEVLIB_COMPAT -# include "devLibVME.h" -#endif diff --git a/src/libCom/osi/devLibVME.c b/src/libCom/osi/devLibVME.c deleted file mode 100644 index 6c7d93f99..000000000 --- a/src/libCom/osi/devLibVME.c +++ /dev/null @@ -1,1156 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devLib.c - support for allocation of common device resources */ - -/* - * Original Author: Marty Kraimer - * Author: Jeff Hill - * Date: 03-10-93 - * - * NOTES: - * .01 06-14-93 joh needs devAllocInterruptVector() routine - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "epicsMutex.h" -#include "errlog.h" -#include "ellLib.h" - -#define NO_DEVLIB_COMPAT -#include "devLibVME.h" -#include "devLibVMEImpl.h" - -static ELLLIST addrAlloc[atLast]; -static ELLLIST addrFree[atLast]; - -static size_t addrLast[atLast] = { - 0xffff, - 0xffffff, - 0xffffffff, - 0xffffff, - 0xffffff, - }; - -static unsigned addrHexDig[atLast] = { - 4, - 6, - 8, - 6, - 6 - }; - -static long addrFail[atLast] = { - S_dev_badA16, - S_dev_badA24, - S_dev_badA32, - S_dev_badISA, - S_dev_badCRCSR - }; - -static epicsMutexId addrListLock; -static char devLibInitFlag; - -const char *epicsAddressTypeName[] - = { - "VME A16", - "VME A24", - "VME A32", - "ISA", - "VME CR/CSR" - }; - -typedef struct{ - ELLNODE node; - const char *pOwnerName; - volatile void *pPhysical; - /* - * first, last is used here instead of base, size - * so that we can store a block that is the maximum size - * available in type size_t - */ - size_t begin; - size_t end; -}rangeItem; - -/* - * These routines are not exported - */ - -static long devLibInit(void); - -static long addrVerify( - epicsAddressType addrType, - size_t base, - size_t size); - -static long blockFind ( - epicsAddressType addrType, - const rangeItem *pRange, - /* size needed */ - size_t requestSize, - /* n ls bits zero in base addr */ - unsigned alignment, - /* base address found */ - size_t *pFirst); - -static void report_conflict( - epicsAddressType addrType, - size_t base, - size_t size, - const char *pOwnerName); - -static void report_conflict_device( - epicsAddressType addrType, - const rangeItem *pRange); - -static void devInsertAddress( - ELLLIST *pRangeList, - rangeItem *pNewRange); - -static long devListAddressMap( - ELLLIST *pRangeList); - -static long devCombineAdjacentBlocks( - ELLLIST *pRangeList, - rangeItem *pRange); - -static long devInstallAddr( - rangeItem *pRange, /* item on the free list to be split */ - const char *pOwnerName, - epicsAddressType addrType, - size_t base, - size_t size, - volatile void **ppPhysicalAddress); - -#define SUCCESS 0 - -/* - * devBusToLocalAddr() - */ -long devBusToLocalAddr( - epicsAddressType addrType, - size_t busAddr, - volatile void **ppLocalAddress) -{ - long status; - volatile void *localAddress; - - /* - * Make sure that devLib has been intialized - */ - if (!devLibInitFlag) { - status = devLibInit(); - if(status){ - return status; - } - } - - /* - * Make sure we have a valid bus address - */ - status = addrVerify (addrType, busAddr, 4); - if (status) { - return status; - } - - /* - * Call the virtual os routine to map the bus address to a CPU address - */ - status = (*pdevLibVME->pDevMapAddr) (addrType, 0, busAddr, 4, &localAddress); - if (status) { - errPrintf (status, __FILE__, __LINE__, "%s bus address =0X%X\n", - epicsAddressTypeName[addrType], (unsigned int)busAddr); - return status; - } - - /* - * Return the local CPU address if the pointer is supplied - */ - if (ppLocalAddress) { - *ppLocalAddress = localAddress; - } - - return SUCCESS; - -}/*end devBusToLocalAddr()*/ - - -/* - * devRegisterAddress() - */ -long devRegisterAddress( - const char *pOwnerName, - epicsAddressType addrType, - size_t base, - size_t size, - volatile void **ppPhysicalAddress) -{ - rangeItem *pRange; - long s; - - if (!devLibInitFlag) { - s = devLibInit(); - if(s){ - return s; - } - } - - s = addrVerify (addrType, base, size); - if (s) { - return s; - } - - if (size == 0) { - return S_dev_lowValue; - } - -#ifdef DEBUG - printf ("Req Addr 0X%X Size 0X%X\n", base, size); -#endif - - epicsMutexMustLock(addrListLock); - pRange = (rangeItem *) ellFirst(&addrFree[addrType]); - while (TRUE) { - if (pRange->begin > base) { - pRange = NULL; -# ifdef DEBUG - printf ("Unable to locate a free block\n"); - devListAddressMap (&addrFree[addrType]); -# endif - break; - } - else if (base + (size - 1) <= pRange->end) { -# ifdef DEBUG - printf ("Found free block Begin 0X%X End 0X%X\n", - pRange->begin, pRange->end); -# endif - break; - } - - pRange = (rangeItem *) ellNext (&pRange->node); - } - epicsMutexUnlock(addrListLock); - - if (pRange==NULL) { - report_conflict (addrType, base, size, pOwnerName); - return S_dev_addressOverlap; - } - - s = devInstallAddr( - pRange, /* item on the free list to be split */ - pOwnerName, - addrType, - base, - size, - ppPhysicalAddress); - - return s; -} - -/* - * devReadProbe() - * - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ -long devReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevReadProbe) (wordSize, ptr, pValue); -} - -/* - * devWriteProbe - * - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ -long devWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevWriteProbe) (wordSize, ptr, pValue); -} - -/* - * devInstallAddr() - */ -static long devInstallAddr ( - rangeItem *pRange, /* item on the free list to be split */ - const char *pOwnerName, - epicsAddressType addrType, - size_t base, - size_t size, - volatile void **ppPhysicalAddress) -{ - volatile void *pPhysicalAddress; - rangeItem *pNewRange; - size_t reqEnd = base + (size-1); - long status; - - /* - * does it start below the specified block - */ - if (base < pRange->begin) { - return S_dev_badArgument; - } - - /* - * does it end above the specified block - */ - if (reqEnd > pRange->end) { - return S_dev_badArgument; - } - - /* - * always map through the virtual os in case the memory - * management is set up there - */ - status = (*pdevLibVME->pDevMapAddr) (addrType, 0, base, - size, &pPhysicalAddress); - if (status) { - errPrintf (status, __FILE__, __LINE__, "%s base=0X%X size = 0X%X", - epicsAddressTypeName[addrType], (unsigned int)base, (unsigned int)size); - return status; - } - - /* - * set the callers variable if the pointer is supplied - */ - if (ppPhysicalAddress) { - *ppPhysicalAddress = pPhysicalAddress; - } - - /* - * does it start at the beginning of the block - */ - if (pRange->begin == base) { - if (pRange->end == reqEnd) { - epicsMutexMustLock(addrListLock); - ellDelete(&addrFree[addrType], &pRange->node); - epicsMutexUnlock(addrListLock); - free ((void *)pRange); - } - else { - pRange->begin = base + size; - } - } - /* - * does it end at the end of the block - */ - else if (pRange->end == reqEnd) { - pRange->end = base-1; - } - /* - * otherwise split the item on the free list - */ - else { - - pNewRange = (rangeItem *) calloc (1, sizeof(*pRange)); - if(!pNewRange){ - return S_dev_noMemory; - } - - pNewRange->begin = base + size; - pNewRange->end = pRange->end; - pNewRange->pOwnerName = ""; - pNewRange->pPhysical = NULL; - pRange->end = base - 1; - - /* - * add the node after the old item on the free list - * (blocks end up ordered by address) - */ - epicsMutexMustLock(addrListLock); - ellInsert(&addrFree[addrType], &pRange->node, &pNewRange->node); - epicsMutexUnlock(addrListLock); - } - - /* - * allocate a new address range entry and add it to - * the list - */ - pNewRange = (rangeItem *)calloc (1, sizeof(*pRange)); - if (!pNewRange) { - return S_dev_noMemory; - } - - pNewRange->begin = base; - pNewRange->end = reqEnd; - pNewRange->pOwnerName = pOwnerName; - pNewRange->pPhysical = pPhysicalAddress; - - devInsertAddress (&addrAlloc[addrType], pNewRange); - - return SUCCESS; -} - -/* - * report_conflict() - */ -static void report_conflict ( - epicsAddressType addrType, - size_t base, - size_t size, - const char *pOwnerName -) -{ - const rangeItem *pRange; - - errPrintf ( - S_dev_addressOverlap, - __FILE__, - __LINE__, - "%10s 0X%08X - OX%08X Requested by %s", - epicsAddressTypeName[addrType], - (unsigned int)base, - (unsigned int)(base+size-1), - pOwnerName); - - pRange = (rangeItem *) ellFirst(&addrAlloc[addrType]); - while (pRange) { - - if (pRange->begin <= base + (size-1) && pRange->end >= base) { - report_conflict_device (addrType, pRange); - } - - pRange = (rangeItem *) pRange->node.next; - } -} - -/* - * report_conflict_device() - */ -static void report_conflict_device(epicsAddressType addrType, const rangeItem *pRange) -{ - errPrintf ( - S_dev_identifyOverlap, - __FILE__, - __LINE__, - "%10s 0X%08X - 0X%08X Owned by %s", - epicsAddressTypeName[addrType], - (unsigned int)pRange->begin, - (unsigned int)pRange->end, - pRange->pOwnerName); -} - -/* - * devUnregisterAddress() - */ -long devUnregisterAddress( - epicsAddressType addrType, - size_t baseAddress, - const char *pOwnerName) -{ - rangeItem *pRange; - int s; - - if (!devLibInitFlag) { - s = devLibInit(); - if(s) { - return s; - } - } - - s = addrVerify (addrType, baseAddress, 1); - if (s != SUCCESS) { - return s; - } - - epicsMutexMustLock(addrListLock); - pRange = (rangeItem *) ellFirst(&addrAlloc[addrType]); - while (pRange) { - if (pRange->begin == baseAddress) { - break; - } - if (pRange->begin > baseAddress) { - pRange = NULL; - break; - } - pRange = (rangeItem *) ellNext(&pRange->node); - } - epicsMutexUnlock(addrListLock); - - if (!pRange) { - return S_dev_addressNotFound; - } - - if (strcmp(pOwnerName,pRange->pOwnerName)) { - s = S_dev_addressOverlap; - errPrintf ( - s, - __FILE__, - __LINE__, - "unregister address for %s at 0X%X failed because %s owns it", - pOwnerName, - (unsigned int)baseAddress, - pRange->pOwnerName); - return s; - } - - epicsMutexMustLock(addrListLock); - ellDelete (&addrAlloc[addrType], &pRange->node); - epicsMutexUnlock(addrListLock); - - pRange->pOwnerName = ""; - devInsertAddress (&addrFree[addrType], pRange); - s = devCombineAdjacentBlocks (&addrFree[addrType], pRange); - if(s){ - errMessage (s, "devCombineAdjacentBlocks error"); - return s; - } - - return SUCCESS; -} - -/* - * devCombineAdjacentBlocks() - */ -static long devCombineAdjacentBlocks( - ELLLIST *pRangeList, - rangeItem *pRange) -{ - rangeItem *pBefore; - rangeItem *pAfter; - - pBefore = (rangeItem *) ellPrevious (&pRange->node); - pAfter = (rangeItem *) ellNext (&pRange->node); - - /* - * combine adjacent blocks - */ - if (pBefore) { - if (pBefore->end == pRange->begin-1) { - epicsMutexMustLock(addrListLock); - pRange->begin = pBefore->begin; - ellDelete (pRangeList, &pBefore->node); - epicsMutexUnlock(addrListLock); - free ((void *)pBefore); - } - } - - if (pAfter) { - if (pAfter->begin == pRange->end+1) { - epicsMutexMustLock(addrListLock); - pRange->end = pAfter->end; - ellDelete (pRangeList, &pAfter->node); - epicsMutexUnlock(addrListLock); - free((void *)pAfter); - } - } - - return SUCCESS; -} - -/* - * devInsertAddress() - */ -static void devInsertAddress( -ELLLIST *pRangeList, -rangeItem *pNewRange) -{ - rangeItem *pBefore; - rangeItem *pAfter; - - epicsMutexMustLock(addrListLock); - pAfter = (rangeItem *) ellFirst (pRangeList); - while (pAfter) { - if (pNewRange->end < pAfter->begin) { - break; - } - pAfter = (rangeItem *) ellNext (&pAfter->node); - } - - if (pAfter) { - pBefore = (rangeItem *) ellPrevious (&pAfter->node); - ellInsert (pRangeList, &pBefore->node, &pNewRange->node); - } - else { - ellAdd (pRangeList, &pNewRange->node); - } - epicsMutexUnlock(addrListLock); -} - -/* - * devAllocAddress() - */ -long devAllocAddress( - const char *pOwnerName, - epicsAddressType addrType, - size_t size, - unsigned alignment, /* n ls bits zero in base addr*/ - volatile void ** pLocalAddress ) -{ - int s; - rangeItem *pRange; - size_t base = 0; - - if (!devLibInitFlag) { - s = devLibInit(); - if(s){ - return s; - } - } - - s = addrVerify (addrType, 0, size); - if(s){ - return s; - } - - if (size == 0) { - return S_dev_lowValue; - } - - epicsMutexMustLock(addrListLock); - pRange = (rangeItem *) ellFirst (&addrFree[addrType]); - while (pRange) { - if ((pRange->end - pRange->begin) + 1 >= size){ - s = blockFind ( - addrType, - pRange, - size, - alignment, - &base); - if (s==SUCCESS) { - break; - } - } - pRange = (rangeItem *) pRange->node.next; - } - epicsMutexUnlock(addrListLock); - - if(!pRange){ - s = S_dev_deviceDoesNotFit; - errMessage(s, epicsAddressTypeName[addrType]); - return s; - } - - s = devInstallAddr (pRange, pOwnerName, addrType, base, - size, pLocalAddress); - - return s; -} - -/* - * addrVerify() - * - * care has been taken here not to overflow type size_t - */ -static long addrVerify(epicsAddressType addrType, size_t base, size_t size) -{ - if (addrType>=atLast) { - return S_dev_uknAddrType; - } - - if (size == 0) { - return addrFail[addrType]; - } - - if (size-1 > addrLast[addrType]) { - return addrFail[addrType]; - } - - if (base > addrLast[addrType]) { - return addrFail[addrType]; - } - - if (size - 1 > addrLast[addrType] - base) { - return addrFail[addrType]; - } - - return SUCCESS; -} - -/* - * devLibInit() - */ -static long devLibInit (void) -{ - rangeItem *pRange; - int i; - - - if(devLibInitFlag) return(SUCCESS); - if(!pdevLibVME) { - epicsPrintf ("pdevLibVME is NULL\n"); - return S_dev_internal; - } - - if (NELEMENTS(addrAlloc) != NELEMENTS(addrFree)) { - return S_dev_internal; - } - - addrListLock = epicsMutexMustCreate(); - - epicsMutexMustLock(addrListLock); - for (i=0; ipOwnerName = ""; - pRange->pPhysical = NULL; - pRange->begin = 0; - pRange->end = addrLast[i]; - ellAdd (&addrFree[i], &pRange->node); - } - epicsMutexUnlock(addrListLock); - devLibInitFlag = TRUE; - return pdevLibVME->pDevInit(); -} - -/* - * devAddressMap() - */ -long devAddressMap(void) -{ - return devListAddressMap(addrAlloc); -} - -/* - * devListAddressMap() - */ -static long devListAddressMap(ELLLIST *pRangeList) -{ - rangeItem *pri; - int i; - long s; - - if (!devLibInitFlag) { - s = devLibInit (); - if (s) { - return s; - } - } - - epicsMutexMustLock(addrListLock); - for (i=0; ibegin, - addrHexDig[i], - (unsigned long) pri->end, - pri->pPhysical, - pri->pOwnerName); - pri = (rangeItem *) ellNext (&pri->node); - } - } - epicsMutexUnlock(addrListLock); - - return SUCCESS; -} - - -/* - * - * blockFind() - * - * Find unoccupied block in a large block - * - */ -static long blockFind ( - epicsAddressType addrType, - const rangeItem *pRange, - /* size needed */ - size_t requestSize, - /* n ls bits zero in base addr */ - unsigned alignment, - /* base address found */ - size_t *pBase) -{ - int s = SUCCESS; - size_t bb; - size_t mask; - size_t newBase; - size_t newSize; - - /* - * align the block base - */ - mask = devCreateMask (alignment); - newBase = pRange->begin; - if ( mask & newBase ) { - newBase |= mask; - newBase++; - } - - if ( requestSize == 0) { - return S_dev_badRequest; - } - - /* - * align size of block - */ - newSize = requestSize; - if (mask & newSize) { - newSize |= mask; - newSize++; - } - - if (pRange->end - pRange->begin + 1 < newSize) { - return S_dev_badRequest; - } - - bb = pRange->begin; - while (bb <= (pRange->end + 1) - newSize) { - s = devNoResponseProbe (addrType, bb, newSize); - if (s==SUCCESS) { - *pBase = bb; - return SUCCESS; - } - bb += newSize; - } - - return s; -} - -/* - * devNoResponseProbe() - */ -long devNoResponseProbe (epicsAddressType addrType, - size_t base, size_t size) -{ - volatile void *pPhysical; - size_t probe; - size_t byteNo; - unsigned wordSize; - union { - char charWord; - short shortWord; - int intWord; - long longWord; - }allWordSizes; - long s; - - if (!devLibInitFlag) { - s = devLibInit(); - if (s) { - return s; - } - } - - byteNo = 0; - while (byteNo < size) { - - probe = base + byteNo; - - /* - * for all word sizes - */ - for (wordSize=1; wordSize<=sizeof(allWordSizes); wordSize <<= 1) { - /* - * only check naturally aligned words - */ - if ( (probe&(wordSize-1)) != 0 ) { - break; - } - - if (byteNo+wordSize>size) { - break; - } - - /* - * every byte in the block must - * map to a physical address - */ - s = (*pdevLibVME->pDevMapAddr) (addrType, 0, probe, wordSize, &pPhysical); - if (s!=SUCCESS) { - return s; - } - - /* - * verify that no device is present - */ - s = (*pdevLibVME->pDevReadProbe)(wordSize, pPhysical, &allWordSizes); - if (s==SUCCESS) { - return S_dev_addressOverlap; - } - } - byteNo++; - } - return SUCCESS; -} - -long devConnectInterruptVME( -unsigned vectorNumber, -void (*pFunction)(void *), -void *parameter ) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevConnectInterruptVME) (vectorNumber, - pFunction, parameter); -} - -long devDisconnectInterruptVME( -unsigned vectorNumber, -void (*pFunction)(void *) ) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevDisconnectInterruptVME) (vectorNumber, pFunction); -} - -int devInterruptInUseVME (unsigned level) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevInterruptInUseVME) (level); -} - -long devEnableInterruptLevelVME (unsigned level) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevEnableInterruptLevelVME) (level); -} - -long devDisableInterruptLevelVME (unsigned level) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevDisableInterruptLevelVME) (level); -} - -/* - * devConnectInterrupt () - * - * !! DEPRECATED !! - */ -long devConnectInterrupt( -epicsInterruptType intType, -unsigned vectorNumber, -void (*pFunction)(void *), -void *parameter) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - switch(intType){ - case intVME: - case intVXI: - return (*pdevLibVME->pDevConnectInterruptVME) (vectorNumber, - pFunction, parameter); - default: - return S_dev_uknIntType; - } -} - -/* - * - * devDisconnectInterrupt() - * - * !! DEPRECATED !! - */ -long devDisconnectInterrupt( -epicsInterruptType intType, -unsigned vectorNumber, -void (*pFunction)(void *) -) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - switch(intType){ - case intVME: - case intVXI: - return (*pdevLibVME->pDevDisconnectInterruptVME) (vectorNumber, - pFunction); - default: - return S_dev_uknIntType; - } -} - -/* - * devEnableInterruptLevel() - * - * !! DEPRECATED !! - */ -long devEnableInterruptLevel( -epicsInterruptType intType, -unsigned level) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - switch(intType){ - case intVME: - case intVXI: - return (*pdevLibVME->pDevEnableInterruptLevelVME) (level); - default: - return S_dev_uknIntType; - } -} - -/* - * devDisableInterruptLevel() - * - * !! DEPRECATED !! - */ -long devDisableInterruptLevel ( -epicsInterruptType intType, -unsigned level) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - switch(intType){ - case intVME: - case intVXI: - return (*pdevLibVME->pDevDisableInterruptLevelVME) (level); - default: - return S_dev_uknIntType; - } -} - -/* - * locationProbe - * - * !! DEPRECATED !! - */ -long locationProbe (epicsAddressType addrType, char *pLocation) -{ - return devNoResponseProbe (addrType, (size_t) pLocation, sizeof(long)); -} - -/****************************************************************************** - * - * The follwing may, or may not be present in the BSP for the CPU in use. - * - */ -/****************************************************************************** - * - * Routines to use to allocate and free memory present in the A24 region. - * - ******************************************************************************/ - -int devLibA24Debug = 0; /* Debugging flag */ - -void *devLibA24Calloc(size_t size) -{ - void *ret; - - ret = devLibA24Malloc(size); - - if (ret == NULL) - return (NULL); - - memset(ret, 0x00, size); - return(ret); -} - -void *devLibA24Malloc(size_t size) -{ - void *ret; - - if (devLibA24Debug) - epicsPrintf ("devLibA24Malloc(%u) entered\n", (unsigned int)size); - - ret = pdevLibVME->pDevA24Malloc(size); - return(ret); -} - -void devLibA24Free(void *pBlock) -{ - if (devLibA24Debug) - epicsPrintf("devLibA24Free(%p) entered\n", pBlock); - - pdevLibVME->pDevA24Free(pBlock); -} diff --git a/src/libCom/osi/devLibVME.h b/src/libCom/osi/devLibVME.h deleted file mode 100644 index 4fb17f0c2..000000000 --- a/src/libCom/osi/devLibVME.h +++ /dev/null @@ -1,306 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devLib.h */ - -/* - * Original Author: Marty Kraimer - * Author: Jeff Hill - * Date: 03-10-93 - */ - -#ifndef INCdevLibh -#define INCdevLibh 1 - -#include "dbDefs.h" -#include "osdVME.h" -#include "errMdef.h" -#include "shareLib.h" -#include "devLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * epdevAddressType & EPICStovxWorksAddrType - * devLib.c must change in unison - */ -typedef enum { - atVMEA16, - atVMEA24, - atVMEA32, - atISA, /* memory mapped ISA access (until now only on PC) */ - atVMECSR, /* VME-64 CR/CSR address space */ - atLast /* atLast must be the last enum in this list */ - } epicsAddressType; - -/* - * pointer to an array of strings for each of - * the above address types - */ -epicsShareExtern const char *epicsAddressTypeName[]; - -#ifdef __cplusplus -} -#endif - -/* - * To retain compatibility include everything by default - */ -#ifndef NO_DEVLIB_COMPAT -# include "devLibVMEImpl.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * General API - * - * This section applies to all bus types - */ - -epicsShareFunc long devAddressMap(void); /* print an address map */ - -/* - * devBusToLocalAddr() - * - * OSI routine to translate bus addresses their local CPU address mapping - */ -epicsShareFunc long devBusToLocalAddr ( - epicsAddressType addrType, - size_t busAddr, - volatile void **ppLocalAddr); -/* - * devReadProbe() - * - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ -epicsShareFunc long devReadProbe ( - unsigned wordSize, volatile const void *ptr, void *pValueRead); - -/* - * devNoResponseProbe() - * - * Verifies that no devices respond at naturally aligned words - * within the specified address range. Return success if no devices - * respond. Returns an error if a device does respond or if - * a physical address for a naturally aligned word cant be mapped. - * Checks all naturally aligned word sizes between char and long for - * the entire specified range of bytes. - */ -epicsShareFunc long devNoResponseProbe( - epicsAddressType addrType, - size_t base, - size_t size -); - -/* - * devWriteProbe - * - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ -epicsShareFunc long devWriteProbe ( - unsigned wordSize, volatile void *ptr, const void *pValueWritten); - -epicsShareFunc long devRegisterAddress( - const char *pOwnerName, - epicsAddressType addrType, - size_t logicalBaseAddress, - size_t size, /* bytes */ - volatile void **pPhysicalAddress); - -epicsShareFunc long devUnregisterAddress( - epicsAddressType addrType, - size_t logicalBaseAddress, - const char *pOwnerName); - -/* - * allocate and register an unoccupied address block - */ -epicsShareFunc long devAllocAddress( - const char *pOwnerName, - epicsAddressType addrType, - size_t size, - unsigned alignment, /*n ls bits zero in addr*/ - volatile void **pLocalAddress); - -/* - * VME API - * - * Functions in this section apply only to the VME bus type - */ - -/* - * connect ISR to a VME interrupt vector - */ -epicsShareFunc long devConnectInterruptVME( - unsigned vectorNumber, - void (*pFunction)(void *), - void *parameter); - -/* - * disconnect ISR from a VME interrupt vector - * - * The parameter pFunction should be set to the C function pointer that - * was connected. It is used as a key to prevent a driver from inadvertently - * removing an interrupt handler that it didn't install - */ -epicsShareFunc long devDisconnectInterruptVME( - unsigned vectorNumber, - void (*pFunction)(void *)); - -/* - * determine if a VME interrupt vector is in use - * - * returns boolean - */ -epicsShareFunc int devInterruptInUseVME (unsigned vectorNumber); - -/* - * enable VME interrupt level - */ -epicsShareFunc long devEnableInterruptLevelVME (unsigned level); - -/* - * disable VME interrupt level - */ -epicsShareFunc long devDisableInterruptLevelVME (unsigned level); - -/* - * Routines to allocate and free memory in the A24 memory region. - * - */ -epicsShareFunc void *devLibA24Malloc(size_t); -epicsShareFunc void *devLibA24Calloc(size_t); -epicsShareFunc void devLibA24Free(void *pBlock); - -/* - * ISA API - * - * Functions in this section apply only to the ISA bus type - */ - -/* - * connect ISR to an ISA interrupt level - * (not implemented) - * (API should be reviewed) - */ -epicsShareFunc long devConnectInterruptISA( - unsigned interruptLevel, - void (*pFunction)(void *), - void *parameter); - -/* - * disconnect ISR from an ISA interrupt level - * (not implemented) - * (API should be reviewed) - * - * The parameter pFunction should be set to the C function pointer that - * was connected. It is used as a key to prevent a driver from inadvertently - * removing an interrupt handler that it didn't install - */ -epicsShareFunc long devDisconnectInterruptISA( - unsigned interruptLevel, - void (*pFunction)(void *)); - -/* - * determine if an ISA interrupt level is in use - * (not implemented) - * - * returns boolean - */ -epicsShareFunc int devInterruptLevelInUseISA (unsigned interruptLevel); - -/* - * enable ISA interrupt level - */ -epicsShareFunc long devEnableInterruptLevelISA (unsigned level); - -/* - * disable ISA interrupt level - */ -epicsShareFunc long devDisableInterruptLevelISA (unsigned level); - -/* - * Deprecated interface - */ - -#ifndef NO_DEVLIB_OLD_INTERFACE - -typedef enum {intVME, intVXI, intISA} epicsInterruptType; - -/* - * NOTE: this routine has been deprecated. It exists - * for backwards compatibility purposes only. - * - * Please use one of devConnectInterruptVME, devConnectInterruptPCI, - * devConnectInterruptISA etc. devConnectInterrupt will be removed - * in a future release. - */ -epicsShareFunc long devConnectInterrupt( - epicsInterruptType intType, - unsigned vectorNumber, - void (*pFunction)(void *), - void *parameter); - -/* - * NOTE: this routine has been deprecated. It exists - * for backwards compatibility purposes only. - * - * Please use one of devDisconnectInterruptVME, devDisconnectInterruptPCI, - * devDisconnectInterruptISA etc. devDisconnectInterrupt will be removed - * in a future release. - */ -epicsShareFunc long devDisconnectInterrupt( - epicsInterruptType intType, - unsigned vectorNumber, - void (*pFunction)(void *)); - -/* - * NOTE: this routine has been deprecated. It exists - * for backwards compatibility purposes only. - * - * Please use one of devEnableInterruptLevelVME, devEnableInterruptLevelPCI, - * devEnableInterruptLevelISA etc. devEnableInterruptLevel will be removed - * in a future release. - */ -epicsShareFunc long devEnableInterruptLevel( - epicsInterruptType intType, unsigned level); - -/* - * NOTE: this routine has been deprecated. It exists - * for backwards compatibility purposes only. - * - * Please use one of devDisableInterruptLevelVME, devDisableInterruptLevelISA, - * devDisableInterruptLevelPCI etc. devDisableInterruptLevel will be removed - * in a future release. - */ -epicsShareFunc long devDisableInterruptLevel ( - epicsInterruptType intType, unsigned level); - -/* - * NOTE: this routine has been deprecated. It exists - * for backwards compatibility purposes only. - * - * Please use devNoResponseProbe(). locationProbe() will be removed - * in a future release. - */ -epicsShareFunc long locationProbe (epicsAddressType addrType, char *pLocation); - -#endif /* NO_DEVLIB_OLD_INTERFACE */ - -#ifdef __cplusplus -} -#endif - -#endif /* INCdevLibh.h*/ diff --git a/src/libCom/osi/devLibVMEImpl.h b/src/libCom/osi/devLibVMEImpl.h deleted file mode 100644 index e479d869c..000000000 --- a/src/libCom/osi/devLibVMEImpl.h +++ /dev/null @@ -1,104 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devLibImpl.h */ - -/* - * Original Author: Marty Kraimer - * Author: Jeff Hill - * Date: 03-10-93 - */ - -#ifndef INCdevLibImplh -#define INCdevLibImplh 1 - -#include "dbDefs.h" -#include "shareLib.h" -#include "devLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * virtual OS layer for devLib.c - * - * The global virtual OS table pdevLibVME controls - * the behaviour of the functions defined in devLib.h. - * All of which call into the functions found in this table - * to perform system specific tasks. - */ -typedef struct devLibVME { - /* - * maps logical address to physical address, but does not detect - * two device drivers that are using the same address range - */ - long (*pDevMapAddr) (epicsAddressType addrType, unsigned options, - size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress); - - /* - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ - long (*pDevReadProbe) (unsigned wordSize, volatile const void *ptr, void *pValueRead); - - /* - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ - long (*pDevWriteProbe) (unsigned wordSize, volatile void *ptr, const void *pValueWritten); - - /* - * connect ISR to a VME interrupt vector - * (required for backwards compatibility) - */ - long (*pDevConnectInterruptVME) (unsigned vectorNumber, - void (*pFunction)(void *), void *parameter); - - /* - * disconnect ISR from a VME interrupt vector - * (required for backwards compatibility) - */ - long (*pDevDisconnectInterruptVME) (unsigned vectorNumber, - void (*pFunction)(void *)); - - /* - * enable VME interrupt level - */ - long (*pDevEnableInterruptLevelVME) (unsigned level); - - /* - * disable VME interrupt level - */ - long (*pDevDisableInterruptLevelVME) (unsigned level); - /* malloc/free A24 address space */ - void *(*pDevA24Malloc)(size_t nbytes); - void (*pDevA24Free)(void *pBlock); - long (*pDevInit)(void); - - /* - * test if VME interrupt has an ISR connected - */ - int (*pDevInterruptInUseVME) (unsigned vectorNumber); -}devLibVME; - -epicsShareExtern devLibVME *pdevLibVME; - -#ifndef NO_DEVLIB_COMPAT -# define pdevLibVirtualOS pdevLibVME -typedef devLibVME devLibVirtualOS; -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* INCdevLibImplh */ diff --git a/src/libCom/osi/epicsAssert.h b/src/libCom/osi/epicsAssert.h deleted file mode 100644 index 6f83d3a82..000000000 --- a/src/libCom/osi/epicsAssert.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * EPICS assert - * - * Author: Jeffrey O. Hill - * Date: 022795 - */ - -#ifndef INC_epicsAssert_H -#define INC_epicsAssert_H - -#include "shareLib.h" -#include "compilerDependencies.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifndef epicsAssertAuthor -# define epicsAssertAuthor 0 -#endif - -#undef assert - -#ifdef NDEBUG -# define assert(ignore) ((void) 0) -#else /* NDEBUG */ - -epicsShareFunc void epicsAssert (const char *pFile, const unsigned line, - const char *pExp, const char *pAuthorName); - -# define assert(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -#endif /* NDEBUG */ - - -/* Compile-time checks */ -#if __cplusplus>=201103L -#define STATIC_ASSERT(expr) static_assert(expr, #expr) -#else -#define STATIC_JOIN(x, y) STATIC_JOIN2(x, y) -#define STATIC_JOIN2(x, y) x ## y -#define STATIC_ASSERT(expr) \ - typedef int STATIC_JOIN(static_assert_failed_at_line_, __LINE__) \ - [ (expr) ? 1 : -1 ] EPICS_UNUSED -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsAssert_H */ diff --git a/src/libCom/osi/epicsAtomic.h b/src/libCom/osi/epicsAtomic.h deleted file mode 100644 index b3aad5c9c..000000000 --- a/src/libCom/osi/epicsAtomic.h +++ /dev/null @@ -1,217 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomic_h -#define epicsAtomic_h - -#include /* define size_t */ - -#include "compilerSpecific.h" - -#define EPICS_ATOMIC_INLINE static EPICS_ALWAYS_INLINE - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void * EpicsAtomicPtrT; - -/* load target into cache */ -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void); - -/* push cache version of target into target */ -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void); - -/* - * lock out other smp processors from accessing the target, - * load target into cache, add one to target, flush cache - * to target, allow other smp processors to access the target, - * return new value of target as modified by this operation - */ -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ); -EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget ); - -/* - * lock out other smp processors from accessing the target, - * load target into cache, subtract one from target, flush cache - * to target, allow out other smp processors to access the target, - * return new value of target as modified by this operation - */ -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ); -EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget ); - -/* - * lock out other smp processors from accessing the target, - * load target into cache, add/sub delta to/from target, flush cache - * to target, allow other smp processors to access the target, - * return new value of target as modified by this operation - */ -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta ); -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta ); -EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta ); - -/* - * set cache version of target, flush cache to target - */ -EPICS_ATOMIC_INLINE void epicsAtomicSetSizeT ( size_t * pTarget, size_t newValue ); -EPICS_ATOMIC_INLINE void epicsAtomicSetIntT ( int * pTarget, int newValue ); -EPICS_ATOMIC_INLINE void epicsAtomicSetPtrT ( EpicsAtomicPtrT * pTarget, EpicsAtomicPtrT newValue ); - -/* - * fetch target into cache, return new value of target - */ -EPICS_ATOMIC_INLINE size_t epicsAtomicGetSizeT ( const size_t * pTarget ); -EPICS_ATOMIC_INLINE int epicsAtomicGetIntT ( const int * pTarget ); -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicGetPtrT ( const EpicsAtomicPtrT * pTarget ); - -/* - * lock out other smp processors from accessing the target, - * load target into cache, if target is equal to oldVal set target - * to newVal, flush cache to target, allow other smp processors - * to access the target, return the original value stored in the - * target - */ -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget, - size_t oldVal, size_t newVal ); -EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget, - int oldVal, int newVal ); -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( - EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldVal, - EpicsAtomicPtrT newVal ); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -/* - * options for in-line compiler intrinsic or OS specific - * implementations of the above function prototypes - * - * for some of the compilers we must define the - * in-line functions before they get used in the c++ - * in-line functions below - */ -#include "epicsAtomicCD.h" - -#ifdef __cplusplus - -namespace epics { -namespace atomic { - -/* - * overloaded c++ interface - */ - -/************* incr ***************/ -EPICS_ATOMIC_INLINE size_t increment ( size_t & v ) -{ - return epicsAtomicIncrSizeT ( & v ); -} - -EPICS_ATOMIC_INLINE int increment ( int & v ) -{ - return epicsAtomicIncrIntT ( & v ); -} - -/************* decr ***************/ -EPICS_ATOMIC_INLINE size_t decrement ( size_t & v ) -{ - return epicsAtomicDecrSizeT ( & v ); -} - -EPICS_ATOMIC_INLINE int decrement ( int & v ) -{ - return epicsAtomicDecrIntT ( & v ); -} - -/************* add ***************/ -EPICS_ATOMIC_INLINE size_t add ( size_t & v, size_t delta ) -{ - return epicsAtomicAddSizeT ( & v, delta ); -} - -EPICS_ATOMIC_INLINE int add ( int & v, int delta ) -{ - return epicsAtomicAddIntT ( & v, delta ); -} - -/************* sub ***************/ -EPICS_ATOMIC_INLINE size_t subtract ( size_t & v, size_t delta ) -{ - return epicsAtomicSubSizeT ( & v, delta ); -} - -EPICS_ATOMIC_INLINE int subtract ( int & v, int delta ) -{ - return epicsAtomicAddIntT ( & v, -delta ); -} - -/************* set ***************/ -EPICS_ATOMIC_INLINE void set ( size_t & v , size_t newValue ) -{ - epicsAtomicSetSizeT ( & v, newValue ); -} - -EPICS_ATOMIC_INLINE void set ( int & v, int newValue ) -{ - epicsAtomicSetIntT ( & v, newValue ); -} - -EPICS_ATOMIC_INLINE void set ( EpicsAtomicPtrT & v, EpicsAtomicPtrT newValue ) -{ - epicsAtomicSetPtrT ( & v, newValue ); -} - -/************* get ***************/ -EPICS_ATOMIC_INLINE size_t get ( const size_t & v ) -{ - return epicsAtomicGetSizeT ( & v ); -} - -EPICS_ATOMIC_INLINE int get ( const int & v ) -{ - return epicsAtomicGetIntT ( & v ); -} - -EPICS_ATOMIC_INLINE EpicsAtomicPtrT get ( const EpicsAtomicPtrT & v ) -{ - return epicsAtomicGetPtrT ( & v ); -} - -/************* cas ***************/ -EPICS_ATOMIC_INLINE size_t compareAndSwap ( size_t & v, - size_t oldVal, size_t newVal ) -{ - return epicsAtomicCmpAndSwapSizeT ( & v, oldVal, newVal ); -} - -EPICS_ATOMIC_INLINE int compareAndSwap ( int & v, int oldVal, int newVal ) -{ - return epicsAtomicCmpAndSwapIntT ( & v, oldVal, newVal ); -} - -EPICS_ATOMIC_INLINE EpicsAtomicPtrT compareAndSwap ( EpicsAtomicPtrT & v, - EpicsAtomicPtrT oldVal, - EpicsAtomicPtrT newVal ) -{ - return epicsAtomicCmpAndSwapPtrT ( & v, oldVal, newVal ); -} - -} /* end of name space atomic */ -} /* end of name space epics */ - -#endif /* ifdef __cplusplus */ - -#endif /* epicsAtomic_h */ diff --git a/src/libCom/osi/epicsAtomicDefault.h b/src/libCom/osi/epicsAtomicDefault.h deleted file mode 100644 index 26115ce63..000000000 --- a/src/libCom/osi/epicsAtomicDefault.h +++ /dev/null @@ -1,247 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicDefault_h -#define epicsAtomicDefault_h - -#ifdef __cpluplus -extern "C" { -#endif - -/* - * struct EpicsAtomicLockKey; - * epicsShareFunc void epicsAtomicReadMemoryBarrier (); - * epicsShareFunc void epicsAtomicWriteMemoryBarrier (); - * epicsShareFunc void epicsAtomicLock ( struct EpicsAtomicLockKey * ); - * epicsShareFunc void epicsAtomicUnock ( struct EpicsAtomicLockKey * ); - */ - -/* - * incr - */ -#ifndef EPICS_ATOMIC_INCR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget ) -{ - EpicsAtomicLockKey key; - int result; - - epicsAtomicLock ( & key ); - result = ++(*pTarget); - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -#ifndef EPICS_ATOMIC_INCR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ) -{ - EpicsAtomicLockKey key; - size_t result; - - epicsAtomicLock ( & key ); - result = ++(*pTarget); - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -/* - * decr - */ -#ifndef EPICS_ATOMIC_DECR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget ) -{ - EpicsAtomicLockKey key; - int result; - - epicsAtomicLock ( & key ); - result = --(*pTarget); - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -#ifndef EPICS_ATOMIC_DECR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ) -{ - EpicsAtomicLockKey key; - size_t result; - - epicsAtomicLock ( & key ); - result = --(*pTarget); - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -/* - * add/sub - */ -#ifndef EPICS_ATOMIC_ADD_INTT -EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta ) -{ - EpicsAtomicLockKey key; - int result; - - epicsAtomicLock ( & key ); - result = *pTarget += delta; - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -#ifndef EPICS_ATOMIC_ADD_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta ) -{ - EpicsAtomicLockKey key; - size_t result; - - epicsAtomicLock ( & key ); - result = *pTarget += delta; - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -#ifndef EPICS_ATOMIC_SUB_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta ) -{ - EpicsAtomicLockKey key; - size_t result; - - epicsAtomicLock ( & key ); - result = *pTarget -= delta; - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -/* - * set - */ -#ifndef EPICS_ATOMIC_SET_INTT -EPICS_ATOMIC_INLINE void epicsAtomicSetIntT ( int * pTarget, int newVal ) -{ - *pTarget = newVal; - epicsAtomicWriteMemoryBarrier (); -} -#endif - -#ifndef EPICS_ATOMIC_SET_SIZET -EPICS_ATOMIC_INLINE void epicsAtomicSetSizeT ( size_t * pTarget, size_t newVal ) -{ - *pTarget = newVal; - epicsAtomicWriteMemoryBarrier (); -} -#endif - -#ifndef EPICS_ATOMIC_SET_PTRT -EPICS_ATOMIC_INLINE void epicsAtomicSetPtrT ( EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT newVal ) -{ - *pTarget = newVal; - epicsAtomicWriteMemoryBarrier (); -} -#endif - -/* - * get - */ -#ifndef EPICS_ATOMIC_GET_INTT -EPICS_ATOMIC_INLINE int epicsAtomicGetIntT ( const int * pTarget ) -{ - epicsAtomicReadMemoryBarrier (); - return *pTarget; -} -#endif - -#ifndef EPICS_ATOMIC_GET_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicGetSizeT ( const size_t * pTarget ) -{ - epicsAtomicReadMemoryBarrier (); - return *pTarget; -} -#endif - -#ifndef EPICS_ATOMIC_GET_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT - epicsAtomicGetPtrT ( const EpicsAtomicPtrT * pTarget ) -{ - epicsAtomicReadMemoryBarrier (); - return *pTarget; -} -#endif - -/* - * cmp and swap - */ -#ifndef EPICS_ATOMIC_CAS_INTT -EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget, int oldval, int newval ) -{ - EpicsAtomicLockKey key; - int cur; - - epicsAtomicLock ( & key ); - cur = *pTarget; - if ( cur == oldval ) { - *pTarget = newval; - } - epicsAtomicUnlock ( & key ); - return cur; -} -#endif - -#ifndef EPICS_ATOMIC_CAS_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget, - size_t oldval, size_t newval ) -{ - EpicsAtomicLockKey key; - size_t cur; - - epicsAtomicLock ( & key ); - cur = *pTarget; - if ( cur == oldval ) { - *pTarget = newval; - } - epicsAtomicUnlock ( & key ); - return cur; -} -#endif - -#ifndef EPICS_ATOMIC_CAS_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( - EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldval, EpicsAtomicPtrT newval ) -{ - EpicsAtomicLockKey key; - EpicsAtomicPtrT cur; - - epicsAtomicLock ( & key ); - cur = *pTarget; - if ( cur == oldval ) { - *pTarget = newval; - } - epicsAtomicUnlock ( & key ); - return cur; -} -#endif - -#ifdef __cpluplus -} /* end of extern "C" */ -#endif - -#endif /* epicsAtomicDefault_h */ - - diff --git a/src/libCom/osi/epicsEndian.h b/src/libCom/osi/epicsEndian.h deleted file mode 100644 index fd662822f..000000000 --- a/src/libCom/osi/epicsEndian.h +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_epicsEndian_H -#define INC_epicsEndian_H - -/* This file must be usable from both C and C++ */ - -#define EPICS_ENDIAN_LITTLE 1234 -#define EPICS_ENDIAN_BIG 4321 - - -/* The following OS Dependent file defines the macros - * EPICS_BYTE_ORDER and EPICS_FLOAT_WORD_ORDER to be - * one of the above EPICS_ENDIAN_ values. - */ - -#include "osdWireConfig.h" - -#ifndef EPICS_BYTE_ORDER -#error osdWireConfig.h didnt define EPICS_BYTE_ORDER -#endif - -#ifndef EPICS_FLOAT_WORD_ORDER -#error osdWireConfig.h didnt define EPICS_FLOAT_WORD_ORDER -#endif - -#endif /* INC_epicsEndian_H */ diff --git a/src/libCom/osi/epicsEvent.cpp b/src/libCom/osi/epicsEvent.cpp deleted file mode 100644 index 237f7d268..000000000 --- a/src/libCom/osi/epicsEvent.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* epicsMutex.c */ -/* Author: Jeff Hill */ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsEvent.h" -#include "epicsStdio.h" -#include "cantProceed.h" - -// vxWorks 5.4 gcc fails during compile when I use std::exception -using namespace std; - -// exception payload -class epicsEvent::invalidSemaphore : public exception -{ - const char * what () const throw (); -}; - -const char * epicsEvent::invalidSemaphore::what () const throw () -{ - return "epicsEvent::invalidSemaphore()"; -} - -// -// Its probably preferable to not make these inline because they are in -// the sharable library interface. The use of inline or not here is probably -// not an issue because all of this ends up in the operating system in system -// calls -// - -epicsEvent::epicsEvent ( epicsEventInitialState initial ) : - id ( epicsEventCreate ( initial ) ) -{ - if ( this->id == 0 ) { - throw std::bad_alloc (); - } -} - -epicsEvent::~epicsEvent () -{ - epicsEventDestroy ( this->id ); -} - -void epicsEvent::trigger () -{ - epicsEventStatus status = epicsEventTrigger (this->id); - - if (status != epicsEventOK) { - throw invalidSemaphore (); - } -} - -void epicsEvent::wait () -{ - epicsEventStatus status = epicsEventWait (this->id); - - if (status != epicsEventOK) { - throw invalidSemaphore (); - } -} - -bool epicsEvent::wait (double timeOut) -{ - epicsEventStatus status = epicsEventWaitWithTimeout (this->id, timeOut); - - if (status == epicsEventOK) { - return true; - } else if (status == epicsEventWaitTimeout) { - return false; - } - throw invalidSemaphore (); -} - -bool epicsEvent::tryWait () -{ - epicsEventStatus status = epicsEventTryWait (this->id); - - if (status == epicsEventOK) { - return true; - } else if (status == epicsEventWaitTimeout) { - return false; - } - throw invalidSemaphore (); -} - -void epicsEvent::show ( unsigned level ) const -{ - epicsEventShow ( this->id, level ); -} - - -// epicsEventMust... convenience routines for C code - -extern "C" { - -epicsShareFunc epicsEventId epicsEventMustCreate ( - epicsEventInitialState initialState) -{ - epicsEventId id = epicsEventCreate (initialState); - - if (!id) - cantProceed ("epicsEventMustCreate"); - return id; -} - -epicsShareFunc void epicsEventMustTrigger (epicsEventId id) { - epicsEventStatus status = epicsEventTrigger (id); - - if (status != epicsEventOK) - cantProceed ("epicsEventMustTrigger"); -} - -epicsShareFunc void epicsEventMustWait (epicsEventId id) { - epicsEventStatus status = epicsEventWait (id); - - if (status != epicsEventOK) - cantProceed ("epicsEventMustWait"); -} - -} // extern "C" - diff --git a/src/libCom/osi/epicsEvent.h b/src/libCom/osi/epicsEvent.h deleted file mode 100644 index e77d9a5ce..000000000 --- a/src/libCom/osi/epicsEvent.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef epicsEventh -#define epicsEventh - -#include "shareLib.h" - -typedef struct epicsEventOSD *epicsEventId; - -typedef enum { - epicsEventOK = 0, - epicsEventWaitTimeout, - epicsEventError -} epicsEventStatus; - -/* Backwards compatibility */ -#define epicsEventWaitStatus epicsEventStatus -#define epicsEventWaitOK epicsEventOK -#define epicsEventWaitError epicsEventError - -typedef enum { - epicsEventEmpty, - epicsEventFull -} epicsEventInitialState; - -#ifdef __cplusplus - -class epicsShareClass epicsEvent { -public: - epicsEvent ( epicsEventInitialState initial = epicsEventEmpty ); - ~epicsEvent (); - void trigger (); - void signal () { this->trigger(); } - void wait (); /* blocks until full */ - bool wait ( double timeOut ); /* false if still empty at time out */ - bool tryWait (); /* false if empty */ - void show ( unsigned level ) const; - - class invalidSemaphore; /* exception payload */ -private: - epicsEvent ( const epicsEvent & ); - epicsEvent & operator = ( const epicsEvent & ); - epicsEventId id; -}; - -extern "C" { -#endif /*__cplusplus */ - -epicsShareFunc epicsEventId epicsEventCreate( - epicsEventInitialState initialState); -epicsShareFunc epicsEventId epicsEventMustCreate ( - epicsEventInitialState initialState); -epicsShareFunc void epicsEventDestroy(epicsEventId id); -epicsShareFunc epicsEventStatus epicsEventTrigger( - epicsEventId id); -epicsShareFunc void epicsEventMustTrigger(epicsEventId id); -#define epicsEventSignal(ID) epicsEventMustTrigger(ID) -epicsShareFunc epicsEventStatus epicsEventWait( - epicsEventId id); -epicsShareFunc void epicsEventMustWait(epicsEventId id); -epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout( - epicsEventId id, double timeOut); -epicsShareFunc epicsEventStatus epicsEventTryWait( - epicsEventId id); -epicsShareFunc void epicsEventShow( - epicsEventId id, unsigned int level); - -#ifdef __cplusplus -} -#endif /*__cplusplus */ - -#include "osdEvent.h" - -#endif /* epicsEventh */ diff --git a/src/libCom/osi/epicsFindSymbol.h b/src/libCom/osi/epicsFindSymbol.h deleted file mode 100644 index 9935834da..000000000 --- a/src/libCom/osi/epicsFindSymbol.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef epicsFindSymbolh -#define epicsFindSymbolh - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -epicsShareFunc void * epicsLoadLibrary(const char *name); -epicsShareFunc const char *epicsLoadError(void); -epicsShareFunc void * epicsShareAPI epicsFindSymbol(const char *name); - -#ifdef __cplusplus -} -#endif - -#endif /* epicsFindSymbolh */ diff --git a/src/libCom/osi/epicsGeneralTime.c b/src/libCom/osi/epicsGeneralTime.c deleted file mode 100644 index ca3317ee3..000000000 --- a/src/libCom/osi/epicsGeneralTime.c +++ /dev/null @@ -1,635 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2008 Diamond Light Source Ltd -* Copyright (c) 2004 Oak Ridge National Laboratory -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Original Authors: David H. Thompson & Sheng Peng (ORNL) */ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsTypes.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsMessageQueue.h" -#include "epicsString.h" -#include "epicsStdioRedirect.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "epicsTimer.h" -#include "epicsInterrupt.h" -#include "osiSock.h" -#include "ellLib.h" -#include "errlog.h" -#include "cantProceed.h" -#include "envDefs.h" -#include "generalTimeSup.h" -#include "epicsGeneralTime.h" - -/* Change 'undef' to 'define' to turn on debug statements: */ -#undef DEBUG_GENERAL_TIME - -#ifdef DEBUG_GENERAL_TIME - int generalTimeDebug = 10; -# define IFDEBUG(n) \ - if (generalTimeDebug >= n) /* block or statement */ -#else -# define IFDEBUG(n) \ - if(0) /* Compiler will elide the block or statement */ -#endif - -/* Declarations */ - -typedef struct { - ELLNODE node; - char *name; - int priority; - union { - TIMECURRENTFUN Time; - TIMEEVENTFUN Event; - } get; - union { - TIMECURRENTFUN Time; - TIMEEVENTFUN Event; - } getInt; -} gtProvider; - -static struct { - epicsMutexId timeListLock; - ELLLIST timeProviders; - gtProvider *lastTimeProvider; - epicsTimeStamp lastProvidedTime; - - epicsMutexId eventListLock; - ELLLIST eventProviders; - gtProvider *lastEventProvider; - epicsTimeStamp eventTime[NUM_TIME_EVENTS]; - epicsTimeStamp lastProvidedBestTime; - - int ErrorCounts; -} gtPvt; - -static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; - -static const char * const tsfmt = "%Y-%m-%d %H:%M:%S.%09f"; - -/* Implementation */ - -static void generalTime_InitOnce(void *dummy) -{ - ellInit(>Pvt.timeProviders); - gtPvt.timeListLock = epicsMutexMustCreate(); - - ellInit(>Pvt.eventProviders); - gtPvt.eventListLock = epicsMutexMustCreate(); - - IFDEBUG(1) - printf("General Time Initialized\n"); -} - -void generalTime_Init(void) -{ - epicsThreadOnce(&onceId, generalTime_InitOnce, NULL); -} - - -int generalTimeGetExceptPriority(epicsTimeStamp *pDest, int *pPrio, int ignore) -{ - gtProvider *ptp; - int status = S_time_noProvider; - - generalTime_Init(); - - IFDEBUG(2) - printf("generalTimeGetExceptPriority(ignore=%d)\n", ignore); - - epicsMutexMustLock(gtPvt.timeListLock); - for (ptp = (gtProvider *)ellFirst(>Pvt.timeProviders); - ptp; ptp = (gtProvider *)ellNext(&ptp->node)) { - if ((ignore > 0 && ptp->priority == ignore) || - (ignore < 0 && ptp->priority != -ignore)) - continue; - - status = ptp->get.Time(pDest); - if (status == epicsTimeOK) { - /* No ratchet, time from this routine may go backwards */ - if (pPrio) - *pPrio = ptp->priority; - break; - } - else IFDEBUG(2) - printf("gTGExP provider '%s' returned error\n", ptp->name); - } - epicsMutexUnlock(gtPvt.timeListLock); - - IFDEBUG(2) { - if (ptp && status == epicsTimeOK) { - char buff[40]; - - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, pDest); - printf("gTGExP returning %s from provider '%s'\n", - buff, ptp->name); - } - else - printf("gTGExP returning error\n"); - } - - return status; -} - -int epicsShareAPI epicsTimeGetCurrent(epicsTimeStamp *pDest) -{ - gtProvider *ptp; - int status = S_time_noProvider; - epicsTimeStamp ts; - - generalTime_Init(); - - IFDEBUG(20) - printf("epicsTimeGetCurrent()\n"); - - epicsMutexMustLock(gtPvt.timeListLock); - for (ptp = (gtProvider *)ellFirst(>Pvt.timeProviders); - ptp; ptp = (gtProvider *)ellNext(&ptp->node)) { - - status = ptp->get.Time(&ts); - if (status == epicsTimeOK) { - /* check time is monotonic */ - if (epicsTimeGreaterThanEqual(&ts, >Pvt.lastProvidedTime)) { - *pDest = ts; - gtPvt.lastProvidedTime = ts; - gtPvt.lastTimeProvider = ptp; - } else { - int key; - - *pDest = gtPvt.lastProvidedTime; - key = epicsInterruptLock(); - gtPvt.ErrorCounts++; - epicsInterruptUnlock(key); - - IFDEBUG(10) { - char last[40], buff[40]; - - epicsTimeToStrftime(last, sizeof(last), tsfmt, - >Pvt.lastProvidedTime); - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, &ts); - printf("eTGC provider '%s' returned older time\n" - " %s, using %s instead\n", ptp->name, buff, last); - } - } - break; - } - } - if (status) - gtPvt.lastTimeProvider = NULL; - epicsMutexUnlock(gtPvt.timeListLock); - - IFDEBUG(20) { - if (ptp && status == epicsTimeOK) { - char buff[40]; - - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, &ts); - printf("eTGC returning %s from provider '%s'\n", - buff, ptp->name); - } - else - printf("eTGC returning error\n"); - } - - return status; -} - -int epicsTimeGetCurrentInt(epicsTimeStamp *pDest) -{ - gtProvider *ptp = gtPvt.lastTimeProvider; - - if (ptp == NULL || - ptp->getInt.Time == NULL) { - IFDEBUG(20) - epicsInterruptContextMessage("eTGCInt: No support\n"); - return S_time_noProvider; - } - - return ptp->getInt.Time(pDest); -} - - -static int generalTimeGetEventPriority(epicsTimeStamp *pDest, int eventNumber, - int *pPrio) -{ - gtProvider *ptp; - int status = S_time_noProvider; - epicsTimeStamp ts; - - generalTime_Init(); - - IFDEBUG(2) - printf("generalTimeGetEventPriority(eventNum=%d)\n", eventNumber); - - if ((eventNumber < 0 || eventNumber >= NUM_TIME_EVENTS) && - (eventNumber != epicsTimeEventBestTime)) - return S_time_badEvent; - - epicsMutexMustLock(gtPvt.eventListLock); - for (ptp = (gtProvider *)ellFirst(>Pvt.eventProviders); - ptp; ptp = (gtProvider *)ellNext(&ptp->node)) { - - status = ptp->get.Event(&ts, eventNumber); - if (status == epicsTimeOK) { - gtPvt.lastEventProvider = ptp; - if (pPrio) - *pPrio = ptp->priority; - - if (eventNumber == epicsTimeEventBestTime) { - if (epicsTimeGreaterThanEqual(&ts, - >Pvt.lastProvidedBestTime)) { - *pDest = ts; - gtPvt.lastProvidedBestTime = ts; - } else { - int key; - - *pDest = gtPvt.lastProvidedBestTime; - key = epicsInterruptLock(); - gtPvt.ErrorCounts++; - epicsInterruptUnlock(key); - - IFDEBUG(10) { - char last[40], buff[40]; - - epicsTimeToStrftime(last, sizeof(last), tsfmt, - >Pvt.lastProvidedBestTime); - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, &ts); - printf("gTGEvP provider '%s' returned older time\n" - " %s, using %s instead\n", - ptp->name, buff, last); - } - } - } else { - if (epicsTimeGreaterThanEqual(pDest, - >Pvt.eventTime[eventNumber])) { - *pDest = ts; - gtPvt.eventTime[eventNumber] = ts; - } else { - int key; - - *pDest = gtPvt.eventTime[eventNumber]; - key = epicsInterruptLock(); - gtPvt.ErrorCounts++; - epicsInterruptUnlock(key); - } - - IFDEBUG(10) { - char last[40], buff[40]; - - epicsTimeToStrftime(last, sizeof(last), tsfmt, - >Pvt.lastProvidedBestTime); - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, &ts); - printf("gTGEvP provider '%s' returned older time\n" - " %s, using %s instead\n", - ptp->name, buff, last); - } - } - break; - } - else IFDEBUG(2) - printf("gTGEvP provider '%s' returned error\n", ptp->name); - } - if (status) - gtPvt.lastEventProvider = NULL; - epicsMutexUnlock(gtPvt.eventListLock); - - IFDEBUG(10) { - if (ptp && status == epicsTimeOK) { - char buff[40]; - - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, &ts); - printf("gTGEvP returning %s from provider '%s'\n", - buff, ptp->name); - } - else - printf("gTGEvP returning error\n"); - } - - return status; -} - -int epicsShareAPI epicsTimeGetEvent(epicsTimeStamp *pDest, int eventNumber) -{ - if (eventNumber == epicsTimeEventCurrentTime) { - return epicsTimeGetCurrent(pDest); - } else { - return generalTimeGetEventPriority(pDest, eventNumber, NULL); - } -} - -int epicsTimeGetEventInt(epicsTimeStamp *pDest, int eventNumber) -{ - if (eventNumber == epicsTimeEventCurrentTime) { - return epicsTimeGetCurrentInt(pDest); - } else { - gtProvider *ptp = gtPvt.lastEventProvider; - - if (ptp == NULL || - ptp->getInt.Event == NULL) { - IFDEBUG(20) - epicsInterruptContextMessage("eTGEvInt: No support\n"); - return S_time_noProvider; - } - - return ptp->getInt.Event(pDest, eventNumber); - } -} - - -/* Provider Registration */ - -static void insertProvider(gtProvider *ptp, ELLLIST *plist, epicsMutexId lock) -{ - gtProvider *ptpref; - - epicsMutexMustLock(lock); - - for (ptpref = (gtProvider *)ellFirst(plist); - ptpref; ptpref = (gtProvider *)ellNext(&ptpref->node)) { - if (ptpref->priority > ptp->priority) - break; - } - - if (ptpref) { - /* Found a provider below the new one */ - ptpref = (gtProvider *)ellPrevious(&ptpref->node); - ellInsert(plist, &ptpref->node, &ptp->node); - } else { - ellAdd(plist, &ptp->node); - } - - epicsMutexUnlock(lock); -} - -static gtProvider * findProvider(ELLLIST *plist, epicsMutexId lock, - const char *name, int priority) -{ - gtProvider *ptp; - - epicsMutexMustLock(lock); - - for (ptp = (gtProvider *)ellFirst(plist); - ptp; ptp = (gtProvider *)ellNext(&ptp->node)) { - if (ptp->priority == priority && - !strcmp(ptp->name, name)) - break; - } - - epicsMutexUnlock(lock); - return ptp; -} - -int generalTimeRegisterEventProvider(const char *name, int priority, - TIMEEVENTFUN getEvent) -{ - gtProvider *ptp; - - generalTime_Init(); - - if (name == NULL || getEvent == NULL) - return S_time_badArgs; - - ptp = (gtProvider *)malloc(sizeof(gtProvider)); - if (ptp == NULL) - return S_time_noMemory; - - ptp->name = epicsStrDup(name); - ptp->priority = priority; - ptp->get.Event = getEvent; - ptp->getInt.Event = NULL; - - insertProvider(ptp, >Pvt.eventProviders, gtPvt.eventListLock); - - IFDEBUG(1) - printf("Registered event provider '%s' at %d\n", name, priority); - - return epicsTimeOK; -} - -int generalTimeAddIntEventProvider(const char *name, int priority, - TIMEEVENTFUN getEvent) -{ - gtProvider *ptp = findProvider(>Pvt.eventProviders, gtPvt.eventListLock, - name, priority); - if (ptp == NULL) - return S_time_noProvider; - - ptp->getInt.Event = getEvent; - - IFDEBUG(1) - printf("Event provider '%s' is interrupt-callable\n", name); - - return epicsTimeOK; -} - -int generalTimeRegisterCurrentProvider(const char *name, int priority, - TIMECURRENTFUN getTime) -{ - gtProvider *ptp; - - generalTime_Init(); - - if (name == NULL || getTime == NULL) - return S_time_badArgs; - - ptp = (gtProvider *)malloc(sizeof(gtProvider)); - if (ptp == NULL) - return S_time_noMemory; - - ptp->name = epicsStrDup(name); - ptp->priority = priority; - ptp->get.Time = getTime; - ptp->getInt.Time = NULL; - - insertProvider(ptp, >Pvt.timeProviders, gtPvt.timeListLock); - - IFDEBUG(1) - printf("Registered time provider '%s' at %d\n", name, priority); - - return epicsTimeOK; -} - -int generalTimeAddIntCurrentProvider(const char *name, int priority, - TIMECURRENTFUN getTime) -{ - gtProvider *ptp = findProvider(>Pvt.timeProviders, gtPvt.timeListLock, - name, priority); - if (ptp == NULL) - return S_time_noProvider; - - ptp->getInt.Time = getTime; - - IFDEBUG(1) - printf("Time provider '%s' is interrupt-callable\n", name); - - return epicsTimeOK; -} - -/* - * Provide an optional "last resort" provider for Event Time. - * - * This is deliberately optional, as it represents site policy. - * It is intended to be installed as an EventTime provider at the lowest - * priority, to return the current time for an event if there is no - * better time provider for event times. - * - * Typically, this will only be used during startup, or a time-provider - * resynchronisation, where events are being generated by the event system - * but the time provided by the system is not yet valid. - */ -static int lastResortGetEvent(epicsTimeStamp *timeStamp, int eventNumber) -{ - return epicsTimeGetCurrent(timeStamp); -} - -int installLastResortEventProvider(void) -{ - return generalTimeEventTpRegister("Last Resort Event", - LAST_RESORT_PRIORITY, lastResortGetEvent); -} - - -/* Status Report */ - -long generalTimeReport(int level) -{ - int items; - - if (onceId == EPICS_THREAD_ONCE_INIT) { - printf("General time framework not yet initialized.\n"); - return epicsTimeOK; - } - - printf("Backwards time errors prevented %u times.\n\n", - generalTimeGetErrorCounts()); - - /* Use an output buffer to avoid holding mutexes during printing */ - - printf("Current Time Providers:\n"); - epicsMutexMustLock(gtPvt.timeListLock); - if ((items = ellCount(>Pvt.timeProviders))) { - gtProvider *ptp; - char *message; /* Temporary output buffer */ - char *pout; - - message = calloc(items, 80 * 2); /* Each provider needs 2 lines */ - if (!message) { - epicsMutexUnlock(gtPvt.timeListLock); - printf("Out of memory\n"); - return S_time_noMemory; - } - - pout = message; - - for (ptp = (gtProvider *)ellFirst(>Pvt.timeProviders); - ptp; ptp = (gtProvider *)ellNext(&ptp->node)) { - pout += sprintf(pout, " \"%s\", priority = %d\n", - ptp->name, ptp->priority); - if (level) { - epicsTimeStamp tempTS; - if (ptp->get.Time(&tempTS) == epicsTimeOK) { - char tempTSText[40]; - epicsTimeToStrftime(tempTSText, sizeof(tempTSText), - "%Y-%m-%d %H:%M:%S.%06f", &tempTS); - pout += sprintf(pout, "\tCurrent Time is %s.\n", - tempTSText); - } else { - pout += sprintf(pout, "\tCurrent Time not available\n"); - } - } - } - epicsMutexUnlock(gtPvt.timeListLock); - puts(message); - free(message); - } else { - epicsMutexUnlock(gtPvt.timeListLock); - printf("\tNo Providers registered.\n"); - } - - printf("Event Time Providers:\n"); - epicsMutexMustLock(gtPvt.eventListLock); - if ((items = ellCount(>Pvt.eventProviders))) - { - gtProvider *ptp; - char *message; /* Temporary output buffer */ - char *pout; - - message = calloc(items, 80); /* Each provider needs 1 line, */ - if (!message) { - epicsMutexUnlock(gtPvt.eventListLock); - printf("Out of memory\n"); - return S_time_noMemory; - } - - pout = message; - - for (ptp = (gtProvider *)ellFirst(>Pvt.eventProviders); - ptp; ptp = (gtProvider *)ellNext(&ptp->node)) { - pout += sprintf(pout, " \"%s\", priority = %d\n", - ptp->name, ptp->priority); - } - epicsMutexUnlock(gtPvt.eventListLock); - puts(message); - free(message); - } - else - { - epicsMutexUnlock(gtPvt.eventListLock); - printf("\tNo Providers registered.\n"); - } - - return epicsTimeOK; -} - -/* - * Access to internal status values. - */ - -void generalTimeResetErrorCounts(void) -{ - int key = epicsInterruptLock(); - gtPvt.ErrorCounts = 0; - epicsInterruptUnlock(key); -} - -int generalTimeGetErrorCounts(void) -{ - int key = epicsInterruptLock(); - int errors = gtPvt.ErrorCounts; - epicsInterruptUnlock(key); - return errors; -} - -const char * generalTimeCurrentProviderName(void) -{ - if (gtPvt.lastTimeProvider) - return gtPvt.lastTimeProvider->name; - return NULL; -} - -const char * generalTimeEventProviderName(void) -{ - if (gtPvt.lastEventProvider) - return gtPvt.lastEventProvider->name; - return NULL; -} - -const char * generalTimeHighestCurrentName(void) -{ - gtProvider *ptp; - - epicsMutexMustLock(gtPvt.timeListLock); - ptp = (gtProvider *)ellFirst(>Pvt.timeProviders); - epicsMutexUnlock(gtPvt.timeListLock); - return ptp ? ptp->name : NULL; -} diff --git a/src/libCom/osi/epicsGeneralTime.h b/src/libCom/osi/epicsGeneralTime.h deleted file mode 100644 index 3adc23705..000000000 --- a/src/libCom/osi/epicsGeneralTime.h +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2008 Diamond Light Source Ltd -* Copyright (c) 2004 Oak Ridge National Laboratory -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_epicsGeneralTime_H -#define INC_epicsGeneralTime_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define NUM_TIME_EVENTS 256 -/* Time Events are numbered 0 through (NUM_TIME_EVENTS-1) */ - -epicsShareFunc void generalTime_Init(void); - -epicsShareFunc int installLastResortEventProvider(void); - -epicsShareFunc void generalTimeResetErrorCounts(void); -epicsShareFunc int generalTimeGetErrorCounts(void); - -epicsShareFunc const char * generalTimeCurrentProviderName(void); -epicsShareFunc const char * generalTimeEventProviderName(void); -epicsShareFunc const char * generalTimeHighestCurrentName(void); - -/* Original names, for compatibility */ -#define generalTimeCurrentTpName generalTimeCurrentProviderName -#define generalTimeEventTpName generalTimeEventProviderName - -epicsShareFunc long generalTimeReport(int interest); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsGeneralTime_H */ diff --git a/src/libCom/osi/epicsInterrupt.h b/src/libCom/osi/epicsInterrupt.h deleted file mode 100644 index 93b443810..000000000 --- a/src/libCom/osi/epicsInterrupt.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef epicsInterrupth -#define epicsInterrupth - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -epicsShareFunc int epicsInterruptLock(void); -epicsShareFunc void epicsInterruptUnlock(int key); -epicsShareFunc int epicsInterruptIsInterruptContext(void); -epicsShareFunc void epicsInterruptContextMessage(const char *message); - -#ifdef __cplusplus -} -#endif - -#include "osdInterrupt.h" - -#endif /* epicsInterrupth */ diff --git a/src/libCom/osi/epicsMath.cpp b/src/libCom/osi/epicsMath.cpp deleted file mode 100644 index 1388e658a..000000000 --- a/src/libCom/osi/epicsMath.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonna LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsMath.cpp */ - -#define epicsExportSharedSymbols -#include - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4723) -#endif - -#ifndef NAN -static float makeNAN ( void ) -{ - float a = 0, b = 0; - return a / b; -} -#define NAN makeNAN() -#endif - -#ifndef INFINITY -static float makeINF ( void ) -{ - float a = 1, b = 0; - return a / b; -} -#define INFINITY makeINF() -#endif - -extern "C" { -epicsShareDef float epicsNAN = NAN; -epicsShareDef float epicsINF = INFINITY; -} - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - diff --git a/src/libCom/osi/epicsMessageQueue.cpp b/src/libCom/osi/epicsMessageQueue.cpp deleted file mode 100644 index 1527b3d3a..000000000 --- a/src/libCom/osi/epicsMessageQueue.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsMessageQueue.h" -#include "epicsStdio.h" - -epicsMessageQueue::epicsMessageQueue(unsigned int aCapacity, - unsigned int aMaxMessageSize) - : id ( epicsMessageQueueCreate(aCapacity, aMaxMessageSize) ) -{ - if (id == NULL) - throw std::bad_alloc (); -} - -epicsMessageQueue::~epicsMessageQueue() -{ - epicsMessageQueueDestroy(id); -} - -int -epicsMessageQueue::trySend(void *message, unsigned int size) -{ - return epicsMessageQueueTrySend(id, message, size); -} - -int -epicsMessageQueue::send(void *message, unsigned int size) -{ - return epicsMessageQueueSend(id, message, size); -} - -int -epicsMessageQueue::send(void *message, unsigned int size, double timeout) -{ - return epicsMessageQueueSendWithTimeout(id, message, size, timeout); -} - -int -epicsMessageQueue::tryReceive(void *message, unsigned int size ) -{ - return epicsMessageQueueTryReceive(id, message, size); -} - -int -epicsMessageQueue::receive(void *message, unsigned int size ) -{ - return epicsMessageQueueReceive(id, message, size); -} - -int -epicsMessageQueue::receive(void *message, unsigned int size, double timeout) -{ - return epicsMessageQueueReceiveWithTimeout(id, message, size, timeout); -} - -unsigned int -epicsMessageQueue::pending() -{ - return epicsMessageQueuePending(id); -} - -void -epicsMessageQueue::show(unsigned int level) -{ - epicsMessageQueueShow(id, level); -} diff --git a/src/libCom/osi/epicsMessageQueue.h b/src/libCom/osi/epicsMessageQueue.h deleted file mode 100644 index c6a98fd47..000000000 --- a/src/libCom/osi/epicsMessageQueue.h +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -/* - * Interthread message passing - */ -#ifndef epicsMessageQueueh -#define epicsMessageQueueh - -#include "epicsAssert.h" -#include "shareLib.h" - -typedef struct epicsMessageQueueOSD *epicsMessageQueueId; - -#ifdef __cplusplus - -class epicsShareClass epicsMessageQueue { -public: - epicsMessageQueue ( unsigned int capacity, - unsigned int maximumMessageSize ); - ~epicsMessageQueue (); - int trySend ( void *message, unsigned int messageSize ); - int send ( void *message, unsigned int messageSize); - int send ( void *message, unsigned int messageSize, double timeout ); - int tryReceive ( void *message, unsigned int size ); - int receive ( void *message, unsigned int size ); - int receive ( void *message, unsigned int size, double timeout ); - void show ( unsigned int level = 0 ); - unsigned int pending (); - -private: /* Prevent compiler-generated member functions */ - /* default constructor, copy constructor, assignment operator */ - epicsMessageQueue(); - epicsMessageQueue(const epicsMessageQueue &); - epicsMessageQueue& operator=(const epicsMessageQueue &); - - epicsMessageQueueId id; -}; - -extern "C" { -#endif /*__cplusplus */ - -epicsShareFunc epicsMessageQueueId epicsShareAPI epicsMessageQueueCreate( - unsigned int capacity, - unsigned int maximumMessageSize); -epicsShareFunc void epicsShareAPI epicsMessageQueueDestroy( - epicsMessageQueueId id); -epicsShareFunc int epicsShareAPI epicsMessageQueueTrySend( - epicsMessageQueueId id, - void *message, - unsigned int messageSize); -epicsShareFunc int epicsShareAPI epicsMessageQueueSend( - epicsMessageQueueId id, - void *message, - unsigned int messageSize); -epicsShareFunc int epicsShareAPI epicsMessageQueueSendWithTimeout( - epicsMessageQueueId id, - void *message, - unsigned int messageSize, - double timeout); -epicsShareFunc int epicsShareAPI epicsMessageQueueTryReceive( - epicsMessageQueueId id, - void *message, - unsigned int size); -epicsShareFunc int epicsShareAPI epicsMessageQueueReceive( - epicsMessageQueueId id, - void *message, - unsigned int size); -epicsShareFunc int epicsShareAPI epicsMessageQueueReceiveWithTimeout( - epicsMessageQueueId id, - void *message, - unsigned int size, - double timeout); -epicsShareFunc int epicsShareAPI epicsMessageQueuePending( - epicsMessageQueueId id); -epicsShareFunc void epicsShareAPI epicsMessageQueueShow( - epicsMessageQueueId id, - int level); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#include "osdMessageQueue.h" - -#endif /* epicsMessageQueueh */ diff --git a/src/libCom/osi/epicsMutex.cpp b/src/libCom/osi/epicsMutex.cpp deleted file mode 100644 index 7c8d05056..000000000 --- a/src/libCom/osi/epicsMutex.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsMutex.cpp */ -/* Author: Marty Kraimer and Jeff Hill Date: 03APR01 */ - -/* - * NOTES: - * 1) LOG_LAST_OWNER feature is normally commented out because - * it slows down the system at run time, anfd because its not - * currently safe to convert a thread id to a thread name because - * the thread may have exited making the thread id invalid. - */ - -#include - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "epicsThread.h" -#include "valgrind/valgrind.h" -#include "ellLib.h" -#include "errlog.h" -#include "epicsMutex.h" -#include "epicsThread.h" - -static epicsThreadOnceId epicsMutexOsiOnce = EPICS_THREAD_ONCE_INIT; -static ELLLIST mutexList; -static ELLLIST freeList; - -struct epicsMutexParm { - ELLNODE node; - epicsMutexOSD * id; -# ifdef LOG_LAST_OWNER - epicsThreadId lastOwner; -# endif - const char *pFileName; - int lineno; -}; - -static epicsMutexOSD * epicsMutexGlobalLock; - - -// vxWorks 5.4 gcc fails during compile when I use std::exception -using namespace std; - -// exception payload -class epicsMutex::mutexCreateFailed : public exception -{ - const char * what () const throw (); -}; - -const char * epicsMutex::mutexCreateFailed::what () const throw () -{ - return "epicsMutex::mutexCreateFailed()"; -} - -// exception payload -class epicsMutex::invalidMutex : public exception -{ - const char * what () const throw (); -}; - -const char * epicsMutex::invalidMutex::what () const throw () -{ - return "epicsMutex::invalidMutex()"; -} - -static void epicsMutexOsiInit(void *) { - ellInit(&mutexList); - ellInit(&freeList); - VALGRIND_CREATE_MEMPOOL(&freeList, 0, 0); - epicsMutexGlobalLock = epicsMutexOsdCreate(); -} - -epicsMutexId epicsShareAPI epicsMutexOsiCreate( - const char *pFileName,int lineno) -{ - epicsMutexOSD * id; - - epicsThreadOnce(&epicsMutexOsiOnce, epicsMutexOsiInit, NULL); - - id = epicsMutexOsdCreate(); - if(!id) { - return 0; - } - epicsMutexLockStatus lockStat = - epicsMutexOsdLock(epicsMutexGlobalLock); - assert ( lockStat == epicsMutexLockOK ); - epicsMutexParm *pmutexNode = - reinterpret_cast < epicsMutexParm * > ( ellFirst(&freeList) ); - if(pmutexNode) { - ellDelete(&freeList,&pmutexNode->node); - VALGRIND_MEMPOOL_FREE(&freeList, pmutexNode); - } else { - pmutexNode = static_cast < epicsMutexParm * > ( calloc(1,sizeof(epicsMutexParm)) ); - } - VALGRIND_MEMPOOL_ALLOC(&freeList, pmutexNode, sizeof(epicsMutexParm)); - pmutexNode->id = id; -# ifdef LOG_LAST_OWNER - pmutexNode->lastOwner = 0; -# endif - pmutexNode->pFileName = pFileName; - pmutexNode->lineno = lineno; - ellAdd(&mutexList,&pmutexNode->node); - epicsMutexOsdUnlock(epicsMutexGlobalLock); - return(pmutexNode); -} - -epicsMutexId epicsShareAPI epicsMutexOsiMustCreate( - const char *pFileName,int lineno) -{ - epicsMutexId id = epicsMutexOsiCreate(pFileName,lineno); - assert(id); - return(id ); -} - -void epicsShareAPI epicsMutexDestroy(epicsMutexId pmutexNode) -{ - epicsMutexLockStatus lockStat = - epicsMutexOsdLock(epicsMutexGlobalLock); - assert ( lockStat == epicsMutexLockOK ); - ellDelete(&mutexList,&pmutexNode->node); - epicsMutexOsdDestroy(pmutexNode->id); - VALGRIND_MEMPOOL_FREE(&freeList, pmutexNode); - VALGRIND_MEMPOOL_ALLOC(&freeList, &pmutexNode->node, sizeof(pmutexNode->node)); - ellAdd(&freeList,&pmutexNode->node); - epicsMutexOsdUnlock(epicsMutexGlobalLock); -} - -void epicsShareAPI epicsMutexUnlock(epicsMutexId pmutexNode) -{ - epicsMutexOsdUnlock(pmutexNode->id); -} - -epicsMutexLockStatus epicsShareAPI epicsMutexLock( - epicsMutexId pmutexNode) -{ - epicsMutexLockStatus status = - epicsMutexOsdLock(pmutexNode->id); -# ifdef LOG_LAST_OWNER - if ( status == epicsMutexLockOK ) { - pmutexNode->lastOwner = epicsThreadGetIdSelf(); - } -# endif - return status; -} - -epicsMutexLockStatus epicsShareAPI epicsMutexTryLock( - epicsMutexId pmutexNode) -{ - epicsMutexLockStatus status = - epicsMutexOsdTryLock(pmutexNode->id); -# ifdef LOG_LAST_OWNER - if ( status == epicsMutexLockOK ) { - pmutexNode->lastOwner = epicsThreadGetIdSelf(); - } -# endif - return status; -} - -/* Empty the freeList. - * Called from epicsExit.c, but not via epicsAtExit() - * to avoid the possibility of a circular reference. - */ -extern "C" -void epicsMutexCleanup(void) -{ - ELLNODE *cur; - epicsMutexLockStatus lockStat = - epicsMutexOsdLock(epicsMutexGlobalLock); - assert ( lockStat == epicsMutexLockOK ); - - while((cur=ellGet(&freeList))!=NULL) { - VALGRIND_MEMPOOL_FREE(&freeList, cur); - free(cur); - } - - epicsMutexOsdUnlock(epicsMutexGlobalLock); -} - -void epicsShareAPI epicsMutexShow( - epicsMutexId pmutexNode, unsigned int level) -{ -# ifdef LOG_LAST_OWNER - char threadName [255]; - if ( pmutexNode->lastOwner ) { -# error currently not safe to fetch name for stale thread - epicsThreadGetName ( pmutexNode->lastOwner, - threadName, sizeof ( threadName ) ); - } - else { - strcpy ( threadName, "" ); - } - printf("epicsMutexId %p last owner \"%s\" source %s line %d\n", - (void *)pmutexNode, threadName, - pmutexNode->pFileName, pmutexNode->lineno); -# else - printf("epicsMutexId %p source %s line %d\n", - (void *)pmutexNode, pmutexNode->pFileName, - pmutexNode->lineno); -# endif - if ( level > 0 ) { - epicsMutexOsdShow(pmutexNode->id,level-1); - } -} - -void epicsShareAPI epicsMutexShowAll(int onlyLocked,unsigned int level) -{ - epicsMutexParm *pmutexNode; - - if (epicsMutexOsiOnce == EPICS_THREAD_ONCE_INIT) - return; - - printf("ellCount(&mutexList) %d ellCount(&freeList) %d\n", - ellCount(&mutexList),ellCount(&freeList)); - epicsMutexLockStatus lockStat = - epicsMutexOsdLock(epicsMutexGlobalLock); - assert ( lockStat == epicsMutexLockOK ); - pmutexNode = reinterpret_cast < epicsMutexParm * > ( ellFirst(&mutexList) ); - while(pmutexNode) { - if(onlyLocked) { - epicsMutexLockStatus status; - status = epicsMutexOsdTryLock(pmutexNode->id); - if(status==epicsMutexLockOK) { - epicsMutexOsdUnlock(pmutexNode->id); - pmutexNode = - reinterpret_cast < epicsMutexParm * > - ( ellNext(&pmutexNode->node) ); - continue; - } - } - epicsMutexShow(pmutexNode, level); - pmutexNode = - reinterpret_cast < epicsMutexParm * > ( ellNext(&pmutexNode->node) ); - } - epicsMutexOsdUnlock(epicsMutexGlobalLock); -} - -epicsMutex :: epicsMutex () : - id ( epicsMutexCreate () ) -{ - if ( this->id == 0 ) { - throw mutexCreateFailed (); - } -} - -epicsMutex :: epicsMutex ( const char *pFileName, int lineno ) : - id ( epicsMutexOsiCreate (pFileName, lineno) ) -{ - if ( this->id == 0 ) { - throw mutexCreateFailed (); - } -} - -epicsMutex ::~epicsMutex () -{ - epicsMutexDestroy ( this->id ); -} - -void epicsMutex::lock () -{ - epicsMutexLockStatus status = epicsMutexLock ( this->id ); - if ( status != epicsMutexLockOK ) { - throw invalidMutex (); - } -} - -bool epicsMutex::tryLock () -{ - epicsMutexLockStatus status = epicsMutexTryLock ( this->id ); - if ( status == epicsMutexLockOK ) { - return true; - } - else if ( status != epicsMutexLockTimeout ) { - throw invalidMutex (); - } - return false; -} - -void epicsMutex::unlock () -{ - epicsMutexUnlock ( this->id ); -} - -void epicsMutex :: show ( unsigned level ) const -{ - epicsMutexShow ( this->id, level ); -} - -static epicsThreadPrivate < epicsDeadlockDetectMutex > - * pCurrentMutexLevel = 0; - -static epicsThreadOnceId epicsDeadlockDetectMutexInit = EPICS_THREAD_ONCE_INIT; - -extern "C" -void epicsDeadlockDetectMutexInitFunc ( void * ) -{ - pCurrentMutexLevel = new epicsThreadPrivate < epicsDeadlockDetectMutex > (); -} - -epicsDeadlockDetectMutex:: - epicsDeadlockDetectMutex ( hierarchyLevel_t level ) : - hierarchyLevel ( level ), pPreviousLevel ( 0 ) -{ - epicsThreadOnce ( & epicsDeadlockDetectMutexInit, - epicsDeadlockDetectMutexInitFunc, 0 ); -} - -epicsDeadlockDetectMutex::~epicsDeadlockDetectMutex () -{ -} - -void epicsDeadlockDetectMutex::show ( unsigned level ) const -{ - this->mutex.show ( level ); -} - -void epicsDeadlockDetectMutex::lock () -{ - epicsDeadlockDetectMutex * pPrev = pCurrentMutexLevel->get(); - if ( pPrev && pPrev != this ) { - if ( pPrev->hierarchyLevel >= this->hierarchyLevel ) { - errlogPrintf ( "!!!! Deadlock Vulnerability Detected !!!! " - "at level %u and moving to level %u\n", - pPrev->hierarchyLevel, - this->hierarchyLevel ); - } - } - this->mutex.lock (); - if ( pPrev && pPrev != this ) { - pCurrentMutexLevel->set ( this ); - this->pPreviousLevel = pPrev; - } -} - -void epicsDeadlockDetectMutex::unlock () -{ - pCurrentMutexLevel->set ( this->pPreviousLevel ); - this->mutex.unlock (); -} - -bool epicsDeadlockDetectMutex::tryLock () -{ - bool success = this->mutex.tryLock (); - if ( success ) { - this->pPreviousLevel = pCurrentMutexLevel->get(); - pCurrentMutexLevel->set ( this ); - } - return success; -} - - diff --git a/src/libCom/osi/epicsMutex.h b/src/libCom/osi/epicsMutex.h deleted file mode 100644 index 6d74f9599..000000000 --- a/src/libCom/osi/epicsMutex.h +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef epicsMutexh -#define epicsMutexh - -#include "epicsAssert.h" - -#include "shareLib.h" - -typedef struct epicsMutexParm *epicsMutexId; -typedef enum { - epicsMutexLockOK,epicsMutexLockTimeout,epicsMutexLockError -} epicsMutexLockStatus; - -#ifdef __cplusplus - -#include "compilerDependencies.h" -#include "epicsGuard.h" - -#define newEpicsMutex new epicsMutex(__FILE__,__LINE__) - -class epicsShareClass epicsMutex { -public: - typedef epicsGuard guard_t; - typedef epicsGuard release_t; - class mutexCreateFailed; /* exception payload */ - class invalidMutex; /* exception payload */ - epicsMutex (); - epicsMutex ( const char *pFileName, int lineno ); - ~epicsMutex (); - void show ( unsigned level ) const; - void lock (); /* blocks until success */ - void unlock (); - bool tryLock (); /* true if successful */ -private: - epicsMutexId id; - epicsMutex ( const epicsMutex & ); - epicsMutex & operator = ( const epicsMutex & ); -}; - -class epicsShareClass epicsDeadlockDetectMutex { -public: - typedef epicsGuard guard_t; - typedef epicsGuard release_t; - typedef unsigned hierarchyLevel_t; - epicsDeadlockDetectMutex ( unsigned hierarchyLevel_t ); - ~epicsDeadlockDetectMutex (); - void show ( unsigned level ) const; - void lock (); /* blocks until success */ - void unlock (); - bool tryLock (); /* true if successful */ -private: - epicsMutex mutex; - const hierarchyLevel_t hierarchyLevel; - class epicsDeadlockDetectMutex * pPreviousLevel; - epicsDeadlockDetectMutex ( const epicsDeadlockDetectMutex & ); - epicsDeadlockDetectMutex & operator = ( const epicsDeadlockDetectMutex & ); -}; - -#endif /*__cplusplus*/ - -#ifdef __cplusplus -extern "C" { -#endif /*__cplusplus*/ - -#define epicsMutexCreate() epicsMutexOsiCreate(__FILE__,__LINE__) -epicsShareFunc epicsMutexId epicsShareAPI epicsMutexOsiCreate( - const char *pFileName,int lineno); -#define epicsMutexMustCreate() epicsMutexOsiMustCreate(__FILE__,__LINE__) -epicsShareFunc epicsMutexId epicsShareAPI epicsMutexOsiMustCreate( - const char *pFileName,int lineno); -epicsShareFunc void epicsShareAPI epicsMutexDestroy(epicsMutexId id); -epicsShareFunc void epicsShareAPI epicsMutexUnlock(epicsMutexId id); -epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexLock( - epicsMutexId id); -#define epicsMutexMustLock(ID) { \ - epicsMutexLockStatus status = epicsMutexLock(ID); \ - assert(status == epicsMutexLockOK); \ -} -epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexTryLock( - epicsMutexId id); -epicsShareFunc void epicsShareAPI epicsMutexShow( - epicsMutexId id,unsigned int level); -epicsShareFunc void epicsShareAPI epicsMutexShowAll( - int onlyLocked,unsigned int level); - -/*NOTES: - epicsMutex MUST implement recursive locking - epicsMutex should implement priority inheritance and deletion safe -*/ - -/* - * The following is the interface to the OS dependent - * implementation and should NOT be called directly by - * user code - */ -struct epicsMutexOSD * epicsMutexOsdCreate(void); -void epicsMutexOsdDestroy(struct epicsMutexOSD *); -void epicsMutexOsdUnlock(struct epicsMutexOSD *); -epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD *); -epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD *); -void epicsMutexOsdShow(struct epicsMutexOSD *,unsigned int level); - -#ifdef __cplusplus -} -#endif - -#include "osdMutex.h" - -#endif /* epicsMutexh */ diff --git a/src/libCom/osi/epicsReadline.c b/src/libCom/osi/epicsReadline.c deleted file mode 100644 index 936cbce99..000000000 --- a/src/libCom/osi/epicsReadline.c +++ /dev/null @@ -1,148 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Eric Norum Date: 12DEC2001 */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "envDefs.h" -#include "epicsReadline.h" - -#define EPICS_COMMANDLINE_LIBRARY_EPICS 0 -#define EPICS_COMMANDLINE_LIBRARY_LIBTECLA 1 -#define EPICS_COMMANDLINE_LIBRARY_READLINE 2 -#define EPICS_COMMANDLINE_LIBRARY_READLINE_CURSES 2 -#define EPICS_COMMANDLINE_LIBRARY_READLINE_NCURSES 2 - -#ifndef EPICS_COMMANDLINE_LIBRARY -# define EPICS_COMMANDLINE_LIBRARY EPICS_COMMANDLINE_LIBRARY_EPICS -#endif - -struct osdContext; -struct readlineContext { - FILE *in; - char *line; - struct osdContext *osd; -}; - -static void osdReadlineBegin(struct readlineContext *); -static char * osdReadline(const char *prompt, struct readlineContext *); -static void osdReadlineEnd(struct readlineContext *); - -#if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_EPICS - -static void osdReadlineBegin(struct readlineContext * c) {} -static char * osdReadline(const char *prompt, struct readlineContext * c) { return NULL; } -static void osdReadlineEnd(struct readlineContext * c) {} - -#else - -# if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_READLINE -# include "gnuReadline.c" -# else -# include "osdReadline.c" -# endif - -#endif - -/* - * Create a command-line context - */ -void * epicsShareAPI -epicsReadlineBegin(FILE *in) -{ - struct readlineContext *readlineContext = calloc(1, sizeof(*readlineContext)); - - if (readlineContext) { - readlineContext->in = in; - readlineContext->line = NULL; - if (!envGetConfigParamPtr(&IOCSH_HISTEDIT_DISABLE)) - osdReadlineBegin(readlineContext); - } - return readlineContext; -} - -/* - * Read a line of input - */ -char * epicsShareAPI -epicsReadline (const char *prompt, void *context) -{ - struct readlineContext *readlineContext = context; - FILE *in; - char *line; - int c; /* char is unsigned on some archs, EOF is -ve */ - int linelen = 0; - int linesize = 50; - - if (readlineContext->osd) - return osdReadline(prompt, readlineContext); - - free(readlineContext->line); - readlineContext->line = NULL; - if ((in = readlineContext->in) == NULL) { - in = stdin; - if (prompt) { - fputs(prompt, stdout); - fflush(stdout); - } - } - line = (char *)malloc(linesize); - if (line == NULL) { - printf("Out of memory!\n"); - return NULL; - } - while ((c = getc(in)) != '\n') { - if (c == EOF) { - if (ferror(in)) { - if ((errno == EINTR) || (errno == EPIPE)) { - clearerr(in); - continue; - } - } - free (line); - return NULL; - } - if ((linelen + 1) >= linesize) { - char *cp; - - linesize += 50; - cp = (char *)realloc(line, linesize); - if (cp == NULL) { - printf("Out of memory!\n"); - free(line); - return NULL; - } - line = cp; - } - line[linelen++] = c; - } - line[linelen] = '\0'; - readlineContext->line = line; - return line; -} - -/* - * Destroy a command-line context - */ -void epicsShareAPI -epicsReadlineEnd (void *context) -{ - if (context) { - struct readlineContext *readlineContext = context; - - if (readlineContext->osd) - osdReadlineEnd(readlineContext); - else - free(readlineContext->line); - free(readlineContext); - } -} - diff --git a/src/libCom/osi/epicsReadline.h b/src/libCom/osi/epicsReadline.h deleted file mode 100644 index 1d0e8b761..000000000 --- a/src/libCom/osi/epicsReadline.h +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef INC_epicsReadline_H -#define INC_epicsReadline_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -epicsShareFunc void * epicsShareAPI epicsReadlineBegin (FILE *in); -epicsShareFunc char * epicsShareAPI epicsReadline (const char *prompt, void *context); -epicsShareFunc void epicsShareAPI epicsReadlineEnd (void *context); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsReadline_H */ diff --git a/src/libCom/osi/epicsSignal.h b/src/libCom/osi/epicsSignal.h deleted file mode 100644 index 79adf71d1..000000000 --- a/src/libCom/osi/epicsSignal.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2002 The University of Chicago, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_epicsSignal_H -#define INC_epicsSignal_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -/* - * The requests in this interface are typically ignored on OS that do not implement - * POSIX signals. - */ - -struct epicsThreadOSD; - -/* - * Required to avoid problems with soft IOCs getting SIGHUPs when a - * Channel Access client disconnects - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore ( void ); - -/* - * Required to avoid terminating a process which is blocking in a - * socket send() call when the SIGPIPE signal is generated by the OS. - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore ( void ); - -/* - * required only if shutdown() and close() do not interrupt a thread blocking in - * a socket system call - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void ); -epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm ( struct epicsThreadOSD * ); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsSignal_H */ diff --git a/src/libCom/osi/epicsSpin.h b/src/libCom/osi/epicsSpin.h deleted file mode 100644 index 22ce8ec8f..000000000 --- a/src/libCom/osi/epicsSpin.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsSpinh -#define epicsSpinh - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct epicsSpin *epicsSpinId; - -epicsShareFunc epicsSpinId epicsSpinCreate(void); -epicsShareFunc epicsSpinId epicsSpinMustCreate(void); -epicsShareFunc void epicsSpinDestroy(epicsSpinId); - -epicsShareFunc void epicsSpinLock(epicsSpinId); -epicsShareFunc int epicsSpinTryLock(epicsSpinId); -epicsShareFunc void epicsSpinUnlock(epicsSpinId); - -#ifdef __cplusplus -} -#endif - -#endif /* epicsSpinh */ diff --git a/src/libCom/osi/epicsStackTrace.c b/src/libCom/osi/epicsStackTrace.c deleted file mode 100644 index 0fe6928c4..000000000 --- a/src/libCom/osi/epicsStackTrace.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsThread.h" -#include "epicsMutex.h" -#include "errlog.h" -#include "epicsStackTracePvt.h" -#include "epicsStackTrace.h" - -/* How many stack frames to capture */ -#define MAXDEPTH 100 - -static epicsThreadOnceId stackTraceInitId = EPICS_THREAD_ONCE_INIT; -static epicsMutexId stackTraceMtx; - -static void stackTraceInit(void *unused) -{ - stackTraceMtx = epicsMutexMustCreate(); -} - -static void stackTraceLock(void) -{ - epicsThreadOnce( &stackTraceInitId, stackTraceInit, 0 ); - epicsMutexLock( stackTraceMtx ); -} - -static void stackTraceUnlock(void) -{ - epicsMutexUnlock( stackTraceMtx ); -} - -static int -dumpInfo(void *addr, epicsSymbol *sym_p) -{ -int rval = 0; - - rval += errlogPrintf("[%*p]", (int)(sizeof(addr)*2 + 2), addr); - if ( sym_p ) { - if ( sym_p->f_nam ) { - rval += errlogPrintf(": %s", sym_p->f_nam); - } - if ( sym_p->s_nam ) { - rval += errlogPrintf("(%s+0x%lx)", sym_p->s_nam, (unsigned long)((char*)addr - (char*)sym_p->s_val)); - } else { - rval += errlogPrintf("()"); - } - } - rval += errlogPrintf("\n"); - errlogFlush(); - - return rval; -} - -void epicsStackTrace(void) -{ -void **buf; -int i,n; -epicsSymbol sym; - - if ( 0 == epicsStackTraceGetFeatures() ) { - /* unsupported on this platform */ - return; - } - - if ( ! (buf = malloc(sizeof(*buf) * MAXDEPTH))) { - free(buf); - errlogPrintf("epicsStackTrace(): not enough memory for backtrace\n"); - return; - } - - n = epicsBackTrace(buf, MAXDEPTH); - - if ( n > 0 ) { - - stackTraceLock(); - - errlogPrintf("Dumping a stack trace of thread '%s':\n", epicsThreadGetNameSelf()); - - errlogFlush(); - - for ( i=0; i, 2011, 2014 - */ - -#ifndef INC_epicsStackTrace_H -#define INC_epicsStackTrace_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Dump a stack trace to the errlog */ -epicsShareFunc void epicsStackTrace(void); - -/* Inquire about functionality implemented on your system */ - -/* StackTrace provides numerical addresses */ -#define EPICS_STACKTRACE_ADDRESSES (1<<0) - -/* StackTrace is able to lookup dynamic symbols */ -#define EPICS_STACKTRACE_DYN_SYMBOLS (1<<1) - -/* StackTrace is able to lookup global symbols */ -#define EPICS_STACKTRACE_GBL_SYMBOLS (1<<2) - -/* StackTrace is able to lookup local symbols */ -#define EPICS_STACKTRACE_LCL_SYMBOLS (1<<3) - -/* returns ORed bitset of supported features */ -epicsShareFunc int epicsStackTraceGetFeatures(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/osi/epicsStackTracePvt.h b/src/libCom/osi/epicsStackTracePvt.h deleted file mode 100644 index de26044fa..000000000 --- a/src/libCom/osi/epicsStackTracePvt.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#ifndef INC_epicsStackTracePvt_H -#define INC_epicsStackTracePvt_H - -#include "shareLib.h" - -typedef struct epicsSymbol { - const char *f_nam; /* file where the symbol is defined */ - const char *s_nam; /* symbol name */ - void *s_val; /* symbol value */ -} epicsSymbol; - -#ifdef __cplusplus -extern "C" { -#endif - -/* Take a snapshot of the stack into 'buf' (limited to buf_sz entries) - * RETURNS: actual number of entries in 'buf' - */ -epicsShareFunc int epicsBackTrace(void **buf, int buf_sz); - -/* Find symbol closest to 'addr'. - * - * If successful the routine fills in the members of *sym_p but - * note that 'f_nam' and/or 's_nam' may be NULL if the address - * cannot be resolved. - * - * RETURNS: 0 on success, nonzero on failure (not finding an address - * is not considered an error). - */ -epicsShareFunc int epicsFindAddr(void *addr, epicsSymbol *sym_p); - -/* report supported features (as reported by epicsStackTraceGetFeatures) */ -epicsShareFunc int epicsFindAddrGetFeatures(); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/osi/epicsStdio.c b/src/libCom/osi/epicsStdio.c deleted file mode 100644 index 52b65bbe4..000000000 --- a/src/libCom/osi/epicsStdio.c +++ /dev/null @@ -1,129 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* epicsStdio.c */ - -/* Author: Marty Kraimer */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#define epicsStdioStdStreams -#include "shareLib.h" -#include "epicsThread.h" -#include "epicsStdio.h" - -static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; -static epicsThreadPrivateId stdinThreadPrivateId; -static epicsThreadPrivateId stdoutThreadPrivateId; -static epicsThreadPrivateId stderrThreadPrivateId = 0; - -static void once(void *junk) -{ - stdinThreadPrivateId = epicsThreadPrivateCreate(); - stdoutThreadPrivateId = epicsThreadPrivateCreate(); - stderrThreadPrivateId = epicsThreadPrivateCreate(); -} - -FILE * epicsShareAPI epicsGetStdin(void) -{ - FILE *fp = epicsGetThreadStdin(); - - if (!fp) - fp = stdin; - return fp; -} - -FILE * epicsShareAPI epicsGetStdout(void) -{ - FILE *fp = epicsGetThreadStdout(); - - if (!fp) - fp = stdout; - return fp; -} - -FILE * epicsShareAPI epicsGetStderr(void) -{ - FILE *fp = epicsGetThreadStderr(); - - if (!fp) - fp = stderr; - return fp; -} - -FILE * epicsShareAPI epicsGetThreadStdin(void) -{ - epicsThreadOnce(&onceId,once,0); - return epicsThreadPrivateGet(stdinThreadPrivateId); -} - -FILE * epicsShareAPI epicsGetThreadStdout(void) -{ - epicsThreadOnce(&onceId,once,0); - return epicsThreadPrivateGet(stdoutThreadPrivateId); -} - -FILE * epicsShareAPI epicsGetThreadStderr(void) -{ - /* Deliberately don't do the epicsThreadOnce() here; epicsThreadInit() - * is allowed to use stderr inside its once() routine, in which case we - * must return the OS's stderr instead. There may be a tiny chance of a - * race happening here during initialization for some architectures, so - * we only use it for stderr to reduce the chance of that happening. - */ - if (!stderrThreadPrivateId) - return NULL; - return epicsThreadPrivateGet(stderrThreadPrivateId); -} - -void epicsShareAPI epicsSetThreadStdin(FILE *fp) -{ - epicsThreadOnce(&onceId,once,0); - epicsThreadPrivateSet(stdinThreadPrivateId,fp); -} - -void epicsShareAPI epicsSetThreadStdout(FILE *fp) -{ - epicsThreadOnce(&onceId,once,0); - epicsThreadPrivateSet(stdoutThreadPrivateId,fp); -} - -void epicsShareAPI epicsSetThreadStderr(FILE *fp) -{ - epicsThreadOnce(&onceId,once,0); - epicsThreadPrivateSet(stderrThreadPrivateId,fp); -} - -int epicsShareAPI epicsStdoutPrintf(const char *pFormat, ...) -{ - va_list pvar; - int nchar; - FILE *stream = epicsGetStdout(); - - va_start(pvar, pFormat); - nchar = vfprintf(stream, pFormat, pvar); - va_end(pvar); - return nchar; -} - -int epicsShareAPI epicsStdoutPuts(const char *str) -{ - return fprintf(epicsGetStdout(), "%s\n", str); -} - -int epicsShareAPI epicsStdoutPutchar(int c) -{ - return putc(c, epicsGetStdout()); -} diff --git a/src/libCom/osi/epicsStdio.h b/src/libCom/osi/epicsStdio.h deleted file mode 100644 index 172d5cf87..000000000 --- a/src/libCom/osi/epicsStdio.h +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* epicsStdio.h */ - -#ifndef epicsStdioh -#define epicsStdioh - -#include -#include - -#include "shareLib.h" -#include "compilerDependencies.h" -#include "epicsTempFile.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef epicsStdioStdStreams -# undef stdin -# define stdin epicsGetStdin() -# undef stdout -# define stdout epicsGetStdout() -# undef stderr -# define stderr epicsGetStderr() -#endif - -/* Make printf, puts and putchar use *our* version of stdout */ - -#ifdef printf -# undef printf -#endif /* printf */ -#define printf epicsStdoutPrintf - -#ifdef puts -# undef puts -#endif /* puts */ -#define puts epicsStdoutPuts - -#ifdef putchar -# undef putchar -#endif /* putchar */ -#define putchar epicsStdoutPutchar - -epicsShareFunc int epicsShareAPI epicsSnprintf( - char *str, size_t size, const char *format, ...) EPICS_PRINTF_STYLE(3,4); -epicsShareFunc int epicsShareAPI epicsVsnprintf( - char *str, size_t size, const char *format, va_list ap); - -/* - * truncate to specified size (we dont use truncate() - * because it is not portable) - * - * pFileName - name (and optionally path) of file - * size - the new file size (if file is curretly larger) - * - * returns TF_OK if the file is less than size bytes - * or if it was successfully truncated. Returns - * TF_ERROR if the file could not be truncated. - */ -enum TF_RETURN {TF_OK=0, TF_ERROR=1}; -epicsShareFunc enum TF_RETURN truncateFile ( const char *pFileName, unsigned long size ); - -/* The following are for redirecting stdin,stdout,stderr */ -epicsShareFunc FILE * epicsShareAPI epicsGetStdin(void); -epicsShareFunc FILE * epicsShareAPI epicsGetStdout(void); -epicsShareFunc FILE * epicsShareAPI epicsGetStderr(void); -/* These are intended for iocsh only */ -epicsShareFunc FILE * epicsShareAPI epicsGetThreadStdin(void); -epicsShareFunc FILE * epicsShareAPI epicsGetThreadStdout(void); -epicsShareFunc FILE * epicsShareAPI epicsGetThreadStderr(void); -epicsShareFunc void epicsShareAPI epicsSetThreadStdin(FILE *); -epicsShareFunc void epicsShareAPI epicsSetThreadStdout(FILE *); -epicsShareFunc void epicsShareAPI epicsSetThreadStderr(FILE *); - -epicsShareFunc int epicsShareAPI epicsStdoutPrintf( - const char *pformat, ...) EPICS_PRINTF_STYLE(1,2); -epicsShareFunc int epicsShareAPI epicsStdoutPuts(const char *str); -epicsShareFunc int epicsShareAPI epicsStdoutPutchar(int c); - -#ifdef __cplusplus -} -#endif - -#endif /* epicsStdioh */ diff --git a/src/libCom/osi/epicsStdioRedirect.h b/src/libCom/osi/epicsStdioRedirect.h deleted file mode 100644 index 6f99cc9a5..000000000 --- a/src/libCom/osi/epicsStdioRedirect.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* epicsStdioRedirect.h */ - -/* This file is now obselete, and is likely to be - * deleted in a future release of EPICS Base. - * - * Use the epicsStdio.h header file instead. - */ - -#ifndef epicsStdioRedirecth -#define epicsStdioRedirecth - -#include - -#endif /* epicsStdioRedirecth */ diff --git a/src/libCom/osi/epicsTempFile.h b/src/libCom/osi/epicsTempFile.h deleted file mode 100644 index c48e336ec..000000000 --- a/src/libCom/osi/epicsTempFile.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* epicsTempFile.h */ - -#ifndef INC_epicsTempFile_H -#define INC_epicsTempFile_H - -#include - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void epicsShareAPI epicsTempName(char *pbuf, size_t bufLen); -epicsShareFunc FILE * epicsShareAPI epicsTempFile(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsTempFile_H */ diff --git a/src/libCom/osi/epicsThread.cpp b/src/libCom/osi/epicsThread.cpp deleted file mode 100644 index 892d73de0..000000000 --- a/src/libCom/osi/epicsThread.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// Author: Jeff Hill -// - -#include -#include - -#include -#include -#include -#include - -// The following is required for Solaris builds -#undef __EXTENSIONS__ - -#define epicsExportSharedSymbols -#include "epicsAlgorithm.h" -#include "epicsTime.h" -#include "epicsThread.h" -#include "epicsAssert.h" -#include "epicsGuard.h" -#include "errlog.h" - -using namespace std; - -epicsThreadRunable::~epicsThreadRunable () {} -void epicsThreadRunable::run () {} -void epicsThreadRunable::show ( unsigned int ) const {} - -class epicsThread :: unableToCreateThread : - public std :: exception { -public: - const char * what () const throw (); -}; - -const char * epicsThread :: - unableToCreateThread :: what () const throw () -{ - return "unable to create thread"; -} - -void epicsThread :: printLastChanceExceptionMessage ( - const char * pExceptionTypeName, - const char * pExceptionContext ) -{ - char date[64]; - try { - epicsTime cur = epicsTime :: getCurrent (); - cur.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S.%f"); - } - catch ( ... ) { - strcpy ( date, "" ); - } - char name [128]; - epicsThreadGetName ( this->id, name, sizeof ( name ) ); - errlogPrintf ( - "epicsThread: Unexpected C++ exception \"%s\" " - "with type \"%s\" in thread \"%s\" at %s\n", - pExceptionContext, pExceptionTypeName, name, date ); - errlogFlush (); - // This behavior matches the C++ implementation when an exception - // isn't handled by the thread code. Users can install their own - // application-specific unexpected handler if preferred. - std::unexpected (); -} - -extern "C" void epicsThreadCallEntryPoint ( void * pPvt ) -{ - epicsThread * pThread = - static_cast ( pPvt ); - bool threadDestroyed = false; - try { - pThread->pThreadDestroyed = & threadDestroyed; - if ( pThread->beginWait () ) { - pThread->runable.run (); - // The run() routine may have destroyed the epicsThread - // object by now; pThread can only be used below here - // when the threadDestroyed flag is false. - } - } - catch ( const epicsThread::exitException & ) { - } - catch ( std :: exception & except ) { - if ( ! threadDestroyed ) { - pThread->printLastChanceExceptionMessage ( - typeid ( except ).name (), except.what () ); - } - } - catch ( ... ) { - if ( ! threadDestroyed ) { - pThread->printLastChanceExceptionMessage ( - "catch ( ... )", "Non-standard C++ exception" ); - } - } - if ( ! threadDestroyed ) { - epicsGuard < epicsMutex > guard ( pThread->mutex ); - pThread->pThreadDestroyed = NULL; - pThread->terminated = true; - pThread->exitEvent.signal (); - // After the terminated flag is set and guard's destructor - // releases the lock, pThread must never be used again. - } -} - -bool epicsThread::beginWait () throw () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - while ( ! this->begin && ! this->cancel ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->event.wait (); - } - return this->begin && ! this->cancel; -} - -void epicsThread::exit () -{ - throw exitException (); -} - -void epicsThread::exitWait () throw () -{ - bool success = this->exitWait ( DBL_MAX ); - assert ( success ); -} - -bool epicsThread::exitWait ( const double delay ) throw () -{ - try { - // When called (usually by a destructor) in the context of - // the managed thread we can't wait for the thread to exit. - // Set the threadDestroyed flag and return success. - if ( this->isCurrentThread() ) { - if ( this->pThreadDestroyed ) { - *this->pThreadDestroyed = true; - } - return true; - } - epicsTime exitWaitBegin = epicsTime::getCurrent (); - double exitWaitElapsed = 0.0; - epicsGuard < epicsMutex > guard ( this->mutex ); - this->cancel = true; - while ( ! this->terminated && exitWaitElapsed < delay ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->event.signal (); - this->exitEvent.wait ( delay - exitWaitElapsed ); - epicsTime current = epicsTime::getCurrent (); - exitWaitElapsed = current - exitWaitBegin; - } - } - catch ( std :: exception & except ) { - errlogPrintf ( - "epicsThread::exitWait(): Unexpected exception " - " \"%s\"\n", - except.what () ); - epicsThreadSleep ( epicsMin ( delay, 5.0 ) ); - } - catch ( ... ) { - errlogPrintf ( - "Non-standard unexpected exception in " - "epicsThread::exitWait()\n" ); - epicsThreadSleep ( epicsMin ( delay, 5.0 ) ); - } - // the event mechanism is used for other purposes - this->event.signal (); - return this->terminated; -} - -epicsThread::epicsThread ( - epicsThreadRunable & runableIn, const char * pName, - unsigned stackSize, unsigned priority ) : - runable ( runableIn ), id ( 0 ), pThreadDestroyed ( 0 ), - begin ( false ), cancel ( false ), terminated ( false ) -{ - this->id = epicsThreadCreate ( - pName, priority, stackSize, epicsThreadCallEntryPoint, - static_cast < void * > ( this ) ); - if ( ! this->id ) { - throw unableToCreateThread (); - } -} - -epicsThread::~epicsThread () throw () -{ - while ( ! this->exitWait ( 10.0 ) ) { - char nameBuf [256]; - this->getName ( nameBuf, sizeof ( nameBuf ) ); - fprintf ( stderr, - "epicsThread::~epicsThread(): " - "blocking for thread \"%s\" to exit\n", - nameBuf ); - fprintf ( stderr, - "was epicsThread object destroyed before thread exit ?\n"); - } -} - -void epicsThread::start () throw () -{ - { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->begin = true; - } - this->event.signal (); -} - -bool epicsThread::isCurrentThread () const throw () -{ - return ( epicsThreadGetIdSelf () == this->id ); -} - -void epicsThread::resume () throw () -{ - epicsThreadResume ( this->id ); -} - -void epicsThread::getName ( char *name, size_t size ) const throw () -{ - epicsThreadGetName ( this->id, name, size ); -} - -epicsThreadId epicsThread::getId () const throw () -{ - return this->id; -} - -unsigned int epicsThread::getPriority () const throw () -{ - return epicsThreadGetPriority (this->id); -} - -void epicsThread::setPriority (unsigned int priority) throw () -{ - epicsThreadSetPriority (this->id, priority); -} - -bool epicsThread::priorityIsEqual (const epicsThread &otherThread) const throw () -{ - if ( epicsThreadIsEqual (this->id, otherThread.id) ) { - return true; - } - return false; -} - -bool epicsThread::isSuspended () const throw () -{ - if ( epicsThreadIsSuspended (this->id) ) { - return true; - } - return false; -} - -bool epicsThread::operator == (const epicsThread &rhs) const throw () -{ - return (this->id == rhs.id); -} - -void epicsThread::suspendSelf () throw () -{ - epicsThreadSuspendSelf (); -} - -void epicsThread::sleep (double seconds) throw () -{ - epicsThreadSleep (seconds); -} - -const char *epicsThread::getNameSelf () throw () -{ - return epicsThreadGetNameSelf (); -} - -bool epicsThread::isOkToBlock () throw () -{ - return epicsThreadIsOkToBlock() != 0; -} - -void epicsThread::setOkToBlock(bool isOkToBlock) throw () -{ - epicsThreadSetOkToBlock(static_cast(isOkToBlock)); -} - -void epicsThreadPrivateBase::throwUnableToCreateThreadPrivate () -{ - throw epicsThreadPrivateBase::unableToCreateThreadPrivate (); -} - -void epicsThread :: show ( unsigned level ) const throw () -{ - ::printf ( "epicsThread at %p\n", this->id ); - if ( level > 0u ) { - epicsThreadShow ( this->id, level - 1 ); - if ( level > 1u ) { - ::printf ( "pThreadDestroyed = %p\n", this->pThreadDestroyed ); - ::printf ( "begin = %c, cancel = %c, terminated = %c\n", - this->begin ? 'T' : 'F', - this->cancel ? 'T' : 'F', - this->terminated ? 'T' : 'F' ); - this->runable.show ( level - 2u ); - this->mutex.show ( level - 2u ); - ::printf ( "general purpose event\n" ); - this->event.show ( level - 2u ); - ::printf ( "exit event\n" ); - this->exitEvent.show ( level - 2u ); - } - } -} - -extern "C" { - static epicsThreadOnceId okToBlockOnce = EPICS_THREAD_ONCE_INIT; - epicsThreadPrivateId okToBlockPrivate; - static const int okToBlockNo = 0; - static const int okToBlockYes = 1; - - static void epicsThreadOnceIdInit(void *) - { - okToBlockPrivate = epicsThreadPrivateCreate(); - } - - int epicsShareAPI epicsThreadIsOkToBlock(void) - { - const int *pokToBlock; - epicsThreadOnce(&okToBlockOnce, epicsThreadOnceIdInit, NULL); - pokToBlock = (int *) epicsThreadPrivateGet(okToBlockPrivate); - return (pokToBlock ? *pokToBlock : 0); - } - - void epicsShareAPI epicsThreadSetOkToBlock(int isOkToBlock) - { - const int *pokToBlock; - epicsThreadOnce(&okToBlockOnce, epicsThreadOnceIdInit, NULL); - pokToBlock = (isOkToBlock) ? &okToBlockYes : &okToBlockNo; - epicsThreadPrivateSet(okToBlockPrivate, (void *)pokToBlock); - } - - epicsThreadId epicsShareAPI epicsThreadMustCreate ( - const char *name, unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) - { - epicsThreadId id = epicsThreadCreate ( - name, priority, stackSize, funptr, parm ); - assert ( id ); - return id; - } -} // extern "C" - -// Ensure the main thread gets a unique ID -epicsThreadId epicsThreadMainId = epicsThreadGetIdSelf(); diff --git a/src/libCom/osi/epicsThread.h b/src/libCom/osi/epicsThread.h deleted file mode 100644 index 84b2c4788..000000000 --- a/src/libCom/osi/epicsThread.h +++ /dev/null @@ -1,247 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2013 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef epicsThreadh -#define epicsThreadh - -#include - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*EPICSTHREADFUNC)(void *parm); - -#define epicsThreadPriorityMax 99 -#define epicsThreadPriorityMin 0 - -/* some generic values */ -#define epicsThreadPriorityLow 10 -#define epicsThreadPriorityMedium 50 -#define epicsThreadPriorityHigh 90 - -/* some iocCore specific values */ -#define epicsThreadPriorityCAServerLow 20 -#define epicsThreadPriorityCAServerHigh 40 -#define epicsThreadPriorityScanLow 60 -#define epicsThreadPriorityScanHigh 70 -#define epicsThreadPriorityIocsh 91 -#define epicsThreadPriorityBaseMax 91 - -/* stack sizes for each stackSizeClass are implementation and CPU dependent */ -typedef enum { - epicsThreadStackSmall, epicsThreadStackMedium, epicsThreadStackBig -} epicsThreadStackSizeClass; - -typedef enum { - epicsThreadBooleanStatusFail, epicsThreadBooleanStatusSuccess -} epicsThreadBooleanStatus; - -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize( - epicsThreadStackSizeClass size); - -/* (epicsThreadId)0 is guaranteed to be an invalid thread id */ -typedef struct epicsThreadOSD *epicsThreadId; - -typedef epicsThreadId epicsThreadOnceId; -#define EPICS_THREAD_ONCE_INIT 0 - -epicsShareFunc void epicsShareAPI epicsThreadOnce( - epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg); - -/* When real-time scheduling is active, attempt any post-init operations - * that preserve real-time performance. For POSIX targets this locks the - * process into RAM, preventing swap-related VM faults. - */ -epicsShareFunc void epicsThreadRealtimeLock(void); - -epicsShareFunc void epicsShareAPI epicsThreadExitMain(void); - -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate ( - const char * name, unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void * parm ); -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadMustCreate ( - const char * name, unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void * parm ); -epicsShareFunc void epicsShareAPI epicsThreadSuspendSelf(void); -epicsShareFunc void epicsShareAPI epicsThreadResume(epicsThreadId id); -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPriority( - epicsThreadId id); -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPrioritySelf(void); -epicsShareFunc void epicsShareAPI epicsThreadSetPriority( - epicsThreadId id,unsigned int priority); -epicsShareFunc epicsThreadBooleanStatus epicsShareAPI - epicsThreadHighestPriorityLevelBelow ( - unsigned int priority, unsigned *pPriorityJustBelow); -epicsShareFunc epicsThreadBooleanStatus epicsShareAPI - epicsThreadLowestPriorityLevelAbove ( - unsigned int priority, unsigned *pPriorityJustAbove); -epicsShareFunc int epicsShareAPI epicsThreadIsEqual( - epicsThreadId id1, epicsThreadId id2); -epicsShareFunc int epicsShareAPI epicsThreadIsSuspended(epicsThreadId id); -epicsShareFunc void epicsShareAPI epicsThreadSleep(double seconds); -epicsShareFunc double epicsShareAPI epicsThreadSleepQuantum(void); -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetIdSelf(void); -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetId(const char *name); -epicsShareFunc int epicsThreadGetCPUs(void); - -epicsShareFunc const char * epicsShareAPI epicsThreadGetNameSelf(void); - -/* For epicsThreadGetName name is guaranteed to be null terminated */ -/* size is size of buffer to hold name (including terminator) */ -/* Failure results in an empty string stored in name */ -epicsShareFunc void epicsShareAPI epicsThreadGetName( - epicsThreadId id, char *name, size_t size); - -epicsShareFunc int epicsShareAPI epicsThreadIsOkToBlock(void); -epicsShareFunc void epicsShareAPI epicsThreadSetOkToBlock(int isOkToBlock); - -epicsShareFunc void epicsShareAPI epicsThreadShowAll(unsigned int level); -epicsShareFunc void epicsShareAPI epicsThreadShow( - epicsThreadId id,unsigned int level); - -/* Hooks called when a thread starts, map function called once for every thread */ -typedef void (*EPICS_THREAD_HOOK_ROUTINE)(epicsThreadId id); -epicsShareFunc int epicsThreadHookAdd(EPICS_THREAD_HOOK_ROUTINE hook); -epicsShareFunc int epicsThreadHookDelete(EPICS_THREAD_HOOK_ROUTINE hook); -epicsShareFunc void epicsThreadHooksShow(void); -epicsShareFunc void epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func); - -typedef struct epicsThreadPrivateOSD * epicsThreadPrivateId; -epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate(void); -epicsShareFunc void epicsShareAPI epicsThreadPrivateDelete(epicsThreadPrivateId id); -epicsShareFunc void epicsShareAPI epicsThreadPrivateSet(epicsThreadPrivateId,void *); -epicsShareFunc void * epicsShareAPI epicsThreadPrivateGet(epicsThreadPrivateId); - -#ifdef __cplusplus -} -#endif - -#ifdef __cplusplus - -#include "epicsEvent.h" -#include "epicsMutex.h" - -class epicsShareClass epicsThreadRunable { -public: - virtual ~epicsThreadRunable () = 0; - virtual void run () = 0; - virtual void show ( unsigned int level ) const; -}; - -extern "C" void epicsThreadCallEntryPoint ( void * ); - -class epicsShareClass epicsThread { -public: - epicsThread ( epicsThreadRunable &,const char *name, unsigned int stackSize, - unsigned int priority=epicsThreadPriorityLow ); - ~epicsThread () throw (); - void start () throw (); - void exitWait () throw (); - bool exitWait ( const double delay ) throw (); - static void exit (); - void resume () throw (); - void getName ( char * name, size_t size ) const throw (); - epicsThreadId getId () const throw (); - unsigned int getPriority () const throw (); - void setPriority ( unsigned int ) throw (); - bool priorityIsEqual ( const epicsThread & ) const throw (); - bool isSuspended () const throw (); - bool isCurrentThread () const throw (); - bool operator == ( const epicsThread & ) const throw (); - void show ( unsigned level ) const throw (); - - /* these operate on the current thread */ - static void suspendSelf () throw (); - static void sleep (double seconds) throw (); - static const char * getNameSelf () throw (); - static bool isOkToBlock () throw (); - static void setOkToBlock ( bool isOkToBlock ) throw (); - - /* exceptions */ - class unableToCreateThread; -private: - epicsThreadRunable & runable; - epicsThreadId id; - epicsMutex mutex; - epicsEvent event; - epicsEvent exitEvent; - bool * pThreadDestroyed; - bool begin; - bool cancel; - bool terminated; - - bool beginWait () throw (); - epicsThread ( const epicsThread & ); - epicsThread & operator = ( const epicsThread & ); - friend void epicsThreadCallEntryPoint ( void * ); - void printLastChanceExceptionMessage ( - const char * pExceptionTypeName, - const char * pExceptionContext ); - /* exceptions */ - class exitException {}; -}; - -class epicsShareClass epicsThreadPrivateBase { -public: - class unableToCreateThreadPrivate {}; /* exception */ -protected: - static void throwUnableToCreateThreadPrivate (); -}; - -template < class T > -class epicsThreadPrivate : - private epicsThreadPrivateBase { -public: - epicsThreadPrivate (); - ~epicsThreadPrivate () throw (); - T * get () const throw (); - void set (T *) throw (); -private: - epicsThreadPrivateId id; -}; - -#endif /* __cplusplus */ - -#include "osdThread.h" - -#ifdef __cplusplus - -template -inline epicsThreadPrivate::epicsThreadPrivate () -{ - this->id = epicsThreadPrivateCreate (); - if ( this->id == 0 ) { - epicsThreadPrivateBase::throwUnableToCreateThreadPrivate (); - } -} - -template -inline epicsThreadPrivate::~epicsThreadPrivate () throw () -{ - epicsThreadPrivateDelete ( this->id ); -} - -template -inline T *epicsThreadPrivate::get () const throw () -{ - return static_cast ( epicsThreadPrivateGet (this->id) ); -} - -template -inline void epicsThreadPrivate::set (T *pIn) throw () -{ - epicsThreadPrivateSet ( this->id, static_cast (pIn) ); -} - -#endif /* ifdef __cplusplus */ - -#endif /* epicsThreadh */ diff --git a/src/libCom/osi/epicsTime.cpp b/src/libCom/osi/epicsTime.cpp deleted file mode 100644 index 6dd1d3f97..000000000 --- a/src/libCom/osi/epicsTime.cpp +++ /dev/null @@ -1,1133 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsTime.cpp */ -/* Author Jeffrey O. Hill */ - -// Notes: -// 1) The epicsTime::nSec field is not public and so it could be -// changed to work more like the fractional seconds field in the NTP time -// stamp. That would significantly improve the precision of epicsTime on -// 64 bit architectures. -// - -#include - -#include -#include -#include -#include -#include -#include -#include // vxWorks 6.0 requires this include - -#define epicsExportSharedSymbols -#include "locationException.h" -#include "epicsAssert.h" -#include "epicsVersion.h" -#include "envDefs.h" -#include "epicsTime.h" -#include "osiSock.h" /* pull in struct timeval */ -#include "epicsStdio.h" - -static const char pEpicsTimeVersion[] = - "@(#) " EPICS_VERSION_STRING ", Common Utilities Library " __DATE__; - -// -// useful public constants -// -static const unsigned mSecPerSec = 1000u; -static const unsigned uSecPerMSec = 1000u; -static const unsigned uSecPerSec = uSecPerMSec * mSecPerSec; -static const unsigned nSecPerUSec = 1000u; -static const unsigned nSecPerSec = nSecPerUSec * uSecPerSec; -static const unsigned nSecFracDigits = 9u; - - -// Timescale conversion data - -static const unsigned long NTP_TIME_AT_POSIX_EPOCH = 2208988800ul; -static const unsigned long NTP_TIME_AT_EPICS_EPOCH = - NTP_TIME_AT_POSIX_EPOCH + POSIX_TIME_AT_EPICS_EPOCH; - -// -// epicsTime (const unsigned long secIn, const unsigned long nSecIn) -// -inline epicsTime::epicsTime (const unsigned long secIn, const unsigned long nSecIn) : - secPastEpoch ( secIn ), nSec ( nSecIn ) -{ - if (nSecIn >= nSecPerSec) { - this->secPastEpoch += nSecIn / nSecPerSec; - this->nSec = nSecIn % nSecPerSec; - } -} - -// -// epicsTimeLoadTimeInit -// -class epicsTimeLoadTimeInit { -public: - epicsTimeLoadTimeInit (); - double epicsEpochOffset; // seconds - double time_tSecPerTick; // seconds (both NTP and EPICS use int sec) - unsigned long epicsEpochOffsetAsAnUnsignedLong; - bool useDiffTimeOptimization; -}; - -// -// epicsTimeLoadTimeInit () -// -epicsTimeLoadTimeInit::epicsTimeLoadTimeInit () -{ - // All we know about time_t is that it is an arithmetic type. - time_t t_zero = static_cast (0); - time_t t_one = static_cast (1); - this->time_tSecPerTick = difftime (t_one, t_zero); - - /* The EPICS epoch (1/1/1990 00:00:00UTC) was 631152000 seconds after - * the ANSI epoch (1/1/1970 00:00:00UTC) - * Convert this offset into time_t units, however this must not be - * calculated using local time (i.e. using mktime() or similar), since - * in the UK the ANSI Epoch had daylight saving time in effect, and - * the value calculated would be 3600 seconds wrong.*/ - this->epicsEpochOffset = - (double) POSIX_TIME_AT_EPICS_EPOCH / this->time_tSecPerTick; - - if (this->time_tSecPerTick == 1.0 && - this->epicsEpochOffset <= ULONG_MAX && - this->epicsEpochOffset >= 0) { - // We can use simpler code on Posix-compliant systems - this->useDiffTimeOptimization = true; - this->epicsEpochOffsetAsAnUnsignedLong = - static_cast(this->epicsEpochOffset); - } else { - // Forced to use the slower but correct code - this->useDiffTimeOptimization = false; - this->epicsEpochOffsetAsAnUnsignedLong = 0; - } -} - -// -// private epicsTime::addNanoSec () -// -// Most formats keep the nSec value as an unsigned long, so are +ve. -// struct timeval's tv_usec may be -1, but I think that means error, -// so this private method never needs to handle -ve offsets. -// -void epicsTime :: addNanoSec ( long nSecAdj ) -{ - if (nSecAdj <= 0) - return; - - if (static_cast(nSecAdj) >= nSecPerSec) { - this->secPastEpoch += nSecAdj / nSecPerSec; - nSecAdj %= nSecPerSec; - } - - this->nSec += nSecAdj; // Can't overflow - if (this->nSec >= nSecPerSec) { - this->secPastEpoch++; - this->nSec -= nSecPerSec; - } -} - -// -// epicsTime (const time_t_wrapper &tv) -// -epicsTime::epicsTime ( const time_t_wrapper & ansiTimeTicks ) -{ - // avoid c++ static initialization order issues - static epicsTimeLoadTimeInit & lti = * new epicsTimeLoadTimeInit (); - - // - // try to directly map time_t into an unsigned long integer because this is - // faster on systems w/o hardware floating point and a simple integer type time_t. - // - if ( lti.useDiffTimeOptimization ) { - // LONG_MAX is used here and not ULONG_MAX because some systems (linux) - // still store time_t as a long. - if ( ansiTimeTicks.ts > 0 && ansiTimeTicks.ts <= LONG_MAX ) { - unsigned long ticks = static_cast < unsigned long > ( ansiTimeTicks.ts ); - if ( ticks >= lti.epicsEpochOffsetAsAnUnsignedLong ) { - this->secPastEpoch = ticks - lti.epicsEpochOffsetAsAnUnsignedLong; - } - else { - this->secPastEpoch = ( ULONG_MAX - lti.epicsEpochOffsetAsAnUnsignedLong ) + ticks; - } - this->nSec = 0; - return; - } - } - - // - // otherwise map time_t, which ANSI C and POSIX define as any arithmetic type, - // into type double - // - double sec = ansiTimeTicks.ts * lti.time_tSecPerTick - lti.epicsEpochOffset; - - // - // map into the the EPICS time stamp range (which allows rollover) - // - static double uLongMax = static_cast (ULONG_MAX); - if ( sec < 0.0 ) { - if ( sec < -uLongMax ) { - sec = sec + static_cast ( -sec / uLongMax ) * uLongMax; - } - sec += uLongMax; - } - else if ( sec > uLongMax ) { - sec = sec - static_cast ( sec / uLongMax ) * uLongMax; - } - - this->secPastEpoch = static_cast ( sec ); - this->nSec = static_cast ( ( sec-this->secPastEpoch ) * nSecPerSec ); -} - -epicsTime::epicsTime (const epicsTimeStamp &ts) -{ - if ( ts.nsec < nSecPerSec ) { - this->secPastEpoch = ts.secPastEpoch; - this->nSec = ts.nsec; - } - else { - throw std::logic_error ( - "epicsTimeStamp has overflow in nano-seconds field" ); - } -} - -epicsTime::epicsTime () : - secPastEpoch(0u), nSec(0u) {} - -epicsTime::epicsTime (const epicsTime &t) : - secPastEpoch (t.secPastEpoch), nSec (t.nSec) {} - -epicsTime epicsTime::getCurrent () -{ - epicsTimeStamp current; - int status = epicsTimeGetCurrent (¤t); - if (status) { - throwWithLocation ( unableToFetchCurrentTime () ); - } - return epicsTime ( current ); -} - -epicsTime epicsTime::getEvent (const epicsTimeEvent &event) -{ - epicsTimeStamp current; - int status = epicsTimeGetEvent (¤t, event); - if (status) { - throwWithLocation ( unableToFetchCurrentTime () ); - } - return epicsTime ( current ); -} - -// -// operator time_t_wrapper () -// -epicsTime::operator time_t_wrapper () const -{ - // avoid c++ static initialization order issues - static epicsTimeLoadTimeInit & lti = * new epicsTimeLoadTimeInit (); - time_t_wrapper wrap; - - if ( lti.useDiffTimeOptimization ) { - if ( this->secPastEpoch < ULONG_MAX - lti.epicsEpochOffsetAsAnUnsignedLong ) { - wrap.ts = static_cast ( this->secPastEpoch + lti.epicsEpochOffsetAsAnUnsignedLong ); - return wrap; - } - } - - // - // map type double into time_t which ansi C defines as some arithmetic type - // - double tmp = (this->secPastEpoch + lti.epicsEpochOffset) / lti.time_tSecPerTick; - tmp += (this->nSec / lti.time_tSecPerTick) / nSecPerSec; - - wrap.ts = static_cast ( tmp ); - - return wrap; -} - -// -// convert to ANSI C struct tm (with nano seconds) adjusted for the local time zone -// -epicsTime::operator local_tm_nano_sec () const -{ - time_t_wrapper ansiTimeTicks = *this; - - local_tm_nano_sec tm; - - int status = epicsTime_localtime ( &ansiTimeTicks.ts, &tm.ansi_tm ); - if ( status ) { - throw std::logic_error ( "epicsTime_localtime failed" ); - } - - tm.nSec = this->nSec; - - return tm; -} - -// -// convert to ANSI C struct tm (with nano seconds) adjusted for UTC -// -epicsTime::operator gm_tm_nano_sec () const -{ - time_t_wrapper ansiTimeTicks = *this; - - gm_tm_nano_sec tm; - - int status = epicsTime_gmtime ( &ansiTimeTicks.ts, &tm.ansi_tm ); - if ( status ) { - throw std::logic_error ( "epicsTime_gmtime failed" ); - } - - tm.nSec = this->nSec; - - return tm; -} - -// -// epicsTime (const local_tm_nano_sec &tm) -// -epicsTime::epicsTime (const local_tm_nano_sec &tm) -{ - struct tm tmp = tm.ansi_tm; - time_t_wrapper ansiTimeTicks = { mktime (&tmp) }; - - static const time_t mktimeError = static_cast (-1); - if (ansiTimeTicks.ts == mktimeError) { - throwWithLocation ( formatProblemWithStructTM () ); - } - - *this = epicsTime(ansiTimeTicks); - this->addNanoSec(tm.nSec); -} - -// -// epicsTime (const gm_tm_nano_sec &tm) -// - -// do conversion avoiding the timezone mechanism -static inline int is_leap(int year) -{ - if (year % 400 == 0) - return 1; - if (year % 100 == 0) - return 0; - if (year % 4 == 0) - return 1; - return 0; -} - -static inline int days_from_0(int year) -{ - year--; - return 365 * year + (year / 400) - (year / 100) + (year / 4); -} - -static inline int days_from_1970(int year) -{ - static const int days_from_0_to_1970 = days_from_0(1970); - return days_from_0(year) - days_from_0_to_1970; -} - -static inline int days_from_1jan(int year, int month, int day) -{ - static const int days[2][12] = - { - { 0,31,59,90,120,151,181,212,243,273,304,334}, - { 0,31,60,91,121,152,182,213,244,274,305,335} - }; - return days[is_leap(year)][month-1] + day - 1; -} - -epicsTime::epicsTime (const gm_tm_nano_sec &tm) -{ - int year = tm.ansi_tm.tm_year + 1900; - int month = tm.ansi_tm.tm_mon; - if (month > 11) { - year += month / 12; - month %= 12; - } else if (month < 0) { - int years_diff = (-month + 11) / 12; - year -= years_diff; - month += 12 * years_diff; - } - month++; - - int day = tm.ansi_tm.tm_mday; - int day_of_year = days_from_1jan(year, month, day); - int days_since_epoch = days_from_1970(year) + day_of_year; - - time_t_wrapper ansiTimeTicks; - ansiTimeTicks.ts = ((days_since_epoch - * 24 + tm.ansi_tm.tm_hour) - * 60 + tm.ansi_tm.tm_min) - * 60 + tm.ansi_tm.tm_sec; - - *this = epicsTime(ansiTimeTicks); - this->addNanoSec(tm.nSec); -} - -// -// operator struct timespec () -// -epicsTime::operator struct timespec () const -{ - struct timespec ts; - time_t_wrapper ansiTimeTicks; - - ansiTimeTicks = *this; - ts.tv_sec = ansiTimeTicks.ts; - ts.tv_nsec = static_cast (this->nSec); - return ts; -} - -// -// epicsTime (const struct timespec &ts) -// -epicsTime::epicsTime (const struct timespec &ts) -{ - time_t_wrapper ansiTimeTicks; - - ansiTimeTicks.ts = ts.tv_sec; - *this = epicsTime (ansiTimeTicks); - this->addNanoSec (ts.tv_nsec); -} - -// -// operator struct timeval () -// -epicsTime::operator struct timeval () const -{ - struct timeval ts; - time_t_wrapper ansiTimeTicks; - - ansiTimeTicks = *this; - // On Posix systems timeval :: tv_sec is a time_t so this can be - // a direct assignment. On other systems I dont know that we can - // guarantee that time_t and timeval :: tv_sec will have the - // same epoch or have the same scaling factor to discrete seconds. - // For example, on windows time_t changed recently to a 64 bit - // quantity but timeval is still a long. That can cause problems - // on 32 bit systems. So technically, we should have an os - // dependent conversion between time_t and timeval :: tv_sec? - ts.tv_sec = ansiTimeTicks.ts; - ts.tv_usec = static_cast < long > ( this->nSec / nSecPerUSec ); - return ts; -} - -// -// epicsTime (const struct timeval &ts) -// -epicsTime::epicsTime (const struct timeval &ts) -{ - time_t_wrapper ansiTimeTicks; - // On Posix systems timeval :: tv_sec is a time_t so this can be - // a direct assignment. On other systems I dont know that we can - // guarantee that time_t and timeval :: tv_sec will have the - // same epoch or have the same scaling factor to discrete seconds. - // For example, on windows time_t changed recently to a 64 bit - // quantity but timeval is still a long. That can cause problems - // on 32 bit systems. So technically, we should have an os - // dependent conversion between time_t and timeval :: tv_sec? - ansiTimeTicks.ts = ts.tv_sec; - *this = epicsTime (ansiTimeTicks); - this->addNanoSec (ts.tv_usec * nSecPerUSec); -} - - -static const double NTP_FRACTION_DENOMINATOR = 1.0 + 0xffffffff; - -struct l_fp { /* NTP time stamp */ - epicsUInt32 l_ui; /* sec past NTP epoch */ - epicsUInt32 l_uf; /* fractional seconds */ -}; - -// -// epicsTime::l_fp () -// -epicsTime::operator l_fp () const -{ - l_fp ts; - ts.l_ui = this->secPastEpoch + NTP_TIME_AT_EPICS_EPOCH; - ts.l_uf = static_cast < unsigned long > - ( ( this->nSec * NTP_FRACTION_DENOMINATOR ) / nSecPerSec ); - return ts; -} - -// -// epicsTime::epicsTime ( const l_fp & ts ) -// -epicsTime::epicsTime ( const l_fp & ts ) -{ - this->secPastEpoch = ts.l_ui - NTP_TIME_AT_EPICS_EPOCH; - this->nSec = static_cast < unsigned long > - ( ( ts.l_uf / NTP_FRACTION_DENOMINATOR ) * nSecPerSec ); -} - -epicsTime::operator epicsTimeStamp () const -{ - if ( this->nSec >= nSecPerSec ) { - throw std::logic_error ( - "epicsTimeStamp has overflow in nano-seconds field?" ); - } - epicsTimeStamp ts; - // - // truncation by design - // ------------------- - // epicsTime::secPastEpoch is based on ulong and has much greater range - // on 64 bit hosts than the original epicsTimeStamp::secPastEpoch. The - // epicsTimeStamp::secPastEpoch is based on epicsUInt32 so that it will - // match the original network protocol. Of course one can anticipate - // that eventually, a epicsUInt64 based network time stamp will be - // introduced when 64 bit architectures are more ubiquitous. - // - // Truncation usually works fine here because the routines in this code - // that compute time stamp differences and compare time stamps produce - // good results when the operands are on either side of a time stamp - // rollover as long as the difference between the operands does not exceed - // 1/2 of full range. - // - ts.secPastEpoch = static_cast < epicsUInt32 > ( this->secPastEpoch ); - ts.nsec = static_cast < epicsUInt32 > ( this->nSec ); - return ts; -} - -// Break up a format string into "%0f" -// (where in an unsigned integer) -// Result: -// A) Copies a prefix which is valid for ANSI strftime into the supplied -// buffer setting the buffer to an empty string if no prefix is present. -// B) Indicates whether a valid "%0f]" is present or not and if so -// specifying its nnnn -// C) returning a pointer to the postfix (which might be passed again -// to fracFormatFind. -static const char * fracFormatFind ( - const char * const pFormat, - char * const pPrefixBuf, - const size_t prefixBufLen, - bool & fracFmtFound, - unsigned long & fracFmtWidth ) -{ - assert ( prefixBufLen > 1 ); - unsigned long width = ULONG_MAX; - bool fracFound = false; - const char * pAfter = pFormat; - const char * pFmt = pFormat; - while ( *pFmt != '\0' ) { - if ( *pFmt == '%' ) { - if ( pFmt[1] == '%' ) { - pFmt++; - } - else if ( pFmt[1] == 'f' ) { - fracFound = true; - pAfter = & pFmt[2]; - break; - } - else { - errno = 0; - char * pAfterTmp; - unsigned long result = strtoul ( pFmt + 1, & pAfterTmp, 10 ); - if ( errno == 0 && *pAfterTmp == 'f' && result > 0 ) { - width = result; - fracFound = true; - pAfter = pAfterTmp + 1; - break; - } - } - } - pFmt++; - pAfter = pFmt; - } - size_t len = pFmt - pFormat; - if ( len < prefixBufLen ) { - strncpy ( pPrefixBuf, pFormat, len ); - pPrefixBuf [ len ] = '\0'; - if ( fracFound ) { - fracFmtFound = true; - fracFmtWidth = width; - } - else { - fracFmtFound = false; - } - } - else { - strncpy ( pPrefixBuf, "", prefixBufLen - 1 ); - pPrefixBuf [ prefixBufLen - 1 ] = '\0'; - fracFmtFound = false; - pAfter = ""; - } - - return pAfter; -} - -// -// size_t epicsTime::strftime () -// -size_t epicsTime::strftime ( - char * pBuff, size_t bufLength, const char * pFormat ) const -{ - if ( bufLength == 0u ) { - return 0u; - } - - // presume that EPOCH date is an uninitialized time stamp - if ( this->secPastEpoch == 0 && this->nSec == 0u ) { - strncpy ( pBuff, "", bufLength ); - pBuff[bufLength-1] = '\0'; - return strlen ( pBuff ); - } - - char * pBufCur = pBuff; - const char * pFmt = pFormat; - size_t bufLenLeft = bufLength; - while ( *pFmt != '\0' && bufLenLeft > 1 ) { - // look for "%0f" at the end (used for fractional second formatting) - char strftimePrefixBuf [256]; - bool fracFmtFound; - unsigned long fracWid = 0; - pFmt = fracFormatFind ( - pFmt, - strftimePrefixBuf, sizeof ( strftimePrefixBuf ), - fracFmtFound, fracWid ); - - // nothing more in the string, then quit - if ( ! ( strftimePrefixBuf[0] != '\0' || fracFmtFound ) ) { - break; - } - // all but fractional seconds use strftime formatting - if ( strftimePrefixBuf[0] != '\0' ) { - local_tm_nano_sec tmns = *this; - size_t strftimeNumChar = :: strftime ( - pBufCur, bufLenLeft, strftimePrefixBuf, & tmns.ansi_tm ); - pBufCur [ strftimeNumChar ] = '\0'; - pBufCur += strftimeNumChar; - bufLenLeft -= strftimeNumChar; - } - - // fractional seconds formating - if ( fracFmtFound && bufLenLeft > 1 ) { - if ( fracWid > nSecFracDigits ) { - fracWid = nSecFracDigits; - } - // verify that there are enough chars left for the fractional seconds - if ( fracWid < bufLenLeft ) - { - local_tm_nano_sec tmns = *this; - if ( tmns.nSec < nSecPerSec ) { - // divisors for fraction (see below) - static const unsigned long div[] = { - static_cast < unsigned long > ( 1e9 ), - static_cast < unsigned long > ( 1e8 ), - static_cast < unsigned long > ( 1e7 ), - static_cast < unsigned long > ( 1e6 ), - static_cast < unsigned long > ( 1e5 ), - static_cast < unsigned long > ( 1e4 ), - static_cast < unsigned long > ( 1e3 ), - static_cast < unsigned long > ( 1e2 ), - static_cast < unsigned long > ( 1e1 ), - static_cast < unsigned long > ( 1e0 ) - }; - // round without overflowing into whole seconds - unsigned long frac = tmns.nSec + div[fracWid] / 2; - if (frac >= nSecPerSec) - frac = nSecPerSec - 1; - // convert nanosecs to integer of correct range - frac /= div[fracWid]; - char fracFormat[32]; - sprintf ( fracFormat, "%%0%lulu", fracWid ); - int status = epicsSnprintf ( pBufCur, bufLenLeft, fracFormat, frac ); - if ( status > 0 ) { - unsigned long nChar = static_cast < unsigned long > ( status ); - if ( nChar >= bufLenLeft ) { - nChar = bufLenLeft - 1; - } - pBufCur[nChar] = '\0'; - pBufCur += nChar; - bufLenLeft -= nChar; - } - } - else { - static const char pOVF [] = "OVF"; - size_t tmpLen = sizeof ( pOVF ) - 1; - if ( tmpLen >= bufLenLeft ) { - tmpLen = bufLenLeft - 1; - } - strncpy ( pBufCur, pOVF, tmpLen ); - pBufCur[tmpLen] = '\0'; - pBufCur += tmpLen; - bufLenLeft -= tmpLen; - } - } - else { - static const char pDoesntFit [] = "************"; - size_t tmpLen = sizeof ( pDoesntFit ) - 1; - if ( tmpLen >= bufLenLeft ) { - tmpLen = bufLenLeft - 1; - } - strncpy ( pBufCur, pDoesntFit, tmpLen ); - pBufCur[tmpLen] = '\0'; - pBufCur += tmpLen; - bufLenLeft -= tmpLen; - break; - } - } - } - return pBufCur - pBuff; -} - -// -// epicsTime::show (unsigned) -// -void epicsTime::show ( unsigned level ) const -{ - char bigBuffer[256]; - - size_t numChar = this->strftime ( bigBuffer, sizeof ( bigBuffer ), - "%a %b %d %Y %H:%M:%S.%09f" ); - if ( numChar > 0 ) { - printf ( "epicsTime: %s\n", bigBuffer ); - } - - if ( level > 1 ) { - // this also suppresses the "defined, but not used" - // warning message - printf ( "epicsTime: revision \"%s\"\n", - pEpicsTimeVersion ); - } - -} - -// -// epicsTime::operator + (const double &rhs) -// -// rhs has units seconds -// -epicsTime epicsTime::operator + (const double &rhs) const -{ - unsigned long newSec, newNSec, secOffset, nSecOffset; - double fnsec; - - if (rhs >= 0) { - secOffset = static_cast (rhs); - fnsec = rhs - secOffset; - nSecOffset = static_cast ( (fnsec * nSecPerSec) + 0.5 ); - - newSec = this->secPastEpoch + secOffset; // overflow expected - newNSec = this->nSec + nSecOffset; - if (newNSec >= nSecPerSec) { - newSec++; // overflow expected - newNSec -= nSecPerSec; - } - } - else { - secOffset = static_cast (-rhs); - fnsec = rhs + secOffset; - nSecOffset = static_cast ( (-fnsec * nSecPerSec) + 0.5 ); - - newSec = this->secPastEpoch - secOffset; // underflow expected - if (this->nSec>=nSecOffset) { - newNSec = this->nSec - nSecOffset; - } - else { - // borrow - newSec--; // underflow expected - newNSec = this->nSec + (nSecPerSec - nSecOffset); - } - } - return epicsTime (newSec, newNSec); -} - -// -// operator - -// -// To make this code robust during timestamp rollover events -// time stamp differences greater than one half full scale are -// interpreted as rollover situations: -// -// when RHS is greater than THIS: -// RHS-THIS > one half full scale => return THIS + (ULONG_MAX-RHS) -// RHS-THIS <= one half full scale => return -(RHS-THIS) -// -// when THIS is greater than or equal to RHS -// THIS-RHS > one half full scale => return -(RHS + (ULONG_MAX-THIS)) -// THIS-RHS <= one half full scale => return THIS-RHS -// -double epicsTime::operator - (const epicsTime &rhs) const -{ - double nSecRes, secRes; - - // - // first compute the difference between the nano-seconds members - // - // nano sec member is not allowed to be greater that 1/2 full scale - // so the unsigned to signed conversion is ok - // - if (this->nSec>=rhs.nSec) { - nSecRes = this->nSec - rhs.nSec; - } - else { - nSecRes = rhs.nSec - this->nSec; - nSecRes = -nSecRes; - } - - // - // next compute the difference between the seconds members - // and invert the sign of the nano seconds result if there - // is a range violation - // - if (this->secPastEpochsecPastEpoch; - if (secRes > ULONG_MAX/2) { - // - // In this situation where the difference is more than - // 68 years assume that the seconds counter has rolled - // over and compute the "wrap around" difference - // - secRes = 1 + (ULONG_MAX-secRes); - nSecRes = -nSecRes; - } - else { - secRes = -secRes; - } - } - else { - secRes = this->secPastEpoch - rhs.secPastEpoch; - if (secRes > ULONG_MAX/2) { - // - // In this situation where the difference is more than - // 68 years assume that the seconds counter has rolled - // over and compute the "wrap around" difference - // - secRes = 1 + (ULONG_MAX-secRes); - secRes = -secRes; - nSecRes = -nSecRes; - } - } - - return secRes + nSecRes/nSecPerSec; -} - -// -// operator <= -// -bool epicsTime::operator <= (const epicsTime &rhs) const -{ - bool rc; - - if (this->secPastEpochsecPastEpoch < ULONG_MAX/2) { - // - // In this situation where the difference is less than - // 69 years compute the expected result - // - rc = true; - } - else { - // - // In this situation where the difference is more than - // 69 years assume that the seconds counter has rolled - // over and compute the "wrap around" result - // - rc = false; - } - } - else if (this->secPastEpoch>rhs.secPastEpoch) { - if (this->secPastEpoch-rhs.secPastEpoch < ULONG_MAX/2) { - // - // In this situation where the difference is less than - // 69 years compute the expected result - // - rc = false; - } - else { - // - // In this situation where the difference is more than - // 69 years assume that the seconds counter has rolled - // over and compute the "wrap around" result - // - rc = true; - } - } - else { - if (this->nSec<=rhs.nSec) { - rc = true; - } - else { - rc = false; - } - } - return rc; -} - -// -// operator < -// -bool epicsTime::operator < (const epicsTime &rhs) const -{ - bool rc; - - if (this->secPastEpochsecPastEpoch < ULONG_MAX/2) { - // - // In this situation where the difference is less than - // 69 years compute the expected result - // - rc = true; - } - else { - // - // In this situation where the difference is more than - // 69 years assume that the seconds counter has rolled - // over and compute the "wrap around" result - // - rc = false; - } - } - else if (this->secPastEpoch>rhs.secPastEpoch) { - if (this->secPastEpoch-rhs.secPastEpoch < ULONG_MAX/2) { - // - // In this situation where the difference is less than - // 69 years compute the expected result - // - rc = false; - } - else { - // - // In this situation where the difference is more than - // 69 years assume that the seconds counter has rolled - // over and compute the "wrap around" result - // - rc = true; - } - } - else { - if (this->nSec epicsTime (*pRight); - } - catch ( ... ) { - return 0; - } - } - epicsShareFunc int epicsShareAPI epicsTimeGreaterThanEqual (const epicsTimeStamp *pLeft, const epicsTimeStamp *pRight) - { - try { - return epicsTime (*pLeft) >= epicsTime (*pRight); - } - catch ( ... ) { - return 0; - } - } - epicsShareFunc size_t epicsShareAPI epicsTimeToStrftime (char *pBuff, size_t bufLength, const char *pFormat, const epicsTimeStamp *pTS) - { - try { - return epicsTime(*pTS).strftime (pBuff, bufLength, pFormat); - } - catch ( ... ) { - return 0; - } - } - epicsShareFunc void epicsShareAPI epicsTimeShow (const epicsTimeStamp *pTS, unsigned interestLevel) - { - try { - epicsTime(*pTS).show (interestLevel); - } - catch ( ... ) { - printf ( "Invalid epicsTimeStamp\n" ); - } - } -} diff --git a/src/libCom/osi/epicsTime.h b/src/libCom/osi/epicsTime.h deleted file mode 100644 index 149f6f2d3..000000000 --- a/src/libCom/osi/epicsTime.h +++ /dev/null @@ -1,357 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsTime.h */ -/* Author Jeffrey O. Hill */ - -#ifndef epicsTimehInclude -#define epicsTimehInclude - -#include - -#include "shareLib.h" -#include "epicsTypes.h" -#include "osdTime.h" -#include "errMdef.h" - -/* The EPICS Epoch is 00:00:00 Jan 1, 1990 UTC */ -#define POSIX_TIME_AT_EPICS_EPOCH 631152000u - -/* epics time stamp for C interface*/ -typedef struct epicsTimeStamp { - epicsUInt32 secPastEpoch; /* seconds since 0000 Jan 1, 1990 */ - epicsUInt32 nsec; /* nanoseconds within second */ -} epicsTimeStamp; - -/*TS_STAMP is deprecated */ -#define TS_STAMP epicsTimeStamp - - -struct timespec; /* POSIX real time */ -struct timeval; /* BSD */ -struct l_fp; /* NTP timestamp */ - -#ifdef __cplusplus - -/* - * extend ANSI C RTL "struct tm" to include nano seconds within a second - * and a struct tm that is adjusted for the local timezone - */ -struct local_tm_nano_sec { - struct tm ansi_tm; /* ANSI C time details */ - unsigned long nSec; /* nano seconds extension */ -}; - -/* - * extend ANSI C RTL "struct tm" to includes nano seconds within a second - * and a struct tm that is adjusted for GMT (UTC) - */ -struct gm_tm_nano_sec { - struct tm ansi_tm; /* ANSI C time details */ - unsigned long nSec; /* nano seconds extension */ -}; - -/* - * wrapping this in a struct allows conversion to and - * from ANSI time_t but does not allow unexpected - * conversions to occur - */ -struct time_t_wrapper { - time_t ts; -}; - -class epicsShareClass epicsTimeEvent -{ -public: - epicsTimeEvent (const int &number); - operator int () const; -private: - int eventNumber; -}; - -class epicsShareClass epicsTime -{ -public: - /* exceptions */ - class unableToFetchCurrentTime {}; - class formatProblemWithStructTM {}; - - epicsTime (); - epicsTime ( const epicsTime & t ); - - static epicsTime getEvent ( const epicsTimeEvent & ); - static epicsTime getCurrent (); - - /* convert to and from EPICS epicsTimeStamp format */ - operator epicsTimeStamp () const; - epicsTime ( const epicsTimeStamp & ts ); - epicsTime & operator = ( const epicsTimeStamp & ); - - /* convert to and from ANSI time_t */ - operator time_t_wrapper () const; - epicsTime ( const time_t_wrapper & ); - epicsTime & operator = ( const time_t_wrapper & ); - - /* - * convert to and from ANSI Cs "struct tm" (with nano seconds) - * adjusted for the local time zone - */ - operator local_tm_nano_sec () const; - epicsTime ( const local_tm_nano_sec & ); - epicsTime & operator = ( const local_tm_nano_sec & ); - - /* - * convert to and from ANSI Cs "struct tm" (with nano seconds) - * adjusted for GM time (UTC) - */ - operator gm_tm_nano_sec () const; - epicsTime ( const gm_tm_nano_sec & ); - epicsTime & operator = ( const gm_tm_nano_sec & ); - - /* convert to and from POSIX RTs "struct timespec" */ - operator struct timespec () const; - epicsTime ( const struct timespec & ); - epicsTime & operator = ( const struct timespec & ); - - /* convert to and from BSDs "struct timeval" */ - operator struct timeval () const; - epicsTime ( const struct timeval & ); - epicsTime & operator = ( const struct timeval & ); - - /* convert to and from NTP timestamp format */ - operator l_fp () const; - epicsTime ( const l_fp & ); - epicsTime & operator = ( const l_fp & ); - - /* convert to and from WIN32s FILETIME (implemented only on WIN32) */ - operator struct _FILETIME () const; - epicsTime ( const struct _FILETIME & ); - epicsTime & operator = ( const struct _FILETIME & ); - - /* arithmetic operators */ - double operator- ( const epicsTime & ) const; /* returns seconds */ - epicsTime operator+ ( const double & ) const; /* add rhs seconds */ - epicsTime operator- ( const double & ) const; /* subtract rhs seconds */ - epicsTime operator+= ( const double & ); /* add rhs seconds */ - epicsTime operator-= ( const double & ); /* subtract rhs seconds */ - - /* comparison operators */ - bool operator == ( const epicsTime & ) const; - bool operator != ( const epicsTime & ) const; - bool operator <= ( const epicsTime & ) const; - bool operator < ( const epicsTime & ) const; - bool operator >= ( const epicsTime & ) const; - bool operator > ( const epicsTime & ) const; - - /* convert current state to user-specified string */ - size_t strftime ( char * pBuff, size_t bufLength, const char * pFormat ) const; - - /* dump current state to standard out */ - void show ( unsigned interestLevel ) const; - -private: - /* - * private because: - * a) application does not break when EPICS epoch is changed - * b) no assumptions about internal storage or internal precision - * in the application - * c) it would be easy to forget which argument is nanoseconds - * and which argument is seconds (no help from compiler) - */ - epicsTime ( const unsigned long secPastEpoch, const unsigned long nSec ); - void addNanoSec ( long nanoSecAdjust ); - - unsigned long secPastEpoch; /* seconds since O000 Jan 1, 1990 */ - unsigned long nSec; /* nanoseconds within second */ -}; - -extern "C" { -#endif /* __cplusplus */ - -/* epicsTime routines return S_time_ error status values */ -#define epicsTimeOK 0 -#define S_time_noProvider (M_time| 1) /*No time provider*/ -#define S_time_badEvent (M_time| 2) /*Bad event number*/ -#define S_time_badArgs (M_time| 3) /*Invalid arguments*/ -#define S_time_noMemory (M_time| 4) /*Out of memory*/ -#define S_time_unsynchronized (M_time| 5) /*Provider not synchronized*/ -#define S_time_timezone (M_time| 6) /*Invalid timeone*/ -#define S_time_conversion (M_time| 7) /*Time conversion error*/ - -/*Some special values for eventNumber*/ -#define epicsTimeEventCurrentTime 0 -#define epicsTimeEventBestTime -1 -#define epicsTimeEventDeviceTime -2 - -/* These are implemented in the "generalTime" framework */ -epicsShareFunc int epicsShareAPI epicsTimeGetCurrent ( epicsTimeStamp * pDest ); -epicsShareFunc int epicsShareAPI epicsTimeGetEvent ( - epicsTimeStamp *pDest, int eventNumber); - -/* These are callable from an Interrupt Service Routine */ -epicsShareFunc int epicsTimeGetCurrentInt(epicsTimeStamp *pDest); -epicsShareFunc int epicsTimeGetEventInt(epicsTimeStamp *pDest, int eventNumber); - -/* convert to and from ANSI C's "time_t" */ -epicsShareFunc int epicsShareAPI epicsTimeToTime_t ( - time_t * pDest, const epicsTimeStamp * pSrc ); -epicsShareFunc int epicsShareAPI epicsTimeFromTime_t ( - epicsTimeStamp * pDest, time_t src ); - -/* convert to and from ANSI C's "struct tm" with nano seconds */ -epicsShareFunc int epicsShareAPI epicsTimeToTM ( - struct tm * pDest, unsigned long * pNSecDest, const epicsTimeStamp * pSrc ); -epicsShareFunc int epicsShareAPI epicsTimeToGMTM ( - struct tm * pDest, unsigned long * pNSecDest, const epicsTimeStamp * pSrc ); -epicsShareFunc int epicsShareAPI epicsTimeFromTM ( - epicsTimeStamp * pDest, const struct tm * pSrc, unsigned long nSecSrc ); -epicsShareFunc int epicsShareAPI epicsTimeFromGMTM ( - epicsTimeStamp * pDest, const struct tm * pSrc, unsigned long nSecSrc ); - -/* convert to and from POSIX RT's "struct timespec" */ -epicsShareFunc int epicsShareAPI epicsTimeToTimespec ( - struct timespec * pDest, const epicsTimeStamp * pSrc ); -epicsShareFunc int epicsShareAPI epicsTimeFromTimespec ( - epicsTimeStamp * pDest, const struct timespec * pSrc ); - -/* convert to and from BSD's "struct timeval" */ -epicsShareFunc int epicsShareAPI epicsTimeToTimeval ( - struct timeval * pDest, const epicsTimeStamp * pSrc ); -epicsShareFunc int epicsShareAPI epicsTimeFromTimeval ( - epicsTimeStamp * pDest, const struct timeval * pSrc ); - -/*arithmetic operations */ -epicsShareFunc double epicsShareAPI epicsTimeDiffInSeconds ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight );/* left - right */ -epicsShareFunc void epicsShareAPI epicsTimeAddSeconds ( - epicsTimeStamp * pDest, double secondsToAdd ); /* adds seconds to *pDest */ - -/*comparison operations: returns (0,1) if (false,true) */ -epicsShareFunc int epicsShareAPI epicsTimeEqual ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); -epicsShareFunc int epicsShareAPI epicsTimeNotEqual ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); -epicsShareFunc int epicsShareAPI epicsTimeLessThan ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left < right */ -epicsShareFunc int epicsShareAPI epicsTimeLessThanEqual ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left <= right) */ -epicsShareFunc int epicsShareAPI epicsTimeGreaterThan ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left > right */ -epicsShareFunc int epicsShareAPI epicsTimeGreaterThanEqual ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left >= right */ - -/*convert to ASCII string */ -epicsShareFunc size_t epicsShareAPI epicsTimeToStrftime ( - char * pBuff, size_t bufLength, const char * pFormat, const epicsTimeStamp * pTS ); - -/* dump current state to standard out */ -epicsShareFunc void epicsShareAPI epicsTimeShow ( - const epicsTimeStamp *, unsigned interestLevel ); - -/* OS dependent reentrant versions of the ANSI C interface because */ -/* vxWorks gmtime_r interface does not match POSIX standards */ -epicsShareFunc int epicsShareAPI epicsTime_localtime ( const time_t * clock, struct tm * result ); -epicsShareFunc int epicsShareAPI epicsTime_gmtime ( const time_t * clock, struct tm * result ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -/* inline member functions ,*/ -#ifdef __cplusplus - -/* epicsTimeEvent */ - -inline epicsTimeEvent::epicsTimeEvent (const int &number) : - eventNumber(number) {} - -inline epicsTimeEvent::operator int () const -{ - return this->eventNumber; -} - - -/* epicsTime */ - -inline epicsTime epicsTime::operator - ( const double & rhs ) const -{ - return epicsTime::operator + ( -rhs ); -} - -inline epicsTime epicsTime::operator += ( const double & rhs ) -{ - *this = epicsTime::operator + ( rhs ); - return *this; -} - -inline epicsTime epicsTime::operator -= ( const double & rhs ) -{ - *this = epicsTime::operator + ( -rhs ); - return *this; -} - -inline bool epicsTime::operator == ( const epicsTime & rhs ) const -{ - if ( this->secPastEpoch == rhs.secPastEpoch && this->nSec == rhs.nSec ) { - return true; - } - return false; -} - -inline bool epicsTime::operator != ( const epicsTime & rhs ) const -{ - return !epicsTime::operator == ( rhs ); -} - -inline bool epicsTime::operator >= ( const epicsTime & rhs ) const -{ - return ! ( *this < rhs ); -} - -inline bool epicsTime::operator > ( const epicsTime & rhs ) const -{ - return ! ( *this <= rhs ); -} - -inline epicsTime & epicsTime::operator = ( const local_tm_nano_sec & rhs ) -{ - return *this = epicsTime ( rhs ); -} - -inline epicsTime & epicsTime::operator = ( const gm_tm_nano_sec & rhs ) -{ - return *this = epicsTime ( rhs ); -} - -inline epicsTime & epicsTime::operator = ( const struct timespec & rhs ) -{ - *this = epicsTime ( rhs ); - return *this; -} - -inline epicsTime & epicsTime::operator = ( const epicsTimeStamp & rhs ) -{ - *this = epicsTime ( rhs ); - return *this; -} - -inline epicsTime & epicsTime::operator = ( const l_fp & rhs ) -{ - *this = epicsTime ( rhs ); - return *this; -} - -inline epicsTime & epicsTime::operator = ( const time_t_wrapper & rhs ) -{ - *this = epicsTime ( rhs ); - return *this; -} -#endif /* __cplusplus */ - -#endif /* epicsTimehInclude */ - diff --git a/src/libCom/osi/generalTimeSup.h b/src/libCom/osi/generalTimeSup.h deleted file mode 100644 index bd6627ef6..000000000 --- a/src/libCom/osi/generalTimeSup.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2008 Diamond Light Source Ltd -* Copyright (c) 2004 Oak Ridge National Laboratory -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_generalTimeSup_H -#define INC_generalTimeSup_H - -#include "epicsTime.h" -#include "epicsTimer.h" -#include "shareLib.h" - -#define LAST_RESORT_PRIORITY 999 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int (*TIMECURRENTFUN)(epicsTimeStamp *pDest); -typedef int (*TIMEEVENTFUN)(epicsTimeStamp *pDest, int event); - -epicsShareFunc int generalTimeRegisterCurrentProvider(const char *name, - int priority, TIMECURRENTFUN getTime); -epicsShareFunc int generalTimeRegisterEventProvider(const char *name, - int priority, TIMEEVENTFUN getEvent); - -/* Original names, for compatibility */ -#define generalTimeCurrentTpRegister generalTimeRegisterCurrentProvider -#define generalTimeEventTpRegister generalTimeRegisterEventProvider - -epicsShareFunc int generalTimeAddIntCurrentProvider(const char *name, - int priority, TIMECURRENTFUN getTime); -epicsShareFunc int generalTimeAddIntEventProvider(const char *name, - int priority, TIMEEVENTFUN getEvent); - -epicsShareFunc int generalTimeGetExceptPriority(epicsTimeStamp *pDest, - int *pPrio, int ignorePrio); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_generalTimeSup_H */ diff --git a/src/libCom/osi/os/Darwin/epicsMath.h b/src/libCom/osi/os/Darwin/epicsMath.h deleted file mode 100644 index d540ba5d3..000000000 --- a/src/libCom/osi/os/Darwin/epicsMath.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsMathh -#define epicsMathh - -#include -#include - -#define finite(x) isfinite(x) - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* epicsMathh */ diff --git a/src/libCom/osi/os/Darwin/osdBackTrace.cpp b/src/libCom/osi/os/Darwin/osdBackTrace.cpp deleted file mode 100644 index 4595fee3a..000000000 --- a/src/libCom/osi/os/Darwin/osdBackTrace.cpp +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include "osdExecinfoBackTrace.cpp" diff --git a/src/libCom/osi/os/Darwin/osdEnv.c b/src/libCom/osi/os/Darwin/osdEnv.c deleted file mode 100644 index ab3f93644..000000000 --- a/src/libCom/osi/os/Darwin/osdEnv.c +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdEnv.c */ -/* - * Author: Eric Norum - * Date: May 7, 2001 - * - * Routines to modify/display environment variables and EPICS parameters - * - */ - -#include -#include -#include -#include -#include - -/* - * Starting in Mac OS X 10.5 (Leopard) shared libraries and - * bundles don't have direct access to environ (man environ). - */ -#include -#define environ (*_NSGetEnviron()) - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "envDefs.h" -#include "iocsh.h" - -/* - * Set the value of an environment variable - */ -epicsShareFunc void epicsShareAPI epicsEnvSet (const char *name, const char *value) -{ - iocshEnvClear(name); - setenv(name, value, 1); -} - -/* - * Show the value of the specified, or all, environment variables - */ -epicsShareFunc void epicsShareAPI epicsEnvShow (const char *name) -{ - if (name == NULL) { - extern char **environ; - char **sp; - - for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++) - printf ("%s\n", *sp); - } - else { - const char *cp = getenv (name); - if (cp == NULL) - printf ("%s is not an environment variable.\n", name); - else - printf ("%s=%s\n", name, cp); - } -} diff --git a/src/libCom/osi/os/Darwin/osdFindAddr.c b/src/libCom/osi/os/Darwin/osdFindAddr.c deleted file mode 100644 index b92770a54..000000000 --- a/src/libCom/osi/os/Darwin/osdFindAddr.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -/* Make sure dladdr() is visible */ -#define _DARWIN_C_SOURCE - -#include - -#define epicsExportSharedSymbols -#include "epicsStackTrace.h" -#include "epicsStackTracePvt.h" - -/* Darwin's finds local symbols, too :-) */ - -int epicsFindAddr(void *addr, epicsSymbol *sym_p) -{ - Dl_info inf; - - if ( ! dladdr(addr, &inf) ) { - sym_p->f_nam = 0; - sym_p->s_nam = 0; - sym_p->s_val = 0; - } else { - sym_p->f_nam = inf.dli_fname; - sym_p->s_nam = inf.dli_sname; - sym_p->s_val = inf.dli_saddr; - } - - return 0; -} - -int epicsFindAddrGetFeatures(void) -{ - return EPICS_STACKTRACE_LCL_SYMBOLS - | EPICS_STACKTRACE_GBL_SYMBOLS - | EPICS_STACKTRACE_DYN_SYMBOLS; -} diff --git a/src/libCom/osi/os/Darwin/osdSock.h b/src/libCom/osi/os/Darwin/osdSock.h deleted file mode 100644 index 1d4556eee..000000000 --- a/src/libCom/osi/os/Darwin/osdSock.h +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Eric Norum - */ - -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; -typedef socklen_t osiSocklen_t; - -#define FD_IN_FDSET(FD) ((FD)ifr_addr.sa_len + sizeof((pifreq)->ifr_name)) - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/Darwin/osdSockAddrReuse.cpp b/src/libCom/osi/os/Darwin/osdSockAddrReuse.cpp deleted file mode 100644 index 869514160..000000000 --- a/src/libCom/osi/os/Darwin/osdSockAddrReuse.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" - -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEADDR?\n"); - } -} - -/* - * SO_REUSEPORT is not in POSIX - */ -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEPORT, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEPORT?\n"); - } -} diff --git a/src/libCom/osi/os/Darwin/osdTime.cpp b/src/libCom/osi/os/Darwin/osdTime.cpp deleted file mode 100644 index 72b3dc874..000000000 --- a/src/libCom/osi/os/Darwin/osdTime.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -#include "osiSock.h" - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsTime.h" -#include "generalTimeSup.h" - -static clock_serv_t host_clock; - -extern "C" { -static int osdTimeGetCurrent (epicsTimeStamp *pDest) -{ - mach_timespec_t mts; - struct timespec ts; - - clock_get_time(host_clock, &mts); - ts.tv_sec = mts.tv_sec; - ts.tv_nsec = mts.tv_nsec; - *pDest = epicsTime(ts); - return epicsTimeOK; -} -} // extern "C" - - -static int timeRegister(void) -{ - host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &host_clock); - - generalTimeCurrentTpRegister("MachTime", \ - LAST_RESORT_PRIORITY, osdTimeGetCurrent); - return 1; -} -static int done = timeRegister(); - - -int epicsTime_gmtime(const time_t *pAnsiTime, struct tm *pTM) -{ - return gmtime_r(pAnsiTime, pTM) ? - epicsTimeOK : errno; -} - -int epicsTime_localtime(const time_t *clock, struct tm *result) -{ - return localtime_r(clock, result) ? - epicsTimeOK : errno; -} - -extern "C" epicsShareFunc void -convertDoubleToWakeTime(double timeout, struct timespec *wakeTime) -{ - mach_timespec_t now; - struct timespec wait; - - if (timeout < 0.0) - timeout = 0.0; - else if (timeout > 60 * 60 * 24 * 3652.5) - timeout = 60 * 60 * 24 * 3652.5; /* 10 years */ - - clock_get_time(host_clock, &now); - - wait.tv_sec = static_cast< time_t >(timeout); - wait.tv_nsec = static_cast< long >((timeout - (double)wait.tv_sec) * 1e9); - - wakeTime->tv_sec = now.tv_sec + wait.tv_sec; - wakeTime->tv_nsec = now.tv_nsec + wait.tv_nsec; - if (wakeTime->tv_nsec >= 1000000000L) { - wakeTime->tv_nsec -= 1000000000L; - ++wakeTime->tv_sec; - } -} diff --git a/src/libCom/osi/os/Darwin/osdTime.h b/src/libCom/osi/os/Darwin/osdTime.h deleted file mode 100644 index d0c361404..000000000 --- a/src/libCom/osi/os/Darwin/osdTime.h +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Eric Norum - */ - -#ifndef osdTimeh -#define osdTimeh - -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void convertDoubleToWakeTime(double timeout, - struct timespec *wakeTime); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ifndef osdTimeh */ - diff --git a/src/libCom/osi/os/Darwin/osiFileName.h b/src/libCom/osi/os/Darwin/osiFileName.h deleted file mode 100644 index a78118679..000000000 --- a/src/libCom/osi/os/Darwin/osiFileName.h +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Eric Norum - */ - -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/Linux/osdBackTrace.cpp b/src/libCom/osi/os/Linux/osdBackTrace.cpp deleted file mode 100644 index 4595fee3a..000000000 --- a/src/libCom/osi/os/Linux/osdBackTrace.cpp +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include "osdExecinfoBackTrace.cpp" diff --git a/src/libCom/osi/os/Linux/osdFindAddr.c b/src/libCom/osi/os/Linux/osdFindAddr.c deleted file mode 100644 index 84d17d96f..000000000 --- a/src/libCom/osi/os/Linux/osdFindAddr.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include "osdElfFindAddr.c" diff --git a/src/libCom/osi/os/Linux/osdSock.h b/src/libCom/osi/os/Linux/osdSock.h deleted file mode 100644 index 614f3f98d..000000000 --- a/src/libCom/osi/os/Linux/osdSock.h +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Linux specific socket include - */ - -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; -typedef socklen_t osiSocklen_t; - -#define FD_IN_FDSET(FD) ((FD)ifr_name)) - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/Linux/osdThread.h b/src/libCom/osi/os/Linux/osdThread.h deleted file mode 100644 index 7d2a4868d..000000000 --- a/src/libCom/osi/os/Linux/osdThread.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef INC_osdThread_H -#define INC_osdThread_H - -#include -#include - -#include "shareLib.h" -#include "ellLib.h" -#include "epicsEvent.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct epicsThreadOSD { - ELLNODE node; - pthread_t tid; - pid_t lwpId; - pthread_attr_t attr; - struct sched_param schedParam; - int schedPolicy; - EPICSTHREADFUNC createFunc; - void *createArg; - epicsEventId suspendEvent; - int isSuspended; - int isEpicsThread; - int isRealTimeScheduled; - int isOnThreadList; - unsigned int osiPriority; - char name[1]; /* actually larger */ -} epicsThreadOSD; - -epicsShareFunc pthread_t epicsThreadGetPosixThreadId(epicsThreadId id); -epicsShareFunc int epicsThreadGetPosixPriority(epicsThreadId id); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_osdThread_H */ diff --git a/src/libCom/osi/os/Linux/osdThreadExtra.c b/src/libCom/osi/os/Linux/osdThreadExtra.c deleted file mode 100644 index 6423004c5..000000000 --- a/src/libCom/osi/os/Linux/osdThreadExtra.c +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2012 ITER Organization -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 18JAN2000 */ - -/* This differs from the posix implementation of epicsThread by: - * - printing the Linux LWP ID instead of the POSIX thread ID in the show routines - * - installing a default thread start hook, that sets the Linux thread name to the - * EPICS thread name to make it visible on OS level, and discovers the LWP ID */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "ellLib.h" -#include "epicsEvent.h" -#include "epicsThread.h" - -void epicsThreadShowInfo(epicsThreadId pthreadInfo, unsigned int level) -{ - if (!pthreadInfo) { - fprintf(epicsGetStdout(), " NAME EPICS ID " - "LWP ID OSIPRI OSSPRI STATE\n"); - } else { - struct sched_param param; - int priority = 0; - - if (pthreadInfo->tid) { - int policy; - int status = pthread_getschedparam(pthreadInfo->tid, &policy, - ¶m); - - if (!status) - priority = param.sched_priority; - } - fprintf(epicsGetStdout(),"%16.16s %14p %8lu %3d%8d %8.8s\n", - pthreadInfo->name,(void *) - pthreadInfo,(unsigned long)pthreadInfo->lwpId, - pthreadInfo->osiPriority,priority, - pthreadInfo->isSuspended ? "SUSPEND" : "OK"); - } -} - -static void thread_hook(epicsThreadId pthreadInfo) -{ - /* Set the name of the thread's process. Limited to 16 characters. */ - char comm[16]; - - if (strcmp(pthreadInfo->name, "_main_")) { - snprintf(comm, sizeof(comm), "%s", pthreadInfo->name); - prctl(PR_SET_NAME, comm, 0l, 0l, 0l); - } - pthreadInfo->lwpId = syscall(SYS_gettid); -} - -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault = thread_hook; -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain = thread_hook; diff --git a/src/libCom/osi/os/Linux/osdTime.h b/src/libCom/osi/os/Linux/osdTime.h deleted file mode 100644 index 988f8747f..000000000 --- a/src/libCom/osi/os/Linux/osdTime.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Eric Norum - */ - -#ifndef osdTimeh -#define osdTimeh - -/* - * Linux needs this include file since the POSIX version - * causes `struct timespec' to be defined in more than one place. - */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void epicsShareAPI - convertDoubleToWakeTime(double timeout,struct timespec *wakeTime); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ifndef osdTimeh */ - diff --git a/src/libCom/osi/os/Linux/osiFileName.h b/src/libCom/osi/os/Linux/osiFileName.h deleted file mode 100644 index 3a6448d54..000000000 --- a/src/libCom/osi/os/Linux/osiFileName.h +++ /dev/null @@ -1,19 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * osiFileName.h - * Author: Jeff Hill - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/Linux/osiUnistd.h b/src/libCom/osi/os/Linux/osiUnistd.h deleted file mode 100644 index 336a9a802..000000000 --- a/src/libCom/osi/os/Linux/osiUnistd.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include - -/* - * Some systems fail to provide prototypes of these functions. - * Others provide different prototypes. - * There seems to be no way to handle this automatically, so - * if you get compile errors, just make the appropriate changes here. - */ diff --git a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c b/src/libCom/osi/os/RTEMS/devLibVMEOSD.c deleted file mode 100644 index 0a96bad1a..000000000 --- a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c +++ /dev/null @@ -1,365 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* RTEMS port by Till Straumann, - * 3/2002 - * - */ - -#include -#include -#include -#include -#include "devLibVME.h" -#include - -#if defined(__PPC__) || defined(__mcf528x__) - -#if defined(__PPC__) -#include -#include -#endif - - -typedef void myISR (void *pParam); - -static myISR *isrFetch(unsigned vectorNumber, void **parg); - -/* - * this routine needs to be in the symbol table - * for this code to work correctly - */ -static void unsolicitedHandlerEPICS(int vectorNumber); - -static myISR *defaultHandlerAddr[]={ - (myISR*)unsolicitedHandlerEPICS, -}; - -/* - * Make sure that the CR/CSR addressing mode is defined. - * (it may not be in some BSPs). - */ -#ifndef VME_AM_CSR -# define VME_AM_CSR (0x2f) -#endif - -/* - * we use a translation between an EPICS encoding - * and a vxWorks encoding here - * to reduce dependency of drivers on vxWorks - * - * we assume that the BSP are configured to use these - * address modes by default - */ -#define EPICSAddrTypeNoConvert -1 -int EPICStovxWorksAddrType[] - = { - VME_AM_SUP_SHORT_IO, - VME_AM_STD_SUP_DATA, - VME_AM_EXT_SUP_DATA, - EPICSAddrTypeNoConvert, - VME_AM_CSR - }; - -/* - * maps logical address to physical address, but does not detect - * two device drivers that are using the same address range - */ -static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options, - size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress); - -/* - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ -static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue); - -/* - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ -static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue); - -static long rtemsDevConnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)(), - void *parameter); - -static long rtemsDevDisconnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)() -); - -static long rtemsDevEnableInterruptLevelVME (unsigned level); - -static long rtemsDevDisableInterruptLevelVME (unsigned level); - -static int rtemsDevInterruptInUseVME (unsigned vectorNumber); - -/* RTEMS specific init */ - -/*devA24Malloc and devA24Free are not implemented*/ -static void *devA24Malloc(size_t size) { return 0;} -static void devA24Free(void *pBlock) {}; -static long rtemsDevInit(void); - -/* - * used by bind in devLib.c - */ -static devLibVME rtemsVirtualOS = { - rtemsDevMapAddr, rtemsDevReadProbe, rtemsDevWriteProbe, - rtemsDevConnectInterruptVME, rtemsDevDisconnectInterruptVME, - rtemsDevEnableInterruptLevelVME, rtemsDevDisableInterruptLevelVME, - devA24Malloc,devA24Free,rtemsDevInit,rtemsDevInterruptInUseVME -}; -devLibVME *pdevLibVME = &rtemsVirtualOS; - -/* RTEMS specific initialization */ -static long -rtemsDevInit(void) -{ - /* assume the vme bridge has been initialized by bsp */ - /* init BSP extensions [memProbe etc.] */ - return bspExtInit(); -} - -/* - * devConnectInterruptVME - * - * wrapper to minimize driver dependency on OS - */ -static long rtemsDevConnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)(), - void *parameter) -{ - int status; - - - if (devInterruptInUseVME(vectorNumber)) { - return S_dev_vectorInUse; - } - status = BSP_installVME_isr( - vectorNumber, - pFunction, - parameter); - if (status) { - return S_dev_vecInstlFail; - } - - return 0; -} - -/* - * - * devDisconnectInterruptVME() - * - * wrapper to minimize driver dependency on OS - * - * The parameter pFunction should be set to the C function pointer that - * was connected. It is used as a key to prevent a driver from removing - * an interrupt handler that was installed by another driver - * - */ -static long rtemsDevDisconnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)() -) -{ - void (*psub)(); - void *arg; - int status; - - /* - * If pFunction not connected to this vector - * then they are probably disconnecting from the wrong vector - */ - psub = isrFetch(vectorNumber, &arg); - if(psub != pFunction){ - return S_dev_vectorNotInUse; - } - - status = BSP_removeVME_isr( - vectorNumber, - psub, - arg) || - BSP_installVME_isr( - vectorNumber, - (BSP_VME_ISR_t)unsolicitedHandlerEPICS, - (void*)vectorNumber); - if(status){ - return S_dev_vecInstlFail; - } - - return 0; -} - -/* - * enable VME interrupt level - */ -static long rtemsDevEnableInterruptLevelVME (unsigned level) -{ - return BSP_enableVME_int_lvl(level); -} - -/* - * disable VME interrupt level - */ -static long rtemsDevDisableInterruptLevelVME (unsigned level) -{ - return BSP_disableVME_int_lvl(level); -} - -/* - * rtemsDevMapAddr () - */ -static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options, - size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress) -{ - long status; - - if (ppPhysicalAddress==NULL) { - return S_dev_badArgument; - } - - if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert) - { - *ppPhysicalAddress = (void *) logicalAddress; - } - else - { - status = BSP_vme2local_adrs(EPICStovxWorksAddrType[addrType], - logicalAddress, (unsigned long *)ppPhysicalAddress); - if (status) { - return S_dev_addrMapFail; - } - } - - return 0; -} - -/* - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ -rtems_status_code bspExtMemProbe(void *addr, int write, int size, void *pval); -static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) -{ - long status; - - /* - * this global variable exists in the nivxi library - */ - status = bspExtMemProbe ((void*)ptr, 0/*read*/, wordSize, pValue); - if (status!=RTEMS_SUCCESSFUL) { - return S_dev_noDevice; - } - - return 0; -} - -/* - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ -static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue) -{ - long status; - - /* - * this global variable exists in the nivxi library - */ - status = bspExtMemProbe ((void*)ptr, 1/*write*/, wordSize, (void*)pValue); - if (status!=RTEMS_SUCCESSFUL) { - return S_dev_noDevice; - } - - return 0; -} - -/* - * isrFetch() - */ -static myISR *isrFetch(unsigned vectorNumber, void **parg) -{ - /* - * fetch the handler or C stub attached at this vector - */ - return (myISR *) BSP_getVME_isr(vectorNumber,parg); -} - -/* - * determine if a VME interrupt vector is in use - */ -static int rtemsDevInterruptInUseVME (unsigned vectorNumber) -{ - int i; - myISR *psub; - void *arg; - - psub = isrFetch (vectorNumber,&arg); - - if (!psub) - return FALSE; - - /* - * its a C routine. Does it match a default handler? - */ - for (i=0; i -#include "epicsMMIO.h" -#include "compilerSpecific.h" -#include "epicsInterrupt.h" - -#define EPICS_ATOMIC_OS_NAME "RTEMS" - -typedef struct EpicsAtomicLockKey { - int key; -} EpicsAtomicLockKey; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - epicsAtomicMemoryBarrierFallback(); -} -#endif - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - rwbarr(); -} -#endif - -EPICS_ATOMIC_INLINE void epicsAtomicLock ( struct EpicsAtomicLockKey * pkey ) -{ - pkey->key = epicsInterruptLock(); -} - -EPICS_ATOMIC_INLINE void epicsAtomicUnlock ( struct EpicsAtomicLockKey * pkey ) -{ - epicsInterruptUnlock(pkey->key); -} - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#include "epicsAtomicDefault.h" - -#endif /* epicsAtomicOSD_h */ - diff --git a/src/libCom/osi/os/RTEMS/epicsMMIO.h b/src/libCom/osi/os/RTEMS/epicsMMIO.h deleted file mode 100644 index 293886b78..000000000 --- a/src/libCom/osi/os/RTEMS/epicsMMIO.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Michael Davidsaver - */ - -#ifndef EPICSMMIO_H -#define EPICSMMIO_H - -#include -#include -#include - -#if defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC) -# include - -/*NOTE: All READ/WRITE operations have an implicit read or write barrier */ - -# define ioread8(A) in_8((volatile epicsUInt8*)(A)) -# define iowrite8(A,D) out_8((volatile epicsUInt8*)(A), D) -# define le_ioread16(A) in_le16((volatile epicsUInt16*)(A)) -# define le_ioread32(A) in_le32((volatile epicsUInt32*)(A)) -# define le_iowrite16(A,D) out_le16((volatile epicsUInt16*)(A), D) -# define le_iowrite32(A,D) out_le32((volatile epicsUInt32*)(A), D) -# define be_ioread16(A) in_be16((volatile epicsUInt16*)(A)) -# define be_ioread32(A) in_be32((volatile epicsUInt32*)(A)) -# define be_iowrite16(A,D) out_be16((volatile epicsUInt16*)(A), D) -# define be_iowrite32(A,D) out_be32((volatile epicsUInt32*)(A), D) - -# define rbarr() iobarrier_r() -# define wbarr() iobarrier_w() -# define rwbarr() iobarrier_rw() - -/* Define native operations */ -# define nat_ioread16 be_ioread16 -# define nat_ioread32 be_ioread32 -# define nat_iowrite16 be_iowrite16 -# define nat_iowrite32 be_iowrite32 - -static EPICS_ALWAYS_INLINE -epicsUInt16 -bswap16(epicsUInt16 value) -{ - return (((epicsUInt16)(value) & 0x00ff) << 8) | - (((epicsUInt16)(value) & 0xff00) >> 8); -} - -static EPICS_ALWAYS_INLINE -epicsUInt32 -bswap32(epicsUInt32 value) -{ - return (((epicsUInt32)(value) & 0x000000ff) << 24) | - (((epicsUInt32)(value) & 0x0000ff00) << 8) | - (((epicsUInt32)(value) & 0x00ff0000) >> 8) | - (((epicsUInt32)(value) & 0xff000000) >> 24); -} - -#elif defined(i386) || defined(__i386__) || defined(__i386) || defined(__m68k__) - -/* X86 does not need special handling for read/write width. - * - * TODO: Memory barriers? - */ - -#include "epicsMMIODef.h" - -#else -# warning I/O operations not defined for this RTEMS architecture - -#include "epicsMMIODef.h" - -#endif /* if defined PPC */ - -#endif /* EPICSMMIO_H */ diff --git a/src/libCom/osi/os/RTEMS/epicsMath.h b/src/libCom/osi/os/RTEMS/epicsMath.h deleted file mode 100644 index 83115f06e..000000000 --- a/src/libCom/osi/os/RTEMS/epicsMath.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsMathh -#define epicsMathh - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* epicsMathh */ diff --git a/src/libCom/osi/os/RTEMS/osdEvent.c b/src/libCom/osi/os/RTEMS/osdEvent.c deleted file mode 100644 index 455413870..000000000 --- a/src/libCom/osi/os/RTEMS/osdEvent.c +++ /dev/null @@ -1,200 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdEvent.c - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ - -/* - * We want to access information which is - * normally hidden from application programs. - */ -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1 - -#include -#include -#include - -#include "epicsEvent.h" -#include "epicsThread.h" -#include "errlog.h" - -/* #define EPICS_RTEMS_SEMAPHORE_STATS */ -/* - * Some performance tuning instrumentation - */ -#ifdef EPICS_RTEMS_SEMAPHORE_STATS -unsigned long semEstat[4]; -#define SEMSTAT(i) semEstat[i]++; -#else -#define SEMSTAT(i) -#endif - -/* - * Create a simple binary semaphore - */ -epicsEventId -epicsEventCreate(epicsEventInitialState initialState) -{ - rtems_status_code sc; - rtems_id sid; - rtems_interrupt_level level; - static char c1 = 'a'; - static char c2 = 'a'; - static char c3 = 'a'; - - sc = rtems_semaphore_create (rtems_build_name ('B', c3, c2, c1), - initialState, - RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | - RTEMS_NO_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL, - 0, - &sid); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf ("Can't create binary semaphore: %s\n", rtems_status_text (sc)); - return NULL; - } - rtems_interrupt_disable (level); - if (c1 == 'z') { - if (c2 == 'z') { - if (c3 == 'z') { - c3 = 'a'; - } - else { - c3++; - } - c2 = 'a'; - } - else { - c2++; - } - c1 = 'a'; - } - else { - c1++; - } - rtems_interrupt_enable (level); - return (epicsEventId)sid; -} - -void -epicsEventDestroy(epicsEventId id) -{ - rtems_id sid = (rtems_id)id; - rtems_status_code sc; - - sc = rtems_semaphore_delete (sid); - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf ("Can't destroy semaphore: %s\n", rtems_status_text (sc)); -} - -epicsEventStatus -epicsEventTrigger(epicsEventId id) -{ - rtems_id sid = (rtems_id)id; - rtems_status_code sc; - - sc = rtems_semaphore_release (sid); - if (sc == RTEMS_SUCCESSFUL) - return epicsEventOK; - errlogPrintf ("Can't release semaphore: %s\n", rtems_status_text (sc)); - return epicsEventError; -} - -epicsEventStatus -epicsEventWait(epicsEventId id) -{ - rtems_id sid = (rtems_id)id; - rtems_status_code sc; - - SEMSTAT(0) - sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - return epicsEventError; - return epicsEventOK; -} - -epicsEventStatus -epicsEventWaitWithTimeout(epicsEventId id, double timeOut) -{ - rtems_id sid = (rtems_id)id; - rtems_status_code sc; - rtems_interval delay; - extern double rtemsTicksPerSecond_double; - - if (timeOut <= 0.0) - return epicsEventTryWait(id); - SEMSTAT(1) - delay = timeOut * rtemsTicksPerSecond_double; - if (delay == 0) - delay++; - sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, delay); - if (sc == RTEMS_SUCCESSFUL) - return epicsEventOK; - else if (sc == RTEMS_TIMEOUT) - return epicsEventWaitTimeout; - else - return epicsEventError; -} - -epicsEventStatus -epicsEventTryWait(epicsEventId id) -{ - rtems_id sid = (rtems_id)id; - rtems_status_code sc; - - SEMSTAT(2) - sc = rtems_semaphore_obtain (sid, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT); - if (sc == RTEMS_SUCCESSFUL) - return epicsEventOK; - else if (sc == RTEMS_UNSATISFIED) - return epicsEventWaitTimeout; - else - return epicsEventError; -} - -void -epicsEventShow(epicsEventId id, unsigned int level) -{ -#if __RTEMS_VIOLATE_KERNEL_VISIBILITY__ - rtems_id sid = (rtems_id)id; - Semaphore_Control *the_semaphore; - Semaphore_Control semaphore; - Objects_Locations location; - - the_semaphore = _Semaphore_Get (sid, &location); - if (location != OBJECTS_LOCAL) - return; - /* - * Yes, there's a race condition here since an interrupt might - * change things while the copy is in progress, but the information - * is only for display, so it's not that critical. - */ - semaphore = *the_semaphore; - _Thread_Enable_dispatch(); - printf (" %8.8x ", (int)sid); - if (_Attributes_Is_counting_semaphore (semaphore.attribute_set)) { - printf ("Count: %d", (int)semaphore.Core_control.semaphore.count); - } - else { - if (_CORE_mutex_Is_locked(&semaphore.Core_control.mutex)) { - char name[30]; - epicsThreadGetName ((epicsThreadId)semaphore.Core_control.mutex.holder_id, name, sizeof name); - printf ("Held by:%8.8x (%s) Nest count:%d", - (unsigned int)semaphore.Core_control.mutex.holder_id, - name, - (int)semaphore.Core_control.mutex.nest_count); - } - else { - printf ("Not Held"); - } - } - printf ("\n"); -#endif -} diff --git a/src/libCom/osi/os/RTEMS/osdEvent.h b/src/libCom/osi/os/RTEMS/osdEvent.h deleted file mode 100644 index 6c53aada7..000000000 --- a/src/libCom/osi/os/RTEMS/osdEvent.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdEvent.h - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ - -/* osdEvent.h not needed */ diff --git a/src/libCom/osi/os/RTEMS/osdFindSymbol.c b/src/libCom/osi/os/RTEMS/osdFindSymbol.c deleted file mode 100644 index 9e947f95c..000000000 --- a/src/libCom/osi/os/RTEMS/osdFindSymbol.c +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/RTEMS/osdFindSymbol.c */ - -/* GESYS could support this, but must use compile-time detection - * as the code must build for non-GESYS systems as well. - */ - -#define epicsExportSharedSymbols -#include "epicsFindSymbol.h" - -epicsShareFunc void * epicsLoadLibrary(const char *name) -{ - return 0; -} - -epicsShareFunc const char *epicsLoadError(void) -{ - return "epicsLoadLibrary not implemented"; -} - -epicsShareFunc void * epicsShareAPI epicsFindSymbol(const char *name) -{ - return 0; -} diff --git a/src/libCom/osi/os/RTEMS/osdInterrupt.c b/src/libCom/osi/os/RTEMS/osdInterrupt.c deleted file mode 100644 index 88ce664e5..000000000 --- a/src/libCom/osi/os/RTEMS/osdInterrupt.c +++ /dev/null @@ -1,94 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdInterrupt.c - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ - -#include -#include -#include -#include "errlog.h" -#include "epicsInterrupt.h" -#include "epicsThread.h" - -#define INTERRUPT_CONTEXT_MESSAGE_QUEUE_COUNT 100 - -static rtems_id interruptContextMessageQueue; - -int -epicsInterruptLock (void) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable (level); - return level; -} - -void -epicsInterruptUnlock (int key) -{ - rtems_interrupt_level level = key; - - rtems_interrupt_enable (level); -} - -int -epicsInterruptIsInterruptContext (void) -{ - return rtems_interrupt_is_in_progress (); -} - -/* - * Pass a message from an interrupt context. - * Note that this passes a pointer to the message, not the message itself. - * This implies that the message must remain valid after the - * interrupt context is no longer active. - */ -void -epicsInterruptContextMessage (const char *message) -{ - rtems_message_queue_send (interruptContextMessageQueue, &message, sizeof message); -} - -/* - * Daemon to process interrupt context messages - */ -void -InterruptContextMessageDaemon (void *unused) -{ - const char *message; - size_t size; - rtems_status_code sc; - - sc = rtems_message_queue_create (rtems_build_name ('I', 'C', 'M', 'Q'), - INTERRUPT_CONTEXT_MESSAGE_QUEUE_COUNT, - sizeof message, - RTEMS_FIFO | RTEMS_LOCAL, - &interruptContextMessageQueue); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf ("Can't create interrupt context message queue: %s\n", rtems_status_text (sc)); - epicsThreadSuspendSelf (); - } - for (;;) { - sc = rtems_message_queue_receive (interruptContextMessageQueue, - &message, - &size, - RTEMS_WAIT, - RTEMS_NO_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf ("Can't receive message from interrupt context: %s\n", rtems_status_text (sc)); - epicsThreadSuspendSelf (); - } - if (size == sizeof message) - syslog (LOG_ERR, "%s", message); - else - errlogPrintf ("Received %u-byte message from interrupt context", (unsigned int)size); - } -} diff --git a/src/libCom/osi/os/RTEMS/osdInterrupt.h b/src/libCom/osi/os/RTEMS/osdInterrupt.h deleted file mode 100644 index 2f3a2c596..000000000 --- a/src/libCom/osi/os/RTEMS/osdInterrupt.h +++ /dev/null @@ -1,13 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Daemon to soak up and report messages from interrupt contexts - */ -extern void InterruptContextMessageDaemon (void *); diff --git a/src/libCom/osi/os/RTEMS/osdMessageQueue.c b/src/libCom/osi/os/RTEMS/osdMessageQueue.c deleted file mode 100644 index a566de6f6..000000000 --- a/src/libCom/osi/os/RTEMS/osdMessageQueue.c +++ /dev/null @@ -1,251 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -/* - * We want to access information which is - * normally hidden from application programs. - */ -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1 - -#define epicsExportSharedSymbols -#include -#include -#include -#include -#include -#include -#include "epicsMessageQueue.h" -#include "errlog.h" - -epicsShareFunc epicsMessageQueueId epicsShareAPI -epicsMessageQueueCreate(unsigned int capacity, unsigned int maximumMessageSize) -{ - rtems_status_code sc; - epicsMessageQueueId id = calloc(1, sizeof(*id)); - rtems_interrupt_level level; - static char c1 = 'a'; - static char c2 = 'a'; - static char c3 = 'a'; - - if(!id) - return NULL; - - sc = rtems_message_queue_create (rtems_build_name ('Q', c3, c2, c1), - capacity, - maximumMessageSize, - RTEMS_FIFO|RTEMS_LOCAL, - &id->id); - if (sc != RTEMS_SUCCESSFUL) { - free(id); - errlogPrintf ("Can't create message queue: %s\n", rtems_status_text (sc)); - return NULL; - } - id->maxSize = maximumMessageSize; - id->localBuf = NULL; - rtems_interrupt_disable (level); - if (c1 == 'z') { - if (c2 == 'z') { - if (c3 == 'z') { - c3 = 'a'; - } - else { - c3++; - } - c2 = 'a'; - } - else { - c2++; - } - c1 = 'a'; - } - else { - c1++; - } - rtems_interrupt_enable (level); - return id; -} - -static rtems_status_code rtems_message_queue_send_timeout( - rtems_id id, - void *buffer, - uint32_t size, - rtems_interval timeout) -{ - Message_queue_Control *the_message_queue; - Objects_Locations location; - CORE_message_queue_Status msg_status; - - the_message_queue = _Message_queue_Get( id, &location ); - switch ( location ) - { - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - msg_status = _CORE_message_queue_Send( - &the_message_queue->message_queue, - buffer, - size, - id, - NULL, - 1, - timeout - ); - - _Thread_Enable_dispatch(); - - /* - * If we had to block, then this is where the task returns - * after it wakes up. The returned status is correct for - * non-blocking operations but if we blocked, then we need - * to look at the status in our TCB. - */ - - if ( msg_status == CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT ) - msg_status = _Thread_Executing->Wait.return_code; - return _Message_queue_Translate_core_message_queue_return_code( msg_status ); - } - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -epicsShareFunc int epicsShareAPI epicsMessageQueueSend( - epicsMessageQueueId id, - void *message, - unsigned int messageSize) -{ - if (rtems_message_queue_send_timeout(id->id, message, messageSize, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL) - return 0; - else - return -1; -} - -epicsShareFunc int epicsShareAPI epicsMessageQueueSendWithTimeout( - epicsMessageQueueId id, - void *message, - unsigned int messageSize, - double timeout) -{ - rtems_interval delay; - extern double rtemsTicksPerSecond_double; - - /* - * Convert time to ticks - */ - if (timeout <= 0.0) - return epicsMessageQueueTrySend(id, message, messageSize); - delay = (int)(timeout * rtemsTicksPerSecond_double); - if (delay == 0) - delay++; - if (rtems_message_queue_send_timeout(id->id, message, messageSize, delay) == RTEMS_SUCCESSFUL) - return 0; - else - return -1; -} - -static int receiveMessage( - epicsMessageQueueId id, - void *buffer, - uint32_t size, - uint32_t wait, - rtems_interval delay) -{ - size_t rsize; - rtems_status_code sc; - - if (size < id->maxSize) { - if (id->localBuf == NULL) { - id->localBuf = malloc(id->maxSize); - if (id->localBuf == NULL) - return -1; - } - rsize = receiveMessage(id, id->localBuf, id->maxSize, wait, delay); - if (rsize > size) - return -1; - memcpy(buffer, id->localBuf, rsize); - } - else { - sc = rtems_message_queue_receive(id->id, buffer, &rsize, wait, delay); - if (sc != RTEMS_SUCCESSFUL) - return -1; - } - return rsize; -} - -epicsShareFunc int epicsShareAPI epicsMessageQueueTryReceive( - epicsMessageQueueId id, - void *message, - unsigned int size) -{ - return receiveMessage(id, message, size, RTEMS_NO_WAIT, 0); -} - -epicsShareFunc int epicsShareAPI epicsMessageQueueReceive( - epicsMessageQueueId id, - void *message, - unsigned int size) -{ - return receiveMessage(id, message, size, RTEMS_WAIT, RTEMS_NO_TIMEOUT); -} - -epicsShareFunc int epicsShareAPI epicsMessageQueueReceiveWithTimeout( - epicsMessageQueueId id, - void *message, - unsigned int size, - double timeout) -{ - rtems_interval delay; - uint32_t wait; - extern double rtemsTicksPerSecond_double; - - /* - * Convert time to ticks - */ - if (timeout <= 0.0) { - wait = RTEMS_NO_WAIT; - delay = 0; - } - else { - wait = RTEMS_WAIT; - delay = (int)(timeout * rtemsTicksPerSecond_double); - if (delay == 0) - delay++; - } - return receiveMessage(id, message, size, wait, delay); -} - -epicsShareFunc int epicsShareAPI epicsMessageQueuePending( - epicsMessageQueueId id) -{ - uint32_t count; - rtems_status_code sc; - - sc = rtems_message_queue_get_number_pending(id->id, &count); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf("Message queue %x get number pending failed: %s\n", - (unsigned int)id, - rtems_status_text(sc)); - return -1; - } - return count; -} - -epicsShareFunc void epicsShareAPI epicsMessageQueueShow( - epicsMessageQueueId id, - int level) -{ - int pending = epicsMessageQueuePending(id); - if (pending >= 0) - printf ("Message queue %lx -- Pending: %d\n", (unsigned long)id, pending); -} diff --git a/src/libCom/osi/os/RTEMS/osdMessageQueue.h b/src/libCom/osi/os/RTEMS/osdMessageQueue.h deleted file mode 100644 index 0244a1f0b..000000000 --- a/src/libCom/osi/os/RTEMS/osdMessageQueue.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -/* - * Very thin shims around RTEMS routines - */ -#include - -struct epicsMessageQueueOSD { - rtems_id id; - unsigned int maxSize; - void *localBuf; - -}; -#define epicsMessageQueueDestroy(q) (rtems_message_queue_delete((q)->id)) - -#define epicsMessageQueueTrySend(q,m,l) (rtems_message_queue_send((q)->id, (m), (l)) == RTEMS_SUCCESSFUL ? 0 : -1) diff --git a/src/libCom/osi/os/RTEMS/osdMutex.c b/src/libCom/osi/os/RTEMS/osdMutex.c deleted file mode 100644 index 96fde6ea0..000000000 --- a/src/libCom/osi/os/RTEMS/osdMutex.c +++ /dev/null @@ -1,195 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdMutex.c - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ - -/* - * We want to access information which is - * normally hidden from application programs. - */ -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1 - -#include -#include -#include -#include - -#include "epicsStdio.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "errlog.h" - -#define RTEMS_FAST_MUTEX -/* #define EPICS_RTEMS_SEMAPHORE_STATS */ -/* - * Some performance tuning instrumentation - */ -#ifdef EPICS_RTEMS_SEMAPHORE_STATS -unsigned long semMstat[4]; -#define SEMSTAT(i) semMstat[i]++; -#else -#define SEMSTAT(i) -#endif - -struct epicsMutexOSD * -epicsMutexOsdCreate(void) -{ - rtems_status_code sc; - rtems_id sid; - rtems_interrupt_level level; - static char c1 = 'a'; - static char c2 = 'a'; - static char c3 = 'a'; - - sc = rtems_semaphore_create (rtems_build_name ('M', c3, c2, c1), - 1, - RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|RTEMS_INHERIT_PRIORITY|RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL, - 0, - &sid); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf ("Can't create mutex semaphore: %s\n", rtems_status_text (sc)); - return NULL; - } - rtems_interrupt_disable (level); - if (c1 == 'z') { - if (c2 == 'z') { - if (c3 == 'z') { - c3 = 'a'; - } - else { - c3++; - } - c2 = 'a'; - } - else { - c2++; - } - c1 = 'a'; - } - else { - c1++; - } - rtems_interrupt_enable (level); -#ifdef RTEMS_FAST_MUTEX - { - Semaphore_Control *the_semaphore; - Objects_Locations location; - - the_semaphore = _Semaphore_Get( sid, &location ); - _Thread_Enable_dispatch(); - - return (struct epicsMutexOSD *)the_semaphore; - } -#endif - return (struct epicsMutexOSD *)sid; -} - -void epicsMutexOsdDestroy(struct epicsMutexOSD * id) -{ - rtems_status_code sc; - rtems_id sid; -#ifdef RTEMS_FAST_MUTEX - Semaphore_Control *the_semaphore = (Semaphore_Control *)id; - sid = the_semaphore->Object.id; -#else - sid = (rtems_id)id; -#endif - sc = rtems_semaphore_delete (sid); - if (sc == RTEMS_RESOURCE_IN_USE) { - rtems_semaphore_release (sid); - sc = rtems_semaphore_delete (sid); - } - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf ("Can't destroy semaphore %p (%lx): %s\n", id, (unsigned long)sid, rtems_status_text (sc)); -} - -void epicsMutexOsdUnlock(struct epicsMutexOSD * id) -{ -#ifdef RTEMS_FAST_MUTEX - Semaphore_Control *the_semaphore = (Semaphore_Control *)id; - _Thread_Disable_dispatch(); - _CORE_mutex_Surrender ( - &the_semaphore->Core_control.mutex, - the_semaphore->Object.id, - NULL - ); - _Thread_Enable_dispatch(); -#else - epicsEventSignal (id); -#endif - -} - -epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * id) -{ -#ifdef RTEMS_FAST_MUTEX - Semaphore_Control *the_semaphore = (Semaphore_Control *)id; - ISR_Level level; - SEMSTAT(0) - _ISR_Disable( level ); - _CORE_mutex_Seize( - &the_semaphore->Core_control.mutex, - the_semaphore->Object.id, - 1, /* TRUE or FALSE */ - 0, /* same as passed to obtain -- ticks */ - level - ); - if (_Thread_Executing->Wait.return_code == 0) - return epicsMutexLockOK; - else - return epicsMutexLockError; -#else - SEMSTAT(0) - return((epicsEventWait (id) == epicsEventWaitOK) - ?epicsMutexLockOK : epicsMutexLockError); -#endif -} - -epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * id) -{ -#ifdef RTEMS_FAST_MUTEX - Semaphore_Control *the_semaphore = (Semaphore_Control *)id; - ISR_Level level; - SEMSTAT(2) - _ISR_Disable( level ); - _CORE_mutex_Seize( - &the_semaphore->Core_control.mutex, - the_semaphore->Object.id, - 0, /* TRUE or FALSE */ - 0, /* same as passed to obtain -- ticks */ - level - ); - if (_Thread_Executing->Wait.return_code == CORE_MUTEX_STATUS_SUCCESSFUL) - return epicsMutexLockOK; - else if (_Thread_Executing->Wait.return_code == CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT) - return epicsMutexLockTimeout; - else - return epicsMutexLockError; -#else - epicsEventWaitStatus status; - SEMSTAT(2) - status = epicsEventTryWait(id); - return((status==epicsEventWaitOK - ? epicsMutexLockOK - : (status==epicsEventWaitTimeout) - ? epicsMutexLockTimeout - : epicsMutexLockError)); -#endif -} - -epicsShareFunc void epicsMutexOsdShow(struct epicsMutexOSD * id,unsigned int level) -{ -#ifdef RTEMS_FAST_MUTEX - Semaphore_Control *the_semaphore = (Semaphore_Control *)id; - id = (struct epicsMutexOSD *)the_semaphore->Object.id; -#endif - epicsEventShow ((epicsEventId)id,level); -} diff --git a/src/libCom/osi/os/RTEMS/osdMutex.h b/src/libCom/osi/os/RTEMS/osdMutex.h deleted file mode 100644 index 7e2ecc77d..000000000 --- a/src/libCom/osi/os/RTEMS/osdMutex.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdMutex.h - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ - -/* osdSem.h not needed */ diff --git a/src/libCom/osi/os/RTEMS/osdPoolStatus.c b/src/libCom/osi/os/RTEMS/osdPoolStatus.c deleted file mode 100644 index b2f401190..000000000 --- a/src/libCom/osi/os/RTEMS/osdPoolStatus.c +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include - -#define epicsExportSharedSymbols -#include "osiPoolStatus.h" - -/* - * osiSufficentSpaceInPool () - */ -epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize ) -{ - rtems_malloc_statistics_t s; - unsigned long n; - - malloc_get_statistics(&s); - n = s.space_available - (unsigned long)(s.lifetime_allocated - s.lifetime_freed); - return (n > (50000 + contiguousBlockSize)); -} diff --git a/src/libCom/osi/os/RTEMS/osdProcess.c b/src/libCom/osi/os/RTEMS/osdProcess.c deleted file mode 100644 index 2768dbb0d..000000000 --- a/src/libCom/osi/os/RTEMS/osdProcess.c +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Operating System Dependent Implementation of osiProcess.h - * - * Author: Jeff Hill - * - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "osiProcess.h" - -epicsShareFunc osiGetUserNameReturn epicsShareAPI osiGetUserName (char *pBuf, unsigned bufSizeIn) -{ - const char *pName = "rtems"; - unsigned uiLength; - size_t len; - - len = strlen (pName); - - if ( len>UINT_MAX || len<=0 ) { - return osiGetUserNameFail; - } - uiLength = (unsigned) len; - - if ( uiLength + 1 >= bufSizeIn ) { - return osiGetUserNameFail; - } - - strncpy ( pBuf, pName, (size_t) bufSizeIn ); - - return osiGetUserNameSuccess; -} - -epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProcess - (const char *pProcessName, const char *pBaseExecutableName) -{ - return osiSpawnDetachedProcessNoSupport; -} diff --git a/src/libCom/osi/os/RTEMS/osdReadline.c b/src/libCom/osi/os/RTEMS/osdReadline.c deleted file mode 100644 index 877db53f6..000000000 --- a/src/libCom/osi/os/RTEMS/osdReadline.c +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Eric Norum Date: 12DEC2001 */ - -/* - * This file is included by epicsReadline.c which has already included the - * headers stdio.h, stdlib.h, errno.h, envDefs.h and epicsReadline.h - */ - -#include -#include - -struct osdContext {}; - -/* - * Create a command-line context - */ -static void -osdReadlineBegin (struct readlineContext *context) -{ - GetLine *gl; - long i = 50; - - envGetLongConfigParam(&IOCSH_HISTSIZE, &i); - if (i < 0) - i = 0; - - gl = new_GetLine(200, i * 40); - if (gl) { - context->osd = (struct osdContext *) gl; - if (context->in) - gl_change_terminal(gl, context->in, stdout, NULL); - } -} - -/* - * Read a line of input - */ -static char * -osdReadline (const char *prompt, struct readlineContext *context) -{ - GetLine *gl = (GetLine *) context->osd; - char *line; - - line = gl_get_line(gl, prompt ? prompt : "", NULL, -1); - if (line) { - char *nl = strchr(line, '\n'); - - if (nl) - *nl = '\0'; - } - return line; -} - -/* - * Destroy a command-line context - */ -static void -osdReadlineEnd(struct readlineContext *context) -{ - GetLine *gl = (GetLine *) context->osd; - - del_GetLine(gl); -} - diff --git a/src/libCom/osi/os/RTEMS/osdSignal.cpp b/src/libCom/osi/os/RTEMS/osdSignal.cpp deleted file mode 100644 index 08dfa023c..000000000 --- a/src/libCom/osi/os/RTEMS/osdSignal.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2002 The University of Chicago, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE Versions 3.13.7 - * and higher are distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "epicsSignal.h" - -/* - * All NOOPs if the os isnt POSIX - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm ( struct epicsThreadOSD * /* threadId */ ) {} - diff --git a/src/libCom/osi/os/RTEMS/osdSock.h b/src/libCom/osi/os/RTEMS/osdSock.h deleted file mode 100644 index 930ed0e72..000000000 --- a/src/libCom/osi/os/RTEMS/osdSock.h +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdSock.h - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); - -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; -typedef socklen_t osiSocklen_t; - -#define FD_IN_FDSET(FD) ((FD) -#include -#include - -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK (u_long)0x7F000001 -#endif - -#ifndef INADDR_NONE -# define INADDR_NONE (0xffffffff) -#endif - -/* - * For shutdown() - */ -#ifndef SHUT_RD -# define SHUT_RD 0 -#endif - -#ifndef SHUT_WR -# define SHUT_WR 1 -#endif - -#ifndef SHUT_RDWR -# define SHUT_RDWR 2 -#endif - -/* - * Ensure that we get the right network code in default/osdNetIntf.c. - */ -#define ifreq_size(pifreq) (pifreq->ifr_addr.sa_len + sizeof(pifreq->ifr_name)) - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/RTEMS/osdSpin.c b/src/libCom/osi/os/RTEMS/osdSpin.c deleted file mode 100644 index 7a4546812..000000000 --- a/src/libCom/osi/os/RTEMS/osdSpin.c +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2012 ITER Organization. -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2013 Brookhaven Science Assoc. as Operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Authors: Ralph Lange - * Andrew Johnson - * Michael Davidsaver - * - * Inspired by Linux UP spinlocks implemention - * include/linux/spinlock_api_up.h - */ - -/* - * RTEMS (single CPU): LOCK INTERRUPT and DISABLE PREEMPTION - * - * CAVEAT: - * This implementation is intended for UP architectures only. - */ - -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1 - -#include -#include - -#include "cantProceed.h" -#include "epicsSpin.h" - -typedef struct epicsSpin { - rtems_interrupt_level level; - unsigned int locked; -} epicsSpin; - -epicsSpinId epicsSpinCreate(void) { - return calloc(1, sizeof(epicsSpin)); -} - -epicsSpinId epicsSpinMustCreate(void) -{ - epicsSpinId ret = epicsSpinCreate(); - if (!ret) - cantProceed("epicsSpinMustCreate: epicsSpinCreate failed."); - return ret; -} - -void epicsSpinDestroy(epicsSpinId spin) { - free(spin); -} - -void epicsSpinLock(epicsSpinId spin) { - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - _Thread_Disable_dispatch(); - if (spin->locked) { - rtems_interrupt_enable(level); - _Thread_Enable_dispatch(); - if (!rtems_interrupt_is_in_progress()) { - printk("epicsSpinLock(%p): Deadlock.\n", spin); - cantProceed("Recursive lock, missed unlock or block when locked."); - } - else { - printk("epicsSpinLock(%p): Deadlock in ISR.\n" - "Recursive lock, missed unlock or block when locked.\n", - spin); - } - return; - } - spin->level = level; - spin->locked = 1; -} - -int epicsSpinTryLock(epicsSpinId spin) { - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - _Thread_Disable_dispatch(); - if (spin->locked) { - rtems_interrupt_enable(level); - _Thread_Enable_dispatch(); - return 1; - } - spin->level = level; - spin->locked = 1; - return 0; -} - -void epicsSpinUnlock(epicsSpinId spin) { - rtems_interrupt_level level = spin->level; - - if (!spin->locked) { - printk("epicsSpinUnlock(%p): not locked\n", spin); - return; - } - spin->level = spin->locked = 0; - rtems_interrupt_enable (level); - _Thread_Enable_dispatch(); -} diff --git a/src/libCom/osi/os/RTEMS/osdStrtod.h b/src/libCom/osi/os/RTEMS/osdStrtod.h deleted file mode 100644 index 39fda698d..000000000 --- a/src/libCom/osi/os/RTEMS/osdStrtod.h +++ /dev/null @@ -1,11 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * epicsStrtod() for systems with working strtod() routine - */ -#define epicsStrtod strtod diff --git a/src/libCom/osi/os/RTEMS/osdThread.c b/src/libCom/osi/os/RTEMS/osdThread.c deleted file mode 100644 index 769e95820..000000000 --- a/src/libCom/osi/os/RTEMS/osdThread.c +++ /dev/null @@ -1,748 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdThread.c - * Author: W. Eric Norum - */ - -/* - * We want to print out some task information which is - * normally hidden from application programs. - */ -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1 - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "epicsStdio.h" -#include "errlog.h" -#include "epicsMutex.h" -#include "epicsString.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "osiUnistd.h" -#include "osdInterrupt.h" -#include "epicsExit.h" - -epicsShareFunc void osdThreadHooksRun(epicsThreadId id); -epicsShareFunc void osdThreadHooksRunMain(epicsThreadId id); - -/* - * Per-task variables - */ -struct taskVar { - struct taskVar *forw; - struct taskVar *back; - char *name; - rtems_id id; - EPICSTHREADFUNC funptr; - void *parm; - unsigned int threadVariableCapacity; - void **threadVariables; -}; -static struct epicsMutexOSD *taskVarMutex; -static struct taskVar *taskVarHead; -#define RTEMS_NOTEPAD_TASKVAR 11 - -/* - * Support for `once-only' execution - */ -static volatile int initialized = 0; /* strictly speaking 'volatile' is not enough here, but it shouldn't hurt */ -static struct epicsMutexOSD *onceMutex; - -static -void epicsMutexOsdMustLock(struct epicsMutexOSD * L) -{ - while(epicsMutexOsdLock(L)!=epicsMutexLockOK) { - cantProceed("epicsThreadOnce() mutex error"); - } -} - -/* - * Just map osi 0 to 99 into RTEMS 199 to 100 - * For RTEMS lower number means higher priority - * RTEMS = 100 + (99 - osi) - * = 199 - osi - * osi = 199 - RTEMS - */ -int epicsThreadGetOsiPriorityValue(int ossPriority) -{ - if (ossPriority < 100) { - return epicsThreadPriorityMax; - } - else if (ossPriority > 199) { - return epicsThreadPriorityMin; - } - else { - return (199u - (unsigned int)ossPriority); - } -} - -int epicsThreadGetOssPriorityValue(unsigned int osiPriority) -{ - if (osiPriority > 99) { - return 100; - } - else { - return (199 - (signed int)osiPriority); - } -} - -/* - * epicsThreadLowestPriorityLevelAbove () - */ -epicsShareFunc epicsThreadBooleanStatus epicsThreadLowestPriorityLevelAbove - (unsigned int priority, unsigned *pPriorityJustAbove) -{ - unsigned newPriority = priority + 1; - - newPriority = priority + 1; - if (newPriority <= 99) { - *pPriorityJustAbove = newPriority; - return epicsThreadBooleanStatusSuccess; - } - return epicsThreadBooleanStatusFail; -} - -/* - * epicsThreadHighestPriorityLevelBelow () - */ -epicsShareFunc epicsThreadBooleanStatus epicsThreadHighestPriorityLevelBelow - (unsigned int priority, unsigned *pPriorityJustBelow) -{ - unsigned newPriority = priority - 1; - - if (newPriority <= 99) { - *pPriorityJustBelow = newPriority; - return epicsThreadBooleanStatusSuccess; - } - return epicsThreadBooleanStatusFail; -} - -unsigned int -epicsThreadGetStackSize (epicsThreadStackSizeClass size) -{ - unsigned int stackSize = 11000; - switch(size) { - case epicsThreadStackSmall: stackSize = 5000; break; - case epicsThreadStackMedium: stackSize = 8000; break; - case epicsThreadStackBig: break; - default: - errlogPrintf("epicsThreadGetStackSize illegal argument"); - break; - } - if (stackSize < RTEMS_MINIMUM_STACK_SIZE) - stackSize = RTEMS_MINIMUM_STACK_SIZE; - return stackSize; -} - -/* - * Ensure integrity of task variable list - */ -static void -taskVarLock (void) -{ - epicsMutexOsdMustLock (taskVarMutex); -} - -static void -taskVarUnlock (void) -{ - epicsMutexOsdUnlock (taskVarMutex); -} - -/* - * EPICS threads destroy themselves by returning from the thread entry function. - * This simple wrapper provides the same semantics on RTEMS. - */ -static rtems_task -threadWrapper (rtems_task_argument arg) -{ - struct taskVar *v = (struct taskVar *)arg; - - osdThreadHooksRun((epicsThreadId)v->id); - (*v->funptr)(v->parm); - epicsExitCallAtThreadExits (); - taskVarLock (); - if (v->back) - v->back->forw = v->forw; - else - taskVarHead = v->forw; - if (v->forw) - v->forw->back = v->back; - taskVarUnlock (); - free (v->threadVariables); - free (v->name); - free (v); - rtems_task_delete (RTEMS_SELF); -} - -/* - * The task wrapper takes care of cleanup - */ -void epicsThreadExitMain (void) -{ -} - -static void -setThreadInfo(rtems_id tid, const char *name, EPICSTHREADFUNC funptr, - void *parm) -{ - struct taskVar *v; - uint32_t note; - rtems_status_code sc; - - v = mallocMustSucceed (sizeof *v, "epicsThreadCreate_vars"); - v->name = epicsStrDup(name); - v->id = tid; - v->funptr = funptr; - v->parm = parm; - v->threadVariableCapacity = 0; - v->threadVariables = NULL; - note = (uint32_t)v; - rtems_task_set_note (tid, RTEMS_NOTEPAD_TASKVAR, note); - taskVarLock (); - v->forw = taskVarHead; - v->back = NULL; - if (v->forw) - v->forw->back = v; - taskVarHead = v; - taskVarUnlock (); - if (funptr) { - sc = rtems_task_start (tid, threadWrapper, (rtems_task_argument)v); - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf ("setThreadInfo: Can't start %s: %s\n", - name, rtems_status_text(sc)); - } -} - -/* - * OS-dependent initialization - * No need to worry about making this thread-safe since - * it must be called before epicsThreadCreate creates - * any new threads. - */ -static void -epicsThreadInit (void) -{ - if (!initialized) { - rtems_id tid; - rtems_task_priority old; - - rtems_task_set_priority (RTEMS_SELF, epicsThreadGetOssPriorityValue(99), &old); - onceMutex = epicsMutexOsdCreate(); - taskVarMutex = epicsMutexOsdCreate(); - if (!onceMutex || !taskVarMutex) - cantProceed("epicsThreadInit() can't create global mutexes\n"); - rtems_task_ident (RTEMS_SELF, 0, &tid); - setThreadInfo (tid, "_main_", NULL, NULL); - osdThreadHooksRunMain((epicsThreadId)tid); - initialized = 1; - epicsThreadCreate ("ImsgDaemon", 99, - epicsThreadGetStackSize (epicsThreadStackSmall), - InterruptContextMessageDaemon, NULL); - } -} - -void epicsThreadRealtimeLock(void) -{} - -/* - * Create and start a new thread - */ -epicsThreadId -epicsThreadCreate (const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) -{ - rtems_id tid; - rtems_status_code sc; - char c[4]; - - if (!initialized) epicsThreadInit(); - if (stackSize < RTEMS_MINIMUM_STACK_SIZE) { - errlogPrintf ("Warning: epicsThreadCreate %s illegal stackSize %d\n", - name, stackSize); - stackSize = RTEMS_MINIMUM_STACK_SIZE; - } - strncpy (c, name, sizeof c); - sc = rtems_task_create (rtems_build_name (c[0], c[1], c[2], c[3]), - epicsThreadGetOssPriorityValue (priority), - stackSize, - RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0), - RTEMS_FLOATING_POINT|RTEMS_LOCAL, - &tid); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf ("epicsThreadCreate create failure for %s: %s\n", - name, rtems_status_text(sc)); - return 0; - } - setThreadInfo (tid, name, funptr,parm); - return (epicsThreadId)tid; -} - -epicsThreadId -threadMustCreate (const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) -{ - epicsThreadId tid = epicsThreadCreate(name, priority, stackSize, funptr, parm); - - if (tid == NULL) - cantProceed(0); - return tid; -} - -void -epicsThreadSuspendSelf (void) -{ - rtems_status_code sc; - - sc = rtems_task_suspend (RTEMS_SELF); - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf("epicsThreadSuspendSelf failed: %s\n", - rtems_status_text(sc)); -} - -void epicsThreadResume(epicsThreadId id) -{ - rtems_id tid = (rtems_id)id; - rtems_status_code sc; - - sc = rtems_task_resume (tid); - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf("epicsThreadResume failed: %s\n", - rtems_status_text (sc)); -} - -unsigned int epicsThreadGetPriority(epicsThreadId id) -{ - rtems_id tid = (rtems_id)id; - rtems_status_code sc; - rtems_task_priority pri; - - sc = rtems_task_set_priority (tid, RTEMS_CURRENT_PRIORITY, &pri); - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf("epicsThreadGetPriority failed: %s\n", - rtems_status_text(sc)); - return epicsThreadGetOsiPriorityValue(pri); -} - -unsigned int epicsThreadGetPrioritySelf(void) -{ - return epicsThreadGetPriority((epicsThreadId)RTEMS_SELF); -} - -void -epicsThreadSetPriority (epicsThreadId id,unsigned int osip) -{ - rtems_id tid = (rtems_id)id; - rtems_status_code sc; - rtems_task_priority pri = epicsThreadGetOssPriorityValue(osip); - - sc = rtems_task_set_priority (tid, pri, &pri); - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf("epicsThreadSetPriority failed: %s\n", - rtems_status_text(sc)); -} - -int -epicsThreadIsEqual (epicsThreadId id1, epicsThreadId id2) -{ - return (id1 == id2); -} - -int -epicsThreadIsSuspended (epicsThreadId id) -{ - rtems_id tid = (rtems_id)id; - rtems_status_code sc; - - switch (sc = rtems_task_is_suspended (tid)) { - case RTEMS_SUCCESSFUL: - return 0; - - case RTEMS_ALREADY_SUSPENDED: - return 1; - - default: - return 1; - } -} - -void -epicsThreadSleep (double seconds) -{ - rtems_status_code sc; - rtems_interval delay; - extern double rtemsTicksPerSecond_double; - - if (seconds > 0.0) { - seconds *= rtemsTicksPerSecond_double; - seconds += 0.99999999; /* 8 9s here is optimal */ - delay = (seconds >= INT_MAX) ? INT_MAX : (int) seconds; - } - else { /* seconds <= 0 or NAN */ - delay = 0; - } - sc = rtems_task_wake_after (delay); - if(sc != RTEMS_SUCCESSFUL) - errlogPrintf("epicsThreadSleep: %s\n", rtems_status_text(sc)); -} - -epicsThreadId -epicsThreadGetIdSelf (void) -{ - rtems_id tid; - - rtems_task_ident (RTEMS_SELF, 0, &tid); - return (epicsThreadId)tid; -} - -const char *epicsThreadGetNameSelf(void) -{ - uint32_t note; - struct taskVar *v; - - rtems_task_get_note (RTEMS_SELF, RTEMS_NOTEPAD_TASKVAR, ¬e); - v = (void *)note; - return v->name; -} - -void epicsThreadGetName (epicsThreadId id, char *name, size_t size) -{ - rtems_id tid = (rtems_id)id; - struct taskVar *v; - int haveName = 0; - - taskVarLock (); - for (v=taskVarHead ; v != NULL ; v=v->forw) { - if (v->id == tid) { - strncpy(name, v->name, size); - haveName = 1; - break; - } - } - taskVarUnlock (); - if (!haveName) { -#if (__RTEMS_MAJOR__>4 || \ - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>8) || \ - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==8 && __RTEMS_REVISION__>=99)) - if (_Objects_Get_name_as_string((rtems_id)id, size, name) != NULL) - haveName = 1; -#else - /* - * Try to get the RTEMS task name - */ - Thread_Control *thr; - Objects_Locations l; - if ((thr=_Thread_Get(tid, &l)) != NULL) { - if (OBJECTS_LOCAL == l) { - int length; - Objects_Information *oi = _Objects_Get_information(tid); - if (oi->name_length >= size) - length = size - 1; - else - length = oi->name_length; - if (oi->is_string) - strncpy(name, thr->Object.name, length); - else - _Objects_Copy_name_raw( &thr->Object.name, name, length); - name[length] = '\0'; - haveName = 1; - } - _Thread_Enable_dispatch(); - } -#endif - } - if (!haveName) - snprintf(name, size, "0x%lx", (long)tid); - name[size-1] = '\0'; -} - -epicsThreadId epicsThreadGetId (const char *name) -{ - struct taskVar *v; - rtems_id tid = 0; - - /* - * Linear search is good enough since this routine - * is invoked only by command-line calls. - */ - taskVarLock (); - for (v = taskVarHead ; v != NULL ; v = v->forw) { - if (strcmp (name, v->name) == 0) { - tid = v->id; - break; - } - } - taskVarUnlock (); - return (epicsThreadId)tid; -} - -/* - * Ensure func() is run only once. - */ -void epicsThreadOnce(epicsThreadOnceId *id, void(*func)(void *), void *arg) -{ - #define EPICS_THREAD_ONCE_DONE (epicsThreadId) 1 - - if (!initialized) epicsThreadInit(); - epicsMutexOsdMustLock(onceMutex); - if (*id != EPICS_THREAD_ONCE_DONE) { - if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ - *id = epicsThreadGetIdSelf(); /* mark active */ - epicsMutexOsdUnlock(onceMutex); - func(arg); - epicsMutexOsdMustLock(onceMutex); - *id = EPICS_THREAD_ONCE_DONE; /* mark done */ - } else if (*id == epicsThreadGetIdSelf()) { - epicsMutexOsdUnlock(onceMutex); - cantProceed("Recursive epicsThreadOnce() initialization\n"); - } else - while (*id != EPICS_THREAD_ONCE_DONE) { - /* Another thread is in the above func(arg) call. */ - epicsMutexOsdUnlock(onceMutex); - epicsThreadSleep(epicsThreadSleepQuantum()); - epicsMutexOsdMustLock(onceMutex); - } - } - epicsMutexOsdUnlock(onceMutex); -} - -/* - * Thread private storage implementation based on the vxWorks - * implementation by Andrew Johnson APS/ASD. - */ -epicsThreadPrivateId epicsThreadPrivateCreate () -{ - unsigned int taskVarIndex; - static volatile unsigned int threadVariableCount = 0; - - if (!initialized) epicsThreadInit (); - taskVarLock (); - taskVarIndex = ++threadVariableCount; - taskVarUnlock (); - return (epicsThreadPrivateId)taskVarIndex; -} - -void epicsThreadPrivateDelete (epicsThreadPrivateId id) -{ - /* empty */ -} - -void epicsThreadPrivateSet (epicsThreadPrivateId id, void *pvt) -{ - unsigned int varIndex = (unsigned int)id; - uint32_t note; - struct taskVar *v; - int i; - - rtems_task_get_note (RTEMS_SELF, RTEMS_NOTEPAD_TASKVAR, ¬e); - v = (struct taskVar *)note; - if (varIndex >= v->threadVariableCapacity) { - v->threadVariables = realloc (v->threadVariables, - (varIndex + 1) * sizeof(void *)); - if (v->threadVariables == NULL) - cantProceed("epicsThreadPrivateSet realloc failed\n"); - for (i = v->threadVariableCapacity ; i < varIndex ; i++) - v->threadVariables[i] = NULL; - v->threadVariableCapacity = varIndex + 1; - } - v->threadVariables[varIndex] = pvt; -} - -void * epicsThreadPrivateGet (epicsThreadPrivateId id) -{ - unsigned int varIndex = (unsigned int)id; - uint32_t note; - struct taskVar *v; - - rtems_task_get_note (RTEMS_SELF, RTEMS_NOTEPAD_TASKVAR, ¬e); - v = (struct taskVar *)note; - if (varIndex >= v->threadVariableCapacity) - return NULL; - return v->threadVariables[varIndex]; -} - -/* - * Show task info - */ -struct bitmap { - char *msg; - unsigned long mask; - unsigned long state; -}; - -static void -showBitmap (char *cbuf, unsigned long bits, const struct bitmap *bp) -{ - for ( ; bp->msg != NULL ; bp++) { - if ((bp->mask & bits) == bp->state) { - strcpy (cbuf, bp->msg); - cbuf += strlen (bp->msg); - } - } -} - -static void -showInternalTaskInfo (rtems_id tid) -{ -#ifdef __RTEMS_VIOLATE_KERNEL_VISIBILITY__ - int epicsPri; - Thread_Control *the_thread; - Objects_Locations location; - static Thread_Control thread; - static char bitbuf[120]; - static const struct bitmap taskState[] = { - { "RUN", STATES_ALL_SET, STATES_READY }, - { "DORM", STATES_DORMANT, STATES_DORMANT }, - { "SUSP", STATES_SUSPENDED, STATES_SUSPENDED }, - { "TRANS", STATES_TRANSIENT, STATES_TRANSIENT }, - { "Delay", STATES_DELAYING, STATES_DELAYING }, - { "Wtime", STATES_WAITING_FOR_TIME, STATES_WAITING_FOR_TIME }, - { "Wbuf", STATES_WAITING_FOR_BUFFER, STATES_WAITING_FOR_BUFFER }, - { "Wseg", STATES_WAITING_FOR_SEGMENT, STATES_WAITING_FOR_SEGMENT }, - { "Wmsg" , STATES_WAITING_FOR_MESSAGE, STATES_WAITING_FOR_MESSAGE }, - { "Wevnt", STATES_WAITING_FOR_EVENT, STATES_WAITING_FOR_EVENT }, - { "Wsem", STATES_WAITING_FOR_SEMAPHORE,STATES_WAITING_FOR_SEMAPHORE }, - { "Wmtx", STATES_WAITING_FOR_MUTEX, STATES_WAITING_FOR_MUTEX }, - { "Wjoin", STATES_WAITING_FOR_JOIN_AT_EXIT,STATES_WAITING_FOR_JOIN_AT_EXIT }, - { "Wrpc", STATES_WAITING_FOR_RPC_REPLY,STATES_WAITING_FOR_RPC_REPLY }, - { "Wrate", STATES_WAITING_FOR_PERIOD, STATES_WAITING_FOR_PERIOD }, - { "Wsig", STATES_WAITING_FOR_SIGNAL, STATES_WAITING_FOR_SIGNAL }, - { NULL, 0, 0 }, - }; - - the_thread = _Thread_Get (tid, &location); - if (location != OBJECTS_LOCAL) { - fprintf(epicsGetStdout(),"%-30s", " *** RTEMS task gone! ***"); - return; - } - thread = *the_thread; - _Thread_Enable_dispatch(); - /* - * Show both real and current priorities if they differ. - * Note that the epicsThreadGetOsiPriorityValue routine is not used here. - * If a thread has a priority outside the normal EPICS range then - * that priority should be displayed, not the value truncated to - * the EPICS range. - */ - epicsPri = 199-thread.real_priority; - if (epicsPri < 0) - fprintf(epicsGetStdout()," <0"); - else if (epicsPri > 99) - fprintf(epicsGetStdout()," >99"); - else - fprintf(epicsGetStdout()," %4d", epicsPri); - if (thread.current_priority == thread.real_priority) - fprintf(epicsGetStdout(),"%4d ", (int)thread.current_priority); - else - fprintf(epicsGetStdout(),"%4d/%-3d", (int)thread.real_priority, (int)thread.current_priority); - showBitmap (bitbuf, thread.current_state, taskState); - fprintf(epicsGetStdout(),"%8.8s", bitbuf); - if (thread.current_state & (STATES_WAITING_FOR_SEMAPHORE | - STATES_WAITING_FOR_MUTEX | - STATES_WAITING_FOR_MESSAGE)) - fprintf(epicsGetStdout()," %8.8x", (int)thread.Wait.id); - else - fprintf(epicsGetStdout()," %8.8s", ""); -#endif -} - -static void -epicsThreadShowInfo (struct taskVar *v, unsigned int level) -{ - if (!v) { - fprintf(epicsGetStdout()," PRIORITY\n"); - fprintf(epicsGetStdout()," ID EPICS RTEMS STATE WAIT NAME\n"); - fprintf(epicsGetStdout(),"+--------+-----------+--------+--------+---------------------+\n"); - } else { - fprintf(epicsGetStdout(),"%9.8x", (int)v->id); - showInternalTaskInfo (v->id); - fprintf(epicsGetStdout()," %s\n", v->name); - } -} - -void epicsThreadShow (epicsThreadId id, unsigned int level) -{ - struct taskVar *v; - - if (!id) { - epicsThreadShowInfo (NULL, level); - return; - } - taskVarLock (); - for (v = taskVarHead ; v != NULL ; v = v->forw) { - if ((rtems_id)id == v->id) { - epicsThreadShowInfo (v, level); - taskVarUnlock (); - return; - } - } - taskVarUnlock (); - fprintf(epicsGetStdout(),"*** Thread %x does not exist.\n", (unsigned int)id); -} - -void epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func) -{ - struct taskVar *v; - - taskVarLock (); - /* - * Map tasks in the order of creation (backwards through list) - */ - for (v = taskVarHead ; v != NULL && v->forw != NULL ; v = v->forw) - continue; - while (v) { - func ((epicsThreadId)v->id); - v = v->back; - } - taskVarUnlock (); -} - -void epicsThreadShowAll (unsigned int level) -{ - struct taskVar *v; - - epicsThreadShowInfo (NULL, level); - taskVarLock (); - /* - * Show tasks in the order of creation (backwards through list) - */ - for (v = taskVarHead ; v != NULL && v->forw != NULL ; v = v->forw) - continue; - while (v) { - epicsThreadShowInfo (v, level); - v = v->back; - } - taskVarUnlock (); -} - -double epicsThreadSleepQuantum ( void ) -{ - extern double rtemsTicksPerSecond_double; - - return 1.0 / rtemsTicksPerSecond_double; -} - -epicsShareFunc int epicsThreadGetCPUs(void) -{ -#if defined(RTEMS_SMP) - return rtems_smp_get_number_of_processors(); -#else - return 1; -#endif -} diff --git a/src/libCom/osi/os/RTEMS/osdThread.h b/src/libCom/osi/os/RTEMS/osdThread.h deleted file mode 100644 index 4451f845a..000000000 --- a/src/libCom/osi/os/RTEMS/osdThread.h +++ /dev/null @@ -1,12 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -int epicsThreadGetOssPriorityValue(unsigned int osiPriority); - diff --git a/src/libCom/osi/os/RTEMS/osdThreadExtra.c b/src/libCom/osi/os/RTEMS/osdThreadExtra.c deleted file mode 100644 index 0a7c7ae95..000000000 --- a/src/libCom/osi/os/RTEMS/osdThreadExtra.c +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 ITER Organization -* -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Ralph Lange Date: 26 Jun 2012 */ - -/* Null default thread hooks for all platforms that do not do anything special */ - -#define epicsExportSharedSymbols -#include "epicsThread.h" - -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault; -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain; diff --git a/src/libCom/osi/os/RTEMS/osdTime.cpp b/src/libCom/osi/os/RTEMS/osdTime.cpp deleted file mode 100644 index 4947c568e..000000000 --- a/src/libCom/osi/os/RTEMS/osdTime.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: W. Eric Norum - */ -#define __BSD_VISIBLE 1 -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include "epicsTime.h" -#include "osdTime.h" -#include "osiNTPTime.h" -#include "osiClockTime.h" -#include "generalTimeSup.h" - -extern "C" { - -extern rtems_interval rtemsTicksPerSecond; -int rtems_bsdnet_get_ntp(int, int(*)(), struct timespec *); -static int ntpSocket = -1; - -void osdTimeRegister(void) -{ - /* Init NTP first so it can be used to sync ClockTime */ - NTPTime_Init(100); - ClockTime_Init(CLOCKTIME_SYNC); -} - -int osdNTPGet(struct timespec *ts) -{ - static unsigned bequiet; - ssize_t ret; - - if (ntpSocket < 0) - return -1; - - /* rtems_bsdnet_get_ntp() will send an NTP request, then - * call recvfrom() exactly once to process the expected reply. - * Any leftovers in the socket buffer (ie. duplicates of - * previous replies) will cause problems. - * So flush out the socket buffer first. - */ - do { - char junk[16]; - - ret = recvfrom(ntpSocket, junk, sizeof(junk), MSG_DONTWAIT, NULL, NULL); - if (ret == -1 && errno == EAGAIN) { - break; - } - else if (ret == -1) { - if (!bequiet) { - printf("osdNTPGet cleaner error: %s\n", strerror(errno)); - bequiet = 1; - } - break; - } - else { - bequiet = 0; - } - } while (ret > 0); - - return rtems_bsdnet_get_ntp(ntpSocket, NULL, ts); -} - -void osdNTPInit(void) -{ - struct sockaddr_in myAddr; - - ntpSocket = socket (AF_INET, SOCK_DGRAM, 0); - if (ntpSocket < 0) { - printf("osdNTPInit() Can't create socket: %s\n", strerror (errno)); - return; - } - memset (&myAddr, 0, sizeof myAddr); - myAddr.sin_family = AF_INET; - myAddr.sin_port = htons (0); - myAddr.sin_addr.s_addr = htonl (INADDR_ANY); - if (bind (ntpSocket, (struct sockaddr *)&myAddr, sizeof myAddr) < 0) { - printf("osdNTPInit() Can't bind socket: %s\n", strerror (errno)); - close (ntpSocket); - ntpSocket = -1; - } -} - -void osdNTPReport(void) -{ -} - -int osdTickGet(void) -{ - rtems_interval t; - rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &t); - return t; -} - -int osdTickRateGet(void) -{ - return rtemsTicksPerSecond; -} - -/* - * Use reentrant versions of time access - */ -int epicsTime_gmtime ( const time_t *pAnsiTime, struct tm *pTM ) -{ - struct tm * pRet = gmtime_r ( pAnsiTime, pTM ); - if ( pRet ) { - return epicsTimeOK; - } - else { - return errno; - } -} - -int epicsTime_localtime ( const time_t *clock, struct tm *result ) -{ - struct tm * pRet = localtime_r ( clock, result ); - if ( pRet ) { - return epicsTimeOK; - } - else { - return errno; - } -} - -rtems_interval rtemsTicksPerSecond; -double rtemsTicksPerSecond_double, rtemsTicksPerTwoSeconds_double; - -} // extern "C" - -/* - * Static constructors are run too early in a standalone binary - * to be able to initialize the NTP time provider (the network - * is not available yet), so the RTEMS standalone startup code - * explicitly calls osdTimeRegister() at the appropriate time. - * However if we are loaded dynamically we *do* register our - * standard time providers at static constructor time; in this - * case the network is available already. - */ -static int staticTimeRegister(void) -{ - rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &rtemsTicksPerSecond); - rtemsTicksPerSecond_double = rtemsTicksPerSecond; - rtemsTicksPerTwoSeconds_double = rtemsTicksPerSecond_double * 2.0; - - /* If networking is already up at the time static constructors - * are executed then we are probably run-time loaded and it's - * OK to osdTimeRegister() at this point. - */ - if (rtems_bsdnet_ticks_per_second != 0) - osdTimeRegister(); - - return 1; -} -static int done = staticTimeRegister(); diff --git a/src/libCom/osi/os/RTEMS/osdTime.h b/src/libCom/osi/os/RTEMS/osdTime.h deleted file mode 100644 index 55e3bc2b0..000000000 --- a/src/libCom/osi/os/RTEMS/osdTime.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_osdTime_H -#define INC_osdTime_H - -#ifdef __cplusplus -extern "C" { -#endif - -void osdTimeRegister(void); - -void osdNTPInit(void); -int osdNTPGet(struct timespec *); -void osdNTPReport(void); - -int osdTickRateGet(void); -int osdTickGet(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_osdTime_H */ diff --git a/src/libCom/osi/os/RTEMS/osdVME.h b/src/libCom/osi/os/RTEMS/osdVME.h deleted file mode 100644 index 65548abcb..000000000 --- a/src/libCom/osi/os/RTEMS/osdVME.h +++ /dev/null @@ -1,22 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * OS-dependent VME support - */ -#ifndef __i386__ -#ifndef __mc68000 -#ifndef __arm__ -#include -#endif -#endif -#endif - -void bcopyLongs(char *source, char *destination, int nlongs); diff --git a/src/libCom/osi/os/RTEMS/osiFileName.h b/src/libCom/osi/os/RTEMS/osiFileName.h deleted file mode 100644 index 8c9226898..000000000 --- a/src/libCom/osi/os/RTEMS/osiFileName.h +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osiFileName.h - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/RTEMS/osiUnistd.h b/src/libCom/osi/os/RTEMS/osiUnistd.h deleted file mode 100644 index c0a6e222d..000000000 --- a/src/libCom/osi/os/RTEMS/osiUnistd.h +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -/* - * Some systems fail to provide prototypes of these functions. - * Others provide different prototypes. - * There seems to be no way to handle this automatically, so - * if you get compile errors, just make the appropriate changes here. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -int putenv (char *); -char *strdup (const char *); -char *strtok_r(char*, const char*, char**); - -int snprintf(char *str, size_t size, const char *format, ...); -#include -int vsnprintf(char *str, size_t size, const char *format, va_list ap); - - -#ifdef __cplusplus -} -#endif diff --git a/src/libCom/osi/os/WIN32/epicsAtomicMS.h b/src/libCom/osi/os/WIN32/epicsAtomicMS.h deleted file mode 100644 index 14d2c9bac..000000000 --- a/src/libCom/osi/os/WIN32/epicsAtomicMS.h +++ /dev/null @@ -1,222 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicMS_h -#define epicsAtomicMS_h - -#include "epicsAssert.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef EPICS_ATOMIC_INCR_INTT -#define EPICS_ATOMIC_INCR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget ) -{ - STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( int ) ); - MS_LONG * const pTarg = ( MS_LONG * ) pTarget; - return MS_InterlockedIncrement ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_DECR_INTT -#define EPICS_ATOMIC_DECR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget ) -{ - STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( int ) ); - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - return MS_InterlockedDecrement ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_ADD_INTT -#define EPICS_ATOMIC_ADD_INTT -EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta ) -{ - STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( int ) ); - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - /* we dont use InterlockedAdd because only latest windows is supported */ - return delta + ( int ) MS_InterlockedExchangeAdd ( pTarg, - ( MS_LONG ) delta ); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_INTT -#define EPICS_ATOMIC_CAS_INTT -EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget, - int oldVal, int newVal ) -{ - STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( int ) ); - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - return (int) MS_InterlockedCompareExchange ( pTarg, - (MS_LONG) newVal, (MS_LONG) oldVal ); -} -#endif - -#if ! defined ( MS_ATOMIC_64 ) - -/* - * necessary for next three functions - * - * looking at the MS documentation it appears that they will - * keep type long the same size as an int on 64 bit builds - */ -STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( size_t ) ); - -#ifndef EPICS_ATOMIC_INCR_SIZET -#define EPICS_ATOMIC_INCR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ) -{ - MS_LONG * const pTarg = ( MS_LONG * ) pTarget; - return MS_InterlockedIncrement ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_DECR_SIZET -#define EPICS_ATOMIC_DECR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ) -{ - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - return MS_InterlockedDecrement ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_ADD_SIZET -#define EPICS_ATOMIC_ADD_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, - size_t delta ) -{ - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - /* we dont use InterlockedAdd because only latest windows is supported */ - return delta + ( size_t ) MS_InterlockedExchangeAdd ( pTarg, - ( MS_LONG ) delta ); -} -#endif - -#ifndef EPICS_ATOMIC_SUB_SIZET -#define EPICS_ATOMIC_SUB_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta ) -{ - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - MS_LONG ldelta = (MS_LONG) delta; - /* we dont use InterlockedAdd because only latest windows is supported */ - return ( ( size_t ) MS_InterlockedExchangeAdd ( pTarg, -ldelta ) ) - delta; -} -#endif - -#ifndef EPICS_ATOMIC_CAS_SIZET -#define EPICS_ATOMIC_CAS_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( - size_t * pTarget, - size_t oldVal, size_t newVal ) -{ - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - return (size_t) MS_InterlockedCompareExchange ( pTarg, - (MS_LONG) newVal, (MS_LONG) oldVal ); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_PTRT -#define EPICS_ATOMIC_CAS_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( - EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal ) -{ - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - return (EpicsAtomicPtrT) MS_InterlockedCompareExchange ( pTarg, - (MS_LONG) newVal, (MS_LONG) oldVal ); -} -#endif - -#else /* ! MS_ATOMIC_64 */ - -/* - * necessary for next three functions - */ -STATIC_ASSERT ( sizeof ( MS_LONGLONG ) == sizeof ( size_t ) ); - -#ifndef EPICS_ATOMIC_INCR_SIZET -#define EPICS_ATOMIC_INCR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ) -{ - MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) pTarget; - return ( size_t ) MS_InterlockedIncrement64 ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_DECR_SIZET -#define EPICS_ATOMIC_DECR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ) -{ - MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget ); - return ( size_t ) MS_InterlockedDecrement64 ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_ADD_SIZET -#define EPICS_ATOMIC_ADD_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta ) -{ - MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget ); - /* we dont use InterlockedAdd64 because only latest windows is supported */ - return delta + ( size_t ) MS_InterlockedExchangeAdd64 ( pTarg, - ( MS_LONGLONG ) delta ); -} -#endif - -#ifndef EPICS_ATOMIC_SUB_SIZET -#define EPICS_ATOMIC_SUB_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta ) -{ - MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget ); - MS_LONGLONG ldelta = (MS_LONGLONG) delta; - /* we dont use InterlockedAdd64 because only latest windows is supported */ - return (( size_t ) MS_InterlockedExchangeAdd64 ( pTarg, -ldelta )) - delta; -} -#endif - -#ifndef EPICS_ATOMIC_CAS_SIZET -#define EPICS_ATOMIC_CAS_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget, - size_t oldVal, size_t newVal ) -{ - MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget ); - return (size_t) MS_InterlockedCompareExchange64 ( pTarg, - (MS_LONGLONG) newVal, - (MS_LONGLONG) oldVal ); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_PTRT -#define EPICS_ATOMIC_CAS_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( - EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal ) -{ - MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget ); - return (EpicsAtomicPtrT) MS_InterlockedCompareExchange64 ( pTarg, - (MS_LONGLONG) newVal, (MS_LONGLONG) oldVal ); -} -#endif - -#endif /* ! MS_ATOMIC_64 */ - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#endif /* ifdef epicsAtomicMS_h */ - diff --git a/src/libCom/osi/os/WIN32/epicsAtomicOSD.h b/src/libCom/osi/os/WIN32/epicsAtomicOSD.h deleted file mode 100644 index 2170fceff..000000000 --- a/src/libCom/osi/os/WIN32/epicsAtomicOSD.h +++ /dev/null @@ -1,67 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicOSD_h -#define epicsAtomicOSD_h - -#define EPICS_ATOMIC_OS_NAME "WIN32" - -#ifdef VC_EXTRALEAN -# define VC_EXTRALEAN_DETECTED_epicsAtomicOSD_h -#else -# define VC_EXTRALEAN -#endif - -#ifdef STRICT -# define STRICT_DETECTED_epicsAtomicOSD_h -#else -# define STRICT -#endif - -#include "windows.h" - -#ifndef VC_EXTRALEAN_DETECTED_epicsAtomicOSD_h -# undef VC_EXTRALEAN -#endif - -#ifndef STRICT_DETECTED_epicsAtomicOSD_h -# undef STRICT -#endif - -#if defined ( _WIN64 ) -# define MS_ATOMIC_64 -#endif - -#define MS_LONG LONG -#define MS_InterlockedExchange InterlockedExchange -#define MS_InterlockedCompareExchange InterlockedCompareExchange -#define MS_InterlockedIncrement InterlockedIncrement -#define MS_InterlockedDecrement InterlockedDecrement -#define MS_InterlockedExchange InterlockedExchange -#define MS_InterlockedExchangeAdd InterlockedExchangeAdd -#if defined ( MS_ATOMIC_64 ) -# define MS_LONGLONG LONGLONG -# define MS_InterlockedIncrement64 InterlockedIncrement64 -# define MS_InterlockedDecrement64 InterlockedDecrement64 -# define MS_InterlockedExchange64 InterlockedExchange64 -# define MS_InterlockedExchangeAdd64 InterlockedExchangeAdd64 -# define MS_InterlockedCompareExchange64 InterlockedCompareExchange64 -#endif - -#include "epicsAtomicMS.h" -#include "epicsAtomicDefault.h" - -#endif /* epicsAtomicOSD_h */ - diff --git a/src/libCom/osi/os/WIN32/epicsGetopt.c b/src/libCom/osi/os/WIN32/epicsGetopt.c deleted file mode 100644 index 1ea064ea2..000000000 --- a/src/libCom/osi/os/WIN32/epicsGetopt.c +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef _MINGW - -/* - * Copyright (c) 1987, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include - -#define _getprogname() nargv[0] - -epicsShareDef -int opterr = 1, /* if error message should be printed */ - optind = 1, /* index into parent argv vector */ - optopt; /* character checked for validity */ -int optreset; /* reset getopt */ - -epicsShareDef -char *optarg; /* argument associated with option */ - -#define BADCH (int)'?' -#define BADARG (int)':' -#define EMSG "" - -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int getopt(nargc, nargv, ostr) - int nargc; - char * const *nargv; - const char *ostr; -{ - static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ - - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc || *(place = nargv[optind]) != '-') { - place = EMSG; - return (-1); - } - if (place[1] && *++place == '-') { /* found "--" */ - ++optind; - place = EMSG; - return (-1); - } - } /* option letter okay? */ - if ((optopt = (int)*place++) == (int)':' || - !(oli = strchr(ostr, optopt))) { - /* - * if the user didn't specify '-' as an option, - * assume it means -1. - */ - if (optopt == (int)'-') - return (-1); - if (!*place) - ++optind; - if (opterr && *ostr != ':' && optopt != BADCH) - (void)fprintf(stderr, "%s: illegal option -- %c\n", - _getprogname(), optopt); - return (BADCH); - } - if (*++oli != ':') { /* don't need argument */ - optarg = NULL; - if (!*place) - ++optind; - } - else { /* need an argument */ - if (*place) /* no white space */ - optarg = place; - else if (nargc <= ++optind) { /* no arg */ - place = EMSG; - if (*ostr == ':') - return (BADARG); - if (opterr) - (void)fprintf(stderr, - "%s: option requires an argument -- %c\n", - _getprogname(), optopt); - return (BADCH); - } - else /* white space */ - optarg = nargv[optind]; - place = EMSG; - ++optind; - } - return (optopt); /* dump back option letter */ -} - -#endif /* !_MINGW */ diff --git a/src/libCom/osi/os/WIN32/epicsGetopt.h b/src/libCom/osi/os/WIN32/epicsGetopt.h deleted file mode 100644 index f92041085..000000000 --- a/src/libCom/osi/os/WIN32/epicsGetopt.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer -* Synchrotronstrahlung. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef _EPICS_GETOPT_H -#define _EPICS_GETOPT_H - -#ifdef _MINGW - -#include - -#else /* _MINGW */ - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int getopt(int argc, char * const argv[], const char *optstring); - -epicsShareExtern char *optarg; - -epicsShareExtern int optind, opterr, optopt; - -#ifdef __cplusplus -} -#endif - -#endif /* _MINGW */ - -#endif /* _EPICS_GETOPT_H */ diff --git a/src/libCom/osi/os/WIN32/epicsMath.h b/src/libCom/osi/os/WIN32/epicsMath.h deleted file mode 100644 index 33eb9dddd..000000000 --- a/src/libCom/osi/os/WIN32/epicsMath.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsMathh -#define epicsMathh - -#include -#include -#include - -#ifndef finite -#define finite(D) _finite(D) -#endif - -#ifndef isnan -#define isnan(D) _isnan(D) -#endif - -#ifndef isinf -#define isinf(D) ( !_finite(D) && !_isnan(D) ) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* epicsMathh */ diff --git a/src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp b/src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp deleted file mode 100644 index 3db87ac84..000000000 --- a/src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "epicsStdio.h" - -/* - * epicsSocketConvertErrorToString () - */ -void epicsSocketConvertErrorToString ( - char * pBuf, unsigned bufSize, int theSockError ) -{ - if ( bufSize ) { - /* - * this does not work on systems prior to W2K - */ - DWORD success = FormatMessage ( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, - NULL, theSockError, - MAKELANGID ( LANG_NEUTRAL, SUBLANG_DEFAULT ), /* Default language */ - pBuf, bufSize, NULL ); - if ( ! success ) { - int status = epicsSnprintf ( - pBuf, bufSize, "WINSOCK Error %d", theSockError ); - if ( status <= 0 ) { - strncpy ( pBuf, "WINSOCK Error", bufSize ); - pBuf [bufSize - 0] = '\0'; - } - } - } -} - -/* - * epicsSocketConvertErrnoToString () - */ -void epicsSocketConvertErrnoToString ( - char * pBuf, unsigned bufSize ) -{ - epicsSocketConvertErrorToString ( pBuf, bufSize, SOCKERRNO ); -} diff --git a/src/libCom/osi/os/WIN32/epicsTempFile.cpp b/src/libCom/osi/os/WIN32/epicsTempFile.cpp deleted file mode 100644 index 11b835134..000000000 --- a/src/libCom/osi/os/WIN32/epicsTempFile.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsTempFile.h" - -// -// epicsTempName -// -// allow the teporary file directory to be set with the -// TMP environment varianble -// -extern "C" -epicsShareFunc void epicsShareAPI epicsTempName ( - char * pNameBuf, size_t nameBufLength ) -{ - if ( nameBufLength ) { - pNameBuf[0] = '\0'; - char * pName = _tempnam ( "c:\\tmp", "epics" ); - if ( pName ) { - if ( nameBufLength > strlen ( pName ) ) { - strncpy ( pNameBuf, pName, nameBufLength ); - } - free ( pName ); - } - } -} - -// -// epicsTmpFile -// -// allow the teporary file directory to be set with the -// TMP environment varianble -// -extern "C" -epicsShareFunc FILE * epicsShareAPI epicsTempFile () -{ - char * pName = _tempnam ( "c:\\tmp", "epics" ); - if( ! pName ) { - return 0; - } - // We use open followed by fdopen so that the _O_EXCL - // flag can be used. This causes detection of a race - // condition where two programs end up receiving the - // same temporary file name. - // - // _O_CREAT create if non-existant - // _O_EXCL file must not exist - // _O_RDWR read and write the file - // _O_TEMPORARY delete file on close - // _O_BINARY no translation - // _O_SHORT_LIVED avoid flush to disk - // - const int openFlag = _O_CREAT | _O_EXCL | _O_RDWR | - _O_SHORT_LIVED | _O_BINARY | _O_TEMPORARY; - int fd = open ( pName, openFlag, _S_IWRITE ); - FILE * pNewFile = 0; - if ( fd >=0 ) { - pNewFile = _fdopen ( fd, "w+b" ); - } - else { - printf ( - "Temporary file \"%s\" open failed because " - "\"%s\"\n", pName, strerror ( errno ) ); - } - free ( pName ); - return pNewFile; -} - diff --git a/src/libCom/osi/os/WIN32/forceBadAllocException.cpp b/src/libCom/osi/os/WIN32/forceBadAllocException.cpp deleted file mode 100644 index 985ec988e..000000000 --- a/src/libCom/osi/os/WIN32/forceBadAllocException.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// On older version of ms visual c++ operator new -// does not throw a bad_alloc exception -// when it fails. It simply returns a null pointer. -// This behavior is not in conformance with the -// ANSI / ISO C++. -// -#if _MSC_VER > 1000 && _MSC_VER < 1400 - -#include -#include - -// instruct loader to call this gllobal object -// constructor before user global object constructors -#pragma warning (disable: 4073) -#pragma init_seg(lib) -#pragma warning (default: 4073) - -static int my_new_handler (size_t size) -{ - throw std::bad_alloc(); - return 0; -} - -class my_new_handler_obj -{ -public: - my_new_handler_obj() - { - //_old_new_mode = _set_new_mode(1); // cause malloc to throw like new - _old_new_handler = _set_new_handler(my_new_handler); - } - - ~my_new_handler_obj() - { - _set_new_handler(_old_new_handler); - //_set_new_mode(_old_new_mode); - } - -private: - _PNH _old_new_handler; - //int _old_new_mode; -}; - -static my_new_handler_obj _g_new_handler_obj; - -#endif diff --git a/src/libCom/osi/os/WIN32/osdBackTrace.cpp b/src/libCom/osi/os/WIN32/osdBackTrace.cpp deleted file mode 100644 index 8f5896a37..000000000 --- a/src/libCom/osi/os/WIN32/osdBackTrace.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2014 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsStackTracePvt.h" - -int epicsBackTrace(void **buf, int buf_sz) -{ -#ifdef CaptureStackBackTrace - /* Docs say that (for some windows versions) the sum of - * skipped + captured frames must be less than 63 - */ - if ( buf_sz >= 63 ) - buf_sz = 62; - return CaptureStackBackTrace(0, buf_sz, buf, 0); -#else - /* Older versions of MinGW */ - return -1; -#endif -} diff --git a/src/libCom/osi/os/WIN32/osdEvent.c b/src/libCom/osi/os/WIN32/osdEvent.c deleted file mode 100644 index 314138b27..000000000 --- a/src/libCom/osi/os/WIN32/osdEvent.c +++ /dev/null @@ -1,145 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdEvent.c */ -/* - * WIN32 version - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - * - */ - -#include - -#define VC_EXTRALEAN -#define STRICT -#include - -#define epicsExportSharedSymbols -#include "shareLib.h" -#include "epicsEvent.h" - -typedef struct epicsEventOSD { - HANDLE handle; -} epicsEventOSD; - -/* - * epicsEventCreate () - */ -epicsShareFunc epicsEventId epicsEventCreate ( - epicsEventInitialState initialState ) -{ - epicsEventOSD *pSem; - - pSem = malloc ( sizeof ( *pSem ) ); - if ( pSem ) { - pSem->handle = CreateEvent ( NULL, FALSE, initialState?TRUE:FALSE, NULL ); - if ( pSem->handle == 0 ) { - free ( pSem ); - pSem = 0; - } - } - - return pSem; -} - -/* - * epicsEventDestroy () - */ -epicsShareFunc void epicsEventDestroy ( epicsEventId pSem ) -{ - CloseHandle ( pSem->handle ); - free ( pSem ); -} - -/* - * epicsEventTrigger () - */ -epicsShareFunc epicsEventStatus epicsEventTrigger ( epicsEventId pSem ) -{ - BOOL status; - status = SetEvent ( pSem->handle ); - return status ? epicsEventOK : epicsEventError; -} - -/* - * epicsEventWait () - */ -epicsShareFunc epicsEventStatus epicsEventWait ( epicsEventId pSem ) -{ - DWORD status; - status = WaitForSingleObject (pSem->handle, INFINITE); - if ( status == WAIT_OBJECT_0 ) { - return epicsEventOK; - } - else { - return epicsEventError; - } -} - -/* - * epicsEventWaitWithTimeout () - */ -epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout ( - epicsEventId pSem, double timeOut ) -{ - static const unsigned mSecPerSec = 1000; - DWORD status; - DWORD tmo; - - if ( timeOut <= 0.0 ) { - tmo = 0u; - } - else if ( timeOut >= INFINITE / mSecPerSec ) { - tmo = INFINITE - 1; - } - else { - tmo = ( DWORD ) ( ( timeOut * mSecPerSec ) + 0.5 ); - if ( tmo == 0 ) { - tmo = 1; - } - } - status = WaitForSingleObject ( pSem->handle, tmo ); - if ( status == WAIT_OBJECT_0 ) { - return epicsEventOK; - } - else if ( status == WAIT_TIMEOUT ) { - return epicsEventWaitTimeout; - } - else { - return epicsEventError; - } -} - -/* - * epicsEventTryWait () - */ -epicsShareFunc epicsEventStatus epicsEventTryWait ( epicsEventId pSem ) -{ - DWORD status; - - status = WaitForSingleObject ( pSem->handle, 0 ); - if ( status == WAIT_OBJECT_0 ) { - return epicsEventOK; - } - else if ( status == WAIT_TIMEOUT ) { - return epicsEventWaitTimeout; - } - else { - return epicsEventError; - } -} - -/* - * epicsEventShow () - */ -epicsShareFunc void epicsEventShow ( epicsEventId id, unsigned level ) -{ -} diff --git a/src/libCom/osi/os/WIN32/osdEvent.h b/src/libCom/osi/os/WIN32/osdEvent.h deleted file mode 100644 index f57f2cc49..000000000 --- a/src/libCom/osi/os/WIN32/osdEvent.h +++ /dev/null @@ -1,19 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdEvent.c */ -/* - * WIN32 version - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -/* osdEvent.h not needed */ diff --git a/src/libCom/osi/os/WIN32/osdFindSymbol.c b/src/libCom/osi/os/WIN32/osdFindSymbol.c deleted file mode 100644 index 6de3c428e..000000000 --- a/src/libCom/osi/os/WIN32/osdFindSymbol.c +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 Dirk Zimoch, PSI -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/WIN32/osdFindSymbol.c */ - - -#include - -#define epicsExportSharedSymbols -#include "epicsFindSymbol.h" - -static int epicsLoadErrorCode = 0; - -epicsShareFunc void * epicsLoadLibrary(const char *name) -{ - HMODULE lib; - - epicsLoadErrorCode = 0; - lib = LoadLibrary(name); - if (lib == NULL) - { - epicsLoadErrorCode = GetLastError(); - } - return lib; -} - -epicsShareFunc const char *epicsLoadError(void) -{ - static char buffer[100]; - - FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - epicsLoadErrorCode, - 0, - buffer, - sizeof(buffer)-1, NULL ); - return buffer; -} - -epicsShareFunc void * epicsShareAPI epicsFindSymbol(const char *name) -{ - return GetProcAddress(0, name); -} diff --git a/src/libCom/osi/os/WIN32/osdMutex.c b/src/libCom/osi/os/WIN32/osdMutex.c deleted file mode 100644 index 63a51efd5..000000000 --- a/src/libCom/osi/os/WIN32/osdMutex.c +++ /dev/null @@ -1,179 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdMutex.c */ -/* - * WIN32 version - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - * - */ - -#include -#include - -#define VC_EXTRALEAN -#define STRICT -/* - * Defining this allows the *much* faster critical - * section mutex primitive to be used. Unfortunately, - * using certain of these functions drops support for W95\W98\WME - * unless we specify "delay loading" when we link with the - * DLL so that DLL entry points are not resolved until they - * are used. The code does have run time switches so - * that the more advanced calls are not called unless - * they are available in the windows OS, but this feature - * isnt going to be very useful unless we specify "delay - * loading" when we link with the DLL. - * - * It appears that the only entry point used here that causes - * portability problems with W95\W98\WME is TryEnterCriticalSection. - */ -#ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0400 -#endif -#include - -#define epicsExportSharedSymbols -#include "shareLib.h" -#include "epicsMutex.h" -#include "epicsAssert.h" -#include "epicsStdio.h" - -typedef struct epicsMutexOSD { - union { - HANDLE mutex; - CRITICAL_SECTION criticalSection; - } os; -} epicsMutexOSD; - -static BOOL thisIsNT = FALSE; -static LONG weHaveInitialized = 0; - -/* - * epicsMutexCreate () - */ -epicsMutexOSD * epicsMutexOsdCreate ( void ) -{ - epicsMutexOSD * pSem; - - if ( ! weHaveInitialized ) { - BOOL status; - OSVERSIONINFO osInfo; - osInfo.dwOSVersionInfoSize = sizeof ( OSVERSIONINFO ); - status = GetVersionEx ( & osInfo ); - thisIsNT = status && ( osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ); - weHaveInitialized = 1; - } - - pSem = malloc ( sizeof (*pSem) ); - if ( pSem ) { - if ( thisIsNT ) { - InitializeCriticalSection ( &pSem->os.criticalSection ); - } - else { - pSem->os.mutex = CreateMutex ( NULL, FALSE, NULL ); - if ( pSem->os.mutex == 0 ) { - free ( pSem ); - pSem = 0; - } - } - } - return pSem; -} - -/* - * epicsMutexOsdDestroy () - */ -void epicsMutexOsdDestroy ( epicsMutexOSD * pSem ) -{ - if ( thisIsNT ) { - DeleteCriticalSection ( &pSem->os.criticalSection ); - } - else { - CloseHandle ( pSem->os.mutex ); - } - free ( pSem ); -} - -/* - * epicsMutexOsdUnlock () - */ -void epicsMutexOsdUnlock ( epicsMutexOSD * pSem ) -{ - if ( thisIsNT ) { - LeaveCriticalSection ( &pSem->os.criticalSection ); - } - else { - BOOL success = ReleaseMutex ( pSem->os.mutex ); - assert ( success ); - } -} - -/* - * epicsMutexOsdLock () - */ -epicsMutexLockStatus epicsMutexOsdLock ( epicsMutexOSD * pSem ) -{ - if ( thisIsNT ) { - EnterCriticalSection ( &pSem->os.criticalSection ); - } - else { - DWORD status = WaitForSingleObject ( pSem->os.mutex, INFINITE ); - if ( status != WAIT_OBJECT_0 ) { - return epicsMutexLockError; - } - } - return epicsMutexLockOK; -} - -/* - * epicsMutexOsdTryLock () - */ -epicsMutexLockStatus epicsMutexOsdTryLock ( epicsMutexOSD * pSem ) -{ - if ( thisIsNT ) { - if ( TryEnterCriticalSection ( &pSem->os.criticalSection ) ) { - return epicsMutexLockOK; - } - else { - return epicsMutexLockTimeout; - } - } - else { - DWORD status = WaitForSingleObject ( pSem->os.mutex, 0 ); - if ( status != WAIT_OBJECT_0 ) { - if (status == WAIT_TIMEOUT) { - return epicsMutexLockTimeout; - } - else { - return epicsMutexLockError; - } - } - } - return epicsMutexLockOK; -} - -/* - * epicsMutexOsdShow () - */ -void epicsMutexOsdShow ( epicsMutexOSD * pSem, unsigned level ) -{ - if ( thisIsNT ) { - printf ("epicsMutex: win32 critical section at %p\n", - (void * ) & pSem->os.criticalSection ); - } - else { - printf ( "epicsMutex: win32 mutex at %p\n", - ( void * ) pSem->os.mutex ); - } -} - diff --git a/src/libCom/osi/os/WIN32/osdMutex.h b/src/libCom/osi/os/WIN32/osdMutex.h deleted file mode 100644 index d8f3f78bd..000000000 --- a/src/libCom/osi/os/WIN32/osdMutex.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* osdMutex.h */ -/* - * WIN32 version - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef osdMutexh -#define osdMutexh - -#endif /* osdMutexh */ diff --git a/src/libCom/osi/os/WIN32/osdNetIntf.c b/src/libCom/osi/os/WIN32/osdNetIntf.c deleted file mode 100644 index db445d494..000000000 --- a/src/libCom/osi/os/WIN32/osdNetIntf.c +++ /dev/null @@ -1,253 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * WIN32 specific initialisation for bsd sockets, - * based on Chris Timossi's base/src/ca/windows_depend.c, - * and also further additions by Kay Kasemir when this was in - * dllmain.cc - * - * 7-1-97 -joh- - * - */ - -/* - * ANSI C - */ -#include -#include - -/* - * WIN32 specific - */ -#define VC_EXTRALEAN -#define STRICT -#include -#include - -/* - * EPICS - */ -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" -#include "epicsThread.h" -#include "epicsVersion.h" - -static osiSockAddr osiLocalAddrResult; -static epicsThreadOnceId osiLocalAddrId = EPICS_THREAD_ONCE_INIT; - -/* - * osiLocalAddr () - */ -static void osiLocalAddrOnce ( void *raw ) -{ - SOCKET *psocket = raw; - osiSockAddr addr; - int status; - INTERFACE_INFO *pIfinfo; - INTERFACE_INFO *pIfinfoList = NULL; - unsigned nelem; - DWORD numifs; - DWORD cbBytesReturned; - - memset ( (void *) &addr, '\0', sizeof ( addr ) ); - addr.sa.sa_family = AF_UNSPEC; - - /* only valid for winsock 2 and above */ - if ( wsaMajorVersion() < 2 ) { - goto fail; - } - - nelem = 100; - pIfinfoList = (INTERFACE_INFO *) calloc ( nelem, sizeof (INTERFACE_INFO) ); - if (!pIfinfoList) { - errlogPrintf ("calloc failed\n"); - goto fail; - } - - status = WSAIoctl (*psocket, SIO_GET_INTERFACE_LIST, NULL, 0, - (LPVOID)pIfinfoList, nelem*sizeof(INTERFACE_INFO), - &cbBytesReturned, NULL, NULL); - - if (status != 0 || cbBytesReturned == 0) { - errlogPrintf ("WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError()); - goto fail; - } - - numifs = cbBytesReturned / sizeof(INTERFACE_INFO); - for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++){ - - /* - * dont use interfaces that have been disabled - */ - if (!(pIfinfo->iiFlags & IFF_UP)) { - continue; - } - - /* - * dont use the loop back interface - */ - if (pIfinfo->iiFlags & IFF_LOOPBACK) { - continue; - } - - addr.sa = pIfinfo->iiAddress.Address; - - /* Work around MS Winsock2 bugs */ - if (addr.sa.sa_family == 0) { - addr.sa.sa_family = AF_INET; - } - - osiLocalAddrResult = addr; - free ( pIfinfoList ); - return; - } - - errlogPrintf ( - "osiLocalAddr(): only loopback found\n"); -fail: - /* fallback to loopback */ - memset ( (void *) &addr, '\0', sizeof ( addr ) ); - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - osiLocalAddrResult = addr; - - free ( pIfinfoList ); -} - -epicsShareFunc osiSockAddr epicsShareAPI osiLocalAddr (SOCKET socket) -{ - epicsThreadOnce(&osiLocalAddrId, osiLocalAddrOnce, (void*)&socket); - return osiLocalAddrResult; -} - -/* - * osiSockDiscoverBroadcastAddresses () - */ -epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses - (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr) -{ - int status; - INTERFACE_INFO *pIfinfo; - INTERFACE_INFO *pIfinfoList; - unsigned nelem; - int numifs; - DWORD cbBytesReturned; - osiSockAddrNode *pNewNode; - - if ( pMatchAddr->sa.sa_family == AF_INET ) { - if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) { - pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) ); - if ( pNewNode == NULL ) { - return; - } - pNewNode->addr.ia.sin_family = AF_INET; - pNewNode->addr.ia.sin_port = htons ( 0 ); - pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - ellAdd ( pList, &pNewNode->node ); - return; - } - } - - /* only valid for winsock 2 and above */ - if (wsaMajorVersion() < 2 ) { - fprintf(stderr, "Need to set EPICS_CA_AUTO_ADDR_LIST=NO for winsock 1\n"); - return; - } - - nelem = 100; - pIfinfoList = (INTERFACE_INFO *) calloc(nelem, sizeof(INTERFACE_INFO)); - if(!pIfinfoList){ - return; - } - - status = WSAIoctl (socket, SIO_GET_INTERFACE_LIST, - NULL, 0, - (LPVOID)pIfinfoList, nelem*sizeof(INTERFACE_INFO), - &cbBytesReturned, NULL, NULL); - - if (status != 0 || cbBytesReturned == 0) { - fprintf(stderr, "WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError()); - free(pIfinfoList); - return; - } - - numifs = cbBytesReturned/sizeof(INTERFACE_INFO); - for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++){ - - /* - * dont bother with interfaces that have been disabled - */ - if (!(pIfinfo->iiFlags & IFF_UP)) { - continue; - } - - if (pIfinfo->iiFlags & IFF_LOOPBACK) { - continue; - } - - /* - * work around WS2 bug - */ - if (pIfinfo->iiAddress.Address.sa_family != AF_INET) { - if (pIfinfo->iiAddress.Address.sa_family == 0) { - pIfinfo->iiAddress.Address.sa_family = AF_INET; - } - } - - /* - * if it isnt a wildcarded interface then look for - * an exact match - */ - if (pMatchAddr->sa.sa_family != AF_UNSPEC) { - if (pIfinfo->iiAddress.Address.sa_family != pMatchAddr->sa.sa_family) { - continue; - } - if (pIfinfo->iiAddress.Address.sa_family != AF_INET) { - continue; - } - if (pMatchAddr->sa.sa_family != AF_INET) { - continue; - } - if (pMatchAddr->ia.sin_addr.s_addr != htonl(INADDR_ANY)) { - if (pIfinfo->iiAddress.AddressIn.sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr) { - continue; - } - } - } - - pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode)); - if (pNewNode==NULL) { - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n"); - return; - } - - if (pIfinfo->iiAddress.Address.sa_family == AF_INET && - pIfinfo->iiFlags & IFF_BROADCAST) { - const unsigned mask = pIfinfo->iiNetmask.AddressIn.sin_addr.s_addr; - const unsigned bcast = pIfinfo->iiBroadcastAddress.AddressIn.sin_addr.s_addr; - const unsigned addr = pIfinfo->iiAddress.AddressIn.sin_addr.s_addr; - unsigned result = (addr & mask) | (bcast &~mask); - pNewNode->addr.ia.sin_family = AF_INET; - pNewNode->addr.ia.sin_addr.s_addr = result; - pNewNode->addr.ia.sin_port = htons ( 0 ); - } - else { - pNewNode->addr.sa = pIfinfo->iiBroadcastAddress.Address; - } - - /* - * LOCK applied externally - */ - ellAdd (pList, &pNewNode->node); - } - - free (pIfinfoList); -} diff --git a/src/libCom/osi/os/WIN32/osdPoolStatus.c b/src/libCom/osi/os/WIN32/osdPoolStatus.c deleted file mode 100644 index bb764b2ad..000000000 --- a/src/libCom/osi/os/WIN32/osdPoolStatus.c +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "osiPoolStatus.h" - -/* - * osiSufficentSpaceInPool () - * - * @@@@@ not implemented @@@@@ - * - */ -epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize ) -{ - return 1; -} diff --git a/src/libCom/osi/os/WIN32/osdPoolStatus.h b/src/libCom/osi/os/WIN32/osdPoolStatus.h deleted file mode 100644 index 178434b11..000000000 --- a/src/libCom/osi/os/WIN32/osdPoolStatus.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifdef osdPoolStatush -#define osdPoolStatush - -#endif /* osdPoolStatush */ diff --git a/src/libCom/osi/os/WIN32/osdProcess.c b/src/libCom/osi/os/WIN32/osdProcess.c deleted file mode 100644 index 6e69c0485..000000000 --- a/src/libCom/osi/os/WIN32/osdProcess.c +++ /dev/null @@ -1,137 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Operating System Dependent Implementation of osiProcess.h - * - * Author: Jeff Hill - * - */ - -#ifndef _WIN32 -#error This source is specific to WIN32 -#endif - -#include - -#define STRICT -#include - -#define epicsExportSharedSymbols -#include "osiProcess.h" -#include "errlog.h" - -epicsShareFunc osiGetUserNameReturn epicsShareAPI osiGetUserName (char *pBuf, unsigned bufSizeIn) -{ - DWORD bufsize; - - if ( bufSizeIn > 0xffffffff ) { - return osiGetUserNameFail; - } - - bufsize = (DWORD) bufSizeIn; - - if ( ! GetUserName (pBuf, &bufsize) ) { - return osiGetUserNameFail; - } - - if ( *pBuf == '\0' ) { - return osiGetUserNameFail; - } - - return osiGetUserNameSuccess; -} - -epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProcess - ( const char *pProcessName, const char *pBaseExecutableName ) -{ - BOOL status; - STARTUPINFO startupInfo; - PROCESS_INFORMATION processInfo; - - GetStartupInfo ( &startupInfo ); - startupInfo.lpReserved = NULL; - startupInfo.lpTitle = (char *) pProcessName; - startupInfo.dwFlags = STARTF_USESHOWWINDOW; - startupInfo.wShowWindow = SW_SHOWMINNOACTIVE; - - status = CreateProcess ( - NULL, /* pointer to name of executable module (not required if command line is specified) */ - (char *) pBaseExecutableName, /* pointer to command line string */ - NULL, /* pointer to process security attributes */ - NULL, /* pointer to thread security attributes */ - FALSE, /* handle inheritance flag */ - CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, /* creation flags */ - NULL, /* pointer to new environment block (defaults to caller's environement) */ - NULL, /* pointer to current directory name (defaults to caller's current directory) */ - &startupInfo, /* pointer to STARTUPINFO */ - &processInfo /* pointer to PROCESS_INFORMATION */ - ); - if ( status == 0 ) { - DWORD W32status; - LPVOID errStrMsgBuf; - LPVOID complteMsgBuf; - - W32status = FormatMessage ( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError (), - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ - (LPTSTR) &errStrMsgBuf, - 0, - NULL - ); - - if ( W32status ) { - char *pFmtArgs[6]; - pFmtArgs[0] = "Failed to start executable -"; - pFmtArgs[1] = (char *) pBaseExecutableName; - pFmtArgs[2] = errStrMsgBuf; - pFmtArgs[3] = "Changes may be required in your \"path\" environment variable."; - pFmtArgs[4] = "PATH = "; - pFmtArgs[5] = getenv ("path"); - if ( pFmtArgs[5] == NULL ) { - pFmtArgs[5] = ""; - } - - W32status = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | - FORMAT_MESSAGE_ARGUMENT_ARRAY | 80, - "%1 \"%2\". %3 %4 %5 \"%6\"", - 0, - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ - (LPTSTR) &complteMsgBuf, - 0, - pFmtArgs - ); - if (W32status) { - /* Display the string. */ - MessageBox (NULL, complteMsgBuf, "Configuration Problem", - MB_OK | MB_ICONINFORMATION); - LocalFree (complteMsgBuf); - } - else { - /* Display the string. */ - MessageBox (NULL, errStrMsgBuf, "Failed to start executable", - MB_OK | MB_ICONINFORMATION); - } - - /* Free the buffer. */ - LocalFree (errStrMsgBuf); - } - else { - errlogPrintf ("!!WARNING!!\n"); - errlogPrintf ("Unable to locate executable \"%s\".\n", pBaseExecutableName); - errlogPrintf ("You may need to modify your \"path\" environment variable.\n"); - } - return osiSpawnDetachedProcessFail; - } - - return osiSpawnDetachedProcessSuccess; -} diff --git a/src/libCom/osi/os/WIN32/osdSignal.cpp b/src/libCom/osi/os/WIN32/osdSignal.cpp deleted file mode 100644 index 5f799273a..000000000 --- a/src/libCom/osi/os/WIN32/osdSignal.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2002 The University of Chicago, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE Versions 3.13.7 - * and higher are distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "epicsSignal.h" - -/* - * NOOP - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm ( struct epicsThreadOSD * /* threadid */ ) {} - diff --git a/src/libCom/osi/os/WIN32/osdSock.c b/src/libCom/osi/os/WIN32/osdSock.c deleted file mode 100644 index b8c8363fb..000000000 --- a/src/libCom/osi/os/WIN32/osdSock.c +++ /dev/null @@ -1,190 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * WIN32 specific initialisation for bsd sockets, - * based on Chris Timossi's base/src/ca/windows_depend.c, - * and also further additions by Kay Kasemir when this was in - * dllmain.cc - * - * 7-1-97 -joh- - * - */ - -/* - * ANSI C - */ -#include -#include - -/* - * WIN32 specific - */ -#define VC_EXTRALEAN -#define STRICT -#include - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" -#include "epicsVersion.h" - -static unsigned nAttached = 0; -static WSADATA WsaData; /* version of winsock */ - -epicsShareFunc unsigned epicsShareAPI wsaMajorVersion () -{ - return (unsigned) LOBYTE( WsaData.wVersion ); -} - -/* - * osiSockAttach() - */ -epicsShareFunc int epicsShareAPI osiSockAttach() -{ - int status; - - if (nAttached) { - nAttached++; - return TRUE; - } - -#if _DEBUG - /* for gui applications, setup console for error messages */ - if (AllocConsole()) - { - char title[256]; - DWORD titleLength = GetConsoleTitle(title, sizeof(title)); - if (titleLength) { - titleLength = strlen (title); - strncat (title, " " EPICS_VERSION_STRING, sizeof(title)); - } - else { - strncpy(title, EPICS_VERSION_STRING, sizeof(title)); - } - title[sizeof(title)-1]= '\0'; - SetConsoleTitle(title); - freopen( "CONOUT$", "a", stderr ); - } -#endif - - /* - * attach to win sock - */ - status = WSAStartup(MAKEWORD(/*major*/2,/*minor*/2), &WsaData); - if (status != 0) { - fprintf(stderr, - "Unable to attach to windows sockets version 2. error=%d\n", status); - fprintf(stderr, - "A Windows Sockets II update for windows 95 is available at\n"); - fprintf(stderr, - "http://www.microsoft.com/windows95/info/ws2.htm"); - return FALSE; - } - -# if defined ( _DEBUG ) && 0 - fprintf(stderr, "EPICS attached to winsock version %s\n", WsaData.szDescription); -# endif - - nAttached = 1u; - - return TRUE; -} - -/* - * osiSockRelease() - */ -epicsShareFunc void epicsShareAPI osiSockRelease() -{ - if (nAttached) { - if (--nAttached==0u) { - WSACleanup(); -# if defined ( _DEBUG ) && 0 - fprintf(stderr, "EPICS released winsock version %s\n", WsaData.szDescription); -# endif - memset (&WsaData, '\0', sizeof(WsaData)); - } - } -} - -epicsShareFunc SOCKET epicsShareAPI epicsSocketCreate ( - int domain, int type, int protocol ) -{ - return socket ( domain, type, protocol ); -} - -epicsShareFunc int epicsShareAPI epicsSocketAccept ( - int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ) -{ - return accept ( sock, pAddr, addrlen ); -} - -epicsShareFunc void epicsShareAPI epicsSocketDestroy ( SOCKET s ) -{ - int status = closesocket ( s ); - if ( status < 0 ) { - char buf [ 64 ]; - epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) ); - errlogPrintf ( - "epicsSocketDestroy: failed to " - "close a socket because \"%s\"\n", buf ); - } -} - -/* - * ipAddrToHostName - */ -epicsShareFunc unsigned epicsShareAPI ipAddrToHostName - (const struct in_addr *pAddr, char *pBuf, unsigned bufSize) -{ - struct hostent *ent; - - if (bufSize<1) { - return 0; - } - - ent = gethostbyaddr((char *) pAddr, sizeof (*pAddr), AF_INET); - if (ent) { - strncpy (pBuf, ent->h_name, bufSize); - pBuf[bufSize-1] = '\0'; - return strlen (pBuf); - } - return 0; -} - -/* - * hostToIPAddr () - */ -epicsShareFunc int epicsShareAPI hostToIPAddr - (const char *pHostName, struct in_addr *pIPA) -{ - struct hostent *phe; - - phe = gethostbyname (pHostName); - if (phe && phe->h_addr_list[0]) { - if (phe->h_addrtype==AF_INET && phe->h_length<=sizeof(struct in_addr)) { - struct in_addr *pInAddrIn = (struct in_addr *) phe->h_addr_list[0]; - - *pIPA = *pInAddrIn; - - /* - * success - */ - return 0; - } - } - - /* - * return indicating an error - */ - return -1; -} - - diff --git a/src/libCom/osi/os/WIN32/osdSock.h b/src/libCom/osi/os/WIN32/osdSock.h deleted file mode 100644 index d92e18755..000000000 --- a/src/libCom/osi/os/WIN32/osdSock.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef osdSockH -#define osdSockH - -#include -#include - -/* - * winsock2.h changes the structure alignment to 4 if - * WIN32 isnt set which can be a source of confusion - */ -#ifndef WIN32 -# define WIN32 -#endif -#include -#include - -#define SOCKERRNO WSAGetLastError() - -#define socket_ioctl(A,B,C) ioctlsocket(A,B,C) -typedef u_long FAR osiSockIoctl_t; -typedef int osiSocklen_t; - -#ifndef SHUT_RD -# define SHUT_RD SD_RECEIVE -#endif - -#ifndef SHUT_WR -# define SHUT_WR SD_SEND -#endif - -#ifndef SHUT_RDWR -# define SHUT_RDWR SD_BOTH -#endif - -#define MAXHOSTNAMELEN 75 -#define IPPORT_USERRESERVED 5000U - -#define SOCK_EWOULDBLOCK WSAEWOULDBLOCK -#define SOCK_ENOBUFS WSAENOBUFS -#define SOCK_ECONNRESET WSAECONNRESET -#define SOCK_ETIMEDOUT WSAETIMEDOUT -#define SOCK_EACCES WSAEACCES -#define SOCK_EADDRINUSE WSAEADDRINUSE -#define SOCK_EADDRNOTAVAIL WSAEADDRNOTAVAIL -#define SOCK_ECONNREFUSED WSAECONNREFUSED -#define SOCK_ECONNABORTED WSAECONNABORTED -#define SOCK_EINPROGRESS WSAEINPROGRESS -#define SOCK_EISCONN WSAEISCONN -#define SOCK_EALREADY WSAEALREADY -#define SOCK_EINVAL WSAEINVAL -#define SOCK_EINTR WSAEINTR -#define SOCK_EPIPE EPIPE -#define SOCK_EMFILE WSAEMFILE -#define SOCK_SHUTDOWN WSAESHUTDOWN -#define SOCK_ENOTSOCK WSAENOTSOCK -#define SOCK_EBADF WSAENOTSOCK - -/* - * Under WIN32, FD_SETSIZE is the max. number of sockets, - * not the max. fd value that you use in select(). - * - * Therefore, it is difficult to detemine if any given - * fd can be used with FD_SET(), FD_CLR(), and FD_ISSET(). - */ -#define FD_IN_FDSET(FD) (1) - -epicsShareFunc unsigned epicsShareAPI wsaMajorVersion (); - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/WIN32/osdSockAddrReuse.cpp b/src/libCom/osi/os/WIN32/osdSockAddrReuse.cpp deleted file mode 100644 index d441d7511..000000000 --- a/src/libCom/osi/os/WIN32/osdSockAddrReuse.cpp +++ /dev/null @@ -1,44 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" - -/* - * Note: WINSOCK appears to assign a different functionality for - * SO_REUSEADDR compared to other OS. With WINSOCK SO_REUSEADDR indicates - * that simultaneously servers can bind to the same TCP port on the same host! - * Also, servers are always enabled to reuse a port immediately after - * they exit ( even if SO_REUSEADDR isnt set ). - */ -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ) -{ -} - -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEADDR?\n"); - } -} diff --git a/src/libCom/osi/os/WIN32/osdStdio.c b/src/libCom/osi/os/WIN32/osdStdio.c deleted file mode 100644 index 8a2d58ea9..000000000 --- a/src/libCom/osi/os/WIN32/osdStdio.c +++ /dev/null @@ -1,45 +0,0 @@ -/* osdStdio.c */ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#ifndef _MSC_VER -/* Older versions of MinGW omitted this prototype from stdio.h */ -_CRTIMP int __cdecl __MINGW_NOTHROW _vscprintf (const char*, va_list); -#endif - -#define epicsExportSharedSymbols -#include "epicsStdio.h" - -int epicsShareAPI epicsVsnprintf(char *str, size_t len, - const char *fmt, va_list ap) -{ - int retval = _vsnprintf(str, len, fmt, ap); - int needed = _vscprintf(fmt, ap); - - if ((int) len < needed + 1) { - str[len - 1] = 0; - return needed; - } - - return retval; -} - -int epicsShareAPI epicsSnprintf (char *str, size_t len, const char *fmt, ...) -{ - int rtn; - va_list pvar; - - va_start (pvar, fmt); - rtn = epicsVsnprintf (str, len, fmt, pvar); - va_end (pvar); - return (rtn); -} diff --git a/src/libCom/osi/os/WIN32/osdStrtod.h b/src/libCom/osi/os/WIN32/osdStrtod.h deleted file mode 100644 index 4edb444ee..000000000 --- a/src/libCom/osi/os/WIN32/osdStrtod.h +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * This header fragment is intended to be included as part of epicsString.h - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * epicsStrtod() for systems with broken strtod() routine - */ -epicsShareFunc double epicsStrtod(const char *str, char **endp); - -/* - * Microsoft apparently added strto[u]ll() in VS2013 - * Older compilers have these equivalents though - */ - -#if !defined(_MINGW) && (_MSC_VER < 1800) -# define strtoll _strtoi64 -# define strtoull _strtoui64 -#endif - -#ifdef __cplusplus -} -#endif diff --git a/src/libCom/osi/os/WIN32/osdThread.c b/src/libCom/osi/os/WIN32/osdThread.c deleted file mode 100644 index 8cdb4a3f4..000000000 --- a/src/libCom/osi/os/WIN32/osdThread.c +++ /dev/null @@ -1,1125 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#include -#include -#include -#include - -#define VC_EXTRALEAN -#define STRICT -#ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x400 /* No support for W95 */ -#endif -#include -#include /* for _endthread() etc */ - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "shareLib.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "epicsAssert.h" -#include "ellLib.h" -#include "epicsExit.h" - -epicsShareFunc void osdThreadHooksRun(epicsThreadId id); - -void setThreadName ( DWORD dwThreadID, LPCSTR szThreadName ); -static void threadCleanupWIN32 ( void ); - -typedef struct win32ThreadGlobal { - CRITICAL_SECTION mutex; - ELLLIST threadList; - DWORD tlsIndexThreadLibraryEPICS; -} win32ThreadGlobal; - -typedef struct epicsThreadOSD { - ELLNODE node; - HANDLE handle; - EPICSTHREADFUNC funptr; - void * parm; - char * pName; - DWORD id; - unsigned epicsPriority; - char isSuspended; -} win32ThreadParam; - -typedef struct epicsThreadPrivateOSD { - DWORD key; -} epicsThreadPrivateOSD; - -#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION -# define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 -#endif - -#define osdOrdinaryPriorityStateCount 5u -static const int osdOrdinaryPriorityList [osdOrdinaryPriorityStateCount] = -{ - THREAD_PRIORITY_LOWEST, /* -2 on >= W2K ??? on W95 */ - THREAD_PRIORITY_BELOW_NORMAL, /* -1 on >= W2K ??? on W95 */ - THREAD_PRIORITY_NORMAL, /* 0 on >= W2K ??? on W95 */ - THREAD_PRIORITY_ABOVE_NORMAL, /* 1 on >= W2K ??? on W95 */ - THREAD_PRIORITY_HIGHEST /* 2 on >= W2K ??? on W95 */ -}; - -# define osdRealtimePriorityStateCount 14u -static const int osdRealtimePriorityList [osdRealtimePriorityStateCount] = -{ - -7, /* allowed on >= W2k, but no #define supplied */ - -6, /* allowed on >= W2k, but no #define supplied */ - -5, /* allowed on >= W2k, but no #define supplied */ - -4, /* allowed on >= W2k, but no #define supplied */ - -3, /* allowed on >= W2k, but no #define supplied */ - THREAD_PRIORITY_LOWEST, /* -2 on >= W2K ??? on W95 */ - THREAD_PRIORITY_BELOW_NORMAL, /* -1 on >= W2K ??? on W95 */ - THREAD_PRIORITY_NORMAL, /* 0 on >= W2K ??? on W95 */ - THREAD_PRIORITY_ABOVE_NORMAL, /* 1 on >= W2K ??? on W95 */ - THREAD_PRIORITY_HIGHEST, /* 2 on >= W2K ??? on W95 */ - 3, /* allowed on >= W2k, but no #define supplied */ - 4, /* allowed on >= W2k, but no #define supplied */ - 5, /* allowed on >= W2k, but no #define supplied */ - 6 /* allowed on >= W2k, but no #define supplied */ -}; - -#if defined(EPICS_BUILD_DLL) -BOOL WINAPI DllMain ( - HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved ) -{ - static DWORD dllHandleIndex; - HMODULE dllHandle = 0; - BOOL success = TRUE; - - switch ( dwReason ) - { - case DLL_PROCESS_ATTACH: - dllHandleIndex = TlsAlloc (); - if ( dllHandleIndex == TLS_OUT_OF_INDEXES ) { - success = FALSE; - } - break; - - case DLL_PROCESS_DETACH: - success = TlsFree ( dllHandleIndex ); - break; - - case DLL_THREAD_ATTACH: - /* - * Dont allow user's explicitly calling FreeLibrary for Com.dll to yank - * the carpet out from under EPICS threads that are still using Com.dll - */ -#if _WIN32_WINNT >= 0x0501 - /* - * Only in WXP - * Thats a shame because this is probably much faster - */ - success = GetModuleHandleEx ( - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - ( LPCTSTR ) DllMain, & dllHandle ); -#else - { - char name[256]; - DWORD nChar = GetModuleFileName ( - hModule, name, sizeof ( name ) ); - if ( nChar && nChar < sizeof ( name ) ) { - dllHandle = LoadLibrary ( name ); - if ( ! dllHandle ) { - success = FALSE; - } - } - else { - success = FALSE; - } - } -#endif - if ( success ) { - success = TlsSetValue ( dllHandleIndex, dllHandle ); - } - break; - case DLL_THREAD_DETACH: - /* - * Thread is exiting, release Com.dll. I am assuming that windows is - * smart enough to postpone the unload until this function returns. - */ - dllHandle = TlsGetValue ( dllHandleIndex ); - if ( dllHandle ) { - success = FreeLibrary ( dllHandle ); - } - break; - } - - return success; -} -#endif - -/* - * fetchWin32ThreadGlobal () - * Search for "Synchronization and Multiprocessor Issues" in ms doc - * to understand why this is necessary and why this works on smp systems. - */ -static win32ThreadGlobal * fetchWin32ThreadGlobal ( void ) -{ - static win32ThreadGlobal * pWin32ThreadGlobal = 0; - static LONG initStarted = 0; - static LONG initCompleted = 0; - int crtlStatus; - LONG started; - LONG done; - - done = InterlockedCompareExchange ( & initCompleted, 0, 0 ); - if ( done ) { - return pWin32ThreadGlobal; - } - - started = InterlockedCompareExchange ( & initStarted, 0, 1 ); - if ( started ) { - unsigned tries = 0u; - while ( ! InterlockedCompareExchange ( & initCompleted, 0, 0 ) ) { - /* - * I am not fond of busy loops, but since this will - * collide very infrequently and this is the lowest - * level init then perhaps this is ok - */ - Sleep ( 1 ); - if ( tries++ > 1000 ) { - return 0; - } - } - return pWin32ThreadGlobal; - } - - pWin32ThreadGlobal = ( win32ThreadGlobal * ) - calloc ( 1, sizeof ( * pWin32ThreadGlobal ) ); - if ( ! pWin32ThreadGlobal ) { - InterlockedExchange ( & initStarted, 0 ); - return 0; - } - - InitializeCriticalSection ( & pWin32ThreadGlobal->mutex ); - ellInit ( & pWin32ThreadGlobal->threadList ); - pWin32ThreadGlobal->tlsIndexThreadLibraryEPICS = TlsAlloc(); - if ( pWin32ThreadGlobal->tlsIndexThreadLibraryEPICS == 0xFFFFFFFF ) { - DeleteCriticalSection ( & pWin32ThreadGlobal->mutex ); - free ( pWin32ThreadGlobal ); - pWin32ThreadGlobal = 0; - return 0; - } - - crtlStatus = atexit ( threadCleanupWIN32 ); - if ( crtlStatus ) { - TlsFree ( pWin32ThreadGlobal->tlsIndexThreadLibraryEPICS ); - DeleteCriticalSection ( & pWin32ThreadGlobal->mutex ); - free ( pWin32ThreadGlobal ); - pWin32ThreadGlobal = 0; - return 0; - } - - InterlockedExchange ( & initCompleted, 1 ); - - return pWin32ThreadGlobal; -} - -static void epicsParmCleanupWIN32 ( win32ThreadParam * pParm ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - if ( ! pGbl ) { - fprintf ( stderr, "epicsParmCleanupWIN32: unable to find ctx\n" ); - return; - } - - if ( pParm ) { - /* fprintf ( stderr, "thread %s is exiting\n", pParm->pName ); */ - EnterCriticalSection ( & pGbl->mutex ); - ellDelete ( & pGbl->threadList, & pParm->node ); - LeaveCriticalSection ( & pGbl->mutex ); - - CloseHandle ( pParm->handle ); - free ( pParm ); - TlsSetValue ( pGbl->tlsIndexThreadLibraryEPICS, 0 ); - } -} - -/* - * threadCleanupWIN32 () - */ -static void threadCleanupWIN32 ( void ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - if ( ! pGbl ) { - fprintf ( stderr, "threadCleanupWIN32: unable to find ctx\n" ); - return; - } - - while ( ( pParm = ( win32ThreadParam * ) - ellFirst ( & pGbl->threadList ) ) ) { - epicsParmCleanupWIN32 ( pParm ); - } -} - -/* - * epicsThreadExitMain () - */ -epicsShareFunc void epicsShareAPI epicsThreadExitMain ( void ) -{ - _endthread (); -} - -/* - * osdPriorityMagFromPriorityOSI () - */ -static unsigned osdPriorityMagFromPriorityOSI ( unsigned osiPriority, unsigned priorityStateCount ) -{ - unsigned magnitude; - - /* optimizer will remove this one if epicsThreadPriorityMin is zero */ - /* and osiPriority is unsigned */ - if ( osiPriority < epicsThreadPriorityMin ) { - osiPriority = epicsThreadPriorityMin; - } - - if ( osiPriority > epicsThreadPriorityMax ) { - osiPriority = epicsThreadPriorityMax; - } - - magnitude = osiPriority * priorityStateCount; - magnitude /= ( epicsThreadPriorityMax - epicsThreadPriorityMin ) + 1; - - return magnitude; -} - -epicsShareFunc -void epicsThreadRealtimeLock(void) -{} - -/* - * epicsThreadGetOsdPriorityValue () - */ -static int epicsThreadGetOsdPriorityValue ( unsigned osiPriority ) -{ - const DWORD priorityClass = GetPriorityClass ( GetCurrentProcess () ); - const int * pStateList; - unsigned stateCount; - unsigned magnitude; - - if ( priorityClass == REALTIME_PRIORITY_CLASS ) { - stateCount = osdRealtimePriorityStateCount; - pStateList = osdRealtimePriorityList; - } - else { - stateCount = osdOrdinaryPriorityStateCount; - pStateList = osdOrdinaryPriorityList; - } - - magnitude = osdPriorityMagFromPriorityOSI ( osiPriority, stateCount ); - return pStateList[magnitude]; -} - -/* - * osiPriorityMagFromMagnitueOSD () - */ -static unsigned osiPriorityMagFromMagnitueOSD ( unsigned magnitude, unsigned osdPriorityStateCount ) -{ - unsigned osiPriority; - - osiPriority = magnitude * ( epicsThreadPriorityMax - epicsThreadPriorityMin ); - osiPriority /= osdPriorityStateCount - 1u; - osiPriority += epicsThreadPriorityMin; - - return osiPriority; -} - - -/* - * epicsThreadGetOsiPriorityValue () - */ -static unsigned epicsThreadGetOsiPriorityValue ( int osdPriority ) -{ - const DWORD priorityClass = GetPriorityClass ( GetCurrentProcess () ); - const int * pStateList; - unsigned stateCount; - unsigned magnitude; - - if ( priorityClass == REALTIME_PRIORITY_CLASS ) { - stateCount = osdRealtimePriorityStateCount; - pStateList = osdRealtimePriorityList; - } - else { - stateCount = osdOrdinaryPriorityStateCount; - pStateList = osdOrdinaryPriorityList; - } - - for ( magnitude = 0u; magnitude < stateCount; magnitude++ ) { - if ( osdPriority == pStateList[magnitude] ) { - break; - } - } - - if ( magnitude >= stateCount ) { - fprintf ( stderr, - "Unrecognized WIN32 thread priority level %d.\n", - osdPriority ); - fprintf ( stderr, - "Mapping to EPICS thread priority level epicsThreadPriorityMin.\n" ); - return epicsThreadPriorityMin; - } - - return osiPriorityMagFromMagnitueOSD ( magnitude, stateCount ); -} - -/* - * epicsThreadLowestPriorityLevelAbove () - */ -epicsShareFunc epicsThreadBooleanStatus epicsShareAPI epicsThreadLowestPriorityLevelAbove - ( unsigned int priority, unsigned * pPriorityJustAbove ) -{ - const DWORD priorityClass = GetPriorityClass ( GetCurrentProcess () ); - epicsThreadBooleanStatus status; - unsigned stateCount; - unsigned magnitude; - - if ( priorityClass == REALTIME_PRIORITY_CLASS ) { - stateCount = osdRealtimePriorityStateCount; - } - else { - stateCount = osdOrdinaryPriorityStateCount; - } - - magnitude = osdPriorityMagFromPriorityOSI ( priority, stateCount ); - - if ( magnitude < ( stateCount - 1 ) ) { - *pPriorityJustAbove = osiPriorityMagFromMagnitueOSD ( magnitude + 1u, stateCount ); - status = epicsThreadBooleanStatusSuccess; - } - else { - status = epicsThreadBooleanStatusFail; - } - return status; -} - -/* - * epicsThreadHighestPriorityLevelBelow () - */ -epicsShareFunc epicsThreadBooleanStatus epicsShareAPI epicsThreadHighestPriorityLevelBelow - ( unsigned int priority, unsigned * pPriorityJustBelow ) -{ - const DWORD priorityClass = GetPriorityClass ( GetCurrentProcess () ); - epicsThreadBooleanStatus status; - unsigned stateCount; - unsigned magnitude; - - if ( priorityClass == REALTIME_PRIORITY_CLASS ) { - stateCount = osdRealtimePriorityStateCount; - } - else { - stateCount = osdOrdinaryPriorityStateCount; - } - - magnitude = osdPriorityMagFromPriorityOSI ( priority, stateCount ); - - if ( magnitude > 0u ) { - *pPriorityJustBelow = osiPriorityMagFromMagnitueOSD ( magnitude - 1u, stateCount ); - status = epicsThreadBooleanStatusSuccess; - } - else { - status = epicsThreadBooleanStatusFail; - } - return status; -} - -/* - * epicsThreadGetStackSize () - */ -epicsShareFunc unsigned int epicsShareAPI - epicsThreadGetStackSize ( epicsThreadStackSizeClass stackSizeClass ) -{ - #define STACK_SIZE(f) (f * 0x10000 * sizeof(void *)) - static const unsigned stackSizeTable[epicsThreadStackBig+1] = { - STACK_SIZE(1), STACK_SIZE(2), STACK_SIZE(4) - }; - - if (stackSizeClassepicsThreadStackBig) { - fprintf ( stderr, - "epicsThreadGetStackSize illegal argument (too large)"); - return stackSizeTable[epicsThreadStackBig]; - } - - return stackSizeTable[stackSizeClass]; -} - -void epicsThreadCleanupWIN32 () -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - if ( ! pGbl ) { - fprintf ( stderr, "epicsThreadCleanupWIN32: unable to find ctx\n" ); - return; - } - - pParm = ( win32ThreadParam * ) - TlsGetValue ( pGbl->tlsIndexThreadLibraryEPICS ); - epicsParmCleanupWIN32 ( pParm ); -} - -/* - * epicsWin32ThreadEntry() - */ -static unsigned WINAPI epicsWin32ThreadEntry ( LPVOID lpParameter ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm = ( win32ThreadParam * ) lpParameter; - unsigned retStat = 0u; - BOOL success; - - if ( pGbl ) { - setThreadName ( pParm->id, pParm->pName ); - - success = TlsSetValue ( pGbl->tlsIndexThreadLibraryEPICS, pParm ); - if ( success ) { - osdThreadHooksRun ( ( epicsThreadId ) pParm ); - /* printf ( "starting thread %d\n", pParm->id ); */ - ( *pParm->funptr ) ( pParm->parm ); - /* printf ( "terminating thread %d\n", pParm->id ); */ - retStat = 1; - } - else { - fprintf ( stderr, "epicsWin32ThreadEntry: unable to set private\n" ); - } - } - else { - fprintf ( stderr, "epicsWin32ThreadEntry: unable to find ctx\n" ); - } - - epicsExitCallAtThreadExits (); - /* - * CAUTION: !!!! the thread id might continue to be used after this thread exits !!!! - */ - epicsParmCleanupWIN32 ( pParm ); - - return retStat; /* this indirectly closes the thread handle */ -} - -static win32ThreadParam * epicsThreadParmCreate ( const char *pName ) -{ - win32ThreadParam *pParmWIN32; - - pParmWIN32 = calloc ( 1, sizeof ( *pParmWIN32 ) + strlen ( pName ) + 1 ); - if ( pParmWIN32 ) { - pParmWIN32->pName = (char *) ( pParmWIN32 + 1 ); - strcpy ( pParmWIN32->pName, pName ); - pParmWIN32->isSuspended = 0; - } - return pParmWIN32; -} - -static win32ThreadParam * epicsThreadImplicitCreate ( void ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - DWORD id = GetCurrentThreadId (); - win32ThreadParam * pParm; - char name[64]; - HANDLE handle; - BOOL success; - - if ( ! pGbl ) { - fprintf ( stderr, "epicsThreadImplicitCreate: unable to find ctx\n" ); - return 0; - } - - success = DuplicateHandle ( GetCurrentProcess (), GetCurrentThread (), - GetCurrentProcess (), & handle, 0, FALSE, DUPLICATE_SAME_ACCESS ); - if ( ! success ) { - return 0; - } - { - unsigned long idForFormat = id; - sprintf ( name, "win%lx", idForFormat ); - } - pParm = epicsThreadParmCreate ( name ); - if ( pParm ) { - int win32ThreadPriority; - - pParm->handle = handle; - pParm->id = id; - win32ThreadPriority = GetThreadPriority ( pParm->handle ); - assert ( win32ThreadPriority != THREAD_PRIORITY_ERROR_RETURN ); - pParm->epicsPriority = epicsThreadGetOsiPriorityValue ( win32ThreadPriority ); - success = TlsSetValue ( pGbl->tlsIndexThreadLibraryEPICS, pParm ); - if ( ! success ) { - epicsParmCleanupWIN32 ( pParm ); - pParm = 0; - } - else { - EnterCriticalSection ( & pGbl->mutex ); - ellAdd ( & pGbl->threadList, & pParm->node ); - LeaveCriticalSection ( & pGbl->mutex ); - } - } - return pParm; -} - -/* - * epicsThreadCreate () - */ -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate (const char *pName, - unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC pFunc,void *pParm) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParmWIN32; - int osdPriority; - DWORD wstat; - BOOL bstat; - - if ( ! pGbl ) { - return NULL; - } - - pParmWIN32 = epicsThreadParmCreate ( pName ); - if ( pParmWIN32 == 0 ) { - return ( epicsThreadId ) pParmWIN32; - } - pParmWIN32->funptr = pFunc; - pParmWIN32->parm = pParm; - pParmWIN32->epicsPriority = priority; - - { - unsigned threadId; - pParmWIN32->handle = (HANDLE) _beginthreadex ( - 0, stackSize, epicsWin32ThreadEntry, - pParmWIN32, - CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, - & threadId ); - if ( pParmWIN32->handle == 0 ) { - free ( pParmWIN32 ); - return NULL; - } - /* weird win32 interface threadId parameter inconsistency */ - pParmWIN32->id = ( DWORD ) threadId ; - } - - osdPriority = epicsThreadGetOsdPriorityValue (priority); - bstat = SetThreadPriority ( pParmWIN32->handle, osdPriority ); - if (!bstat) { - CloseHandle ( pParmWIN32->handle ); - free ( pParmWIN32 ); - return NULL; - } - - EnterCriticalSection ( & pGbl->mutex ); - ellAdd ( & pGbl->threadList, & pParmWIN32->node ); - LeaveCriticalSection ( & pGbl->mutex ); - - wstat = ResumeThread ( pParmWIN32->handle ); - if (wstat==0xFFFFFFFF) { - EnterCriticalSection ( & pGbl->mutex ); - ellDelete ( & pGbl->threadList, & pParmWIN32->node ); - LeaveCriticalSection ( & pGbl->mutex ); - CloseHandle ( pParmWIN32->handle ); - free ( pParmWIN32 ); - return NULL; - } - - return ( epicsThreadId ) pParmWIN32; -} - -/* - * epicsThreadSuspendSelf () - */ -epicsShareFunc void epicsShareAPI epicsThreadSuspendSelf () -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - DWORD stat; - - assert ( pGbl ); - - pParm = ( win32ThreadParam * ) - TlsGetValue ( pGbl->tlsIndexThreadLibraryEPICS ); - if ( ! pParm ) { - pParm = epicsThreadImplicitCreate (); - } - if ( pParm ) { - EnterCriticalSection ( & pGbl->mutex ); - pParm->isSuspended = 1; - LeaveCriticalSection ( & pGbl->mutex ); - } - stat = SuspendThread ( GetCurrentThread () ); - assert ( stat != 0xFFFFFFFF ); -} - -/* - * epicsThreadResume () - */ -epicsShareFunc void epicsShareAPI epicsThreadResume ( epicsThreadId id ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm = ( win32ThreadParam * ) id; - DWORD stat; - - assert ( pGbl ); - - EnterCriticalSection ( & pGbl->mutex ); - - stat = ResumeThread ( pParm->handle ); - pParm->isSuspended = 0; - - LeaveCriticalSection ( & pGbl->mutex ); - - assert ( stat != 0xFFFFFFFF ); -} - -/* - * epicsThreadGetPriority () - */ -epicsShareFunc unsigned epicsShareAPI epicsThreadGetPriority (epicsThreadId id) -{ - win32ThreadParam * pParm = ( win32ThreadParam * ) id; - return pParm->epicsPriority; -} - -/* - * epicsThreadGetPrioritySelf () - */ -epicsShareFunc unsigned epicsShareAPI epicsThreadGetPrioritySelf () -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - assert ( pGbl ); - - pParm = ( win32ThreadParam * ) - TlsGetValue ( pGbl->tlsIndexThreadLibraryEPICS ); - if ( ! pParm ) { - pParm = epicsThreadImplicitCreate (); - } - if ( pParm ) { - return pParm->epicsPriority; - } - else { - int win32ThreadPriority = - GetThreadPriority ( GetCurrentThread () ); - assert ( win32ThreadPriority != THREAD_PRIORITY_ERROR_RETURN ); - return epicsThreadGetOsiPriorityValue ( win32ThreadPriority ); - } -} - -/* - * epicsThreadSetPriority () - */ -epicsShareFunc void epicsShareAPI epicsThreadSetPriority ( epicsThreadId id, unsigned priority ) -{ - win32ThreadParam * pParm = ( win32ThreadParam * ) id; - BOOL stat = SetThreadPriority ( pParm->handle, epicsThreadGetOsdPriorityValue (priority) ); - assert (stat); -} - -/* - * epicsThreadIsEqual () - */ -epicsShareFunc int epicsShareAPI epicsThreadIsEqual ( epicsThreadId id1, epicsThreadId id2 ) -{ - win32ThreadParam * pParm1 = ( win32ThreadParam * ) id1; - win32ThreadParam * pParm2 = ( win32ThreadParam * ) id2; - return ( id1 == id2 && pParm1->id == pParm2->id ); -} - -/* - * epicsThreadIsSuspended () - */ -epicsShareFunc int epicsShareAPI epicsThreadIsSuspended ( epicsThreadId id ) -{ - win32ThreadParam *pParm = ( win32ThreadParam * ) id; - DWORD exitCode; - BOOL stat; - - stat = GetExitCodeThread ( pParm->handle, & exitCode ); - if ( stat ) { - if ( exitCode != STILL_ACTIVE ) { - return 1; - } - else { - return pParm->isSuspended; - } - } - else { - return 1; - } -} - -/* - * epicsThreadSleep () - */ -epicsShareFunc void epicsShareAPI epicsThreadSleep ( double seconds ) -{ - static const unsigned mSecPerSec = 1000; - DWORD milliSecDelay; - - if ( seconds > 0.0 ) { - seconds *= mSecPerSec; - seconds += 0.99999999; /* 8 9s here is optimal */ - milliSecDelay = ( seconds >= INFINITE ) ? - INFINITE - 1 : ( DWORD ) seconds; - } - else { /* seconds <= 0 or NAN */ - milliSecDelay = 0u; - } - Sleep ( milliSecDelay ); -} - -/* - * epicsThreadSleepQuantum () - */ -double epicsShareAPI epicsThreadSleepQuantum () -{ - /* - * Its worth noting here that the sleep quantum on windows can - * mysteriously get better. I eventually tracked this down to - * codes that call timeBeginPeriod(1). Calling timeBeginPeriod() - * specifying a better timer resolution also increases the interrupt - * load. This appears to be related to java applet activity. - * The function timeGetDevCaps can tell us the range of periods - * that can be specified to timeBeginPeriod, but alas there - * appears to be no way to find out what the value of the global - * minimum of all timeBeginPeriod calls for all processes is. - */ - static const double secPerTick = 100e-9; - DWORD adjustment; - DWORD delay; - BOOL disabled; - BOOL success; - - success = GetSystemTimeAdjustment ( - & adjustment, & delay, & disabled ); - if ( success ) { - return delay * secPerTick; - } - else { - return 0.0; - } -} - -/* - * epicsThreadGetIdSelf () - */ -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetIdSelf (void) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - assert ( pGbl ); - - pParm = ( win32ThreadParam * ) TlsGetValue ( - pGbl->tlsIndexThreadLibraryEPICS ); - if ( ! pParm ) { - pParm = epicsThreadImplicitCreate (); - assert ( pParm ); /* very dangerous to allow non-unique thread id into use */ - } - return ( epicsThreadId ) pParm; -} - -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetId ( const char * pName ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - if ( ! pGbl ) { - return 0; - } - - EnterCriticalSection ( & pGbl->mutex ); - - for ( pParm = ( win32ThreadParam * ) ellFirst ( & pGbl->threadList ); - pParm; pParm = ( win32ThreadParam * ) ellNext ( & pParm->node ) ) { - if ( pParm->pName ) { - if ( strcmp ( pParm->pName, pName ) == 0 ) { - break; - } - } - } - - LeaveCriticalSection ( & pGbl->mutex ); - - /* !!!! warning - the thread parm could vanish at any time !!!! */ - - return ( epicsThreadId ) pParm; -} - - -/* - * epicsThreadGetNameSelf () - */ -epicsShareFunc const char * epicsShareAPI epicsThreadGetNameSelf (void) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - if ( ! pGbl ) { - return "thread library not initialized"; - } - - pParm = ( win32ThreadParam * ) - TlsGetValue ( pGbl->tlsIndexThreadLibraryEPICS ); - if ( ! pParm ) { - pParm = epicsThreadImplicitCreate (); - } - - if ( pParm ) { - if ( pParm->pName ) { - return pParm->pName; - } - } - return "anonymous"; -} - -/* - * epicsThreadGetName () - */ -epicsShareFunc void epicsShareAPI epicsThreadGetName ( - epicsThreadId id, char * pName, size_t size ) -{ - win32ThreadParam * pParm = ( win32ThreadParam * ) id; - - if ( size ) { - size_t sizeMinusOne = size-1; - strncpy ( pName, pParm->pName, sizeMinusOne ); - pName [sizeMinusOne] = '\0'; - } -} - -/* - * epics_GetThreadPriorityAsString () - */ -static const char * epics_GetThreadPriorityAsString ( HANDLE thr ) -{ - const char * pPriName = "?????"; - switch ( GetThreadPriority ( thr ) ) { - case THREAD_PRIORITY_TIME_CRITICAL: - pPriName = "tm-crit"; - break; - case THREAD_PRIORITY_HIGHEST: - pPriName = "high"; - break; - case THREAD_PRIORITY_ABOVE_NORMAL: - pPriName = "normal+"; - break; - case THREAD_PRIORITY_NORMAL: - pPriName = "normal"; - break; - case THREAD_PRIORITY_BELOW_NORMAL: - pPriName = "normal-"; - break; - case THREAD_PRIORITY_LOWEST: - pPriName = "low"; - break; - case THREAD_PRIORITY_IDLE: - pPriName = "idle"; - break; - } - return pPriName; -} - -/* - * epicsThreadShowInfo () - */ -static void epicsThreadShowInfo ( epicsThreadId id, unsigned level ) -{ - win32ThreadParam * pParm = ( win32ThreadParam * ) id; - - if ( pParm ) { - unsigned long idForFormat = pParm->id; - fprintf ( epicsGetStdout(), "%-15s %-8p %-8lx %-9u %-9s %-7s", pParm->pName, - (void *) pParm, idForFormat, pParm->epicsPriority, - epics_GetThreadPriorityAsString ( pParm->handle ), - epicsThreadIsSuspended ( id ) ? "suspend" : "ok" ); - if ( level ) { - fprintf (epicsGetStdout(), " %-8p %-8p ", - (void *) pParm->handle, (void *) pParm->parm ); - } - } - else { - fprintf (epicsGetStdout(), - "NAME EPICS-ID WIN32-ID EPICS-PRI WIN32-PRI STATE " ); - if ( level ) { - fprintf (epicsGetStdout(), " HANDLE FUNCTION PARAMETER" ); - } - } - fprintf (epicsGetStdout(),"\n" ); -} - -/* - * epicsThreadMap () - */ -epicsShareFunc void epicsThreadMap ( EPICS_THREAD_HOOK_ROUTINE func ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - if ( ! pGbl ) { - return; - } - - EnterCriticalSection ( & pGbl->mutex ); - - for ( pParm = ( win32ThreadParam * ) ellFirst ( & pGbl->threadList ); - pParm; pParm = ( win32ThreadParam * ) ellNext ( & pParm->node ) ) { - func ( ( epicsThreadId ) pParm ); - } - - LeaveCriticalSection ( & pGbl->mutex ); -} - -/* - * epicsThreadShowAll () - */ -epicsShareFunc void epicsShareAPI epicsThreadShowAll ( unsigned level ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - if ( ! pGbl ) { - return; - } - - EnterCriticalSection ( & pGbl->mutex ); - - epicsThreadShowInfo ( 0, level ); - for ( pParm = ( win32ThreadParam * ) ellFirst ( & pGbl->threadList ); - pParm; pParm = ( win32ThreadParam * ) ellNext ( & pParm->node ) ) { - epicsThreadShowInfo ( ( epicsThreadId ) pParm, level ); - } - - LeaveCriticalSection ( & pGbl->mutex ); -} - -/* - * epicsThreadShow () - */ -epicsShareFunc void epicsShareAPI epicsThreadShow ( epicsThreadId id, unsigned level ) -{ - epicsThreadShowInfo ( 0, level ); - epicsThreadShowInfo ( id, level ); -} - -/* - * epicsThreadOnce () - */ -epicsShareFunc void epicsShareAPI epicsThreadOnce ( - epicsThreadOnceId *id, void (*func)(void *), void *arg ) -{ - static struct epicsThreadOSD threadOnceComplete; - #define EPICS_THREAD_ONCE_DONE & threadOnceComplete - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - - assert ( pGbl ); - - EnterCriticalSection ( & pGbl->mutex ); - - if ( *id != EPICS_THREAD_ONCE_DONE ) { - if ( *id == EPICS_THREAD_ONCE_INIT ) { /* first call */ - *id = epicsThreadGetIdSelf(); /* mark active */ - LeaveCriticalSection ( & pGbl->mutex ); - func ( arg ); - EnterCriticalSection ( & pGbl->mutex ); - *id = EPICS_THREAD_ONCE_DONE; /* mark done */ - } else if ( *id == epicsThreadGetIdSelf() ) { - LeaveCriticalSection ( & pGbl->mutex ); - cantProceed( "Recursive epicsThreadOnce() initialization\n" ); - } else - while ( *id != EPICS_THREAD_ONCE_DONE ) { - /* Another thread is in the above func(arg) call. */ - LeaveCriticalSection ( & pGbl->mutex ); - epicsThreadSleep ( epicsThreadSleepQuantum() ); - EnterCriticalSection ( & pGbl->mutex ); - } - } - LeaveCriticalSection ( & pGbl->mutex ); -} - -/* - * epicsThreadPrivateCreate () - */ -epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate () -{ - epicsThreadPrivateOSD *p = ( epicsThreadPrivateOSD * ) malloc ( sizeof ( *p ) ); - if ( p ) { - p->key = TlsAlloc (); - if ( p->key == 0xFFFFFFFF ) { - free ( p ); - p = 0; - } - } - return p; -} - -/* - * epicsThreadPrivateDelete () - */ -epicsShareFunc void epicsShareAPI epicsThreadPrivateDelete ( epicsThreadPrivateId p ) -{ - BOOL stat = TlsFree ( p->key ); - assert ( stat ); - free ( p ); -} - -/* - * epicsThreadPrivateSet () - */ -epicsShareFunc void epicsShareAPI epicsThreadPrivateSet ( epicsThreadPrivateId pPvt, void *pVal ) -{ - BOOL stat = TlsSetValue ( pPvt->key, (void *) pVal ); - assert (stat); -} - -/* - * epicsThreadPrivateGet () - */ -epicsShareFunc void * epicsShareAPI epicsThreadPrivateGet ( epicsThreadPrivateId pPvt ) -{ - return ( void * ) TlsGetValue ( pPvt->key ); -} - -/* - * epicsThreadGetCPUs () - */ -epicsShareFunc int epicsThreadGetCPUs ( void ) -{ - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - if (sysinfo.dwNumberOfProcessors > 0) - return sysinfo.dwNumberOfProcessors; - return 1; -} - -#ifdef TEST_CODES -void testPriorityMapping () -{ - unsigned i; - - for (i=epicsThreadPriorityMin; i -#include -#include -#include - -// -// WIN32 -// -#define VC_EXTRALEAN -#define STRICT -#include -#include - -// -// EPICS -// -#define epicsExportSharedSymbols -#include "epicsTime.h" -#include "generalTimeSup.h" -#include "epicsTimer.h" -#include "errlog.h" -#include "epicsAssert.h" -#include "epicsThread.h" - -#if defined ( DEBUG ) -# define debugPrintf(argsInParen) ::printf argsInParen -#else -# define debugPrintf(argsInParen) -#endif - -extern "C" void setThreadName ( DWORD dwThreadID, LPCSTR szThreadName ); - -static int osdTimeGetCurrent ( epicsTimeStamp *pDest ); - -// for mingw -#if !defined ( MAXLONGLONG ) -# define MAXLONGLONG 0x7fffffffffffffffLL -#endif -#if !defined ( MINLONGLONG ) -# define MINLONGLONG ~0x7fffffffffffffffLL -#endif -#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION -# define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 -#endif - -static const LONGLONG epicsEpochInFileTime = 0x01b41e2a18d64000LL; - -static unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ); - -class currentTime { -public: - currentTime (); - ~currentTime (); - void getCurrentTime ( epicsTimeStamp & dest ); - void startPLL (); -private: - CRITICAL_SECTION mutex; - LONGLONG lastPerfCounter; - LONGLONG perfCounterFreq; - LONGLONG epicsTimeLast; // nano-sec since the EPICS epoch - LONGLONG perfCounterFreqPLL; - LONGLONG lastPerfCounterPLL; - LONGLONG lastFileTimePLL; - HANDLE threadHandle; - unsigned threadId; - bool perfCtrPresent; - bool threadShutdownCmd; - bool threadHasExited; - void updatePLL (); - static const int pllDelay; /* integer seconds */ - // cant be static because of diff btw __stdcall and __cdecl - friend unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ); -}; - -const int currentTime :: pllDelay = 5; - -static currentTime * pCurrentTime = 0; -static const LONGLONG FILE_TIME_TICKS_PER_SEC = 10000000; -static const LONGLONG EPICS_TIME_TICKS_PER_SEC = 1000000000; -static const LONGLONG ET_TICKS_PER_FT_TICK = - EPICS_TIME_TICKS_PER_SEC / FILE_TIME_TICKS_PER_SEC; - -// -// Start and register time provider -// -static int timeRegister(void) -{ - pCurrentTime = new currentTime (); - - generalTimeCurrentTpRegister("PerfCounter", 150, osdTimeGetCurrent); - - pCurrentTime->startPLL (); - return 1; -} -static int done = timeRegister(); - -// -// osdTimeGetCurrent () -// -static int osdTimeGetCurrent ( epicsTimeStamp *pDest ) -{ - assert ( pCurrentTime ); - - pCurrentTime->getCurrentTime ( *pDest ); - return epicsTimeOK; -} - -// synthesize a reentrant gmtime on WIN32 -int epicsShareAPI epicsTime_gmtime ( const time_t *pAnsiTime, struct tm *pTM ) -{ - struct tm * pRet = gmtime ( pAnsiTime ); - if ( pRet ) { - *pTM = *pRet; - return epicsTimeOK; - } - else { - return errno; - } -} - -// synthesize a reentrant localtime on WIN32 -int epicsShareAPI epicsTime_localtime ( - const time_t * pAnsiTime, struct tm * pTM ) -{ - struct tm * pRet = localtime ( pAnsiTime ); - if ( pRet ) { - *pTM = *pRet; - return epicsTimeOK; - } - else { - return errno; - } -} - -currentTime::currentTime () : - lastPerfCounter ( 0 ), - perfCounterFreq ( 0 ), - epicsTimeLast ( 0 ), - perfCounterFreqPLL ( 0 ), - lastPerfCounterPLL ( 0 ), - lastFileTimePLL ( 0 ), - threadHandle ( 0 ), - threadId ( 0 ), - perfCtrPresent ( false ), - threadShutdownCmd ( false ), - threadHasExited ( false ) -{ - InitializeCriticalSection ( & this->mutex ); - - // avoid interruptions by briefly becoming a time critical thread - int originalPriority = GetThreadPriority ( GetCurrentThread () ); - SetThreadPriority ( GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL ); - - FILETIME ft; - GetSystemTimeAsFileTime ( & ft ); - LARGE_INTEGER tmp; - QueryPerformanceCounter ( & tmp ); - this->lastPerfCounter = tmp.QuadPart; - // if no high resolution counters then default to low res file time - if ( QueryPerformanceFrequency ( & tmp ) ) { - this->perfCounterFreq = tmp.QuadPart; - this->perfCtrPresent = true; - } - SetThreadPriority ( GetCurrentThread (), originalPriority ); - - LARGE_INTEGER liFileTime; - liFileTime.LowPart = ft.dwLowDateTime; - liFileTime.HighPart = ft.dwHighDateTime; - - if ( liFileTime.QuadPart >= epicsEpochInFileTime ) { - // the windows file time has a maximum resolution of 100 nS - // and a nominal resolution of 10 mS - 16 mS - this->epicsTimeLast = - ( liFileTime.QuadPart - epicsEpochInFileTime ) * - ET_TICKS_PER_FT_TICK; - } - else { - errlogPrintf ( - "win32 osdTime.cpp init detected questionable " - "system date prior to EPICS epoch, epics time will not advance\n" ); - this->epicsTimeLast = 0; - } - - this->perfCounterFreqPLL = this->perfCounterFreq; - this->lastPerfCounterPLL = this->lastPerfCounter; - this->lastFileTimePLL = liFileTime.QuadPart; -} - -void currentTime :: startPLL () -{ - // create frequency estimation thread when needed - if ( this->perfCtrPresent && ! this->threadHandle ) { - this->threadHandle = (HANDLE) - _beginthreadex ( 0, 4096, _pllThreadEntry, this, - CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, - & this->threadId ); - assert ( this->threadHandle ); - BOOL bstat = SetThreadPriority ( - this->threadHandle, THREAD_PRIORITY_HIGHEST ); - assert ( bstat ); - DWORD wstat = ResumeThread ( this->threadHandle ); - assert ( wstat != 0xFFFFFFFF ); - } -} - -currentTime::~currentTime () -{ - EnterCriticalSection ( & this->mutex ); - this->threadShutdownCmd = true; - while ( ! this->threadHasExited ) { - LeaveCriticalSection ( & this->mutex ); - Sleep ( 250 /* mS */ ); - EnterCriticalSection ( & this->mutex ); - } - LeaveCriticalSection ( & this->mutex ); - DeleteCriticalSection ( & this->mutex ); -} - -void currentTime::getCurrentTime ( epicsTimeStamp & dest ) -{ - if ( this->perfCtrPresent ) { - EnterCriticalSection ( & this->mutex ); - - LARGE_INTEGER curPerfCounter; - QueryPerformanceCounter ( & curPerfCounter ); - - LONGLONG offset; - if ( curPerfCounter.QuadPart >= this->lastPerfCounter ) { - offset = curPerfCounter.QuadPart - this->lastPerfCounter; - } - else { - // - // must have been a timer roll-over event - // - // It takes 9.223372036855e+18/perf_freq sec to roll over this - // counter. This is currently about 245118 years using the perf - // counter freq value on my system (1193182). Nevertheless, I - // have code for this situation because the performance - // counter resolution will more than likely improve over time. - // - offset = ( MAXLONGLONG - this->lastPerfCounter ) - + ( curPerfCounter.QuadPart - MINLONGLONG ) + 1; - } - if ( offset < MAXLONGLONG / EPICS_TIME_TICKS_PER_SEC ) { - offset *= EPICS_TIME_TICKS_PER_SEC; - offset /= this->perfCounterFreq; - } - else { - double fpOffset = static_cast < double > ( offset ); - fpOffset *= EPICS_TIME_TICKS_PER_SEC; - fpOffset /= static_cast < double > ( this->perfCounterFreq ); - offset = static_cast < LONGLONG > ( fpOffset ); - } - LONGLONG epicsTimeCurrent = this->epicsTimeLast + offset; - if ( this->epicsTimeLast > epicsTimeCurrent ) { - double diff = static_cast < double > - ( this->epicsTimeLast - epicsTimeCurrent ) / EPICS_TIME_TICKS_PER_SEC; - errlogPrintf ( - "currentTime::getCurrentTime(): %f sec " - "time discontinuity detected\n", - diff ); - } - this->epicsTimeLast = epicsTimeCurrent; - this->lastPerfCounter = curPerfCounter.QuadPart; - - LeaveCriticalSection ( & this->mutex ); - - dest.secPastEpoch = static_cast < epicsUInt32 > - ( epicsTimeCurrent / EPICS_TIME_TICKS_PER_SEC ); - dest.nsec = static_cast < epicsUInt32 > - ( epicsTimeCurrent % EPICS_TIME_TICKS_PER_SEC ); - } - else { - // if high resolution performance counters are not supported then - // fall back to low res file time - FILETIME ft; - GetSystemTimeAsFileTime ( & ft ); - dest = epicsTime ( ft ); - } -} - -// -// Maintain corrected version of the performance counter's frequency using -// a phase locked loop. This approach is similar to NTP's. -// -void currentTime :: updatePLL () -{ - EnterCriticalSection ( & this->mutex ); - - // avoid interruptions by briefly becoming a time critical thread - LARGE_INTEGER curFileTime; - LARGE_INTEGER curPerfCounter; - { - int originalPriority = GetThreadPriority ( GetCurrentThread () ); - SetThreadPriority ( GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL ); - FILETIME ft; - GetSystemTimeAsFileTime ( & ft ); - QueryPerformanceCounter ( & curPerfCounter ); - SetThreadPriority ( GetCurrentThread (), originalPriority ); - - curFileTime.LowPart = ft.dwLowDateTime; - curFileTime.HighPart = ft.dwHighDateTime; - } - - LONGLONG perfCounterDiff; - if ( curPerfCounter.QuadPart >= this->lastPerfCounterPLL ) { - perfCounterDiff = curPerfCounter.QuadPart - this->lastPerfCounterPLL; - } - else { - // - // must have been a timer roll-over event - // - // It takes 9.223372036855e+18/perf_freq sec to roll over this - // counter. This is currently about 245118 years using the perf - // counter freq value on my system (1193182). Nevertheless, I - // have code for this situation because the performance - // counter resolution will more than likely improve over time. - // - perfCounterDiff = ( MAXLONGLONG - this->lastPerfCounterPLL ) - + ( curPerfCounter.QuadPart - MINLONGLONG ) + 1; - } - this->lastPerfCounterPLL = curPerfCounter.QuadPart; - - LONGLONG fileTimeDiff = curFileTime.QuadPart - this->lastFileTimePLL; - this->lastFileTimePLL = curFileTime.QuadPart; - - // discard glitches - if ( fileTimeDiff <= 0 ) { - LeaveCriticalSection( & this->mutex ); - debugPrintf ( ( "currentTime: file time difference in PLL was less than zero\n" ) ); - return; - } - - LONGLONG freq = ( FILE_TIME_TICKS_PER_SEC * perfCounterDiff ) / fileTimeDiff; - LONGLONG delta = freq - this->perfCounterFreqPLL; - - // discard glitches - LONGLONG bound = this->perfCounterFreqPLL >> 10; - if ( delta < -bound || delta > bound ) { - LeaveCriticalSection( & this->mutex ); - debugPrintf ( ( "freq est out of bounds l=%d e=%d h=%d\n", - static_cast < int > ( -bound ), - static_cast < int > ( delta ), - static_cast < int > ( bound ) ) ); - return; - } - - // update feedback loop estimating the performance counter's frequency - LONGLONG feedback = delta >> 8; - this->perfCounterFreqPLL += feedback; - - LONGLONG perfCounterDiffSinceLastFetch; - if ( curPerfCounter.QuadPart >= this->lastPerfCounter ) { - perfCounterDiffSinceLastFetch = - curPerfCounter.QuadPart - this->lastPerfCounter; - } - else { - // - // must have been a timer roll-over event - // - // It takes 9.223372036855e+18/perf_freq sec to roll over this - // counter. This is currently about 245118 years using the perf - // counter freq value on my system (1193182). Nevertheless, I - // have code for this situation because the performance - // counter resolution will more than likely improve over time. - // - perfCounterDiffSinceLastFetch = - ( MAXLONGLONG - this->lastPerfCounter ) - + ( curPerfCounter.QuadPart - MINLONGLONG ) + 1; - } - - // discard performance counter delay measurement glitches - { - const LONGLONG expectedDly = this->perfCounterFreq * pllDelay; - const LONGLONG bnd = expectedDly / 4; - if ( perfCounterDiffSinceLastFetch <= 0 || - perfCounterDiffSinceLastFetch >= expectedDly + bnd ) { - LeaveCriticalSection( & this->mutex ); - debugPrintf ( ( "perf ctr measured delay out of bounds m=%d max=%d\n", - static_cast < int > ( perfCounterDiffSinceLastFetch ), - static_cast < int > ( expectedDly + bnd ) ) ); - return; - } - } - - // Update the current estimated time. - this->epicsTimeLast += - ( perfCounterDiffSinceLastFetch * EPICS_TIME_TICKS_PER_SEC ) - / this->perfCounterFreq; - this->lastPerfCounter = curPerfCounter.QuadPart; - - LONGLONG epicsTimeFromCurrentFileTime; - - { - static bool firstMessageWasSent = false; - if ( curFileTime.QuadPart >= epicsEpochInFileTime ) { - epicsTimeFromCurrentFileTime = - ( curFileTime.QuadPart - epicsEpochInFileTime ) * - ET_TICKS_PER_FT_TICK; - firstMessageWasSent = false; - } - else { - /* - * if the system time jumps to before the EPICS epoch - * then latch to the EPICS epoch printing only one - * warning message the first time that the issue is - * detected - */ - if ( ! firstMessageWasSent ) { - errlogPrintf ( - "win32 osdTime.cpp time PLL update detected questionable " - "system date prior to EPICS epoch, epics time will not advance\n" ); - firstMessageWasSent = true; - } - epicsTimeFromCurrentFileTime = 0; - } - } - - delta = epicsTimeFromCurrentFileTime - this->epicsTimeLast; - if ( delta > EPICS_TIME_TICKS_PER_SEC || delta < -EPICS_TIME_TICKS_PER_SEC ) { - // When there is an abrupt shift in the current computed time vs - // the time derived from the current file time then someone has - // probably adjusted the real time clock and the best reaction - // is to just assume the new time base - this->epicsTimeLast = epicsTimeFromCurrentFileTime; - this->perfCounterFreq = this->perfCounterFreqPLL; - debugPrintf ( ( "currentTime: did someone adjust the date?\n" ) ); - } - else { - // update the effective performance counter frequency that will bring - // our calculated time base in syncy with file time one second from now. - this->perfCounterFreq = - ( EPICS_TIME_TICKS_PER_SEC * this->perfCounterFreqPLL ) - / ( delta + EPICS_TIME_TICKS_PER_SEC ); - - // limit effective performance counter frequency rate of change - LONGLONG lowLimit = this->perfCounterFreqPLL - bound; - if ( this->perfCounterFreq < lowLimit ) { - debugPrintf ( ( "currentTime: out of bounds low freq excursion %d\n", - static_cast ( lowLimit - this->perfCounterFreq ) ) ); - this->perfCounterFreq = lowLimit; - } - else { - LONGLONG highLimit = this->perfCounterFreqPLL + bound; - if ( this->perfCounterFreq > highLimit ) { - debugPrintf ( ( "currentTime: out of bounds high freq excursion %d\n", - static_cast ( this->perfCounterFreq - highLimit ) ) ); - this->perfCounterFreq = highLimit; - } - } - -# if defined ( DEBUG ) - LARGE_INTEGER sysFreq; - QueryPerformanceFrequency ( & sysFreq ); - double freqDiff = static_cast - ( this->perfCounterFreq - sysFreq.QuadPart ); - freqDiff /= sysFreq.QuadPart; - freqDiff *= 100.0; - double freqEstDiff = static_cast - ( this->perfCounterFreqPLL - sysFreq.QuadPart ); - freqEstDiff /= sysFreq.QuadPart; - freqEstDiff *= 100.0; - debugPrintf ( ( "currentTime: freq delta %f %% freq est " - "delta %f %% time delta %f sec\n", - freqDiff, - freqEstDiff, - static_cast < double > ( delta ) / - EPICS_TIME_TICKS_PER_SEC ) ); -# endif - } - - LeaveCriticalSection ( & this->mutex ); -} - -static unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ) -{ - currentTime * pCT = - reinterpret_cast < currentTime * > ( pCurrentTimeIn ); - setThreadName ( pCT->threadId, "EPICS Time PLL" ); - while ( ! pCT->threadShutdownCmd ) { - Sleep ( currentTime :: pllDelay * 1000 /* mS */ ); - pCT->updatePLL (); - } - EnterCriticalSection ( & pCT->mutex ); - pCT->threadHasExited = true; - LeaveCriticalSection ( & pCT->mutex ); - return 1; -} - -epicsTime::operator FILETIME () const -{ - LARGE_INTEGER ftTicks; - ftTicks.QuadPart = ( this->secPastEpoch * FILE_TIME_TICKS_PER_SEC ) + - ( this->nSec / ET_TICKS_PER_FT_TICK ); - ftTicks.QuadPart += epicsEpochInFileTime; - FILETIME ts; - ts.dwLowDateTime = ftTicks.LowPart; - ts.dwHighDateTime = ftTicks.HighPart; - return ts; -} - -epicsTime::epicsTime ( const FILETIME & ts ) -{ - LARGE_INTEGER lift; - lift.LowPart = ts.dwLowDateTime; - lift.HighPart = ts.dwHighDateTime; - if ( lift.QuadPart > epicsEpochInFileTime ) { - LONGLONG fileTimeTicksSinceEpochEPICS = - lift.QuadPart - epicsEpochInFileTime; - this->secPastEpoch = static_cast < epicsUInt32 > - ( fileTimeTicksSinceEpochEPICS / FILE_TIME_TICKS_PER_SEC ); - this->nSec = static_cast < epicsUInt32 > - ( ( fileTimeTicksSinceEpochEPICS % FILE_TIME_TICKS_PER_SEC ) * - ET_TICKS_PER_FT_TICK ); - } - else { - this->secPastEpoch = 0; - this->nSec = 0; - } -} - -epicsTime & epicsTime::operator = ( const FILETIME & rhs ) -{ - *this = epicsTime ( rhs ); - return *this; -} diff --git a/src/libCom/osi/os/WIN32/osdTime.h b/src/libCom/osi/os/WIN32/osdTime.h deleted file mode 100644 index 35848f6dc..000000000 --- a/src/libCom/osi/os/WIN32/osdTime.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#ifndef INC_osdTime_H -#define INC_osdTime_H - -/* MinGW only has a snippet time.h not protected against multiple inclusion */ -#if defined(__struct_timespec_defined) -#define _TIMESPEC_DEFINED 1 -#endif - -#if ! defined(_MINGW) || ! defined(_TIMESPEC_DEFINED) -# if _MSC_VER >= 1900 -# include -# else - -#define __struct_timespec_defined 1 -#define _TIMESPEC_DEFINED 1 -struct timespec { - time_t tv_sec; /* seconds since some epoch */ - long tv_nsec; /* nanoseconds within the second */ -}; - -# endif /* _MSC_VER */ -#endif /* ! defined(_MINGW) || ! defined(_TIMESPEC_DEFINED) */ - -#endif /* ifndef INC_osdTime_H */ - diff --git a/src/libCom/osi/os/WIN32/osdWireConfig.h b/src/libCom/osi/os/WIN32/osdWireConfig.h deleted file mode 100644 index 1715786e0..000000000 --- a/src/libCom/osi/os/WIN32/osdWireConfig.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * WIN32 version of - * osdWireConfig.h - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef osdWireConfig_h -#define osdWireConfig_h - -/* for now, assume that win32 runs only on generic little endian */ -#define EPICS_BYTE_ORDER EPICS_ENDIAN_LITTLE -#define EPICS_FLOAT_WORD_ORDER EPICS_BYTE_ORDER - -#endif /* ifdef osdWireConfig_h */ diff --git a/src/libCom/osi/os/WIN32/osiFileName.h b/src/libCom/osi/os/WIN32/osiFileName.h deleted file mode 100644 index 6ff0308b2..000000000 --- a/src/libCom/osi/os/WIN32/osiFileName.h +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * osiFileName.h - * Author: Jeff Hill - * - */ -#ifndef osiFileNameH -#define osiFileNameH - -#define OSI_PATH_LIST_SEPARATOR ";" -#define OSI_PATH_SEPARATOR "\\" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/WIN32/osiUnistd.h b/src/libCom/osi/os/WIN32/osiUnistd.h deleted file mode 100644 index 3f34e74cc..000000000 --- a/src/libCom/osi/os/WIN32/osiUnistd.h +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include diff --git a/src/libCom/osi/os/WIN32/setThreadName.cpp b/src/libCom/osi/os/WIN32/setThreadName.cpp deleted file mode 100644 index 49663c8af..000000000 --- a/src/libCom/osi/os/WIN32/setThreadName.cpp +++ /dev/null @@ -1,51 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define VC_EXTRALEAN -#define STRICT -#if _WIN64 -# define _WIN32_WINNT 0x400 /* defining this drops support for W95 */ -#endif -#include - -/* - * this was copied directly from an example in visual c++ 7 documentation, - * It uses visual C++ specific keywords for exception handling, but is - * probably only useful when using the visual c++ or later debugger. - * - * Usage: setThreadName (-1, "MainThread"); - */ -extern "C" void setThreadName ( DWORD dwThreadID, LPCSTR szThreadName ) -{ -#if _MSC_VER >= 1300 && defined ( _DEBUG ) - typedef struct tagTHREADNAME_INFO - { - DWORD dwType; // must be 0x1000 - LPCSTR szName; // pointer to name (in user addr space) - DWORD dwThreadID; // thread ID (-1=caller thread) - DWORD dwFlags; // reserved for future use, must be zero - } THREADNAME_INFO; - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = szThreadName; - info.dwThreadID = dwThreadID; - info.dwFlags = 0; - - __try - { - RaiseException( 0x406D1388, 0, - sizeof(info)/sizeof(DWORD), (const ULONG_PTR*)&info ); - } - __except(EXCEPTION_CONTINUE_EXECUTION) - { - } -#endif -} diff --git a/src/libCom/osi/os/WIN32/systemCallIntMech.cpp b/src/libCom/osi/os/WIN32/systemCallIntMech.cpp deleted file mode 100644 index 5e13299c0..000000000 --- a/src/libCom/osi/os/WIN32/systemCallIntMech.cpp +++ /dev/null @@ -1,22 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" - -enum epicsSocketSystemCallInterruptMechanismQueryInfo - epicsSocketSystemCallInterruptMechanismQuery () -{ - return esscimqi_socketCloseRequired; -} diff --git a/src/libCom/osi/os/cygwin32/devLibVMEOSD.c b/src/libCom/osi/os/cygwin32/devLibVMEOSD.c deleted file mode 100644 index 53cbd58cd..000000000 --- a/src/libCom/osi/os/cygwin32/devLibVMEOSD.c +++ /dev/null @@ -1,13 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#define epicsExportSharedSymbols -#include "devLibVME.h" - -epicsShareDef devLibVME *pdevLibVME = NULL; diff --git a/src/libCom/osi/os/cygwin32/osdSock.h b/src/libCom/osi/os/cygwin32/osdSock.h deleted file mode 100644 index d642cad44..000000000 --- a/src/libCom/osi/os/cygwin32/osdSock.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * cygwin32 specific include - */ - - -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; -typedef int osiSocklen_t; -#define FD_IN_FDSET(FD) ((FD)=0) -#ifndef SHUT_RD -#define SHUT_RD 0 -#endif -#ifndef SHUT_WR -#define SHUT_WR 1 -#endif -#ifndef SHUT_RDWR -# define SHUT_RDWR 2 -#endif - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EACCES EACCES -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE -#define SOCK_EMFILE EMFILE -#define SOCK_SHUTDOWN ESHUTDOWN -#define SOCK_ENOTSOCK ENOTSOCK -#define SOCK_EBADF EBADF - -#define ifreq_size(pifreq) (sizeof(pifreq->ifr_name)) - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/cygwin32/osdSockAddrReuse.cpp b/src/libCom/osi/os/cygwin32/osdSockAddrReuse.cpp deleted file mode 100644 index d441d7511..000000000 --- a/src/libCom/osi/os/cygwin32/osdSockAddrReuse.cpp +++ /dev/null @@ -1,44 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" - -/* - * Note: WINSOCK appears to assign a different functionality for - * SO_REUSEADDR compared to other OS. With WINSOCK SO_REUSEADDR indicates - * that simultaneously servers can bind to the same TCP port on the same host! - * Also, servers are always enabled to reuse a port immediately after - * they exit ( even if SO_REUSEADDR isnt set ). - */ -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ) -{ -} - -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEADDR?\n"); - } -} diff --git a/src/libCom/osi/os/cygwin32/osdStrtod.h b/src/libCom/osi/os/cygwin32/osdStrtod.h deleted file mode 100644 index b5fda31c3..000000000 --- a/src/libCom/osi/os/cygwin32/osdStrtod.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * This header fragment is intended to be included as part of epicsString.h - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * epicsStrtod() for systems with broken strtod() routine - */ -epicsShareFunc double epicsStrtod(const char *str, char **endp); - -#ifdef __cplusplus -} -#endif diff --git a/src/libCom/osi/os/cygwin32/osiFileName.h b/src/libCom/osi/os/cygwin32/osiFileName.h deleted file mode 100644 index 6d7fd6eb9..000000000 --- a/src/libCom/osi/os/cygwin32/osiFileName.h +++ /dev/null @@ -1,20 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * osiFileName.h - * Author: Jeff Hill - */ -#ifndef osiFileNameH -#define osiFileNameH - -#define OSI_PATH_LIST_SEPARATOR ";" -#define OSI_PATH_SEPARATOR "\\" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/cygwin32/systemCallIntMech.cpp b/src/libCom/osi/os/cygwin32/systemCallIntMech.cpp deleted file mode 100644 index 9c0df3293..000000000 --- a/src/libCom/osi/os/cygwin32/systemCallIntMech.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeff Hill - */ - -#include - -#define epicsExportSharedSymbols -#include "osiSock.h" - -enum epicsSocketSystemCallInterruptMechanismQueryInfo - epicsSocketSystemCallInterruptMechanismQuery () -{ -#if (CYGWIN_VERSION_DLL_MAJOR == 1007) && (CYGWIN_VERSION_DLL_MINOR < 15) - // Behaviour changed in early Cygwin 1.7 releases, reverted later. - return esscimqi_socketCloseRequired; -#else - return esscimqi_socketBothShutdownRequired; -#endif -} diff --git a/src/libCom/osi/os/default/devLibVMEOSD.c b/src/libCom/osi/os/default/devLibVMEOSD.c deleted file mode 100644 index b8b1d5047..000000000 --- a/src/libCom/osi/os/default/devLibVMEOSD.c +++ /dev/null @@ -1,15 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 The University of Chicago, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#define epicsExportSharedSymbols -#include "devLibVME.h" - -/* This file must contain no definitions other than the following: */ - -epicsShareDef devLibVME *pdevLibVME; diff --git a/src/libCom/osi/os/default/epicsAtomicOSD.cpp b/src/libCom/osi/os/default/epicsAtomicOSD.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/libCom/osi/os/default/epicsGetopt.h b/src/libCom/osi/os/default/epicsGetopt.h deleted file mode 100644 index 4bcc962cb..000000000 --- a/src/libCom/osi/os/default/epicsGetopt.h +++ /dev/null @@ -1,17 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer -* Synchrotronstrahlung. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef _EPICS_GETOPT_H -#define _EPICS_GETOPT_H - -#include - -#endif /* _EPICS_GETOPT_H */ diff --git a/src/libCom/osi/os/default/epicsMMIO.h b/src/libCom/osi/os/default/epicsMMIO.h deleted file mode 100644 index 79040932a..000000000 --- a/src/libCom/osi/os/default/epicsMMIO.h +++ /dev/null @@ -1,2 +0,0 @@ - -#include "epicsMMIODef.h" diff --git a/src/libCom/osi/os/default/epicsMMIODef.h b/src/libCom/osi/os/default/epicsMMIODef.h deleted file mode 100644 index dc4bb4cb7..000000000 --- a/src/libCom/osi/os/default/epicsMMIODef.h +++ /dev/null @@ -1,274 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Michael Davidsaver - */ - -#ifndef EPICSMMIODEF_H -#define EPICSMMIODEF_H - -#include -#include -#include -#include - -#ifdef __cplusplus -# ifndef INLINE -# define INLINE inline -# endif -#endif - -/** @ingroup mmio - *@{ - */ - -/** @brief Read a single byte. - */ -static EPICS_ALWAYS_INLINE -epicsUInt8 -ioread8(volatile void* addr) -{ - return *(volatile epicsUInt8*)(addr); -} - -/** @brief Write a single byte. - */ -static EPICS_ALWAYS_INLINE -void -iowrite8(volatile void* addr, epicsUInt8 val) -{ - *(volatile epicsUInt8*)(addr) = val; -} - -/** @brief Read two bytes in host order. - * Not byte swapping - */ -static EPICS_ALWAYS_INLINE -epicsUInt16 -nat_ioread16(volatile void* addr) -{ - return *(volatile epicsUInt16*)(addr); -} - -/** @brief Write two byte in host order. - * Not byte swapping - */ -static EPICS_ALWAYS_INLINE -void -nat_iowrite16(volatile void* addr, epicsUInt16 val) -{ - *(volatile epicsUInt16*)(addr) = val; -} - -/** @brief Read four bytes in host order. - * Not byte swapping - */ -static EPICS_ALWAYS_INLINE -epicsUInt32 -nat_ioread32(volatile void* addr) -{ - return *(volatile epicsUInt32*)(addr); -} - -/** @brief Write four byte in host order. - * Not byte swapping - */ -static EPICS_ALWAYS_INLINE -void -nat_iowrite32(volatile void* addr, epicsUInt32 val) -{ - *(volatile epicsUInt32*)(addr) = val; -} - -#if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG - -/** @ingroup mmio - *@{ - */ - -static EPICS_ALWAYS_INLINE -epicsUInt16 -bswap16(epicsUInt16 value) -{ - return (((epicsUInt16)(value) & 0x00ff) << 8) | - (((epicsUInt16)(value) & 0xff00) >> 8); -} - -static EPICS_ALWAYS_INLINE -epicsUInt32 -bswap32(epicsUInt32 value) -{ - return (((epicsUInt32)(value) & 0x000000ff) << 24) | - (((epicsUInt32)(value) & 0x0000ff00) << 8) | - (((epicsUInt32)(value) & 0x00ff0000) >> 8) | - (((epicsUInt32)(value) & 0xff000000) >> 24); -} - -# define be_ioread16(A) nat_ioread16(A) -# define be_ioread32(A) nat_ioread32(A) -# define be_iowrite16(A,D) nat_iowrite16(A,D) -# define be_iowrite32(A,D) nat_iowrite32(A,D) - -# define le_ioread16(A) bswap16(nat_ioread16(A)) -# define le_ioread32(A) bswap32(nat_ioread32(A)) -# define le_iowrite16(A,D) nat_iowrite16(A,bswap16(D)) -# define le_iowrite32(A,D) nat_iowrite32(A,bswap32(D)) - -/** @} */ - -#elif EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE - -/* Get hton[sl] declarations: */ -#include - -/** @ingroup mmio - *@{ - */ - -/* hton* is optimized or a builtin for most compilers - * so use it if possible - */ -#define bswap16(v) htons(v) -#define bswap32(v) htonl(v) - -# define be_ioread16(A) bswap16(nat_ioread16(A)) -# define be_ioread32(A) bswap32(nat_ioread32(A)) -# define be_iowrite16(A,D) nat_iowrite16(A,bswap16(D)) -# define be_iowrite32(A,D) nat_iowrite32(A,bswap32(D)) - -# define le_ioread16(A) nat_ioread16(A) -# define le_ioread32(A) nat_ioread32(A) -# define le_iowrite16(A,D) nat_iowrite16(A,D) -# define le_iowrite32(A,D) nat_iowrite32(A,D) - -/** @} */ - -#else -# error Unable to determine native byte order -#endif - -/** @def bswap16 - * @brief Unconditional two byte swap - */ -/** @def bswap32 - * @brief Unconditional four byte swap - */ -/** @def be_ioread16 - * @brief Read two byte in big endian order. - */ -/** @def be_iowrite16 - * @brief Write two byte in big endian order. - */ -/** @def be_ioread32 - * @brief Read four byte in big endian order. - */ -/** @def be_iowrite32 - * @brief Write four byte in big endian order. - */ -/** @def le_ioread16 - * @brief Read two byte in little endian order. - */ -/** @def le_iowrite16 - * @brief Write two byte in little endian order. - */ -/** @def le_ioread32 - * @brief Read four byte in little endian order. - */ -/** @def le_iowrite32 - * @brief Write four byte in little endian order. - */ - -/** @ingroup mmio - *@{ - */ - -/** @brief Explicit read memory barrier - * Prevents reordering of reads around it. - */ -#define rbarr() do{}while(0) -/** @brief Explicit write memory barrier - * Prevents reordering of writes around it. - */ -#define wbarr() do{}while(0) -/** @brief Explicit read/write memory barrier - * Prevents reordering of reads or writes around it. - */ -#define rwbarr() do{}while(0) - -/** @} */ - -/** @defgroup mmio Memory Mapped I/O - * - * Safe operations on I/O memory. - * - *This files defines a set of macros for access to Memory Mapped I/O - * - *They are named T_ioread# and T_iowrite# where # can be 8, 16, or 32. - *'T' can either be 'le', 'be', or 'nat' (except ioread8 and - *iowrite8). - * - *The macros defined use OS specific extensions (when available) - *to ensure the following. - * - *@li Width. A 16 bit operation will not be broken into two 8 bit operations, - * or one half of a 32 bit operation. - * - *@li Order. Writes to two different registers will not be reordered. - * This only applies to MMIO operations, not between MMIO and - * normal memory operations. - * - *PCI access should use either 'le_' or 'be_' as determined by the - *device byte order. - * - *VME access should always use 'nat_'. If the device byte order is - *little endian then an explicit swap is required. - * - *@section mmioex Examples: - * - *@subsection mmioexbe Big endian device: - * - *@b PCI - * - @code - be_iowrite16(base+off, 14); - var = be_ioread16(base+off); - @endcode - * - *@b VME - * - @code - nat_iowrite16(base+off, 14); - var = nat_ioread16(base+off); - @endcode - * - *@subsection mmioexle Little endian device - * - *@b PCI - @code - le_iowrite16(base+off, 14); - var = le_ioread16(base+off); - @endcode - *@b VME - @code - nat_iowrite16(base+off, bswap16(14)); - var = bswap16(nat_iowrite16(base+off)); - @endcode - *This difference arises because VME bridges implement hardware byte - *swapping on little endian systems, while PCI bridges do not. - *Software accessing PCI devices must know if byte swapping is required. - *This conditional swap is implemented by the 'be_' and 'le_' macros. - * - *This is a fundamental difference between PCI and VME. - * - *Software accessing PCI @b must do conditional swapping. - * - *Software accessing VME must @b not do conditional swapping. - * - *@note All read and write operations have an implicit read or write barrier. - */ - -#endif /* EPICSMMIODEF_H */ diff --git a/src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp b/src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp deleted file mode 100644 index 3cbfce60d..000000000 --- a/src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdSock.c */ -/* - * Author: Jeff Hill - * Date: 04-05-94 - * - */ - -#include - -#define epicsExportSharedSymbols -#include "osiSock.h" - -/* - * epicsSocketConvertErrorToString() - */ -void epicsSocketConvertErrorToString ( - char * pBuf, unsigned bufSize, int theSockError ) -{ - if ( bufSize ) { - strncpy ( pBuf, strerror ( theSockError ), bufSize ); - pBuf[bufSize-1] = '\0'; - } -} - -/* - * epicsSocketConvertErrnoToString() - */ -void epicsSocketConvertErrnoToString ( - char * pBuf, unsigned bufSize ) -{ - epicsSocketConvertErrorToString ( pBuf, bufSize, SOCKERRNO ); -} diff --git a/src/libCom/osi/os/default/gnuReadline.c b/src/libCom/osi/os/default/gnuReadline.c deleted file mode 100644 index ae646a53e..000000000 --- a/src/libCom/osi/os/default/gnuReadline.c +++ /dev/null @@ -1,124 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Eric Norum Date: 12DEC2001 */ - -/* - * This file is included by epicsReadline.c which has already included the - * headers stdio.h, stdlib.h, errno.h, envDefs.h and epicsReadline.h - */ - -#include -#include - -#include "epicsExit.h" - -static struct osdContext { - char dummy; /* Required for older compilers */ -} present; - -static enum {rlNone, rlIdle, rlBusy} rlState = rlNone; - -static void rlExit(void *dummy) { - if (rlState == rlBusy) - rl_cleanup_after_signal(); -} - - -/* - * Create a command-line context - */ -static void -osdReadlineBegin(struct readlineContext *context) -{ - if (rlState == rlNone) { - epicsAtExit(rlExit, NULL); - rlState = rlIdle; - } - - context->osd = &present; - if (context->in == NULL) { - long i = 50; - - envGetLongConfigParam(&IOCSH_HISTSIZE, &i); - if (i < 0) - i = 0; - stifle_history(i); - rl_bind_key('\t', rl_insert); - } -} - -/* - * Read a line of input - */ -static char * -osdReadline (const char *prompt, struct readlineContext *context) -{ - char *line; - - free(context->line); - context->line = NULL; - if (context->in == NULL) { - rlState = rlBusy; - line = readline (prompt); - rlState = rlIdle; - } - else { - int c; /* char is unsigned on some archs; EOF is -ve */ - int linelen = 0; - int linesize = 50; - - line = malloc(linesize); - if (line == NULL) { - printf("Out of memory!\n"); - return NULL; - } - if (prompt) { - fputs(prompt, stdout); - fflush(stdout); - } - while ((c = getc(context->in)) != '\n') { - if (c == EOF) { - free(line); - line = NULL; - break; - } - if ((linelen + 1) >= linesize) { - char *cp; - - linesize += 50; - cp = (char *)realloc(line, linesize); - if (cp == NULL) { - printf ("Out of memory!\n"); - free(line); - line = NULL; - break; - } - line = cp; - } - line[linelen++] = c; - } - if (line) - line[linelen] = '\0'; - } - context->line = line; - if (line && *line) - add_history(line); - return line; -} - -/* - * Destroy a command-line context - */ -static void -osdReadlineEnd (struct readlineContext *context) -{ - if (context->osd) { - free(context->line); - } -} - diff --git a/src/libCom/osi/os/default/osdAssert.c b/src/libCom/osi/os/default/osdAssert.c deleted file mode 100644 index 14d548c3d..000000000 --- a/src/libCom/osi/os/default/osdAssert.c +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey Hill - * Date: 02-27-95 - */ - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "epicsPrint.h" -#include "epicsVersion.h" -#include "epicsAssert.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "cantProceed.h" -#include "epicsStackTrace.h" - - -void epicsAssert (const char *pFile, const unsigned line, - const char *pExp, const char *pAuthorName) -{ - epicsTimeStamp current; - - errlogPrintf("\n\n\n" - "A call to 'assert(%s)'\n" - " by thread '%s' failed in %s line %u.\n", - pExp, epicsThreadGetNameSelf(), pFile, line); - - epicsStackTrace(); - - errlogPrintf("EPICS Release %s.\n", epicsReleaseVersion); - - if (epicsTimeGetCurrent(¤t) == 0) { - char date[64]; - - epicsTimeToStrftime(date, sizeof(date), - "%Y-%m-%d %H:%M:%S.%f %Z", ¤t); - errlogPrintf("Local time is %s\n", date); - } - - if (!pAuthorName) { - pAuthorName = "the author"; - } - errlogPrintf("Please E-mail this message to %s or to tech-talk@aps.anl.gov\n", - pAuthorName); - - errlogPrintf("Calling epicsThreadSuspendSelf()\n"); - epicsThreadSuspendSelf (); -} diff --git a/src/libCom/osi/os/default/osdBackTrace.cpp b/src/libCom/osi/os/default/osdBackTrace.cpp deleted file mode 100644 index e1f96c033..000000000 --- a/src/libCom/osi/os/default/osdBackTrace.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#define epicsExportSharedSymbols -#include "epicsStackTracePvt.h" - -int epicsBackTrace(void **buf, int buf_sz) -{ - return -1; -} diff --git a/src/libCom/osi/os/default/osdEnv.c b/src/libCom/osi/os/default/osdEnv.c deleted file mode 100644 index 682bcc934..000000000 --- a/src/libCom/osi/os/default/osdEnv.c +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdEnv.c */ -/* - * Author: Eric Norum - * Date: May 7, 2001 - * - * Routines to modify/display environment variables and EPICS parameters - * - */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "errlog.h" -#include "cantProceed.h" -#include "envDefs.h" -#include "osiUnistd.h" -#include "epicsFindSymbol.h" -#include "iocsh.h" - -/* - * Set the value of an environment variable - * Leaks memory, but the assumption is that this routine won't be - * called often enough for the leak to be a problem. - */ -epicsShareFunc void epicsShareAPI epicsEnvSet (const char *name, const char *value) -{ - char *cp; - - iocshEnvClear(name); - - cp = mallocMustSucceed (strlen (name) + strlen (value) + 2, "epicsEnvSet"); - strcpy (cp, name); - strcat (cp, "="); - strcat (cp, value); - if (putenv (cp) < 0) { - errPrintf( - -1L, - __FILE__, - __LINE__, - "Failed to set environment parameter \"%s\" to \"%s\": %s\n", - name, - value, - strerror (errno)); - free (cp); - } -} - -/* - * Show the value of the specified, or all, environment variables - */ -epicsShareFunc void epicsShareAPI epicsEnvShow (const char *name) -{ - if (name == NULL) { - extern char **environ; - char **sp; - - for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++) - printf ("%s\n", *sp); - } - else { - const char *cp = getenv (name); - if (cp == NULL) - printf ("%s is not an environment variable.\n", name); - else - printf ("%s=%s\n", name, cp); - } -} diff --git a/src/libCom/osi/os/default/osdFindAddr.c b/src/libCom/osi/os/default/osdFindAddr.c deleted file mode 100644 index 582dd5442..000000000 --- a/src/libCom/osi/os/default/osdFindAddr.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#define epicsExportSharedSymbols -#include "epicsStackTracePvt.h" -#include "epicsStackTrace.h" - -int epicsFindAddr(void *addr, epicsSymbol *sym_p) -{ - sym_p->f_nam = 0; - sym_p->s_nam = 0; - sym_p->s_val = 0; - return -1; -} - -int epicsFindAddrGetFeatures(void) -{ - return 0; -} diff --git a/src/libCom/osi/os/default/osdFindSymbol.c b/src/libCom/osi/os/default/osdFindSymbol.c deleted file mode 100644 index 9d9a8878c..000000000 --- a/src/libCom/osi/os/default/osdFindSymbol.c +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/default/osdFindSymbol.c */ - -#define epicsExportSharedSymbols -#include "epicsFindSymbol.h" - -epicsShareFunc void * epicsLoadLibrary(const char *name) -{ - return 0; -} - -epicsShareFunc const char *epicsLoadError(void) -{ - return "epicsLoadLibrary not implemented"; -} - -epicsShareFunc void * epicsShareAPI epicsFindSymbol(const char *name) -{ - return 0; -} diff --git a/src/libCom/osi/os/default/osdInterrupt.c b/src/libCom/osi/os/default/osdInterrupt.c deleted file mode 100644 index 91c5c5681..000000000 --- a/src/libCom/osi/os/default/osdInterrupt.c +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/default/osdInterrupt.c */ - -/* Author: Marty Kraimer Date: 15JUL99 */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMutex.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "errlog.h" -#include "epicsInterrupt.h" - - -static epicsMutexId globalLock = NULL; -static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; - -static void initOnce(void *junk) -{ - globalLock = epicsMutexMustCreate(); -} - -epicsShareFunc int epicsInterruptLock() -{ - epicsThreadOnce(&onceId, initOnce, NULL); - epicsMutexMustLock(globalLock); - return 0; -} - -epicsShareFunc void epicsInterruptUnlock(int key) -{ - if (!globalLock) - cantProceed("epicsInterruptUnlock called before epicsInterruptLock\n"); - epicsMutexUnlock(globalLock); -} - -epicsShareFunc int epicsInterruptIsInterruptContext() -{ - return 0; -} - -epicsShareFunc void epicsInterruptContextMessage(const char *message) -{ - errlogPrintf("%s", message); -} - diff --git a/src/libCom/osi/os/default/osdInterrupt.h b/src/libCom/osi/os/default/osdInterrupt.h deleted file mode 100644 index 5559d6280..000000000 --- a/src/libCom/osi/os/default/osdInterrupt.h +++ /dev/null @@ -1,15 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef osdInterrupth -#define osdInterrupth - -#endif /* osdInterrupth */ - diff --git a/src/libCom/osi/os/default/osdMessageQueue.cpp b/src/libCom/osi/os/default/osdMessageQueue.cpp deleted file mode 100644 index c86d8cc2b..000000000 --- a/src/libCom/osi/os/default/osdMessageQueue.cpp +++ /dev/null @@ -1,408 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -#include -#include - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMessageQueue.h" -#include -#include -#include -#include - -/* - * Event cache - */ -struct eventNode { - ELLNODE link; - epicsEventId event; -}; - -/* - * List of threads waiting to send or receive a message - */ -struct threadNode { - ELLNODE link; - struct eventNode *evp; - void *buf; - unsigned int size; - volatile bool eventSent; -}; - -/* - * Message info - */ -struct epicsMessageQueueOSD { - ELLLIST sendQueue; - ELLLIST receiveQueue; - ELLLIST eventFreeList; - int numberOfSendersWaiting; - - epicsMutexId mutex; - unsigned long capacity; - unsigned long maxMessageSize; - - unsigned long *buf; - char *firstMessageSlot; - char *lastMessageSlot; - volatile char *inPtr; - volatile char *outPtr; - unsigned long slotSize; - - bool full; -}; - -epicsShareFunc epicsMessageQueueId epicsShareAPI epicsMessageQueueCreate( - unsigned int capacity, - unsigned int maxMessageSize) -{ - epicsMessageQueueId pmsg; - unsigned int slotBytes, slotLongs; - - if(capacity == 0) - return NULL; - - pmsg = (epicsMessageQueueId)calloc(1, sizeof(*pmsg)); - if(!pmsg) - return NULL; - - pmsg->capacity = capacity; - pmsg->maxMessageSize = maxMessageSize; - slotLongs = 1 + ((maxMessageSize + sizeof(unsigned long) - 1) / sizeof(unsigned long)); - slotBytes = slotLongs * sizeof(unsigned long); - - pmsg->mutex = epicsMutexCreate(); - pmsg->buf = (unsigned long*)calloc(pmsg->capacity, slotBytes); - if(!pmsg->buf || !pmsg->mutex) { - if(pmsg->mutex) - epicsMutexDestroy(pmsg->mutex); - free(pmsg->buf); - free(pmsg); - return NULL; - } - - pmsg->inPtr = pmsg->outPtr = pmsg->firstMessageSlot = (char *)&pmsg->buf[0]; - pmsg->lastMessageSlot = (char *)&pmsg->buf[(capacity - 1) * slotLongs]; - pmsg->full = false; - pmsg->slotSize = slotBytes; - - ellInit(&pmsg->sendQueue); - ellInit(&pmsg->receiveQueue); - ellInit(&pmsg->eventFreeList); - return pmsg; -} - -static void -freeEventNode(struct eventNode *enode) -{ - epicsEventDestroy(enode->event); - free(enode); -} - -epicsShareFunc void epicsShareAPI -epicsMessageQueueDestroy(epicsMessageQueueId pmsg) -{ - struct eventNode *evp; - - while ((evp = reinterpret_cast < struct eventNode * > - ( ellGet(&pmsg->eventFreeList) ) ) != NULL) { - freeEventNode(evp); - } - epicsMutexDestroy(pmsg->mutex); - free(pmsg->buf); - free(pmsg); -} - -static struct eventNode * -getEventNode(epicsMessageQueueId pmsg) -{ - struct eventNode *evp; - - evp = reinterpret_cast < struct eventNode * > ( ellGet(&pmsg->eventFreeList) ); - if (evp == NULL) { - evp = (struct eventNode *) calloc(1, sizeof(*evp)); - if (evp) { - evp->event = epicsEventCreate(epicsEventEmpty); - if (evp->event == NULL) { - free(evp); - return NULL; - } - } - } - return evp; -} - -static int -mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, - double timeout) -{ - char *myInPtr, *nextPtr; - struct threadNode *pthr; - - if(size > pmsg->maxMessageSize) - return -1; - - /* - * See if message can be sent - */ - epicsMutexMustLock(pmsg->mutex); - - if ((pmsg->numberOfSendersWaiting > 0) - || (pmsg->full && (ellFirst(&pmsg->receiveQueue) == NULL))) { - /* - * Return if not allowed to wait - */ - if (timeout == 0) { - epicsMutexUnlock(pmsg->mutex); - return -1; - } - - /* - * Wait - */ - struct threadNode threadNode; - threadNode.evp = getEventNode(pmsg); - threadNode.eventSent = false; - if (!threadNode.evp) { - epicsMutexUnlock(pmsg->mutex); - return -1; - } - - ellAdd(&pmsg->sendQueue, &threadNode.link); - pmsg->numberOfSendersWaiting++; - - epicsMutexUnlock(pmsg->mutex); - - epicsEventStatus status; - if (timeout > 0) - status = epicsEventWaitWithTimeout(threadNode.evp->event, timeout); - else - status = epicsEventWait(threadNode.evp->event); - - epicsMutexMustLock(pmsg->mutex); - - if(!threadNode.eventSent) - ellDelete(&pmsg->sendQueue, &threadNode.link); - pmsg->numberOfSendersWaiting--; - - ellAdd(&pmsg->eventFreeList, &threadNode.evp->link); - - if ((pmsg->full && (ellFirst(&pmsg->receiveQueue) == NULL)) || - status != epicsEventOK) { - epicsMutexUnlock(pmsg->mutex); - return -1; - } - } - - /* - * Copy message to waiting receiver - */ - if ((pthr = reinterpret_cast < struct threadNode * > - ( ellGet(&pmsg->receiveQueue) ) ) != NULL) { - if(size <= pthr->size) - memcpy(pthr->buf, message, size); - pthr->size = size; - pthr->eventSent = true; - epicsEventSignal(pthr->evp->event); - epicsMutexUnlock(pmsg->mutex); - return 0; - } - - /* - * Copy to queue - */ - myInPtr = (char *)pmsg->inPtr; - if (myInPtr == pmsg->lastMessageSlot) - nextPtr = pmsg->firstMessageSlot; - else - nextPtr = myInPtr + pmsg->slotSize; - if (nextPtr == (char *)pmsg->outPtr) - pmsg->full = true; - *(volatile unsigned long *)myInPtr = size; - memcpy((unsigned long *)myInPtr + 1, message, size); - pmsg->inPtr = nextPtr; - epicsMutexUnlock(pmsg->mutex); - return 0; -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueueTrySend(epicsMessageQueueId pmsg, void *message, - unsigned int size) -{ - return mySend(pmsg, message, size, 0); -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueueSend(epicsMessageQueueId pmsg, void *message, - unsigned int size) -{ - return mySend(pmsg, message, size, -1); -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueueSendWithTimeout(epicsMessageQueueId pmsg, void *message, - unsigned int size, double timeout) -{ - return mySend(pmsg, message, size, timeout); -} - -static int -myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, - double timeout) -{ - char *myOutPtr; - unsigned long l; - struct threadNode *pthr; - - /* - * If there's a message on the queue, copy it - */ - epicsMutexMustLock(pmsg->mutex); - - myOutPtr = (char *)pmsg->outPtr; - if ((myOutPtr != pmsg->inPtr) || pmsg->full) { - int ret; - l = *(unsigned long *)myOutPtr; - if (l <= size) { - memcpy(message, (unsigned long *)myOutPtr + 1, l); - ret = l; - } - else { - ret = -1; - } - if (myOutPtr == pmsg->lastMessageSlot) - pmsg->outPtr = pmsg->firstMessageSlot; - else - pmsg->outPtr += pmsg->slotSize; - pmsg->full = false; - - /* - * Wake up the oldest task waiting to send - */ - if ((pthr = reinterpret_cast < struct threadNode * > - ( ellGet(&pmsg->sendQueue) ) ) != NULL) { - pthr->eventSent = true; - epicsEventSignal(pthr->evp->event); - } - epicsMutexUnlock(pmsg->mutex); - return ret; - } - - /* - * Return if not allowed to wait - */ - if (timeout == 0) { - epicsMutexUnlock(pmsg->mutex); - return -1; - } - - /* - * Wake up the oldest task waiting to send - */ - if ((pthr = reinterpret_cast < struct threadNode * > - ( ellGet(&pmsg->sendQueue) ) ) != NULL) { - pthr->eventSent = true; - epicsEventSignal(pthr->evp->event); - } - - /* - * Wait for message to arrive - */ - struct threadNode threadNode; - threadNode.evp = getEventNode(pmsg); - threadNode.buf = message; - threadNode.size = size; - threadNode.eventSent = false; - - if (!threadNode.evp) { - epicsMutexUnlock(pmsg->mutex); - return -1; - } - - ellAdd(&pmsg->receiveQueue, &threadNode.link); - epicsMutexUnlock(pmsg->mutex); - - epicsEventStatus status; - if (timeout > 0) - status = epicsEventWaitWithTimeout(threadNode.evp->event, timeout); - else - status = epicsEventWait(threadNode.evp->event); - - epicsMutexMustLock(pmsg->mutex); - - if (!threadNode.eventSent) - ellDelete(&pmsg->receiveQueue, &threadNode.link); - ellAdd(&pmsg->eventFreeList, &threadNode.evp->link); - - epicsMutexUnlock(pmsg->mutex); - - if (threadNode.eventSent && (threadNode.size <= size) && - status == epicsEventOK) - return threadNode.size; - return -1; -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueueTryReceive(epicsMessageQueueId pmsg, void *message, - unsigned int size) -{ - return myReceive(pmsg, message, size, 0); -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueueReceive(epicsMessageQueueId pmsg, void *message, - unsigned int size) -{ - return myReceive(pmsg, message, size, -1); -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueueReceiveWithTimeout(epicsMessageQueueId pmsg, void *message, - unsigned int size, double timeout) -{ - return myReceive(pmsg, message, size, timeout); -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueuePending(epicsMessageQueueId pmsg) -{ - char *myInPtr, *myOutPtr; - int nmsg; - - epicsMutexMustLock(pmsg->mutex); - myInPtr = (char *)pmsg->inPtr; - myOutPtr = (char *)pmsg->outPtr; - if (pmsg->full) - nmsg = pmsg->capacity; - else if (myInPtr >= myOutPtr) - nmsg = (myInPtr - myOutPtr) / pmsg->slotSize; - else - nmsg = pmsg->capacity - (myOutPtr - myInPtr) / pmsg->slotSize; - epicsMutexUnlock(pmsg->mutex); - return nmsg; -} - -epicsShareFunc void epicsShareAPI -epicsMessageQueueShow(epicsMessageQueueId pmsg, int level) -{ - printf("Message Queue Used:%d Slots:%lu", epicsMessageQueuePending(pmsg), pmsg->capacity); - if (level >= 1) - printf(" Maximum size:%lu", pmsg->maxMessageSize); - printf("\n"); -} diff --git a/src/libCom/osi/os/default/osdMessageQueue.h b/src/libCom/osi/os/default/osdMessageQueue.h deleted file mode 100644 index dabf6a71e..000000000 --- a/src/libCom/osi/os/default/osdMessageQueue.h +++ /dev/null @@ -1,3 +0,0 @@ -/* - * Nothing needed for default implementation - */ diff --git a/src/libCom/osi/os/default/osdNetIntf.c b/src/libCom/osi/os/default/osdNetIntf.c deleted file mode 100644 index 62247bc5d..000000000 --- a/src/libCom/osi/os/default/osdNetIntf.c +++ /dev/null @@ -1,352 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - * Date: 04-05-94 - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "epicsAssert.h" -#include "errlog.h" -#include "epicsThread.h" - -#ifdef DEBUG -# define ifDepenDebugPrintf(argsInParen) printf argsInParen -#else -# define ifDepenDebugPrintf(argsInParen) -#endif - -static osiSockAddr osiLocalAddrResult; -static epicsThreadOnceId osiLocalAddrId = EPICS_THREAD_ONCE_INIT; - -/* - * Determine the size of an ifreq structure - * Made difficult by the fact that addresses larger than the structure - * size may be returned from the kernel. - */ -static size_t ifreqSize ( struct ifreq *pifreq ) -{ - size_t size; - - size = ifreq_size ( pifreq ); - if ( size < sizeof ( *pifreq ) ) { - size = sizeof ( *pifreq ); - } - return size; -} - -/* - * Move to the next ifreq structure - */ -static struct ifreq * ifreqNext ( struct ifreq *pifreq ) -{ - struct ifreq *ifr; - - ifr = ( struct ifreq * )( ifreqSize (pifreq) + ( char * ) pifreq ); - ifDepenDebugPrintf( ("ifreqNext() pifreq %p, size 0x%x, ifr 0x%p\n", pifreq, (unsigned)ifreqSize (pifreq), ifr) ); - return ifr; -} - - -/* - * osiSockDiscoverBroadcastAddresses () - */ -epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses - (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr) -{ - static const unsigned nelem = 100; - int status; - struct ifconf ifconf; - struct ifreq *pIfreqList; - struct ifreq *pIfreqListEnd; - struct ifreq *pifreq; - struct ifreq *pnextifreq; - osiSockAddrNode *pNewNode; - - if ( pMatchAddr->sa.sa_family == AF_INET ) { - if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) { - pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) ); - if ( pNewNode == NULL ) { - errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" ); - return; - } - pNewNode->addr.ia.sin_family = AF_INET; - pNewNode->addr.ia.sin_port = htons ( 0 ); - pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - ellAdd ( pList, &pNewNode->node ); - return; - } - } - - /* - * use pool so that we avoid using too much stack space - * - * nelem is set to the maximum interfaces - * on one machine here - */ - pIfreqList = (struct ifreq *) calloc ( nelem, sizeof(*pifreq) ); - if (!pIfreqList) { - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): no memory to complete request\n"); - return; - } - - ifconf.ifc_len = nelem * sizeof(*pifreq); - ifconf.ifc_req = pIfreqList; - status = socket_ioctl (socket, SIOCGIFCONF, &ifconf); - if (status < 0 || ifconf.ifc_len == 0) { - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): unable to fetch network interface configuration (%d)\n", status); - free (pIfreqList); - return; - } - - pIfreqListEnd = (struct ifreq *) (ifconf.ifc_len + (char *) pIfreqList); - pIfreqListEnd--; - - for ( pifreq = pIfreqList; pifreq <= pIfreqListEnd; pifreq = pnextifreq ) { - uint32_t current_ifreqsize; - - /* - * find the next ifreq - */ - pnextifreq = ifreqNext (pifreq); - - /* determine ifreq size */ - current_ifreqsize = ifreqSize ( pifreq ); - /* copy current ifreq to aligned bufferspace (to start of pIfreqList buffer) */ - memmove(pIfreqList, pifreq, current_ifreqsize); - - ifDepenDebugPrintf (("osiSockDiscoverBroadcastAddresses(): found IFACE: %s len: 0x%x current_ifreqsize: 0x%x \n", - pIfreqList->ifr_name, - (unsigned)ifreq_size(pifreq), - (unsigned)current_ifreqsize)); - - /* - * If its not an internet interface then dont use it - */ - if ( pIfreqList->ifr_addr.sa_family != AF_INET ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): interface \"%s\" was not AF_INET\n", pIfreqList->ifr_name) ); - continue; - } - - /* - * if it isnt a wildcarded interface then look for - * an exact match - */ - if ( pMatchAddr->sa.sa_family != AF_UNSPEC ) { - if ( pMatchAddr->sa.sa_family != AF_INET ) { - continue; - } - if ( pMatchAddr->ia.sin_addr.s_addr != htonl (INADDR_ANY) ) { - struct sockaddr_in *pInetAddr = (struct sockaddr_in *) &pIfreqList->ifr_addr; - if ( pInetAddr->sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" didnt match\n", pIfreqList->ifr_name) ); - continue; - } - } - } - - status = socket_ioctl ( socket, SIOCGIFFLAGS, pIfreqList ); - if ( status ) { - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf flags fetch for \"%s\" failed\n", pIfreqList->ifr_name); - continue; - } - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" flags: %x\n", pIfreqList->ifr_name, pIfreqList->ifr_flags) ); - - /* - * dont bother with interfaces that have been disabled - */ - if ( ! ( pIfreqList->ifr_flags & IFF_UP ) ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" was down\n", pIfreqList->ifr_name) ); - continue; - } - - /* - * dont use the loop back interface - */ - if ( pIfreqList->ifr_flags & IFF_LOOPBACK ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): ignoring loopback interface: \"%s\"\n", pIfreqList->ifr_name) ); - continue; - } - - pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) ); - if ( pNewNode == NULL ) { - errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" ); - free ( pIfreqList ); - return; - } - - /* - * If this is an interface that supports - * broadcast fetch the broadcast address. - * - * Otherwise if this is a point to point - * interface then use the destination address. - * - * Otherwise CA will not query through the - * interface. - */ - if ( pIfreqList->ifr_flags & IFF_BROADCAST ) { - osiSockAddr baddr; - status = socket_ioctl (socket, SIOCGIFBRDADDR, pIfreqList); - if ( status ) { - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": bcast addr fetch fail\n", pIfreqList->ifr_name); - free ( pNewNode ); - continue; - } - baddr.sa = pIfreqList->ifr_broadaddr; - if (baddr.ia.sin_family==AF_INET && baddr.ia.sin_addr.s_addr != INADDR_ANY) { - pNewNode->addr.sa = pIfreqList->ifr_broadaddr; - ifDepenDebugPrintf ( ( "found broadcast addr = %x\n", ntohl ( baddr.ia.sin_addr.s_addr ) ) ); - } else { - ifDepenDebugPrintf ( ( "Ignoring broadcast addr = \n", ntohl ( baddr.ia.sin_addr.s_addr ) ) ); - free ( pNewNode ); - continue; - } - } -#if defined (IFF_POINTOPOINT) - else if ( pIfreqList->ifr_flags & IFF_POINTOPOINT ) { - status = socket_ioctl ( socket, SIOCGIFDSTADDR, pIfreqList); - if ( status ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": pt to pt addr fetch fail\n", pIfreqList->ifr_name) ); - free ( pNewNode ); - continue; - } - pNewNode->addr.sa = pIfreqList->ifr_dstaddr; - } -#endif - else { - ifDepenDebugPrintf ( ( "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": not point to point or bcast?\n", pIfreqList->ifr_name ) ); - free ( pNewNode ); - continue; - } - - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" found\n", pIfreqList->ifr_name) ); - - /* - * LOCK applied externally - */ - ellAdd ( pList, &pNewNode->node ); - } - - free ( pIfreqList ); -} - -/* - * osiLocalAddr () - */ -static void osiLocalAddrOnce (void *raw) -{ - SOCKET *psocket = raw; - const unsigned nelem = 100; - osiSockAddr addr; - int status; - struct ifconf ifconf; - struct ifreq *pIfreqList; - struct ifreq *pifreq; - struct ifreq *pIfreqListEnd; - struct ifreq *pnextifreq; - - memset ( (void *) &addr, '\0', sizeof ( addr ) ); - addr.sa.sa_family = AF_UNSPEC; - - pIfreqList = (struct ifreq *) calloc ( nelem, sizeof(*pIfreqList) ); - if ( ! pIfreqList ) { - errlogPrintf ( "osiLocalAddr(): no memory to complete request\n" ); - goto fail; - } - - ifconf.ifc_len = nelem * sizeof ( *pIfreqList ); - ifconf.ifc_req = pIfreqList; - status = socket_ioctl ( *psocket, SIOCGIFCONF, &ifconf ); - if ( status < 0 || ifconf.ifc_len == 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( - "osiLocalAddr(): SIOCGIFCONF ioctl failed because \"%s\"\n", - sockErrBuf ); - goto fail; - } - - pIfreqListEnd = (struct ifreq *) ( ifconf.ifc_len + (char *) ifconf.ifc_req ); - pIfreqListEnd--; - - for ( pifreq = ifconf.ifc_req; pifreq <= pIfreqListEnd; pifreq = pnextifreq ) { - osiSockAddr addrCpy; - uint32_t current_ifreqsize; - - /* - * find the next if req - */ - pnextifreq = ifreqNext ( pifreq ); - - /* determine ifreq size */ - current_ifreqsize = ifreqSize ( pifreq ); - /* copy current ifreq to aligned bufferspace (to start of pIfreqList buffer) */ - memmove(pIfreqList, pifreq, current_ifreqsize); - - if ( pIfreqList->ifr_addr.sa_family != AF_INET ) { - ifDepenDebugPrintf ( ("osiLocalAddr(): interface %s was not AF_INET\n", pIfreqList->ifr_name) ); - continue; - } - - addrCpy.sa = pIfreqList->ifr_addr; - - status = socket_ioctl ( *psocket, SIOCGIFFLAGS, pIfreqList ); - if ( status < 0 ) { - errlogPrintf ( "osiLocalAddr(): net intf flags fetch for %s failed\n", pIfreqList->ifr_name ); - continue; - } - - if ( ! ( pIfreqList->ifr_flags & IFF_UP ) ) { - ifDepenDebugPrintf ( ("osiLocalAddr(): net intf %s was down\n", pIfreqList->ifr_name) ); - continue; - } - - /* - * dont use the loop back interface - */ - if ( pIfreqList->ifr_flags & IFF_LOOPBACK ) { - ifDepenDebugPrintf ( ("osiLocalAddr(): ignoring loopback interface: %s\n", pIfreqList->ifr_name) ); - continue; - } - - ifDepenDebugPrintf ( ("osiLocalAddr(): net intf %s found\n", pIfreqList->ifr_name) ); - - osiLocalAddrResult = addrCpy; - free ( pIfreqList ); - return; - } - - errlogPrintf ( - "osiLocalAddr(): only loopback found\n"); -fail: - /* fallback to loopback */ - memset ( (void *) &addr, '\0', sizeof ( addr ) ); - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - osiLocalAddrResult = addr; - - free ( pIfreqList ); -} - - -epicsShareFunc osiSockAddr epicsShareAPI osiLocalAddr (SOCKET socket) -{ - epicsThreadOnce(&osiLocalAddrId, osiLocalAddrOnce, &socket); - return osiLocalAddrResult; -} diff --git a/src/libCom/osi/os/default/osdPoolStatus.c b/src/libCom/osi/os/default/osdPoolStatus.c deleted file mode 100644 index bb764b2ad..000000000 --- a/src/libCom/osi/os/default/osdPoolStatus.c +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "osiPoolStatus.h" - -/* - * osiSufficentSpaceInPool () - * - * @@@@@ not implemented @@@@@ - * - */ -epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize ) -{ - return 1; -} diff --git a/src/libCom/osi/os/default/osdPoolStatus.h b/src/libCom/osi/os/default/osdPoolStatus.h deleted file mode 100644 index efb2cfab8..000000000 --- a/src/libCom/osi/os/default/osdPoolStatus.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef osdPoolStatush -#define osdPoolStatush - -#endif /* osdPoolStatush */ diff --git a/src/libCom/osi/os/default/osdSignal.cpp b/src/libCom/osi/os/default/osdSignal.cpp deleted file mode 100644 index 08dfa023c..000000000 --- a/src/libCom/osi/os/default/osdSignal.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2002 The University of Chicago, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE Versions 3.13.7 - * and higher are distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "epicsSignal.h" - -/* - * All NOOPs if the os isnt POSIX - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm ( struct epicsThreadOSD * /* threadId */ ) {} - diff --git a/src/libCom/osi/os/default/osdSpin.c b/src/libCom/osi/os/default/osdSpin.c deleted file mode 100644 index 6e9acb158..000000000 --- a/src/libCom/osi/os/default/osdSpin.c +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "errlog.h" -#include "epicsMutex.h" -#include "epicsSpin.h" - -/* - * Default: EPICS MUTEX IMPLEMENTATION - */ - -typedef struct epicsSpin { - epicsMutexId lock; -} epicsSpin; - -epicsSpinId epicsSpinCreate(void) { - epicsSpin *spin; - - spin = calloc(1, sizeof(*spin)); - if (!spin) - goto fail; - - spin->lock = epicsMutexCreate(); - if (!spin->lock) - goto fail; - - return spin; - -fail: - free(spin); - return NULL; -} - -epicsSpinId epicsSpinMustCreate(void) -{ - epicsSpinId ret = epicsSpinCreate(); - if(!ret) - cantProceed("epicsSpinMustCreate: epicsSpinCreate failed."); - return ret; -} - -void epicsSpinDestroy(epicsSpinId spin) { - epicsMutexDestroy(spin->lock); - free(spin); -} - -void epicsSpinLock(epicsSpinId spin) { - epicsMutexLockStatus status; - - status = epicsMutexLock(spin->lock); - if (status != epicsMutexLockOK) { - errlogPrintf("epicsSpinLock(%p): epicsMutexLock returned %s\n", spin, - status == epicsMutexLockTimeout ? - "epicsMutexLockTimeout" : "epicsMutexLockError"); - } -} - -int epicsSpinTryLock(epicsSpinId spin) { - epicsMutexLockStatus status; - - status = epicsMutexTryLock(spin->lock); - if (status == epicsMutexLockOK) return 0; - if (status == epicsMutexLockTimeout) return 1; - - errlogPrintf("epicsSpinTryLock(%p): epicsMutexTryLock returned epicsMutexLockError\n", spin); - return 2; -} - -void epicsSpinUnlock(epicsSpinId spin) { - epicsMutexUnlock(spin->lock); -} diff --git a/src/libCom/osi/os/default/osdThreadExtra.c b/src/libCom/osi/os/default/osdThreadExtra.c deleted file mode 100644 index 0a7c7ae95..000000000 --- a/src/libCom/osi/os/default/osdThreadExtra.c +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 ITER Organization -* -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Ralph Lange Date: 26 Jun 2012 */ - -/* Null default thread hooks for all platforms that do not do anything special */ - -#define epicsExportSharedSymbols -#include "epicsThread.h" - -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault; -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain; diff --git a/src/libCom/osi/os/default/osdThreadHooks.c b/src/libCom/osi/os/default/osdThreadHooks.c deleted file mode 100644 index cbe28a4ff..000000000 --- a/src/libCom/osi/os/default/osdThreadHooks.c +++ /dev/null @@ -1,140 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 ITER Organization -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Authors: Ralph Lange & Andrew Johnson */ - -/* Secure hooks for epicsThread */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "ellLib.h" -#include "epicsMutex.h" -#include "epicsThread.h" - -epicsShareExtern EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault; -epicsShareExtern EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain; - -typedef struct epicsThreadHook { - ELLNODE node; - EPICS_THREAD_HOOK_ROUTINE func; -} epicsThreadHook; - -static ELLLIST hookList = ELLLIST_INIT; -static epicsMutexId hookLock; - - -static void threadHookOnce(void *arg) -{ - hookLock = epicsMutexMustCreate(); - - if (epicsThreadHookDefault) { - static epicsThreadHook defHook = {ELLNODE_INIT, NULL}; - - defHook.func = epicsThreadHookDefault; - ellAdd(&hookList, &defHook.node); - } -} - -static void threadHookInit(void) -{ - static epicsThreadOnceId flag = EPICS_THREAD_ONCE_INIT; - - epicsThreadOnce(&flag, threadHookOnce, NULL); -} - -epicsShareFunc int epicsThreadHookAdd(EPICS_THREAD_HOOK_ROUTINE hook) -{ - epicsThreadHook *pHook; - - if (!hook) return 0; - threadHookInit(); - - pHook = calloc(1, sizeof(epicsThreadHook)); - if (!pHook) { - fprintf(stderr, "epicsThreadHookAdd: calloc failed\n"); - return -1; - } - pHook->func = hook; - - if (epicsMutexLock(hookLock) == epicsMutexLockOK) { - ellAdd(&hookList, &pHook->node); - epicsMutexUnlock(hookLock); - return 0; - } - fprintf(stderr, "epicsThreadHookAdd: Locking problem\n"); - return -1; -} - -epicsShareFunc int epicsThreadHookDelete(EPICS_THREAD_HOOK_ROUTINE hook) -{ - if (!hook) return 0; - threadHookInit(); - - if (epicsMutexLock(hookLock) == epicsMutexLockOK) { - epicsThreadHook *pHook = (epicsThreadHook *) ellFirst(&hookList); - - while (pHook) { - if (hook == pHook->func) { - ellDelete(&hookList, &pHook->node); - break; - } - pHook = (epicsThreadHook *) ellNext(&pHook->node); - } - epicsMutexUnlock(hookLock); - return 0; - } - fprintf(stderr, "epicsThreadHookAdd: Locking problem\n"); - return -1; -} - -epicsShareFunc void osdThreadHooksRunMain(epicsThreadId id) -{ - if (epicsThreadHookMain) - epicsThreadHookMain(id); -} - -epicsShareFunc void osdThreadHooksRun(epicsThreadId id) -{ - threadHookInit(); - - if (epicsMutexLock(hookLock) == epicsMutexLockOK) { - epicsThreadHook *pHook = (epicsThreadHook *) ellFirst(&hookList); - - while (pHook) { - pHook->func(id); - pHook = (epicsThreadHook *) ellNext(&pHook->node); - } - epicsMutexUnlock(hookLock); - } - else { - fprintf(stderr, "osdThreadHooksRun: Locking problem\n"); - } -} - -epicsShareFunc void epicsThreadHooksShow(void) -{ - threadHookInit(); - - if (epicsMutexLock(hookLock) == epicsMutexLockOK) { - epicsThreadHook *pHook = (epicsThreadHook *) ellFirst(&hookList); - - while (pHook) { - printf(" %p\n", pHook->func); - pHook = (epicsThreadHook *) ellNext(&pHook->node); - } - epicsMutexUnlock(hookLock); - } - else { - fprintf(stderr, "epicsThreadHooksShow: Locking problem\n"); - } -} diff --git a/src/libCom/osi/os/default/osdVME.h b/src/libCom/osi/os/default/osdVME.h deleted file mode 100644 index 1b65b3184..000000000 --- a/src/libCom/osi/os/default/osdVME.h +++ /dev/null @@ -1,13 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * OS-dependent VME support - */ diff --git a/src/libCom/osi/os/default/osdWireConfig.h b/src/libCom/osi/os/default/osdWireConfig.h deleted file mode 100644 index e8def865e..000000000 --- a/src/libCom/osi/os/default/osdWireConfig.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Default version of osdWireConfig.h that might - * work on UNIX like systems that define - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef osdWireConfig_h -#define osdWireConfig_h - -/* This file must be usable from both C and C++ */ - -/* if compilation fails because this wasnt found then you may need to define an OS - specific osdWireConfig.h */ -#include - -#ifdef __BYTE_ORDER -# if __BYTE_ORDER == __LITTLE_ENDIAN -# define EPICS_BYTE_ORDER EPICS_ENDIAN_LITTLE -# elif __BYTE_ORDER == __BIG_ENDIAN -# define EPICS_BYTE_ORDER EPICS_ENDIAN_BIG -# else -# error EPICS hasnt been ported to run on the specified __BYTE_ORDER -# endif -#else -# ifdef BYTE_ORDER -# if BYTE_ORDER == LITTLE_ENDIAN -# define EPICS_BYTE_ORDER EPICS_ENDIAN_LITTLE -# elif BYTE_ORDER == BIG_ENDIAN -# define EPICS_BYTE_ORDER EPICS_ENDIAN_BIG -# else -# error EPICS hasnt been ported to run on the specified BYTE_ORDER -# endif -# else -# error doesnt specify __BYTE_ORDER or BYTE_ORDER - is an OS specific osdWireConfig.h needed? -# endif -#endif - -#ifdef __FLOAT_WORD_ORDER -# if __FLOAT_WORD_ORDER == __LITTLE_ENDIAN -# define EPICS_FLOAT_WORD_ORDER EPICS_ENDIAN_LITTLE -# elif __FLOAT_WORD_ORDER == __BIG_ENDIAN -# define EPICS_FLOAT_WORD_ORDER EPICS_ENDIAN_BIG -# else -# error EPICS hasnt been ported to specified __FLOAT_WORD_ORDER -# endif -#else -# ifdef FLOAT_WORD_ORDER -# if FLOAT_WORD_ORDER == LITTLE_ENDIAN -# define EPICS_FLOAT_WORD_ORDER EPICS_ENDIAN_LITTLE -# elif FLOAT_WORD_ORDER == BIG_ENDIAN -# define EPICS_FLOAT_WORD_ORDER EPICS_ENDIAN_BIG -# else -# error EPICS hasnt been ported to specified FLOAT_WORD_ORDER -# endif -# else - /* assume that if neither __FLOAT_WORD_ORDER nor FLOAT_WORD_ORDER are - defined then weird fp ordered archs like arm nwfp aren't supported */ -# define EPICS_FLOAT_WORD_ORDER EPICS_BYTE_ORDER -# endif -#endif - -#endif /* ifdef osdWireConfig_h */ diff --git a/src/libCom/osi/os/default/osdWireFormat.h b/src/libCom/osi/os/default/osdWireFormat.h deleted file mode 100644 index 385c9bd69..000000000 --- a/src/libCom/osi/os/default/osdWireFormat.h +++ /dev/null @@ -1,240 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef osdWireFormat -#define osdWireFormat - -#ifdef __SUNPRO_CC -# include -#else -# include -#endif - -#include "epicsEndian.h" - -// -// The default assumption is that the local floating point format is -// IEEE and that these routines only need to perform byte swapping -// as a side effect of copying an aligned operand into an unaligned -// network byte stream. OS specific code can provide a alternative -// for this file if that assumption is wrong. -// - -// -// EPICS_CONVERSION_REQUIRED is set if either the byte order -// or the floating point word order are not exactly big endian. -// This can be set by hand above for a specific architecture -// should there be an architecture that is a weird middle endian -// ieee floating point format that is also big endian integer. -// -#if EPICS_BYTE_ORDER != EPICS_ENDIAN_BIG || EPICS_FLOAT_WORD_ORDER != EPICS_BYTE_ORDER -# if ! defined ( EPICS_CONVERSION_REQUIRED ) -# define EPICS_CONVERSION_REQUIRED -# endif -#endif - -// -// We still use a big endian wire format for CA consistent with the internet, -// but inconsistent with the vast majority of CPUs -// - -template <> -inline void WireGet < epicsFloat64 > ( - const epicsUInt8 * pWireSrc, epicsFloat64 & dst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - union { - epicsFloat64 _f; - epicsUInt32 _u[2]; - } tmp; -# if EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE - WireGet ( pWireSrc, tmp._u[1] ); - WireGet ( pWireSrc + 4, tmp._u[0] ); -# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG - WireGet ( pWireSrc, tmp._u[0] ); - WireGet ( pWireSrc + 4, tmp._u[1] ); -# else -# error unsupported floating point word order -# endif - dst = tmp._f; -} - -#if defined ( __GNUC__ ) && ( __GNUC__ == 4 && __GNUC_MINOR__ <= 0 ) -template <> -inline void WireGet < epicsOldString > ( - const epicsUInt8 * pWireSrc, epicsOldString & dst ) -{ - memcpy ( dst, pWireSrc, sizeof ( dst ) ); -} -#else -inline void WireGet ( - const epicsUInt8 * pWireSrc, epicsOldString & dst ) -{ - memcpy ( dst, pWireSrc, sizeof ( dst ) ); -} -#endif - -template <> -inline void WireSet < epicsFloat64 > ( - const epicsFloat64 & src, epicsUInt8 * pWireDst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - union { - epicsFloat64 _f; - epicsUInt32 _u[2]; - } tmp; - tmp._f = src; -# if EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE - WireSet ( tmp._u[1], pWireDst ); - WireSet ( tmp._u[0], pWireDst + 4 ); -# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG - WireSet ( tmp._u[0], pWireDst ); - WireSet ( tmp._u[1], pWireDst + 4 ); -# else -# error unsupported floating point word order -# endif -} - -#if defined ( __GNUC__ ) && ( __GNUC__ == 4 && __GNUC_MINOR__ <= 0 ) -template <> -inline void WireSet < epicsOldString > ( - const epicsOldString & src, epicsUInt8 * pWireDst ) -{ - memcpy ( pWireDst, src, sizeof ( src ) ); -} -#else -inline void WireSet ( - const epicsOldString & src, epicsUInt8 * pWireDst ) -{ - memcpy ( pWireDst, src, sizeof ( src ) ); -} -#endif - -template <> -inline void AlignedWireGet < epicsUInt16 > ( - const epicsUInt16 & src, epicsUInt16 & dst ) -{ -# if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE - dst = byteSwap ( src ); -# elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG - dst = src; -# else -# error unsupported endian type -# endif -} - -template <> -inline void AlignedWireGet < epicsUInt32 > ( - const epicsUInt32 & src, epicsUInt32 & dst ) -{ -# if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE - dst = byteSwap ( src ); -# elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG - dst = src; -# else -# error unsupported endian type -# endif -} - -template <> -inline void AlignedWireGet < epicsFloat64 > ( - const epicsFloat64 & src, epicsFloat64 & dst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - union Swapper { - epicsUInt32 _u[2]; - epicsFloat64 _f; - }; -# if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG && EPICS_FLOAT_WORD_ORDER == EPICS_BYTE_ORDER - dst = src; -# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG - Swapper tmp; - tmp._f = src; - AlignedWireGet ( tmp._u[0], tmp._u[0] ); - AlignedWireGet ( tmp._u[1], tmp._u[1] ); - dst = tmp._f; -# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE - Swapper srcu, dstu; - srcu._f = src; - AlignedWireGet ( srcu._u[1], dstu._u[0] ); - AlignedWireGet ( srcu._u[0], dstu._u[1] ); - dst = dstu._f; -# else -# error unsupported floating point word order -# endif -} - -template <> -inline void AlignedWireSet < epicsUInt16 > - ( const epicsUInt16 & src, epicsUInt16 & dst ) -{ -# if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE - dst = byteSwap ( src ); -# elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG - dst = src; -# else -# error undefined endian type -# endif -} - -template <> -inline void AlignedWireSet < epicsUInt32 > ( - const epicsUInt32 & src, epicsUInt32 & dst ) -{ -# if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE - dst = byteSwap ( src ); -# elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG - dst = src; -# else -# error undefined endian type -# endif -} - -template <> -inline void AlignedWireSet < epicsFloat64 > ( - const epicsFloat64 & src, epicsFloat64 & dst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - union Swapper { - epicsUInt32 _u[2]; - epicsFloat64 _f; - }; -# if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG && EPICS_FLOAT_WORD_ORDER == EPICS_BYTE_ORDER - dst = src; -# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG - Swapper tmp; - tmp._f = src; - AlignedWireSet ( tmp._u[0], tmp._u[0] ); - AlignedWireSet ( tmp._u[1], tmp._u[1] ); - dst = tmp._f; -# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE - Swapper srcu, dstu; - srcu._f = src; - AlignedWireSet ( srcu._u[1], dstu._u[0] ); - AlignedWireSet ( srcu._u[0], dstu._u[1] ); - dst = dstu._f; -# else -# error unsupported floating point word order -# endif -} - -#endif // osdWireFormat diff --git a/src/libCom/osi/os/freebsd/osdSock.h b/src/libCom/osi/os/freebsd/osdSock.h deleted file mode 100644 index fe28d4cd5..000000000 --- a/src/libCom/osi/os/freebsd/osdSock.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -#ifndef IPPORT_USERRESERVED -#define IPPORT_USERRESERVED 5000 -#endif - - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; -typedef socklen_t osiSocklen_t; - -#define FD_IN_FDSET(FD) ((FD)ifr_addr.sa_len + sizeof(pifreq->ifr_name)) -#else -# define ifreq_size(pifreq) sizeof(*pifreq) -#endif - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/freebsd/osdTime.h b/src/libCom/osi/os/freebsd/osdTime.h deleted file mode 100644 index 941426c72..000000000 --- a/src/libCom/osi/os/freebsd/osdTime.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Eric Norum - */ - -#ifndef osdTimeh -#define osdTimeh - -/* - * We need this include file since the POSIX version - * causes `struct timespec' to be defined in more than one place. - */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void epicsShareAPI - convertDoubleToWakeTime(double timeout,struct timespec *wakeTime); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ifndef osdTimeh */ - diff --git a/src/libCom/osi/os/freebsd/osiFileName.h b/src/libCom/osi/os/freebsd/osiFileName.h deleted file mode 100644 index 83204c70f..000000000 --- a/src/libCom/osi/os/freebsd/osiFileName.h +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * osiFileName.h - * Author: Jeff Hill - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/freebsd/osiUnistd.h b/src/libCom/osi/os/freebsd/osiUnistd.h deleted file mode 100644 index c64e57a6c..000000000 --- a/src/libCom/osi/os/freebsd/osiUnistd.h +++ /dev/null @@ -1,22 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include - -/* - * Some systems fail to provide prototypes of these functions. - * Others provide different prototypes. - * There seems to be no way to handle this automatically, so - * if you get compile errors, just make the appropriate changes here. - */ diff --git a/src/libCom/osi/os/iOS/epicsMath.h b/src/libCom/osi/os/iOS/epicsMath.h deleted file mode 100644 index 493583f70..000000000 --- a/src/libCom/osi/os/iOS/epicsMath.h +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsMathh -#define epicsMathh - -#include -#include - -#define finite(x) isfinite(x) - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* epicsMathh */ diff --git a/src/libCom/osi/os/iOS/osdEnv.c b/src/libCom/osi/os/iOS/osdEnv.c deleted file mode 100644 index a32cce5ef..000000000 --- a/src/libCom/osi/os/iOS/osdEnv.c +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* osdEnv.c */ -/* - * Author: Eric Norum - * Date: May 7, 2001 - * - * Routines to modify/display environment variables and EPICS parameters - */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include -#include -#include -#include -#include "epicsFindSymbol.h" -#include - -/* - * Set the value of an environment variable - */ -epicsShareFunc void epicsShareAPI epicsEnvSet (const char *name, const char *value) -{ - iocshEnvClear(name); - setenv(name, value, 1); -} - -/* - * Show the value of the specified, or all, environment variables - */ -epicsShareFunc void epicsShareAPI epicsEnvShow (const char *name) -{ - if (name == NULL) { - extern char **environ; - char **sp; - - for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++) - printf ("%s\n", *sp); - } - else { - const char *cp = getenv (name); - if (cp == NULL) - printf ("%s is not an environment variable.\n", name); - else - printf ("%s=%s\n", name, cp); - } -} diff --git a/src/libCom/osi/os/iOS/osdSock.h b/src/libCom/osi/os/iOS/osdSock.h deleted file mode 100644 index 0b3b3f6c1..000000000 --- a/src/libCom/osi/os/iOS/osdSock.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Eric Norum - */ - -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; -typedef socklen_t osiSocklen_t; - -#define FD_IN_FDSET(FD) ((FD)ifr_addr.sa_len + sizeof((pifreq)->ifr_name)) - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/iOS/osdSockAddrReuse.cpp b/src/libCom/osi/os/iOS/osdSockAddrReuse.cpp deleted file mode 100644 index 9f64e331a..000000000 --- a/src/libCom/osi/os/iOS/osdSockAddrReuse.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" - -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEADDR?\n"); - } -} - -/* - * SO_REUSEPORT is not in POSIX - */ -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEPORT, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEPORT?\n"); - } -} diff --git a/src/libCom/osi/os/iOS/osdTime.h b/src/libCom/osi/os/iOS/osdTime.h deleted file mode 100644 index 953ec31b8..000000000 --- a/src/libCom/osi/os/iOS/osdTime.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Eric Norum - */ - -#ifndef osdTimeh -#define osdTimeh - -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void convertDoubleToWakeTime(double timeout, - struct timespec *wakeTime); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ifndef osdTimeh */ - diff --git a/src/libCom/osi/os/iOS/osiFileName.h b/src/libCom/osi/os/iOS/osiFileName.h deleted file mode 100644 index f7dd62878..000000000 --- a/src/libCom/osi/os/iOS/osiFileName.h +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Eric Norum - */ - -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/posix/README b/src/libCom/osi/os/posix/README deleted file mode 100644 index 59f3d9524..000000000 --- a/src/libCom/osi/os/posix/README +++ /dev/null @@ -1,13 +0,0 @@ -A knowledge of pthreads is necessary to understand osdThread.c and osdSem.c. - -The following are good references - -Programming with POSIX Threads, David R. Butenhof, Addison-weslet, 1997 - -Multithreaded Programming with Pthreads, Bil Lewis & Daniel J. Berg, -Sun Microsystems, 1998 - -Pthreads Programming, Bradford Nichols etc, O'Reilly & Associates, 1996 - -The implementation of semMutex is based on the example code by Bil Leeis -that os available via the WWW. diff --git a/src/libCom/osi/os/posix/epicsAtomicOSD.cpp b/src/libCom/osi/os/posix/epicsAtomicOSD.cpp deleted file mode 100644 index 1cc227fcd..000000000 --- a/src/libCom/osi/os/posix/epicsAtomicOSD.cpp +++ /dev/null @@ -1,74 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - * johill@lanl.gov - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "epicsAtomic.h" - -/* - * Slow, but probably correct on all systems. - * Useful only if something more efficient isn`t - * provided based on knowledge of the compiler - * or OS - * - * A statically initialized pthread mutex doesn`t - * need to be destroyed - * - * !!!!! - * !!!!! WARNING - * !!!!! - * !!!!! Do not use this implementation on systems where - * !!!!! code runs at interrupt context. If so, then - * !!!!! an implementation must be provided that is based - * !!!!! on a compiler intrinsic or an interrupt lock and or - * !!!!! a spin lock primitive - * !!!!! - */ -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - -void epicsAtomicLock ( EpicsAtomicLockKey * ) -{ - unsigned countDown = 1000u; - int status; - while ( true ) { - status = pthread_mutex_lock ( & mutex ); - if ( status == 0 ) return; - assert ( status == EINTR ); - static const useconds_t retryDelayUSec = 100000; - usleep ( retryDelayUSec ); - countDown--; - assert ( countDown ); - } -} - -void epicsAtomicUnlock ( EpicsAtomicLockKey * ) -{ - const int status = pthread_mutex_unlock ( & mutex ); - assert ( status == 0 ); -} - - -// Slow, but probably correct on all systems. -// Useful only if something more efficient isn`t -// provided based on knowledge of the compiler -// or OS -void epicsAtomicMemoryBarrierFallback (void) -{ - EpicsAtomicLockKey key; - epicsAtomicLock ( & key ); - epicsAtomicUnlock ( & key ); -} diff --git a/src/libCom/osi/os/posix/epicsAtomicOSD.h b/src/libCom/osi/os/posix/epicsAtomicOSD.h deleted file mode 100644 index 892d2dcb5..000000000 --- a/src/libCom/osi/os/posix/epicsAtomicOSD.h +++ /dev/null @@ -1,54 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicOSD_h -#define epicsAtomicOSD_h - -#include - -#define EPICS_ATOMIC_OS_NAME "POSIX" - -typedef struct EpicsAtomicLockKey {} EpicsAtomicLockKey; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void epicsAtomicLock ( struct EpicsAtomicLockKey * ); -epicsShareFunc void epicsAtomicUnlock ( struct EpicsAtomicLockKey * ); -epicsShareFunc void epicsAtomicMemoryBarrierFallback ( void ); - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - epicsAtomicMemoryBarrierFallback(); -} -#endif - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - epicsAtomicMemoryBarrierFallback(); -} -#endif - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#include "epicsAtomicDefault.h" - -#endif /* epicsAtomicOSD_h */ - diff --git a/src/libCom/osi/os/posix/epicsMath.h b/src/libCom/osi/os/posix/epicsMath.h deleted file mode 100644 index 4e558676c..000000000 --- a/src/libCom/osi/os/posix/epicsMath.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsMathh -#define epicsMathh - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef isfinite -# undef finite -# define finite(x) isfinite((double)(x)) -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* epicsMathh */ diff --git a/src/libCom/osi/os/posix/epicsTempFile.cpp b/src/libCom/osi/os/posix/epicsTempFile.cpp deleted file mode 100644 index 19b5fb4bc..000000000 --- a/src/libCom/osi/os/posix/epicsTempFile.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#define epicsExportSharedSymbols -#include "epicsTempFile.h" - -extern "C" -epicsShareFunc void epicsShareAPI epicsTempName ( - char * pNameBuf, size_t nameBufLength ) -{ - if ( nameBufLength ) { - pNameBuf[0] = '\0'; - char nameBuf[L_tmpnam]; - if ( tmpnam ( nameBuf ) ) { - if ( nameBufLength > strlen ( nameBuf ) ) { - strncpy ( pNameBuf, nameBuf, nameBufLength ); - } - } - } -} - - -extern "C" -epicsShareFunc FILE * epicsShareAPI epicsTempFile ( void ) -{ - return tmpfile (); -} - diff --git a/src/libCom/osi/os/posix/osdElfFindAddr.c b/src/libCom/osi/os/posix/osdElfFindAddr.c deleted file mode 100644 index bc67ae9ea..000000000 --- a/src/libCom/osi/os/posix/osdElfFindAddr.c +++ /dev/null @@ -1,659 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _POSIX_MAPPED_FILES -#include -#endif - -#define epicsExportSharedSymbols -#include "epicsMutex.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "errlog.h" -#include "epicsStackTrace.h" -#include "epicsStackTracePvt.h" - -/* This routine is provided by osiClockTime.c */ -epicsShareExtern void ClockTime_GetProgramStart(epicsTimeStamp *pDest); - -#define FIND_ADDR_DEBUG 0 - -/* - * On some systems (linux, solaris) dladdr doesn't find local symbols - * or symbols in the main executable. - * Hence, we want to use dladdr() to find the file name - * where a symbol is defined and if not more information is available - * then proceed to lookup symbols in the ELF symbol tables. - */ - -/* Macros to handle elf32 vs. elf64 access to unions etc. */ - -#define FLD(c,s,f) (ELFCLASS32==c ? s.e32.f : s.e64.f ) -#define ARR(c,s,i,f) (ELFCLASS32==c ? s.e32[i].f : s.e64[i].f) - -/* Elf header */ -typedef union Ehdr_ { - Elf32_Ehdr e32; - Elf64_Ehdr e64; -} Ehdr; - -/* Section header */ -typedef union Shdr_ { - Elf32_Shdr e32; - Elf64_Shdr e64; -} Shdr; - -/* Elf symbol */ -typedef union Sym_ { - void *raw; - Elf32_Sym *e32; - Elf64_Sym *e64; -} Sym; - -/* Memory mapped portion of a file; we must - * keep additional information because the - * map's starting address + length must be - * page-aligned (man mmap). - */ -typedef struct MMap_ { - void *addr; - off_t off; /* offset into the map where 'real' data start */ - size_t len; - size_t max; /* max offset: legal data from addr+off .. addr+off+max-1 */ - void (*freeMap)(struct MMap_*); /* 'method' to destroy the mapping */ -} *MMap; - -/* Structure describing symbol information - * contained in a file. - * We keep these around (so that the file - * doesn't have to be opened + parsed every - * time we do a lookup). - */ -typedef struct ESyms_ { - struct ESyms_ *next; /* linked list; one struct per executable */ - const char *fname; /* file name */ - int fd; /* file descriptor */ - uintptr_t addr; /* address where file is loaded */ - MMap symMap; - MMap strMap; - size_t nsyms; - uint8_t eclss; -} *ESyms; - -/* LOCKING NOTE: if the ELF symbol facility is ever expanded to be truly used - * in a multithreaded way then proper multiple-readers, single-writer locking - * should be implemented. - */ - -/* Linked list where we keep all our ESyms */ -static ESyms elfs = 0; - -static epicsMutexId listMtx; -static epicsThreadOnceId listMtxInitId = EPICS_THREAD_ONCE_INIT; - -static void listMtxInit(void *unused) -{ - listMtx = epicsMutexMustCreate(); -} - -static void -elfsLockWrite() -{ - epicsThreadOnce(&listMtxInitId, listMtxInit, 0); - epicsMutexMustLock(listMtx); -} - -static void -elfsUnlockWrite() -{ - epicsMutexUnlock(listMtx); -} - -static void -freeMap(MMap m) -{ - if ( m ) { - m->freeMap(m); - free(m); - } -} - -/* Helper to read exactly 'sz' bytes into 'buf' - * RETURNS: # chars read or negative value on error. - */ -static ssize_t -do_read(int fd, void *buf, ssize_t sz) -{ - ssize_t got; - char *ptr=(char*)buf; - - while ( sz > 0 ) { - if ( (got=read(fd,ptr,sz)) <= 0 ) { - return got; - } - ptr+=got; - sz -=got; - } - return ptr-(char*)buf; -} - -/* Elf file access -- can either be with mmap or by sequential read */ - -#ifdef _POSIX_MAPPED_FILES -/* Destructor for data that is mmap()ed */ -static void -freeMapMmap(MMap m) -{ - if ( MAP_FAILED != m->addr ) - munmap( m->addr, m->len ); -} - -/* Obtain section data with mmap() */ -static MMap -getscn_mmap(int fd, uint8_t c, Shdr *shdr_p) -{ - off_t n; - MMap rval = 0; - size_t pgsz = sysconf(_SC_PAGESIZE); - - if ( 0 == (n = (off_t)FLD(c,(*shdr_p),sh_size)) ) { - errlogPrintf("elfRead - getscn() -- no section data\n"); - goto bail; - } - - if ( ! (rval = (MMap) malloc(sizeof(*rval))) ) { - errlogPrintf("elfRead - getscn() -- no memory for section map\n"); - goto bail; - } - - rval->freeMap = freeMapMmap; - - rval->off = (off_t) (FLD(c,(*shdr_p),sh_offset) & (pgsz-1)); - rval->len = (n + rval->off + (pgsz - 1)) & ~(pgsz - 1); - rval->max = rval->len - rval->off; - - if ( MAP_FAILED == (rval->addr = mmap(0, rval->len, PROT_READ, MAP_SHARED, fd, (off_t) (FLD(c,(*shdr_p),sh_offset) & ~(pgsz-1)))) ) { - errlogPrintf("elfRead - getscn() -- mapping section contents: %s\n", strerror(errno)); - goto bail; - } - - return rval; - -bail: - freeMap(rval); - return 0; -} -#else -static MMap getscn_mmap(int fd, uint8_t c, Shrd *shdr_p) -{ - return 0; -} -#endif - -/* Destructor for data that is read into a malloc()ed buffer */ -static void -freeMapMalloc(MMap m) -{ - free(m->addr); -} - -/* Read section data into a malloc()ed buffer */ -static MMap -getscn_read(int fd, uint8_t c, Shdr *shdr_p) -{ - ssize_t n; - MMap rval = 0; - - if ( 0 == (n = (ssize_t) FLD(c,(*shdr_p),sh_size)) ) { - errlogPrintf("elfRead - getscn() -- no section data\n"); - goto bail; - } - - if ( ! (rval = (MMap) malloc(sizeof(*rval))) ) { - errlogPrintf("elfRead - getscn() -- no memory for section map\n"); - goto bail; - } - - rval->freeMap = freeMapMalloc; - - if ( ! (rval->addr = malloc(n)) ) { - errlogPrintf("elfRead - getscn() -- no memory for section data\n"); - goto bail; - } - - rval->off = 0; - rval->len = n; - rval->max = rval->len - rval->off; - - /* seek to symbol table contents */ - if ( (off_t)-1 == lseek(fd, (off_t) FLD(c,(*shdr_p),sh_offset), SEEK_SET) ) { - errlogPrintf("elfRead - getscn() -- seeking to sh_offset: %s\n", strerror(errno)); - goto bail; - } - - if ( n != do_read(fd, rval->addr, n) ) { - errlogPrintf("elfRead - getscn() -- reading section contents: %s\n", strerror(errno)); - goto bail; - } - - return rval; - -bail: - freeMap(rval); - return 0; -} - -static MMap -getscn(int fd, uint8_t c, Shdr *shdr_p) -{ - MMap rval = getscn_mmap(fd, c, shdr_p); - - if ( ! rval ) - rval = getscn_read(fd, c, shdr_p); - - return rval; -} - -/* Release resources but keep filename so that - * a file w/o symbol table is not read over and over again. - */ -static void -elfSymsRelease(ESyms es) -{ - if ( es ) { - freeMap(es->symMap); - es->symMap = 0; - freeMap(es->strMap); - es->strMap = 0; - if ( es->fd >= 0 ) - close(es->fd); - es->fd = -1; - es->nsyms = 0; - } -} - -static ESyms -elfRead(const char *fname, uintptr_t fbase) -{ - int i; - Ehdr ehdr; - Shdr shdr; - uint8_t c; - ESyms es; - ssize_t idx,n; - const char *cp; - struct stat stat_b; - - if ( !(es = (ESyms) malloc(sizeof(*es))) ) { - /* no memory -- give up */ - return 0; - } - - memset(es, 0, sizeof(*es)); - es->fd = -1; - es->fname = fname; - - if ( (es->fd = open(fname, O_RDONLY)) < 0 ) { - errlogPrintf("elfRead() -- unable to open file: %s\n", strerror(errno)); - goto bail; - } - - if ( EI_NIDENT != do_read(es->fd, &ehdr, EI_NIDENT) ) { - errlogPrintf("elfRead() -- unable to read ELF e_ident: %s\n", strerror(errno)); - goto bail; - } - - if ( ELFMAG0 != ehdr.e32.e_ident[EI_MAG0] - || ELFMAG1 != ehdr.e32.e_ident[EI_MAG1] - || ELFMAG2 != ehdr.e32.e_ident[EI_MAG2] - || ELFMAG3 != ehdr.e32.e_ident[EI_MAG3] ) { - errlogPrintf("bad ELF magic number\n"); - goto bail; - } - - if ( EV_CURRENT != ehdr.e32.e_ident[EI_VERSION] ) { - errlogPrintf("bad ELF version\n"); - goto bail; - } - - switch ( (es->eclss = c = ehdr.e32.e_ident[EI_CLASS]) ) { - default: - errlogPrintf("bad ELF class\n"); - goto bail; - - case ELFCLASS32: - n = sizeof(Elf32_Ehdr); - break; - case ELFCLASS64: - n = sizeof(Elf64_Ehdr); - break; - } - n -= EI_NIDENT; - - if ( 0 == fstat(es->fd, &stat_b) ) { - epicsTimeStamp progStartStamp; - time_t progStartTime; - - ClockTime_GetProgramStart(&progStartStamp); - epicsTimeToTime_t(&progStartTime, &progStartStamp); - if ( stat_b.st_mtime >= progStartTime ) { - errlogPrintf("elfRead() -- WARNING: '%s' was modified after program start -- symbol information may be inaccurate or invalid\n", fname); - } - } - - /* read rest */ - if ( n != do_read(es->fd, ehdr.e32.e_ident + EI_NIDENT, n) ) { - errlogPrintf("elfRead() -- unable to read ELF ehdr: %s\n", strerror(errno)); - goto bail; - } - - /* seek to section header table */ - if ( (off_t)-1 == lseek(es->fd, (off_t) FLD(c,ehdr,e_shoff), SEEK_SET) ) { - errlogPrintf("elfRead() -- unable to seek to shoff: %s\n", strerror(errno)); - goto bail; - } - - n = ELFCLASS32 == c ? sizeof(shdr.e32) : sizeof(shdr.e64); - - for ( i = 0; ifd, &shdr, n) ) { - errlogPrintf("elfRead() -- unable to read section header: %s\n", strerror(errno)); - goto bail; - } - if ( SHT_SYMTAB == FLD(c,shdr,sh_type) ) - break; - } - - if ( i>=FLD(c,ehdr,e_shnum) ) { - /* no SYMTAB -- try dynamic symbols */ - - if ( (off_t)-1 == lseek(es->fd, (off_t) FLD(c,ehdr,e_shoff), SEEK_SET) ) { - errlogPrintf("elfRead() -- unable to seek to shoff: %s\n", strerror(errno)); - goto bail; - } - - for ( i = 0; ifd, &shdr, n) ) { - errlogPrintf("elfRead() -- unable to read section header: %s\n", strerror(errno)); - goto bail; - } - if ( SHT_DYNSYM == FLD(c,shdr,sh_type) ) - break; - } - } - - if ( i>=FLD(c,ehdr,e_shnum) ) { - errlogPrintf("elfRead() -- no symbol table found\n"); - goto bail; - } - - if ( 0 == (n = (ssize_t) FLD(c,shdr,sh_size)) ) { - errlogPrintf("elfRead() -- no symbol table data\n"); - goto bail; - } - - if ( !(es->symMap = getscn(es->fd, c, &shdr)) ) { - errlogPrintf("elfRead() -- unable to read ELF symtab\n"); - goto bail; - } - - es->nsyms = n / (ELFCLASS32==c ? sizeof(Elf32_Sym) : sizeof(Elf64_Sym)); - - /* find and read string table */ - - n = ELFCLASS32 == c ? sizeof(shdr.e32) : sizeof(shdr.e64); - - /* seek to section header table */ - if ( (off_t)-1 == lseek(es->fd, (off_t) (FLD(c,ehdr,e_shoff) + n * FLD(c,shdr,sh_link)), SEEK_SET) ) { - errlogPrintf("elfRead() -- unable to lseek to ELF e_shoff: %s\n", strerror(errno)); - goto bail; - } - - if ( n != do_read(es->fd, &shdr, n) ) { - errlogPrintf("elfRead() -- unable to read ELF strtab section header: %s\n", strerror(errno)); - goto bail; - } - - if ( !(es->strMap = getscn(es->fd,c,&shdr)) ) { - errlogPrintf("elfRead() -- unable to read ELF strtab\n"); - goto bail; - } - - /* Make sure there is a terminating NUL - unfortunately, memrchr is not portable */ - cp = (char*)es->strMap->addr + es->strMap->off; - for ( idx = es->strMap->max - 1; i >= 0; i-- ) { - if ( !cp[i] ) - break; - } - es->strMap->max = idx + 1; - - switch ( FLD(c,ehdr,e_type) ) { - case ET_EXEC: - /* Symbols in an executable already has absolute addresses */ - es->addr = 0; - break; - case ET_DYN: - /* Symbols in an shared library are relative to base address */ - es->addr = fbase; - break; - default: - errlogPrintf("dlLookupAddr(): Unexpected ELF object file type %u\n", FLD(c,ehdr,e_type)); - goto bail; - } - - return es; - -bail: - elfSymsRelease(es); - return es; -} - -/* Destroy a cached ELF symbol table */ -static void -elfSymsDestroy(ESyms es) -{ - if ( es ) { - elfSymsRelease(es); - free(es); - } -} - -/* Destroy all cached ELF symbol tables - * - * However - w/o proper locking for read access - * this must not be used. Otherwise, readers - * will hold stale pointers... - * - * We leave the commented code here to show - * how the tables can be torn down. - -void -elfSymTblFlush() -{ -ESyms es; - - elfsLockWrite(); - while ( (es = elfs) ) { - elfs = es->next; - es->next = 0; - elfsUnlockWrite(); - elfSymsDestroy(es); - elfsLockWrite(); - } - elfsUnlockWrite(); -} - -*/ - - -/* This routine must be called with the write-lock held */ -static ESyms -elfSymsFind(const char *fname) -{ - ESyms es; - - for ( es=elfs; es && strcmp(fname, es->fname); es = es->next ) - /* nothing else to do */; - return es; -} - -int -epicsFindAddr(void *addr, epicsSymbol *sym_p) -{ - Dl_info inf; - ESyms es,nes = 0; - uintptr_t minoff,off; - size_t i; - Sym sym; - Sym nearest; - const char *strtab; - uint8_t c; - size_t idx; - - if ( ! dladdr(addr, &inf) || (!inf.dli_fname && !inf.dli_sname) ) { - sym_p->f_nam = 0; - sym_p->s_nam = 0; - /* unable to lookup */ - return 0; - } - - sym_p->f_nam = inf.dli_fname; - - /* If the symbol is in the main executable then solaris' dladdr returns bogus info */ -#ifndef __sun - if ( (sym_p->s_nam = inf.dli_sname) ) { - sym_p->s_val = inf.dli_saddr; - /* Have a symbol name - just use it and be done */ - return 0; - } -#endif - - /* No symbol info; try to access ELF file and ready symbol table from there */ - - elfsLockWrite(); - - /* See if we have loaded this file already */ - es = elfSymsFind(inf.dli_fname); - - if ( !es ) { - - elfsUnlockWrite(); - - if ( ! (nes = elfRead(inf.dli_fname, (uintptr_t)inf.dli_fbase)) ) { - /* this path can only be taken if there is no memory for '*nes' */ - return 0; - } - - elfsLockWrite(); - - /* Has someone else intervened and already added this file while we were reading ? */ - es = elfSymsFind(inf.dli_fname); - - if ( es ) { - /* will undo our work in the unlikely event... */ - } else { - nes->next = elfs; - es = elfs = nes; - nes = 0; - } - } - - elfsUnlockWrite(); - - /* Undo our work in the unlikely event that it was redundant */ - if ( nes ) - elfSymsDestroy( nes ); - - nearest.raw = 0; - minoff = (uintptr_t)-1LL; - - if ( es->nsyms ) { - c = es->eclss; - sym.raw = (char*)es->symMap->addr + es->symMap->off; - strtab = (char*)es->strMap->addr + es->strMap->off; - - /* Do a brute-force search through the symbol table; if this is executed - * very often then it would be worthwhile constructing a sorted list of - * symbol addresses but for the stack trace we don't care... - */ -#if (FIND_ADDR_DEBUG & 1) - printf("Looking for %p\n", addr); -#endif - - if ( ELFCLASS32 == c ) { - for ( i=0; insyms; i++ ) { - if ( STT_FUNC != ELF32_ST_TYPE(sym.e32[i].st_info) ) - continue; - /* don't bother about undefined symbols */ - if ( 0 == sym.e32[i].st_shndx ) - continue; -#if (FIND_ADDR_DEBUG & 1) - printf("Trying: %s (0x%lx)\n", strtab + sym.e32[i].st_name, (unsigned long)(sym.e32[i].st_value + es->addr)); -#endif - if ( (uintptr_t)addr >= (uintptr_t)sym.e32[i].st_value + es->addr ) { - off = (uintptr_t)addr - ((uintptr_t)sym.e32[i].st_value + es->addr); - if ( off < minoff ) { - minoff = off; - nearest.e32 = &sym.e32[i]; - } - } - } - } else { - for ( i=0; insyms; i++ ) { - if ( STT_FUNC != ELF64_ST_TYPE(sym.e64[i].st_info) ) - continue; - /* don't bother about undefined symbols */ - if ( 0 == sym.e64[i].st_shndx ) - continue; -#if (FIND_ADDR_DEBUG & 1) - printf("Trying: %s (0x%llx)\n", strtab + sym.e64[i].st_name, (unsigned long long)(sym.e64[i].st_value + es->addr)); -#endif - if ( (uintptr_t)addr >= (uintptr_t)sym.e64[i].st_value + es->addr ) { - off = (uintptr_t)addr - ((uintptr_t)sym.e64[i].st_value + es->addr); - if ( off < minoff ) { - minoff = off; - nearest.e64 = &sym.e64[i]; - } - } - } - } - } - - if ( nearest.raw && ( (idx = ARR(c,nearest,0,st_name)) < es->strMap->max ) ) { - sym_p->s_nam = strtab + idx; - sym_p->s_val = (char*) ARR(c, nearest, 0, st_value) + es->addr; - } - - return 0; -} - -int epicsFindAddrGetFeatures(void) -{ - /* The static information given here may not be correct; - * it also depends on - * - compilation (frame pointer optimization) - * - linkage (static vs. dynamic) - * - stripping - */ - return EPICS_STACKTRACE_LCL_SYMBOLS - | EPICS_STACKTRACE_GBL_SYMBOLS - | EPICS_STACKTRACE_DYN_SYMBOLS; -} diff --git a/src/libCom/osi/os/posix/osdEvent.c b/src/libCom/osi/os/posix/osdEvent.c deleted file mode 100644 index f133ed028..000000000 --- a/src/libCom/osi/os/posix/osdEvent.c +++ /dev/null @@ -1,158 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/posix/osdEvent.c */ - -/* Author: Marty Kraimer Date: 13AUG1999 */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsEvent.h" -#include "epicsTime.h" -#include "errlog.h" - -struct epicsEventOSD { - pthread_mutex_t mutex; - pthread_cond_t cond; - int isFull; -}; - -#define printStatus(status, routine, func) \ - errlogPrintf("%s: %s failed: %s\n", (func), (routine), strerror(status)) - -#define checkStatus(status, routine, func) \ - if (status) { \ - printStatus(status, routine, func); \ - } - -#define checkStatusReturn(status, routine, func) \ - if (status) { \ - printStatus(status, routine, func); \ - return epicsEventError; \ - } - - -epicsShareFunc epicsEventId epicsEventCreate(epicsEventInitialState init) -{ - epicsEventId pevent = malloc(sizeof(*pevent)); - - if (pevent) { - int status = pthread_mutex_init(&pevent->mutex, 0); - - pevent->isFull = (init == epicsEventFull); - if (status) { - printStatus(status, "pthread_mutex_init", "epicsEventCreate"); - } else { - status = pthread_cond_init(&pevent->cond, 0); - if (!status) - return pevent; - printStatus(status, "pthread_cond_init", "epicsEventCreate"); - status = pthread_mutex_destroy(&pevent->mutex); - checkStatus(status, "pthread_mutex_destroy", "epicsEventCreate"); - } - free(pevent); - } - return NULL; -} - -epicsShareFunc void epicsEventDestroy(epicsEventId pevent) -{ - int status = pthread_mutex_destroy(&pevent->mutex); - - checkStatus(status, "pthread_mutex_destroy", "epicsEventDestroy"); - status = pthread_cond_destroy(&pevent->cond); - checkStatus(status, "pthread_cond_destroy", "epicsEventDestroy"); - free(pevent); -} - -epicsShareFunc epicsEventStatus epicsEventTrigger(epicsEventId pevent) -{ - int status = pthread_mutex_lock(&pevent->mutex); - - checkStatusReturn(status, "pthread_mutex_lock", "epicsEventTrigger"); - if (!pevent->isFull) { - pevent->isFull = 1; - status = pthread_cond_signal(&pevent->cond); - checkStatus(status, "pthread_cond_signal", "epicsEventTrigger"); - } - status = pthread_mutex_unlock(&pevent->mutex); - checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventTrigger"); - return epicsEventOK; -} - -epicsShareFunc epicsEventStatus epicsEventWait(epicsEventId pevent) -{ - epicsEventStatus result = epicsEventOK; - int status = pthread_mutex_lock(&pevent->mutex); - - checkStatusReturn(status, "pthread_mutex_lock", "epicsEventWait"); - while (!pevent->isFull) { - status = pthread_cond_wait(&pevent->cond, &pevent->mutex); - if (status) { - printStatus(status, "pthread_cond_wait", "epicsEventWait"); - result = epicsEventError; - goto release; - } - } - pevent->isFull = 0; - result = epicsEventOK; -release: - status = pthread_mutex_unlock(&pevent->mutex); - checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventWait"); - return result; -} - -epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout(epicsEventId pevent, - double timeout) -{ - epicsEventStatus result = epicsEventOK; - int status = pthread_mutex_lock(&pevent->mutex); - - checkStatusReturn(status, "pthread_mutex_lock", "epicsEventWaitWithTimeout"); - if (!pevent->isFull) { - struct timespec wakeTime; - - convertDoubleToWakeTime(timeout, &wakeTime); - while (!status && !pevent->isFull) { - status = pthread_cond_timedwait(&pevent->cond, &pevent->mutex, - &wakeTime); - } - if (status) { - result = (status == ETIMEDOUT) ? - epicsEventWaitTimeout : epicsEventError; - goto release; - } - } - pevent->isFull = 0; -release: - status = pthread_mutex_unlock(&pevent->mutex); - checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventWaitWithTimeout"); - return result; -} - -epicsShareFunc epicsEventStatus epicsEventTryWait(epicsEventId id) -{ - return epicsEventWaitWithTimeout(id, 0.0); -} - -epicsShareFunc void epicsEventShow(epicsEventId pevent, unsigned int level) -{ - printf("epicsEvent %p: %s\n", pevent, - pevent->isFull ? "full" : "empty"); - if (level > 0) - printf(" pthread_mutex = %p, pthread_cond = %p\n", - &pevent->mutex, &pevent->cond); -} diff --git a/src/libCom/osi/os/posix/osdEvent.h b/src/libCom/osi/os/posix/osdEvent.h deleted file mode 100644 index e2f8b9af9..000000000 --- a/src/libCom/osi/os/posix/osdEvent.h +++ /dev/null @@ -1,10 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* for a pure posix implementation no osdEvent.h definitions are needed*/ diff --git a/src/libCom/osi/os/posix/osdExecinfoBackTrace.cpp b/src/libCom/osi/os/posix/osdExecinfoBackTrace.cpp deleted file mode 100644 index ae13d28fc..000000000 --- a/src/libCom/osi/os/posix/osdExecinfoBackTrace.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsStackTracePvt.h" - -int epicsBackTrace(void **buf, int buf_sz) -{ - return backtrace(buf, buf_sz); -} diff --git a/src/libCom/osi/os/posix/osdFindSymbol.c b/src/libCom/osi/os/posix/osdFindSymbol.c deleted file mode 100644 index acfc405e5..000000000 --- a/src/libCom/osi/os/posix/osdFindSymbol.c +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/posix/osdFindSymbol.c */ - -#include - -#define epicsExportSharedSymbols -#include "epicsFindSymbol.h" - -epicsShareFunc void * epicsLoadLibrary(const char *name) -{ - return dlopen(name, RTLD_LAZY | RTLD_GLOBAL); -} - -epicsShareFunc const char *epicsLoadError(void) -{ - return dlerror(); -} - -epicsShareFunc void * epicsShareAPI epicsFindSymbol(const char *name) -{ - return dlsym(0, name); -} diff --git a/src/libCom/osi/os/posix/osdMutex.c b/src/libCom/osi/os/posix/osdMutex.c deleted file mode 100644 index f569916a5..000000000 --- a/src/libCom/osi/os/posix/osdMutex.c +++ /dev/null @@ -1,331 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/posix/osdMutex.c */ - -/* Author: Marty Kraimer Date: 13AUG1999 */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMutex.h" -#include "cantProceed.h" -#include "epicsTime.h" -#include "errlog.h" -#include "epicsAssert.h" - -#define checkStatus(status,message) \ - if((status)) { \ - errlogPrintf("epicsMutex %s failed: error %s\n", \ - (message), strerror((status))); \ - } -#define checkStatusQuit(status,message,method) \ - if(status) { \ - errlogPrintf("epicsMutex %s failed: error %s\n", \ - (message), strerror((status))); \ - cantProceed((method)); \ - } - -static int mutexLock(pthread_mutex_t *id) -{ - int status; - - while ((status = pthread_mutex_lock(id)) == EINTR) { - errlogPrintf("pthread_mutex_lock returned EINTR. Violates SUSv3\n"); - } - return status; -} - -/* Until these can be demonstrated to work leave them undefined*/ -/* On solaris 8 _POSIX_THREAD_PRIO_INHERIT fails*/ -#undef _POSIX_THREAD_PROCESS_SHARED -#undef _POSIX_THREAD_PRIO_INHERIT - -/* Two completely different implementations are provided below - * If support is available for PTHREAD_MUTEX_RECURSIVE then - * only pthread_mutex is used. - * If support is not available for PTHREAD_MUTEX_RECURSIVE then - * a much more complicated solution is required - */ - - -#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE)>=500 -typedef struct epicsMutexOSD { - pthread_mutex_t lock; - pthread_mutexattr_t mutexAttr; -} epicsMutexOSD; - -epicsMutexOSD * epicsMutexOsdCreate(void) { - epicsMutexOSD *pmutex; - int status; - - pmutex = calloc(1, sizeof(*pmutex)); - if(!pmutex) - goto fail; - - status = pthread_mutexattr_init(&pmutex->mutexAttr); - if (status) - goto fail; - -#if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0 - status = pthread_mutexattr_setprotocol(&pmutex->mutexAttr, - PTHREAD_PRIO_INHERIT); - if (errVerbose) checkStatus(status, "pthread_mutexattr_setprotocal"); -#endif /*_POSIX_THREAD_PRIO_INHERIT*/ - - status = pthread_mutexattr_settype(&pmutex->mutexAttr, - PTHREAD_MUTEX_RECURSIVE); - checkStatus(status, "pthread_mutexattr_settype"); - if (status) - goto fail; - - status = pthread_mutex_init(&pmutex->lock, &pmutex->mutexAttr); - if (status) - goto dattr; - return pmutex; - -dattr: - pthread_mutexattr_destroy(&pmutex->mutexAttr); -fail: - free(pmutex); - return NULL; -} - -void epicsMutexOsdDestroy(struct epicsMutexOSD * pmutex) -{ - int status; - - status = pthread_mutex_destroy(&pmutex->lock); - checkStatus(status, "pthread_mutex_destroy"); - status = pthread_mutexattr_destroy(&pmutex->mutexAttr); - checkStatus(status, "pthread_mutexattr_destroy"); - free(pmutex); -} - -void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex) -{ - int status; - - status = pthread_mutex_unlock(&pmutex->lock); - checkStatus(status, "pthread_mutex_unlock epicsMutexOsdUnlock"); -} - -epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex) -{ - int status; - - status = mutexLock(&pmutex->lock); - if (status == EINVAL) return epicsMutexLockError; - if(status) { - errlogMessage("epicsMutex pthread_mutex_lock failed: error epicsMutexOsdLock\n"); - return epicsMutexLockError; - } - return epicsMutexLockOK; -} - -epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex) -{ - int status; - - if (!pmutex) return epicsMutexLockError; - status = pthread_mutex_trylock(&pmutex->lock); - if (status == EINVAL) return epicsMutexLockError; - if (status == EBUSY) return epicsMutexLockTimeout; - if(status) { - errlogMessage("epicsMutex pthread_mutex_trylock failed: error epicsMutexOsdTryLock"); - return epicsMutexLockError; - } - return epicsMutexLockOK; -} - -void epicsMutexOsdShow(struct epicsMutexOSD * pmutex, unsigned int level) -{ -} - -#else /*defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE)>=500 */ - -typedef struct epicsMutexOSD { - pthread_mutex_t lock; - pthread_mutexattr_t mutexAttr; - pthread_cond_t waitToBeOwner; -#if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED > 0 - pthread_condattr_t condAttr; -#endif /*_POSIX_THREAD_PROCESS_SHARED*/ - int count; - int owned; /* TRUE | FALSE */ - pthread_t ownerTid; -} epicsMutexOSD; - -epicsMutexOSD * epicsMutexOsdCreate(void) { - epicsMutexOSD *pmutex; - int status; - - pmutex = calloc(1, sizeof(*pmutex)); - if(!pmutex) - return NULL; - - status = pthread_mutexattr_init(&pmutex->mutexAttr); - if(status) - goto fail; - -#if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0 - status = pthread_mutexattr_setprotocol( - &pmutex->mutexAttr,PTHREAD_PRIO_INHERIT); - if (errVerbose) checkStatus(status, "pthread_mutexattr_setprotocal"); -#endif /*_POSIX_THREAD_PRIO_INHERIT*/ - - status = pthread_mutex_init(&pmutex->lock, &pmutex->mutexAttr); - if(status) - goto dattr; - -#if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED > 0 - status = pthread_condattr_init(&pmutex->condAttr); - checkStatus(status, "pthread_condattr_init"); - status = pthread_condattr_setpshared(&pmutex->condAttr, - PTHREAD_PROCESS_PRIVATE); - checkStatus(status, "pthread_condattr_setpshared"); - status = pthread_cond_init(&pmutex->waitToBeOwner, &pmutex->condAttr); -#else - status = pthread_cond_init(&pmutex->waitToBeOwner, 0); -#endif /*_POSIX_THREAD_PROCESS_SHARED*/ - if(status) - goto dmutex; - - return pmutex; - -dmutex: - pthread_mutex_destroy(&pmutex->lock); -dattr: - pthread_mutexattr_destroy(&pmutex->mutexAttr); -fail: - free(pmutex); - return NULL; -} - -void epicsMutexOsdDestroy(struct epicsMutexOSD * pmutex) -{ - int status; - - status = pthread_cond_destroy(&pmutex->waitToBeOwner); - checkStatus(status, "pthread_cond_destroy"); -#if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED > 0 - status = pthread_condattr_destroy(&pmutex->condAttr); -#endif /*_POSIX_THREAD_PROCESS_SHARED*/ - status = pthread_mutex_destroy(&pmutex->lock); - checkStatus(status, "pthread_mutex_destroy"); - status = pthread_mutexattr_destroy(&pmutex->mutexAttr); - checkStatus(status, "pthread_mutexattr_destroy"); - free(pmutex); -} - -void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex) -{ - int status; - - status = mutexLock(&pmutex->lock); - checkStatus(status, "pthread_mutex_lock epicsMutexOsdUnlock"); - if(status) - return; - - if ((pmutex->count <= 0) || (pmutex->ownerTid != pthread_self())) { - pthread_mutex_unlock(&pmutex->lock); - checkStatus(status, "pthread_mutex_unlock epicsMutexOsdUnlock"); - errlogPrintf("epicsMutexOsdUnlock but caller is not owner\n"); - cantProceed("epicsMutexOsdUnlock but caller is not owner"); - return; - } - - pmutex->count--; - if (pmutex->count == 0) { - pmutex->owned = 0; - pmutex->ownerTid = 0; - status = pthread_cond_signal(&pmutex->waitToBeOwner); - checkStatusQuit(status, "pthread_cond_signal epicsMutexOsdUnlock", "epicsMutexOsdUnlock"); - } - - status = pthread_mutex_unlock(&pmutex->lock); - checkStatus(status, "pthread_mutex_unlock epicsMutexOsdUnlock"); -} - -static int condWait(pthread_cond_t *condId, pthread_mutex_t *mutexId) -{ - int status; - - while ((status = pthread_cond_wait(condId, mutexId)) == EINTR) { - errlogPrintf("pthread_cond_wait returned EINTR. Violates SUSv3\n"); - } - return status; -} - -epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex) -{ - pthread_t tid = pthread_self(); - int status; - - if (!pmutex || !tid) return epicsMutexLockError; - status = mutexLock(&pmutex->lock); - if (status == EINVAL) return epicsMutexLockError; - checkStatus(status, "pthread_mutex_lock epicsMutexOsdLock"); - if(status) - return epicsMutexLockError; - - while (pmutex->owned && !pthread_equal(pmutex->ownerTid, tid)) - condWait(&pmutex->waitToBeOwner, &pmutex->lock); - pmutex->ownerTid = tid; - pmutex->owned = 1; - pmutex->count++; - - status = pthread_mutex_unlock(&pmutex->lock); - checkStatus(status, "pthread_mutex_unlock epicsMutexOsdLock"); - if(status) - return epicsMutexLockError; - return epicsMutexLockOK; -} - -epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex) -{ - pthread_t tid = pthread_self(); - epicsMutexLockStatus result; - int status; - - status = mutexLock(&pmutex->lock); - if (status == EINVAL) return epicsMutexLockError; - checkStatus(status, "pthread_mutex_lock epicsMutexOsdTryLock"); - if(status) - return epicsMutexLockError; - - if (!pmutex->owned || pthread_equal(pmutex->ownerTid, tid)) { - pmutex->ownerTid = tid; - pmutex->owned = 1; - pmutex->count++; - result = epicsMutexLockOK; - } else { - result = epicsMutexLockTimeout; - } - - status = pthread_mutex_unlock(&pmutex->lock); - checkStatus(status, "pthread_mutex_unlock epicsMutexOsdTryLock"); - if(status) - return epicsMutexLockError; - return result; -} - -void epicsMutexOsdShow(struct epicsMutexOSD *pmutex,unsigned int level) -{ - printf("ownerTid %p count %d owned %d\n", - (void *)pmutex->ownerTid, pmutex->count, pmutex->owned); -} -#endif /*defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE)>=500 */ diff --git a/src/libCom/osi/os/posix/osdMutex.h b/src/libCom/osi/os/posix/osdMutex.h deleted file mode 100644 index cc416384a..000000000 --- a/src/libCom/osi/os/posix/osdMutex.h +++ /dev/null @@ -1,10 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* for a pure posix implementation no osdMutex.h definitions are needed*/ diff --git a/src/libCom/osi/os/posix/osdProcess.c b/src/libCom/osi/os/posix/osdProcess.c deleted file mode 100644 index a08871465..000000000 --- a/src/libCom/osi/os/posix/osdProcess.c +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Operating System Dependent Implementation of osiProcess.h - * - * Author: Jeff Hill - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "osiProcess.h" -#include "errlog.h" -#include "epicsAssert.h" - -epicsShareFunc osiGetUserNameReturn epicsShareAPI osiGetUserName (char *pBuf, unsigned bufSizeIn) -{ - struct passwd *p; - - p = getpwuid ( getuid () ); - if ( p && p->pw_name ) { - size_t len = strlen ( p->pw_name ); - unsigned uiLength; - - if ( len > UINT_MAX || len <= 0 ) { - return osiGetUserNameFail; - } - uiLength = (unsigned) len; - - if ( uiLength + 1 >= bufSizeIn ) { - return osiGetUserNameFail; - } - - strncpy ( pBuf, p->pw_name, (size_t) bufSizeIn ); - - return osiGetUserNameSuccess; - } - else { - return osiGetUserNameFail; - } -} - -epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProcess - (const char *pProcessName, const char *pBaseExecutableName) -{ - int status; - - /* - * create a duplicate process - */ - status = fork (); - if (status < 0) { - return osiSpawnDetachedProcessFail; - } - - /* - * return to the caller - * in the initiating (parent) process - */ - if (status) { - return osiSpawnDetachedProcessSuccess; - } - - /* - * This is executed only by the new child process. - * Close all open files except for STDIO, so they will not - * be inherited by the new program. - */ - { - int fd, maxfd = sysconf ( _SC_OPEN_MAX ); - for ( fd = 0; fd <= maxfd; fd++ ) { - if (fd==STDIN_FILENO) continue; - if (fd==STDOUT_FILENO) continue; - if (fd==STDERR_FILENO) continue; - close (fd); - } - } - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - /* - * Drop real-time SCHED_FIFO priority - */ - { - struct sched_param p; - - p.sched_priority = 0; - status = sched_setscheduler(0, SCHED_OTHER, &p); - } -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ - - /* - * Run the specified executable - */ - status = execlp (pBaseExecutableName, pBaseExecutableName, (char *)NULL); - if ( status < 0 ) { - fprintf ( stderr, "**** The executable \"%s\" couldn't be located\n", pBaseExecutableName ); - fprintf ( stderr, "**** because of errno = \"%s\".\n", strerror (errno) ); - fprintf ( stderr, "**** You may need to modify your PATH environment variable.\n" ); - fprintf ( stderr, "**** Unable to start \"%s\" process.\n", pProcessName); - } - /* Don't run our parent's atexit() handlers */ - _exit ( -1 ); -} diff --git a/src/libCom/osi/os/posix/osdSignal.cpp b/src/libCom/osi/os/posix/osdSignal.cpp deleted file mode 100644 index 3f8deb4fb..000000000 --- a/src/libCom/osi/os/posix/osdSignal.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Authors: J. Hill, A. Johnson - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsSignal.h" - -static void ignoreIfDefault(int signum, const char *name) -{ - struct sigaction curAction; - int status = sigaction(signum, NULL, &curAction); - - if (status >= 0 && - curAction.sa_handler == SIG_DFL) { - curAction.sa_handler = SIG_IGN; - status = sigaction(signum, &curAction, NULL); - } - if (status < 0) { - fprintf(stderr, "%s: sigaction failed for %s, %s\n", - __FILE__, name, strerror(errno)); - } -} - -/* - * epicsSignalInstallSigHupIgnore () - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore (void) -{ - ignoreIfDefault(SIGHUP, "SIGHUP"); -} - -/* - * epicsSignalInstallSigPipeIgnore () - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore (void) -{ - ignoreIfDefault(SIGPIPE, "SIGPIPE"); -} - -/* Disabled */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm - ( struct epicsThreadOSD * /* threadId */ ) {} diff --git a/src/libCom/osi/os/posix/osdSock.c b/src/libCom/osi/os/posix/osdSock.c deleted file mode 100644 index 9f8146142..000000000 --- a/src/libCom/osi/os/posix/osdSock.c +++ /dev/null @@ -1,183 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdSock.c */ -/* - * Author: Jeff Hill - * Date: 04-05-94 - * - */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsThread.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "osiSock.h" -#include "epicsAssert.h" -#include "errlog.h" - -/* - * Protect some routines which are not thread-safe - */ -static epicsMutexId infoMutex; -static void createInfoMutex (void *unused) -{ - infoMutex = epicsMutexMustCreate (); -} -static void lockInfo (void) -{ - static epicsThreadOnceId infoMutexOnceFlag = EPICS_THREAD_ONCE_INIT; - - epicsThreadOnce (&infoMutexOnceFlag, createInfoMutex, NULL); - epicsMutexMustLock (infoMutex); -} -static void unlockInfo (void) -{ - epicsMutexUnlock (infoMutex); -} - -/* - * NOOP - */ -int osiSockAttach() -{ - return 1; -} - -/* - * NOOP - */ -void osiSockRelease() -{ -} - -/* - * this version sets the file control flags so that - * the socket will be closed if the user uses exec() - * as is the case with third party tools such as TCL/TK - */ -epicsShareFunc SOCKET epicsShareAPI epicsSocketCreate ( - int domain, int type, int protocol ) -{ - SOCKET sock = socket ( domain, type, protocol ); - if ( sock < 0 ) { - sock = INVALID_SOCKET; - } - else { - int status = fcntl ( sock, F_SETFD, FD_CLOEXEC ); - if ( status < 0 ) { - char buf [ 64 ]; - epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) ); - errlogPrintf ( - "epicsSocketCreate: failed to " - "fcntl FD_CLOEXEC because \"%s\"\n", - buf ); - close ( sock ); - sock = INVALID_SOCKET; - } - } - return sock; -} - -epicsShareFunc int epicsShareAPI epicsSocketAccept ( - int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ) -{ - int newSock = accept ( sock, pAddr, addrlen ); - if ( newSock < 0 ) { - newSock = INVALID_SOCKET; - } - else { - int status = fcntl ( newSock, F_SETFD, FD_CLOEXEC ); - if ( status < 0 ) { - char buf [ 64 ]; - epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) ); - errlogPrintf ( - "epicsSocketCreate: failed to " - "fcntl FD_CLOEXEC because \"%s\"\n", - buf ); - close ( newSock ); - newSock = INVALID_SOCKET; - } - } - return newSock; -} - -epicsShareFunc void epicsShareAPI epicsSocketDestroy ( SOCKET s ) -{ - int status = close ( s ); - if ( status < 0 ) { - char buf [ 64 ]; - epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) ); - errlogPrintf ( - "epicsSocketDestroy: failed to " - "close a socket because \"%s\"\n", - buf ); - } -} - -/* - * ipAddrToHostName - * On many systems, gethostbyaddr must be protected by a - * mutex since the routine is not thread-safe. - */ -epicsShareFunc unsigned epicsShareAPI ipAddrToHostName - (const struct in_addr *pAddr, char *pBuf, unsigned bufSize) -{ - struct hostent *ent; - int ret = 0; - - if (bufSize<1) { - return 0; - } - - lockInfo (); - ent = gethostbyaddr((const char *) pAddr, sizeof (*pAddr), AF_INET); - if (ent) { - strncpy (pBuf, ent->h_name, bufSize); - pBuf[bufSize-1] = '\0'; - ret = strlen (pBuf); - } - unlockInfo (); - return ret; -} - -/* - * hostToIPAddr () - * On many systems, gethostbyname must be protected by a - * mutex since the routine is not thread-safe. - */ -epicsShareFunc int epicsShareAPI hostToIPAddr - (const char *pHostName, struct in_addr *pIPA) -{ - struct hostent *phe; - int ret = -1; - - lockInfo (); - phe = gethostbyname (pHostName); - if (phe && phe->h_addr_list[0]) { - if (phe->h_addrtype==AF_INET && phe->h_length<=sizeof(struct in_addr)) { - struct in_addr *pInAddrIn = (struct in_addr *) phe->h_addr_list[0]; - - *pIPA = *pInAddrIn; - ret = 0; - } - } - unlockInfo (); - return ret; -} - - - diff --git a/src/libCom/osi/os/posix/osdSockAddrReuse.cpp b/src/libCom/osi/os/posix/osdSockAddrReuse.cpp deleted file mode 100644 index 3a3f78ebd..000000000 --- a/src/libCom/osi/os/posix/osdSockAddrReuse.cpp +++ /dev/null @@ -1,49 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" - -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnableAddressReuseDuringTimeWaitState: " - "unable to set SO_REUSEADDR?\n"); - } -} - -/* - * SO_REUSEPORT is not in POSIX - */ -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEADDR?\n"); - } -} diff --git a/src/libCom/osi/os/posix/osdSpin.c b/src/libCom/osi/os/posix/osdSpin.c deleted file mode 100644 index aa61a6c90..000000000 --- a/src/libCom/osi/os/posix/osdSpin.c +++ /dev/null @@ -1,180 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "errlog.h" -#include "cantProceed.h" -#include "epicsSpin.h" - -/* POSIX spinlocks may be subject to priority inversion - * and so can't be guaranteed safe in situations where - * threads have different priorities, and thread - * preemption can't be disabled. - */ -#if defined(DONT_USE_POSIX_THREAD_PRIORITY_SCHEDULING) -#if defined(_POSIX_SPIN_LOCKS) && (_POSIX_SPIN_LOCKS > 0) -# define USE_PSPIN -#endif -#endif - -#define checkStatus(status,message) \ - if ((status)) { \ - errlogPrintf("epicsSpin %s failed: error %s\n", \ - (message), strerror((status))); \ - } - -#ifdef USE_PSPIN - -/* - * POSIX SPIN LOCKS IMPLEMENTATION - */ - -typedef struct epicsSpin { - pthread_spinlock_t lock; -} epicsSpin; - -epicsSpinId epicsSpinCreate(void) { - epicsSpin *spin; - int status; - - spin = calloc(1, sizeof(*spin)); - if (!spin) - goto fail; - - status = pthread_spin_init(&spin->lock, PTHREAD_PROCESS_PRIVATE); - checkStatus(status, "pthread_spin_init"); - if (status) - goto fail; - - return spin; - -fail: - free(spin); - return NULL; -} - -void epicsSpinDestroy(epicsSpinId spin) { - int status; - - status = pthread_spin_destroy(&spin->lock); - checkStatus(status, "pthread_spin_destroy"); - - free(spin); -} - -void epicsSpinLock(epicsSpinId spin) { - int status; - - status = pthread_spin_lock(&spin->lock); - checkStatus(status, "pthread_spin_lock"); - if (status) - cantProceed(NULL); -} - -int epicsSpinTryLock(epicsSpinId spin) { - int status; - - status = pthread_spin_trylock(&spin->lock); - if (status == EBUSY) - return 1; - checkStatus(status, "pthread_spin_trylock"); - return status; -} - -void epicsSpinUnlock(epicsSpinId spin) { - int status; - - status = pthread_spin_unlock(&spin->lock); - checkStatus(status, "pthread_spin_unlock"); -} - -#else /* USE_PSPIN */ - -/* - * POSIX MUTEX IMPLEMENTATION - */ - -typedef struct epicsSpin { - pthread_mutex_t lock; -} epicsSpin; - -epicsSpinId epicsSpinCreate(void) { - epicsSpin *spin; - int status; - - spin = calloc(1, sizeof(*spin)); - if (!spin) - goto fail; - - status = pthread_mutex_init(&spin->lock, NULL); - checkStatus(status, "pthread_mutex_init"); - if (status) - goto fail; - - return spin; - -fail: - free(spin); - return NULL; -} - -void epicsSpinDestroy(epicsSpinId spin) { - int status; - - status = pthread_mutex_destroy(&spin->lock); - checkStatus(status, "pthread_mutex_destroy"); - - free(spin); -} - -void epicsSpinLock(epicsSpinId spin) { - int status; - - status = pthread_mutex_lock(&spin->lock); - checkStatus(status, "pthread_mutex_lock"); - if (status) - cantProceed(NULL); -} - -int epicsSpinTryLock(epicsSpinId spin) { - int status; - - status = pthread_mutex_trylock(&spin->lock); - if (status == EBUSY) - return 1; - checkStatus(status, "pthread_mutex_trylock"); - return status; -} - -void epicsSpinUnlock(epicsSpinId spin) { - int status; - - status = pthread_mutex_unlock(&spin->lock); - checkStatus(status, "pthread_mutex_unlock"); -} - -#endif /* USE_PSPIN */ - - -epicsSpinId epicsSpinMustCreate(void) -{ - epicsSpinId ret = epicsSpinCreate(); - if(!ret) - cantProceed("epicsSpinMustCreate: epicsSpinCreate failed."); - return ret; -} diff --git a/src/libCom/osi/os/posix/osdStdio.c b/src/libCom/osi/os/posix/osdStdio.c deleted file mode 100644 index 2a23cee71..000000000 --- a/src/libCom/osi/os/posix/osdStdio.c +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#define epicsExportSharedSymbols -#include - -epicsShareFunc int epicsShareAPI epicsSnprintf( - char *str, size_t size, const char *format, ...) -{ - int nchars; - va_list pvar; - - va_start(pvar,format); - nchars = epicsVsnprintf(str,size,format,pvar); - va_end (pvar); - return(nchars); -} - -epicsShareFunc int epicsShareAPI epicsVsnprintf( - char *str, size_t size, const char *format, va_list ap) -{ - return vsnprintf ( str, size, format, ap ); -} diff --git a/src/libCom/osi/os/posix/osdStrtod.h b/src/libCom/osi/os/posix/osdStrtod.h deleted file mode 100644 index 502889a9d..000000000 --- a/src/libCom/osi/os/posix/osdStrtod.h +++ /dev/null @@ -1,15 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * This header fragment is intended to be included as part of epicsString.h - */ - -/* - * epicsStrtod() for systems with working strtod() routine - */ -#define epicsStrtod strtod diff --git a/src/libCom/osi/os/posix/osdThread.c b/src/libCom/osi/os/posix/osdThread.c deleted file mode 100644 index 755390eed..000000000 --- a/src/libCom/osi/os/posix/osdThread.c +++ /dev/null @@ -1,914 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2013 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 18JAN2000 */ - -/* This is a posix implementation of epicsThread */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(_POSIX_MEMLOCK) && _POSIX_MEMLOCK > 0 -#include -#endif - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "ellLib.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsString.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "errlog.h" -#include "epicsAssert.h" -#include "epicsExit.h" - -epicsShareFunc void epicsThreadShowInfo(epicsThreadOSD *pthreadInfo, unsigned int level); -epicsShareFunc void osdThreadHooksRun(epicsThreadId id); -epicsShareFunc void osdThreadHooksRunMain(epicsThreadId id); - -static int mutexLock(pthread_mutex_t *id) -{ - int status; - - while(1) { - status = pthread_mutex_lock(id); - if(status!=EINTR) return status; - fprintf(stderr,"pthread_mutex_lock returned EINTR. Violates SUSv3\n"); - } -} - -#if defined DONT_USE_POSIX_THREAD_PRIORITY_SCHEDULING -#undef _POSIX_THREAD_PRIORITY_SCHEDULING -#endif - -typedef struct commonAttr{ - pthread_attr_t attr; - struct sched_param schedParam; - int maxPriority; - int minPriority; - int schedPolicy; - int usePolicy; -} commonAttr; - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 -typedef struct { - int min_pri, max_pri; - int policy; - int ok; -} priAvailable; -#endif - -static pthread_key_t getpthreadInfo; -static pthread_mutex_t onceLock; -static pthread_mutex_t listLock; -static ELLLIST pthreadList = ELLLIST_INIT; -static commonAttr *pcommonAttr = 0; -static int epicsThreadOnceCalled = 0; - -static epicsThreadOSD *createImplicit(void); - -#define checkStatus(status,message) \ -if((status)) {\ - errlogPrintf("%s error %s\n",(message),strerror((status))); \ -} - -#define checkStatusQuit(status,message,method) \ -if(status) { \ - errlogPrintf("%s error %s\n",(message),strerror((status))); \ - cantProceed((method)); \ -} - -/* The following are for use by once, which is only invoked from epicsThreadInit*/ -/* Until epicsThreadInit completes errlogInit will not work */ -/* It must also be used by init_threadInfo otherwise errlogInit could get */ -/* called recursively */ -#define checkStatusOnce(status,message) \ -if((status)) {\ - fprintf(stderr,"%s error %s\n",(message),strerror((status))); } - -#define checkStatusOnceQuit(status,message,method) \ -if(status) { \ - fprintf(stderr,"%s error %s",(message),strerror((status))); \ - fprintf(stderr," %s\n",method); \ - fprintf(stderr,"epicsThreadInit cant proceed. Program exiting\n"); \ - exit(-1);\ -} - - -epicsShareFunc int epicsThreadGetPosixPriority(epicsThreadId pthreadInfo) -{ -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - double maxPriority,minPriority,slope,oss; - - if(pcommonAttr->maxPriority==pcommonAttr->minPriority) - return(pcommonAttr->maxPriority); - maxPriority = (double)pcommonAttr->maxPriority; - minPriority = (double)pcommonAttr->minPriority; - slope = (maxPriority - minPriority)/100.0; - oss = (double)pthreadInfo->osiPriority * slope + minPriority; - return((int)oss); -#else - return 0; -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ -} - -static void setSchedulingPolicy(epicsThreadOSD *pthreadInfo,int policy) -{ -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - int status; - - if(!pcommonAttr->usePolicy) return; - - status = pthread_attr_getschedparam( - &pthreadInfo->attr,&pthreadInfo->schedParam); - checkStatusOnce(status,"pthread_attr_getschedparam"); - pthreadInfo->schedParam.sched_priority = epicsThreadGetPosixPriority(pthreadInfo); - pthreadInfo->schedPolicy = policy; - status = pthread_attr_setschedpolicy( - &pthreadInfo->attr,policy); - checkStatusOnce(status,"pthread_attr_setschedpolicy"); - status = pthread_attr_setschedparam( - &pthreadInfo->attr,&pthreadInfo->schedParam); - checkStatusOnce(status,"pthread_attr_setschedparam"); - status = pthread_attr_setinheritsched( - &pthreadInfo->attr,PTHREAD_EXPLICIT_SCHED); - checkStatusOnce(status,"pthread_attr_setinheritsched"); -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ -} - -static epicsThreadOSD * create_threadInfo(const char *name) -{ - epicsThreadOSD *pthreadInfo; - - /* sizeof(epicsThreadOSD) includes one byte for the '\0' */ - pthreadInfo = calloc(1,sizeof(*pthreadInfo) + strlen(name)); - if(!pthreadInfo) - return NULL; - pthreadInfo->suspendEvent = epicsEventCreate(epicsEventEmpty); - if(!pthreadInfo->suspendEvent){ - free(pthreadInfo); - return NULL; - } - strcpy(pthreadInfo->name, name); - return pthreadInfo; -} - -static epicsThreadOSD * init_threadInfo(const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) -{ - epicsThreadOSD *pthreadInfo; - int status; - - pthreadInfo = create_threadInfo(name); - if(!pthreadInfo) - return NULL; - pthreadInfo->createFunc = funptr; - pthreadInfo->createArg = parm; - status = pthread_attr_init(&pthreadInfo->attr); - checkStatusOnce(status,"pthread_attr_init"); - if(status) return 0; - status = pthread_attr_setdetachstate( - &pthreadInfo->attr, PTHREAD_CREATE_DETACHED); - checkStatusOnce(status,"pthread_attr_setdetachstate"); -#if defined (_POSIX_THREAD_ATTR_STACKSIZE) -#if ! defined (OSITHREAD_USE_DEFAULT_STACK) - status = pthread_attr_setstacksize( &pthreadInfo->attr,(size_t)stackSize); - checkStatusOnce(status,"pthread_attr_setstacksize"); -#endif /*OSITHREAD_USE_DEFAULT_STACK*/ -#endif /*_POSIX_THREAD_ATTR_STACKSIZE*/ - status = pthread_attr_setscope(&pthreadInfo->attr,PTHREAD_SCOPE_PROCESS); - if(errVerbose) checkStatusOnce(status,"pthread_attr_setscope"); - pthreadInfo->osiPriority = priority; - return(pthreadInfo); -} - -static void free_threadInfo(epicsThreadOSD *pthreadInfo) -{ - int status; - - status = mutexLock(&listLock); - checkStatusQuit(status,"pthread_mutex_lock","free_threadInfo"); - if(pthreadInfo->isOnThreadList) ellDelete(&pthreadList,&pthreadInfo->node); - status = pthread_mutex_unlock(&listLock); - checkStatusQuit(status,"pthread_mutex_unlock","free_threadInfo"); - epicsEventDestroy(pthreadInfo->suspendEvent); - status = pthread_attr_destroy(&pthreadInfo->attr); - checkStatusQuit(status,"pthread_attr_destroy","free_threadInfo"); - free(pthreadInfo); -} - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 -/* - * The actually available range priority range (at least under linux) - * may be restricted by resource limitations (but that is ignored - * by sched_get_priority_max()). See bug #835138 which is fixed by - * this code. - */ - -static int try_pri(int pri, int policy) -{ -struct sched_param schedp; - - schedp.sched_priority = pri; - return pthread_setschedparam(pthread_self(), policy, &schedp); -} - -static void* -find_pri_range(void *arg) -{ -priAvailable *prm = arg; -int min = sched_get_priority_min(prm->policy); -int max = sched_get_priority_max(prm->policy); -int low, try; - - if ( -1 == min || -1 == max ) { - /* something is very wrong; maintain old behavior - * (warning message if sched_get_priority_xxx() fails - * and use default policy's sched_priority [even if - * that is likely to cause epicsThreadCreate to fail - * because that priority is not suitable for SCHED_FIFO]). - */ - prm->min_pri = prm->max_pri = -1; - return 0; - } - - - if ( try_pri(min, prm->policy) ) { - /* cannot create thread at minimum priority; - * probably no permission to use SCHED_FIFO - * at all. However, we still must return - * a priority range accepted by the SCHED_FIFO - * policy. Otherwise, epicsThreadCreate() cannot - * detect the unsufficient permission (EPERM) - * and fall back to a non-RT thread (because - * pthread_attr_setschedparam would fail with - * EINVAL due to the bad priority). - */ - prm->min_pri = prm->max_pri = min; - return 0; - } - - - /* Binary search through available priorities. - * The actually available range may be restricted - * by resource limitations (but that is ignored - * by sched_get_priority_max() [linux]). - */ - low = min; - - while ( low < max ) { - try = (max+low)/2; - if ( try_pri(try, prm->policy) ) { - max = try; - } else { - low = try + 1; - } - } - - prm->min_pri = min; - prm->max_pri = try_pri(max, prm->policy) ? max-1 : max; - prm->ok = 1; - - return 0; -} - -static void findPriorityRange(commonAttr *a_p) -{ -priAvailable arg; -pthread_t id; -void *dummy; -int status; - - arg.policy = a_p->schedPolicy; - arg.ok = 0; - - status = pthread_create(&id, 0, find_pri_range, &arg); - checkStatusQuit(status, "pthread_create","epicsThreadInit"); - - status = pthread_join(id, &dummy); - checkStatusQuit(status, "pthread_join","epicsThreadInit"); - - a_p->minPriority = arg.min_pri; - a_p->maxPriority = arg.max_pri; - a_p->usePolicy = arg.ok; -} -#endif - - -static void once(void) -{ - epicsThreadOSD *pthreadInfo; - int status; - - pthread_key_create(&getpthreadInfo,0); - status = pthread_mutex_init(&onceLock,0); - checkStatusQuit(status,"pthread_mutex_init","epicsThreadInit"); - status = pthread_mutex_init(&listLock,0); - checkStatusQuit(status,"pthread_mutex_init","epicsThreadInit"); - pcommonAttr = calloc(1,sizeof(commonAttr)); - if(!pcommonAttr) checkStatusOnceQuit(errno,"calloc","epicsThreadInit"); - status = pthread_attr_init(&pcommonAttr->attr); - checkStatusOnceQuit(status,"pthread_attr_init","epicsThreadInit"); - status = pthread_attr_setdetachstate( - &pcommonAttr->attr, PTHREAD_CREATE_DETACHED); - checkStatusOnce(status,"pthread_attr_setdetachstate"); - status = pthread_attr_setscope(&pcommonAttr->attr,PTHREAD_SCOPE_PROCESS); - if(errVerbose) checkStatusOnce(status,"pthread_attr_setscope"); - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - status = pthread_attr_setschedpolicy( - &pcommonAttr->attr,SCHED_FIFO); - checkStatusOnce(status,"pthread_attr_setschedpolicy"); - status = pthread_attr_getschedpolicy( - &pcommonAttr->attr,&pcommonAttr->schedPolicy); - checkStatusOnce(status,"pthread_attr_getschedpolicy"); - status = pthread_attr_getschedparam( - &pcommonAttr->attr,&pcommonAttr->schedParam); - checkStatusOnce(status,"pthread_attr_getschedparam"); - - findPriorityRange(pcommonAttr); - - if(pcommonAttr->maxPriority == -1) { - pcommonAttr->maxPriority = pcommonAttr->schedParam.sched_priority; - fprintf(stderr,"sched_get_priority_max failed set to %d\n", - pcommonAttr->maxPriority); - } - if(pcommonAttr->minPriority == -1) { - pcommonAttr->minPriority = pcommonAttr->schedParam.sched_priority; - fprintf(stderr,"sched_get_priority_min failed set to %d\n", - pcommonAttr->maxPriority); - } - - if (errVerbose) { - fprintf(stderr, "LRT: min priority: %d max priority %d\n", - pcommonAttr->minPriority, pcommonAttr->maxPriority); - } - -#else - if(errVerbose) fprintf(stderr,"task priorities are not implemented\n"); -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ - - pthreadInfo = init_threadInfo("_main_",0,epicsThreadGetStackSize(epicsThreadStackSmall),0,0); - assert(pthreadInfo!=NULL); - status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo); - checkStatusOnceQuit(status,"pthread_setspecific","epicsThreadInit"); - status = mutexLock(&listLock); - checkStatusQuit(status,"pthread_mutex_lock","epicsThreadInit"); - ellAdd(&pthreadList,&pthreadInfo->node); - pthreadInfo->isOnThreadList = 1; - status = pthread_mutex_unlock(&listLock); - checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadInit"); - status = atexit(epicsExitCallAtExits); - checkStatusOnce(status,"atexit"); - osdThreadHooksRunMain(pthreadInfo); - epicsThreadOnceCalled = 1; -} - -static void * start_routine(void *arg) -{ - epicsThreadOSD *pthreadInfo = (epicsThreadOSD *)arg; - int status; - sigset_t blockAllSig; - - sigfillset(&blockAllSig); - pthread_sigmask(SIG_SETMASK,&blockAllSig,NULL); - status = pthread_setspecific(getpthreadInfo,arg); - checkStatusQuit(status,"pthread_setspecific","start_routine"); - status = mutexLock(&listLock); - checkStatusQuit(status,"pthread_mutex_lock","start_routine"); - ellAdd(&pthreadList,&pthreadInfo->node); - pthreadInfo->isOnThreadList = 1; - status = pthread_mutex_unlock(&listLock); - checkStatusQuit(status,"pthread_mutex_unlock","start_routine"); - osdThreadHooksRun(pthreadInfo); - - (*pthreadInfo->createFunc)(pthreadInfo->createArg); - - epicsExitCallAtThreadExits (); - free_threadInfo(pthreadInfo); - return(0); -} - -static void epicsThreadInit(void) -{ - static pthread_once_t once_control = PTHREAD_ONCE_INIT; - int status = pthread_once(&once_control,once); - checkStatusQuit(status,"pthread_once","epicsThreadInit"); -} - -epicsShareFunc -void epicsThreadRealtimeLock(void) -{ -#if defined(_POSIX_MEMLOCK) && _POSIX_MEMLOCK > 0 - if (pcommonAttr->maxPriority > pcommonAttr->minPriority) { - int status = mlockall(MCL_CURRENT | MCL_FUTURE); - - if (status) { - fprintf(stderr, "epicsThreadRealtimeLock " - "Warning: Unable to lock the virtual address space.\n" - "VM page faults may harm real-time performance.\n"); - } - } -#endif -} - -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize (epicsThreadStackSizeClass stackSizeClass) -{ -#if defined (OSITHREAD_USE_DEFAULT_STACK) - return 0; -#elif defined(_POSIX_THREAD_ATTR_STACKSIZE) && _POSIX_THREAD_ATTR_STACKSIZE > 0 - #define STACK_SIZE(f) (f * 0x10000 * sizeof(void *)) - static const unsigned stackSizeTable[epicsThreadStackBig+1] = { - STACK_SIZE(1), STACK_SIZE(2), STACK_SIZE(4) - }; - if (stackSizeClassepicsThreadStackBig) { - errlogPrintf("epicsThreadGetStackSize illegal argument (too large)"); - return stackSizeTable[epicsThreadStackBig]; - } - - return stackSizeTable[stackSizeClass]; -#else - return 0; -#endif /*_POSIX_THREAD_ATTR_STACKSIZE*/ -} - -epicsShareFunc void epicsShareAPI epicsThreadOnce(epicsThreadOnceId *id, void (*func)(void *), void *arg) -{ - static struct epicsThreadOSD threadOnceComplete; - #define EPICS_THREAD_ONCE_DONE &threadOnceComplete - int status; - - epicsThreadInit(); - status = mutexLock(&onceLock); - if(status) { - fprintf(stderr,"epicsThreadOnce: pthread_mutex_lock returned %s.\n", - strerror(status)); - exit(-1); - } - - if (*id != EPICS_THREAD_ONCE_DONE) { - if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ - *id = epicsThreadGetIdSelf(); /* mark active */ - status = pthread_mutex_unlock(&onceLock); - checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); - func(arg); - status = mutexLock(&onceLock); - checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); - *id = EPICS_THREAD_ONCE_DONE; /* mark done */ - } else if (*id == epicsThreadGetIdSelf()) { - status = pthread_mutex_unlock(&onceLock); - checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); - cantProceed("Recursive epicsThreadOnce() initialization\n"); - } else - while (*id != EPICS_THREAD_ONCE_DONE) { - /* Another thread is in the above func(arg) call. */ - status = pthread_mutex_unlock(&onceLock); - checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); - epicsThreadSleep(epicsThreadSleepQuantum()); - status = mutexLock(&onceLock); - checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); - } - } - status = pthread_mutex_unlock(&onceLock); - checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadOnce"); -} - -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate(const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) -{ - epicsThreadOSD *pthreadInfo; - int status; - sigset_t blockAllSig, oldSig; - - epicsThreadInit(); - assert(pcommonAttr); - sigfillset(&blockAllSig); - pthread_sigmask(SIG_SETMASK,&blockAllSig,&oldSig); - pthreadInfo = init_threadInfo(name,priority,stackSize,funptr,parm); - if(pthreadInfo==0) return 0; - pthreadInfo->isEpicsThread = 1; - setSchedulingPolicy(pthreadInfo,SCHED_FIFO); - pthreadInfo->isRealTimeScheduled = 1; - status = pthread_create(&pthreadInfo->tid,&pthreadInfo->attr, - start_routine,pthreadInfo); - if(status==EPERM){ - /* Try again without SCHED_FIFO*/ - free_threadInfo(pthreadInfo); - pthreadInfo = init_threadInfo(name,priority,stackSize,funptr,parm); - if(pthreadInfo==0) return 0; - pthreadInfo->isEpicsThread = 1; - status = pthread_create(&pthreadInfo->tid,&pthreadInfo->attr, - start_routine,pthreadInfo); - } - checkStatusOnce(status,"pthread_create"); - if(status) { - free_threadInfo(pthreadInfo); - return 0; - } - status = pthread_sigmask(SIG_SETMASK,&oldSig,NULL); - checkStatusOnce(status,"pthread_sigmask"); - return(pthreadInfo); -} - -/* - * Create dummy context for threads not created by epicsThreadCreate(). - */ -static epicsThreadOSD *createImplicit(void) -{ - epicsThreadOSD *pthreadInfo; - char name[64]; - pthread_t tid; - int status; - - tid = pthread_self(); - sprintf(name, "non-EPICS_%ld", (long)tid); - pthreadInfo = create_threadInfo(name); - assert(pthreadInfo); - pthreadInfo->tid = tid; - pthreadInfo->osiPriority = 0; - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - { - struct sched_param param; - int policy; - if(pthread_getschedparam(tid,&policy,¶m) == 0) - pthreadInfo->osiPriority = - (param.sched_priority - pcommonAttr->minPriority) * 100.0 / - (pcommonAttr->maxPriority - pcommonAttr->minPriority + 1); - } -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ - - status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo); - checkStatus(status,"pthread_setspecific createImplicit"); - if(status){ - free_threadInfo(pthreadInfo); - return NULL; - } - return pthreadInfo; -} - -epicsShareFunc void epicsShareAPI epicsThreadSuspendSelf(void) -{ - epicsThreadOSD *pthreadInfo; - - epicsThreadInit(); - pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); - if(pthreadInfo==NULL) - pthreadInfo = createImplicit(); - pthreadInfo->isSuspended = 1; - epicsEventWait(pthreadInfo->suspendEvent); -} - -epicsShareFunc void epicsShareAPI epicsThreadResume(epicsThreadOSD *pthreadInfo) -{ - assert(epicsThreadOnceCalled); - pthreadInfo->isSuspended = 0; - epicsEventSignal(pthreadInfo->suspendEvent); -} - -epicsShareFunc void epicsShareAPI epicsThreadExitMain(void) -{ - epicsThreadOSD *pthreadInfo; - - epicsThreadInit(); - pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); - if(pthreadInfo==NULL) - pthreadInfo = createImplicit(); - if(pthreadInfo->createFunc) { - errlogPrintf("called from non-main thread\n"); - cantProceed("epicsThreadExitMain"); - } - else { - free_threadInfo(pthreadInfo); - pthread_exit(0); - } -} - -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPriority(epicsThreadId pthreadInfo) -{ - assert(epicsThreadOnceCalled); - return(pthreadInfo->osiPriority); -} - -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPrioritySelf(void) -{ - epicsThreadInit(); - return(epicsThreadGetPriority(epicsThreadGetIdSelf())); -} - -epicsShareFunc void epicsShareAPI epicsThreadSetPriority(epicsThreadId pthreadInfo,unsigned int priority) -{ -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - int status; -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ - - assert(epicsThreadOnceCalled); - assert(pthreadInfo); - if(!pthreadInfo->isEpicsThread) { - fprintf(stderr,"epicsThreadSetPriority called by non epics thread\n"); - return; - } - pthreadInfo->osiPriority = priority; - if(!pthreadInfo->isRealTimeScheduled) return; - -#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - if(!pcommonAttr->usePolicy) return; - pthreadInfo->schedParam.sched_priority = epicsThreadGetPosixPriority(pthreadInfo); - status = pthread_attr_setschedparam( - &pthreadInfo->attr,&pthreadInfo->schedParam); - if(errVerbose) checkStatus(status,"pthread_attr_setschedparam"); - status = pthread_setschedparam( - pthreadInfo->tid, pthreadInfo->schedPolicy, &pthreadInfo->schedParam); - if(errVerbose) checkStatus(status,"pthread_setschedparam"); -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ -} - -epicsShareFunc epicsThreadBooleanStatus epicsShareAPI epicsThreadHighestPriorityLevelBelow( - unsigned int priority, unsigned *pPriorityJustBelow) -{ - unsigned newPriority = priority - 1; -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - int diff; - diff = pcommonAttr->maxPriority - pcommonAttr->minPriority; - if(diff<0) diff = -diff; - if(diff>1 && diff <100) newPriority -= 100/(diff+1); -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ - if (newPriority <= 99) { - *pPriorityJustBelow = newPriority; - return epicsThreadBooleanStatusSuccess; - } - return epicsThreadBooleanStatusFail; -} - -epicsShareFunc epicsThreadBooleanStatus epicsShareAPI epicsThreadLowestPriorityLevelAbove( - unsigned int priority, unsigned *pPriorityJustAbove) -{ - unsigned newPriority = priority + 1; - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - int diff; - diff = pcommonAttr->maxPriority - pcommonAttr->minPriority; - if(diff<0) diff = -diff; - if(diff>1 && diff <100) newPriority += 100/(diff+1); -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ - - if (newPriority <= 99) { - *pPriorityJustAbove = newPriority; - return epicsThreadBooleanStatusSuccess; - } - return epicsThreadBooleanStatusFail; -} - -epicsShareFunc int epicsShareAPI epicsThreadIsEqual(epicsThreadId p1, epicsThreadId p2) -{ - assert(epicsThreadOnceCalled); - assert(p1); - assert(p2); - return(pthread_equal(p1->tid,p2->tid)); -} - -epicsShareFunc int epicsShareAPI epicsThreadIsSuspended(epicsThreadId pthreadInfo) { - assert(epicsThreadOnceCalled); - assert(pthreadInfo); - return(pthreadInfo->isSuspended ? 1 : 0); -} - -epicsShareFunc void epicsShareAPI epicsThreadSleep(double seconds) -{ - struct timespec delayTime; - struct timespec remainingTime; - double nanoseconds; - - if (seconds > 0) { - delayTime.tv_sec = seconds; - nanoseconds = (seconds - delayTime.tv_sec) *1e9; - delayTime.tv_nsec = nanoseconds; - } - else { - delayTime.tv_sec = 0; - delayTime.tv_nsec = 0; - } - while (nanosleep(&delayTime, &remainingTime) == -1 && - errno == EINTR) - delayTime = remainingTime; -} - -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetIdSelf(void) { - epicsThreadOSD *pthreadInfo; - - epicsThreadInit(); - pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); - if(pthreadInfo==NULL) - pthreadInfo = createImplicit(); - assert ( pthreadInfo ); - return(pthreadInfo); -} - -epicsShareFunc pthread_t epicsThreadGetPosixThreadId ( epicsThreadId threadId ) -{ - return threadId->tid; -} - -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetId(const char *name) { - epicsThreadOSD *pthreadInfo; - int status; - - assert(epicsThreadOnceCalled); - status = mutexLock(&listLock); - checkStatus(status,"pthread_mutex_lock epicsThreadGetId"); - if(status) - return NULL; - pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); - while(pthreadInfo) { - if(strcmp(name,pthreadInfo->name) == 0) break; - pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node); - } - status = pthread_mutex_unlock(&listLock); - checkStatus(status,"pthread_mutex_unlock epicsThreadGetId"); - - return(pthreadInfo); -} - -epicsShareFunc const char epicsShareAPI *epicsThreadGetNameSelf() -{ - epicsThreadOSD *pthreadInfo; - - epicsThreadInit(); - pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); - if(pthreadInfo==NULL) - pthreadInfo = createImplicit(); - return(pthreadInfo->name); -} - -epicsShareFunc void epicsShareAPI epicsThreadGetName(epicsThreadId pthreadInfo, char *name, size_t size) -{ - assert(epicsThreadOnceCalled); - strncpy(name, pthreadInfo->name, size-1); - name[size-1] = '\0'; -} - -epicsShareFunc void epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func) -{ - epicsThreadOSD *pthreadInfo; - int status; - - epicsThreadInit(); - status = mutexLock(&listLock); - checkStatus(status, "pthread_mutex_lock epicsThreadMap"); - if (status) - return; - pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); - while (pthreadInfo) { - func(pthreadInfo); - pthreadInfo = (epicsThreadOSD *)ellNext(&pthreadInfo->node); - } - status = pthread_mutex_unlock(&listLock); - checkStatus(status, "pthread_mutex_unlock epicsThreadMap"); -} - -epicsShareFunc void epicsShareAPI epicsThreadShowAll(unsigned int level) -{ - epicsThreadOSD *pthreadInfo; - int status; - - epicsThreadInit(); - epicsThreadShow(0,level); - status = mutexLock(&listLock); - checkStatus(status,"pthread_mutex_lock epicsThreadShowAll"); - if(status) - return; - pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); - while(pthreadInfo) { - epicsThreadShowInfo(pthreadInfo,level); - pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node); - } - status = pthread_mutex_unlock(&listLock); - checkStatus(status,"pthread_mutex_unlock epicsThreadShowAll"); -} - -epicsShareFunc void epicsShareAPI epicsThreadShow(epicsThreadId showThread, unsigned int level) -{ - epicsThreadOSD *pthreadInfo; - int status; - int found = 0; - - epicsThreadInit(); - if(!showThread) { - epicsThreadShowInfo(0,level); - return; - } - status = mutexLock(&listLock); - checkStatus(status,"pthread_mutex_lock epicsThreadShowAll"); - if(status) - return; - pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); - while(pthreadInfo) { - if (((epicsThreadId)pthreadInfo == showThread) - || ((epicsThreadId)pthreadInfo->tid == showThread)) { - found = 1; - epicsThreadShowInfo(pthreadInfo,level); - } - pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node); - } - status = pthread_mutex_unlock(&listLock); - checkStatus(status,"pthread_mutex_unlock epicsThreadShowAll"); - if(status) return; - if (!found) - printf("Thread %#lx (%lu) not found.\n", (unsigned long)showThread, (unsigned long)showThread); -} - -epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate(void) -{ - pthread_key_t *key; - int status; - - epicsThreadInit(); - key = calloc(1,sizeof(pthread_key_t)); - if(!key) - return NULL; - status = pthread_key_create(key,0); - checkStatus(status,"pthread_key_create epicsThreadPrivateCreate"); - if(status) - return NULL; - return((epicsThreadPrivateId)key); -} - -epicsShareFunc void epicsShareAPI epicsThreadPrivateDelete(epicsThreadPrivateId id) -{ - pthread_key_t *key = (pthread_key_t *)id; - int status; - - assert(epicsThreadOnceCalled); - status = pthread_key_delete(*key); - checkStatusQuit(status,"pthread_key_delete","epicsThreadPrivateDelete"); - free((void *)key); -} - -epicsShareFunc void epicsShareAPI epicsThreadPrivateSet (epicsThreadPrivateId id, void *value) -{ - pthread_key_t *key = (pthread_key_t *)id; - int status; - - assert(epicsThreadOnceCalled); - if(errVerbose && !value) - errlogPrintf("epicsThreadPrivateSet: setting value of 0\n"); - status = pthread_setspecific(*key,value); - checkStatusQuit(status,"pthread_setspecific","epicsThreadPrivateSet"); -} - -epicsShareFunc void epicsShareAPI *epicsThreadPrivateGet(epicsThreadPrivateId id) -{ - pthread_key_t *key = (pthread_key_t *)id; - - assert(epicsThreadOnceCalled); - return pthread_getspecific(*key); -} - -epicsShareFunc double epicsShareAPI epicsThreadSleepQuantum () -{ - double hz; - hz = sysconf ( _SC_CLK_TCK ); - if(hz<0) - return 0.0; - return 1.0 / hz; -} - -epicsShareFunc int epicsThreadGetCPUs(void) -{ - long ret; -#ifdef _SC_NPROCESSORS_ONLN - ret = sysconf(_SC_NPROCESSORS_ONLN); - if (ret > 0) - return ret; -#endif -#ifdef _SC_NPROCESSORS_CONF - ret = sysconf(_SC_NPROCESSORS_CONF); - if (ret > 0) - return ret; -#endif - return 1; -} diff --git a/src/libCom/osi/os/posix/osdThread.h b/src/libCom/osi/os/posix/osdThread.h deleted file mode 100644 index 3a80b537c..000000000 --- a/src/libCom/osi/os/posix/osdThread.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef osdThreadh -#define osdThreadh - -#include - -#include "shareLib.h" -#include "ellLib.h" -#include "epicsEvent.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct epicsThreadOSD { - ELLNODE node; - pthread_t tid; - pthread_attr_t attr; - struct sched_param schedParam; - int schedPolicy; - EPICSTHREADFUNC createFunc; - void *createArg; - epicsEventId suspendEvent; - int isSuspended; - int isEpicsThread; - int isRealTimeScheduled; - int isOnThreadList; - unsigned int osiPriority; - char name[1]; /* actually larger */ -} epicsThreadOSD; - -epicsShareFunc pthread_t epicsThreadGetPosixThreadId(epicsThreadId id); -epicsShareFunc int epicsThreadGetPosixPriority(epicsThreadId id); - -#ifdef __cplusplus -} -#endif - -#endif /* osdThreadh */ diff --git a/src/libCom/osi/os/posix/osdThreadExtra.c b/src/libCom/osi/os/posix/osdThreadExtra.c deleted file mode 100644 index af622dc08..000000000 --- a/src/libCom/osi/os/posix/osdThreadExtra.c +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 18JAN2000 */ - -/* This is part of the posix implementation of epicsThread */ - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "ellLib.h" -#include "epicsEvent.h" -#include "epicsThread.h" - -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault; -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain; - -void epicsThreadShowInfo(epicsThreadOSD *pthreadInfo, unsigned int level) -{ - if(!pthreadInfo) { - fprintf(epicsGetStdout()," NAME EPICS ID " - "PTHREAD ID OSIPRI OSSPRI STATE\n"); - } else { - struct sched_param param; - int policy; - int priority = 0; - - if(pthreadInfo->tid) { - int status; - status = pthread_getschedparam(pthreadInfo->tid,&policy,¶m); - if(!status) priority = param.sched_priority; - } - fprintf(epicsGetStdout(),"%16.16s %14p %12lu %3d%8d %8.8s\n", - pthreadInfo->name,(void *) - pthreadInfo,(unsigned long)pthreadInfo->tid, - pthreadInfo->osiPriority,priority, - pthreadInfo->isSuspended?"SUSPEND":"OK"); - } -} - diff --git a/src/libCom/osi/os/posix/osdTime.cpp b/src/libCom/osi/os/posix/osdTime.cpp deleted file mode 100644 index d5fb05a1c..000000000 --- a/src/libCom/osi/os/posix/osdTime.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include -#include - -#include "osiSock.h" - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsTime.h" -#include "generalTimeSup.h" - -#ifdef CLOCK_REALTIME - #include "osiClockTime.h" - - #define TIME_INIT ClockTime_Init(CLOCKTIME_NOSYNC) -#else - /* Some posix systems may not have CLOCK_REALTIME */ - - #define TIME_INIT generalTimeCurrentTpRegister("GetTimeOfDay", \ - LAST_RESORT_PRIORITY, osdTimeGetCurrent) - - extern "C" { - static int osdTimeGetCurrent (epicsTimeStamp *pDest) - { - struct timeval tv; - struct timezone tz; - - if (gettimeofday (&tv, &tz)) - return errno; - - *pDest = epicsTime(tv); - return epicsTimeOK; - } - } // extern "C" -#endif - -#ifdef __CYGWIN__ -int clock_settime(clockid_t clock, const timespec *tp) -{ - return -EFAULT; -} -#endif - - -static int timeRegister(void) -{ - TIME_INIT; - return 1; -} -static int done = timeRegister(); - - -int epicsTime_gmtime ( const time_t *pAnsiTime, - struct tm *pTM ) -{ - struct tm * pRet = gmtime_r ( pAnsiTime, pTM ); - if ( pRet ) { - return epicsTimeOK; - } - else { - return errno; - } -} - -int epicsTime_localtime ( const time_t *clock, - struct tm *result ) -{ - struct tm * pRet = localtime_r ( clock, result ); - if ( pRet ) { - return epicsTimeOK; - } - else { - return errno; - } -} - -extern "C" epicsShareFunc void - convertDoubleToWakeTime(double timeout,struct timespec *wakeTime) -{ - struct timespec now, wait; - int status; - - if (timeout < 0.0) - timeout = 0.0; - else if (timeout > 60 * 60 * 24 * 3652.5) - timeout = 60 * 60 * 24 * 3652.5; /* 10 years */ - -#ifdef CLOCK_REALTIME - status = clock_gettime(CLOCK_REALTIME, &now); -#else - { - struct timeval tv; - struct timezone tz; - status = gettimeofday(&tv, &tz); - now.tv_sec = tv.tv_sec; - now.tv_nsec = tv.tv_usec * 1000; - } -#endif - if (status) { - perror("convertDoubleToWakeTime"); - cantProceed("convertDoubleToWakeTime"); - } - - wait.tv_sec = static_cast< time_t >(timeout); - wait.tv_nsec = static_cast< long >((timeout - (double)wait.tv_sec) * 1e9); - - wakeTime->tv_sec = now.tv_sec + wait.tv_sec; - wakeTime->tv_nsec = now.tv_nsec + wait.tv_nsec; - if (wakeTime->tv_nsec >= 1000000000L) { - wakeTime->tv_nsec -= 1000000000L; - ++wakeTime->tv_sec; - } -} diff --git a/src/libCom/osi/os/posix/osdTime.h b/src/libCom/osi/os/posix/osdTime.h deleted file mode 100644 index d1da77696..000000000 --- a/src/libCom/osi/os/posix/osdTime.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#ifndef osdTimeh -#define osdTimeh - -#include - -#if !defined(_POSIX_TIMERS) || _POSIX_TIMERS < 0 - struct timespec { - time_t tv_sec; /* seconds since some epoch */ - long tv_nsec; /* nanoseconds within the second */ - }; -#endif /* !_POSIX_TIMERS */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void epicsShareAPI - convertDoubleToWakeTime(double timeout,struct timespec *wakeTime); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ifndef osdTimeh */ - diff --git a/src/libCom/osi/os/posix/osiUnistd.h b/src/libCom/osi/os/posix/osiUnistd.h deleted file mode 100644 index 5121261b6..000000000 --- a/src/libCom/osi/os/posix/osiUnistd.h +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include diff --git a/src/libCom/osi/os/posix/systemCallIntMech.cpp b/src/libCom/osi/os/posix/systemCallIntMech.cpp deleted file mode 100644 index cdac1d0cb..000000000 --- a/src/libCom/osi/os/posix/systemCallIntMech.cpp +++ /dev/null @@ -1,22 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" - -enum epicsSocketSystemCallInterruptMechanismQueryInfo - epicsSocketSystemCallInterruptMechanismQuery () -{ - return esscimqi_socketBothShutdownRequired; -} diff --git a/src/libCom/osi/os/solaris/epicsAtomicOSD.h b/src/libCom/osi/os/solaris/epicsAtomicOSD.h deleted file mode 100644 index 1fa23bd88..000000000 --- a/src/libCom/osi/os/solaris/epicsAtomicOSD.h +++ /dev/null @@ -1,185 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#include "shareLib.h" - -#ifndef epicsAtomicOSD_h -#define epicsAtomicOSD_h - -#define EPICS_ATOMIC_OS_NAME "Solaris" - -#if defined ( __SunOS_5_10 ) - -/* - * atomic.h exists only in Solaris 10 or higher - */ -#include - -#include "epicsAssert.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -#define EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - membar_consumer (); -} -#endif - -#ifndef EPICS_ATOMIC_WRITE_MEMORY_BARRIER -#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - membar_producer (); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_INTT -#define EPICS_ATOMIC_CAS_INTT -EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget, - int oldVal, int newVal ) -{ - STATIC_ASSERT ( sizeof ( int ) == sizeof ( unsigned ) ); - unsigned * const pTarg = ( unsigned * ) pTarget; - return ( int ) atomic_cas_uint ( pTarg, ( unsigned ) oldVal, - ( unsigned ) newVal ); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_SIZET -#define EPICS_ATOMIC_CAS_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( - size_t * pTarget, - size_t oldVal, size_t newVal ) -{ - STATIC_ASSERT ( sizeof ( ulong_t ) == sizeof ( size_t ) ); - ulong_t * const pTarg = ( ulong_t * ) pTarget; - return ( size_t ) atomic_cas_ulong ( pTarg, oldVal, newVal ); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_PTRT -#define EPICS_ATOMIC_CAS_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( - EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldVal, - EpicsAtomicPtrT newVal ) -{ - return atomic_cas_ptr ( pTarget, oldVal, newVal ); -} -#endif - -#ifndef EPICS_ATOMIC_INCR_INTT -#define EPICS_ATOMIC_INCR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget ) -{ - STATIC_ASSERT ( sizeof ( unsigned ) == sizeof ( int ) ); - unsigned * const pTarg = ( unsigned * ) ( pTarget ); - return ( int ) atomic_inc_uint_nv ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_INCR_SIZET -#define EPICS_ATOMIC_INCR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ) -{ - STATIC_ASSERT ( sizeof ( ulong_t ) == sizeof ( size_t ) ); - ulong_t * const pTarg = ( ulong_t * ) pTarget; - return ( size_t ) atomic_inc_ulong_nv ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_DECR_INTT -#define EPICS_ATOMIC_DECR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget ) -{ - STATIC_ASSERT ( sizeof ( unsigned ) == sizeof ( int ) ); - unsigned * const pTarg = ( unsigned * ) ( pTarget ); - return ( int ) atomic_dec_uint_nv ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_DECR_SIZET -#define EPICS_ATOMIC_DECR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ) -{ - STATIC_ASSERT ( sizeof ( ulong_t ) == sizeof ( size_t ) ); - ulong_t * const pTarg = ( ulong_t * ) pTarget; - return ( size_t ) atomic_dec_ulong_nv ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_ADD_INTT -#define EPICS_ATOMIC_ADD_INTT -EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta ) -{ - STATIC_ASSERT ( sizeof ( unsigned ) == sizeof ( int ) ); - unsigned * const pTarg = ( unsigned * ) ( pTarget ); - return ( int ) atomic_add_int_nv ( pTarg, delta ); -} -#endif - -#ifndef EPICS_ATOMIC_ADD_SIZET -#define EPICS_ATOMIC_ADD_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, - size_t delta ) -{ - STATIC_ASSERT ( sizeof ( ulong_t ) == sizeof ( size_t ) ); - ulong_t * const pTarg = ( ulong_t * ) pTarget; - return ( size_t ) atomic_add_long_nv ( pTarg, ( long ) delta ); -} -#endif - -#ifndef EPICS_ATOMIC_SUB_SIZET -#define EPICS_ATOMIC_SUB_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, - size_t delta ) -{ - STATIC_ASSERT ( sizeof ( ulong_t ) == sizeof ( size_t ) ); - ulong_t * const pTarg = ( ulong_t * ) pTarget; - long sdelta = ( long ) delta; - return ( size_t ) atomic_add_long_nv ( pTarg, -sdelta ); -} -#endif - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#endif /* ifdef __SunOS_5_10 */ - -typedef struct EpicsAtomicLockKey { - char dummy; -} EpicsAtomicLockKey; - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void epicsAtomicLock ( struct EpicsAtomicLockKey * ); -epicsShareFunc void epicsAtomicUnlock ( struct EpicsAtomicLockKey * ); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#include "epicsAtomicDefault.h" - -#endif /* epicsAtomicOSD_h */ - diff --git a/src/libCom/osi/os/solaris/epicsMath.h b/src/libCom/osi/os/solaris/epicsMath.h deleted file mode 100644 index 87d4986a7..000000000 --- a/src/libCom/osi/os/solaris/epicsMath.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne, LLC as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_epicsMath_H -#define INC_epicsMath_H - -#include -#include -#include - -#ifndef isinf -# define isinf(x) (((x)==(x)) && !finite((x))) -/* same as (!isnan(x) && !finite(x)) */ -#endif - -#ifndef isnan -# define isnan(x) ((x) != (x)) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsMath_H */ diff --git a/src/libCom/osi/os/solaris/osdBackTrace.cpp b/src/libCom/osi/os/solaris/osdBackTrace.cpp deleted file mode 100644 index 55d5e3648..000000000 --- a/src/libCom/osi/os/solaris/osdBackTrace.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2014 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsStackTracePvt.h" - -struct wlk { - void **buf; - int max; - int cur; -}; - - -extern "C" { - -static int -walker(uintptr_t addr, int sig, void *arg) -{ -struct wlk *w_p = (struct wlk *)arg; - if ( w_p->cur < w_p->max ) - w_p->buf[w_p->cur++] = (void*)addr; - return 0; -} - -} - -int epicsBackTrace(void **buf, int buf_sz) -{ -ucontext_t u; -struct wlk d; - d.buf = buf; - d.max = buf_sz; - d.cur = 0; - if ( getcontext(&u) ) - return -1; - walkcontext( &u, walker, &d ); - return d.cur; -} diff --git a/src/libCom/osi/os/solaris/osdFindAddr.c b/src/libCom/osi/os/solaris/osdFindAddr.c deleted file mode 100644 index 84d17d96f..000000000 --- a/src/libCom/osi/os/solaris/osdFindAddr.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include "osdElfFindAddr.c" diff --git a/src/libCom/osi/os/solaris/osdSock.h b/src/libCom/osi/os/solaris/osdSock.h deleted file mode 100644 index a39c6c3d3..000000000 --- a/src/libCom/osi/os/solaris/osdSock.h +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Solaris specific socket include - */ - -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; - -#if SOLARIS > 6 || defined ( _SOCKLEN_T ) - typedef uint32_t osiSocklen_t; -#else - typedef int osiSocklen_t; -#endif - -#define DOES_NOT_ACCEPT_ZERO_LENGTH_UDP - -#define FD_IN_FDSET(FD) ((FD)=0) - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EACCES EACCES -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE -#define SOCK_EMFILE EMFILE -#define SOCK_SHUTDOWN ESHUTDOWN -#define SOCK_ENOTSOCK ENOTSOCK -#define SOCK_EBADF EBADF - -#ifndef SHUT_RD -# define SHUT_RD 0 -#endif - -#ifndef SHUT_WR -# define SHUT_WR 1 -#endif - -#ifndef SHUT_RDWR -# define SHUT_RDWR 2 -#endif - -#ifndef INADDR_NONE -# define INADDR_NONE (0xffffffff) -#endif - -#define ifreq_size(pifreq) (sizeof(pifreq->ifr_name)) - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/solaris/osdStrtod.h b/src/libCom/osi/os/solaris/osdStrtod.h deleted file mode 100644 index b5fda31c3..000000000 --- a/src/libCom/osi/os/solaris/osdStrtod.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * This header fragment is intended to be included as part of epicsString.h - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * epicsStrtod() for systems with broken strtod() routine - */ -epicsShareFunc double epicsStrtod(const char *str, char **endp); - -#ifdef __cplusplus -} -#endif diff --git a/src/libCom/osi/os/solaris/osdWireConfig.h b/src/libCom/osi/os/solaris/osdWireConfig.h deleted file mode 100644 index 277fe395e..000000000 --- a/src/libCom/osi/os/solaris/osdWireConfig.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Solaris version of - * osdWireConfig.h - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef osdWireConfig_h -#define osdWireConfig_h - -#include - -#if defined ( _LITTLE_ENDIAN ) -# define EPICS_BYTE_ORDER EPICS_ENDIAN_LITTLE -#elif defined ( _BIG_ENDIAN ) -# define EPICS_BYTE_ORDER EPICS_ENDIAN_BIG -#else -# error EPICS hasnt been ported to byte order specified by on Solaris -#endif - -/* for now, assume that Solaris doesnt run on weird arch like ARM NWFP */ -#define EPICS_FLOAT_WORD_ORDER EPICS_BYTE_ORDER - -#endif /* ifdef osdWireConfig_h */ - diff --git a/src/libCom/osi/os/solaris/osiFileName.h b/src/libCom/osi/os/solaris/osiFileName.h deleted file mode 100644 index b79203992..000000000 --- a/src/libCom/osi/os/solaris/osiFileName.h +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * osiFileName.h - * Author: Jeff Hill - * - * - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/vxWorks/atReboot.cpp b/src/libCom/osi/os/vxWorks/atReboot.cpp deleted file mode 100644 index 2f755c581..000000000 --- a/src/libCom/osi/os/vxWorks/atReboot.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* atReboot.cpp */ - -/* Author: Marty Kraimer Date: 30AUG2003 */ - -#include - -#include "epicsFindSymbol.h" -#include "epicsExit.h" - -extern "C" { - -typedef int (*sysAtReboot_t)(void(func)(void)); - -void atRebootRegister(void) -{ - sysAtReboot_t sysAtReboot = (sysAtReboot_t) epicsFindSymbol("_sysAtReboot"); - - if (sysAtReboot) { - STATUS status = sysAtReboot(epicsExitCallAtExits); - - if (status) { - printf("atReboot: sysAtReboot returned error %d\n", status); - } - } else { - printf("BSP routine sysAtReboot() not found, epicsExit() will not be\n" - "called by reboot. For reduced functionality, call\n" - " rebootHookAdd(epicsExitCallAtExits)\n"); - } -} - -} diff --git a/src/libCom/osi/os/vxWorks/camacLib.h b/src/libCom/osi/os/vxWorks/camacLib.h deleted file mode 100644 index a30ab5659..000000000 --- a/src/libCom/osi/os/vxWorks/camacLib.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* camacLib.h -- Prototypes for camacLib.o - * - * Marty Wise - * 10/11/93 - * - */ - -/********************************/ -/* GLOBAL DATA */ -/********************************/ -extern int debug_hook; - -extern struct glob_dat { - int total; - int read_error[5]; - int write_error[5]; - int cmd_error[5]; - int total_err; - int lam_count[12]; -} debug_dat; - - -/********************************/ -/* FUNCTION PROTOTYPES */ -/********************************/ - -void cdreg(int *ext, int b, int c, int n, int a); -void cfsa(int f, int ext, int *dat, int *q); -void cssa(int f, int ext, short *dat, int *q); -void ccci(int ext, int l); -void cccz(int ext); -void cccc(int ext); -void ccinit(int b); -void ctci(int ext, int *l); -void cgreg(int ext, int *b, int *c, int *n, int *a); -void cfmad(int f, int extb[2], int *intc, int cb[4]); -void cfubc(int f, int ext, int *intc, int cb[4]); -void cfubc(int f, int ext, int *intc, int cb[4]); -void csmad(int f, int extb[2], short *intc, int cb[4]); -void ctcd(int ext, int *l); -void cccd(int ext, int l); -void csga(int fa[], int exta[], unsigned short intc[], int qa[], int cb[4]); -void cfga(int fa[], int exta[], int intc[], int qa[], int cb[4]); -void cfubr(int f, int ext, int intc[], int cb[4]); -void csubc(int f, int ext, unsigned short *intc, int cb[4]); -void csubr(int f, int ext, int intc[], int cb[4]); -void print_reg(int ext); - diff --git a/src/libCom/osi/os/vxWorks/devLibVMEOSD.c b/src/libCom/osi/os/vxWorks/devLibVMEOSD.c deleted file mode 100644 index 82bec603d..000000000 --- a/src/libCom/osi/os/vxWorks/devLibVMEOSD.c +++ /dev/null @@ -1,502 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Archictecture dependent support for common device driver resources - * - * Author: Jeff Hill - * Date: 10-30-98 - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsFindSymbol.h" -#include "devLibVME.h" -#include "errlog.h" - -typedef void myISR (void *pParam); - -#if CPU_FAMILY != PPC -/* - * A list of the names of the unexpected interrupt handlers - * ( some of these are provided by wrs ) - */ -static char *defaultHandlerNames[] = { - "excStub", - "excIntStub", - "unsolicitedHandlerEPICS"}; - -static myISR *defaultHandlerAddr[NELEMENTS(defaultHandlerNames)]; -#endif - -static myISR *isrFetch(unsigned vectorNumber); - -/* - * this routine needs to be in the symbol table - * (i.e. not static) for this code to work correctly - */ -void unsolicitedHandlerEPICS(int vectorNumber); - -/* - * this is in veclist.c - */ -int cISRTest(void (*)(), void (**)(), void **); - -/* - * Make sure that the CR/CSR addressing mode is defined. - * (it may not be in older versions of vxWorks) - */ -#ifndef VME_AM_CSR -# define VME_AM_CSR (0x2f) -#endif - -/* - * we use a translation between an EPICS encoding - * and a vxWorks encoding here - * to reduce dependency of drivers on vxWorks - * - * we assume that the BSP are configured to use these - * address modes by default - */ - -#define EPICSAddrTypeNoConvert -1 - -int EPICStovxWorksAddrType[] - = { - VME_AM_SUP_SHORT_IO, - VME_AM_STD_SUP_DATA, - VME_AM_EXT_SUP_DATA, - EPICSAddrTypeNoConvert, - VME_AM_CSR - }; - -#if CPU_FAMILY != PPC -static void initHandlerAddrList(void); -#endif - -/* - * maps logical address to physical address, but does not detect - * two device drivers that are using the same address range - */ -static long vxDevMapAddr (epicsAddressType addrType, unsigned options, - size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress); - -/* - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ -static long vxDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue); - -/* - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ -static long vxDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue); - -static void *devA24Malloc(size_t size); -static void devA24Free(void *pBlock); -static long devInit(void) { return 0;} - -static long vxDevConnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)(), - void *parameter); - -static long vxDevDisconnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)() -); - -static long vxDevEnableInterruptLevelVME (unsigned level); - -static long vxDevDisableInterruptLevelVME (unsigned level); - -static int vxDevInterruptInUseVME (unsigned vectorNumber); - -/* - * used by dynamic bind in devLib.c - */ -static devLibVME vxVirtualOS = { - vxDevMapAddr, vxDevReadProbe, vxDevWriteProbe, - vxDevConnectInterruptVME, vxDevDisconnectInterruptVME, - vxDevEnableInterruptLevelVME, vxDevDisableInterruptLevelVME, - devA24Malloc,devA24Free,devInit,vxDevInterruptInUseVME -}; -devLibVME *pdevLibVME = &vxVirtualOS; - -/* - * devConnectInterruptVME - * - * wrapper to minimize driver dependency on vxWorks - */ -static long vxDevConnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)(), - void *parameter) -{ - int status; - - - if (devInterruptInUseVME(vectorNumber)) { - return S_dev_vectorInUse; - } - status = intConnect( - (void *)INUM_TO_IVEC(vectorNumber), - pFunction, - (int) parameter); - if (status<0) { - return S_dev_vecInstlFail; - } - - return 0; -} - -/* - * - * vxDevDisconnectInterruptVME() - * - * wrapper to minimize driver dependency on vxWorks - * - * The parameter pFunction should be set to the C function pointer that - * was connected. It is used as a key to prevent a driver from removing - * an interrupt handler that was installed by another driver - * - */ -static long vxDevDisconnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)() -) -{ - void (*psub)(); - int status; - -# if CPU_FAMILY == PPC - return S_dev_vecInstlFail; -# endif - - /* - * If pFunction not connected to this vector - * then they are probably disconnecting from the wrong vector - */ - psub = isrFetch(vectorNumber); - if(psub != pFunction){ - return S_dev_vectorNotInUse; - } - - status = intConnect( - (void *)INUM_TO_IVEC(vectorNumber), - unsolicitedHandlerEPICS, - (int) vectorNumber); - if(status<0){ - return S_dev_vecInstlFail; - } - - return 0; -} - -/* - * enable VME interrupt level - */ -static long vxDevEnableInterruptLevelVME (unsigned level) -{ -# if CPU_FAMILY != I80X86 - int s; - s = sysIntEnable (level); - if (s!=OK) { - return S_dev_intEnFail; - } - return 0; -# else - return S_dev_intEnFail; -# endif -} - -/* - * enable ISA interrupt level - */ -long devEnableInterruptLevelISA (unsigned level) -{ -# if CPU_FAMILY == I80X86 - int s; - s = sysIntEnablePIC (level); - if (s!=OK) { - return S_dev_intEnFail; - } - return 0; -# else - return S_dev_intEnFail; -# endif -} - -/* - * disable ISA interrupt level - */ -long devDisableInterruptLevelISA (unsigned level) -{ -# if CPU_FAMILY == I80X86 - int s; - s = sysIntDisablePIC (level); - if (s!=OK) { - return S_dev_intEnFail; - } -# else - return S_dev_intEnFail; -# endif - - return 0; -} - -/* - * disable VME interrupt level - */ -static long vxDevDisableInterruptLevelVME (unsigned level) -{ -# if CPU_FAMILY != I80X86 - int s; - s = sysIntDisable (level); - if (s!=OK) { - return S_dev_intDissFail; - } - return 0; -# else - return S_dev_intEnFail; -# endif -} - -/* - * vxDevMapAddr () - */ -static long vxDevMapAddr (epicsAddressType addrType, unsigned options, - size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress) -{ - long status; - - if (ppPhysicalAddress==NULL) { - return S_dev_badArgument; - } - - if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert) - { - *ppPhysicalAddress = (void *) logicalAddress; - } - else - { - status = sysBusToLocalAdrs (EPICStovxWorksAddrType[addrType], - (char *) logicalAddress, (char **)ppPhysicalAddress); - if (status) { - return S_dev_addrMapFail; - } - } - - return 0; -} - -/* - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isn't present - */ -static long vxDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) -{ - long status; - - status = vxMemProbe ((char *)ptr, VX_READ, wordSize, (char *) pValue); - if (status!=OK) { - return S_dev_noDevice; - } - - return 0; -} - -/* - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isn't present - */ -static long vxDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue) -{ - long status; - - status = vxMemProbe ((char *)ptr, VX_WRITE, wordSize, (char *) pValue); - if (status!=OK) { - return S_dev_noDevice; - } - - return 0; -} - -/* - * isrFetch() - */ -static myISR *isrFetch(unsigned vectorNumber) -{ - myISR *psub; - myISR *pCISR; - void *pParam; - int s; - - /* - * fetch the handler or C stub attached at this vector - */ - psub = (myISR *) intVecGet((FUNCPTR *)INUM_TO_IVEC(vectorNumber)); - - if ( psub ) { - /* - * from libvxWorks/veclist.c - * - * checks to see if it is a C ISR - * and if so finds the function pointer and - * the parameter passed - */ - s = cISRTest(psub, &pCISR, &pParam); - if(!s){ - psub = pCISR; - } - } - - return psub; -} - -/* - * determine if a VME interrupt vector is in use - */ -static int vxDevInterruptInUseVME (unsigned vectorNumber) -{ -#if CPU_FAMILY == PPC - return FALSE; -#else - { - static int init; - int i; - myISR *psub; - - if (!init) { - initHandlerAddrList(); - init = TRUE; - } - - psub = isrFetch (vectorNumber); - - /* - * its a C routine. Does it match a default handler? - */ - for (i=0; i -#endif - -#include "vxWorks.h" /* obtain the version of vxWorks */ -#include "epicsAssert.h" - -/* - * With vxWorks 6.6 and later we need to use vxAtomicLib - * to implement this functionality correctly on SMP systems - */ -#if _WRS_VXWORKS_MAJOR * 100 + _WRS_VXWORKS_MINOR >= 606 - -#include -#include - -#define EPICS_ATOMIC_OS_NAME "VX-ATOMICLIB" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -#define EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - VX_MEM_BARRIER_R (); -} -#endif - -#ifndef EPICS_ATOMIC_WRITE_MEMORY_BARRIER -#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - VX_MEM_BARRIER_W (); -} -#endif - -/* - * we make the probably correct guess that if ULONG_MAX - * is the same as UINT_MAX then sizeof ( atomic_t ) - * will be the same as sizeof ( size_t ) - * - * if ULONG_MAX != UINT_MAX then its 64 bit vxWorks and - * WRS doesnt not supply at this time the atomic interface - * for 8 byte integers that is needed - so that architecture - * receives the lock synchronized version - */ -#if ULONG_MAX == UINT_MAX - -STATIC_ASSERT ( sizeof ( atomic_t ) == sizeof ( size_t ) ); -STATIC_ASSERT ( sizeof ( atomic_t ) == sizeof ( EpicsAtomicPtrT ) ); - - -#ifndef EPICS_ATOMIC_INCR_SIZET -#define EPICS_ATOMIC_INCR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicInc ( pTarg ); - return 1 + ( size_t ) ( oldVal ); -} -#endif - -#ifndef EPICS_ATOMIC_DECR_SIZET -#define EPICS_ATOMIC_DECR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicDec ( pTarg ); - return ( ( size_t ) oldVal ) - 1u; -} -#endif - -#ifndef EPICS_ATOMIC_ADD_SIZET -#define EPICS_ATOMIC_ADD_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta ) -{ - /* - * vxAtomicLib doc indicates that vxAtomicAdd is - * implemented using signed arithmetic, but it - * does not change the end result because twos - * complement addition is used in either case - */ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicAdd ( pTarg, (atomic_t) delta ); - return delta + ( size_t ) oldVal; -} -#endif - -#ifndef EPICS_ATOMIC_SUB_SIZET -#define EPICS_ATOMIC_SUB_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta ) -{ - /* - * vxAtomicLib doc indicates that vxAtomicSub is - * implemented using signed arithmetic, but it - * does not change the end result because twos - * complement subtraction is used in either case - */ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicSub ( pTarg, (atomic_t) delta ); - return ( ( size_t ) oldVal ) - delta; -} -#endif - -#ifndef EPICS_ATOMIC_CAS_SIZET -#define EPICS_ATOMIC_CAS_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget, - size_t oldVal, size_t newVal ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - return ( size_t ) vxCas ( pTarg, (atomic_t) oldVal, (atomic_t) newVal ); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_PTRT -#define EPICS_ATOMIC_CAS_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - return (EpicsAtomicPtrT) vxCas ( pTarg, (atomic_t) oldVal, (atomic_t) newVal ); -} -#endif - -#else /* ULONG_MAX == UINT_MAX */ - -/* - * if its 64 bit SMP vxWorks and the compiler doesnt - * have an intrinsic then maybe there isnt any way to - * implement these without using a global lock because - * size_t is maybe bigger than atomic_t - * - * I dont yet have access to vxWorks manuals for - * 64 bit systems so this is still undecided, but is - * defaulting now to a global lock - */ - -#endif /* ULONG_MAX == UINT_MAX */ - -STATIC_ASSERT ( sizeof ( atomic_t ) == sizeof ( int ) ); - -#ifndef EPICS_ATOMIC_INCR_INTT -#define EPICS_ATOMIC_INCR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicInc ( pTarg ); - return 1 + ( int ) oldVal; -} -#endif - -#ifndef EPICS_ATOMIC_DECR_INTT -#define EPICS_ATOMIC_DECR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicDec ( pTarg ); - return ( ( int ) oldVal ) - 1; -} -#endif - -#ifndef EPICS_ATOMIC_ADD_INTT -#define EPICS_ATOMIC_ADD_INTT -EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicAdd ( pTarg, (atomic_t) delta ); - return delta + ( int ) oldVal; -} -#endif - -#ifndef EPICS_ATOMIC_CAS_INTT -#define EPICS_ATOMIC_CAS_INTT -EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget, - int oldVal, int newVal ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - return ( int ) vxCas ( pTarg, (atomic_t) oldVal, (atomic_t) newVal ); -} -#endif - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#else /* _WRS_VXWORKS_MAJOR * 100 + _WRS_VXWORKS_MINOR >= 606 */ - -#include "vxLib.h" -#include "intLib.h" - -#define EPICS_ATOMIC_OS_NAME "VX-INTLIB" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef EPICS_ATOMIC_LOCK -#define EPICS_ATOMIC_LOCK - -typedef struct EpicsAtomicLockKey { int m_key; } EpicsAtomicLockKey; - -EPICS_ATOMIC_INLINE void epicsAtomicLock ( EpicsAtomicLockKey * pKey ) -{ - pKey->m_key = intLock (); -} - -EPICS_ATOMIC_INLINE void epicsAtomicUnlock ( EpicsAtomicLockKey * pKey ) -{ - intUnlock ( pKey->m_key ); -} -#endif - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -#define EPICS_ATOMIC_READ_MEMORY_BARRIER -/* - * no need for memory barrior since prior to vxWorks 6.6 it is a single cpu system - * (we are not protecting against multiple access to memory mapped IO) - */ -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) {} -#endif - -#ifndef EPICS_ATOMIC_WRITE_MEMORY_BARRIER -#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER -/* - * no need for memory barrior since prior to vxWorks 6.6 it is a single cpu system - * (we are not protecting against multiple access to memory mapped IO) - */ -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) {} -#endif - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#endif /* _WRS_VXWORKS_MAJOR * 100 + _WRS_VXWORKS_MINOR >= 606 */ - -#include "epicsAtomicDefault.h" - -#endif /* epicsAtomicOSD_h */ - diff --git a/src/libCom/osi/os/vxWorks/epicsDynLink.c b/src/libCom/osi/os/vxWorks/epicsDynLink.c deleted file mode 100644 index df954782a..000000000 --- a/src/libCom/osi/os/vxWorks/epicsDynLink.c +++ /dev/null @@ -1,94 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * On 68K targets, all symbols have an underscore prepended to their name. - * This code permits both standards to work, as long as you're not looking - * for a symbol name that actually begins with an underscore. - */ - -#include - -#include "epicsDynLink.h" - -#if _WRS_VXWORKS_MAJOR < 6 || _WRS_VXWORKS_MINOR < 9 - -static int symNoUnderscore(SYMTAB_ID symTblId) -{ - static int init = 0; - static int noUnderscore = 0; - - if (!init) { - char name[] = "symFindByNameEPICS"; - char *pSymValue; - SYM_TYPE type; - - if (symFindByName(symTblId, name, &pSymValue, &type) == OK) - noUnderscore = 1; - init = 1; - } - return noUnderscore; -} - -STATUS symFindByNameEPICS(SYMTAB_ID symTblId, char *name, char **ppvalue, - SYM_TYPE *pType) -{ - if (name[0] == '_' && symNoUnderscore(symTblId)) - name++; - - return symFindByName(symTblId, name, ppvalue, pType); -} - -STATUS symFindByNameAndTypeEPICS(SYMTAB_ID symTblId, char *name, - char **ppvalue, SYM_TYPE *pType, SYM_TYPE sType, SYM_TYPE mask) -{ - if (name[0] == '_' && symNoUnderscore(symTblId)) - name++; - - return symFindByNameAndType(symTblId, name, ppvalue, pType, sType, mask); -} - -#else /* VxWorks 6.9 deprecated the symFindBy routines */ - -STATUS symFindByNameEPICS(SYMTAB_ID symTblId, char *name, char **ppvalue, - SYM_TYPE *pType) -{ - SYMBOL_DESC symDesc; - STATUS status; - - memset(&symDesc, 0, sizeof(SYMBOL_DESC)); - symDesc.mask = SYM_FIND_BY_NAME; - symDesc.name = name + (name[0] == '_'); - status = symFind(sysSymTbl, &symDesc); - if (!status) { - *ppvalue = symDesc.value; - *pType = symDesc.type; - } - return status; -} - -STATUS symFindByNameAndTypeEPICS(SYMTAB_ID symTblId, char *name, - char **ppvalue, SYM_TYPE *pType, SYM_TYPE sType, SYM_TYPE mask) -{ - SYMBOL_DESC symDesc; - STATUS status; - - memset(&symDesc, 0, sizeof(SYMBOL_DESC)); - symDesc.mask = SYM_FIND_BY_NAME | SYM_FIND_BY_TYPE; - symDesc.name = name + (name[0] == '_'); - symDesc.type = sType; - symDesc.typeMask = mask; - status = symFind(sysSymTbl, &symDesc); - if (!status) { - *ppvalue = symDesc.value; - *pType = symDesc.type; - } - return status; -} - -#endif diff --git a/src/libCom/osi/os/vxWorks/epicsDynLink.h b/src/libCom/osi/os/vxWorks/epicsDynLink.h deleted file mode 100644 index 581260a49..000000000 --- a/src/libCom/osi/os/vxWorks/epicsDynLink.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * These routines will eventually need to be made OS independent - * (currently this is vxWorks specific) - */ - -#ifndef epicsDynLinkh -#define epicsDynLinkh - -#include "vxWorks.h" -#include "symLib.h" -#include "sysSymTbl.h" -#include "compilerDependencies.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Use epicsFindSymbol() instead of these */ - -STATUS symFindByNameEPICS(SYMTAB_ID symTblId, char *name, char **pvalue, - SYM_TYPE *pType) EPICS_DEPRECATED; - -STATUS symFindByNameAndTypeEPICS(SYMTAB_ID symTblId, char *name, char **pvalue, - SYM_TYPE *pType, SYM_TYPE sType, SYM_TYPE mask) EPICS_DEPRECATED; - -#ifdef __cplusplus -} -#endif - -#endif /* ifdef epicsDynLinkh */ - diff --git a/src/libCom/osi/os/vxWorks/epicsMMIO.h b/src/libCom/osi/os/vxWorks/epicsMMIO.h deleted file mode 100644 index b12c71ad9..000000000 --- a/src/libCom/osi/os/vxWorks/epicsMMIO.h +++ /dev/null @@ -1,174 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2006 The Regents of the University of California, -* as Operator of Los Alamos National Laboratory. -* Copyright (c) 2006 The Board of Trustees of the Leland Stanford Junior -* University, as Operator of the Stanford Linear Accelerator Center. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Original Author: Eric Bjorklund (was called mrfSyncIO.h) - * Author: Michael Davidsaver - */ - -#ifndef EPICSMMIO_H -#define EPICSMMIO_H - -#if (CPU_FAMILY != PPC) && (CPU_FAMILY != I80X86) -# include "epicsMMIODef.h" -#else - -/**************************************************************************************************/ -/* Required Header Files */ -/**************************************************************************************************/ - -/* This is needed on vxWorks 6.8 */ -#ifndef _VSB_CONFIG_FILE -# define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> -#endif - -#include /* vxWorks common definitions */ -#include /* vxWorks System Library Definitions */ -#include /* vxWorks Version Definitions */ - -#include /* EPICS Common Type Definitions */ -#include /* EPICS Byte Order Definitions */ -#include - -/*===================== - * vxAtomicLib.h (which defines the memory barrier macros) - * is available on vxWorks 6.6 and above. - */ - -#if _WRS_VXWORKS_MAJOR > 6 -# include -#elif _WRS_VXWORKS_MAJOR == 6 && _WRS_VXWORKS_MINOR >= 6 -# include -#endif - -static EPICS_ALWAYS_INLINE -epicsUInt16 -bswap16(epicsUInt16 value) -{ - return (((epicsUInt16)(value) & 0x00ff) << 8) | - (((epicsUInt16)(value) & 0xff00) >> 8); -} - -static EPICS_ALWAYS_INLINE -epicsUInt32 -bswap32(epicsUInt32 value) -{ - return (((epicsUInt32)(value) & 0x000000ff) << 24) | - (((epicsUInt32)(value) & 0x0000ff00) << 8) | - (((epicsUInt32)(value) & 0x00ff0000) >> 8) | - (((epicsUInt32)(value) & 0xff000000) >> 24); -} - -#if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG -# define be16_to_cpu(X) (epicsUInt16)(X) -# define be32_to_cpu(X) (epicsUInt32)(X) -# define le16_to_cpu(X) bswap16(X) -# define le32_to_cpu(X) bswap32(X) - -#elif EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE -# define be16_to_cpu(X) bswap16(X) -# define be32_to_cpu(X) bswap32(X) -# define le16_to_cpu(X) (epicsUInt16)(X) -# define le32_to_cpu(X) (epicsUInt32)(X) - -#else -# error Unable to determine native byte order -#endif - -#if CPU_FAMILY == PPC - -/* All PowerPC BSPs that I have studied implement these functions - * with the same definition, byte-swapping the data and adding a - * sync and/or eieio instruction as necessary on that CPU board. - * They do *not* all implement the sys{In/Out}{Byte/Word/Long} - * functions to do the same thing though, so we can't use them. - */ -#ifdef __cplusplus -extern "C" { -#endif -UINT8 sysPciInByte(UINT8 *addr); -void sysPciOutByte(UINT8 *addr, UINT8 data); -UINT16 sysPciInWord(UINT16 *addr); -void sysPciOutWord(UINT16 *addr, UINT16 data); -UINT32 sysPciInLong (UINT32 *addr); -void sysPciOutLong (UINT32 *addr, UINT32 data); -#ifdef __cplusplus -} -#endif - -#define ioread8(address) sysPciInByte((UINT8 *)(address)) -#define iowrite8(address,data) sysPciOutByte((UINT8 *)(address), (epicsUInt8)(data)) - -#define nat_ioread16(address) bswap16(sysPciInWord((UINT16 *)(address))) -#define nat_ioread32(address) bswap32(sysPciInLong((UINT32 *)(address))) - -#define nat_iowrite16(address,data) sysPciOutWord((UINT16 *)(address), bswap16(data)) -#define nat_iowrite32(address,data) sysPciOutLong((UINT32 *)(address), bswap32(data)) - -#define be_ioread16(address) bswap16(sysPciInWord((UINT16 *)(address))) -#define be_ioread32(address) bswap32(sysPciInLong((UINT32 *)(address))) - -#define be_iowrite16(address,data) sysPciOutWord((UINT16 *)(address), bswap16(data)) -#define be_iowrite32(address,data) sysPciOutLong((UINT32 *)(address), bswap32(data)) - -#define le_ioread16(address) sysPciInWord((UINT16 *)(address)) -#define le_ioread32(address) sysPciInLong((UINT32 *)(address)) - -#define le_iowrite16(address,data) sysPciOutWord((UINT16 *)(address), (data)) -#define le_iowrite32(address,data) sysPciOutLong((UINT32 *)(address), (data)) - -#else /* CPU_FAMILY == I80X86 */ - -/* All Intel BSPs should implement the sys{In/Out}{Byte/Word/Long} - * functions, which are declared in the sysLib.h header. - */ - -#define ioread8(address) sysInByte ((epicsUInt32)(address)) -#define iowrite8(address,data) sysOutByte ((epicsUInt32)(address), (epicsUInt8)(data)) - -#define nat_ioread16(address) sysInWord ((epicsUInt32)(address)) -#define nat_ioread32(address) sysInLong ((epicsUInt32)(address)) - -#define nat_iowrite16(address,data) sysOutWord((epicsUInt32)(address),(data)) -#define nat_iowrite32(address,data) sysOutLong((epicsUInt32)(address),(data)) - -#define be_ioread16(address) be16_to_cpu (sysInWord ((epicsUInt32)(address))) -#define be_ioread32(address) be32_to_cpu (sysInLong ((epicsUInt32)(address))) - -#define be_iowrite16(address,data) sysOutWord ((epicsUInt32)(address), be16_to_cpu((epicsUInt16)(data))) -#define be_iowrite32(address,data) sysOutLong ((epicsUInt32)(address), be32_to_cpu((epicsUInt32)(data))) - -#define le_ioread16(address) le16_to_cpu (sysInWord ((epicsUInt32)(address))) -#define le_ioread32(address) le32_to_cpu (sysInLong ((epicsUInt32)(address))) - -#define le_iowrite16(address,data) sysOutWord ((epicsUInt32)(address), le16_to_cpu((epicsUInt16)(data))) -#define le_iowrite32(address,data) sysOutLong ((epicsUInt32)(address), le32_to_cpu((epicsUInt32)(data))) - -#endif /* I80X86 */ - - -#ifndef VX_MEM_BARRIER_R -# define VX_MEM_BARRIER_R() do{}while(0) -#endif -#ifndef VX_MEM_BARRIER_W -# define VX_MEM_BARRIER_W() do{}while(0) -#endif -#ifndef VX_MEM_BARRIER_RW -# define VX_MEM_BARRIER_RW() do{}while(0) -#endif - -#define rbarr() VX_MEM_BARRIER_R() -#define wbarr() VX_MEM_BARRIER_W() -#define rwbarr() VX_MEM_BARRIER_RW() - -#endif /* CPU_FAMILY */ -#endif /* EPICSMMIO_H */ diff --git a/src/libCom/osi/os/vxWorks/epicsMath.h b/src/libCom/osi/os/vxWorks/epicsMath.h deleted file mode 100644 index e973d2d9c..000000000 --- a/src/libCom/osi/os/vxWorks/epicsMath.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsMathh -#define epicsMathh - -#include -#include -#include - -/* private/mathP.h defines NAN as 4, and uses its value in the - * isNan() macro. We need mathP.h for isInf(), but can create - * our own isnan() test. epicsMath.cpp requires that NAN either - * be undef or yield the NaN value, so this solves the issue. - */ -#undef NAN - -#define isnan(D) (!(D == D)) -#define isinf(D) isInf(D) -#define finite(D) (!isnan(D) && !isInf(D)) - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* epicsMathh */ diff --git a/src/libCom/osi/os/vxWorks/logMsgToErrlog.cpp b/src/libCom/osi/os/vxWorks/logMsgToErrlog.cpp deleted file mode 100644 index b44881cd0..000000000 --- a/src/libCom/osi/os/vxWorks/logMsgToErrlog.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * route vxWorks logMsg messages into the EPICS logging system - * - * Author: Jeff Hill - * - */ - -#include -#include - -#include -#include -#include - -#include "errlog.h" - -// vxCommonLibrary calls logMsgToErrlog so that logMsgToErrlog gets loaded -extern "C" { - int logMsgToErrlog(); -} - -int logMsgToErrlog() { return 0;} - -static class errlogDevTimeInit -{ -public: - errlogDevTimeInit (); -} errlogDevInstance; - -static int errlogOpen ( DEV_HDR *, const char *, int ) -{ - return OK; -} - -static int errlogWrite ( DEV_HDR *, const char * pInBuf, int nbytes ) -{ - errlogPrintfNoConsole ( "%.*s", nbytes, pInBuf ); - return nbytes; -} - -errlogDevTimeInit::errlogDevTimeInit () -{ - int errlogNo = iosDrvInstall ( - 0, // create not supported - 0, // remove not supported - reinterpret_cast < FUNCPTR > ( errlogOpen ), - 0, // close is a noop - 0, // read not supported - reinterpret_cast < FUNCPTR > ( errlogWrite ), - 0 // ioctl not supported - ); - if ( errlogNo == ERROR ) { - errlogPrintf ( - "Unable to install driver routing the vxWorks " - "logging system to the EPICS logging system because \"%s\"\n", - strerror ( errno ) ); - return; - } - DEV_HDR * pDev = static_cast < DEV_HDR * > ( calloc ( 1, sizeof ( *pDev ) ) ); - if ( ! pDev ) { - errlogPrintf ( - "Unable to create driver data structure for routing the vxWorks " - "logging system to the EPICS logging system because \"%s\"\n", - strerror ( errno ) ); - return; - } - int status = iosDevAdd ( pDev, "/errlog/", errlogNo ); - if ( status < 0 ) { - errlogPrintf ( - "Unable to install device routing the vxWorks " - "logging system to the EPICS logging system because \"%s\"\n", - strerror ( errno ) ); - free ( pDev ); - return; - } - int fd = open ( "/errlog/any", O_WRONLY, 0 ); - if ( fd < 0 ) { - errlogPrintf ( - "Unable to open fd routing the vxWorks " - "logging system to the EPICS logging system because \"%s\"\n", - strerror ( errno ) ); - return; - } - status = logFdAdd ( fd ); - if ( status != OK) { - errlogPrintf ( - "Unable to install fd routing the vxWorks " - "logging system to the EPICS logging system because \"%s\"\n", - strerror ( errno ) ); - close ( fd ); - return; - } -} - diff --git a/src/libCom/osi/os/vxWorks/module_types.h b/src/libCom/osi/os/vxWorks/module_types.h deleted file mode 100644 index 07372c37a..000000000 --- a/src/libCom/osi/os/vxWorks/module_types.h +++ /dev/null @@ -1,494 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* module_types.h */ -/* - * Author: Bob Dalesio - * Date: 12-07-88 - */ - -#ifndef INCLmodule_typesh -#define INCLmodule_typesh - -/* Device module types */ -/* - * all devices have corresponding entries in ~operator/db/src/menus.c - * changes must be made in both areas to keep the database and drivers in sync - */ -/* & in comment indicates tested with card 0 */ -/* % in comment indicates tested with card other than card 0 */ -/* # in comment indicates that the Nth card has been tested */ -/* !! never been tested */ - -/* - * @# If any changes are made to this file, check the procedures - * ab_card, and vme_card in signallist.c, and get_address in sigmenu.c. - */ - -#ifdef MODULE_TYPES_INIT -#define MODULE_TYPES_DEF(MT_DEF_PARM) MT_DEF_PARM -#else -#define MODULE_TYPES_DEF(MT_DEF_PARM) extern MT_DEF_PARM; -#endif - -/* Number of columns used in io_report. */ -#define IOR_MAX_COLS 4 - -/* I/O types */ -#define IO_AI 0 -#define IO_AO 1 -#define IO_BI 2 -#define IO_BO 3 -#define IO_SM 4 -#define IO_WF 5 -#define IO_TIMER 6 -#define MAX_IO_TYPE IO_TIMER - -/* bus types */ -/* must correspond to the values in link types */ -/* these defines are in ~gta/dbcon/h/link.h */ - - -/* equates for the Allen-Bradley cards. */ -#define AB_BASE_ADDR 0xc00000 /* base addr of first AB6008SV */ -#define AB_MAX_LINKS 2 /* number of serial links from VME */ -#define AB_MAX_ADAPTERS 8 /* number of physical adapters on a link */ -#define AB_MAX_CARDS 16 /* max number of IO cards per adapter */ -#define AB_CARD_ADAPTER 16 /* cards per logical adapter */ -#define AB_CHAN_CARD 16 /* max channels per card */ - -/* analog inputs */ -#define AB1771IL 0 /* &% Allen-Bradley low level analog input */ -#define AB1771IFE 1 /* &% Allen-Bradley low level analog input */ -#define AB1771IXE 2 /* &% Allen-Bradley millivolt input */ -#define XY566SE 3 /* & Xycom 12-bit Single Ended Scanned*/ -#define XY566DI 4 /* &% Xycom 12-bit Differential Scanned */ -#define XY566DIL 5 /* &% Xycom 12-bit Differential Latched */ -#define VXI_AT5_AI 6 /* % AT-5 VXI module's Analog Inputs */ -#define AB1771IFE_SE 7 /* % A-B IFE in 16 single-ended input mode */ -#define AB1771IFE_4to20MA 8 /* % A-B IFE in 8 double-ended 4to20Ma */ -#define DVX2502 9 /* &% DVX_2502 128 chan 16 bit differential */ -#define AB1771IFE_0to5V 10 /* % A-B IFE in 8 double-ended 4to20Ma */ -#define KSCV215 11 /* % KSC V215 VXI 16 bit differential */ -#define AB1771IrPlatinum 12 /* % A-B RTD Platinum */ -#define AB1771IrCopper 13 /* % A-B RTD Copper */ -#define MAX_AI_TYPES AB1771IrCopper -MODULE_TYPES_DEF(short ai_num_cards[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={12,12,12, 4, 4, 6,32,12,12, 1, 12, 32, 12,12}; -#endif -MODULE_TYPES_DEF(short ai_num_channels[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 8, 8, 8,32,16,16, 8,16, 8, 127, 8, 32,6,6}; -#endif -MODULE_TYPES_DEF(short ai_interruptable[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,0,0}; -#endif -MODULE_TYPES_DEF(short ai_bus[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 4, 4, 4, 2, 2, 2, 2, 4, 4, 2, 4, 2,4,4}; -#endif -MODULE_TYPES_DEF(unsigned short ai_addrs[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0,0,0,0x6000,0x7000,0xe000, 0xc014,0,0, 0xff00, 0, 0,0,0}; -#endif -MODULE_TYPES_DEF(long ai_memaddrs[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0,0,0,0x000000,0x040000,0x0c0000, 0,0,0, 0x100000, 0, 0,0,0}; -#endif - -/* analog outputs */ -#define AB1771OFE 0 /* &% Allen-Bradley 12 bit Analog Output */ -#define VMI4100 1 /* & VMIC VMIVME 4100 */ -#define ZIO085 2 /* & Ziomek 085 */ -#define VXI_AT5_AO 3 /* !! AT-5 VXI modules analog outputs */ -#define MAX_AO_TYPES VXI_AT5_AO -MODULE_TYPES_DEF(short ao_num_cards[MAX_AO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - = {12, 4, 1, 32}; -#endif -MODULE_TYPES_DEF(short ao_num_channels[MAX_AO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - = { 4, 16, 32, 16}; -#endif -MODULE_TYPES_DEF(short ao_interruptable[MAX_AO_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = { 0, 0, 0, 1}; -#endif -MODULE_TYPES_DEF(short ao_bus[MAX_AO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 4, 2, 2, 2}; -#endif -MODULE_TYPES_DEF(unsigned short ao_addrs[MAX_AO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0,0x4100,0x0800, 0xc000}; -#endif - -/* binary inputs */ -#define ABBI_08_BIT 0 /* &% Allen-Bradley generic Binary In 8 bit */ -#define ABBI_16_BIT 1 /* &% Allen-Bradley generic Binary In 16 bit */ -#define BB910 2 /* & BURR BROWN MPV 910 (relay) */ -#define XY210 3 /* &% XYcom 32 bit binary in */ -#define VXI_AT5_BI 4 /* !! AT-5 VXI modules binary inputs */ -#define HPE1368A_BI 5 /* !! HP E1368A video switch */ -#define AT8_FP10S_BI 6 /* !! AT8 FP10 slave fast protect */ -#define XY240_BI 7 /* !! Xycom 32 bit binary in / 32 bit binary out */ -#define MAX_BI_TYPES XY240_BI -MODULE_TYPES_DEF(short bi_num_cards[MAX_BI_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 12, 12, 4, 4, 32, 32, 8, 2}; -#endif -MODULE_TYPES_DEF(short bi_num_channels[MAX_BI_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 8, 16, 32, 32, 32, 16, 32, 32}; -#endif -MODULE_TYPES_DEF(short bi_interruptable[MAX_BI_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 1, 1, 0, 0, 1, 1, 1, 1}; -#endif -MODULE_TYPES_DEF(short bi_bus[MAX_BI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 4, 4, 2, 2, 2, 2, 2, 2}; -#endif -MODULE_TYPES_DEF(unsigned short bi_addrs[MAX_BI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0,0,0xb800,0xa000, 0xc000, 0xc000, 0x0e00, 0xd000}; -#endif - -/* binary outputs */ -#define ABBO_08_BIT 0 /* &% Allen-Bradley 8 bit binary out */ -#define ABBO_16_BIT 1 /* &% Allen-Bradley 16 bit binary out */ -#define BB902 2 /* &% BURR BROWN MPV 902 (relay) */ -#define XY220 3 /* &% XYcom 32 bit binary out */ -#define VXI_AT5_BO 4 /* !! AT-5 VXI modules binary outputs */ -#define HPE1368A_BO 5 /* !! HP E1368A video switch */ -#define AT8_FP10M_BO 6 /* !! AT8 FP10 master fast protect */ -#define XY240_BO 7 /* !! Xycom 32 bit binary in / 32 bit binary out */ -#define MAX_BO_TYPES XY240_BO -MODULE_TYPES_DEF(short bo_num_cards[MAX_BO_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={12, 12, 4, 1, 32, 32, 2, 2}; -#endif -MODULE_TYPES_DEF(short bo_num_channels[MAX_BO_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 8, 16, 32, 32, 32, 16, 32, 32}; -#endif -MODULE_TYPES_DEF(short bo_interruptable[MAX_BO_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 0, 0, 0, 0, 1, 0, 0, 1 }; -#endif -MODULE_TYPES_DEF(short bo_bus[MAX_BO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 4, 4, 2, 2, 2, 2, 2, 2 }; -#endif -MODULE_TYPES_DEF(unsigned short bo_addrs[MAX_BO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0,0,0xd800,0xc800, 0xc000, 0xc000, 0x0c00, 0xd000}; -#endif - -/* stepper motor drivers */ -#define CM57_83E 0 /* & Compumotor 57-83E motor controller */ -#define OMS_6AXIS 1 /* & OMS six axis motor controller */ -#define MAX_SM_TYPES OMS_6AXIS -MODULE_TYPES_DEF(short sm_num_cards[MAX_SM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 8, 8 }; -#endif -MODULE_TYPES_DEF(short sm_num_channels[MAX_SM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = { 1, 8}; -#endif -MODULE_TYPES_DEF(short sm_interruptable[MAX_SM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = { 0, 0 }; -#endif -MODULE_TYPES_DEF(short sm_bus[MAX_SM_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 2, 2 }; -#endif -MODULE_TYPES_DEF(unsigned short sm_addrs[MAX_SM_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0x8000, 0xfc00 }; -#endif - -/* waveforms */ -#define XY566WF 0 /* & Xycom 566 as a waveform */ -#define CAMAC_THING 1 /* !! CAMAC waveform digitizer */ -#define JGVTR1 2 /* & Joerger transient recorder */ -#define COMET 3 /* !! COMET transient recorder */ -#define MAX_WF_TYPES COMET -MODULE_TYPES_DEF(short wf_num_cards[MAX_WF_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={4, 4, 8, 4}; -#endif -MODULE_TYPES_DEF(short wf_num_channels[MAX_WF_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={1, 1, 1, 4}; -#endif -MODULE_TYPES_DEF(short wf_interruptable[MAX_WF_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = {0, 0, 0, 0}; -#endif -MODULE_TYPES_DEF(short wf_bus[MAX_WF_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={2, 3, 2, 2}; -#endif -MODULE_TYPES_DEF(unsigned short wf_addrs[MAX_WF_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0x9000, 0, 0xB000, 0xbc00}; -#endif -MODULE_TYPES_DEF(unsigned short wf_armaddrs[MAX_WF_TYPES+1]) -#ifdef MODULE_TYPES_INIT - = {0x5400, 0, 0, 0}; -#endif -MODULE_TYPES_DEF(long wf_memaddrs[MAX_WF_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0x080000, 0, 0xb80000, 0xe0000000}; -#endif - - -/* timing cards */ -#define MZ8310 0 /* &% Mizar Timing Module */ -#define DG535 1 /* !! GPIB timing instrument */ -#define VXI_AT5_TIME 2 /* !! AT-5 VXI modules timing channels */ -#define MAX_TM_TYPES VXI_AT5_TIME -MODULE_TYPES_DEF(short tm_num_cards[MAX_TM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 4, 1, 32 }; -#endif -MODULE_TYPES_DEF(short tm_num_channels[MAX_TM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={10, 1, 10}; -#endif -MODULE_TYPES_DEF(short tm_interruptable[MAX_TM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = { 1, 0, 1 }; -#endif -MODULE_TYPES_DEF(short tm_bus[MAX_TM_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 2, 5, 2 }; -#endif -MODULE_TYPES_DEF(unsigned short tm_addrs[MAX_TM_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0xf800, 0, 0xc000 }; -#endif - -/* AT830X clock cards */ -MODULE_TYPES_DEF(long AT830X_1_addrs ) -#ifdef MODULE_TYPES_INIT - = 0x0400; -#endif -MODULE_TYPES_DEF(short AT830X_1_num_cards ) -#ifdef MODULE_TYPES_INIT - = 2; -#endif -MODULE_TYPES_DEF(long AT830X_addrs ) -#ifdef MODULE_TYPES_INIT - = 0xaa0000; -#endif -MODULE_TYPES_DEF(short AT830X_num_cards ) -#ifdef MODULE_TYPES_INIT - = 2; -#endif - -/* - * system controller cards. - * (driver looks for only one card) - */ -MODULE_TYPES_DEF(long xy010ScA16Base) -#ifdef MODULE_TYPES_INIT - = 0x0000; -#endif -/* - * limit the size of the VXI logical address space - * - * = + 0xc000 - * - * LA VME address - * 0 - * EPICS_VXI_LA_COUNT + (EPICS_VXI_LA_COUNT-1)*64 - */ -MODULE_TYPES_DEF(unsigned char EPICS_VXI_LA_COUNT) -#ifdef MODULE_TYPES_INIT - = 32; -#endif - -/* - * - * address ranges for VXI A24 and A32 devices - * - */ -MODULE_TYPES_DEF(char *EPICS_VXI_A24_BASE) -#ifdef MODULE_TYPES_INIT - = (char *) 0x900000; -#endif -MODULE_TYPES_DEF(unsigned long EPICS_VXI_A24_SIZE) -#ifdef MODULE_TYPES_INIT - = 0x100000; -#endif -MODULE_TYPES_DEF(char *EPICS_VXI_A32_BASE) -#ifdef MODULE_TYPES_INIT - = (char *) 0x90000000; -#endif -MODULE_TYPES_DEF(unsigned long EPICS_VXI_A32_SIZE) -#ifdef MODULE_TYPES_INIT - = 0x10000000; -#endif - - -/****************************************************************************** - * - * Interrupt vector locations used by the MV167 CPU board. - * These are defined in mv167.h - * - * PCC2_INT_VEC_BASE 0x40 PCC interrupt vector base number - * any multiple of 0x10 - * UTIL_INT_VEC_BASE0 0x50 VMEchip2 utility interrupt - * vector base number - * any multiple of 0x10 - * UTIL_INT_VEC_BASE1 0x60 VMEchip2 utility interrupt - * vector base number - * any multiple of 0x10 - * - * INT_VEC_CD2400_A 0x90 int vec for channel A - * INT_VEC_CD2400_B 0x94 int vec for channel B - * INT_VEC_CD2400_C 0x98 int vec for channel C - * INT_VEC_CD2400_D 0x9c int vec for channel D - * - * LANC_IRQ_LEVEL 3 LNANC IRQ level - * MPCC_IRQ_LEVEL 4 serial comm IRQ level - * SYS_CLK_LEVEL 6 interrupt level for sysClk - * AUX_CLK_LEVEL 5 interrupt level for auxClk - * SCSI_IRQ_LEVEL 2 scsi interrupt level - * - ******************************************************************************/ - -/* interrupt vector allocation - one for each XY566 DIL card */ -MODULE_TYPES_DEF(int AI566_VNUM) -#ifdef MODULE_TYPES_INIT - =0xf8; /* Xycom 566 Differential Latched */ -#endif - -/* interrupt vector allocation - one for each DVX card */ -MODULE_TYPES_DEF(int DVX_IVEC0) -#ifdef MODULE_TYPES_INIT - =0xd0; -#endif - -/* stepper motor interrupt vector - one for each motor */ -MODULE_TYPES_DEF(int MD_INT_BASE) -#ifdef MODULE_TYPES_INIT - =0xf0; /* base of the motor int vector */ -#endif - -/* I reserve from here up to num_cards * 4 interrupting chans/card - joh */ -MODULE_TYPES_DEF(int MZ8310_INT_VEC_BASE) -#ifdef MODULE_TYPES_INIT - =0xe8; -#endif - -/* Allen-Bradley Serial Driver - MAX_AB_LINKS number of vectors */ -MODULE_TYPES_DEF(int AB_VEC_BASE) -#ifdef MODULE_TYPES_INIT - =0x60; -#endif - -/* only one interrupt vector allocated for all Joerger VTR1 boards joh */ -MODULE_TYPES_DEF(int JGVTR1_INT_VEC) -#ifdef MODULE_TYPES_INIT - =0xe0; -#endif - -/* AT830X_1 cards have 1 intr vector for each AT830X_1_num_cards (presently 2) */ -MODULE_TYPES_DEF(int AT830X_1_IVEC0) -#ifdef MODULE_TYPES_INIT - =0xd4; -#endif - -/* AT830X cards have 1 intr vector for each AT830X_num_cards (presently 2) */ -MODULE_TYPES_DEF(int AT830X_IVEC0) -#ifdef MODULE_TYPES_INIT - =0xd6; -#endif - -/* AT8 fast protect interrupt vector base */ -MODULE_TYPES_DEF(int AT8FP_IVEC_BASE) -#ifdef MODULE_TYPES_INIT - =0xa2; -#endif - - -MODULE_TYPES_DEF(int AT8FPM_IVEC_BASE ) -#ifdef MODULE_TYPES_INIT - =0xaa; -#endif - - -/****************************************************************************** - * - * Addresses and IRQ information used by the XVME402 bitbus cards. - * - ******************************************************************************/ -MODULE_TYPES_DEF(unsigned short BB_SHORT_OFF ) -#ifdef MODULE_TYPES_INIT - = 0x1800; /* the first address of link 0's region */ -#endif -#define BB_NUM_LINKS 4 /* max number of BB ports allowed */ -MODULE_TYPES_DEF(int BB_IVEC_BASE ) -#ifdef MODULE_TYPES_INIT - = 0xa0; /* vectored interrupts (2 used for each link) */ -#endif -MODULE_TYPES_DEF(int BB_IRQ_LEVEL ) -#ifdef MODULE_TYPES_INIT - = 5; /* IRQ level */ -#endif - -/****************************************************************************** - * - * Information for the PEP modular Bitbus boards. - * - ******************************************************************************/ -MODULE_TYPES_DEF(unsigned short PEP_BB_SHORT_OFF ) -#ifdef MODULE_TYPES_INIT - = 0x1c00; -#endif -MODULE_TYPES_DEF(int PEP_BB_IVEC_BASE ) -#ifdef MODULE_TYPES_INIT - = 0xe8; -#endif - -/****************************************************************************** - * - * Addresses and IRQ information used by the NI1014 and NI1014D bitbus cards. - * - ******************************************************************************/ -MODULE_TYPES_DEF(unsigned short NIGPIB_SHORT_OFF) -#ifdef MODULE_TYPES_INIT - = 0x5000;/* First address of link 0's region */ -#endif - /* Each link uses 0x0200 bytes */ -#define NIGPIB_NUM_LINKS 4 /* Max number of NI GPIB ports allowed */ -MODULE_TYPES_DEF(int NIGPIB_IVEC_BASE ) -#ifdef MODULE_TYPES_INIT - = 100; /* Vectored interrupts (2 used for each link) */ -#endif -MODULE_TYPES_DEF(int NIGPIB_IRQ_LEVEL ) -#ifdef MODULE_TYPES_INIT - =5; /* IRQ level */ -#endif - -#if 0 /* JRW */ -#define NI1014_LINK_NUM_BASE 0 -#endif - -/* - * nothing after this endif - */ -#endif /*INCLmodule_typesh*/ diff --git a/src/libCom/osi/os/vxWorks/osdEnv.c b/src/libCom/osi/os/vxWorks/osdEnv.c deleted file mode 100644 index c81f49316..000000000 --- a/src/libCom/osi/os/vxWorks/osdEnv.c +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdEnv.c */ -/* - * Author: Eric Norum - * Date: May 7, 2001 - * - * Routines to modify/display environment variables and EPICS parameters - * - */ - -/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */ -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsFindSymbol.h" -#include "epicsStdio.h" -#include "errlog.h" -#include "iocsh.h" - -/* - * Set the value of an environment variable - * Leaks memory, but the assumption is that this routine won't be - * called often enough for the leak to be a problem. - */ -epicsShareFunc void epicsShareAPI epicsEnvSet (const char *name, const char *value) -{ - char *cp; - - iocshEnvClear(name); - - cp = mallocMustSucceed (strlen (name) + strlen (value) + 2, "epicsEnvSet"); - strcpy (cp, name); - strcat (cp, "="); - strcat (cp, value); - if (putenv (cp) < 0) { - errPrintf(-1L, __FILE__, __LINE__, - "Failed to set environment parameter \"%s\" to \"%s\": %s\n", - name, value, strerror (errno)); - free (cp); - } -} - -/* - * Show the value of the specified, or all, environment variables - */ -epicsShareFunc void epicsShareAPI epicsEnvShow (const char *name) -{ - if (name == NULL) { - envShow (0); - } - else { - const char *cp = getenv (name); - if (cp == NULL) - printf ("%s is not an environment variable.\n", name); - else - printf ("%s=%s\n", name, cp); - } -} diff --git a/src/libCom/osi/os/vxWorks/osdEvent.c b/src/libCom/osi/os/vxWorks/osdEvent.c deleted file mode 100644 index 875d4e6f6..000000000 --- a/src/libCom/osi/os/vxWorks/osdEvent.c +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* os/vxWorks/osdEvent.c */ - -/* Author: Marty Kraimer Date: 25AUG99 */ - -#include -#include -#include -#include -#include -#include - -#include "epicsEvent.h" - -/* The following not defined in any vxWorks header */ -int sysClkRateGet(void); - -epicsEventId epicsEventCreate(epicsEventInitialState initialState) -{ - return (epicsEventId) semBCreate(SEM_Q_FIFO, - (initialState == epicsEventEmpty) ? SEM_EMPTY : SEM_FULL); -} - -void epicsEventDestroy(epicsEventId id) -{ - semDelete((SEM_ID)id); -} - -epicsEventStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut) -{ - int rate = sysClkRateGet(); - int status; - int ticks; - - if (timeOut <= 0.0) { - ticks = 0; - } else if (timeOut >= (double) INT_MAX / rate) { - ticks = WAIT_FOREVER; - } else { - ticks = timeOut * rate; - if (ticks <= 0) - ticks = 1; - } - status = semTake((SEM_ID)id, ticks); - if (status == OK) - return epicsEventOK; - if (errno == S_objLib_OBJ_TIMEOUT || - (errno == S_objLib_OBJ_UNAVAILABLE && ticks == 0)) - return epicsEventWaitTimeout; - return epicsEventError; -} - -epicsEventStatus epicsEventTryWait(epicsEventId id) -{ - int status = semTake((SEM_ID)id, NO_WAIT); - - if (status == OK) - return epicsEventOK; - if (errno == S_objLib_OBJ_UNAVAILABLE) - return epicsEventWaitTimeout; - return epicsEventError; -} - -void epicsEventShow(epicsEventId id, unsigned int level) -{ - semShow((SEM_ID)id,level); -} diff --git a/src/libCom/osi/os/vxWorks/osdEvent.h b/src/libCom/osi/os/vxWorks/osdEvent.h deleted file mode 100644 index b08b4d98f..000000000 --- a/src/libCom/osi/os/vxWorks/osdEvent.h +++ /dev/null @@ -1,20 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* os/vxWorks/osdEvent.h */ - -/* Author: Marty Kraimer Date: 25AUG99 */ - -#include -#include - -#define epicsEventTrigger(ID) \ - (semGive((SEM_ID)(ID)) == OK ? epicsEventOK : epicsEventError) - -#define epicsEventWait(ID) \ - (semTake((SEM_ID)(ID), WAIT_FOREVER) == OK ? epicsEventOK : epicsEventError) diff --git a/src/libCom/osi/os/vxWorks/osdFindSymbol.c b/src/libCom/osi/os/vxWorks/osdFindSymbol.c deleted file mode 100644 index da17c5bf3..000000000 --- a/src/libCom/osi/os/vxWorks/osdFindSymbol.c +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/vxWorks/osdFindSymbol */ - -/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */ -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dbmf.h" -#include "epicsString.h" -#include "epicsFindSymbol.h" - -static char *errmsg = NULL; -static char *oldmsg = NULL; - -epicsShareFunc void * epicsLoadLibrary(const char *name) -{ - MODULE_ID m = 0; - int fd; - - if (oldmsg) { - free(oldmsg); - oldmsg = NULL; - } - if (errmsg) { - free(errmsg); - errmsg = NULL; - } - - fd = open(name, O_RDONLY, 0); - if (fd != ERROR) { - m = loadModule(fd, GLOBAL_SYMBOLS); - close(fd); - } - - if (!m) { - errmsg = epicsStrDup(strerror(errno)); - } - return m; -} - -epicsShareFunc const char *epicsLoadError(void) -{ - if (oldmsg) - free(oldmsg); - - oldmsg = errmsg; - errmsg = NULL; - return oldmsg; -} - -void *epicsFindSymbol(const char *name) -{ - STATUS status; - -#if _WRS_VXWORKS_MAJOR < 6 || _WRS_VXWORKS_MINOR < 9 - char *pvalue; - SYM_TYPE type; - - status = symFindByName(sysSymTbl, (char *)name, &pvalue, &type); - if (!status) - return pvalue; - - if (name[0] == '_' ) { - status = symFindByName(sysSymTbl, (char *)(name+1), &pvalue, &type); - } -#if CPU_FAMILY == MC680X0 - else { - char *pname = dbmfMalloc(strlen(name) + 2); - - pname[0] = '_'; - strcpy(pname + 1, name); - status = symFindByName(sysSymTbl, pname, &pvalue, &type); - dbmfFree(pname); - } -#endif - if (!status) - return pvalue; - -#else - - SYMBOL_DESC symDesc; - - memset(&symDesc, 0, sizeof(SYMBOL_DESC)); - symDesc.mask = SYM_FIND_BY_NAME; - symDesc.name = (char *) name; - status = symFind(sysSymTbl, &symDesc); - if (!status) - return symDesc.value; - - if (name[0] == '_') { - symDesc.name++; - status = symFind(sysSymTbl, &symDesc); - if (!status) - return symDesc.value; - } - /* No need to prepend an '_'; 68K-only, no longer supported */ -#endif - return 0; -} diff --git a/src/libCom/osi/os/vxWorks/osdInterrupt.c b/src/libCom/osi/os/vxWorks/osdInterrupt.c deleted file mode 100644 index 3ac9e9e83..000000000 --- a/src/libCom/osi/os/vxWorks/osdInterrupt.c +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/vxWorks/osdInterrupt.c */ - -/* Author: Marty Kraimer Date: 28JAN2000 */ - -#include -#include -#include - -#include "epicsInterrupt.h" - -int epicsInterruptLock() {return(intLock());} - -void epicsInterruptUnlock(int key) {intUnlock(key);} - -int epicsInterruptIsInterruptContext() {return(intContext());} - -void epicsInterruptContextMessage(const char *message) -{ - logMsg((char *)message,0,0,0,0,0,0); -} diff --git a/src/libCom/osi/os/vxWorks/osdInterrupt.h b/src/libCom/osi/os/vxWorks/osdInterrupt.h deleted file mode 100644 index ad99926de..000000000 --- a/src/libCom/osi/os/vxWorks/osdInterrupt.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/vxWorks/osdInterrupt.h */ - -/* Author: Marty Kraimer Date: 28JAN2000 */ - -/*osdInterrupt.h not needed */ diff --git a/src/libCom/osi/os/vxWorks/osdMessageQueue.cpp b/src/libCom/osi/os/vxWorks/osdMessageQueue.cpp deleted file mode 100644 index 89c2745ed..000000000 --- a/src/libCom/osi/os/vxWorks/osdMessageQueue.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -#define epicsExportSharedSymbols -#include -#include "epicsMessageQueue.h" - -extern "C" int sysClkRateGet(void); - -epicsShareFunc int epicsShareAPI epicsMessageQueueSendWithTimeout( - epicsMessageQueueId id, - void *message, - unsigned int messageSize, - double timeout) -{ - int ticks; - - if (timeout<=0.0) { - ticks = 0; - } else { - ticks = (int)(timeout*sysClkRateGet()); - if(ticks<=0) ticks = 1; - } - return msgQSend((MSG_Q_ID)id, (char *)message, messageSize, ticks, MSG_PRI_NORMAL); -} - -epicsShareFunc int epicsShareAPI epicsMessageQueueReceiveWithTimeout( - epicsMessageQueueId id, - void *message, - unsigned int size, - double timeout) -{ - int ticks; - - if (timeout<=0.0) { - ticks = 0; - } else { - ticks = (int)(timeout*sysClkRateGet()); - if(ticks<=0) ticks = 1; - } - return msgQReceive((MSG_Q_ID)id, (char *)message, size, ticks); -} diff --git a/src/libCom/osi/os/vxWorks/osdMessageQueue.h b/src/libCom/osi/os/vxWorks/osdMessageQueue.h deleted file mode 100644 index 87b35bd38..000000000 --- a/src/libCom/osi/os/vxWorks/osdMessageQueue.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -/* - * Very thin shims around vxWorks routines - */ -#include -#include - -#define epicsMessageQueueCreate(c,s) ((epicsMessageQueueId)msgQCreate((c),(s),MSG_Q_FIFO)) -#define epicsMessageQueueDestroy(q) (msgQDelete((MSG_Q_ID)(q))) - -#define epicsMessageQueueTrySend(q,m,l) (msgQSend((MSG_Q_ID)(q), (char*)(m), (l), NO_WAIT, MSG_PRI_NORMAL)) -#define epicsMessageQueueSend(q,m,l) (msgQSend((MSG_Q_ID)(q), (char*)(m), (l), WAIT_FOREVER, MSG_PRI_NORMAL)) - -#define epicsMessageQueueTryReceive(q,m,s) (msgQReceive((MSG_Q_ID)(q), (char*)(m), (s), NO_WAIT)) -#define epicsMessageQueueReceive(q,m,s) (msgQReceive((MSG_Q_ID)(q), (char*)(m), (s), WAIT_FOREVER)) - -#define epicsMessageQueuePending(q) (msgQNumMsgs((MSG_Q_ID)(q))) -#define epicsMessageQueueShow(q,l) (msgQShow((MSG_Q_ID)(q),(l))) diff --git a/src/libCom/osi/os/vxWorks/osdMutex.c b/src/libCom/osi/os/vxWorks/osdMutex.c deleted file mode 100644 index 38db2ab83..000000000 --- a/src/libCom/osi/os/vxWorks/osdMutex.c +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* os/vxWorks/osdMutex.c */ - -/* Author: Marty Kraimer Date: 25AUG99 */ - -#include -#include -#include -#include -#include - -/* The following not defined in an vxWorks header */ -int sysClkRateGet(void); - - -#include "epicsMutex.h" - -struct epicsMutexOSD * epicsMutexOsdCreate(void) -{ - return((struct epicsMutexOSD *) - semMCreate(SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY)); -} - -void epicsMutexOsdDestroy(struct epicsMutexOSD * id) -{ - semDelete((SEM_ID)id); -} - -epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * id) -{ - int status; - status = semTake((SEM_ID)id,NO_WAIT); - if(status==OK) return(epicsMutexLockOK); - if(errno==S_objLib_OBJ_UNAVAILABLE) return(epicsMutexLockTimeout); - return(epicsMutexLockError); -} - -void epicsMutexOsdShow(struct epicsMutexOSD * id,unsigned int level) -{ - semShow((SEM_ID)id,level); -} diff --git a/src/libCom/osi/os/vxWorks/osdMutex.h b/src/libCom/osi/os/vxWorks/osdMutex.h deleted file mode 100644 index 3ea951a8f..000000000 --- a/src/libCom/osi/os/vxWorks/osdMutex.h +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* os/vxWorks/osdMutex.h */ - -/* Author: Marty Kraimer Date: 25AUG99 */ - -#include -#include - -/* If the macro is replaced by inline it is necessary to say - static __inline__ - but then a warning message appears everywhere osdMutex.h is included -*/ - -#define epicsMutexOsdUnlock(ID) semGive((SEM_ID)(ID)) - -#define epicsMutexOsdLock(ID) \ -(semTake((SEM_ID)(ID),WAIT_FOREVER)==OK ? epicsMutexLockOK : epicsMutexLockError) diff --git a/src/libCom/osi/os/vxWorks/osdPoolStatus.c b/src/libCom/osi/os/vxWorks/osdPoolStatus.c deleted file mode 100644 index 06447c1f7..000000000 --- a/src/libCom/osi/os/vxWorks/osdPoolStatus.c +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsThread.h" -#include "osiPoolStatus.h" - -/* - * It turns out that memPartInfoGet() and memFindMax() are very CPU intensive on vxWorks - * so we must spawn off a thread that periodically polls. Although this isnt 100% safe, I - * dont see what else to do. - * - * It takes about 30 uS to call memPartInfoGet() on a pcPentium I vxWorks system. - * - * joh - */ - -static epicsThreadOnceId osdMaxBlockOnceler = EPICS_THREAD_ONCE_INIT; - -static size_t osdMaxBlockSize = 0; - -static void osdSufficentSpaceInPoolQuery () -{ - osdMaxBlockSize = (size_t) memFindMax (); -} - -static void osdSufficentSpaceInPoolPoll ( void *pArgIn ) -{ - while ( 1 ) { - epicsThreadSleep ( 1.0 ); - osdSufficentSpaceInPoolQuery (); - } -} - -static void osdSufficentSpaceInPoolInit ( void *pArgIn ) -{ - epicsThreadId id; - - osdSufficentSpaceInPoolQuery (); - - id = epicsThreadCreate ( "poolPoll", epicsThreadPriorityMedium, - epicsThreadGetStackSize ( epicsThreadStackSmall ), - osdSufficentSpaceInPoolPoll, 0 ); -} - -/* - * osiSufficentSpaceInPool () - */ -epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize ) -{ - epicsThreadOnce ( &osdMaxBlockOnceler, osdSufficentSpaceInPoolInit, 0 ); - - if ( UINT_MAX - 100000u >= contiguousBlockSize ) { - return ( osdMaxBlockSize > 100000 + contiguousBlockSize ); - } - else { - return 0; - } -} diff --git a/src/libCom/osi/os/vxWorks/osdProcess.c b/src/libCom/osi/os/vxWorks/osdProcess.c deleted file mode 100644 index 2347a407c..000000000 --- a/src/libCom/osi/os/vxWorks/osdProcess.c +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Operating System Dependent Implementation of osiProcess.h - * - * Author: Jeff Hill - * - */ - -/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */ -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include - -#include - -#define epicsExportSharedSymbols -#include "osiProcess.h" -#include "errlog.h" - -epicsShareFunc osiGetUserNameReturn epicsShareAPI osiGetUserName (char *pBuf, unsigned bufSizeIn) -{ - char pName[MAX_IDENTITY_LEN]; - unsigned uiLength; - size_t len; - - remCurIdGet ( pName, NULL ); - len = strlen ( pName ); - - if (len>UINT_MAX || len<=0) { - return osiGetUserNameFail; - } - uiLength = (unsigned) len; - - if ( uiLength + 1 >= bufSizeIn ) { - return osiGetUserNameFail; - } - - strncpy ( pBuf, pName, (size_t) bufSizeIn ); - - return osiGetUserNameSuccess; -} - -epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProcess - (const char *pProcessName, const char *pBaseExecutableName) -{ - return osiSpawnDetachedProcessNoSupport; -} diff --git a/src/libCom/osi/os/vxWorks/osdReadline.c b/src/libCom/osi/os/vxWorks/osdReadline.c deleted file mode 100644 index 9195b6b72..000000000 --- a/src/libCom/osi/os/vxWorks/osdReadline.c +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Eric Norum Date: 12DEC2001 */ - -/* - * This file is included by epicsReadline.c which has already included the - * headers stdio.h, stdlib.h, errno.h, envDefs.h and epicsReadline.h - */ - -#include -#include - -/* FIXME: Remove line-lenth limitation */ -#define LEDLIB_LINESIZE 1000 - -#ifndef _WRS_VXWORKS_MAJOR -typedef int LED_ID; -#endif - -struct osdContext { - LED_ID ledId; - char line[LEDLIB_LINESIZE]; -}; - -/* - * Create a command-line context - */ -static void -osdReadlineBegin(struct readlineContext *context) -{ - struct osdContext osd = malloc(sizeof *osd); - - if (osd != NULL) { - osd->ledId = (LED_ID) ERROR; - if (context->in == NULL) { - long i = 50; - - envGetLongConfigParam(&IOCSH_HISTSIZE, &i); - if (i < 1) - i = 1; - - osd->ledId = ledOpen(fileno(stdin), fileno(stdout), i); - if (osd->ledId == (LED_ID) ERROR) { - context->in = stdin; - printf("Warning -- Unabled to allocate space for command-line history.\n"); - printf("Warning -- Command-line editting disabled.\n"); - } - } - context->osd = osd; - } -} - -/* - * Read a line of input - */ -static char * -osdReadline (const char *prompt, struct readlineContext *context) -{ - struct osdContext *osd = context->osd; - int i; - - if (prompt) { - fputs(prompt, stdout); - fflush(stdout); - } - if (osd->ledId != (LED_ID) ERROR) { - i = ledRead(osd->ledId, osd->line, LEDLIB_LINESIZE-1); - if (i < 0) - return NULL; - } - else { - if (fgets(osd->line, LEDLIB_LINESIZE, context->in) == NULL) - return NULL; - i = strlen(osd->line); - } - if ((i >= 1) && (osd->line[i-1] == '\n')) - osd->line[i-1] = '\0'; - else - osd->line[i] = '\0'; - return osd->line; -} - -/* - * Destroy a command-line context - */ -static void -osdReadlineEnd (struct readlineContext *context) -{ - LED_ID ledId = context->osd->ledId; - - if (ledId != (LED_ID) ERROR) - ledClose(ledId); - free(context->osd); -} - diff --git a/src/libCom/osi/os/vxWorks/osdSignal.cpp b/src/libCom/osi/os/vxWorks/osdSignal.cpp deleted file mode 100644 index 1157854aa..000000000 --- a/src/libCom/osi/os/vxWorks/osdSignal.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2002 The University of Chicago, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE Versions 3.13.7 - * and higher are distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "epicsSignal.h" - -/* - * NOOP - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm ( struct epicsThreadOSD * /* threadId */ ) {} diff --git a/src/libCom/osi/os/vxWorks/osdSock.c b/src/libCom/osi/os/vxWorks/osdSock.c deleted file mode 100644 index a0f5e8ec5..000000000 --- a/src/libCom/osi/os/vxWorks/osdSock.c +++ /dev/null @@ -1,129 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */ -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include - -#ifndef vxWorks -#error this is a vxWorks specific source code -#endif - -#include -#include - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "osiSock.h" - -int osiSockAttach() -{ - return 1; -} - -void osiSockRelease() -{ -} - -epicsShareFunc SOCKET epicsShareAPI epicsSocketCreate ( - int domain, int type, int protocol ) -{ - SOCKET sock = socket ( domain, type, protocol ); - if ( sock < 0 ) { - sock = INVALID_SOCKET; - } - return sock; -} - -epicsShareFunc int epicsShareAPI epicsSocketAccept ( - int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ) -{ - int newSock = accept ( sock, pAddr, addrlen ); - if ( newSock < 0 ) { - newSock = INVALID_SOCKET; - } - return newSock; -} - -epicsShareFunc void epicsShareAPI epicsSocketDestroy ( SOCKET s ) -{ - int status = close ( s ); - if ( status < 0 ) { - char buf [ 64 ]; - epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) ); - errlogPrintf ( - "epicsSocketDestroy: failed to " - "close a socket because \"%s\"\n", - buf ); - } -} - -/* - * ipAddrToHostName - */ -epicsShareFunc unsigned epicsShareAPI ipAddrToHostName - (const struct in_addr *pAddr, char *pBuf, unsigned bufSize) -{ - int status; - int errnoCopy = errno; - unsigned len; - - if (bufSize<1) { - return 0; - } - - if (bufSize>MAXHOSTNAMELEN) { - status = hostGetByAddr ((int)pAddr->s_addr, pBuf); - if (status==OK) { - pBuf[MAXHOSTNAMELEN] = '\0'; - len = strlen (pBuf); - } - else { - len = 0; - } - } - else { - char name[MAXHOSTNAMELEN+1]; - status = hostGetByAddr (pAddr->s_addr, name); - if (status==OK) { - strncpy (pBuf, name, bufSize); - pBuf[bufSize-1] = '\0'; - len = strlen (pBuf); - } - else { - len = 0; - } - } - - errno = errnoCopy; - - return len; -} - -/* - * hostToIPAddr () - */ -epicsShareFunc int epicsShareAPI -hostToIPAddr(const char *pHostName, struct in_addr *pIPA) -{ - int addr = hostGetByName ( (char *) pHostName ); - if ( addr == ERROR ) { - return -1; - } - pIPA->s_addr = (unsigned long) addr; - - /* - * success - */ - return 0; -} - diff --git a/src/libCom/osi/os/vxWorks/osdSock.h b/src/libCom/osi/os/vxWorks/osdSock.h deleted file mode 100644 index 80464ef87..000000000 --- a/src/libCom/osi/os/vxWorks/osdSock.h +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * vxWorks specific socket include - */ - -#ifndef osdSockH -#define osdSockH - -/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */ -#ifndef _VSB_CONFIG_FILE -# define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*This following is not defined in any vxWorks header files*/ -int sysClkRateGet(void); - -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#ifndef SHUT_RD -# define SHUT_RD 0 -#endif -#ifndef SHUT_WR -# define SHUT_WR 1 -#endif -#ifndef SHUT_RDWR -# define SHUT_RDWR 2 -#endif - -/* - * it is quite lame on WRS's part to assume that - * a ptr is always the same as an int - */ -#define socket_ioctl(A,B,C) ioctl(A,B,(int)C) -typedef int osiSockIoctl_t; -typedef int osiSocklen_t; - -#define FD_IN_FDSET(FD) ((FD)=0) - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EACCES EACCES -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE -#define SOCK_EMFILE EMFILE -#define SOCK_SHUTDOWN ESHUTDOWN -#define SOCK_ENOTSOCK ENOTSOCK -#define SOCK_EBADF EBADF - -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK 0x7F000001 -#endif - -#ifndef INADDR_NONE -# define INADDR_NONE (0xffffffff) -#endif - -#if defined(_SIZEOF_ADDR_IFREQ) -# define ifreq_size(pifreq) _SIZEOF_ADDR_IFREQ(*pifreq) -#elif ( defined (BSD) && ( BSD >= 44 ) ) -# define ifreq_size(pifreq) (pifreq->ifr_addr.sa_len + sizeof(pifreq->ifr_name)) -#else -# define ifreq_size(pifreq) sizeof(*pifreq) -#endif - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/vxWorks/osdSpin.c b/src/libCom/osi/os/vxWorks/osdSpin.c deleted file mode 100644 index a68cdd374..000000000 --- a/src/libCom/osi/os/vxWorks/osdSpin.c +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2012 ITER Organization. -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2013 Brookhaven Science Assoc. as Operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Authors: Ralph Lange - * Andrew Johnson - * Michael Davidsaver - * - * Inspired by Linux UP spinlocks implemention - * include/linux/spinlock_api_up.h - */ - -/* - * vxWorks (single CPU): LOCK INTERRUPT and DISABLE PREEMPTION - * - * CAVEAT: - * This implementation will not compile on vxWorks SMP architectures. - * These architectures provide spinlocks, which must be used instead. - * - */ - -/* This is needed for vxWorks 6.x to prevent an obnoxious compiler warning */ -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include -#include -#include - -#include "cantProceed.h" -#include "epicsSpin.h" - -typedef struct epicsSpin { - int key; - unsigned int locked; -} epicsSpin; - -epicsSpinId epicsSpinCreate(void) { - return calloc(1, sizeof(epicsSpin)); -} - -epicsSpinId epicsSpinMustCreate(void) -{ - epicsSpinId ret = epicsSpinCreate(); - if (!ret) - cantProceed("epicsSpinMustCreate: epicsSpinCreate failed."); - return ret; -} - -void epicsSpinDestroy(epicsSpinId spin) { - free(spin); -} - -void epicsSpinLock(epicsSpinId spin) { - int key = intLock(); - - if (!intContext()) - taskLock(); - if (spin->locked) { - intUnlock(key); - if (!intContext()) { - taskUnlock(); - logMsg("epicsSpinLock(%p): Deadlock.\n", - (int) spin, 0, 0, 0, 0, 0); - cantProceed("Recursive lock, missed unlock or block when locked."); - } - else { - logMsg("epicsSpinLock(%p): Deadlock in ISR.\n" - "Recursive lock, missed unlock or block when locked.\n", - (int) spin, 0, 0, 0, 0, 0); - } - return; - } - spin->key = key; - spin->locked = 1; -} - -int epicsSpinTryLock(epicsSpinId spin) { - int key = intLock(); - - if (!intContext()) - taskLock(); - if (spin->locked) { - intUnlock(key); - if (!intContext()) - taskUnlock(); - return 1; - } - spin->key = key; - spin->locked = 1; - return 0; -} - -void epicsSpinUnlock(epicsSpinId spin) { - int key = spin->key; - - if (!spin->locked) { - logMsg("epicsSpinUnlock(%p): not locked\n", - (int) spin, 0, 0, 0, 0, 0); - return; - } - spin->key = spin->locked = 0; - intUnlock(key); - if (!intContext()) - taskUnlock(); -} diff --git a/src/libCom/osi/os/vxWorks/osdStdio.c b/src/libCom/osi/os/vxWorks/osdStdio.c deleted file mode 100644 index 20664a1a4..000000000 --- a/src/libCom/osi/os/vxWorks/osdStdio.c +++ /dev/null @@ -1,57 +0,0 @@ -/* osdStdio.c */ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include "epicsStdio.h" -#include "dbDefs.h" - -struct outStr_s { - char *str; - size_t free; -}; - -static STATUS outRoutine(char *buffer, size_t nchars, int outarg) { - struct outStr_s *poutStr = (struct outStr_s *) outarg; - size_t free = poutStr->free; - size_t len; - - if (free < 1) { /*let fioFormatV continue to count length*/ - return OK; - } else if (free > 1) { - len = min(free-1, nchars); - strncpy(poutStr->str, buffer, len); - poutStr->str += len; - poutStr->free -= len; - } - /*make sure final string is null terminated*/ - *poutStr->str = 0; - return OK; -} - -int epicsVsnprintf(char *str, size_t size, const char *format, va_list ap) { - struct outStr_s outStr; - - outStr.str = str; - outStr.free = size; - return fioFormatV(format, ap, outRoutine, (int) &outStr); -} - -int epicsSnprintf(char *str, size_t size, const char *format, ...) -{ - size_t nchars; - va_list pvar; - - va_start(pvar,format); - nchars = epicsVsnprintf(str,size,format,pvar); - va_end (pvar); - return(nchars); -} diff --git a/src/libCom/osi/os/vxWorks/osdStrtod.h b/src/libCom/osi/os/vxWorks/osdStrtod.h deleted file mode 100644 index 91c47d70e..000000000 --- a/src/libCom/osi/os/vxWorks/osdStrtod.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * This header is included by epicsString.h and epicsStdlib.h - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * epicsStrtod() for systems with broken strtod() routine - */ -double epicsStrtod(const char *str, char **endp); - -/* - * VxWorks doesn't provide these routines, so for now we do - */ - -long long int strtoll(const char *nptr, char **endptr, int base); -unsigned long long int strtoull(const char *nptr, char **endptr, int base); - -#ifdef __cplusplus -} -#endif diff --git a/src/libCom/osi/os/vxWorks/osdThread.c b/src/libCom/osi/os/vxWorks/osdThread.c deleted file mode 100644 index ce01ea609..000000000 --- a/src/libCom/osi/os/vxWorks/osdThread.c +++ /dev/null @@ -1,457 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2012 ITER Organization -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/vxWorks/epicsThread.c */ - -/* Author: Marty Kraimer Date: 25AUG99 */ - -/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */ -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "errlog.h" -#include "ellLib.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "epicsAssert.h" -#include "vxLib.h" -#include "epicsExit.h" - -epicsShareFunc void osdThreadHooksRun(epicsThreadId id); - -#if CPU_FAMILY == MC680X0 -#define ARCH_STACK_FACTOR 1 -#elif CPU_FAMILY == SPARC -#define ARCH_STACK_FACTOR 2 -#else -#define ARCH_STACK_FACTOR 2 -#endif -static const unsigned stackSizeTable[epicsThreadStackBig+1] = - {4000*ARCH_STACK_FACTOR, 6000*ARCH_STACK_FACTOR, 11000*ARCH_STACK_FACTOR}; - -/* Table and lock for epicsThreadMap() */ -#define ID_LIST_CHUNK 512 -static int *taskIdList = 0; -int taskIdListSize = 0; -static SEM_ID epicsThreadListMutex = 0; - -/* This routine is found in atReboot.cpp */ -extern void atRebootRegister(void); - -/* definitions for implementation of epicsThreadPrivate */ -static void **papTSD = 0; -static int nepicsThreadPrivate = 0; - -static SEM_ID epicsThreadOnceMutex = 0; - -/* Just map osi 0 to 99 into vx 100 to 199 */ -/* remember that for vxWorks lower number means higher priority */ -/* vx = 100 + (99 -osi) = 199 - osi*/ -/* osi = 199 - vx */ - -static unsigned int getOsiPriorityValue(int ossPriority) -{ - if ( ossPriority < 100 ) { - return epicsThreadPriorityMax; - } - else if ( ossPriority > 199 ) { - return epicsThreadPriorityMin; - } - else { - return ( 199u - (unsigned int) ossPriority ); - } -} - -static int getOssPriorityValue(unsigned int osiPriority) -{ - if ( osiPriority > 99 ) { - return 100; - } - else { - return ( 199 - (signed int) osiPriority ); - } -} - -#define THREAD_SEM_FLAGS (SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY) -static void epicsThreadInit(void) -{ - static int lock = 0; - static int done = 0; - - if (done) return; - - while(!vxTas(&lock)) - taskDelay(1); - - if (!done) { - epicsThreadOnceMutex = semMCreate(THREAD_SEM_FLAGS); - assert(epicsThreadOnceMutex); - epicsThreadListMutex = semMCreate(THREAD_SEM_FLAGS); - assert(epicsThreadListMutex); - taskIdList = calloc(ID_LIST_CHUNK, sizeof(int)); - assert(taskIdList); - taskIdListSize = ID_LIST_CHUNK; - atRebootRegister(); - done = 1; - } - lock = 0; -} - -void epicsThreadRealtimeLock(void) -{} - -unsigned int epicsThreadGetStackSize (epicsThreadStackSizeClass stackSizeClass) -{ - - if (stackSizeClassepicsThreadStackBig) { - errlogPrintf("epicsThreadGetStackSize illegal argument (too large)"); - return stackSizeTable[epicsThreadStackBig]; - } - - return stackSizeTable[stackSizeClass]; -} - -struct epicsThreadOSD {}; - /* Strictly speaking this should be a WIND_TCB, but we only need it to - * be able to create an epicsThreadId that is guaranteed never to be - * the same as any current TID, and since TIDs are pointers this works. - */ - -void epicsThreadOnce(epicsThreadOnceId *id, void (*func)(void *), void *arg) -{ - static struct epicsThreadOSD threadOnceComplete; - #define EPICS_THREAD_ONCE_DONE &threadOnceComplete - int result; - - epicsThreadInit(); - result = semTake(epicsThreadOnceMutex, WAIT_FOREVER); - assert(result == OK); - if (*id != EPICS_THREAD_ONCE_DONE) { - if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ - *id = epicsThreadGetIdSelf(); /* mark active */ - semGive(epicsThreadOnceMutex); - func(arg); - result = semTake(epicsThreadOnceMutex, WAIT_FOREVER); - assert(result == OK); - *id = EPICS_THREAD_ONCE_DONE; /* mark done */ - } else if (*id == epicsThreadGetIdSelf()) { - semGive(epicsThreadOnceMutex); - cantProceed("Recursive epicsThreadOnce() initialization\n"); - } else - while (*id != EPICS_THREAD_ONCE_DONE) { - /* Another thread is in the above func(arg) call. */ - semGive(epicsThreadOnceMutex); - epicsThreadSleep(epicsThreadSleepQuantum()); - result = semTake(epicsThreadOnceMutex, WAIT_FOREVER); - assert(result == OK); - } - } - semGive(epicsThreadOnceMutex); -} - -static void createFunction(EPICSTHREADFUNC func, void *parm) -{ - int tid = taskIdSelf(); - - taskVarAdd(tid,(int *)(char *)&papTSD); - /*Make sure that papTSD is still 0 after that call to taskVarAdd*/ - papTSD = 0; - osdThreadHooksRun((epicsThreadId)tid); - (*func)(parm); - epicsExitCallAtThreadExits (); - free(papTSD); - taskVarDelete(tid,(int *)(char *)&papTSD); -} - -#ifdef ALTIVEC - #define TASK_FLAGS (VX_FP_TASK | VX_ALTIVEC_TASK) -#else - #define TASK_FLAGS (VX_FP_TASK) -#endif -epicsThreadId epicsThreadCreate(const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) -{ - int tid; - - epicsThreadInit(); - if(stackSize<100) { - errlogPrintf("epicsThreadCreate %s illegal stackSize %d\n",name,stackSize); - return(0); - } - tid = taskSpawn((char *)name,getOssPriorityValue(priority), - TASK_FLAGS, stackSize, - (FUNCPTR)createFunction,(int)funptr,(int)parm, - 0,0,0,0,0,0,0,0); - if(tid==ERROR) { - errlogPrintf("epicsThreadCreate %s failure %s\n", - name,strerror(errno)); - return(0); - } - return((epicsThreadId)tid); -} - -void epicsThreadSuspendSelf() -{ - STATUS status; - - status = taskSuspend(taskIdSelf()); - if(status) errlogPrintf("epicsThreadSuspendSelf failed\n"); -} - -void epicsThreadResume(epicsThreadId id) -{ - int tid = (int)id; - STATUS status; - - status = taskResume(tid); - if(status) errlogPrintf("epicsThreadResume failed\n"); -} - -void epicsThreadExitMain(void) -{ - errlogPrintf("epicsThreadExitMain was called for vxWorks. Why?\n"); -} - -unsigned int epicsThreadGetPriority(epicsThreadId id) -{ - int tid = (int)id; - STATUS status; - int priority = 0; - - status = taskPriorityGet(tid,&priority); - if(status) errlogPrintf("epicsThreadGetPriority failed\n"); - return(getOsiPriorityValue(priority)); -} - -unsigned int epicsThreadGetPrioritySelf(void) -{ - return(epicsThreadGetPriority(epicsThreadGetIdSelf())); -} - -void epicsThreadSetPriority(epicsThreadId id,unsigned int osip) -{ - int tid = (int)id; - STATUS status; - int priority = 0; - - priority = getOssPriorityValue(osip); - status = taskPrioritySet(tid,priority); - if(status) errlogPrintf("epicsThreadSetPriority failed\n"); -} - -epicsThreadBooleanStatus epicsThreadHighestPriorityLevelBelow( - unsigned int priority, unsigned *pPriorityJustBelow) -{ - unsigned newPriority = priority - 1; - if (newPriority <= 99) { - *pPriorityJustBelow = newPriority; - return epicsThreadBooleanStatusSuccess; - } - return epicsThreadBooleanStatusFail; -} - -epicsThreadBooleanStatus epicsThreadLowestPriorityLevelAbove( - unsigned int priority, unsigned *pPriorityJustAbove) -{ - unsigned newPriority = priority + 1; - - newPriority = priority + 1; - if (newPriority <= 99) { - *pPriorityJustAbove = newPriority; - return epicsThreadBooleanStatusSuccess; - } - return epicsThreadBooleanStatusFail; -} - -int epicsThreadIsEqual(epicsThreadId id1, epicsThreadId id2) -{ - return((id1==id2) ? 1 : 0); -} - -int epicsThreadIsSuspended(epicsThreadId id) -{ - int tid = (int)id; - return((int)taskIsSuspended(tid)); -} - -void epicsThreadSleep(double seconds) -{ - STATUS status; - int ticks; - - if (seconds > 0.0) { - seconds *= sysClkRateGet(); - seconds += 0.99999999; /* 8 9s here is optimal */ - ticks = (seconds >= INT_MAX) ? INT_MAX : (int) seconds; - } - else { /* seconds <= 0 or NAN */ - ticks = 0; - } - status = taskDelay(ticks); - if(status) errlogPrintf("epicsThreadSleep\n"); -} - -epicsThreadId epicsThreadGetIdSelf(void) -{ - return((epicsThreadId)taskIdSelf()); -} - -epicsThreadId epicsThreadGetId(const char *name) -{ - int tid = taskNameToId((char *)name); - return((epicsThreadId)(tid==ERROR?0:tid)); -} - -const char *epicsThreadGetNameSelf(void) -{ - return taskName(taskIdSelf()); -} - -void epicsThreadGetName (epicsThreadId id, char *name, size_t size) -{ - int tid = (int)id; - strncpy(name,taskName(tid),size-1); - name[size-1] = '\0'; -} - -epicsShareFunc void epicsThreadMap ( EPICS_THREAD_HOOK_ROUTINE func ) -{ - int noTasks = 0; - int i; - int result; - - result = semTake(epicsThreadListMutex, WAIT_FOREVER); - assert(result == OK); - while (noTasks == 0) { - noTasks = taskIdListGet(taskIdList, taskIdListSize); - if (noTasks == taskIdListSize) { - taskIdList = realloc(taskIdList, (taskIdListSize+ID_LIST_CHUNK)*sizeof(int)); - assert(taskIdList); - taskIdListSize += ID_LIST_CHUNK; - noTasks = 0; - } - } - for (i = 0; i < noTasks; i++) { - func ((epicsThreadId)taskIdList[i]); - } - semGive(epicsThreadListMutex); -} - -void epicsThreadShowAll(unsigned int level) -{ - taskShow(0,2); -} - -void epicsThreadShow(epicsThreadId id, unsigned int level) -{ - int tid = (int)id; - - if (level > 1) level = 1; - if (tid) - taskShow(tid, level); -} - -/* The following algorithm was thought of by Andrew Johnson APS/ASD . - * The basic idea is to use a single vxWorks task variable. - * The task variable is papTSD, which is an array of pointers to the TSD - * The array size is equal to the number of epicsThreadPrivateIds created + 1 - * when epicsThreadPrivateSet is called. - * Until the first call to epicsThreadPrivateCreate by a application papTSD=0 - * After first call papTSD[0] is value of nepicsThreadPrivate when - * epicsThreadPrivateSet was last called by the thread. This is also - * the value of epicsThreadPrivateId. - * The algorithm allows for epicsThreadPrivateCreate being called after - * the first call to epicsThreadPrivateSet. - */ -epicsThreadPrivateId epicsThreadPrivateCreate() -{ - static int lock = 0; - epicsThreadPrivateId id; - - epicsThreadInit(); - /*lock is necessary because ++nepicsThreadPrivate may not be indivisible*/ - while(!vxTas(&lock)) taskDelay(1); - id = (epicsThreadPrivateId)++nepicsThreadPrivate; - lock = 0; - return(id); -} - -void epicsThreadPrivateDelete(epicsThreadPrivateId id) -{ - /*nothing to delete */ - return; -} - -/* - * No mutex is necessary here because by definition - * thread variables are local to a single thread. - */ -void epicsThreadPrivateSet (epicsThreadPrivateId id, void *pvt) -{ - int int_id = (int)id; - int nepicsThreadPrivateOld = 0; - - if (papTSD) nepicsThreadPrivateOld = (int)papTSD[0]; - - if (!papTSD || nepicsThreadPrivateOld < int_id) { - void **papTSDold = papTSD; - int i; - - papTSD = callocMustSucceed(int_id + 1,sizeof(void *), - "epicsThreadPrivateSet"); - papTSD[0] = (void *)(int_id); - for (i = 1; i <= nepicsThreadPrivateOld; i++) { - papTSD[i] = papTSDold[i]; - } - free (papTSDold); - } - papTSD[int_id] = pvt; -} - -void *epicsThreadPrivateGet(epicsThreadPrivateId id) -{ - int int_id = (int)id; - - /* - * If epicsThreadPrivateGet() is called before epicsThreadPrivateSet() - * for any particular thread, the value returned is always NULL. - */ - if ( papTSD && int_id <= (int) papTSD[0] ) { - return papTSD[int_id]; - } - return NULL; -} - -double epicsThreadSleepQuantum () -{ - double HZ = sysClkRateGet (); - return 1.0 / HZ; -} - -epicsShareFunc int epicsThreadGetCPUs(void) -{ - return 1; -} diff --git a/src/libCom/osi/os/vxWorks/osdThread.h b/src/libCom/osi/os/vxWorks/osdThread.h deleted file mode 100644 index 2ee9f2d46..000000000 --- a/src/libCom/osi/os/vxWorks/osdThread.h +++ /dev/null @@ -1,13 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef osdThreadh -#define osdThreadh - -#endif /* osdThreadh */ diff --git a/src/libCom/osi/os/vxWorks/osdThreadExtra.c b/src/libCom/osi/os/vxWorks/osdThreadExtra.c deleted file mode 100644 index 0a7c7ae95..000000000 --- a/src/libCom/osi/os/vxWorks/osdThreadExtra.c +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 ITER Organization -* -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Ralph Lange Date: 26 Jun 2012 */ - -/* Null default thread hooks for all platforms that do not do anything special */ - -#define epicsExportSharedSymbols -#include "epicsThread.h" - -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault; -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain; diff --git a/src/libCom/osi/os/vxWorks/osdTime.cpp b/src/libCom/osi/os/vxWorks/osdTime.cpp deleted file mode 100644 index 4db375fbb..000000000 --- a/src/libCom/osi/os/vxWorks/osdTime.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include -#include -#include -#include -#include - -#include "epicsTime.h" -#include "osiNTPTime.h" -#include "osiClockTime.h" -#include "generalTimeSup.h" -#include "envDefs.h" - -#define NTP_REQUEST_TIMEOUT 4 /* seconds */ - -static char sntp_sync_task[] = "ipsntps"; -static char ntp_daemon[] = "ipntpd"; - -static const char *pserverAddr = NULL; -extern char* sysBootLine; - -static int timeRegister(void) -{ - /* If TIMEZONE not defined, set it from EPICS_TIMEZONE */ - if (getenv("TIMEZONE") == NULL) { - const char *timezone = envGetConfigParamPtr(&EPICS_TIMEZONE); - if (timezone == NULL) { - printf("timeRegister: No Time Zone Information\n"); - } else { - epicsEnvSet("TIMEZONE", timezone); - } - } - - // Define EPICS_TS_FORCE_NTPTIME to force use of NTPTime provider - bool useNTP = getenv("EPICS_TS_FORCE_NTPTIME") != NULL; - - if (!useNTP && - (taskNameToId(sntp_sync_task) != ERROR || - taskNameToId(ntp_daemon) != ERROR)) { - // A VxWorks 6 SNTP/NTP sync task is running - struct timespec clockNow; - - useNTP = clock_gettime(CLOCK_REALTIME, &clockNow) != OK || - clockNow.tv_sec < BUILD_TIME; - // Assumes VxWorks and the host OS have the same epoch - } - - if (useNTP) { - // Start NTP first so it can be used to sync SysTime - NTPTime_Init(100); - ClockTime_Init(CLOCKTIME_SYNC); - } else { - ClockTime_Init(CLOCKTIME_NOSYNC); - } - return 1; -} -static int done = timeRegister(); - - -// Routines for NTPTime provider - -int osdNTPGet(struct timespec *ts) -{ - return sntpcTimeGet(const_cast(pserverAddr), - NTP_REQUEST_TIMEOUT * sysClkRateGet(), ts); -} - -void osdNTPInit(void) -{ - pserverAddr = envGetConfigParamPtr(&EPICS_TS_NTP_INET); - if (!pserverAddr) { /* use the boot host */ - BOOT_PARAMS bootParms; - static char host_addr[BOOT_ADDR_LEN]; - - bootStringToStruct(sysBootLine, &bootParms); - /* bootParms.had = host IP address */ - strncpy(host_addr, bootParms.had, BOOT_ADDR_LEN); - pserverAddr = host_addr; - } -} - -void osdNTPReport(void) -{ - if (pserverAddr) - printf("NTP Server = %s\n", pserverAddr); -} - - -// Other Time Routines - -// vxWorks localtime_r returns different things in different versions. -// It can't fail though, so we just ignore the return value. -int epicsTime_localtime(const time_t *clock, struct tm *result) -{ - localtime_r(clock, result); - return epicsTimeOK; -} - -// vxWorks gmtime_r returns different things in different versions. -// It can't fail though, so we just ignore the return value. -int epicsTime_gmtime ( const time_t *pAnsiTime, struct tm *pTM ) -{ - gmtime_r(pAnsiTime, pTM); - return epicsTimeOK; -} diff --git a/src/libCom/osi/os/vxWorks/osdTime.h b/src/libCom/osi/os/vxWorks/osdTime.h deleted file mode 100644 index a816c7ae3..000000000 --- a/src/libCom/osi/os/vxWorks/osdTime.h +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Following needed for struct timeval */ -#include - -#ifndef osdTimeh -#define osdTimeh - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void osdNTPInit(void); -int osdNTPGet(struct timespec *); -void osdNTPReport(void); - -#define osdTickRateGet sysClkRateGet -#define osdTickGet tickGet - -#ifdef __cplusplus -} -#endif -#endif /* ifndef osdTimeh */ diff --git a/src/libCom/osi/os/vxWorks/osdVME.h b/src/libCom/osi/os/vxWorks/osdVME.h deleted file mode 100644 index b9d031a04..000000000 --- a/src/libCom/osi/os/vxWorks/osdVME.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * OS-dependent VME support - */ -#include diff --git a/src/libCom/osi/os/vxWorks/osdWireConfig.h b/src/libCom/osi/os/vxWorks/osdWireConfig.h deleted file mode 100644 index 408ec6758..000000000 --- a/src/libCom/osi/os/vxWorks/osdWireConfig.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * vxWorks version of - * osdWireConfig.h - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef osdWireConfig_h -#define osdWireConfig_h - -#include -#include - -#if _BYTE_ORDER == _LITTLE_ENDIAN -# define EPICS_BYTE_ORDER EPICS_ENDIAN_LITTLE -#elif _BYTE_ORDER == _BIG_ENDIAN -# define EPICS_BYTE_ORDER EPICS_ENDIAN_BIG -#else -# error EPICS hasnt been ported to _BYTE_ORDER specified by vxWorks -#endif - -/* for now, assume that vxWorks doesnt run on weird arch like ARM NWFP */ -#define EPICS_FLOAT_WORD_ORDER EPICS_BYTE_ORDER - -#endif /* ifdef osdWireConfig_h */ diff --git a/src/libCom/osi/os/vxWorks/osiFileName.h b/src/libCom/osi/os/vxWorks/osiFileName.h deleted file mode 100644 index 3a6448d54..000000000 --- a/src/libCom/osi/os/vxWorks/osiFileName.h +++ /dev/null @@ -1,19 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * osiFileName.h - * Author: Jeff Hill - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/vxWorks/strtoll.c b/src/libCom/osi/os/vxWorks/strtoll.c deleted file mode 100644 index 54e0a9522..000000000 --- a/src/libCom/osi/os/vxWorks/strtoll.c +++ /dev/null @@ -1,139 +0,0 @@ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#ifndef LLONG_MAX -#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL -#define LLONG_MIN (-0x7FFFFFFFFFFFFFFFLL - 1) -#endif - -/* - * Convert a string to a long long integer. - * - * Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -long long -strtoll(const char * __restrict nptr, char ** __restrict endptr, int base) -{ - const char *s; - unsigned long long acc; - char c; - unsigned long long cutoff; - int neg, any, cutlim; - - /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ - s = nptr; - do { - c = *s++; - } while (isspace((unsigned char)c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X') && - ((s[1] >= '0' && s[1] <= '9') || - (s[1] >= 'A' && s[1] <= 'F') || - (s[1] >= 'a' && s[1] <= 'f'))) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - acc = any = 0; - if (base < 2 || base > 36) - goto noconv; - - /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for quads is - * [-9223372036854775808..9223372036854775807] and the input base - * is 10, cutoff will be set to 922337203685477580 and cutlim to - * either 7 (neg==0) or 8 (neg==1), meaning that if we have - * accumulated a value > 922337203685477580, or equal but the - * next digit is > 7 (or 8), the number is too big, and we will - * return a range error. - * - * Set 'any' if any `digits' consumed; make it negative to indicate - * overflow. - */ - cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX - : LLONG_MAX; - cutlim = cutoff % base; - cutoff /= base; - for ( ; ; c = *s++) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') - c -= 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= base; - acc += c; - } - } - if (any < 0) { - acc = neg ? LLONG_MIN : LLONG_MAX; - errno = ERANGE; - } else if (!any) { -noconv: - errno = EINVAL; - } else if (neg) - acc = -acc; - if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} diff --git a/src/libCom/osi/os/vxWorks/strtoull.c b/src/libCom/osi/os/vxWorks/strtoull.c deleted file mode 100644 index 197a45bcf..000000000 --- a/src/libCom/osi/os/vxWorks/strtoull.c +++ /dev/null @@ -1,116 +0,0 @@ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#ifndef ULLONG_MAX -#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL -#endif - -/* - * Convert a string to an unsigned long long integer. - * - * Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -unsigned long long -strtoull(const char * __restrict nptr, char ** __restrict endptr, int base) -{ - const char *s; - unsigned long long acc; - char c; - unsigned long long cutoff; - int neg, any, cutlim; - - /* - * See strtoq for comments as to the logic used. - */ - s = nptr; - do { - c = *s++; - } while (isspace((unsigned char)c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X') && - ((s[1] >= '0' && s[1] <= '9') || - (s[1] >= 'A' && s[1] <= 'F') || - (s[1] >= 'a' && s[1] <= 'f'))) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - acc = any = 0; - if (base < 2 || base > 36) - goto noconv; - - cutoff = ULLONG_MAX / base; - cutlim = ULLONG_MAX % base; - for ( ; ; c = *s++) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') - c -= 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= base; - acc += c; - } - } - if (any < 0) { - acc = ULLONG_MAX; - errno = ERANGE; - } else if (!any) { -noconv: - errno = EINVAL; - } else if (neg) - acc = -acc; - if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} diff --git a/src/libCom/osi/os/vxWorks/task_params.h b/src/libCom/osi/os/vxWorks/task_params.h deleted file mode 100644 index 7b2055157..000000000 --- a/src/libCom/osi/os/vxWorks/task_params.h +++ /dev/null @@ -1,184 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Parameters for tasks on IOC */ -/* - * Authors: Andy Kozubal, Jeff Hill, and Bob Dalesio - * Date: 2-24-89 - */ - -#ifndef INCtaskLibh -#include -#endif - -#define VXTASKIDSELF 0 - -/* Task Names */ -#define EVENTSCAN_NAME "scanEvent" -#define SCANONCE_NAME "scanOnce" -#define SMCMD_NAME "smCommand" -#define SMRESP_NAME "smResponse" -#define ABDONE_NAME "abDone" -#define ABSCAN_NAME "abScan" -#define ABCOS_NAME "abBiCosScanner" -#define MOMENTARY_NAME "momentary" -#define WFDONE_NAME "wfDone" -#define SEQUENCER_NAME "sequencer" -#define BKPT_CONT_NAME "bkptCont" -#define SCANNER_NAME "scanner" -#define REQ_SRVR_NAME "CA_TCP" -#define CA_CLIENT_NAME "CA_client" -#define CA_EVENT_NAME "CA_event" -#define CAST_SRVR_NAME "CA_UDP" -#define CA_REPEATER_NAME "CA_repeater" -#define CA_ONLINE_NAME "CA_online" -#define TASKWD_NAME "taskwd" -#define SMIOTEST_NAME "smInout" -#define SMROTTEST_NAME "smRotate" -#define EVENT_PEND_NAME "event_task" -#define XY240_NAME "xy_240_scan" -#define GPIBLINK_NAME "gpibLink" -#define BBLINK_NAME "bbLinkTask" -#define BBTXLINK_NAME "bbTx" -#define BBRXLINK_NAME "bbRx" -#define BBWDTASK_NAME "bbwd" -#define ERRLOG_NAME "errlog" -#define LOG_RESTART_NAME "logRestart" - -/* Task priorities */ -#define SCANONCE_PRI 129 /* scan one time */ -/*DO NOT RUN ANY RECORD PROCESSING TASKS AT HIGHER PRIORITY THAN _netTask=50*/ -#define CALLBACK_PRI_LOW 140 /* callback task - generall callback task */ -#define CALLBACK_PRI_MEDIUM 135 /* callback task - generall callback task */ -#define CALLBACK_PRI_HIGH 128 /* callback task - generall callback task */ -#define EVENTSCAN_PRI 129 /* Event Scanner - Runs on a global event */ -#define SMCMD_PRI 120 /* Stepper Motor Command Task - Waits for cmds */ -#define SMRESP_PRI 121 /* Stepper Motor Resp Task - Waits for resps */ -#define ABCOS_PRI 121 /* Allen-Bradley Binary Input COS io_event wakeup */ -#define ABDONE_PRI 122 /* Allen-Bradley Resp Task - Interrupt Driven */ -#define ABSCAN_PRI 123 /* Allen-Bradley Scan Task - Base Rate .1 secs */ -#define BBLINK_PRI 124 -#define BBWDTASK_PRI 123 /* BitBus watchdog task */ -#define BBRXLINK_PRI 124 /* BitBus link task */ -#define BBTXLINK_PRI 125 /* BitBus link task */ -#define GPIBLINK_PRI 125 /* GPIB link task */ -#define MOMENTARY_PRI 126 /* Momentary output - posted from watchdog */ -#define WFDONE_PRI 127 /* Waveform Task - Base Rate of .1 second */ -#define PERIODSCAN_PRI 139 /* Periodic Scanners - Slowest rate */ -#define DB_CA_PRI 149 /*database to channel access*/ -#define SEQUENCER_PRI 151 -#define XY240_PRI 160 /* xy 240 dio scanner */ -#define SCANNER_PRI 170 -#define REQ_SRVR_PRI 181 /* Channel Access TCP request server*/ -#define CA_CLIENT_PRI 180 /* Channel Access clients */ -#define CA_REPEATER_PRI 181 /* Channel Access repeater */ -#define ERRLOG_PRI CA_REPEATER_PRI /*error logger task*/ -#define CAST_SRVR_PRI 182 /* Channel Access broadcast server */ -#define CA_ONLINE_PRI 183 /* Channel Access server online notify */ -#define TASKWD_PRI 200 /* Watchdog Scan Task - runs every 6 seconds */ -#define SMIOTEST_PRI 205 /* Stepper Mtr in/out test - runs every .1 sec */ -#define SMROTTEST_PRI 205 /* Stepper Mtr rotate test - runs every .1 sec */ -#define LOG_RESTART_PRI 200 /* Log server connection watch dog */ - -/* Task delay times (seconds) */ -#define TASKWD_DELAY 6 - -/* Task delay times (tics) */ -#define ABSCAN_RATE (sysClkRateGet()/6) -#define SEQUENCER_DELAY (sysClkRateGet()/5) -#define SCANNER_DELAY (sysClkRateGet()/5) -#define CA_ONLINE_DELAY (sysClkRateGet()*15) -#define LOG_RESTART_DELAY (sysClkRateGet()*30) - -/* Task creation options */ -#define ERRLOG_OPT VX_FP_TASK -#define EVENTSCAN_OPT VX_FP_TASK -#define SCANONCE_OPT VX_FP_TASK -#define CALLBACK_OPT VX_FP_TASK -#define SMCMD_OPT VX_FP_TASK -#define SMRESP_OPT VX_FP_TASK -#define ABDONE_OPT VX_FP_TASK -#define ABCOS_OPT VX_FP_TASK -#define ABSCAN_OPT VX_FP_TASK -#define MOMENTARY_OPT VX_FP_TASK -#define PERIODSCAN_OPT VX_FP_TASK -#define WFDONE_OPT VX_FP_TASK -#define SEQUENCER_OPT VX_FP_TASK | VX_STDIO -#define BKPT_CONT_OPT VX_FP_TASK -#define SCANNER_OPT VX_FP_TASK -#define REQ_SRVR_OPT VX_FP_TASK -#define CAST_SRVR_OPT VX_FP_TASK -#define CA_CLIENT_OPT VX_FP_TASK -#define CA_REPEATER_OPT VX_FP_TASK -#define CA_ONLINE_OPT VX_FP_TASK -#define TASKWD_OPT VX_FP_TASK -#define SMIOTEST_OPT VX_FP_TASK -#define SMROTTEST_OPT VX_FP_TASK -#define EVENT_PEND_OPT VX_FP_TASK -#define GPIBLINK_OPT VX_FP_TASK|VX_STDIO -#define BBLINK_OPT VX_FP_TASK|VX_STDIO -#define BBTXLINK_OPT VX_FP_TASK|VX_STDIO -#define BBRXLINK_OPT VX_FP_TASK|VX_STDIO -#define BBWDTASK_OPT VX_FP_TASK|VX_STDIO -#define DB_CA_OPT (VX_FP_TASK | VX_STDIO) -#define XY_240_OPT (0) /* none */ -#define LOG_RESTART_OPT (VX_FP_TASK) - - -/* - * Task stack sizes - * - * (original stack sizes are appropriate for the 68k) - * ARCH_STACK_FACTOR allows scaling the stacks on particular - * processor architectures - */ -#if CPU_FAMILY == MC680X0 -#define ARCH_STACK_FACTOR 1 -#elif CPU_FAMILY == SPARC -#define ARCH_STACK_FACTOR 2 -#else -#define ARCH_STACK_FACTOR 2 -#endif - -#define ERRLOG_STACK (4000*ARCH_STACK_FACTOR) -#define EVENTSCAN_STACK (11000*ARCH_STACK_FACTOR) -#define SCANONCE_STACK (11000*ARCH_STACK_FACTOR) -#define CALLBACK_STACK (11000*ARCH_STACK_FACTOR) -#define SMCMD_STACK (3000*ARCH_STACK_FACTOR) -#define SMRESP_STACK (3000*ARCH_STACK_FACTOR) -#define ABCOS_STACK (3000*ARCH_STACK_FACTOR) -#define ABDONE_STACK (3000*ARCH_STACK_FACTOR) -#define ABSCAN_STACK (3000*ARCH_STACK_FACTOR) -#define MOMENTARY_STACK (2000*ARCH_STACK_FACTOR) -#define PERIODSCAN_STACK (11000*ARCH_STACK_FACTOR) -#define WFDONE_STACK (9000*ARCH_STACK_FACTOR) -#define SEQUENCER_STACK (5500*ARCH_STACK_FACTOR) -#define BKPT_CONT_STACK (11000*ARCH_STACK_FACTOR) -#define SCANNER_STACK (3048*ARCH_STACK_FACTOR) -#define RSP_SRVR_STACK (5096*ARCH_STACK_FACTOR) -#define REQ_SRVR_STACK (5096*ARCH_STACK_FACTOR) -#define CAST_SRVR_STACK (5096*ARCH_STACK_FACTOR) -#define CA_CLIENT_STACK (11000*ARCH_STACK_FACTOR) -#define CA_REPEATER_STACK (5096*ARCH_STACK_FACTOR) -#define CA_ONLINE_STACK (3048*ARCH_STACK_FACTOR) -#define TASKWD_STACK (2000*ARCH_STACK_FACTOR) -#define SMIOTEST_STACK (2000*ARCH_STACK_FACTOR) -#define SMROTTEST_STACK (2000*ARCH_STACK_FACTOR) -#define EVENT_PEND_STACK (5096*ARCH_STACK_FACTOR) -#define TIMESTAMP_STACK (4000*ARCH_STACK_FACTOR) -#define GPIBLINK_STACK (5000*ARCH_STACK_FACTOR) -#define BBLINK_STACK (5000*ARCH_STACK_FACTOR) -#define BBRXLINK_STACK (5000*ARCH_STACK_FACTOR) -#define BBTXLINK_STACK (5000*ARCH_STACK_FACTOR) -#define BBWDTASK_STACK (5000*ARCH_STACK_FACTOR) -#define DB_CA_STACK (11000*ARCH_STACK_FACTOR) -#define XY_240_STACK (4096*ARCH_STACK_FACTOR) -#define LOG_RESTART_STACK (0x1000*ARCH_STACK_FACTOR) - diff --git a/src/libCom/osi/os/vxWorks/veclist.c b/src/libCom/osi/os/vxWorks/veclist.c deleted file mode 100644 index 2a4e617ef..000000000 --- a/src/libCom/osi/os/vxWorks/veclist.c +++ /dev/null @@ -1,208 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * list fuctions attached to the interrupt vector table - * - * Created 28Mar89 Jeffrey O. Hill - * johill@lanl.gov - * (505) 665 1831 - * - */ - -#include "vxWorks.h" -#include "stdio.h" -#include "string.h" -#include "intLib.h" -#include "vxLib.h" -#include "iv.h" -#include "ctype.h" -#include "sysSymTbl.h" - -/* - * - * VME bus dependent - * - */ -#define NVEC 0x100 - -static char *ignore_list[] = {"_excStub","_excIntStub"}; - -int veclist(int); -int cISRTest(FUNCPTR proutine, FUNCPTR *ppisr, void **pparam); -static void *fetch_pointer(unsigned char *); - - -/* - * - * veclist() - * - */ -int veclist(int all) -{ - int vec; - int value; - SYM_TYPE type; - char name[MAX_SYS_SYM_LEN]; - char function_type[10]; - FUNCPTR proutine; - FUNCPTR pCISR; - int cRoutine; - void *pparam; - int status; - unsigned i; - - for(vec=0; vec -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsMutex.h" -#include "epicsThread.h" -#include "errlog.h" -#include "epicsGeneralTime.h" -#include "generalTimeSup.h" -#include "iocsh.h" -#include "osiClockTime.h" -#include "taskwd.h" - -#define NSEC_PER_SEC 1000000000 -#define ClockTimeSyncInterval_value 60.0 - - -static struct { - int synchronize; - int synchronized; - epicsEventId loopEvent; - epicsTimeStamp startTime; - epicsTimeStamp syncTime; - double ClockTimeSyncInterval; - int syncFromPriority; - epicsMutexId lock; -} ClockTimePvt; - -static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; - - -#if defined(CLOCK_REALTIME) && !defined(_WIN32) -/* This code is not used on systems without Posix CLOCK_REALTIME such - * as Darwin, but the only way to detect that is from the OS headers, - * so the Makefile can't exclude building this file on those systems. - */ - -/* Forward references */ - -static int ClockTimeGetCurrent(epicsTimeStamp *pDest); -static void ClockTimeSync(void *dummy); - - -/* ClockTime_Report iocsh command */ -static const iocshArg ReportArg0 = { "interest_level", iocshArgArgv}; -static const iocshArg * const ReportArgs[1] = { &ReportArg0 }; -static const iocshFuncDef ReportFuncDef = {"ClockTime_Report", 1, ReportArgs}; -static void ReportCallFunc(const iocshArgBuf *args) -{ - ClockTime_Report(args[0].ival); -} - -/* ClockTime_Shutdown iocsh command */ -static const iocshFuncDef ShutdownFuncDef = {"ClockTime_Shutdown", 0, NULL}; -static void ShutdownCallFunc(const iocshArgBuf *args) -{ - ClockTime_Shutdown(NULL); -} - - -/* Initialization */ - -static void ClockTime_InitOnce(void *pfirst) -{ - *(int *) pfirst = 1; - - ClockTimePvt.loopEvent = epicsEventMustCreate(epicsEventEmpty); - ClockTimePvt.lock = epicsMutexCreate(); - ClockTimePvt.ClockTimeSyncInterval = 1.0; /* First sync */ - - epicsAtExit(ClockTime_Shutdown, NULL); - - /* Register the iocsh commands */ - iocshRegister(&ReportFuncDef, ReportCallFunc); - iocshRegister(&ShutdownFuncDef, ShutdownCallFunc); - - /* Register as a time provider */ - generalTimeRegisterCurrentProvider("OS Clock", LAST_RESORT_PRIORITY, - ClockTimeGetCurrent); -} - -void ClockTime_Init(int synchronize) -{ - int firstTime = 0; - - epicsThreadOnce(&onceId, ClockTime_InitOnce, &firstTime); - - if (synchronize == CLOCKTIME_SYNC) { - if (ClockTimePvt.synchronize == CLOCKTIME_NOSYNC) { - /* Start synchronizing */ - ClockTimePvt.synchronize = synchronize; - - epicsThreadCreate("ClockTimeSync", epicsThreadPriorityHigh, - epicsThreadGetStackSize(epicsThreadStackSmall), - ClockTimeSync, NULL); - } - else { - /* No change, sync thread should already be running */ - } - } - else { - if (ClockTimePvt.synchronize == CLOCKTIME_SYNC) { - /* Turn off synchronization thread */ - ClockTime_Shutdown(NULL); - } - else { - /* No synchronization thread */ - if (firstTime) - ClockTimeGetCurrent(&ClockTimePvt.startTime); - } - } -} - - -/* Shutdown */ - -void ClockTime_Shutdown(void *dummy) -{ - ClockTimePvt.synchronize = CLOCKTIME_NOSYNC; - epicsEventSignal(ClockTimePvt.loopEvent); -} - -void ClockTime_GetProgramStart(epicsTimeStamp *pDest) -{ - *pDest = ClockTimePvt.startTime; -} - - -/* Synchronization thread */ - -static void ClockTimeSync(void *dummy) -{ - taskwdInsert(0, NULL, NULL); - - for (epicsEventWaitWithTimeout(ClockTimePvt.loopEvent, - ClockTimePvt.ClockTimeSyncInterval); - ClockTimePvt.synchronize == CLOCKTIME_SYNC; - epicsEventWaitWithTimeout(ClockTimePvt.loopEvent, - ClockTimePvt.ClockTimeSyncInterval)) { - epicsTimeStamp timeNow; - int priority; - - if (generalTimeGetExceptPriority(&timeNow, &priority, - LAST_RESORT_PRIORITY) == epicsTimeOK) { - struct timespec clockNow; - - epicsTimeToTimespec(&clockNow, &timeNow); - if (clock_settime(CLOCK_REALTIME, &clockNow)) { - errlogPrintf("ClockTimeSync: clock_settime failed\n"); - continue; - } - - epicsMutexMustLock(ClockTimePvt.lock); - if (!ClockTimePvt.synchronized) { - ClockTimePvt.startTime = timeNow; - ClockTimePvt.synchronized = 1; - } - ClockTimePvt.syncFromPriority = priority; - ClockTimePvt.syncTime = timeNow; - epicsMutexUnlock(ClockTimePvt.lock); - - ClockTimePvt.ClockTimeSyncInterval = ClockTimeSyncInterval_value; - } - } - - ClockTimePvt.synchronized = 0; - taskwdRemove(0); -} - - -/* Time Provider Routine */ - -static int ClockTimeGetCurrent(epicsTimeStamp *pDest) -{ - struct timespec clockNow; - - /* If a Hi-Res clock is available and works, use it */ - #ifdef CLOCK_REALTIME_HR - clock_gettime(CLOCK_REALTIME_HR, &clockNow) && - #endif - clock_gettime(CLOCK_REALTIME, &clockNow); - - if (!ClockTimePvt.synchronized && - clockNow.tv_sec < POSIX_TIME_AT_EPICS_EPOCH) { - clockNow.tv_sec = POSIX_TIME_AT_EPICS_EPOCH + 86400; - clockNow.tv_nsec = 0; - clock_settime(CLOCK_REALTIME, &clockNow); - errlogPrintf("WARNING: OS Clock time was read before being set.\n" - "Using 1990-01-02 00:00:00.000000 UTC\n"); - } - - epicsTimeFromTimespec(pDest, &clockNow); - return 0; -} - -#endif /* CLOCK_REALTIME */ - -/* Allow the following report routine to be compiled anyway - * to avoid getting a build warning from ranlib. - */ - -/* Status Report */ - -int ClockTime_Report(int level) -{ - char timebuf[32]; - - if (onceId == EPICS_THREAD_ONCE_INIT) { - printf("OS Clock driver not %s.\n", -#ifdef CLOCK_REALTIME - "initialized" -#else - "available" -#endif /* CLOCK_REALTIME */ - ); - } - else if (ClockTimePvt.synchronize == CLOCKTIME_SYNC) { - int synchronized, syncFromPriority; - epicsTimeStamp startTime, syncTime; - - epicsMutexMustLock(ClockTimePvt.lock); - synchronized = ClockTimePvt.synchronized; - syncFromPriority = ClockTimePvt.syncFromPriority; - startTime = ClockTimePvt.startTime; - syncTime = ClockTimePvt.syncTime; - epicsMutexUnlock(ClockTimePvt.lock); - - if (synchronized) { - printf("OS Clock driver is synchronized to a priority=%d provider\n", - syncFromPriority); - if (level) { - epicsTimeToStrftime(timebuf, sizeof(timebuf), - "%Y-%m-%d %H:%M:%S.%06f", &startTime); - printf("Initial sync was at %s\n", timebuf); - epicsTimeToStrftime(timebuf, sizeof(timebuf), - "%Y-%m-%d %H:%M:%S.%06f", &syncTime); - printf("Last successful sync was at %s\n", timebuf); - } - printf("Syncronization interval = %.0f seconds\n", - ClockTimePvt.ClockTimeSyncInterval); - } - else - printf("OS Clock driver is *not* synchronized\n"); - } - else { - epicsTimeToStrftime(timebuf, sizeof(timebuf), - "%Y-%m-%d %H:%M:%S.%06f", &ClockTimePvt.startTime); - printf("Program started at %s\n", timebuf); - printf("OS Clock synchronization thread not running.\n"); - } - return 0; -} diff --git a/src/libCom/osi/osiClockTime.h b/src/libCom/osi/osiClockTime.h deleted file mode 100644 index 17eacab3e..000000000 --- a/src/libCom/osi/osiClockTime.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_osiClockTime_H -#define INC_osiClockTime_H - -#define CLOCKTIME_NOSYNC 0 -#define CLOCKTIME_SYNC 1 - -#ifdef __cplusplus -extern "C" { -#endif - -void ClockTime_Init(int synchronize); -void ClockTime_Shutdown(void *dummy); -int ClockTime_Report(int level); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/osi/osiNTPTime.c b/src/libCom/osi/osiNTPTime.c deleted file mode 100644 index d22df861b..000000000 --- a/src/libCom/osi/osiNTPTime.c +++ /dev/null @@ -1,284 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Original Author: Marty Kraimer - * Date: 16JUN2000 - */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsTypes.h" -#include "cantProceed.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "errlog.h" -#include "epicsGeneralTime.h" -#include "generalTimeSup.h" -#include "iocsh.h" -#include "osdTime.h" -#include "osiNTPTime.h" -#include "taskwd.h" - -#define NSEC_PER_SEC 1000000000 -#define NTPTimeSyncInterval 60.0 -#define NTPTimeSyncRetries 4 - - -static struct { - int synchronize; - int synchronized; - epicsEventId loopEvent; - int syncsFailed; - epicsMutexId lock; - epicsTimeStamp syncTime; - epicsUInt32 syncTick; - epicsTimeStamp clockTime; - epicsUInt32 clockTick; - epicsUInt32 ticksToSkip; - double tickRate; -} NTPTimePvt; - -static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; - - -/* Forward references */ - -static int NTPTimeGetCurrent(epicsTimeStamp *pDest); -static void NTPTimeSync(void *dummy); - - -/* NTPTime_Report iocsh command */ -static const iocshArg ReportArg0 = { "interest_level", iocshArgArgv}; -static const iocshArg * const ReportArgs[1] = { &ReportArg0 }; -static const iocshFuncDef ReportFuncDef = {"NTPTime_Report", 1, ReportArgs}; -static void ReportCallFunc(const iocshArgBuf *args) -{ - NTPTime_Report(args[0].ival); -} - -/* NTPTime_Shutdown iocsh command */ -static const iocshFuncDef ShutdownFuncDef = {"NTPTime_Shutdown", 0, NULL}; -static void ShutdownCallFunc(const iocshArgBuf *args) -{ - NTPTime_Shutdown(NULL); -} - - -/* Initialization */ - -static void NTPTime_InitOnce(void *pprio) -{ - struct timespec timespecNow; - - NTPTimePvt.synchronize = 1; - NTPTimePvt.synchronized = 0; - NTPTimePvt.loopEvent = epicsEventMustCreate(epicsEventEmpty); - NTPTimePvt.syncsFailed = 0; - NTPTimePvt.lock = epicsMutexCreate(); - - /* Initialize OS-dependent code */ - osdNTPInit(); - - /* Try to sync with NTP server */ - if (!osdNTPGet(×pecNow)) { - NTPTimePvt.syncTick = osdTickGet(); - if (timespecNow.tv_sec > POSIX_TIME_AT_EPICS_EPOCH && epicsTimeOK == - epicsTimeFromTimespec(&NTPTimePvt.syncTime, ×pecNow)) { - NTPTimePvt.clockTick = NTPTimePvt.syncTick; - NTPTimePvt.clockTime = NTPTimePvt.syncTime; - NTPTimePvt.synchronized = 1; - } - } - - /* Start the sync thread */ - epicsThreadCreate("NTPTimeSync", epicsThreadPriorityHigh, - epicsThreadGetStackSize(epicsThreadStackSmall), - NTPTimeSync, NULL); - - epicsAtExit(NTPTime_Shutdown, NULL); - - /* Register the iocsh commands */ - iocshRegister(&ReportFuncDef, ReportCallFunc); - iocshRegister(&ShutdownFuncDef, ShutdownCallFunc); - - /* Finally register as a time provider */ - generalTimeRegisterCurrentProvider("NTP", *(int *)pprio, NTPTimeGetCurrent); -} - -void NTPTime_Init(int priority) -{ - epicsThreadOnce(&onceId, NTPTime_InitOnce, &priority); -} - - -/* Shutdown */ - -void NTPTime_Shutdown(void *dummy) -{ - NTPTimePvt.synchronize = 0; - epicsEventSignal(NTPTimePvt.loopEvent); -} - - -/* Synchronization thread */ - -static void NTPTimeSync(void *dummy) -{ - taskwdInsert(0, NULL, NULL); - - for (epicsEventWaitWithTimeout(NTPTimePvt.loopEvent, NTPTimeSyncInterval); - NTPTimePvt.synchronize; - epicsEventWaitWithTimeout(NTPTimePvt.loopEvent, NTPTimeSyncInterval)) { - int status; - struct timespec timespecNow; - epicsTimeStamp timeNow; - epicsUInt32 tickNow; - double diff; - double ntpDelta; - - status = osdNTPGet(×pecNow); - tickNow = osdTickGet(); - - if (status) { - if (++NTPTimePvt.syncsFailed > NTPTimeSyncRetries && - NTPTimePvt.synchronized) { - errlogPrintf("NTPTimeSync: NTP requests failing - %s\n", - strerror(errno)); - NTPTimePvt.synchronized = 0; - } - continue; - } - - if (timespecNow.tv_sec <= POSIX_TIME_AT_EPICS_EPOCH || - epicsTimeFromTimespec(&timeNow, ×pecNow) != epicsTimeOK) { - errlogPrintf("NTPTimeSync: Bad time received from NTP server\n"); - NTPTimePvt.synchronized = 0; - continue; - } - - ntpDelta = epicsTimeDiffInSeconds(&timeNow, &NTPTimePvt.syncTime); - if (ntpDelta <= 0.0 && NTPTimePvt.synchronized) { - errlogPrintf("NTPTimeSync: NTP time not increasing, delta = %g\n", - ntpDelta); - NTPTimePvt.synchronized = 0; - continue; - } - - NTPTimePvt.syncsFailed = 0; - if (!NTPTimePvt.synchronized) { - errlogPrintf("NTPTimeSync: Sync recovered.\n"); - } - - epicsMutexMustLock(NTPTimePvt.lock); - diff = epicsTimeDiffInSeconds(&timeNow, &NTPTimePvt.clockTime); - if (diff >= 0.0) { - NTPTimePvt.ticksToSkip = 0; - } else { /* dont go back in time */ - NTPTimePvt.ticksToSkip = -diff * osdTickRateGet(); - } - NTPTimePvt.clockTick = tickNow; - NTPTimePvt.clockTime = timeNow; - NTPTimePvt.synchronized = 1; - epicsMutexUnlock(NTPTimePvt.lock); - - NTPTimePvt.tickRate = (tickNow - NTPTimePvt.syncTick) / ntpDelta; - NTPTimePvt.syncTick = tickNow; - NTPTimePvt.syncTime = timeNow; - } - - NTPTimePvt.synchronized = 0; - taskwdRemove(0); -} - - -/* Time Provider Routine */ - -static int NTPTimeGetCurrent(epicsTimeStamp *pDest) -{ - epicsUInt32 tickNow; - epicsUInt32 ticksSince; - - if (!NTPTimePvt.synchronized) - return S_time_unsynchronized; - - epicsMutexMustLock(NTPTimePvt.lock); - - tickNow = osdTickGet(); - ticksSince = tickNow - NTPTimePvt.clockTick; - - if (NTPTimePvt.ticksToSkip <= ticksSince) { - if (NTPTimePvt.ticksToSkip) { - ticksSince -= NTPTimePvt.ticksToSkip; - NTPTimePvt.ticksToSkip = 0; - } - - if (ticksSince) { - epicsUInt32 ticksPerSecond = osdTickRateGet(); - epicsUInt32 nsecsPerTick = NSEC_PER_SEC / ticksPerSecond; - epicsUInt32 secsSince = ticksSince / ticksPerSecond; - - ticksSince -= secsSince * ticksPerSecond; - NTPTimePvt.clockTime.nsec += ticksSince * nsecsPerTick; - if (NTPTimePvt.clockTime.nsec >= NSEC_PER_SEC) { - secsSince++; - NTPTimePvt.clockTime.nsec -= NSEC_PER_SEC; - } - NTPTimePvt.clockTime.secPastEpoch += secsSince; - NTPTimePvt.clockTick = tickNow; - } - } - - *pDest = NTPTimePvt.clockTime; - - epicsMutexUnlock(NTPTimePvt.lock); - return 0; -} - - -/* Status Report */ - -int NTPTime_Report(int level) -{ - if (onceId == EPICS_THREAD_ONCE_INIT) { - printf("NTP driver not initialized\n"); - } else if (NTPTimePvt.synchronize) { - printf("NTP driver %s synchronized with server\n", - NTPTimePvt.synchronized ? "is" : "is *not*"); - if (NTPTimePvt.syncsFailed) { - printf("Last successful sync was %.1f minutes ago\n", - NTPTimePvt.syncsFailed * NTPTimeSyncInterval / 60.0); - } - if (level) { - char lastSync[32]; - - epicsTimeToStrftime(lastSync, sizeof(lastSync), - "%Y-%m-%d %H:%M:%S.%06f", &NTPTimePvt.syncTime); - printf("Syncronization interval = %.1f seconds\n", - NTPTimeSyncInterval); - printf("Last synchronized at %s\n", - lastSync); - printf("Current OS tick rate = %u Hz\n", - osdTickRateGet()); - printf("Measured tick rate = %.3f Hz\n", - NTPTimePvt.tickRate); - osdNTPReport(); - } - } else { - printf("NTP synchronization thread not running.\n"); - } - return 0; -} diff --git a/src/libCom/osi/osiNTPTime.h b/src/libCom/osi/osiNTPTime.h deleted file mode 100644 index 21b29d118..000000000 --- a/src/libCom/osi/osiNTPTime.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_osiNTPTime_H -#define INC_osiNTPTime_H - -#ifdef __cplusplus -extern "C" { -#endif - -void NTPTime_Init(int priority); -void NTPTime_Shutdown(void *dummy); -int NTPTime_Report(int level); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/osi/osiPoolStatus.h b/src/libCom/osi/osiPoolStatus.h deleted file mode 100644 index b0207f185..000000000 --- a/src/libCom/osi/osiPoolStatus.h +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_osiPoolStatus_H -#define INC_osiPoolStatus_H - -/* - * Author: Jeff Hill - * - * Functions which interrogate the state of the system wide pool - * - */ - -#include -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * tests to see if there is sufficent space for a block of the requested size - * along with whatever additional free space is necessary to keep the system running - * reliably - * - * this routine is called quite frequently so an efficent implementation is important - */ -epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize ); - -#ifdef __cplusplus -} -#endif - -#include "osdPoolStatus.h" - -#endif /* INC_osiPoolStatus_H */ diff --git a/src/libCom/osi/osiProcess.h b/src/libCom/osi/osiProcess.h deleted file mode 100644 index eabff1e72..000000000 --- a/src/libCom/osi/osiProcess.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_osiProcess_H -#define INC_osiProcess_H - -/* - * Operating System Independent Interface to Process Environment - * - * Author: Jeff Hill - * - */ -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum osiGetUserNameReturn { - osiGetUserNameFail, - osiGetUserNameSuccess} osiGetUserNameReturn; -epicsShareFunc osiGetUserNameReturn epicsShareAPI osiGetUserName (char *pBuf, unsigned bufSize); - -/* - * Spawn detached process with named executable, but return - * osiSpawnDetachedProcessNoSupport if the local OS does not - * support heavy weight processes. - */ -typedef enum osiSpawnDetachedProcessReturn { - osiSpawnDetachedProcessFail, - osiSpawnDetachedProcessSuccess, - osiSpawnDetachedProcessNoSupport} osiSpawnDetachedProcessReturn; - -epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProcess - (const char *pProcessName, const char *pBaseExecutableName); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_osiProcess_H */ diff --git a/src/libCom/osi/osiSock.c b/src/libCom/osi/osiSock.c deleted file mode 100644 index 8b4634caf..000000000 --- a/src/libCom/osi/osiSock.c +++ /dev/null @@ -1,189 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * socket support library generic code - * - * 7-1-97 -joh- - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "epicsSignal.h" -#include "epicsStdio.h" -#include "osiSock.h" - -#define nDigitsDottedIP 4u -#define chunkSize 8u - -#define makeMask(NBITS) ( ( 1u << ( (unsigned) NBITS) ) - 1u ) - -/* - * sockAddrAreIdentical() - * (returns true if addresses are identical) - */ -int epicsShareAPI sockAddrAreIdentical - ( const osiSockAddr *plhs, const osiSockAddr *prhs ) -{ - int match; - - if ( plhs->sa.sa_family != prhs->sa.sa_family ) { - match = 0; - } - else if ( plhs->sa.sa_family != AF_INET ) { - match = 0; - } - else if ( plhs->ia.sin_addr.s_addr != prhs->ia.sin_addr.s_addr ) { - match = 0; - } - else if ( plhs->ia.sin_port != prhs->ia.sin_port ) { - match = 0; - } - else { - match = 1; - } - return match; -} - -/* - * sockAddrToA() - * (convert socket address to ASCII host name) - */ -unsigned epicsShareAPI sockAddrToA ( - const struct sockaddr * paddr, char * pBuf, unsigned bufSize ) -{ - if ( bufSize < 1 ) { - return 0; - } - - if ( paddr->sa_family != AF_INET ) { - static const char * pErrStr = ""; - unsigned len = strlen ( pErrStr ); - if ( len < bufSize ) { - strcpy ( pBuf, pErrStr ); - return len; - } - else { - strncpy ( pBuf, "", bufSize-1 ); - pBuf[bufSize-1] = '\0'; - return bufSize-1; - } - } - else { - const struct sockaddr_in * paddr_in = - (const struct sockaddr_in *) paddr; - return ipAddrToA ( paddr_in, pBuf, bufSize ); - } -} - -/* - * ipAddrToA() - * (convert IP address to ASCII host name) - */ -unsigned epicsShareAPI ipAddrToA ( - const struct sockaddr_in * paddr, char * pBuf, unsigned bufSize ) -{ - unsigned len = ipAddrToHostName ( - & paddr->sin_addr, pBuf, bufSize ); - if ( len == 0 ) { - len = ipAddrToDottedIP ( paddr, pBuf, bufSize ); - } - else { - unsigned reducedSize = bufSize - len; - int status = epicsSnprintf ( - &pBuf[len], reducedSize, ":%hu", - ntohs (paddr->sin_port) ); - if ( status > 0 ) { - unsigned portSize = (unsigned) status; - if ( portSize < reducedSize ) { - len += portSize; - } - } - } - return len; -} - -/* - * sockAddrToDottedIP () - */ -unsigned epicsShareAPI sockAddrToDottedIP ( - const struct sockaddr * paddr, char * pBuf, unsigned bufSize ) -{ - if ( paddr->sa_family != AF_INET ) { - const char * pErrStr = ""; - unsigned errStrLen = strlen ( pErrStr ); - if ( errStrLen < bufSize ) { - strcpy ( pBuf, pErrStr ); - return errStrLen; - } - else { - unsigned reducedSize = bufSize - 1u; - strncpy ( pBuf, pErrStr, reducedSize ); - pBuf[reducedSize] = '\0'; - return reducedSize; - } - } - else { - const struct sockaddr_in *paddr_in = ( const struct sockaddr_in * ) paddr; - return ipAddrToDottedIP ( paddr_in, pBuf, bufSize ); - } -} - -/* - * ipAddrToDottedIP () - */ -unsigned epicsShareAPI ipAddrToDottedIP ( - const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize ) -{ - static const char * pErrStr = ""; - unsigned chunk[nDigitsDottedIP]; - unsigned addr = ntohl ( paddr->sin_addr.s_addr ); - unsigned strLen; - unsigned i; - int status; - - if ( bufSize == 0u ) { - return 0u; - } - - for ( i = 0; i < nDigitsDottedIP; i++ ) { - chunk[i] = addr & makeMask ( chunkSize ); - addr >>= chunkSize; - } - - /* - * inet_ntoa() isnt used because it isnt thread safe - * (and the replacements are not standardized) - */ - status = epicsSnprintf ( - pBuf, bufSize, "%u.%u.%u.%u:%hu", - chunk[3], chunk[2], chunk[1], chunk[0], - ntohs ( paddr->sin_port ) ); - if ( status > 0 ) { - strLen = ( unsigned ) status; - if ( strLen < bufSize - 1 ) { - return strLen; - } - } - strLen = strlen ( pErrStr ); - if ( strLen < bufSize ) { - strcpy ( pBuf, pErrStr ); - return strLen; - } - else { - strncpy ( pBuf, pErrStr, bufSize ); - pBuf[bufSize-1] = '\0'; - return bufSize - 1u; - } -} - diff --git a/src/libCom/osi/osiSock.h b/src/libCom/osi/osiSock.h deleted file mode 100644 index 061619e89..000000000 --- a/src/libCom/osi/osiSock.h +++ /dev/null @@ -1,208 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * socket support library API def - * - * 7-1-97 -joh- - */ -#ifndef osiSockh -#define osiSockh - -#include "shareLib.h" -#include "osdSock.h" -#include "ellLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct sockaddr; -struct sockaddr_in; -struct in_addr; - -epicsShareFunc SOCKET epicsShareAPI epicsSocketCreate ( - int domain, int type, int protocol ); -epicsShareFunc int epicsShareAPI epicsSocketAccept ( - int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ); -epicsShareFunc void epicsShareAPI epicsSocketDestroy ( - SOCKET ); -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ); -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ); - -/* - * Fortunately, on most systems the combination of a shutdown of both - * directions and or a signal is sufficent to interrupt a blocking send, - * receive, or connect call. For odd ball systems this is stubbed out in the - * osi area. - */ -enum epicsSocketSystemCallInterruptMechanismQueryInfo { - esscimqi_socketCloseRequired, - esscimqi_socketBothShutdownRequired, - esscimqi_socketSigAlarmRequired /* NO LONGER USED/SUPPORTED */ -}; -epicsShareFunc enum epicsSocketSystemCallInterruptMechanismQueryInfo - epicsSocketSystemCallInterruptMechanismQuery (); - - -/* - * convert socket address to ASCII in this order - * 1) look for matching host name and typically add trailing IP port - * 2) failing that, convert to raw ascii address (typically this is a - * dotted IP address with trailing port) - * 3) failing that, writes "" into pBuf - * - * returns the number of character elements stored in buffer not - * including the null termination, but always writes at least a - * null ternminater in the string (if bufSize >= 1) - */ -epicsShareFunc unsigned epicsShareAPI sockAddrToA ( - const struct sockaddr * paddr, char * pBuf, unsigned bufSize ); - -/* - * convert IP address to ASCII in this order - * 1) look for matching host name and add trailing port - * 2) convert to raw dotted IP address with trailing port - * - * returns the number of character elements stored in buffer not - * including the null termination, but always writes at least a - * null ternminater in the string (if bufSize >= 1) - */ -epicsShareFunc unsigned epicsShareAPI ipAddrToA ( - const struct sockaddr_in * pInetAddr, char * pBuf, unsigned bufSize ); - -/* - * sockAddrToDottedIP () - * typically convert to raw dotted IP address with trailing port - * - * returns the number of character elements stored in buffer not - * including the null termination, but always writes at least a - * null ternminater in the string (if bufSize >= 1) - */ -epicsShareFunc unsigned epicsShareAPI sockAddrToDottedIP ( - const struct sockaddr * paddr, char * pBuf, unsigned bufSize ); - -/* - * ipAddrToDottedIP () - * convert to raw dotted IP address with trailing port - * - * returns the number of character elements stored in buffer not - * including the null termination, but always writes at least a - * null ternminater in the string (if bufSize >= 1) - */ -epicsShareFunc unsigned epicsShareAPI ipAddrToDottedIP ( - const struct sockaddr_in * paddr, char * pBuf, unsigned bufSize ); - -/* - * convert inet address to a host name string - * - * returns the number of character elements stored in buffer not - * including the null termination. This will be zero if a matching - * host name cant be found. - * - * there are many OS specific implementation stubs for this routine - */ -epicsShareFunc unsigned epicsShareAPI ipAddrToHostName ( - const struct in_addr * pAddr, char * pBuf, unsigned bufSize ); - -/* - * attempt to convert ASCII string to an IP address in this order - * 1) look for traditional doted ip with optional port - * 2) look for raw number form of ip address with optional port - * 3) look for valid host name with optional port - */ -epicsShareFunc int epicsShareAPI aToIPAddr - ( const char * pAddrString, unsigned short defaultPort, struct sockaddr_in * pIP); - -/* - * attempt to convert ASCII host name string with optional port to an IP address - */ -epicsShareFunc int epicsShareAPI hostToIPAddr - (const char *pHostName, struct in_addr *pIPA); -/* - * attach to BSD socket library - */ -epicsShareFunc int epicsShareAPI osiSockAttach (void); /* returns T if success, else F */ - -/* - * release BSD socket library - */ -epicsShareFunc void epicsShareAPI osiSockRelease (void); - -/* - * convert socket error numbers to a string - */ -epicsShareFunc void epicsSocketConvertErrorToString ( - char * pBuf, unsigned bufSize, int error ); -epicsShareFunc void epicsSocketConvertErrnoToString ( - char * pBuf, unsigned bufSize ); - -typedef union osiSockAddr { - struct sockaddr_in ia; - struct sockaddr sa; -} osiSockAddr; - -typedef struct osiSockAddrNode { - ELLNODE node; - osiSockAddr addr; -} osiSockAddrNode; - -/* - * sockAddrAreIdentical() - * (returns true if addresses are identical) - */ -epicsShareFunc int epicsShareAPI sockAddrAreIdentical - ( const osiSockAddr * plhs, const osiSockAddr * prhs ); - -/* - * osiSockDiscoverBroadcastAddresses () - * Returns the broadcast addresses of each network interface found. - * - * This routine is provided with the address of an ELLLIST, a socket, - * a destination port number, and a match address. When the - * routine returns there will be one additional entry - * (an osiSockAddrNode) in the list for each network interface found that - * is up and isnt a loop back interface (match addr is INADDR_ANY), - * or only the interfaces that match the specified addresses (match addr - * is other than INADDR_ANY). If the interface supports broadcasting - * then add its broadcast address to the list. If the interface is a - * point to point link then add the destination address of the point to - * point link to the list. - * - * Any mutex locking required to protect pList is applied externally. - * - */ -epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses - (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr); - -/* - * osiLocalAddr () - * Returns the osiSockAddr of the first non-loopback interface found - * that is operational (up flag is set). If no valid address can be - * located then return an osiSockAddr with the address family set to - * unspecified (AF_UNSPEC). - * - * Unfortunately in EPICS 3.13 beta 11 and before the CA - * repeater would not always allow the loopback address - * as a local client address so current clients alternate - * between the address of the first non-loopback interface - * found and the loopback addresss when subscribing with - * the CA repeater until all CA repeaters have been updated - * to current code. After all CA repeaters have been restarted - * this osi interface can be eliminated. - */ -epicsShareFunc osiSockAddr epicsShareAPI osiLocalAddr (SOCKET socket); - -#ifdef __cplusplus -} -#endif - -#endif /* ifndef osiSockh */ diff --git a/src/libCom/osi/osiWireFormat.h b/src/libCom/osi/osiWireFormat.h deleted file mode 100644 index 4d7e6717f..000000000 --- a/src/libCom/osi/osiWireFormat.h +++ /dev/null @@ -1,257 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef osiWireFormat -#define osiWireFormat - -#include "epicsTypes.h" - -// -// With future CA protocols user defined payload composition will be -// supported and we will need to move away from a naturally aligned -// protocol (because pad byte overhead will probably be excessive when -// maintaining 8 byte natural alignment if the user isnt thinking about -// placing like sized elements together). -// -// Nevertheless, the R3.14 protocol continues to be naturally aligned, -// and all of the fields within the DBR_XXXX types are naturally aligned. -// Therefore we support here two wire transfer interfaces (naturally -// aligned and otherwise) because there are important optimizations -// specific to each of them. -// -// At some point in the future the naturally aligned interfaces might -// be eliminated (or unbundled from base) should they be no-longer needed. -// - -template < class T > -void WireGet ( const epicsUInt8 * pWireSrc, T & ); - -template < class T > -void WireSet ( const T &, epicsUInt8 * pWireDst ); - -template < class T > -void AlignedWireGet ( const T &, T & ); - -template < class T > -void AlignedWireSet ( const T &, T & ); - -template < class T > -class AlignedWireRef { -public: - AlignedWireRef ( T & ref ); - operator T () const; - AlignedWireRef < T > & operator = ( const T & ); -private: - T & _ref; - AlignedWireRef ( const AlignedWireRef & ); - AlignedWireRef & operator = ( const AlignedWireRef & ); -}; - -template < class T > -class AlignedWireRef < const T > { -public: - AlignedWireRef ( const T & ref ); - operator T () const; -private: - const T & _ref; - AlignedWireRef ( const AlignedWireRef & ); - AlignedWireRef & operator = ( const AlignedWireRef & ); -}; - -template < class T > -inline AlignedWireRef < T > :: AlignedWireRef ( T & ref ) : - _ref ( ref ) -{ -} - -template < class T > -inline AlignedWireRef < T > :: operator T () const -{ - T tmp; - AlignedWireGet ( _ref, tmp ); - return tmp; -} - -template < class T > -inline AlignedWireRef < T > & AlignedWireRef < T > :: operator = ( const T & src ) -{ - AlignedWireSet ( src, _ref ); - return *this; -} - -template < class T > -inline AlignedWireRef < const T > :: AlignedWireRef ( const T & ref ) : - _ref ( ref ) -{ -} - -template < class T > -inline AlignedWireRef < const T > :: operator T () const -{ - T tmp; - AlignedWireGet ( _ref, tmp ); - return tmp; -} - -// may be useful when creating support for little endian -inline epicsUInt16 byteSwap ( const epicsUInt16 & src ) -{ - return static_cast < epicsUInt16 > - ( ( src << 8u ) | ( src >> 8u ) ); -} - -// may be useful when creating support for little endian -inline epicsUInt32 byteSwap ( const epicsUInt32 & src ) -{ - epicsUInt32 tmp0 = byteSwap ( - static_cast < epicsUInt16 > ( src >> 16u ) ); - epicsUInt32 tmp1 = byteSwap ( - static_cast < epicsUInt16 > ( src ) ); - return static_cast < epicsUInt32 > - ( ( tmp1 << 16u ) | tmp0 ); -} - -template < class T > union WireAlias; - -template <> -union WireAlias < epicsInt8 > { - epicsUInt8 _u; - epicsInt8 _o; -}; - -template <> -union WireAlias < epicsInt16 > { - epicsUInt16 _u; - epicsInt16 _o; -}; - -template <> -union WireAlias < epicsInt32 > { - epicsUInt32 _u; - epicsInt32 _o; -}; - -template <> -union WireAlias < epicsFloat32 > { - epicsUInt32 _u; - epicsFloat32 _o; -}; - -// -// Missaligned unsigned wire format get/set can be implemented generically -// w/o performance penalty. Attempts to improve this on architectures that -// dont have alignement requirements will probably get into trouble with -// over-aggressive optimization under strict aliasing rules. -// - -template < class T > -inline void WireGet ( const epicsUInt8 * pWireSrc, T & dst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - WireAlias < T > tmp; - WireGet ( pWireSrc, tmp._u ); - dst = tmp._o; -} - -template <> -inline void WireGet < epicsUInt8 > ( - const epicsUInt8 * pWireSrc, epicsUInt8 & dst ) -{ - dst = pWireSrc[0]; -} - -template <> -inline void WireGet < epicsUInt16 > ( - const epicsUInt8 * pWireSrc, epicsUInt16 & dst ) -{ - dst = static_cast < epicsUInt16 > ( - ( pWireSrc[0] << 8u ) | pWireSrc[1] ); -} - -template <> -inline void WireGet < epicsUInt32 > ( - const epicsUInt8 * pWireSrc, epicsUInt32 & dst ) -{ - dst = static_cast < epicsUInt32 > ( - ( pWireSrc[0] << 24u ) | - ( pWireSrc[1] << 16u ) | - ( pWireSrc[2] << 8u ) | - pWireSrc[3] ); -} - -template < class T > -inline void WireSet ( const T & src, epicsUInt8 * pWireDst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - WireAlias < T > tmp; - tmp._o = src; - WireSet ( tmp._u, pWireDst ); -} - -template <> -inline void WireSet < epicsUInt8 > ( - const epicsUInt8 & src, epicsUInt8 * pWireDst ) -{ - pWireDst[0] = src; -} - -template <> -inline void WireSet < epicsUInt16 > ( - const epicsUInt16 & src, epicsUInt8 * pWireDst ) -{ - pWireDst[0] = static_cast < epicsUInt8 > ( src >> 8u ); - pWireDst[1] = static_cast < epicsUInt8 > ( src ); -} - -template <> -inline void WireSet < epicsUInt32 > ( - const epicsUInt32 & src, epicsUInt8 * pWireDst ) -{ - pWireDst[0] = static_cast < epicsUInt8 > ( src >> 24u ); - pWireDst[1] = static_cast < epicsUInt8 > ( src >> 16u ); - pWireDst[2] = static_cast < epicsUInt8 > ( src >> 8u ); - pWireDst[3] = static_cast < epicsUInt8 > ( src ); -} - -template < class T > -inline void AlignedWireGet ( const T & src, T & dst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - WireAlias < T > srcu, dstu; - srcu._o = src; - AlignedWireGet ( srcu._u, dstu._u ); - dst = dstu._o; -} - -template < class T > -inline void AlignedWireSet ( const T & src, T & dst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - WireAlias < T > srcu, dstu; - srcu._o = src; - AlignedWireSet ( srcu._u, dstu._u ); - dst = dstu._o; -} - -#include "osdWireFormat.h" - -#endif // osiWireFormat diff --git a/src/libCom/pool/Makefile b/src/libCom/pool/Makefile deleted file mode 100644 index efaf66729..000000000 --- a/src/libCom/pool/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -#************************************************************************* -# Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/pool - -INC += epicsThreadPool.h - -Com_SRCS += poolJob.c -Com_SRCS += threadPool.c - diff --git a/src/libCom/pool/epicsThreadPool.h b/src/libCom/pool/epicsThreadPool.h deleted file mode 100644 index 3416bb23a..000000000 --- a/src/libCom/pool/epicsThreadPool.h +++ /dev/null @@ -1,160 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* General purpose worker thread pool manager - * mdavidsaver@bnl.gov - */ -#ifndef EPICSTHREADPOOL_H -#define EPICSTHREADPOOL_H - -#include -#include - -#include "shareLib.h" -#include "errMdef.h" - -#define S_pool_jobBusy (M_pool| 1) /*Job already queued or running*/ -#define S_pool_jobIdle (M_pool| 2) /*Job was not queued or running*/ -#define S_pool_noPool (M_pool| 3) /*Job not associated with a pool*/ -#define S_pool_paused (M_pool| 4) /*Pool not currently accepting jobs*/ -#define S_pool_noThreads (M_pool| 5) /*Can't create worker thread*/ -#define S_pool_timeout (M_pool| 6) /*Pool still busy after timeout*/ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - unsigned int initialThreads; - unsigned int maxThreads; - unsigned int workerStack; - unsigned int workerPriority; -} epicsThreadPoolConfig; - -typedef struct epicsThreadPool epicsThreadPool; - -/* Job function call modes */ -typedef enum { - /* Normal run of job */ - epicsJobModeRun, - - /* Thread pool is being destroyed. - * A chance to cleanup the job immediately with epicsJobDestroy(). - * If ignored, the job is orphaned (dissociated from the thread pool) - * and epicsJobDestroy() must be called later. - */ - epicsJobModeCleanup -} epicsJobMode; - -typedef void (*epicsJobFunction)(void* arg, epicsJobMode mode); - -typedef struct epicsJob epicsJob; - -/* Pool operations */ - -/* Initialize a pool config with default values. - * This much be done to preserve future compatibility - * when new options are added. - */ -epicsShareFunc void epicsThreadPoolConfigDefaults(epicsThreadPoolConfig *); - -/* fetch or create a thread pool which can be shared with other users. - * may return NULL for allocation failures - */ -epicsShareFunc epicsThreadPool* epicsThreadPoolGetShared(epicsThreadPoolConfig *opts); -epicsShareFunc void epicsThreadPoolReleaseShared(epicsThreadPool *pool); - -/* If opts is NULL then defaults are used. - * The opts pointer is not stored by this call, and may exist on the stack. - */ -epicsShareFunc epicsThreadPool* epicsThreadPoolCreate(epicsThreadPoolConfig *opts); - -/* Blocks until all worker threads have stopped. - * Any jobs still attached to this pool receive a callback with EPICSJOB_CLEANUP - * and are then orphaned. - */ -epicsShareFunc void epicsThreadPoolDestroy(epicsThreadPool *); - -/* pool control options */ -typedef enum { - epicsThreadPoolQueueAdd, /* val==0 causes epicsJobQueue to fail, 1 is default */ - epicsThreadPoolQueueRun /* val==0 prevents workers from running jobs, 1 is default */ -} epicsThreadPoolOption; - -epicsShareFunc void epicsThreadPoolControl(epicsThreadPool* pool, - epicsThreadPoolOption opt, - unsigned int val); - -/* Block until job queue is emptied and no jobs are running. - * Useful after calling epicsThreadPoolControl() with option epicsThreadPoolQueueAdd=0 - * - * timeout<0 waits forever, timeout==0 polls, timeout>0 waits at most one timeout period - * Returns 0 for success or non-zero on error (timeout is ETIMEOUT) - */ -epicsShareFunc int epicsThreadPoolWait(epicsThreadPool* pool, double timeout); - - -/* Per job operations */ - -/* Special flag for epicsJobCreate(). - * When passed as the third argument "user" - * the argument passed to the job callback - * will be the epicsJob* - */ -#define EPICSJOB_SELF epicsJobArgSelfMagic -epicsShareExtern void* epicsJobArgSelfMagic; - -/* Creates, but does not add, a new job. - * If pool is NULL then the job is not associated with any pool and - * epicsJobMove() must be called before epicsJobQueue(). - * Safe to call from a running job function. - * Returns a new job pointer, or NULL on error. - */ -epicsShareFunc epicsJob* epicsJobCreate(epicsThreadPool* pool, - epicsJobFunction cb, - void* user); - -/* Cancel and free a job structure. Does not block. - * Job may not be immediately free'd. - * Safe to call from a running job function. - */ -epicsShareFunc void epicsJobDestroy(epicsJob*); - -/* Move the job to a different pool. - * If pool is NULL then the job will no longer be associated - * with any pool. - * Not thread safe. Job must not be running or queued. - * returns 0 on success, non-zero on error. - */ -epicsShareFunc int epicsJobMove(epicsJob* job, epicsThreadPool* pool); - -/* Adds the job to the run queue - * Safe to call from a running job function. - * returns 0 for success, non-zero on error. - */ -epicsShareFunc int epicsJobQueue(epicsJob*); - -/* Remove a job from the run queue if it is queued. - * Safe to call from a running job function. - * returns 0 if job was queued and now is not. - * 1 if job already ran, is running, or was not queued before, - * Other non-zero on error - */ -epicsShareFunc int epicsJobUnqueue(epicsJob*); - - -/* Mostly useful for debugging */ - -epicsShareFunc void epicsThreadPoolReport(epicsThreadPool *pool, FILE *fd); - -/* Current number of active workers. May be less than the maximum */ -epicsShareFunc unsigned int epicsThreadPoolNThreads(epicsThreadPool *); - -#ifdef __cplusplus -} -#endif - -#endif // EPICSTHREADPOOL_H diff --git a/src/libCom/pool/poolJob.c b/src/libCom/pool/poolJob.c deleted file mode 100644 index 8e86fb768..000000000 --- a/src/libCom/pool/poolJob.c +++ /dev/null @@ -1,327 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include - -#define epicsExportSharedSymbols - -#include "dbDefs.h" -#include "errlog.h" -#include "ellLib.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "epicsInterrupt.h" - -#include "epicsThreadPool.h" -#include "poolPriv.h" - -void *epicsJobArgSelfMagic = &epicsJobArgSelfMagic; - -static -void workerMain(void *arg) -{ - epicsThreadPool *pool = arg; - unsigned int nrun, ocnt; - - /* workers are created with counts - * in the running, sleeping, and (possibly) waking counters - */ - - epicsMutexMustLock(pool->guard); - pool->threadsAreAwake++; - pool->threadsSleeping--; - - while (1) { - ELLNODE *cur; - - pool->threadsAreAwake--; - pool->threadsSleeping++; - epicsMutexUnlock(pool->guard); - - epicsEventMustWait(pool->workerWakeup); - - epicsMutexMustLock(pool->guard); - pool->threadsSleeping--; - pool->threadsAreAwake++; - - if (pool->threadsWaking==0) - continue; - - pool->threadsWaking--; - - CHECKCOUNT(pool); - - if (pool->shutdown) - break; - - if (pool->pauserun) - continue; - - /* more threads to wakeup */ - if (pool->threadsWaking) { - epicsEventSignal(pool->workerWakeup); - } - - while ((cur=ellGet(&pool->jobs)) != NULL) { - epicsJob *job = CONTAINER(cur, epicsJob, jobnode); - - assert(job->queued && !job->running); - - job->queued=0; - job->running=1; - - epicsMutexUnlock(pool->guard); - (*job->func)(job->arg, epicsJobModeRun); - epicsMutexMustLock(pool->guard); - - if (job->freewhendone) { - job->dead=1; - free(job); - } - else { - job->running=0; - /* job may be re-queued from within callback */ - if (job->queued) - ellAdd(&pool->jobs, &job->jobnode); - else - ellAdd(&pool->owned, &job->jobnode); - } - } - - if (pool->observerCount) - epicsEventSignal(pool->observerWakeup); - } - - pool->threadsAreAwake--; - pool->threadsRunning--; - - nrun = pool->threadsRunning; - ocnt = pool->observerCount; - epicsMutexUnlock(pool->guard); - - if (ocnt) - epicsEventSignal(pool->observerWakeup); - - if (nrun) - epicsEventSignal(pool->workerWakeup); /* pass along */ - else - epicsEventSignal(pool->shutdownEvent); -} - -int createPoolThread(epicsThreadPool *pool) -{ - epicsThreadId tid; - - tid = epicsThreadCreate("PoolWorker", - pool->conf.workerPriority, - pool->conf.workerStack, - &workerMain, - pool); - if (!tid) - return S_pool_noThreads; - - pool->threadsRunning++; - pool->threadsSleeping++; - return 0; -} - -epicsJob* epicsJobCreate(epicsThreadPool *pool, - epicsJobFunction func, - void *arg) -{ - epicsJob *job = calloc(1, sizeof(*job)); - - if (!job) - return NULL; - - if (arg == &epicsJobArgSelfMagic) - arg = job; - - job->pool = NULL; - job->func = func; - job->arg = arg; - - epicsJobMove(job, pool); - - return job; -} - -void epicsJobDestroy(epicsJob *job) -{ - epicsThreadPool *pool; - if (!job || !job->pool) { - free(job); - return; - } - pool = job->pool; - - epicsMutexMustLock(pool->guard); - - assert(!job->dead); - - epicsJobUnqueue(job); - - if (job->running || job->freewhendone) { - job->freewhendone = 1; - } - else { - ellDelete(&pool->owned, &job->jobnode); - job->dead = 1; - free(job); - } - - epicsMutexUnlock(pool->guard); -} - -int epicsJobMove(epicsJob *job, epicsThreadPool *newpool) -{ - epicsThreadPool *pool = job->pool; - - /* remove from current pool */ - if (pool) { - epicsMutexMustLock(pool->guard); - - if (job->queued || job->running) { - epicsMutexUnlock(pool->guard); - return S_pool_jobBusy; - } - - ellDelete(&pool->owned, &job->jobnode); - - epicsMutexUnlock(pool->guard); - } - - pool = job->pool = newpool; - - /* add to new pool */ - if (pool) { - epicsMutexMustLock(pool->guard); - - ellAdd(&pool->owned, &job->jobnode); - - epicsMutexUnlock(pool->guard); - } - - return 0; -} - -int epicsJobQueue(epicsJob *job) -{ - int ret = 0; - epicsThreadPool *pool = job->pool; - - if (!pool) - return S_pool_noPool; - - epicsMutexMustLock(pool->guard); - - assert(!job->dead); - - if (pool->pauseadd) { - ret = S_pool_paused; - goto done; - } - else if (job->freewhendone) { - ret = S_pool_jobBusy; - goto done; - } - else if (job->queued) { - goto done; - } - - job->queued = 1; - /* Job may be queued from within a callback */ - if (!job->running) { - ellDelete(&pool->owned, &job->jobnode); - ellAdd(&pool->jobs, &job->jobnode); - } - else { - /* some worker will find it again before sleeping */ - goto done; - } - - /* Since we hold the lock, we can be certain that all awake worker are - * executing work functions. The current thread may be a worker. - * We prefer to wakeup a new worker rather then wait for a busy worker to - * finish. However, after we initiate a wakeup there will be a race - * between the worker waking up, and a busy worker finishing. - * Thus we can't avoid spurious wakeups. - */ - - if (pool->threadsRunning >= pool->conf.maxThreads) { - /* all workers created... */ - /* ... but some are sleeping, so wake one up */ - if (pool->threadsWaking < pool->threadsSleeping) { - pool->threadsWaking++; - epicsEventSignal(pool->workerWakeup); - } - /*else one of the running workers will find this job before sleeping */ - CHECKCOUNT(pool); - - } - else { - /* could create more workers so - * will either create a new worker, or wakeup an existing worker - */ - - if (pool->threadsWaking >= pool->threadsSleeping) { - /* all sleeping workers have already been woken. - * start a new worker for this job - */ - if (createPoolThread(pool) && pool->threadsRunning == 0) { - /* oops, we couldn't lazy create our first worker - * so this job would never run! - */ - ret = S_pool_noThreads; - job->queued = 0; - /* if threadsRunning==0 then no jobs can be running */ - assert(!job->running); - ellDelete(&pool->jobs, &job->jobnode); - ellAdd(&pool->owned, &job->jobnode); - } - } - if (ret == 0) { - pool->threadsWaking++; - epicsEventSignal(pool->workerWakeup); - } - CHECKCOUNT(pool); - } - -done: - epicsMutexUnlock(pool->guard); - return ret; -} - -int epicsJobUnqueue(epicsJob *job) -{ - int ret = S_pool_jobIdle; - epicsThreadPool *pool = job->pool; - - if (!pool) - return S_pool_noPool; - - epicsMutexMustLock(pool->guard); - - assert(!job->dead); - - if (job->queued) { - if (!job->running) { - ellDelete(&pool->jobs, &job->jobnode); - ellAdd(&pool->owned, &job->jobnode); - } - job->queued = 0; - ret = 0; - } - - epicsMutexUnlock(pool->guard); - - return ret; -} - diff --git a/src/libCom/pool/poolPriv.h b/src/libCom/pool/poolPriv.h deleted file mode 100644 index 237cedf45..000000000 --- a/src/libCom/pool/poolPriv.h +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef POOLPRIV_H -#define POOLPRIV_H - -#include "epicsThreadPool.h" -#include "ellLib.h" -#include "epicsThread.h" -#include "epicsEvent.h" -#include "epicsMutex.h" - -struct epicsThreadPool { - ELLNODE sharedNode; - size_t sharedCount; - - ELLLIST jobs; /* run queue */ - ELLLIST owned; /* unqueued jobs. */ - - /* Worker state counters. - * The life cycle of a worker is - * Wakeup -> Awake -> Sleeping - * Newly created workers go into the wakeup state - */ - - /* # of running workers which are not waiting for a wakeup event */ - unsigned int threadsAreAwake; - /* # of sleeping workers which need to be awakened */ - unsigned int threadsWaking; - /* # of workers waiting on the workerWakeup event */ - unsigned int threadsSleeping; - /* # of threads started and not stopped */ - unsigned int threadsRunning; - - /* # of observers waiting on pool events */ - unsigned int observerCount; - - epicsEventId workerWakeup; - epicsEventId shutdownEvent; - - epicsEventId observerWakeup; - - /* Disallow epicsJobQueue */ - unsigned int pauseadd:1; - /* Prevent workers from running new jobs */ - unsigned int pauserun:1; - /* Prevent further changes to pool options */ - unsigned int freezeopt:1; - /* tell workers to exit */ - unsigned int shutdown:1; - - epicsMutexId guard; - - /* copy of config passed when created */ - epicsThreadPoolConfig conf; -}; - -/* Called after manipulating counters to check that invariants are preserved */ -#define CHECKCOUNT(pPool) do { \ - if (!(pPool)->shutdown) { \ - assert((pPool)->threadsAreAwake + (pPool)->threadsSleeping == (pPool)->threadsRunning); \ - assert((pPool)->threadsWaking <= (pPool)->threadsSleeping); \ - } \ -} while(0) - -/* When created a job is idle. queued and running are false - * and jobnode is in the thread pool's owned list. - * - * When the job is added, the queued flag is set and jobnode - * is in the jobs list. - * - * When the job starts running the queued flag is cleared and - * the running flag is set. jobnode is not in any list - * (held locally by worker). - * - * When the job has finished running, the running flag is cleared. - * The queued flag may be set if the job re-added itself. - * Based on the queued flag jobnode is added to the appropriate - * list. - */ -struct epicsJob { - ELLNODE jobnode; - epicsJobFunction func; - void *arg; - epicsThreadPool *pool; - - unsigned int queued:1; - unsigned int running:1; - unsigned int freewhendone:1; /* lazy delete of running job */ - unsigned int dead:1; /* flag to catch use of freed objects */ -}; - -int createPoolThread(epicsThreadPool *pool); - -#endif // POOLPRIV_H diff --git a/src/libCom/pool/threadPool.c b/src/libCom/pool/threadPool.c deleted file mode 100644 index 3cfd06606..000000000 --- a/src/libCom/pool/threadPool.c +++ /dev/null @@ -1,403 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include - -#define epicsExportSharedSymbols - -#include "dbDefs.h" -#include "errlog.h" -#include "ellLib.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "epicsInterrupt.h" -#include "cantProceed.h" - -#include "epicsThreadPool.h" -#include "poolPriv.h" - - -void epicsThreadPoolConfigDefaults(epicsThreadPoolConfig *opts) -{ - memset(opts, 0, sizeof(*opts)); - opts->maxThreads = epicsThreadGetCPUs(); - opts->workerStack = epicsThreadGetStackSize(epicsThreadStackSmall); - - if (epicsThreadLowestPriorityLevelAbove(epicsThreadPriorityCAServerHigh, &opts->workerPriority) - != epicsThreadBooleanStatusSuccess) - opts->workerPriority = epicsThreadPriorityMedium; -} - -epicsThreadPool* epicsThreadPoolCreate(epicsThreadPoolConfig *opts) -{ - size_t i; - epicsThreadPool *pool; - - /* caller likely didn't initialize the options structure */ - if (opts && opts->maxThreads == 0) { - errlogMessage("Error: epicsThreadPoolCreate() options provided, but not initialized"); - return NULL; - } - - pool = calloc(1, sizeof(*pool)); - if (!pool) - return NULL; - - if (opts) - memcpy(&pool->conf, opts, sizeof(*opts)); - else - epicsThreadPoolConfigDefaults(&pool->conf); - - if (pool->conf.initialThreads > pool->conf.maxThreads) - pool->conf.initialThreads = pool->conf.maxThreads; - - pool->workerWakeup = epicsEventCreate(epicsEventEmpty); - pool->shutdownEvent = epicsEventCreate(epicsEventEmpty); - pool->observerWakeup = epicsEventCreate(epicsEventEmpty); - pool->guard = epicsMutexCreate(); - - if (!pool->workerWakeup || !pool->shutdownEvent || - !pool->observerWakeup || !pool->guard) - goto cleanup; - - ellInit(&pool->jobs); - ellInit(&pool->owned); - - epicsMutexMustLock(pool->guard); - - for (i = 0; i < pool->conf.initialThreads; i++) { - createPoolThread(pool); - } - - if (pool->threadsRunning == 0 && pool->conf.initialThreads != 0) { - epicsMutexUnlock(pool->guard); - errlogPrintf("Error: Unable to create any threads for thread pool\n"); - goto cleanup; - - } - else if (pool->threadsRunning < pool->conf.initialThreads) { - errlogPrintf("Warning: Unable to create all threads for thread pool (%u/%u)\n", - pool->threadsRunning, pool->conf.initialThreads); - } - - epicsMutexUnlock(pool->guard); - - return pool; - -cleanup: - if (pool->workerWakeup) - epicsEventDestroy(pool->workerWakeup); - if (pool->shutdownEvent) - epicsEventDestroy(pool->shutdownEvent); - if (pool->observerWakeup) - epicsEventDestroy(pool->observerWakeup); - if (pool->guard) - epicsMutexDestroy(pool->guard); - - free(pool); - return NULL; -} - -static -void epicsThreadPoolControlImpl(epicsThreadPool *pool, epicsThreadPoolOption opt, unsigned int val) -{ - if (pool->freezeopt) - return; - - if (opt == epicsThreadPoolQueueAdd) { - pool->pauseadd = !val; - } - else if (opt == epicsThreadPoolQueueRun) { - if (!val && !pool->pauserun) - pool->pauserun = 1; - - else if (val && pool->pauserun) { - int jobs = ellCount(&pool->jobs); - pool->pauserun = 0; - - if (jobs) { - int wakeable = pool->threadsSleeping - pool->threadsWaking; - - /* first try to give jobs to sleeping workers */ - if (wakeable) { - int wakeup = jobs > wakeable ? wakeable : jobs; - assert(wakeup > 0); - jobs -= wakeup; - pool->threadsWaking += wakeup; - epicsEventSignal(pool->workerWakeup); - CHECKCOUNT(pool); - } - } - while (jobs-- && pool->threadsRunning < pool->conf.maxThreads) { - if (createPoolThread(pool) == 0) { - pool->threadsWaking++; - epicsEventSignal(pool->workerWakeup); - } - else - break; /* oops, couldn't create worker */ - } - CHECKCOUNT(pool); - } - } - /* unknown options ignored */ - -} - -void epicsThreadPoolControl(epicsThreadPool *pool, epicsThreadPoolOption opt, unsigned int val) -{ - epicsMutexMustLock(pool->guard); - epicsThreadPoolControlImpl(pool, opt, val); - epicsMutexUnlock(pool->guard); -} - -int epicsThreadPoolWait(epicsThreadPool *pool, double timeout) -{ - int ret = 0; - epicsMutexMustLock(pool->guard); - - while (ellCount(&pool->jobs) > 0 || pool->threadsAreAwake > 0) { - pool->observerCount++; - epicsMutexUnlock(pool->guard); - - if (timeout < 0.0) { - epicsEventMustWait(pool->observerWakeup); - } - else { - switch (epicsEventWaitWithTimeout(pool->observerWakeup, timeout)) { - case epicsEventWaitError: - cantProceed("epicsThreadPoolWait: failed to wait for Event"); - break; - case epicsEventWaitTimeout: - ret = S_pool_timeout; - break; - case epicsEventWaitOK: - ret = 0; - break; - } - } - - epicsMutexMustLock(pool->guard); - pool->observerCount--; - - if (pool->observerCount) - epicsEventSignal(pool->observerWakeup); - - if (ret != 0) - break; - } - - epicsMutexUnlock(pool->guard); - return ret; -} - -void epicsThreadPoolDestroy(epicsThreadPool *pool) -{ - unsigned int nThr; - ELLLIST notify; - ELLNODE *cur; - - if (!pool) - return; - - ellInit(¬ify); - - epicsMutexMustLock(pool->guard); - - /* run remaining queued jobs */ - epicsThreadPoolControlImpl(pool, epicsThreadPoolQueueAdd, 0); - epicsThreadPoolControlImpl(pool, epicsThreadPoolQueueRun, 1); - nThr = pool->threadsRunning; - pool->freezeopt = 1; - - epicsMutexUnlock(pool->guard); - - epicsThreadPoolWait(pool, -1.0); - /* At this point all queued jobs have run */ - - epicsMutexMustLock(pool->guard); - - pool->shutdown = 1; - /* wakeup all */ - if (pool->threadsWaking < pool->threadsSleeping) { - pool->threadsWaking = pool->threadsSleeping; - epicsEventSignal(pool->workerWakeup); - } - - ellConcat(¬ify, &pool->owned); - ellConcat(¬ify, &pool->jobs); - - epicsMutexUnlock(pool->guard); - - if (nThr && epicsEventWait(pool->shutdownEvent) != epicsEventWaitOK){ - errlogMessage("epicsThreadPoolDestroy: wait error"); - return; - } - - /* all workers are now shutdown */ - - /* notify remaining jobs that pool is being destroyed */ - while ((cur = ellGet(¬ify)) != NULL) { - epicsJob *job = CONTAINER(cur, epicsJob, jobnode); - - job->running = 1; - job->func(job->arg, epicsJobModeCleanup); - job->running = 0; - if (job->freewhendone) - free(job); - else - job->pool = NULL; /* orphan */ - } - - epicsEventDestroy(pool->workerWakeup); - epicsEventDestroy(pool->shutdownEvent); - epicsEventDestroy(pool->observerWakeup); - epicsMutexDestroy(pool->guard); - - free(pool); -} - - -void epicsThreadPoolReport(epicsThreadPool *pool, FILE *fd) -{ - ELLNODE *cur; - epicsMutexMustLock(pool->guard); - - fprintf(fd, "Thread Pool with %u/%u threads\n" - " running %d jobs with %u threads\n", - pool->threadsRunning, - pool->conf.maxThreads, - ellCount(&pool->jobs), - pool->threadsAreAwake); - if (pool->pauseadd) - fprintf(fd, " Inhibit queueing\n"); - if (pool->pauserun) - fprintf(fd, " Pause workers\n"); - if (pool->shutdown) - fprintf(fd, " Shutdown in progress\n"); - - for (cur = ellFirst(&pool->jobs); cur; cur = ellNext(cur)) { - epicsJob *job = CONTAINER(cur, epicsJob, jobnode); - - fprintf(fd, " job %p func: %p, arg: %p ", - job, job->func, - job->arg); - if (job->queued) - fprintf(fd, "Queued "); - if (job->running) - fprintf(fd, "Running "); - if (job->freewhendone) - fprintf(fd, "Free "); - fprintf(fd, "\n"); - } - - epicsMutexUnlock(pool->guard); -} - -unsigned int epicsThreadPoolNThreads(epicsThreadPool *pool) -{ - unsigned int ret; - - epicsMutexMustLock(pool->guard); - ret = pool->threadsRunning; - epicsMutexUnlock(pool->guard); - - return ret; -} - -static -ELLLIST sharedPools = ELLLIST_INIT; - -static -epicsMutexId sharedPoolsGuard; - -static -epicsThreadOnceId sharedPoolsOnce = EPICS_THREAD_ONCE_INIT; - -static -void sharedPoolsInit(void* unused) -{ - sharedPoolsGuard = epicsMutexMustCreate(); -} - -epicsShareFunc epicsThreadPool* epicsThreadPoolGetShared(epicsThreadPoolConfig *opts) -{ - ELLNODE *node; - epicsThreadPool *cur; - epicsThreadPoolConfig defopts; - size_t N = epicsThreadGetCPUs(); - - if (!opts) { - epicsThreadPoolConfigDefaults(&defopts); - opts = &defopts; - } - /* shared pools must have a minimum allowed number of workers. - * Use the number of CPU cores - */ - if (opts->maxThreads < N) - opts->maxThreads = N; - - epicsThreadOnce(&sharedPoolsOnce, &sharedPoolsInit, NULL); - - epicsMutexMustLock(sharedPoolsGuard); - - for (node = ellFirst(&sharedPools); node; node = ellNext(node)) { - cur = CONTAINER(node, epicsThreadPool, sharedNode); - - /* Must have exactly the requested priority - * At least the requested max workers - * and at least the requested stack size - */ - if (cur->conf.workerPriority != opts->workerPriority) - continue; - if (cur->conf.maxThreads < opts->maxThreads) - continue; - if (cur->conf.workerStack < opts->workerStack) - continue; - - cur->sharedCount++; - assert(cur->sharedCount > 0); - epicsMutexUnlock(sharedPoolsGuard); - - epicsMutexMustLock(cur->guard); - *opts = cur->conf; - epicsMutexUnlock(cur->guard); - return cur; - } - - cur = epicsThreadPoolCreate(opts); - if (!cur) { - epicsMutexUnlock(sharedPoolsGuard); - return NULL; - } - cur->sharedCount = 1; - - ellAdd(&sharedPools, &cur->sharedNode); - epicsMutexUnlock(sharedPoolsGuard); - return cur; -} - -epicsShareFunc void epicsThreadPoolReleaseShared(epicsThreadPool *pool) -{ - if (!pool) - return; - - epicsMutexMustLock(sharedPoolsGuard); - - assert(pool->sharedCount > 0); - - pool->sharedCount--; - - if (pool->sharedCount == 0) { - ellDelete(&sharedPools, &pool->sharedNode); - epicsThreadPoolDestroy(pool); - } - - epicsMutexUnlock(sharedPoolsGuard); -} diff --git a/src/libCom/ring/Makefile b/src/libCom/ring/Makefile deleted file mode 100644 index ec2ecbd2d..000000000 --- a/src/libCom/ring/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/ring -#following needed for locating epicsRingPointer.h and epicsRingBytes.h -INC += epicsRingPointer.h -INC += epicsRingBytes.h -Com_SRCS += epicsRingPointer.cpp -Com_SRCS += epicsRingBytes.c diff --git a/src/libCom/ring/epicsRingBytes.c b/src/libCom/ring/epicsRingBytes.c deleted file mode 100644 index cb7e52e83..000000000 --- a/src/libCom/ring/epicsRingBytes.c +++ /dev/null @@ -1,226 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Marty Kraimer Date: 15JUL99 - * Eric Norum - * Ralph Lange - */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsSpin.h" -#include "dbDefs.h" -#include "epicsRingBytes.h" - -/* - * Need at least one extra byte to be able to distinguish a completely - * full buffer from a completely empty one. Allow for a little extra - * space to try and keep good alignment and avoid multiple calls to - * memcpy for a single put/get operation. - */ -#define SLOP 16 - -typedef struct ringPvt { - epicsSpinId lock; - volatile int nextPut; - volatile int nextGet; - int size; - volatile char buffer[1]; /* actually larger */ -}ringPvt; - -epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesCreate(int size) -{ - ringPvt *pring = malloc(sizeof(ringPvt) + size + SLOP); - if(!pring) - return NULL; - pring->size = size + SLOP; - pring->nextGet = 0; - pring->nextPut = 0; - pring->lock = 0; - return((void *)pring); -} - -epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesLockedCreate(int size) -{ - ringPvt *pring = (ringPvt *)epicsRingBytesCreate(size); - if(!pring) - return NULL; - pring->lock = epicsSpinCreate(); - return((void *)pring); -} - -epicsShareFunc void epicsShareAPI epicsRingBytesDelete(epicsRingBytesId id) -{ - ringPvt *pring = (ringPvt *)id; - if (pring->lock) epicsSpinDestroy(pring->lock); - free((void *)pring); -} - -epicsShareFunc int epicsShareAPI epicsRingBytesGet( - epicsRingBytesId id, char *value,int nbytes) -{ - ringPvt *pring = (ringPvt *)id; - int nextGet, nextPut, size; - int count; - - if (pring->lock) epicsSpinLock(pring->lock); - nextGet = pring->nextGet; - nextPut = pring->nextPut; - size = pring->size; - - if (nextGet <= nextPut) { - count = nextPut - nextGet; - if (count < nbytes) - nbytes = count; - if (nbytes) - memcpy (value, (void *)&pring->buffer[nextGet], nbytes); - nextGet += nbytes; - } - else { - count = size - nextGet; - if (count > nbytes) - count = nbytes; - memcpy (value, (void *)&pring->buffer[nextGet], count); - nextGet += count; - if (nextGet == size) { - int nLeft = nbytes - count; - if (nLeft > nextPut) - nLeft = nextPut; - memcpy (value+count, (void *)&pring->buffer[0], nLeft); - nextGet = nLeft; - nbytes = count + nLeft; - } - else { - nbytes = count; - } - } - pring->nextGet = nextGet; - - if (pring->lock) epicsSpinUnlock(pring->lock); - return nbytes; -} - -epicsShareFunc int epicsShareAPI epicsRingBytesPut( - epicsRingBytesId id, char *value,int nbytes) -{ - ringPvt *pring = (ringPvt *)id; - int nextGet, nextPut, size; - int freeCount, copyCount, topCount; - - if (pring->lock) epicsSpinLock(pring->lock); - nextGet = pring->nextGet; - nextPut = pring->nextPut; - size = pring->size; - - if (nextPut < nextGet) { - freeCount = nextGet - nextPut - SLOP; - if (nbytes > freeCount) { - if (pring->lock) epicsSpinUnlock(pring->lock); - return 0; - } - if (nbytes) - memcpy ((void *)&pring->buffer[nextPut], value, nbytes); - nextPut += nbytes; - } - else { - freeCount = size - nextPut + nextGet - SLOP; - if (nbytes > freeCount) { - if (pring->lock) epicsSpinUnlock(pring->lock); - return 0; - } - topCount = size - nextPut; - copyCount = (nbytes > topCount) ? topCount : nbytes; - if (copyCount) - memcpy ((void *)&pring->buffer[nextPut], value, copyCount); - nextPut += copyCount; - if (nextPut == size) { - int nLeft = nbytes - copyCount; - if (nLeft) - memcpy ((void *)&pring->buffer[0], value+copyCount, nLeft); - nextPut = nLeft; - } - } - pring->nextPut = nextPut; - - if (pring->lock) epicsSpinUnlock(pring->lock); - return nbytes; -} - -epicsShareFunc void epicsShareAPI epicsRingBytesFlush(epicsRingBytesId id) -{ - ringPvt *pring = (ringPvt *)id; - - if (pring->lock) epicsSpinLock(pring->lock); - pring->nextGet = pring->nextPut; - if (pring->lock) epicsSpinUnlock(pring->lock); -} - -epicsShareFunc int epicsShareAPI epicsRingBytesFreeBytes(epicsRingBytesId id) -{ - ringPvt *pring = (ringPvt *)id; - int nextGet, nextPut; - - if (pring->lock) epicsSpinLock(pring->lock); - nextGet = pring->nextGet; - nextPut = pring->nextPut; - if (pring->lock) epicsSpinUnlock(pring->lock); - - if (nextPut < nextGet) - return nextGet - nextPut - SLOP; - else - return pring->size - nextPut + nextGet - SLOP; -} - -epicsShareFunc int epicsShareAPI epicsRingBytesUsedBytes(epicsRingBytesId id) -{ - ringPvt *pring = (ringPvt *)id; - int nextGet, nextPut; - int used; - - if (pring->lock) epicsSpinLock(pring->lock); - nextGet = pring->nextGet; - nextPut = pring->nextPut; - if (pring->lock) epicsSpinUnlock(pring->lock); - - used = nextPut - nextGet; - if (used < 0) used += pring->size; - - return used; -} - -epicsShareFunc int epicsShareAPI epicsRingBytesSize(epicsRingBytesId id) -{ - ringPvt *pring = (ringPvt *)id; - - return pring->size - SLOP; -} - -epicsShareFunc int epicsShareAPI epicsRingBytesIsEmpty(epicsRingBytesId id) -{ - ringPvt *pring = (ringPvt *)id; - int isEmpty; - - if (pring->lock) epicsSpinLock(pring->lock); - isEmpty = (pring->nextPut == pring->nextGet); - if (pring->lock) epicsSpinUnlock(pring->lock); - - return isEmpty; -} - -epicsShareFunc int epicsShareAPI epicsRingBytesIsFull(epicsRingBytesId id) -{ - return (epicsRingBytesFreeBytes(id) <= 0); -} diff --git a/src/libCom/ring/epicsRingBytes.h b/src/libCom/ring/epicsRingBytes.h deleted file mode 100644 index 011829bfe..000000000 --- a/src/libCom/ring/epicsRingBytes.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Marty Kraimer Date: 15JUL99 - * Eric Norum - * Ralph Lange - */ - -#ifndef INCepicsRingBytesh -#define INCepicsRingBytesh - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -typedef void *epicsRingBytesId; - -epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesCreate(int nbytes); -/* Same, but secured by a spinlock */ -epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesLockedCreate(int nbytes); -epicsShareFunc void epicsShareAPI epicsRingBytesDelete(epicsRingBytesId id); -epicsShareFunc int epicsShareAPI epicsRingBytesGet( - epicsRingBytesId id, char *value,int nbytes); -epicsShareFunc int epicsShareAPI epicsRingBytesPut( - epicsRingBytesId id, char *value,int nbytes); -epicsShareFunc void epicsShareAPI epicsRingBytesFlush(epicsRingBytesId id); -epicsShareFunc int epicsShareAPI epicsRingBytesFreeBytes(epicsRingBytesId id); -epicsShareFunc int epicsShareAPI epicsRingBytesUsedBytes(epicsRingBytesId id); -epicsShareFunc int epicsShareAPI epicsRingBytesSize(epicsRingBytesId id); -epicsShareFunc int epicsShareAPI epicsRingBytesIsEmpty(epicsRingBytesId id); -epicsShareFunc int epicsShareAPI epicsRingBytesIsFull(epicsRingBytesId id); - -#ifdef __cplusplus -} -#endif - -/* NOTES - If there is only one writer it is not necessary to lock for put - If there is a single reader it is not necessary to lock for puts - - epicsRingBytesLocked uses a spinlock. -*/ - -#endif /* INCepicsRingBytesh */ diff --git a/src/libCom/ring/epicsRingPointer.cpp b/src/libCom/ring/epicsRingPointer.cpp deleted file mode 100644 index 9c144cec1..000000000 --- a/src/libCom/ring/epicsRingPointer.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Marty Kraimer Date: 13OCT2000 - * Ralph Lange - */ - - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsRingPointer.h" -typedef epicsRingPointer voidPointer; - - -epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerCreate(int size) -{ - voidPointer *pvoidPointer = new voidPointer(size, false); - return(reinterpret_cast(pvoidPointer)); -} - -epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerLockedCreate(int size) -{ - voidPointer *pvoidPointer = new voidPointer(size, true); - return(reinterpret_cast(pvoidPointer)); -} - -epicsShareFunc void epicsShareAPI epicsRingPointerDelete(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - delete pvoidPointer; -} - -epicsShareFunc void* epicsShareAPI epicsRingPointerPop(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return pvoidPointer->pop(); -} - -epicsShareFunc int epicsShareAPI epicsRingPointerPush(epicsRingPointerId id, void *p) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return((pvoidPointer->push(p) ? 1 : 0)); -} - -epicsShareFunc void epicsShareAPI epicsRingPointerFlush(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - pvoidPointer->flush(); -} - -epicsShareFunc int epicsShareAPI epicsRingPointerGetFree(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return(pvoidPointer->getFree()); -} - -epicsShareFunc int epicsShareAPI epicsRingPointerGetUsed(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return(pvoidPointer->getUsed()); -} - -epicsShareFunc int epicsShareAPI epicsRingPointerGetSize(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return(pvoidPointer->getSize()); -} - -epicsShareFunc int epicsShareAPI epicsRingPointerIsEmpty(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return((pvoidPointer->isEmpty()) ? 1 : 0); -} - -epicsShareFunc int epicsShareAPI epicsRingPointerIsFull(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return((pvoidPointer->isFull()) ? 1 : 0); -} diff --git a/src/libCom/ring/epicsRingPointer.h b/src/libCom/ring/epicsRingPointer.h deleted file mode 100644 index 48d62036d..000000000 --- a/src/libCom/ring/epicsRingPointer.h +++ /dev/null @@ -1,201 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Marty Kraimer Date: 15JUL99 - * Ralph Lange - */ - -#ifndef INCepicsRingPointerh -#define INCepicsRingPointerh - -/* NOTES - * If there is only one writer it is not necessary to lock push - * If there is a single reader it is not necessary to lock pop - * - * epicsRingPointerLocked uses a spinlock. - */ - -#include "epicsSpin.h" -#include "shareLib.h" - -#ifdef __cplusplus -template -class epicsRingPointer { -public: /* Functions */ - epicsRingPointer(int size, bool locked); - ~epicsRingPointer(); - bool push(T *p); - T* pop(); - void flush(); - int getFree() const; - int getUsed() const; - int getSize() const; - bool isEmpty() const; - bool isFull() const; - -private: /* Prevent compiler-generated member functions */ - /* default constructor, copy constructor, assignment operator */ - epicsRingPointer(); - epicsRingPointer(const epicsRingPointer &); - epicsRingPointer& operator=(const epicsRingPointer &); - -private: /* Data */ - epicsSpinId lock; - volatile int nextPush; - volatile int nextPop; - int size; - T * volatile * buffer; -}; - -extern "C" { -#endif /*__cplusplus */ - -typedef void *epicsRingPointerId; - -epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerCreate(int size); -/* Same, but secured by a spinlock */ -epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerLockedCreate(int size); -epicsShareFunc void epicsShareAPI epicsRingPointerDelete(epicsRingPointerId id); -/*ringPointerPush returns (0,1) if p (was not, was) put on ring*/ -epicsShareFunc int epicsShareAPI epicsRingPointerPush(epicsRingPointerId id,void *p); -/*ringPointerPop returns 0 if ring is empty*/ -epicsShareFunc void* epicsShareAPI epicsRingPointerPop(epicsRingPointerId id) ; -epicsShareFunc void epicsShareAPI epicsRingPointerFlush(epicsRingPointerId id); -epicsShareFunc int epicsShareAPI epicsRingPointerGetFree(epicsRingPointerId id); -epicsShareFunc int epicsShareAPI epicsRingPointerGetUsed(epicsRingPointerId id); -epicsShareFunc int epicsShareAPI epicsRingPointerGetSize(epicsRingPointerId id); -epicsShareFunc int epicsShareAPI epicsRingPointerIsEmpty(epicsRingPointerId id); -epicsShareFunc int epicsShareAPI epicsRingPointerIsFull(epicsRingPointerId id); - -/* This routine was incorrectly named in previous releases */ -#define epicsRingPointerSize epicsRingPointerGetSize - -#ifdef __cplusplus -} -#endif -/* END OF DECLARATIONS */ - -/* INLINE FUNCTIONS */ - -/* Algorithm note - * Space is allocated for one additional element. - * A put request is rejected if the it would cause nextPush to equal nextPop - * The algorithm does not require locking puts for a single writer - * or locking of gets for a single reader - */ -#ifdef __cplusplus - -template -inline epicsRingPointer::epicsRingPointer(int sz, bool locked) : - lock(0), nextPush(0), nextPop(0), size(sz+1), buffer(new T* [sz+1]) -{ - if (locked) - lock = epicsSpinCreate(); -} - -template -inline epicsRingPointer::~epicsRingPointer() -{ - if (lock) epicsSpinDestroy(lock); - delete [] buffer; -} - -template -inline bool epicsRingPointer::push(T *p) -{ - if (lock) epicsSpinLock(lock); - int next = nextPush; - int newNext = next + 1; - if(newNext>=size) newNext=0; - if (newNext == nextPop) { - if (lock) epicsSpinUnlock(lock); - return(false); - } - buffer[next] = p; - nextPush = newNext; - if (lock) epicsSpinUnlock(lock); - return(true); -} - -template -inline T* epicsRingPointer::pop() -{ - if (lock) epicsSpinLock(lock); - int next = nextPop; - if (next == nextPush) { - if (lock) epicsSpinUnlock(lock); - return(0); - } - T*p = buffer[next]; - ++next; - if(next >=size) next = 0; - nextPop = next; - if (lock) epicsSpinUnlock(lock); - return(p); -} - -template -inline void epicsRingPointer::flush() -{ - if (lock) epicsSpinLock(lock); - nextPop = 0; - nextPush = 0; - if (lock) epicsSpinUnlock(lock); -} - -template -inline int epicsRingPointer::getFree() const -{ - if (lock) epicsSpinLock(lock); - int n = nextPop - nextPush - 1; - if (n < 0) n += size; - if (lock) epicsSpinUnlock(lock); - return n; -} - -template -inline int epicsRingPointer::getUsed() const -{ - if (lock) epicsSpinLock(lock); - int n = nextPush - nextPop; - if (n < 0) n += size; - if (lock) epicsSpinUnlock(lock); - return n; -} - -template -inline int epicsRingPointer::getSize() const -{ - return(size-1); -} - -template -inline bool epicsRingPointer::isEmpty() const -{ - bool isEmpty; - if (lock) epicsSpinLock(lock); - isEmpty = (nextPush == nextPop); - if (lock) epicsSpinUnlock(lock); - return isEmpty; -} - -template -inline bool epicsRingPointer::isFull() const -{ - if (lock) epicsSpinLock(lock); - int count = nextPush - nextPop +1; - if (lock) epicsSpinUnlock(lock); - return((count == 0) || (count == size)); -} - -#endif /* __cplusplus */ - -#endif /* INCepicsRingPointerh */ diff --git a/src/libCom/taskwd/Makefile b/src/libCom/taskwd/Makefile deleted file mode 100644 index af738f0d6..000000000 --- a/src/libCom/taskwd/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/taskwd -INC += taskwd.h -Com_SRCS += taskwd.c diff --git a/src/libCom/taskwd/taskwd.c b/src/libCom/taskwd/taskwd.c deleted file mode 100644 index 44ddc779c..000000000 --- a/src/libCom/taskwd/taskwd.c +++ /dev/null @@ -1,430 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* taskwd.c */ - -/* tasks and subroutines for a general purpose task watchdog */ -/* - * Original Author: Marty Kraimer - * Date: 07-18-91 -*/ - -#include -#include - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "dbDefs.h" -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsStdioRedirect.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "valgrind/valgrind.h" -#include "errlog.h" -#include "ellLib.h" -#include "errMdef.h" -#include "taskwd.h" - -struct tNode { - ELLNODE node; - epicsThreadId tid; - TASKWDFUNC callback; - void *usr; - int suspended; -}; - -struct mNode { - ELLNODE node; - const taskwdMonitor *funcs; - void *usr; -}; - -struct aNode { - void *key; - TASKWDANYFUNC callback; - void *usr; -}; - -union twdNode { - struct tNode t; - struct mNode m; - struct aNode a; -}; - -/* Registered Tasks */ -static epicsMutexId tLock; -static ELLLIST tList = ELLLIST_INIT; - -/* Active Monitors */ -static epicsMutexId mLock; -static ELLLIST mList = ELLLIST_INIT; - -/* Free List */ -static epicsMutexId fLock; -static ELLLIST fList = ELLLIST_INIT; - -/* Watchdog task control */ -static volatile enum { - twdctlInit, twdctlRun, twdctlDisable, twdctlExit -} twdCtl; -static epicsEventId loopEvent; -static epicsEventId exitEvent; - -/* Task delay times (seconds) */ -#define TASKWD_DELAY 6.0 - - -/* forward definitions */ -static union twdNode *allocNode(void); -static void freeNode(union twdNode *); - -/* Initialization, lazy */ - -static void twdTask(void *arg) -{ - struct tNode *pt; - struct mNode *pm; - - while (twdCtl != twdctlExit) { - if (twdCtl == twdctlRun) { - epicsMutexMustLock(tLock); - pt = (struct tNode *)ellFirst(&tList); - while (pt) { - int susp = epicsThreadIsSuspended(pt->tid); - if (susp != pt->suspended) { - epicsMutexMustLock(mLock); - pm = (struct mNode *)ellFirst(&mList); - while (pm) { - if (pm->funcs->notify) { - pm->funcs->notify(pm->usr, pt->tid, susp); - } - pm = (struct mNode *)ellNext(&pm->node); - } - epicsMutexUnlock(mLock); - - if (susp) { - char tName[40]; - epicsThreadGetName(pt->tid, tName, sizeof(tName)); - errlogPrintf("Thread %s (%p) suspended\n", - tName, (void *)pt->tid); - if (pt->callback) { - pt->callback(pt->usr); - } - } - pt->suspended = susp; - } - pt = (struct tNode *)ellNext(&pt->node); - } - epicsMutexUnlock(tLock); - } - epicsEventWaitWithTimeout(loopEvent, TASKWD_DELAY); - } - epicsEventSignal(exitEvent); -} - - -static void twdShutdown(void *arg) -{ - ELLNODE *cur; - twdCtl = twdctlExit; - epicsEventSignal(loopEvent); - epicsEventWait(exitEvent); - while ((cur = ellGet(&fList)) != NULL) { - VALGRIND_MEMPOOL_FREE(&fList, cur); - free(cur); - } - VALGRIND_DESTROY_MEMPOOL(&fList); -} - -static void twdInitOnce(void *arg) -{ - epicsThreadId tid; - - tLock = epicsMutexMustCreate(); - mLock = epicsMutexMustCreate(); - fLock = epicsMutexMustCreate(); - ellInit(&fList); - VALGRIND_CREATE_MEMPOOL(&fList, 0, 0); - - twdCtl = twdctlRun; - loopEvent = epicsEventMustCreate(epicsEventEmpty); - exitEvent = epicsEventMustCreate(epicsEventEmpty); - - tid = epicsThreadCreate("taskwd", epicsThreadPriorityLow, - epicsThreadGetStackSize(epicsThreadStackSmall), - twdTask, NULL); - if (tid == 0) - cantProceed("Failed to spawn task watchdog thread\n"); - - epicsAtExit(twdShutdown, NULL); -} - -void taskwdInit(void) -{ - static epicsThreadOnceId twdOnceFlag = EPICS_THREAD_ONCE_INIT; - epicsThreadOnce(&twdOnceFlag, twdInitOnce, NULL); -} - - -/* For tasks to be monitored */ - -void taskwdInsert(epicsThreadId tid, TASKWDFUNC callback, void *usr) -{ - struct tNode *pt; - struct mNode *pm; - - taskwdInit(); - if (tid == 0) - tid = epicsThreadGetIdSelf(); - - pt = &allocNode()->t; - pt->tid = tid; - pt->callback = callback; - pt->usr = usr; - pt->suspended = FALSE; - - epicsMutexMustLock(mLock); - pm = (struct mNode *)ellFirst(&mList); - while (pm) { - if (pm->funcs->insert) { - pm->funcs->insert(pm->usr, tid); - } - pm = (struct mNode *)ellNext(&pm->node); - } - epicsMutexUnlock(mLock); - - epicsMutexMustLock(tLock); - ellAdd(&tList, (void *)pt); - epicsMutexUnlock(tLock); -} - -void taskwdRemove(epicsThreadId tid) -{ - struct tNode *pt; - struct mNode *pm; - char tName[40]; - - taskwdInit(); - - if (tid == 0) - tid = epicsThreadGetIdSelf(); - - epicsMutexMustLock(tLock); - pt = (struct tNode *)ellFirst(&tList); - while (pt != NULL) { - if (tid == pt->tid) { - ellDelete(&tList, (void *)pt); - epicsMutexUnlock(tLock); - freeNode((union twdNode *)pt); - - epicsMutexMustLock(mLock); - pm = (struct mNode *)ellFirst(&mList); - while (pm) { - if (pm->funcs->remove) { - pm->funcs->remove(pm->usr, tid); - } - pm = (struct mNode *)ellNext(&pm->node); - } - epicsMutexUnlock(mLock); - return; - } - pt = (struct tNode *)ellNext(&pt->node); - } - epicsMutexUnlock(tLock); - - epicsThreadGetName(tid, tName, sizeof(tName)); - errlogPrintf("taskwdRemove: Thread %s (%p) not registered!\n", - tName, (void *)tid); -} - - -/* Monitoring API */ - -void taskwdMonitorAdd(const taskwdMonitor *funcs, void *usr) -{ - struct mNode *pm; - - if (funcs == NULL) return; - - taskwdInit(); - - pm = &allocNode()->m; - pm->funcs = funcs; - pm->usr = usr; - - epicsMutexMustLock(mLock); - ellAdd(&mList, (void *)pm); - epicsMutexUnlock(mLock); -} - -void taskwdMonitorDel(const taskwdMonitor *funcs, void *usr) -{ - struct mNode *pm; - - if (funcs == NULL) return; - - taskwdInit(); - - epicsMutexMustLock(mLock); - pm = (struct mNode *)ellFirst(&mList); - while (pm) { - if (pm->funcs == funcs && pm->usr == usr) { - ellDelete(&mList, (void *)pm); - freeNode((union twdNode *)pm); - epicsMutexUnlock(mLock); - return; - } - pm = (struct mNode *)ellNext(&pm->node); - } - epicsMutexUnlock(mLock); - - errlogPrintf("taskwdMonitorDel: Unregistered!\n"); -} - - -/* Support old API for backwards compatibility */ - -static void anyNotify(void *usr, epicsThreadId tid, int suspended) -{ - struct aNode *pa = (struct aNode *)usr; - - if (suspended) { - pa->callback(pa->usr, tid); - } -} - -static taskwdMonitor anyFuncs = { - NULL, anyNotify, NULL -}; - -void taskwdAnyInsert(void *key, TASKWDANYFUNC callback, void *usr) -{ - struct mNode *pm; - struct aNode *pa; - - if (callback == NULL) return; - - taskwdInit(); - - pa = &allocNode()->a; - pa->key = key; - pa->callback = callback; - pa->usr = usr; - - pm = &allocNode()->m; - pm->funcs = &anyFuncs; - pm->usr = pa; - - epicsMutexMustLock(mLock); - ellAdd(&mList, (void *)pm); - epicsMutexUnlock(mLock); -} - -void taskwdAnyRemove(void *key) -{ - struct mNode *pm; - struct aNode *pa; - - taskwdInit(); - - epicsMutexMustLock(mLock); - pm = (struct mNode *)ellFirst(&mList); - while (pm) { - if (pm->funcs == &anyFuncs) { - pa = (struct aNode *)pm->usr; - if (pa->key == key) { - ellDelete(&mList, (void *)pm); - freeNode((union twdNode *)pa); - freeNode((union twdNode *)pm); - epicsMutexUnlock(mLock); - return; - } - } - pm = (struct mNode *)ellNext(&pm->node); - } - epicsMutexUnlock(mLock); - - errlogPrintf("taskwdAnyRemove: Unregistered key %p\n", key); -} - - -/* Report function */ - -epicsShareFunc void taskwdShow(int level) -{ - struct tNode *pt; - int mCount, fCount, tCount; - char tName[40]; - - epicsMutexMustLock(mLock); - mCount = ellCount(&mList); - epicsMutexUnlock(mLock); - - epicsMutexMustLock(fLock); - fCount = ellCount(&fList); - epicsMutexUnlock(fLock); - - epicsMutexMustLock(tLock); - tCount = ellCount(&tList); - printf("%d monitors, %d threads registered, %d free nodes\n", - mCount, tCount, fCount); - if (level) { - printf("%16.16s %9s %12s %12s %12s\n", - "THREAD NAME", "STATE", "EPICS TID", "CALLBACK", "USR ARG"); - pt = (struct tNode *)ellFirst(&tList); - while (pt != NULL) { - epicsThreadGetName(pt->tid, tName, sizeof(tName)); - printf("%16.16s %9s %12p %12p %12p\n", - tName, pt->suspended ? "Suspended" : "Ok ", - (void *)pt->tid, (void *)pt->callback, pt->usr); - pt = (struct tNode *)ellNext(&pt->node); - } - } - epicsMutexUnlock(tLock); -} - - -/* Free list management */ - -static union twdNode *newNode(void) -{ - union twdNode *pn; - - epicsMutexMustLock(fLock); - pn = (union twdNode *)ellGet(&fList); - if (pn) { - VALGRIND_MEMPOOL_FREE(&fList, pn); - } - epicsMutexUnlock(fLock); - if (!pn) - pn = calloc(1, sizeof(union twdNode)); - if (pn) - VALGRIND_MEMPOOL_ALLOC(&fList, pn, sizeof(*pn)); - return pn; -} - -static union twdNode *allocNode(void) -{ - union twdNode *pn = newNode(); - while (!pn) { - errlogPrintf("Thread taskwd suspending: out of memory\n"); - epicsThreadSuspendSelf(); - pn = newNode(); - } - return pn; -} - -static void freeNode(union twdNode *pn) -{ - VALGRIND_MEMPOOL_FREE(&fList, pn); - VALGRIND_MEMPOOL_ALLOC(&fList, pn, sizeof(ELLNODE)); - epicsMutexMustLock(fLock); - ellAdd(&fList, (void *)pn); - epicsMutexUnlock(fLock); -} diff --git a/src/libCom/taskwd/taskwd.h b/src/libCom/taskwd/taskwd.h deleted file mode 100644 index 4d5274d56..000000000 --- a/src/libCom/taskwd/taskwd.h +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* General purpose task watchdog */ -/* - * Original Author: Marty Kraimer - * Date: 07-18-91 -*/ - -#ifndef INC_taskwd_H -#define INC_taskwd_H - -#include "epicsThread.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Initialization, optional */ -epicsShareFunc void taskwdInit(void); - - -/* For tasks to be monitored */ -typedef void (*TASKWDFUNC)(void *usr); - -epicsShareFunc void taskwdInsert(epicsThreadId tid, - TASKWDFUNC callback, void *usr); -epicsShareFunc void taskwdRemove(epicsThreadId tid); - - -/* Monitoring API */ -typedef struct { - void (*insert)(void *usr, epicsThreadId tid); - void (*notify)(void *usr, epicsThreadId tid, int suspended); - void (*remove)(void *usr, epicsThreadId tid); -} taskwdMonitor; - -epicsShareFunc void taskwdMonitorAdd(const taskwdMonitor *funcs, void *usr); -epicsShareFunc void taskwdMonitorDel(const taskwdMonitor *funcs, void *usr); - - -/* Old monitoring API, deprecated */ -typedef void (*TASKWDANYFUNC)(void *usr, epicsThreadId tid); - -epicsShareFunc void taskwdAnyInsert(void *key, - TASKWDANYFUNC callback, void *usr); -epicsShareFunc void taskwdAnyRemove(void *key); - - -/* Report function */ -epicsShareFunc void taskwdShow(int level); - - -#ifdef __cplusplus -} -#endif - -#endif /* INC_taskwd_H */ diff --git a/src/libCom/test/Makefile b/src/libCom/test/Makefile deleted file mode 100755 index 04438854c..000000000 --- a/src/libCom/test/Makefile +++ /dev/null @@ -1,262 +0,0 @@ -#************************************************************************* -# Copyright (c) 2006 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../../.. - -include $(TOP)/configure/CONFIG - -PROD_LIBS += Com -PROD_SYS_LIBS_WIN32 += ws2_32 advapi32 user32 - -TESTPROD_HOST += epicsUnitTestTest -epicsUnitTestTest_SRCS += epicsUnitTestTest.c -# Not much point running this on vxWorks or RTEMS... -TESTS += epicsUnitTestTest - -TESTPROD_HOST += epicsTypesTest -epicsTypesTest_SRCS += epicsTypesTest.cpp -testHarness_SRCS += epicsTypesTest.cpp -TESTS += epicsTypesTest - -TESTPROD_HOST += epicsInlineTest -epicsInlineTest_SRCS += epicsInlineTest1.c -epicsInlineTest_SRCS += epicsInlineTest2.c -epicsInlineTest_SRCS += epicsInlineTest3.cpp -epicsInlineTest_SRCS += epicsInlineTest4.cpp -testHarness_SRCS += $(epicsInlineTest_SRCS) -TESTS += epicsInlineTest - -TESTPROD_HOST += epicsCalcTest -epicsCalcTest_SRCS += epicsCalcTest.cpp -testHarness_SRCS += epicsCalcTest.cpp -TESTS += epicsCalcTest - -TESTPROD_HOST += epicsAlgorithmTest -epicsAlgorithmTest_SRCS += epicsAlgorithmTest.cpp -testHarness_SRCS += epicsAlgorithmTest.cpp -TESTS += epicsAlgorithmTest - -TESTPROD_HOST += epicsMathTest -epicsMathTest_SRCS += epicsMathTest.c -testHarness_SRCS += epicsMathTest.c -TESTS += epicsMathTest - -TESTPROD_HOST += epicsMMIOTest -epicsMMIOTest_SRCS += epicsMMIOTest.c -epicsMMIOTest_SYS_LIBS_solaris = socket -epicsMMIOTest_SYS_LIBS_WIN32 = ws2_32 user32 -testHarness_SRCS += epicsMMIOTest.c -TESTS += epicsMMIOTest - -TESTPROD_HOST += epicsEllTest -epicsEllTest_SRCS += epicsEllTest.c -testHarness_SRCS += epicsEllTest.c -TESTS += epicsEllTest - -TESTPROD_HOST += epicsEnvTest -epicsEnvTest_SRCS += epicsEnvTest.c -testHarness_SRCS += epicsEnvTest.c -TESTS += epicsEnvTest - -TESTPROD_HOST += epicsErrlogTest -epicsErrlogTest_SRCS += epicsErrlogTest.c -epicsErrlogTest_SYS_LIBS_solaris = socket -epicsErrlogTest_SYS_LIBS_WIN32 = ws2_32 user32 -testHarness_SRCS += epicsErrlogTest.c -TESTS += epicsErrlogTest - -TESTPROD_HOST += epicsStdioTest -epicsStdioTest_SRCS += epicsStdioTest.c -testHarness_SRCS += epicsStdioTest.c -TESTS += epicsStdioTest - -TESTPROD_HOST += epicsStdlibTest -epicsStdlibTest_SRCS += epicsStdlibTest.c -testHarness_SRCS += epicsStdlibTest.c -TESTS += epicsStdlibTest - -TESTPROD_HOST += epicsSockResolveTest -epicsSockResolveTest_SRCS += epicsSockResolveTest.c -epicsSockResolveTest_SYS_LIBS_solaris = socket -epicsSockResolveTest_SYS_LIBS_WIN32 = ws2_32 user32 -testHarness_SRCS += epicsSockResolveTest.c -TESTS += epicsSockResolveTest - -TESTPROD_HOST += epicsStringTest -epicsStringTest_SRCS += epicsStringTest.c -testHarness_SRCS += epicsStringTest.c -TESTS += epicsStringTest - -TESTPROD_HOST += epicsTimeTest -epicsTimeTest_SRCS += epicsTimeTest.cpp -testHarness_SRCS += epicsTimeTest.cpp -TESTS += epicsTimeTest - -TESTPROD_HOST += epicsTimeZoneTest -epicsTimeZoneTest_SRCS += epicsTimeZoneTest.c -libComTestHarness_SRCS_RTEMS += epicsTimeZoneTest.c -TESTS += epicsTimeZoneTest - -TESTPROD_HOST += epicsThreadTest -epicsThreadTest_SRCS += epicsThreadTest.cpp -testHarness_SRCS += epicsThreadTest.cpp -TESTS += epicsThreadTest - -TESTPROD_HOST += epicsThreadOnceTest -epicsThreadOnceTest_SRCS += epicsThreadOnceTest.c -testHarness_SRCS += epicsThreadOnceTest.c -TESTS += epicsThreadOnceTest - -TESTPROD_HOST += epicsThreadPriorityTest -epicsThreadPriorityTest_SRCS += epicsThreadPriorityTest.cpp -testHarness_SRCS += epicsThreadPriorityTest.cpp -TESTS += epicsThreadPriorityTest - -TESTPROD_HOST += epicsThreadPrivateTest -epicsThreadPrivateTest_SRCS += epicsThreadPrivateTest.cpp -testHarness_SRCS += epicsThreadPrivateTest.cpp -TESTS += epicsThreadPrivateTest - -TESTPROD_HOST += epicsThreadHooksTest -epicsThreadHooksTest_SRCS += epicsThreadHooksTest.c -testHarness_SRCS += epicsThreadHooksTest.c -TESTS += epicsThreadHooksTest - -TESTPROD_HOST += epicsThreadPoolTest -epicsThreadPoolTest_SRCS += epicsThreadPoolTest.c -testHarness_SRCS += epicsThreadPoolTest.c -TESTS += epicsThreadPoolTest - -TESTPROD_HOST += epicsExitTest -epicsExitTest_SRCS += epicsExitTest.c -testHarness_SRCS += epicsExitTest.c -TESTS += epicsExitTest - -TESTPROD_HOST += epicsTimerTest -epicsTimerTest_SRCS += epicsTimerTest.cpp -testHarness_SRCS += epicsTimerTest.cpp -TESTS += epicsTimerTest - -TESTPROD_HOST += ringPointerTest -ringPointerTest_SRCS += ringPointerTest.c -testHarness_SRCS += ringPointerTest.c -TESTS += ringPointerTest - -TESTPROD_HOST += ringBytesTest -ringBytesTest_SRCS += ringBytesTest.c -testHarness_SRCS += ringBytesTest.c -TESTS += ringBytesTest - -TESTPROD_HOST += epicsEventTest -epicsEventTest_SRCS += epicsEventTest.cpp -testHarness_SRCS += epicsEventTest.cpp -TESTS += epicsEventTest - -TESTPROD_HOST += epicsMutexTest -epicsMutexTest_SRCS += epicsMutexTest.cpp -testHarness_SRCS += epicsMutexTest.cpp -TESTS += epicsMutexTest - -TESTPROD_HOST += epicsSpinTest -epicsSpinTest_SRCS += epicsSpinTest.c -testHarness_SRCS += epicsSpinTest.c -TESTS += epicsSpinTest - -TESTPROD_HOST += epicsAtomicTest -epicsAtomicTest_SRCS += epicsAtomicTest.cpp -testHarness_SRCS += epicsAtomicTest.cpp -TESTS += epicsAtomicTest - -TESTPROD_HOST += macDefExpandTest -macDefExpandTest_SRCS += macDefExpandTest.c -testHarness_SRCS += macDefExpandTest.c -TESTS += macDefExpandTest - -TESTPROD_HOST += cvtFastTest -cvtFastTest_SRCS += cvtFastTest.cpp -testHarness_SRCS += cvtFastTest.cpp -TESTS += cvtFastTest - -TESTPROD_HOST += macLibTest -macLibTest_SRCS += macLibTest.c -testHarness_SRCS += macLibTest.c -TESTS += macLibTest - -TESTPROD_HOST += taskwdTest -taskwdTest_SRCS += taskwdTest.c -testHarness_SRCS += taskwdTest.c -TESTS += taskwdTest - -TESTPROD_HOST += blockingSockTest -blockingSockTest_SRCS += blockingSockTest.cpp -testHarness_SRCS += blockingSockTest.cpp -# needed when its an object library build -blockingSockTest_SYS_LIBS_WIN32 = ws2_32 advapi32 user32 -blockingSockTest_SYS_LIBS_solaris = socket -TESTS += blockingSockTest - -TESTPROD_HOST += epicsMessageQueueTest -epicsMessageQueueTest_SRCS += epicsMessageQueueTest.cpp -testHarness_SRCS += epicsMessageQueueTest.cpp -TESTS += epicsMessageQueueTest - -TESTPROD_HOST += epicsStackTraceTest -epicsStackTraceTest_SRCS += epicsStackTraceTest.c -testHarness_SRCS += epicsStackTraceTest.c -TESTS += epicsStackTraceTest - -TESTPROD_HOST += ipAddrToAsciiTest -ipAddrToAsciiTest_SRCS += ipAddrToAsciiTest.cpp -testHarness_SRCS += ipAddrToAsciiTest.cpp -TESTS += ipAddrToAsciiTest - -# The testHarness runs all the test programs in a known working order. -testHarness_SRCS += epicsRunLibComTests.c - -libComTestHarness_SRCS += $(testHarness_SRCS) -libComTestHarness_SRCS_RTEMS += rtemsTestHarness.c - -PROD_vxWorks = libComTestHarness -PROD_RTEMS += libComTestHarness - -TESTSPEC_vxWorks = libComTestHarness.munch; epicsRunLibComTests -TESTSPEC_RTEMS = libComTestHarness.boot; epicsRunLibComTests - -TESTSCRIPTS_HOST += $(TESTS:%=%.t) - - -# The following are not test programs, they measure performance. -# They should not be added to TESTS or to epicsRunLibComTests.c - -TESTPROD_HOST += epicsThreadPerform -epicsThreadPerform_SRCS += epicsThreadPerform.cpp -testHarness_SRCS += epicsThreadPerform.cpp - -TESTPROD_HOST += epicsMaxThreads -epicsMaxThreads_SRCS += epicsMaxThreads.c -testHarness_SRCS += epicsMaxThreads.c - -TESTPROD_HOST += buckTest -buckTest_SRCS += buckTest.c -testHarness_SRCS += buckTest.c - -#TESTPROD_HOST += fdmgrTest -fdmgrTest_SRCS += fdmgrTest.c -fdmgrTest_LIBS += ca -# FIXME: program never exits. - -TESTPROD_HOST += epicsAtomicPerform -epicsAtomicPerform_SRCS += epicsAtomicPerform.cpp -testHarness_SRCS += epicsAtomicPerform.cpp - -TESTPROD_HOST += cvtFastPerform -cvtFastPerform_SRCS += cvtFastPerform.cpp -testHarness_SRCS += cvtFastPerform.cpp - -include $(TOP)/configure/RULES - diff --git a/src/libCom/test/blockingSockTest.cpp b/src/libCom/test/blockingSockTest.cpp deleted file mode 100644 index 1a16bb9e6..000000000 --- a/src/libCom/test/blockingSockTest.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "osiSock.h" -#include "osiWireFormat.h" -#include "epicsThread.h" -#include "epicsSignal.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -union address { - struct sockaddr_in ia; - struct sockaddr sa; -}; - -class circuit { -public: - circuit ( SOCKET ); - void recvTest (); - void shutdown (); - void close (); - bool recvWakeupDetected () const; - bool sendWakeupDetected () const; - virtual const char * pName () = 0; -protected: - SOCKET sock; - epicsThreadId id; - bool recvWakeup; - bool sendWakeup; -protected: - virtual ~circuit() {} -}; - -class serverCircuit : public circuit { -public: - serverCircuit ( SOCKET ); -private: - const char * pName (); -}; - -class clientCircuit : public circuit { -public: - clientCircuit ( const address & ); -private: - const char * pName (); -}; - -class server { -public: - server ( const address & ); - void start (); - void daemon (); - void stop (); - address addr () const; -protected: - address srvaddr; - SOCKET sock; - epicsThreadId id; - bool exit; -}; - -circuit::circuit ( SOCKET sockIn ) : - sock ( sockIn ), - id ( 0 ), - recvWakeup ( false ), - sendWakeup ( false ) -{ - testOk ( this->sock != INVALID_SOCKET, "Socket valid" ); -} - -bool circuit::recvWakeupDetected () const -{ - return this->recvWakeup; -} - -bool circuit::sendWakeupDetected () const -{ - return this->sendWakeup; -} - -void circuit::shutdown () -{ - int status = ::shutdown ( this->sock, SHUT_RDWR ); - testOk ( status == 0, "Shutdown() returned Ok" ); -} - -void circuit::close () -{ - epicsSocketDestroy ( this->sock ); -} - -void circuit::recvTest () -{ - char buf [1]; - while ( true ) { - int status = recv ( this->sock, - buf, (int) sizeof ( buf ), 0 ); - if ( status == 0 ) { - testDiag ( "%s was disconnected", this->pName () ); - this->recvWakeup = true; - break; - } - else if ( status > 0 ) { - testDiag ( "%s received %i characters", this->pName (), status ); - } - else { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - testDiag ( "%s socket recv() error was \"%s\"", - this->pName (), sockErrBuf ); - this->recvWakeup = true; - break; - } - } -} - -extern "C" void socketRecvTest ( void * pParm ) -{ - circuit * pCir = reinterpret_cast < circuit * > ( pParm ); - pCir->recvTest (); -} - -clientCircuit::clientCircuit ( const address & addrIn ) : - circuit ( epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) -{ - address tmpAddr = addrIn; - int status = ::connect ( - this->sock, & tmpAddr.sa, sizeof ( tmpAddr ) ); - testOk ( status == 0, "Client end connected" ); - - circuit * pCir = this; - this->id = epicsThreadCreate ( - "client circuit", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), - socketRecvTest, pCir ); - testOk ( this->id != 0, "Client thread created" ); -} - - -const char * clientCircuit::pName () -{ - return "client circuit"; -} - -extern "C" void serverDaemon ( void * pParam ) { - server * pSrv = reinterpret_cast < server * > ( pParam ); - pSrv->daemon (); -} - -server::server ( const address & addrIn ) : - srvaddr ( addrIn ), - sock ( epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ), - id ( 0 ), exit ( false ) -{ - testOk ( this->sock != INVALID_SOCKET, "Server socket valid" ); - - // setup server side - osiSocklen_t slen = sizeof ( this->srvaddr ); - int status = bind ( this->sock, & this->srvaddr.sa, slen ); - if ( status ) { - testDiag ( "bind to server socket failed, status = %d", status ); - } - if ( getsockname(this->sock, & this->srvaddr.sa, & slen) != 0 ) { - testAbort ( "Failed to read socket address" ); - } - status = listen ( this->sock, 10 ); - testOk ( status == 0, "Server socket listening" ); -} - -void server::start () -{ - this->id = epicsThreadCreate ( - "server daemon", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), - serverDaemon, this ); - testOk ( this->id != 0, "Server thread created" ); -} - -void server::daemon () -{ - while ( ! this->exit ) { - // accept client side - address addr; - osiSocklen_t addressSize = sizeof ( addr ); - SOCKET ns = accept ( this->sock, - & addr.sa, & addressSize ); - if ( this->exit ) - break; - testOk ( ns != INVALID_SOCKET, "Accepted socket valid" ); - circuit * pCir = new serverCircuit ( ns ); - testOk ( pCir != 0, "Server circuit created" ); - } -} - -void server::stop () -{ - this->exit = true; - epicsSocketDestroy ( this->sock ); -} - -address server::addr () const -{ - return this->srvaddr; -} - -serverCircuit::serverCircuit ( SOCKET sockIn ) : - circuit ( sockIn ) -{ - circuit * pCir = this; - epicsThreadId threadId = epicsThreadCreate ( - "server circuit", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), - socketRecvTest, pCir ); - testOk ( threadId != 0, "Server circuit thread created" ); -} - -const char * serverCircuit::pName () -{ - return "server circuit"; -} - -static const char *mechName(int mech) -{ - static const struct { - int mech; - const char *name; - } mechs[] = { - {-1, "Unknown shutdown mechanism" }, - {esscimqi_socketCloseRequired, "esscimqi_socketCloseRequired" }, - {esscimqi_socketBothShutdownRequired, "esscimqi_socketBothShutdownRequired" }, - {esscimqi_socketSigAlarmRequired, "esscimqi_socketSigAlarmRequired" } - }; - - for (unsigned i=0; i < (sizeof(mechs) / sizeof(mechs[0])); ++i) { - if (mech == mechs[i].mech) - return mechs[i].name; - } - return "Unknown shutdown mechanism value"; -} - -MAIN(blockingSockTest) -{ - testPlan(13); - osiSockAttach(); - - address addr; - memset ( (char *) & addr, 0, sizeof ( addr ) ); - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK ); - addr.ia.sin_port = 0; - - server srv ( addr ); - srv.start (); - addr = srv.addr (); - clientCircuit client ( addr ); - - epicsThreadSleep ( 1.0 ); - testOk ( ! client.recvWakeupDetected (), "Client is asleep" ); - - testDiag("Trying Shutdown mechanism"); - client.shutdown (); - epicsThreadSleep ( 1.0 ); - int mech = -1; - if ( client.recvWakeupDetected () ) { - mech = esscimqi_socketBothShutdownRequired; - testDiag("Shutdown succeeded"); - } - else { - testDiag("Trying Close mechanism"); - client.close (); - epicsThreadSleep ( 1.0 ); - if ( client.recvWakeupDetected () ) { - mech = esscimqi_socketCloseRequired; - testDiag("Close succeeded"); - } - } - testDiag("This OS behaves like \"%s\".", mechName(mech)); - - int query = epicsSocketSystemCallInterruptMechanismQuery (); - if (! testOk(mech == query, "Declared mechanism works") ) - testDiag("epicsSocketSystemCallInterruptMechanismQuery returned \"%s\"", - mechName(query)); - - srv.stop (); - epicsThreadSleep ( 1.0 ); - - osiSockRelease(); - return testDone(); -} - diff --git a/src/libCom/test/buckTest.c b/src/libCom/test/buckTest.c deleted file mode 100644 index 6fc34954e..000000000 --- a/src/libCom/test/buckTest.c +++ /dev/null @@ -1,82 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#include "epicsTime.h" -#include "epicsAssert.h" -#include "bucketLib.h" -#include "testMain.h" - -#define verify(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -MAIN(buckTest) -{ - unsigned id1; - unsigned id2; - char * pValSave1; - char * pValSave2; - int s; - BUCKET * pb; - char * pVal; - unsigned i; - epicsTimeStamp start, finish; - double duration; - const int LOOPS = 500000; - - pb = bucketCreate(8); - if (!pb) { - return -1; - } - - id1 = 0x1000a432; - pValSave1 = "fred"; - s = bucketAddItemUnsignedId(pb, &id1, pValSave1); - verify (s == S_bucket_success); - - pValSave2 = "jane"; - id2 = 0x0000a432; - s = bucketAddItemUnsignedId(pb, &id2, pValSave2); - verify (s == S_bucket_success); - - epicsTimeGetCurrent(&start); - for (i=0; i -#include -#include -#include -#include -#include -#include - -#include "epicsStdio.h" -#include "cvtFast.h" -#include "epicsTime.h" -#include "testMain.h" - -using namespace std; - -class PerfConverter { -public: - virtual const char * name(void) const = 0; - virtual int maxPrecision(void) const = 0; - virtual void target (double srcD, float srcF, char *dst, size_t len, int prec) const = 0; - virtual void add(int prec, double elapsed) = 0; - virtual double total(int prec) = 0; - virtual ~PerfConverter () {}; -}; - -class Perf { -public: - Perf ( int maxConverters ); - virtual ~Perf (); - void addConverter( PerfConverter * c ); - void execute (int count, bool verbose); - void report (const char *title, int count); -protected: - static unsigned const nUnrolled = 10; - static const unsigned uSecPerSec = 1000000; - static unsigned const nIterations = 10000; - - const int maxConverters; - PerfConverter **converters; - int nConverters; - int maxPrecision; - bool verbose; - - void measure ( double srcD, float srcF, int prec ); - -private: - Perf ( const Perf & ); - Perf & operator = ( Perf & ); -}; - -Perf :: Perf ( int maxConverters_ ) : - maxConverters ( maxConverters_ ), - converters ( new PerfConverter * [ maxConverters_ ] ), - nConverters ( 0 ), - maxPrecision ( 0 ) -{ -} - -Perf :: ~Perf () -{ - for ( int j = 0; j < nConverters; j++ ) - delete converters[ j ]; - - delete [] converters; -} - -void Perf :: addConverter(PerfConverter *c) -{ - if ( nConverters >= maxConverters ) - throw std :: runtime_error ( "Too many converters" ); - - converters[ nConverters++ ] = c; - - int prec = c->maxPrecision(); - if ( prec > maxPrecision ) - maxPrecision = prec; -} - -void Perf :: execute (const int count, bool verbose_) -{ - verbose = verbose_; - - for ( int i = 0; i < count; i++ ) { - double srcDbl = rand (); - srcDbl /= (RAND_MAX + 1.0); - srcDbl *= 20.0; - srcDbl -= 10.0; - float srcFlt = (float) srcDbl; - - for ( int prec = 0; prec <= maxPrecision; prec++ ) { - measure (srcFlt, srcDbl, prec); - } - } - report ( "Small numbers, -10..+10", count ); - - for ( int i = 0; i < count; i++ ) { - double mVal = rand (); - mVal /= (RAND_MAX + 1.0); - double eVal = rand (); - eVal /= (RAND_MAX + 1.0); - - double dVal = eVal; - dVal *= FLT_MAX_EXP - FLT_MIN_EXP; - dVal += FLT_MIN_EXP; - int dEVal = static_cast < int > ( dVal + 0.5 ); - double srcDbl = ldexp ( mVal, dEVal ); - float srcFlt = (float) srcDbl; - - for ( int prec = 0; prec <= maxPrecision; prec++ ) { - measure (srcFlt, srcDbl, prec); - } - } - report ( "Random mantissa+exponent", count ); -} - -void Perf :: report (const char *title, const int count) -{ - printf( "\n%s\n\nprec\t", title ); - for ( int j = 0; j < nConverters; j++ ) - printf( "%-16s ", converters[j]->name() ); - - for (int prec = 0; prec <= maxPrecision; prec++ ) { - printf( "\n %2d\t", prec ); - for (int j = 0; j < nConverters; j++ ) { - PerfConverter *c = converters[j]; - if (prec > c->maxPrecision()) - printf( "%11s ", "-" ); - else { - printf( "%11.9f sec ", c->total(prec) / count ); - } - } - } - printf( "\n\n" ); -} - -void Perf :: measure (double srcD, float srcF, int prec) -{ - char buf[40]; - - for ( int j = 0; j < nConverters; j++ ) { - PerfConverter *c = converters[j]; - - if (prec > c->maxPrecision()) - continue; - - std::memset(buf, 0, sizeof(buf)); - - epicsTime beg = epicsTime :: getCurrent (); - for ( unsigned i = 0; i < nIterations; i++ ) { - c->target (srcD, srcF, buf, sizeof(buf) - 1, prec); - } - epicsTime end = epicsTime :: getCurrent (); - - double elapsed = end - beg; - elapsed /= nIterations * nUnrolled; - c->add( prec, elapsed ); - - if (verbose) - printf ( "%17s: %11.9f sec, prec=%2i '%s'\n", - c->name (), elapsed, prec, buf ); - } -} - - -// Conversions to be measured - -class PerfCvtFastFloat : public PerfConverter { - static const int digits = 12; -public: - PerfCvtFastFloat () - { - for (int i = 0; i <= digits; i++) - measured[i] = 0; // Some targets seem to need this - } - int maxPrecision (void) const { return digits; } - const char *name (void) const { return "cvtFloatToString"; } - void target (double srcD, float srcF, char *dst, size_t len, int prec) const - { - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - } - void add (int prec, double elapsed) { measured[prec] += elapsed; } - double total (int prec) { - double total = measured[prec]; - measured[prec] = 0; - return total; - } -private: - double measured[digits+1]; -}; - - -class PerfCvtFastDouble : public PerfConverter { - static const int digits = 17; -public: - PerfCvtFastDouble () - { - for (int i = 0; i <= digits; i++) - measured[i] = 0; // Some targets seem to need this - } - int maxPrecision (void) const { return digits; } - const char *name (void) const { return "cvtDoubleToString"; } - void target (double srcD, float srcF, char *dst, size_t len, int prec) const - { - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - } - void add(int prec, double elapsed) { measured[prec] += elapsed; } - double total (int prec) { - double total = measured[prec]; - measured[prec] = 0; - return total; - } -private: - double measured[digits+1]; -}; - - -class PerfSNPrintf : public PerfConverter { - static const int digits = 17; -public: - PerfSNPrintf () - { - for (int i = 0; i <= digits; i++) - measured[i] = 0; // Some targets seem to need this - } - int maxPrecision (void) const { return digits; } - const char *name (void) const { return "epicsSnprintf"; } - void target (double srcD, float srcF, char *dst, size_t len, int prec) const - { - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - } - void add(int prec, double elapsed) { measured[prec] += elapsed; } - double total (int prec) { - double total = measured[prec]; - measured[prec] = 0; - return total; - } -private: - double measured[digits+1]; -}; - - -// This is a quick-and-dirty std::streambuf converter that writes directly -// into the output buffer. Performance is slower than epicsSnprintf(). - -struct membuf: public std::streambuf { - membuf(char *array, size_t size) { - this->setp(array, array + size - 1); - } -}; - -struct omemstream: virtual membuf, std::ostream { - omemstream(char *array, size_t size): - membuf(array, size), - std::ostream(this) { - } -}; - -static void ossConvertD(char *dst, size_t len, int prec, double src) { - omemstream oss(dst, len); - oss.precision(prec); - oss << src << ends; -} - -class PerfStreamBuf : public PerfConverter { - static const int digits = 17; -public: - PerfStreamBuf () - { - for (int i = 0; i <= digits; i++) - measured[i] = 0; // Some targets seem to need this - } - int maxPrecision (void) const { return digits; } - const char *name (void) const { return "std::streambuf"; } - void target (double srcD, float srcF, char *dst, size_t len, int prec) const - { - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - } - void add(int prec, double elapsed) { measured[prec] += elapsed; } - double total (int prec) { - double total = measured[prec]; - measured[prec] = 0; - return total; - } -private: - double measured[digits+1]; -}; - - -MAIN(cvtFastPerform) -{ - Perf t(4); - - t.addConverter( new PerfCvtFastFloat ); - t.addConverter( new PerfCvtFastDouble ); - t.addConverter( new PerfSNPrintf ); - t.addConverter( new PerfStreamBuf ); - - // The parameter to execute() below are: - // count = number of different random numbers to measure - // verbose = whether to display individual measurements - -#ifdef vxWorks - t.execute (3, true); // Slow... -#else - t.execute (5, false); -#endif - - return 0; -} diff --git a/src/libCom/test/cvtFastTest.c b/src/libCom/test/cvtFastTest.c deleted file mode 100644 index ac853ecc3..000000000 --- a/src/libCom/test/cvtFastTest.c +++ /dev/null @@ -1,459 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* cvtFastTest.c - * - * Test the string converters in libCom/cvtFast/cvtFast.c - * - * To Do: Test Char/Uchar/Short/Ushort/Long/Ulong versions - */ - -#include -#include -#include - -#include "epicsUnitTest.h" -#include "cvtFast.h" -#include "epicsStdlib.h" -#include "testMain.h" - -#define tryIString(typ, lit, siz) \ - len = cvt##typ##ToString(lit, buf); \ - testOk(len == siz, "cvt"#typ"ToString(" #lit ") == " #siz " (%u) -> \"%s\"", (unsigned)len, buf); \ - status = epicsParse##typ(buf, &val_##typ, 10, NULL); \ - testOk(!status, "epicsParse"#typ"('%s') OK", buf); \ - testOk(val_##typ == lit, #lit " => '%s'", buf); - -#define tryFString(typ, lit, prec, siz) \ - len = cvt##typ##ToString(lit, buf, prec); \ - testOk(len == siz, "cvt"#typ"ToString(" #lit ", %d) == " #siz " (%u) -> \"%s\"", prec, (unsigned)len, buf); \ - status = epicsParse##typ(buf, &val_##typ, NULL); \ - testOk(!status, "epicsParse"#typ"('%s') OK", buf); \ - testOk(fabs(val_##typ - lit) < 0.5 * pow(10, -prec), #lit " => '%s'", buf); - - -MAIN(cvtFastTest) -{ - char buf[80]; - size_t len; - long status; - epicsUInt32 val_UInt32; - epicsInt32 val_Int32; - epicsUInt64 val_UInt64; - epicsInt64 val_Int64; - epicsFloat32 val_Float; - epicsFloat64 val_Double; - -#ifdef _WIN32 -#if (defined(_MSC_VER) && _MSC_VER < 1900) || \ - (defined(_MINGW) && defined(_TWO_DIGIT_EXPONENT)) - _set_output_format(_TWO_DIGIT_EXPONENT); -#endif -#endif - - testPlan(1062); - - /* Arguments: type, value, num chars */ - testDiag("------------------------------------------------------"); - testDiag("** Positive Int32 **"); - tryIString(Int32, 0, 1); - tryIString(Int32, 1, 1); - tryIString(Int32, 10, 2); - tryIString(Int32, 100, 3); - tryIString(Int32, 254, 3); - tryIString(Int32, 255, 3); - tryIString(Int32, 256, 3); - tryIString(Int32, 257, 3); - tryIString(Int32, 1000, 4); - tryIString(Int32, 10000, 5); - tryIString(Int32, 32766, 5); - tryIString(Int32, 32767, 5); - tryIString(Int32, 32768, 5); - tryIString(Int32, 32769, 5); - tryIString(Int32, 65534, 5); - tryIString(Int32, 65535, 5); - tryIString(Int32, 65536, 5); - tryIString(Int32, 65537, 5); - tryIString(Int32, 2147483646, 10); - tryIString(Int32, 2147483647, 10); - - testDiag("------------------------------------------------------"); - testDiag("** Negative Int32 **"); - tryIString(Int32, -1, 2); - tryIString(Int32, -10, 3); - tryIString(Int32, -100, 4); - tryIString(Int32, -254, 4); - tryIString(Int32, -255, 4); - tryIString(Int32, -256, 4); - tryIString(Int32, -257, 4); - tryIString(Int32, -1000, 5); - tryIString(Int32, -10000, 6); - tryIString(Int32, -32766, 6); - tryIString(Int32, -32767, 6); - tryIString(Int32, -32768, 6); - tryIString(Int32, -32769, 6); - tryIString(Int32, -65534, 6); - tryIString(Int32, -65535, 6); - tryIString(Int32, -65536, 6); - tryIString(Int32, -65537, 6); - tryIString(Int32, -2147483647, 11); - tryIString(Int32, -2147483648LL, 11); - - testDiag("------------------------------------------------------"); - testDiag("** UInt32 **"); - tryIString(UInt32, 0, 1); - tryIString(UInt32, 1, 1); - tryIString(UInt32, 10, 2); - tryIString(UInt32, 100, 3); - tryIString(UInt32, 254, 3); - tryIString(UInt32, 255, 3); - tryIString(UInt32, 256, 3); - tryIString(UInt32, 257, 3); - tryIString(UInt32, 1000, 4); - tryIString(UInt32, 10000, 5); - tryIString(UInt32, 32766, 5); - tryIString(UInt32, 32767, 5); - tryIString(UInt32, 32768, 5); - tryIString(UInt32, 32769, 5); - tryIString(UInt32, 65534, 5); - tryIString(UInt32, 65535, 5); - tryIString(UInt32, 65536, 5); - tryIString(UInt32, 65537, 5); - tryIString(UInt32, 2147483646ULL, 10); - tryIString(UInt32, 2147483647ULL, 10); - tryIString(UInt32, 2147483648ULL, 10); - tryIString(UInt32, 4294967294ULL, 10); - tryIString(UInt32, 4294967295ULL, 10); - - testDiag("------------------------------------------------------"); - testDiag("** Positive Int64 **"); - tryIString(Int64, 0, 1); - tryIString(Int64, 1, 1); - tryIString(Int64, 10, 2); - tryIString(Int64, 100, 3); - tryIString(Int64, 254, 3); - tryIString(Int64, 255, 3); - tryIString(Int64, 256, 3); - tryIString(Int64, 257, 3); - tryIString(Int64, 1000, 4); - tryIString(Int64, 10000, 5); - tryIString(Int64, 32766, 5); - tryIString(Int64, 32767, 5); - tryIString(Int64, 32768, 5); - tryIString(Int64, 32769, 5); - tryIString(Int64, 65534, 5); - tryIString(Int64, 65535, 5); - tryIString(Int64, 65536, 5); - tryIString(Int64, 65537, 5); - tryIString(Int64, 2147483646, 10); - tryIString(Int64, 2147483647, 10); - tryIString(Int64, 2147483648LL, 10); - tryIString(Int64, 9223372036854775806LL, 19); - tryIString(Int64, 9223372036854775807LL, 19); - - testDiag("------------------------------------------------------"); - testDiag("** Negative Int64 **"); - tryIString(Int64, -1, 2); - tryIString(Int64, -10, 3); - tryIString(Int64, -100, 4); - tryIString(Int64, -254, 4); - tryIString(Int64, -255, 4); - tryIString(Int64, -256, 4); - tryIString(Int64, -257, 4); - tryIString(Int64, -1000, 5); - tryIString(Int64, -10000, 6); - tryIString(Int64, -32766, 6); - tryIString(Int64, -32767, 6); - tryIString(Int64, -32768, 6); - tryIString(Int64, -32769, 6); - tryIString(Int64, -65534, 6); - tryIString(Int64, -65535, 6); - tryIString(Int64, -65536, 6); - tryIString(Int64, -65537, 6); - tryIString(Int64, -2147483647, 11); - tryIString(Int64, -2147483648LL, 11); - tryIString(Int64, -2147483649LL, 11); - tryIString(Int64, -9223372036854775806LL, 20); - tryIString(Int64, -9223372036854775807LL, 20); - tryIString(Int64, -9223372036854775807LL-1, 20); - - testDiag("------------------------------------------------------"); - testDiag("** UInt64 **"); - tryIString(UInt64, 0, 1); - tryIString(UInt64, 1, 1); - tryIString(UInt64, 10, 2); - tryIString(UInt64, 100, 3); - tryIString(UInt64, 254, 3); - tryIString(UInt64, 255, 3); - tryIString(UInt64, 256, 3); - tryIString(UInt64, 257, 3); - tryIString(UInt64, 1000, 4); - tryIString(UInt64, 10000, 5); - tryIString(UInt64, 32766, 5); - tryIString(UInt64, 32767, 5); - tryIString(UInt64, 32768, 5); - tryIString(UInt64, 32769, 5); - tryIString(UInt64, 65534, 5); - tryIString(UInt64, 65535, 5); - tryIString(UInt64, 65536, 5); - tryIString(UInt64, 65537, 5); - tryIString(UInt64, 2147483646, 10); - tryIString(UInt64, 2147483647, 10); - tryIString(UInt64, 2147483648U, 10); - tryIString(UInt64, 2147483649U, 10); - tryIString(UInt64, 4294967294U, 10); - tryIString(UInt64, 4294967295U, 10); - tryIString(UInt64, 4294967296ULL, 10); - tryIString(UInt64, 4294967297ULL, 10); - tryIString(UInt64, 9223372036854775806ULL, 19); - tryIString(UInt64, 9223372036854775807ULL, 19); - tryIString(UInt64, 9223372036854775808ULL, 19); - tryIString(UInt64, 18446744073709551614ULL, 20); - tryIString(UInt64, 18446744073709551615ULL, 20); - - /* Arguments: type, value, precision, num chars */ - testDiag("------------------------------------------------------"); - testDiag("** Positive Float fixed-point **"); - tryFString(Float, 0, 0, 1); - tryFString(Float, 0, 1, 3); - tryFString(Float, 0, 2, 4); - tryFString(Float, 0, 3, 5); - tryFString(Float, 0, 4, 6); - tryFString(Float, 0, 5, 7); - tryFString(Float, 0, 6, 8); - tryFString(Float, 0, 7, 9); - tryFString(Float, 0, 8, 10); - tryFString(Float, FLT_MIN, 0, 1); - tryFString(Float, FLT_MIN, 1, 3); - tryFString(Float, FLT_MIN, 2, 4); - tryFString(Float, FLT_MIN, 3, 5); - tryFString(Float, FLT_MIN, 4, 6); - tryFString(Float, FLT_MIN, 5, 7); - tryFString(Float, FLT_MIN, 6, 8); - tryFString(Float, FLT_MIN, 7, 9); - tryFString(Float, FLT_MIN, 8, 10); - tryFString(Float, 0.000000004999999, 8, 10); - tryFString(Float, 0.000000005000001, 8, 10); - tryFString(Float, 0.00000004999999, 7, 9); - tryFString(Float, 0.00000005000001, 7, 9); - tryFString(Float, 0.0000004999999, 6, 8); - tryFString(Float, 0.0000005000001, 6, 8); - tryFString(Float, 0.000004999999, 5, 7); - tryFString(Float, 0.000005000001, 5, 7); - tryFString(Float, 0.00004999999, 4, 6); - tryFString(Float, 0.00005000001, 4, 6); - tryFString(Float, 0.0004999999, 3, 5); - tryFString(Float, 0.0005000001, 3, 5); - tryFString(Float, 0.004999999, 2, 4); - tryFString(Float, 0.005000001, 2, 4); - tryFString(Float, 0.04999999, 1, 3); - tryFString(Float, 0.05000001, 1, 3); - tryFString(Float, 0.4999999, 0, 1); - tryFString(Float, 0.5000001, 0, 1); - tryFString(Float, 1, 0, 1); - tryFString(Float, 1, 1, 3); - tryFString(Float, 1, 2, 4); - tryFString(Float, 1, 3, 5); - tryFString(Float, 1, 4, 6); - tryFString(Float, 1, 5, 7); - tryFString(Float, 1, 6, 8); - tryFString(Float, 1, 7, 9); - tryFString(Float, 1, 8, 10); - tryFString(Float, 1.0500001, 1, 3); - tryFString(Float, 1.1, 1, 3); - tryFString(Float, 1.1499999, 1, 3); - tryFString(Float, 9.5000001, 0, 2); - tryFString(Float, 10, 0, 2); - tryFString(Float, 10, 1, 4); - tryFString(Float, 10, 8, 11); - tryFString(Float, 100, 0, 3); - tryFString(Float, 100, 1, 5); - tryFString(Float, 100, 8, 12); - tryFString(Float, 1000, 0, 4); - tryFString(Float, 1000, 1, 6); - tryFString(Float, 1000, 8, 13); - tryFString(Float, 10000, 0, 5); - tryFString(Float, 10000, 1, 7); - tryFString(Float, 10000, 8, 14); - tryFString(Float, 100000, 0, 6); - tryFString(Float, 100000, 1, 8); - tryFString(Float, 100000, 8, 15); - tryFString(Float, 1000000, 0, 7); - tryFString(Float, 1000000, 1, 9); - tryFString(Float, 1000000, 8, 16); - tryFString(Float, 10000000, 0, 8); - tryFString(Float, 10000000, 1, 10); - tryFString(Float, 10000000, 8, 17); - - testDiag("------------------------------------------------------"); - testDiag("** Negative Float fixed-point **"); - tryFString(Float, -FLT_MIN, 0, 2); - tryFString(Float, -FLT_MIN, 1, 4); - tryFString(Float, -FLT_MIN, 8, 11); - tryFString(Float, -1, 0, 2); - tryFString(Float, -1, 1, 4); - tryFString(Float, -1, 8, 11); - tryFString(Float, -1.0500001, 1, 4); - tryFString(Float, -1.1, 1, 4); - tryFString(Float, -1.1499999, 1, 4); - tryFString(Float, -9.5000001, 0, 3); - tryFString(Float, -10, 0, 3); - tryFString(Float, -10, 1, 5); - tryFString(Float, -10, 8, 12); - tryFString(Float, -100, 0, 4); - tryFString(Float, -100, 1, 6); - tryFString(Float, -100, 8, 13); - tryFString(Float, -1000, 0, 5); - tryFString(Float, -1000, 1, 7); - tryFString(Float, -1000, 8, 14); - tryFString(Float, -10000, 0, 6); - tryFString(Float, -10000, 1, 8); - tryFString(Float, -10000, 8, 15); - tryFString(Float, -100000, 0, 7); - tryFString(Float, -100000, 1, 9); - tryFString(Float, -100000, 8, 16); - tryFString(Float, -1000000, 0, 8); - tryFString(Float, -1000000, 1, 10); - tryFString(Float, -1000000, 8, 17); - tryFString(Float, -10000000, 0, 9); - tryFString(Float, -10000000, 1, 11); - tryFString(Float, -10000000, 8, 18); - - /* - * Values > 1e7 trigger the %e format. - */ - testDiag("------------------------------------------------------"); - testDiag("** Positive Float scientific **"); - tryFString(Float, 1e+08, 0, 6); - tryFString(Float, 1e+08, 1, 7); - tryFString(Float, 1e+08, 2, 8); - tryFString(Float, 1e+08, 3, 9); - tryFString(Float, 1e+08, 4, 10); - tryFString(Float, 1e+08, 5, 11); - tryFString(Float, 1e+08, 6, 12); - - testDiag("------------------------------------------------------"); - testDiag("** Positive Double fixed-point **"); - tryFString(Double, 0, 0, 1); - tryFString(Double, 0, 1, 3); - tryFString(Double, 0, 2, 4); - tryFString(Double, 0, 3, 5); - tryFString(Double, 0, 4, 6); - tryFString(Double, 0, 5, 7); - tryFString(Double, 0, 6, 8); - tryFString(Double, 0, 7, 9); - tryFString(Double, 0, 8, 10); - tryFString(Double, DBL_MIN, 0, 1); - tryFString(Double, DBL_MIN, 1, 3); - tryFString(Double, DBL_MIN, 2, 4); - tryFString(Double, DBL_MIN, 3, 5); - tryFString(Double, DBL_MIN, 4, 6); - tryFString(Double, DBL_MIN, 5, 7); - tryFString(Double, DBL_MIN, 6, 8); - tryFString(Double, DBL_MIN, 7, 9); - tryFString(Double, DBL_MIN, 8, 10); - tryFString(Double, 0.000000004999999, 8, 10); - tryFString(Double, 0.000000005000001, 8, 10); - tryFString(Double, 0.00000004999999, 7, 9); - tryFString(Double, 0.00000005000001, 7, 9); - tryFString(Double, 0.0000004999999, 6, 8); - tryFString(Double, 0.0000005000001, 6, 8); - tryFString(Double, 0.000004999999, 5, 7); - tryFString(Double, 0.000005000001, 5, 7); - tryFString(Double, 0.00004999999, 4, 6); - tryFString(Double, 0.00005000001, 4, 6); - tryFString(Double, 0.0004999999, 3, 5); - tryFString(Double, 0.0005000001, 3, 5); - tryFString(Double, 0.004999999, 2, 4); - tryFString(Double, 0.005000001, 2, 4); - tryFString(Double, 0.04999999, 1, 3); - tryFString(Double, 0.05000001, 1, 3); - tryFString(Double, 0.4999999, 0, 1); - tryFString(Double, 0.5000001, 0, 1); - tryFString(Double, 1, 0, 1); - tryFString(Double, 1, 1, 3); - tryFString(Double, 1, 2, 4); - tryFString(Double, 1, 3, 5); - tryFString(Double, 1, 4, 6); - tryFString(Double, 1, 5, 7); - tryFString(Double, 1, 6, 8); - tryFString(Double, 1, 7, 9); - tryFString(Double, 1, 8, 10); - tryFString(Double, 1.0500001, 1, 3); - tryFString(Double, 1.1, 1, 3); - tryFString(Double, 1.1499999, 1, 3); - tryFString(Double, 9.5000001, 0, 2); - tryFString(Double, 10, 0, 2); - tryFString(Double, 10, 1, 4); - tryFString(Double, 10, 8, 11); - tryFString(Double, 100, 0, 3); - tryFString(Double, 100, 1, 5); - tryFString(Double, 100, 8, 12); - tryFString(Double, 1000, 0, 4); - tryFString(Double, 1000, 1, 6); - tryFString(Double, 1000, 8, 13); - tryFString(Double, 10000, 0, 5); - tryFString(Double, 10000, 1, 7); - tryFString(Double, 10000, 8, 14); - tryFString(Double, 100000, 0, 6); - tryFString(Double, 100000, 1, 8); - tryFString(Double, 100000, 8, 15); - tryFString(Double, 1000000, 0, 7); - tryFString(Double, 1000000, 1, 9); - tryFString(Double, 1000000, 8, 16); - tryFString(Double, 10000000, 0, 8); - tryFString(Double, 10000000, 1, 10); - tryFString(Double, 10000000, 8, 17); - - testDiag("------------------------------------------------------"); - testDiag("** Negative Double fixed-point **"); - tryFString(Double, -DBL_MIN, 0, 2); - tryFString(Double, -DBL_MIN, 1, 4); - tryFString(Double, -DBL_MIN, 8, 11); - tryFString(Double, -1, 0, 2); - tryFString(Double, -1, 1, 4); - tryFString(Double, -1, 8, 11); - tryFString(Double, -1.0500001, 1, 4); - tryFString(Double, -1.1, 1, 4); - tryFString(Double, -1.1499999, 1, 4); - tryFString(Double, -9.5000001, 0, 3); - tryFString(Double, -10, 0, 3); - tryFString(Double, -10, 1, 5); - tryFString(Double, -10, 8, 12); - tryFString(Double, -100, 0, 4); - tryFString(Double, -100, 1, 6); - tryFString(Double, -100, 8, 13); - tryFString(Double, -1000, 0, 5); - tryFString(Double, -1000, 1, 7); - tryFString(Double, -1000, 8, 14); - tryFString(Double, -10000, 0, 6); - tryFString(Double, -10000, 1, 8); - tryFString(Double, -10000, 8, 15); - tryFString(Double, -100000, 0, 7); - tryFString(Double, -100000, 1, 9); - tryFString(Double, -100000, 8, 16); - tryFString(Double, -1000000, 0, 8); - tryFString(Double, -1000000, 1, 10); - tryFString(Double, -1000000, 8, 17); - tryFString(Double, -10000000, 0, 9); - tryFString(Double, -10000000, 1, 11); - tryFString(Double, -10000000, 8, 18); - - /* - * Values > 1e7 trigger the %e format. - * Windows may print 3 digit exponents... - */ - testDiag("------------------------------------------------------"); - testDiag("** Positive Double scientific **"); - tryFString(Double, 1e+17, 0, 7); - tryFString(Double, 1e+17, 1, 8); - tryFString(Double, 1e+17, 2, 9); - tryFString(Double, 1e+17, 3, 10); - tryFString(Double, 1e+17, 4, 11); - tryFString(Double, 1e+17, 5, 12); - - return testDone(); -} diff --git a/src/libCom/test/epicsAlgorithmTest.cpp b/src/libCom/test/epicsAlgorithmTest.cpp deleted file mode 100644 index fa8c0c03f..000000000 --- a/src/libCom/test/epicsAlgorithmTest.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// epicsAlgorithmTest.cpp -// Authors: Jeff Hill & Andrew Johnson - -#include "epicsUnitTest.h" -#include "epicsAlgorithm.h" -#include "epicsMath.h" -#include "testMain.h" - -MAIN(epicsAlgorithm) -{ - testPlan(22); - - float f1 = 3.3f; - float f2 = 3.4f; - float Inf = epicsINF; - float NaN = epicsNAN; - - testOk(epicsMin(f1, f2) == f1, "epicsMin(f1, f2)"); - testOk(epicsMin(f1, -Inf) == -Inf, "epicsMin(f1, -Inf)"); - testOk(isnan(epicsMin(f1, NaN)), "epicsMin(f1, NaN)"); - testOk(epicsMin(f1, Inf) == f1, "epicsMin(f1, Inf)"); - - testOk(epicsMin(f2, f1) == f1, "epicsMin(f2, f1)"); - testOk(epicsMin(-Inf, f1) == -Inf, "epicsMin(-Inf, f1)"); - testOk(isnan(epicsMin(NaN, f1)), "epicsMin(NaN, f1)"); - testOk(epicsMin(Inf, f1) == f1, "epicsMin(Inf, f1)"); - - testOk(epicsMax(f2, f1) == f2, "epicsMax(f2, f1)"); - testOk(epicsMax(-Inf, f1) == f1, "epicsMax(-Inf, f1)"); - testOk(isnan(epicsMax(NaN, f1)), "epicsMax(NaN, f1)"); - testOk(epicsMax(Inf, f1) == Inf, "epicsMax(Inf, f1)"); - - testOk(epicsMax(f1, f2) == f2, "epicsMax(f1, f2)"); - testOk(epicsMax(f1, -Inf) == f1, "epicsMax(f1, -Inf)"); - testOk(isnan(epicsMax(f1, NaN)), "epicsMax(f1, NaN)"); - testOk(epicsMax(f1, Inf) == Inf, "epicsMax(f1, Inf)"); - - epicsSwap(f1, f2); - testOk(f1==3.4f && f2==3.3f, "epicsSwap(f1, f2)"); - - int i1 = 3; - int i2 = 4; - - testOk(epicsMin(i1, i2) == i1, "epicsMin(i1,i2)"); - testOk(epicsMin(i2, i1) == i1, "epicsMin(i2,i1)"); - - testOk(epicsMax(i1, i2) == i2, "epicsMax(i1,i2)"); - testOk(epicsMax(i2, i1) == i2, "epicsMax(i2,i1)"); - - epicsSwap(i1, i2); - testOk(i1 == 4 && i2 == 3, "epicsSwap(i1, i2)"); - - return testDone(); -} - diff --git a/src/libCom/test/epicsAtomicPerform.cpp b/src/libCom/test/epicsAtomicPerform.cpp deleted file mode 100644 index 2ef005efe..000000000 --- a/src/libCom/test/epicsAtomicPerform.cpp +++ /dev/null @@ -1,574 +0,0 @@ - -#include -#include -#include -#include - -#include "epicsInterrupt.h" -#include "epicsAtomic.h" -#include "epicsTime.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -using std :: size_t; -using namespace epics; -using namespace atomic; - -class RefCtr { -public: - RefCtr (); - ~RefCtr (); - void reference (); - void unreference (); -private: - size_t m_cnt; -}; - -class Ownership { -public: - Ownership (); - Ownership ( RefCtr & refCtr ); - Ownership ( const Ownership & ); - ~Ownership (); - Ownership & operator = ( const Ownership & ); -private: - RefCtr * _pRefCtr; - static RefCtr m_noOwnership; -}; - -inline RefCtr :: RefCtr () -{ - epicsAtomicSetSizeT ( & m_cnt, 0 ); -} - -inline RefCtr :: ~RefCtr () -{ - unsigned cnt = epicsAtomicGetSizeT ( & m_cnt ); - assert ( cnt == 0u ); -} - -inline void RefCtr :: reference () -{ - epicsAtomicIncrSizeT ( & m_cnt ); -} - -inline void RefCtr :: unreference () -{ - epicsAtomicDecrSizeT ( & m_cnt ); -} - -RefCtr Ownership :: m_noOwnership; - -inline Ownership :: Ownership () : - _pRefCtr ( & m_noOwnership ) -{ - m_noOwnership.reference (); -} - -inline Ownership :: Ownership ( RefCtr & refCtr ) : - _pRefCtr ( & refCtr ) -{ - refCtr.reference (); -} - -inline Ownership :: Ownership ( const Ownership & ownership ) : - _pRefCtr ( ownership._pRefCtr ) -{ - _pRefCtr->reference (); -} - -inline Ownership :: ~Ownership () -{ - _pRefCtr->unreference (); -} - -inline Ownership & Ownership :: - operator = ( const Ownership & ownership ) -{ - RefCtr * const pOldRefCtr = _pRefCtr; - _pRefCtr = ownership._pRefCtr; - _pRefCtr->reference (); - pOldRefCtr->unreference (); - return *this; -} - -inline Ownership retOwnership ( const Ownership & ownership ) -{ - return Ownership ( ownership ); -} - -inline Ownership recurRetOwner10 ( const Ownership & ownershipIn ) -{ - Ownership ownership = - retOwnership ( - retOwnership ( - retOwnership ( - retOwnership ( - retOwnership ( ownershipIn ) ) ) ) ); - return retOwnership ( - retOwnership ( - retOwnership ( - retOwnership ( - retOwnership ( ownership ) ) ) ) ); -} - -inline Ownership recurRetOwner100 ( const Ownership & ownershipIn ) -{ - Ownership ownership = - recurRetOwner10 ( - recurRetOwner10 ( - recurRetOwner10 ( - recurRetOwner10 ( - recurRetOwner10 ( ownershipIn ) ) ) ) ); - return recurRetOwner10 ( - recurRetOwner10 ( - recurRetOwner10 ( - recurRetOwner10 ( - recurRetOwner10 ( ownership ) ) ) ) ); -} - -inline Ownership recurRetOwner1000 ( const Ownership & ownershipIn ) -{ - Ownership ownership = - recurRetOwner100 ( - recurRetOwner100 ( - recurRetOwner100 ( - recurRetOwner100 ( - recurRetOwner100 ( ownershipIn ) ) ) ) ); - return recurRetOwner100 ( - recurRetOwner100 ( - recurRetOwner100 ( - recurRetOwner100 ( - recurRetOwner100 ( ownership ) ) ) ) ); -} - -inline void passRefOwnership ( const Ownership & ownershipIn, Ownership & ownershipOut ) -{ - ownershipOut = ownershipIn; -} - -inline void passRefOwnership10 ( const Ownership & ownershipIn, Ownership & ownershipOut ) -{ - Ownership ownershipTmp0; - passRefOwnership ( ownershipIn, ownershipTmp0 ); - Ownership ownershipTmp1; - passRefOwnership ( ownershipTmp0, ownershipTmp1 ); - Ownership ownershipTmp2; - passRefOwnership ( ownershipTmp1, ownershipTmp2 ); - Ownership ownershipTmp3; - passRefOwnership ( ownershipTmp2, ownershipTmp3 ); - Ownership ownershipTmp4; - passRefOwnership ( ownershipTmp3, ownershipTmp4 ); - Ownership ownershipTmp5; - passRefOwnership ( ownershipTmp4, ownershipTmp5 ); - Ownership ownershipTmp6; - passRefOwnership ( ownershipTmp5, ownershipTmp6 ); - Ownership ownershipTmp7; - passRefOwnership ( ownershipTmp6, ownershipTmp7 ); - Ownership ownershipTmp8; - passRefOwnership ( ownershipTmp7, ownershipTmp8 ); - passRefOwnership ( ownershipTmp8, ownershipOut ); -} - -inline void passRefOwnership100 ( const Ownership & ownershipIn, Ownership & ownershipOut ) -{ - Ownership ownershipTmp0; - passRefOwnership10 ( ownershipIn, ownershipTmp0 ); - Ownership ownershipTmp1; - passRefOwnership10 ( ownershipTmp0, ownershipTmp1 ); - Ownership ownershipTmp2; - passRefOwnership10 ( ownershipTmp1, ownershipTmp2 ); - Ownership ownershipTmp3; - passRefOwnership10 ( ownershipTmp2, ownershipTmp3 ); - Ownership ownershipTmp4; - passRefOwnership10 ( ownershipTmp3, ownershipTmp4 ); - Ownership ownershipTmp5; - passRefOwnership10 ( ownershipTmp4, ownershipTmp5 ); - Ownership ownershipTmp6; - passRefOwnership10 ( ownershipTmp5, ownershipTmp6 ); - Ownership ownershipTmp7; - passRefOwnership10 ( ownershipTmp6, ownershipTmp7 ); - Ownership ownershipTmp8; - passRefOwnership10 ( ownershipTmp7, ownershipTmp8 ); - passRefOwnership10 ( ownershipTmp8, ownershipOut ); -} - -inline void passRefOwnership1000 ( const Ownership & ownershipIn, Ownership & ownershipOut ) -{ - Ownership ownershipTmp0; - passRefOwnership100 ( ownershipIn, ownershipTmp0 ); - Ownership ownershipTmp1; - passRefOwnership100 ( ownershipTmp0, ownershipTmp1 ); - Ownership ownershipTmp2; - passRefOwnership100 ( ownershipTmp1, ownershipTmp2 ); - Ownership ownershipTmp3; - passRefOwnership100 ( ownershipTmp2, ownershipTmp3 ); - Ownership ownershipTmp4; - passRefOwnership100 ( ownershipTmp3, ownershipTmp4 ); - Ownership ownershipTmp5; - passRefOwnership100 ( ownershipTmp4, ownershipTmp5 ); - Ownership ownershipTmp6; - passRefOwnership100 ( ownershipTmp5, ownershipTmp6 ); - Ownership ownershipTmp7; - passRefOwnership100 ( ownershipTmp6, ownershipTmp7 ); - Ownership ownershipTmp8; - passRefOwnership100 ( ownershipTmp7, ownershipTmp8 ); - passRefOwnership100 ( ownershipTmp8, ownershipOut ); -} - -time_t extTime = 0; - -template < class T > -class OrdinaryIncr { -public: - OrdinaryIncr () : m_target ( 0 ) {} - void run (); - void diagnostic ( double delay ); -private: - T m_target; -}; - -// tests the time it takes to perform a call to an external -// function and also increment an integer word. The -// epicsInterruptIsInterruptContext function is an -// out-of-line function implemented in a sharable library -// so hopefully it wont be optimized away. -template < class T > -inline void OrdinaryIncr < T > :: run () -{ - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); -} - -template < class T > -void OrdinaryIncr < T > :: diagnostic ( double delay ) -{ - delay /= 10.0; - delay *= 1e6; - const char * const pName = typeid ( T ) . name (); - testDiag ( "raw incr of \"%s\" and a NOOP function call takes %f microseconds", - pName, delay ); -} - -template < class T > -class AtomicIncr { -public: - AtomicIncr () : m_target ( 0 ) {} - void run (); - void diagnostic ( double delay ); -private: - T m_target; -}; - -template < class T > -inline void AtomicIncr < T > :: run () -{ - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); -} - -template < class T > -void AtomicIncr < T > :: diagnostic ( double delay ) -{ - delay /= 10.0; - delay *= 1e6; - const char * const pName = typeid ( T ) . name (); - testDiag ( "epicsAtomicIncr \"%s\" takes %f microseconds", - pName, delay ); -} - -template < class T > T trueValue (); -template < class T > T falseValue (); - -// int -template <> -inline int trueValue < int > () { return 1; } - -template <> -inline int falseValue < int > () { return 0; } - -// size_t -template <> -inline size_t trueValue < size_t > () { return 1u; } - -template <> -inline size_t falseValue < size_t > () { return 0u; } - -// EpicsAtomicPtrT -template <> -inline EpicsAtomicPtrT trueValue < EpicsAtomicPtrT > () -{ static char c; return & c; } - -template <> -inline EpicsAtomicPtrT falseValue < EpicsAtomicPtrT > () -{ return 0u; } - -template < class T > -class AtomicCmpAndSwap { -public: - AtomicCmpAndSwap () : m_target ( 0 ) {} - void run (); - void diagnostic ( double delay ); -private: - T m_target; -}; - -template < class T > -inline void AtomicCmpAndSwap < T > :: run () -{ - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); -} - -template < class T > -void AtomicCmpAndSwap < T > :: diagnostic ( double delay ) -{ - delay /= 10.0; - delay *= 1e6; - const char * const pName = typeid ( T ) . name (); - testDiag ( "epicsAtomicCmpAndSwap of \"%s\" takes %f microseconds", - pName, delay ); -} - -template < class T > -class AtomicSet { -public: - AtomicSet () : m_target ( 0 ) {} - void run (); - void diagnostic ( double delay ); -private: - T m_target; -}; - -template < class T > -inline void AtomicSet < T > :: run () -{ - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); -} - -template < class T > -void AtomicSet < T > :: diagnostic ( double delay ) -{ - delay /= 10.0; - delay *= 1e6; - const char * const pName = typeid ( T ) . name (); - testDiag ( "epicsAtomicSet of \"%s\" takes %f microseconds", - pName, delay ); -} - -static const unsigned N = 10000; - -void recursiveOwnershipRetPerformance () -{ - RefCtr refCtr; - epicsTime begin = epicsTime::getCurrent (); - for ( size_t i = 0; i < N; i++ ) { - Ownership ownership ( refCtr ); - recurRetOwner1000 ( ownership ); - } - double delay = epicsTime::getCurrent () - begin; - delay /= N * 1000u; // convert to delay per call - delay *= 1e6; // convert to micro seconds - testDiag ( "retOwnership() takes %f microseconds", delay ); -} - -void ownershipPassRefPerformance () -{ - RefCtr refCtr; - epicsTime begin = epicsTime::getCurrent (); - for ( size_t i = 0; i < N; i++ ) { - Ownership ownershipSrc ( refCtr ); - Ownership ownershipDest; - passRefOwnership1000 ( ownershipSrc, ownershipDest ); - } - double delay = epicsTime::getCurrent () - begin; - delay /= N * 1000u; // convert to delay per call - delay *= 1e6; // convert to micro seconds - testDiag ( "passRefOwnership() takes %f microseconds", delay ); -} - -template < class T > -class Ten -{ -public: - void run (); - void diagnostic ( double delay ); - typedef Ten < Ten < T > > Hundred; - typedef Ten < Hundred > Thousand; -private: - T m_target; -}; - -template < class T > -inline void Ten < T > :: run () -{ - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); -} - -template < class T > -void Ten < T > :: diagnostic ( double delay ) -{ - m_target.diagnostic ( delay / 10.0 ); -} - -template < class T > -void measurePerformance () -{ - epicsTime begin = epicsTime::getCurrent (); - T target; - for ( size_t i = 0; i < N; i++ ) { - target.run (); - target.run (); - target.run (); - target.run (); - target.run (); - target.run (); - target.run (); - target.run (); - target.run (); - target.run (); - } - double delay = epicsTime::getCurrent () - begin; - delay /= ( N * 10u ); // convert to delay per call - target.diagnostic ( delay ); -} - -template < class T > -void measure () -{ - measurePerformance < typename Ten < T > :: Hundred > (); -} - - -// template instances, needed for vxWorks 5.5.2 - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template class AtomicSet < int >; -template class AtomicSet < size_t >; -template class AtomicSet < EpicsAtomicPtrT >; -template class OrdinaryIncr < int >; -template class OrdinaryIncr < size_t >; -template class AtomicIncr < int >; -template class AtomicIncr < size_t >; -template class AtomicCmpAndSwap < int >; -template class AtomicCmpAndSwap < size_t >; -template class AtomicCmpAndSwap < EpicsAtomicPtrT >; - -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; - -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; - -template void measurePerformance < Ten < Ten < AtomicSet < int > > > >(void); -template void measurePerformance < Ten < Ten < AtomicSet < size_t > > > >(void); -template void measurePerformance < Ten < Ten < AtomicSet < EpicsAtomicPtrT > > > >(void); -template void measurePerformance < Ten < Ten < OrdinaryIncr < int > > > >(void); -template void measurePerformance < Ten < Ten < OrdinaryIncr < size_t > > > >(void); -template void measurePerformance < Ten < Ten < AtomicIncr < int > > > >(void); -template void measurePerformance < Ten < Ten < AtomicIncr < size_t > > > >(void); -template void measurePerformance < Ten < Ten < AtomicCmpAndSwap < int > > > >(void); -template void measurePerformance < Ten < Ten < AtomicCmpAndSwap < size_t > > > >(void); -template void measurePerformance < Ten < Ten < AtomicCmpAndSwap < EpicsAtomicPtrT > > > >(void); - -template void measure < AtomicSet < int > > (void); -template void measure < AtomicSet < size_t > > (void); -template void measure < AtomicSet < EpicsAtomicPtrT > > (void); -template void measure < OrdinaryIncr < int > > (void); -template void measure < OrdinaryIncr < size_t > > (void); -template void measure < AtomicIncr < int > > (void); -template void measure < AtomicIncr < size_t > > (void); -template void measure < AtomicCmpAndSwap < int > > (void); -template void measure < AtomicCmpAndSwap < size_t > > (void); -template void measure < AtomicCmpAndSwap < EpicsAtomicPtrT > > (void); - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - - -MAIN ( epicsAtomicPerform ) -{ - testPlan ( 0 ); - // - // The tests running here are measuring fast - // functions so they tend to be impacted - // by where the cache lines are wrt to the - // virtual pages perhap - // - measure < AtomicSet < int > > (); - measure < AtomicSet < size_t > > (); - measure < AtomicSet < void * > > (); - measure < OrdinaryIncr < int > > (); - measure < OrdinaryIncr < size_t > > (); - measure < AtomicIncr < int > > (); - measure < AtomicIncr < size_t > > (); - measure < AtomicCmpAndSwap < int > > (); - measure < AtomicCmpAndSwap < size_t > > (); - measure < AtomicCmpAndSwap < void * > > (); - recursiveOwnershipRetPerformance (); - ownershipPassRefPerformance (); - return testDone(); -} diff --git a/src/libCom/test/epicsAtomicTest.cpp b/src/libCom/test/epicsAtomicTest.cpp deleted file mode 100644 index fd9fc2e6b..000000000 --- a/src/libCom/test/epicsAtomicTest.cpp +++ /dev/null @@ -1,426 +0,0 @@ - -#include -#include - -#include "epicsAtomic.h" -#include "epicsTime.h" -#include "epicsThread.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -namespace { - -template < class T > -struct TestDataIncrDecr { - T m_testValue; - size_t m_testIterations; -}; - -template < class T > -struct TestDataAddSub { - T m_testValue; - size_t m_testIterations; - static const T delta = 17; -}; - -template < class T > -static void incr ( void *arg ) -{ - using epics::atomic::increment; - TestDataIncrDecr < T > * const pTestData = - reinterpret_cast < TestDataIncrDecr < T > * > ( arg ); - increment ( pTestData->m_testValue ); - increment ( pTestData->m_testIterations ); -} - -template < class T > -static void decr ( void *arg ) -{ - using epics::atomic::decrement; - using epics::atomic::increment; - TestDataIncrDecr < T > * const pTestData = - reinterpret_cast < TestDataIncrDecr < T > * > ( arg ); - decrement ( pTestData->m_testValue ); - increment ( pTestData->m_testIterations ); -} - - -template < class T > -static void add ( void *arg ) -{ - using epics::atomic::add; - using epics::atomic::increment; - TestDataAddSub < T > * const pTestData = - reinterpret_cast < TestDataAddSub < T > * > ( arg ); - add ( pTestData->m_testValue, TestDataAddSub < T > :: delta ); - increment ( pTestData->m_testIterations ); -} - -template < class T > -static void sub ( void *arg ) -{ - using epics::atomic::subtract; - using epics::atomic::increment; - TestDataAddSub < T > * const pTestData = - reinterpret_cast < TestDataAddSub < T > * > ( arg ); - subtract ( pTestData->m_testValue, TestDataAddSub < T > :: delta ); - increment ( pTestData->m_testIterations ); -} - -template < class T > -struct TestDataCAS { - T m_testValue; - size_t m_testIterationsSet; - size_t m_testIterationsNotSet; -}; - -template < class T > -static T trueValue (); -template < class T > -static T falseValue (); - -// int -template <> -inline int trueValue < int > () { return 1; } - -template <> -inline int falseValue < int > () { return 0; } - -// size_t -template <> -inline size_t trueValue < size_t > () { return 1u; } - -template <> -inline size_t falseValue < size_t > () { return 0u; } - -// EpicsAtomicPtrT -template <> -inline EpicsAtomicPtrT trueValue < EpicsAtomicPtrT > () -{ static char c; return & c; } - -template <> -inline EpicsAtomicPtrT falseValue < EpicsAtomicPtrT > () -{ return 0u; } - -template < class T > -static void cas ( void *arg ) -{ - using epics::atomic::set; - using epics::atomic::increment; - using epics::atomic::decrement; - using epics::atomic::compareAndSwap; - - TestDataCAS < T > * const pTestData = - reinterpret_cast < TestDataCAS < T > * > ( arg ); - /* - * intentionally waste cpu and maximize - * contention for the shared data - */ - increment ( pTestData->m_testIterationsNotSet ); - while ( ! compareAndSwap ( pTestData->m_testValue, - falseValue < T > (), - trueValue < T > () ) ) { - } - decrement ( pTestData->m_testIterationsNotSet ); - set ( pTestData->m_testValue, falseValue < T > () ); - increment ( pTestData->m_testIterationsSet ); -} - -template < class T > -void testIncrDecr () -{ - using epics::atomic::set; - using epics::atomic::get; - - static const size_t N = 90; - static const T NT = static_cast < T > ( N ); - - const unsigned int stackSize = - epicsThreadGetStackSize ( epicsThreadStackSmall ); - - TestDataIncrDecr < T > testData = { 0, N }; - set ( testData.m_testValue, NT ); - testOk ( get ( testData.m_testValue ) == NT, - "get returns initial incr/decr test data value that was set" ); - set ( testData.m_testIterations, 0u ); - testOk ( get ( testData.m_testIterations ) == 0u, - "get returns initial incr/decr test thread iterations value that was set" ); - for ( size_t i = 0u; i < N; i++ ) { - epicsThreadMustCreate ( "incr", - 50, stackSize, incr < T >, & testData ); - epicsThreadMustCreate ( "decr", - 50, stackSize, decr < T >, & testData ); - if(i%10==0) - testDiag("iteration %u", (unsigned)i); - } - while ( testData.m_testIterations < 2 * N ) { - epicsThreadSleep ( 0.01 ); - } - testOk ( get ( testData.m_testIterations ) == 2 * N, - "proper number of incr/decr test thread iterations" ); - testOk ( get ( testData.m_testValue ) == NT, - "proper final incr/decr test value" ); -} - -template < class T > -void testAddSub () -{ - using epics::atomic::set; - using epics::atomic::get; - - static const size_t N = 90; - static const T NDT = TestDataAddSub < T > :: delta * - static_cast < T > ( N ); - - const unsigned int stackSize = - epicsThreadGetStackSize ( epicsThreadStackSmall ); - - TestDataIncrDecr < T > testData = { 0, N }; - set ( testData.m_testValue, NDT ); - testOk ( get ( testData.m_testValue ) == NDT, - "get returns initial add/sub test data value that was set" ); - set ( testData.m_testIterations, 0u ); - testOk ( get ( testData.m_testIterations ) == 0u, - "get returns initial incr/decr test thread iterations value that was set" ); - for ( size_t i = 0u; i < N; i++ ) { - epicsThreadMustCreate ( "add", - 50, stackSize, add < T >, & testData ); - epicsThreadMustCreate ( "sub", - 50, stackSize, sub < T >, & testData ); - } - while ( testData.m_testIterations < 2 * N ) { - epicsThreadSleep ( 0.01 ); - } - testOk ( get ( testData.m_testIterations ) == 2 * N, - "proper number of add/sub test thread iterations" ); - testOk ( get ( testData.m_testValue ) == NDT, - "proper final add/sub test value" ); -} - -template < class T > -void testCAS () -{ - using epics::atomic::set; - using epics::atomic::get; - - static const size_t N = 10; - - const unsigned int stackSize = - epicsThreadGetStackSize ( epicsThreadStackSmall ); - - TestDataCAS < T > testData = { 0, N, N }; - set ( testData.m_testIterationsSet, 0 ); - testOk ( get ( testData.m_testIterationsSet ) == 0u, - "get returns initial CAS test thread " - "iterations set value" ); - set ( testData.m_testIterationsNotSet, 0 ); - testOk ( get ( testData.m_testIterationsNotSet ) == 0u, - "get returns initial CAS test thread " - "iterations not set value" ); - set ( testData.m_testValue, trueValue < T > () ); - testOk ( get ( testData.m_testValue ) == trueValue < T > (), - "set/get a true value" ); - for ( size_t i = 0u; i < N; i++ ) { - epicsThreadMustCreate ( "tns", - 50, stackSize, cas < T >, & testData ); - } - set ( testData.m_testValue, falseValue < T > () ); - while ( testData.m_testIterationsSet < N ) { - epicsThreadSleep ( 0.01 ); - } - testOk ( get ( testData.m_testIterationsSet ) == N, - "proper number of CAS test thread set iterations" ); - testOk ( get ( testData.m_testIterationsNotSet ) == 0u, - "proper number of CAS test thread not set iterations" ); -} - -// template instances, needed for vxWorks 5.5.2 - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template void incr < int > (void *); -template void decr < int > (void *); -template void incr < size_t > (void *); -template void decr < size_t > (void *); -template void add < int > (void *); -template void sub < int > (void *); -template void add < size_t > (void *); -template void sub < size_t > (void *); -template void cas < int > (void *); -template void cas < size_t > (void *); -template void cas < EpicsAtomicPtrT > (void *); - -template void testIncrDecr < int > (void); -template void testIncrDecr < size_t > (void); -template void testAddSub < int > (void); -template void testAddSub < size_t > (void); -template void testCAS < int > (void); -template void testCAS < size_t > (void); -template void testCAS < EpicsAtomicPtrT > (void); - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - -static void testClassify() -{ - testDiag("Classify Build conditions"); -#ifdef EPICS_ATOMIC_CMPLR_NAME - testDiag("Compiler dependent impl name %s", EPICS_ATOMIC_CMPLR_NAME); -#else - testDiag("Compiler dependent impl name undefined"); -#endif -#ifdef EPICS_ATOMIC_OS_NAME - testDiag("OS dependent impl name %s", EPICS_ATOMIC_OS_NAME); -#else - testDiag("OS dependent impl name undefined"); -#endif - -#ifdef __GNUC__ -#if GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER - testDiag("GCC using atomic builtin memory barrier"); -#else - testDiag("GCC using asm memory barrier"); -#endif -#if GCC_ATOMIC_INTRINSICS_AVAIL_INT_T || GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER - testDiag("GCC use builtin for int"); -#endif -#if GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T || GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER - testDiag("GCC use builtin for size_t"); -#endif - -#ifndef EPICS_ATOMIC_INCR_INTT - testDiag("Use default epicsAtomicIncrIntT()"); -#endif -#ifndef EPICS_ATOMIC_INCR_SIZET - testDiag("Use default epicsAtomicIncrSizeT()"); -#endif -#ifndef EPICS_ATOMIC_DECR_INTT - testDiag("Use default epicsAtomicDecrIntT()"); -#endif -#ifndef EPICS_ATOMIC_DECR_SIZET - testDiag("Use default epicsAtomicDecrSizeT()"); -#endif -#ifndef EPICS_ATOMIC_ADD_INTT - testDiag("Use default epicsAtomicAddIntT()"); -#endif -#ifndef EPICS_ATOMIC_ADD_SIZET - testDiag("Use default epicsAtomicAddSizeT()"); -#endif -#ifndef EPICS_ATOMIC_SUB_SIZET - testDiag("Use default epicsAtomicSubSizeT()"); -#endif -#ifndef EPICS_ATOMIC_SET_INTT - testDiag("Use default epicsAtomicSetIntT()"); -#endif -#ifndef EPICS_ATOMIC_SET_SIZET - testDiag("Use default epicsAtomicSetSizeT()"); -#endif -#ifndef EPICS_ATOMIC_SET_PTRT - testDiag("Use default epicsAtomicSetPtrT()"); -#endif -#ifndef EPICS_ATOMIC_GET_INTT - testDiag("Use default epicsAtomicGetIntT()"); -#endif -#ifndef EPICS_ATOMIC_GET_SIZET - testDiag("Use default epicsAtomicGetSizeT()"); -#endif -#ifndef EPICS_ATOMIC_GET_PTRT - testDiag("Use default epicsAtomicGetPtrT()"); -#endif -#ifndef EPICS_ATOMIC_CAS_INTT - testDiag("Use default epicsAtomicCmpAndSwapIntT()"); -#endif -#ifndef EPICS_ATOMIC_CAS_SIZET - testDiag("Use default epicsAtomicCmpAndSwapSizeT()"); -#endif -#ifndef EPICS_ATOMIC_CAS_PTRT - testDiag("Use default epicsAtomicCmpAndSwapPtrT()"); -#endif -#endif /* __GNUC__ */ -} - -static -void testBasic() -{ - using epics::atomic::set; - using epics::atomic::get; - using epics::atomic::decrement; - using epics::atomic::increment; - using epics::atomic::add; - using epics::atomic::subtract; - using epics::atomic::compareAndSwap; - - testDiag("Test basic operation symantics"); - - int Int = 0; - size_t Sizet = 0; - void *voidp = NULL; - - set(Int, -42); - set(Sizet, 42); - set(voidp, (void*)&voidp); - - increment(Int); - increment(Sizet); - - testOk1(get(Int)==-41); - testOk1(get(Sizet)==43); - testOk1(get(voidp)==(void*)&voidp); - - decrement(Int); - decrement(Sizet); - - testOk1(get(Int)==-42); - testOk1(get(Sizet)==42); - - add(Int, -2); - subtract(Sizet, 2); - - testOk1(get(Int)==-44); - testOk1(get(Sizet)==40); - - testOk1(compareAndSwap(Int, -34, -10)==-44); - testOk1(compareAndSwap(Sizet, 34, 10)==40); - testOk1(compareAndSwap(voidp, NULL, (void*)&Sizet)==(void*)&voidp); - - testOk1(get(Int)==-44); - testOk1(get(Sizet)==40); - testOk1(get(voidp)==(void*)&voidp); - - testOk1(compareAndSwap(Int, -44, -10)==-44); - testOk1(compareAndSwap(Sizet, 40, 10)==40); - testOk1(compareAndSwap(voidp, (void*)&voidp, (void*)&Sizet)==(void*)&voidp); - - testOk1(get(Int)==-10); - testOk1(get(Sizet)==10); - testOk1(get(voidp)==(void*)&Sizet); -} - -} // namespace - -MAIN ( epicsAtomicTest ) -{ - - testPlan ( 50 ); - testDiag("In %s", EPICS_FUNCTION); - testClassify (); - testBasic(); -#if defined(__rtems__) - testSkip(31, "Tests assume time sliced thread scheduling"); -#else - testIncrDecr < int > (); - testIncrDecr < size_t > (); - testAddSub < int > (); - testAddSub < size_t > (); - testCAS < int > (); - testCAS < size_t > (); - testCAS < EpicsAtomicPtrT > (); -#endif - - return testDone (); -} - diff --git a/src/libCom/test/epicsCalcTest.cpp b/src/libCom/test/epicsCalcTest.cpp deleted file mode 100644 index 1ebc0c578..000000000 --- a/src/libCom/test/epicsCalcTest.cpp +++ /dev/null @@ -1,992 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// Author: Andrew Johnson - -#include -#include - -#include "epicsUnitTest.h" -#include "epicsTypes.h" -#include "epicsMath.h" -#include "epicsAlgorithm.h" -#include "postfix.h" -#include "testMain.h" - -/* Infrastructure for running tests */ - -double doCalc(const char *expr) { - /* Evaluate expression, return result */ - double args[CALCPERFORM_NARGS] = { - 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 - }; - char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); - short err; - double result = 0.0; - result /= result; /* Start as NaN */ - - if(!rpn) { - testAbort("postfix: %s no memory", expr); - return epicsNAN; - } - - if (postfix(expr, rpn, &err)) { - testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr); - } else - if (calcPerform(args, &result, rpn) && finite(result)) { - testDiag("calcPerform: error evaluating '%s'", expr); - } - free(rpn); - return result; -} - -void testCalc(const char *expr, double expected) { - /* Evaluate expression, test against expected result */ - bool pass = false; - double args[CALCPERFORM_NARGS] = { - 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 - }; - char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); - short err; - double result = 0.0; - result /= result; /* Start as NaN */ - - if(!rpn) { - testFail("postfix: %s no memory", expr); - return; - } - - if (postfix(expr, rpn, &err)) { - testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr); - } else - if (calcPerform(args, &result, rpn) && finite(result)) { - testDiag("calcPerform: error evaluating '%s'", expr); - } - - if (finite(expected) && finite(result)) { - pass = fabs(expected - result) < 1e-8; - } else if (isnan(expected)) { - pass = (bool) isnan(result); - } else { - pass = (result == expected); - } - if (!testOk(pass, "%s", expr)) { - testDiag("Expected result is %g, actually got %g", expected, result); - calcExprDump(rpn); - } - free(rpn); -} - -void testUInt32Calc(const char *expr, epicsUInt32 expected) { - /* Evaluate expression, test against expected result */ - bool pass = false; - double args[CALCPERFORM_NARGS] = { - 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 - }; - char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); - short err; - epicsUInt32 uresult; - double result = 0.0; - result /= result; /* Start as NaN */ - - if(!rpn) { - testFail("postfix: %s no memory", expr); - return; - } - - if (postfix(expr, rpn, &err)) { - testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr); - } else - if (calcPerform(args, &result, rpn) && finite(result)) { - testDiag("calcPerform: error evaluating '%s'", expr); - } - - uresult = (epicsUInt32) result; - pass = (uresult == expected); - if (!testOk(pass, "%s", expr)) { - testDiag("Expected result is 0x%x (%u), actually got 0x%x (%u)", - expected, expected, uresult, uresult); - calcExprDump(rpn); - } - free(rpn); -} - -void testArgs(const char *expr, unsigned long einp, unsigned long eout) { - char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); - short err = 0; - unsigned long vinp, vout; - - if(!rpn) { - testFail("postfix: %s no memory", expr); - return; - } - - if (postfix(expr, rpn, &err)) { - testFail("postfix: %s in expression '%s'", calcErrorStr(err), expr); - return; - } - if (calcArgUsage(rpn, &vinp, &vout)) { - testFail("calcArgUsage returned error for '%s'", expr); - return; - } - if (!testOk(vinp == einp && vout == eout, "Args for '%s'", expr)) { - testDiag("Expected (%lx, %lx) got (%lx, %lx)", einp, eout, vinp, vout); - } - free(rpn); -} - -void testBadExpr(const char *expr, short expected_err) { - /* Parse an invalid expression, test against expected error code */ - char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); - short err = 0; - - if(!rpn) { - testFail("postfix: %s no memory", expr); - return; - } - - postfix(expr, rpn, &err); - if (!testOk(err == expected_err, "Bad expression '%s'", expr)) { - testDiag("Expected '%s', actually got '%s'", - calcErrorStr(expected_err), calcErrorStr(err)); - calcExprDump(rpn); - } - free(rpn); -} - -/* Test an expression that is also valid C code */ -#define testExpr(expr) testCalc(#expr, expr); - -/* These are the argument bits for testArgs */ -#define A_A 0x001 -#define A_B 0x002 -#define A_C 0x004 -#define A_D 0x008 -#define A_E 0x010 -#define A_F 0x020 -#define A_G 0x040 -#define A_H 0x080 -#define A_I 0x100 -#define A_J 0x200 -#define A_K 0x400 -#define A_L 0x800 - - -/* Macros and functions to make some expressions into valid C code */ - -#ifndef PI -#define PI 3.14159265358979 -#endif -#define Inf epicsINF -#define NaN epicsNAN -#define D2R (PI/180.) -#define R2D (180./PI) -#define ABS(x) fabs(x) -#define AND & -#define ATAN2(x,y) atan2(y,x) -#define LN(x) log(x) -#define LOG(x) log10(x) -#define LOGE(x) log(x) -#define NINT(x) (double)(long)((x) >= 0 ? (x)+0.5 : (x)-0.5) -#define OR | -#define SQR(x) sqrt(x) -#define XOR ^ - -static inline double MAX(double a) { - return a; -} -static inline double MAX(double a, double b) { - return epicsMax(a,b); -} -static inline double MAX(double a, double b, double c) { - return MAX(MAX(a,b),c); -} -static inline double MAX(double a, double b, double c, double d) { - return MAX(MAX(a,b,c),d); -} -static inline double MAX(double a, double b, double c, double d, double e) { - return MAX(MAX(a,b,c,d),e); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f) { - return MAX(MAX(a,b,c,d,e),f); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f, double g) { - return MAX(MAX(a,b,c,d,e,f),g); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f, double g, double h) { - return MAX(MAX(a,b,c,d,e,f,g),h); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f, double g, double h, double i) { - return MAX(MAX(a,b,c,d,e,f,g,h),i); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f, double g, double h, double i, double j) { - return MAX(MAX(a,b,c,d,e,f,g,h,i),j); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f, double g, double h, double i, double j, double k) { - return MAX(MAX(a,b,c,d,e,f,g,h,i,j),k); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f, double g, double h, double i, double j, double k, double l) { - return MAX(MAX(a,b,c,d,e,f,g,h,i,j,k),l); -} - -static inline double MIN(double a) { - return a; -} -static inline double MIN(double a, double b) { - return epicsMin(a,b); -} -static inline double MIN(double a, double b, double c) { - return MIN(MIN(a,b),c); -} -static inline double MIN(double a, double b, double c, double d) { - return MIN(MIN(a,b,c),d); -} -static inline double MIN(double a, double b, double c, double d, double e) { - return MIN(MIN(a,b,c,d),e); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f) { - return MIN(MIN(a,b,c,d,e),f); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f, double g) { - return MIN(MIN(a,b,c,d,e,f),g); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f, double g, double h) { - return MIN(MIN(a,b,c,d,e,f,g),h); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f, double g, double h, double i) { - return MIN(MIN(a,b,c,d,e,f,g,h),i); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f, double g, double h, double i, double j) { - return MIN(MIN(a,b,c,d,e,f,g,h,i),j); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f, double g, double h, double i, double j, double k) { - return MIN(MIN(a,b,c,d,e,f,g,h,i,j),k); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f, double g, double h, double i, double j, double k, double l) { - return MIN(MIN(a,b,c,d,e,f,g,h,i,j,k),l); -} - -/* The test code below generates lots of spurious warnings because - * it's making sure that our operator priorities match those of C. - * Disable them to quieten the compilation process where possible. - */ -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) -# pragma GCC diagnostic ignored "-Wparentheses" -#endif - -MAIN(epicsCalcTest) -{ - int repeat; - const double a=1.0, b=2.0, c=3.0, d=4.0, e=5.0, f=6.0, - g=7.0, h=8.0, i=9.0, j=10.0, k=11.0, l=12.0; - - testPlan(613); - - /* LITERAL_OPERAND elements */ - testExpr(0); - testExpr(1); - testExpr(2); - testExpr(3); - testExpr(4); - testExpr(5); - testExpr(6); - testExpr(7); - testExpr(8); - testExpr(9); - testExpr(.1); - testExpr(0.1); - testExpr(0X0); - testExpr(0x10); - testExpr(0x7fffffff); - testCalc("0x80000000", -2147483648.0); - testCalc("0xffffffff", -1); - testExpr(Inf); - testCalc("Infinity", Inf); - testExpr(NaN); - - /* OPERAND elements */ - testExpr(a); - testExpr(b); - testExpr(c); - testExpr(d); - testExpr(e); - testExpr(f); - testExpr(g); - testExpr(h); - testExpr(i); - testExpr(j); - testExpr(k); - testExpr(l); - testExpr(PI); - testExpr(D2R); - testExpr(R2D); - - for (repeat=0; repeat<100; repeat++) { - double res = doCalc("rndm"); - if (res<0 || res >1) { - testDiag("rndm returned %g", res); - break; - } - } - testOk(repeat == 100, "rndm"); - - /* UNARY_MINUS element */ - testExpr(-1); - testExpr(-Inf); - testExpr(- -1); - testCalc("-0x80000000", 2147483648.0); - - /* UNARY_OPERATOR elements */ - testExpr((1)); - testExpr(!0); - testExpr(!1); - testExpr(!!0); - testExpr(ABS(1.0)); - testExpr(ABS(-1.)); - testExpr(acos(1.)); - testExpr(asin(0.5)); - testExpr(atan(0.5)); - testExpr(ATAN2(1., 2.)); - testExpr(ceil(0.5)); - testExpr(cos(0.5)); - testExpr(cosh(0.5)); - testExpr(exp(1.)); - testExpr(floor(1.5)); - - testExpr(finite(0.)); - testExpr(finite(Inf)); - testExpr(finite(-Inf)); - testExpr(finite(NaN)); - testCalc("finite(0,1,2)", 1); - testCalc("finite(0,1,NaN)", 0); - testCalc("finite(0,NaN,2)", 0); - testCalc("finite(NaN,1,2)", 0); - testCalc("finite(0,1,Inf)", 0); - testCalc("finite(0,Inf,2)", 0); - testCalc("finite(Inf,1,2)", 0); - testCalc("finite(0,1,-Inf)", 0); - testCalc("finite(0,-Inf,2)", 0); - testCalc("finite(-Inf,1,2)", 0); - testExpr(isinf(0.)); - testExpr(isinf(Inf)); - testExpr(!!isinf(-Inf)); // Some GCCs return -1/0/+1 rather than 0/+1 - testExpr(isinf(NaN)); - testExpr(isnan(0.)); - testExpr(isnan(Inf)); - testExpr(isnan(-Inf)); - testExpr(isnan(NaN)); - testCalc("isnan(0,1,2)", 0); - testCalc("isnan(0,1,NaN)", 1); - testCalc("isnan(0,NaN,2)", 1); - testCalc("isnan(NaN,1,2)", 1); - testCalc("isnan(0,1,Inf)", 0); - testCalc("isnan(0,Inf,2)", 0); - testCalc("isnan(Inf,1,2)", 0); - testCalc("isnan(0,1,-Inf)", 0); - testCalc("isnan(0,-Inf,2)", 0); - testCalc("isnan(-Inf,1,2)", 0); - - testExpr(LN(5.)); - testExpr(LOG(5.)); - testExpr(LOGE(2.)); - - testExpr(MAX(-99)); - testExpr(MAX( 1., 2.)); - testExpr(MAX( 1., Inf)); - testExpr(MAX( 1.,-Inf)); - testExpr(MAX( 1., NaN)); - testExpr(MAX( Inf, 1.)); - testExpr(MAX(-Inf, 1.)); - testExpr(MAX( NaN, 1.)); - testExpr(MAX( 1., 2.,3.)); - testExpr(MAX( 1., 3.,2.)); - testExpr(MAX( 2., 1.,3.)); - testExpr(MAX( 2., 3.,1.)); - testExpr(MAX( 3., 1.,2.)); - testExpr(MAX( 3., 2.,1.)); - testExpr(MAX( 1., 2., Inf)); - testExpr(MAX( 1., 2.,-Inf)); - testExpr(MAX( 1., 2., NaN)); - testExpr(MAX( 1., Inf,2.)); - testExpr(MAX( 1.,-Inf,2.)); - testExpr(MAX( 1., NaN,2.)); - testExpr(MAX( Inf, 1.,2.)); - testExpr(MAX(-Inf, 1.,2.)); - testExpr(MAX( NaN, 1.,2.)); - testExpr(MAX( 1., 2., 3., 4.)); - testExpr(MAX( 1., 2., 4., 3.)); - testExpr(MAX( 1., 4., 3., 2.)); - testExpr(MAX( 4., 2., 3., 1.)); - testExpr(MAX( 1., 2., 3.,NaN)); - testExpr(MAX( 1., 2.,NaN, 3.)); - testExpr(MAX( 1.,NaN, 3., 2.)); - testExpr(MAX(NaN, 2., 3., 1.)); - testExpr(MAX( 1., 2., 3., 4., 5.)); - testExpr(MAX( 1., 2., 3., 5., 4.)); - testExpr(MAX( 1., 2., 5., 4., 3.)); - testExpr(MAX( 1., 5., 3., 4., 2.)); - testExpr(MAX( 5., 2., 3., 4., 1.)); - testExpr(MAX( 1., 2., 3., 4.,NaN)); - testExpr(MAX( 1., 2., 3.,NaN, 4.)); - testExpr(MAX( 1., 2.,NaN, 4., 3.)); - testExpr(MAX( 1.,NaN, 3., 4., 2.)); - testExpr(MAX(NaN, 2., 3., 4., 1.)); - testExpr(MAX( 1., 2., 3., 4., 5., 6.)); - testExpr(MAX( 1., 2., 3., 4., 6., 5.)); - testExpr(MAX( 1., 2., 3., 6., 5., 4.)); - testExpr(MAX( 1., 2., 6., 4., 5., 3.)); - testExpr(MAX( 1., 6., 3., 4., 5., 2.)); - testExpr(MAX( 6., 2., 3., 4., 5., 1.)); - testExpr(MAX( 1., 2., 3., 4., 5.,NaN)); - testExpr(MAX( 1., 2., 3., 4.,NaN, 5.)); - testExpr(MAX( 1., 2., 3.,NaN, 5., 4.)); - testExpr(MAX( 1., 2.,NaN, 4., 5., 3.)); - testExpr(MAX( 1.,NaN, 3., 4., 5., 2.)); - testExpr(MAX(NaN, 2., 3., 4., 5., 1.)); - testExpr(MAX( 1., 2., 3., 4., 5.,Inf)); - testExpr(MAX( 1., 2., 3., 4.,Inf, 5.)); - testExpr(MAX( 1., 2., 3.,Inf, 5., 4.)); - testExpr(MAX( 1., 2.,Inf, 4., 5., 3.)); - testExpr(MAX( 1.,Inf, 3., 4., 5., 2.)); - testExpr(MAX(Inf, 2., 3., 4., 5., 1.)); - testExpr(MAX(1,2,3,4,5,6,7,8,9,10,11,12)); - testExpr(MAX(5,4,3,2,1,0,-1,-2,-3,-4,-5,-6)); - testExpr(MAX(-1,1,0)); - - testExpr(MIN(99)); - testExpr(MIN(1.,2.)); - testExpr(MIN(1.,Inf)); - testExpr(MIN(1.,-Inf)); - testExpr(MIN(1.,NaN)); - testExpr(MIN(NaN,1.)); - testExpr(MIN( 1., 2.,3.)); - testExpr(MIN( 1., 3.,2.)); - testExpr(MIN( 2., 1.,3.)); - testExpr(MIN( 2., 3.,1.)); - testExpr(MIN( 3., 1.,2.)); - testExpr(MIN( 3., 2.,1.)); - testExpr(MIN( 1., 2., Inf)); - testExpr(MIN( 1., 2.,-Inf)); - testExpr(MIN( 1., 2., NaN)); - testExpr(MIN( 1., Inf,2.)); - testExpr(MIN( 1.,-Inf,2.)); - testExpr(MIN( 1., NaN,2.)); - testExpr(MIN( Inf, 1.,2.)); - testExpr(MIN(-Inf, 1.,2.)); - testExpr(MIN( NaN, 1.,2.)); - testExpr(MIN( 1., 2., 3., 4.)); - testExpr(MIN( 1., 2., 4., 3.)); - testExpr(MIN( 1., 4., 3., 2.)); - testExpr(MIN( 4., 2., 3., 1.)); - testExpr(MIN( 1., 2., 3.,NaN)); - testExpr(MIN( 1., 2.,NaN, 3.)); - testExpr(MIN( 1.,NaN, 3., 2.)); - testExpr(MIN(NaN, 2., 3., 1.)); - testExpr(MIN( 1., 2., 3., 4., 5.)); - testExpr(MIN( 1., 2., 3., 5., 4.)); - testExpr(MIN( 1., 2., 5., 4., 3.)); - testExpr(MIN( 1., 5., 3., 4., 2.)); - testExpr(MIN( 5., 2., 3., 4., 1.)); - testExpr(MIN( 1., 2., 3., 4.,NaN)); - testExpr(MIN( 1., 2., 3.,NaN, 4.)); - testExpr(MIN( 1., 2.,NaN, 4., 3.)); - testExpr(MIN( 1.,NaN, 3., 4., 2.)); - testExpr(MIN(NaN, 2., 3., 4., 1.)); - testExpr(MIN( 1., 2., 3., 4., 5., 6.)); - testExpr(MIN( 2., 1., 3., 4., 5., 6.)); - testExpr(MIN( 3., 2., 1., 4., 5., 6.)); - testExpr(MIN( 4., 2., 3., 1., 5., 6.)); - testExpr(MIN( 5., 2., 3., 4., 1., 6.)); - testExpr(MIN( 6., 2., 3., 4., 5., 1.)); - testExpr(MIN( 1., 2., 3., 4., 5.,NaN)); - testExpr(MIN( 1., 2., 3., 4.,NaN, 5.)); - testExpr(MIN( 1., 2., 3.,NaN, 5., 4.)); - testExpr(MIN( 1., 2.,NaN, 4., 5., 3.)); - testExpr(MIN( 1.,NaN, 3., 4., 5., 2.)); - testExpr(MIN(NaN, 2., 3., 4., 5., 1.)); - testExpr(MIN( 1., 2., 3., 4., 5.,-Inf)); - testExpr(MIN( 1., 2., 3., 4.,-Inf, 5.)); - testExpr(MIN( 1., 2., 3.,-Inf, 5., 4.)); - testExpr(MIN( 1., 2.,-Inf, 4., 5., 3.)); - testExpr(MIN( 1.,-Inf, 3., 4., 5., 2.)); - testExpr(MIN(-Inf, 2., 3., 4., 5., 1.)); - testExpr(MIN(1,2,3,4,5,6,7,8,9,10,11,12)); - testExpr(MIN(5,4,3,2,1,0,-1,-2,-3,-4,-5,-6)); - testExpr(MIN(1,-1,0)); - testExpr(MAX(MIN(0,2),MAX(0),MIN(3,2,1))); - - testExpr(NINT(0.4)); - testExpr(NINT(0.6)); - testExpr(NINT(-0.4)); - testExpr(NINT(-0.6)); - testExpr(sin(0.5)); - testExpr(sinh(0.5)); - testExpr(SQR(10.)); - testExpr(sqrt(16.)); - testExpr(tan(0.5)); - testExpr(tanh(0.5)); - testExpr(~5); - testExpr(~~5); - - /* BINARY_OPERATOR elements */ - testExpr(0 != 1); - testExpr(0 != 0); - testExpr(1 != 0); - testExpr(1 != 0 != 2); - testExpr(0.0 != Inf); - testExpr(0.0 != -Inf); - testExpr(0.0 != NaN); - testExpr(Inf != 0.0); - testExpr(Inf != Inf); - testExpr(Inf != -Inf); - testExpr(Inf != NaN); - testExpr(-Inf != 0.0); - testExpr(-Inf != Inf); - testExpr(-Inf != -Inf); - testExpr(-Inf != NaN); - testExpr(NaN != 0.0); - testExpr(NaN != Inf); - testExpr(NaN != -Inf); - testExpr(NaN != NaN); - - testCalc("0 # 1", 0 != 1); - testCalc("0 # 0", 0 != 0); - testCalc("1 # 0", 1 != 0); - testCalc("1 # 0 # 2", 1 != 0 != 2); - - testExpr(7 % 4); - testExpr(-7 % 4); - testExpr(63 % 16 % 6) - testCalc("1 % 0", NaN); - - testExpr(7 & 4); - - testExpr(0 && 0); - testExpr(0 && 1); - testExpr(1 && 0); - testExpr(1 && 1); - - testExpr(2 * 2); - testExpr(0.0 * Inf); - testExpr(0.0 * -Inf); - testExpr(0.0 * NaN); - testExpr(Inf * 0.0); - testExpr(Inf * Inf); - testExpr(Inf * -Inf); - testExpr(Inf * NaN); - testExpr(-Inf * 0.0); - testExpr(-Inf * Inf); - testExpr(-Inf * -Inf); - testExpr(-Inf * NaN); - testExpr(NaN * 0.0); - testExpr(NaN * Inf); - testExpr(NaN * -Inf); - testExpr(NaN * NaN); - - testCalc("2 ** 0.2", pow(2., 0.2)); - testCalc("2 ** -0.2", pow(2., -0.2)); - testCalc("-0.2 ** 2", pow(-0.2, 2.)); - testCalc("-0.2 ** -2", pow(-0.2, -2)); - testCalc("2 ** 2 ** 3", pow(pow(2., 2.), 3.)); - - testExpr(0 + 1); - testExpr(0.0 + Inf); - testExpr(0.0 + -Inf); - testExpr(0.0 + NaN); - testExpr(Inf + 0.0); - testExpr(Inf + Inf); -#if defined(_WIN64) && defined(_MSC_VER) - testCalc("Inf + -Inf", NaN); -#else - testExpr(Inf + -Inf); -#endif - testExpr(Inf + NaN); - testExpr(-Inf + 0.0); -#if defined(_WIN64) && defined(_MSC_VER) - testCalc("-Inf + Inf", NaN); -#else - testExpr(-Inf + Inf); -#endif - testExpr(-Inf + -Inf); - testExpr(-Inf + NaN); - testExpr(NaN + 0.0); - testExpr(NaN + Inf); - testExpr(NaN + -Inf); - testExpr(NaN + NaN); - - testExpr(0 - 1); - testExpr(0 - 1 - 2); - testExpr(0.0 - Inf); - testExpr(0.0 - -Inf); - testExpr(0.0 - NaN); - testExpr(Inf - 0.0); - testExpr(Inf - Inf); - testExpr(Inf - -Inf); - testExpr(Inf - NaN); - testExpr(-Inf - 0.0); - testExpr(-Inf - Inf); - testExpr(-Inf - -Inf); - testExpr(-Inf - NaN); - testExpr(NaN - 0.0); - testExpr(NaN - Inf); - testExpr(NaN - -Inf); - testExpr(NaN - NaN); - - testExpr(2.0 / 3.0); - testExpr(1.0 / 2.0 / 3.0); - testExpr(0.0 / Inf); - testExpr(0.0 / -Inf); - testExpr(0.0 / NaN); - testExpr(Inf / 1.0); - testExpr(Inf / Inf); - testExpr(Inf / -Inf); - testExpr(Inf / NaN); - testExpr(-Inf / 1.0); - testExpr(-Inf / Inf); - testExpr(-Inf / -Inf); - testExpr(-Inf / NaN); - testExpr(NaN / 1.0); - testExpr(NaN / Inf); - testExpr(NaN / -Inf); - testExpr(NaN / NaN); - - testExpr(0 < 1); - testExpr(0 < 0); - testExpr(1 < 0); - testExpr(2 < 0 < 2) - testExpr(0.0 < Inf); - testExpr(0.0 < -Inf); - testExpr(0.0 < NaN); - testExpr(Inf < 0.0); - testExpr(Inf < Inf); - testExpr(Inf < -Inf); - testExpr(Inf < NaN); - testExpr(-Inf < 0.0); - testExpr(-Inf < Inf); - testExpr(-Inf < -Inf); - testExpr(-Inf < NaN); - testExpr(NaN < 0.0); - testExpr(NaN < Inf); - testExpr(NaN < -Inf); - testExpr(NaN < NaN); - - testExpr(1 << 2); - testExpr(1 << 3 << 2) - - testExpr(0 <= 1); - testExpr(0 <= 0); - testExpr(1 <= 0); - testExpr(3 <= 2 <= 3) - testExpr(0.0 <= Inf); - testExpr(0.0 <= -Inf); - testExpr(0.0 <= NaN); - testExpr(Inf <= 0.0); - testExpr(Inf <= Inf); - testExpr(Inf <= -Inf); - testExpr(Inf <= NaN); - testExpr(-Inf <= 0.0); - testExpr(-Inf <= Inf); - testExpr(-Inf <= -Inf); - testExpr(-Inf <= NaN); - testExpr(NaN <= 0.0); - testExpr(NaN <= Inf); - testExpr(NaN <= -Inf); - testExpr(NaN <= NaN); - - testCalc("0 = 1", 0 == 1); - testCalc("0 = 0", 0 == 0); - testCalc("1 = 0", 1 == 0); - testCalc("2 = 2 = 1", 2 == 2 == 1); - - testExpr(0 == 1); - testExpr(0 == 0); - testExpr(1 == 0); - testExpr(2 == 2 == 1); - testExpr(0.0 == Inf); - testExpr(0.0 == -Inf); - testExpr(0.0 == NaN); - testExpr(Inf == 0.0); - testExpr(Inf == Inf); - testExpr(Inf == -Inf); - testExpr(Inf == NaN); - testExpr(-Inf == 0.0); - testExpr(-Inf == Inf); - testExpr(-Inf == -Inf); - testExpr(-Inf == NaN); - testExpr(NaN == 0.0); - testExpr(NaN == Inf); - testExpr(NaN == -Inf); - testExpr(NaN == NaN); - - testExpr(0 > 1); - testExpr(0 > 0); - testExpr(1 > 0); - testExpr(2 > 0 > 2); - testExpr(0.0 > Inf); - testExpr(0.0 > -Inf); - testExpr(0.0 > NaN); - testExpr(Inf > 0.0); - testExpr(Inf > Inf); - testExpr(Inf > -Inf); - testExpr(Inf > NaN); - testExpr(-Inf > 0.0); - testExpr(-Inf > Inf); - testExpr(-Inf > -Inf); - testExpr(-Inf > NaN); - testExpr(NaN > 0.0); - testExpr(NaN > Inf); - testExpr(NaN > -Inf); - testExpr(NaN > NaN); - - testExpr(0 >= 1); - testExpr(0 >= 0); - testExpr(1 >= 0); - testExpr(3 >= 2 >= 3); - testExpr(0.0 >= Inf); - testExpr(0.0 >= -Inf); - testExpr(0.0 >= NaN); - testExpr(Inf >= 0.0); - testExpr(Inf >= Inf); - testExpr(Inf >= -Inf); - testExpr(Inf >= NaN); - testExpr(-Inf >= 0.0); - testExpr(-Inf >= Inf); - testExpr(-Inf >= -Inf); - testExpr(-Inf >= NaN); - testExpr(NaN >= 0.0); - testExpr(NaN >= Inf); - testExpr(NaN >= -Inf); - testExpr(NaN >= NaN); - - testExpr(8 >> 1); - testExpr(64 >> 2 >> 1); - - testExpr(7 AND 4); - - testExpr(1 OR 8); - - testExpr(3 XOR 9); - - testCalc("2 ^ 0.2", pow(2., 0.2)); - testCalc("2 ^ -0.2", pow(2., -0.2)); - testCalc("(-0.2) ^ 2", pow(-0.2, 2.)); - testCalc("(-0.2) ^ -2", pow(-0.2, -2.)); - testCalc("2 ^ 2 ^ 3", pow(pow(2., 2.), 3.)); - - testExpr(1 | 8); - - testExpr(0 || 0); - testExpr(0 || 1); - testExpr(1 || 0); - testExpr(1 || 1); - - /* CONDITIONAL elements */ - testExpr(0 ? 1 : 2); - testExpr(1 ? 1 : 2); - testExpr(Inf ? 1 : 2); - testExpr(NaN ? 1 : 2); - testExpr(0 ? 0 ? 2 : 3 : 4); - testExpr(0 ? 1 ? 2 : 3 : 4); - testExpr(1 ? 0 ? 2 : 3 : 4); - testExpr(1 ? 1 ? 2 : 3 : 4); - testExpr(0 ? 2 : 0 ? 3 : 4); - testExpr(0 ? 2 : 1 ? 3 : 4); - testExpr(1 ? 2 : 0 ? 3 : 4); - testExpr(1 ? 2 : 1 ? 3 : 4); - - /* STORE_OPERATOR and EXPR_TERM elements*/ - testCalc("a := 0; a", 0); - testCalc("b := 0; b", 0); - testCalc("c := 0; c", 0); - testCalc("d := 0; d", 0); - testCalc("e := 0; e", 0); - testCalc("f := 0; f", 0); - testCalc("g := 0; g", 0); - testCalc("h := 0; h", 0); - testCalc("i := 0; i", 0); - testCalc("j := 0; j", 0); - testCalc("k := 0; k", 0); - testCalc("l := 0; l", 0); - - testCalc("a; a := 0", a); - testCalc("b; b := 0", b); - testCalc("c; c := 0", c); - testCalc("d; d := 0", d); - testCalc("e; e := 0", e); - testCalc("f; f := 0", f); - testCalc("g; g := 0", g); - testCalc("h; h := 0", h); - testCalc("i; i := 0", i); - testCalc("j; j := 0", j); - testCalc("k; k := 0", k); - testCalc("l; l := 0", l); - - // Check relative precedences. - testExpr(0 ? 1 : 2 | 4); // 0 1 - testExpr(1 ? 1 : 2 | 4); // 0 1 - testExpr(0 ? 2 | 4 : 1); // 0 1 - testExpr(1 ? 2 | 4 : 1); // 0 1 - testExpr(0 ? 1 : 2 & 3); // 0 2 - testExpr(1 ? 1 : 2 & 3); // 0 2 - testExpr(0 ? 2 & 3 : 1); // 0 2 - testExpr(1 ? 2 & 3 : 1); // 0 2 - testExpr(0 ? 2 : 3 >= 1); // 0 3 - testExpr(0 ? 3 >= 1 : 2); // 0 3 - testExpr(1 ? 0 == 1 : 2); // 0 3 - testExpr(1 ? 2 : 0 == 1); // 0 3 - testExpr(0 ? 1 : 2 + 4); // 0 4 - testExpr(1 ? 1 : 2 + 4); // 0 4 - testExpr(0 ? 2 + 4 : 1); // 0 4 - testExpr(1 ? 2 + 4 : 1); // 0 4 - testExpr(0 ? 1 : 2 * 4); // 0 5 - testExpr(1 ? 1 : 2 * 4); // 0 5 - testExpr(0 ? 2 * 4 : 1); // 0 5 - testExpr(1 ? 2 * 4 : 1); // 0 5 - testCalc("0 ? 1 : 2 ** 3", 8); // 0 6 - testCalc("1 ? 1 : 2 ** 3", 1); // 0 6 - testCalc("0 ? 2 ** 3 : 1", 1); // 0 6 - testCalc("1 ? 2 ** 3 : 1", 8); // 0 6 - testCalc("1 | 3 XOR 1", (1 | 3) ^ 1); // 1 1 - testExpr(1 XOR 3 | 1); // 1 1 - testExpr(3 | 1 & 2); // 1 2 - testExpr(2 | 4 > 3); // 1 3 - testExpr(2 OR 4 > 3); // 1 3 - testExpr(2 XOR 3 >= 0); // 1 3 - testExpr(2 | 1 - 3); // 1 4 - testExpr(2 | 4 / 2); // 1 5 - testCalc("1 | 2 ** 3", 1 | (int) pow(2., 3.));// 1 6 - testExpr(3 << 2 & 10); // 2 2 - testCalc("18 & 6 << 2", (18 & 6) << 2); // 2 2 - testExpr(36 >> 2 & 10); // 2 2 - testCalc("18 & 20 >> 2", (18 & 20) >> 2); // 2 2 - testExpr(3 & 4 == 4); // 2 3 - testExpr(3 AND 4 == 4); // 2 3 - testCalc("1 << 2 != 4", 1 << (2 != 4)); // 2 3 - testCalc("16 >> 2 != 4", 16 >> (2 != 4)); // 2 3 - testExpr(3 AND -2); // 2 8 - testExpr(0 < 1 ? 2 : 3); // 3 0 - testExpr(1 <= 0 ? 2 : 3); // 3 0 - testExpr(0 + -1); // 4 8 - testExpr(0 - -1); // 4 8 - testExpr(10 + 10 * 2); // 4 5 - testExpr(20 + 20 / 2); // 4 5 - testExpr(-1 + 1); // 7 4 - testExpr(-1 - 2); // 7 4 - testCalc("-2 ** 2", pow(-2., 2.)); // 7 6 - testCalc("-2 ^ 2", pow(-2., 2.)); // 7 6 - - // Check parentheses - testCalc("(1 | 2) ** 3", pow((double) (1 | 2), 3.));// 8 6 - testCalc("1+(1|2)**3", 1+pow((double) (1 | 2), 3.));// 8 6 - testExpr(1+(1?(1<2):(1>2))*2); - - testArgs("a", A_A, 0); - testArgs("A", A_A, 0); - testArgs("B", A_B, 0); - testArgs("C", A_C, 0); - testArgs("D", A_D, 0); - testArgs("E", A_E, 0); - testArgs("F", A_F, 0); - testArgs("G", A_G, 0); - testArgs("H", A_H, 0); - testArgs("I", A_I, 0); - testArgs("J", A_J, 0); - testArgs("K", A_K, 0); - testArgs("L", A_L, 0); - testArgs("A+B+C+D+E+F+G+H+I+J+K+L", - A_A|A_B|A_C|A_D|A_E|A_F|A_G|A_H|A_I|A_J|A_K|A_L, 0); - testArgs("0.1;A:=0", 0, A_A); - testArgs("1.1;B:=0", 0, A_B); - testArgs("2.1;C:=0", 0, A_C); - testArgs("3.1;D:=0", 0, A_D); - testArgs("4.1;E:=0", 0, A_E); - testArgs("5.1;F:=0", 0, A_F); - testArgs("6.1;G:=0", 0, A_G); - testArgs("7.1;H:=0", 0, A_H); - testArgs("8.1;I:=0", 0, A_I); - testArgs("9.1;J:=0", 0, A_J); - testArgs("10.1;K:=0", 0, A_K); - testArgs("11.1;L:=0", 0, A_L); - testArgs("12.1;A:=0;B:=A;C:=B;D:=C", 0, A_A|A_B|A_C|A_D); - testArgs("13.1;B:=A;A:=B;C:=D;D:=C", A_A|A_D, A_A|A_B|A_C|A_D); - - // Malformed expressions - testBadExpr("0x0.1", CALC_ERR_SYNTAX); - testBadExpr("1*", CALC_ERR_INCOMPLETE); - testBadExpr("*1", CALC_ERR_SYNTAX); - testBadExpr("MIN", CALC_ERR_INCOMPLETE); - testBadExpr("MIN()", CALC_ERR_SYNTAX); - testBadExpr("MIN(A,)", CALC_ERR_SYNTAX); - testBadExpr("MIN(A,B,)", CALC_ERR_SYNTAX); - testBadExpr("MAX", CALC_ERR_INCOMPLETE); - testBadExpr("MAX()", CALC_ERR_SYNTAX); - testBadExpr("MAX(A,)", CALC_ERR_SYNTAX); - testBadExpr("MAX(A,B,)", CALC_ERR_SYNTAX); - testBadExpr("1?", CALC_ERR_CONDITIONAL); - testBadExpr("1?1", CALC_ERR_CONDITIONAL); - testBadExpr(":1", CALC_ERR_SYNTAX); - - // Bit manipulations wrt bit 31 (bug lp:1514520) - // using integer literals - testUInt32Calc("0xaaaaaaaa AND 0xffff0000", 0xaaaa0000u); - testUInt32Calc("0xaaaaaaaa OR 0xffff0000", 0xffffaaaau); - testUInt32Calc("0xaaaaaaaa XOR 0xffff0000", 0x5555aaaau); - testUInt32Calc("~0xaaaaaaaa", 0x55555555u); - testUInt32Calc("~~0xaaaaaaaa", 0xaaaaaaaau); - testUInt32Calc("0xaaaaaaaa >> 8", 0xffaaaaaau); - testUInt32Calc("0xaaaaaaaa << 8", 0xaaaaaa00u); - // using integer literals assigned to variables - testUInt32Calc("a:=0xaaaaaaaa; b:=0xffff0000; a AND b", 0xaaaa0000u); - testUInt32Calc("a:=0xaaaaaaaa; b:=0xffff0000; a OR b", 0xffffaaaau); - testUInt32Calc("a:=0xaaaaaaaa; b:=0xffff0000; a XOR b", 0x5555aaaau); - testUInt32Calc("a:=0xaaaaaaaa; ~a", 0x55555555u); - testUInt32Calc("a:=0xaaaaaaaa; ~~a", 0xaaaaaaaau); - testUInt32Calc("a:=0xaaaaaaaa; a >> 8", 0xffaaaaaau); - testUInt32Calc("a:=0xaaaaaaaa; a << 8", 0xaaaaaa00u); - - // Test proper conversion of double values (+ 0.1 enforces double literal) - // when used as inputs to the bitwise operations. - // 0xaaaaaaaa = -1431655766 or 2863311530u - testUInt32Calc("-1431655766.1 OR 0", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 OR 0", 0xaaaaaaaau); - testUInt32Calc("0 OR -1431655766.1", 0xaaaaaaaau); - testUInt32Calc("0 OR 2863311530.1", 0xaaaaaaaau); - testUInt32Calc("-1431655766.1 XOR 0", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 XOR 0", 0xaaaaaaaau); - testUInt32Calc("0 XOR -1431655766.1", 0xaaaaaaaau); - testUInt32Calc("0 XOR 2863311530.1", 0xaaaaaaaau); - testUInt32Calc("-1431655766.1 AND 0xffffffff", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 AND 0xffffffff", 0xaaaaaaaau); - testUInt32Calc("0xffffffff AND -1431655766.1", 0xaaaaaaaau); - testUInt32Calc("0xffffffff AND 2863311530.1", 0xaaaaaaaau); - testUInt32Calc("~ -1431655766.1", 0x55555555u); - testUInt32Calc("~ 2863311530.1", 0x55555555u); - testUInt32Calc("-1431655766.1 >> 0", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 >> 0", 0xaaaaaaaau); - testUInt32Calc("-1431655766.1 >> 0.1", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 >> 0.1", 0xaaaaaaaau); - testUInt32Calc("-1431655766.1 << 0", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 << 0", 0xaaaaaaaau); - testUInt32Calc("-1431655766.1 << 0.1", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 << 0.1", 0xaaaaaaaau); - - return testDone(); -} - diff --git a/src/libCom/test/epicsEllTest.c b/src/libCom/test/epicsEllTest.c deleted file mode 100644 index 62ee14e39..000000000 --- a/src/libCom/test/epicsEllTest.c +++ /dev/null @@ -1,268 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 Michael Davidsaver -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "ellLib.h" -#include "dbDefs.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -struct myItem { - ELLNODE node; - int list; - int num; -}; - -static void testList(void) -{ - ELLLIST list1; - ELLLIST list2 = ELLLIST_INIT; - int i1 = 1; - struct myItem *pitem, *pfirst, *pick; - - list1.count = 27; - list1.node.next = (ELLNODE *) 0x01010101; - list1.node.previous = (ELLNODE *) 0x10101010; - - ellInit(&list1); - testOk1(list1.count == 0); - testOk1(list1.node.next == NULL); - testOk1(list1.node.previous == NULL); - - testOk1(list2.count == 0); - testOk1(list2.node.next == NULL); - testOk1(list2.node.previous == NULL); - - /* First build a couple lists and fill them with nodes. */ - pitem = (struct myItem *) malloc(sizeof(struct myItem)); - pitem->node.next = (ELLNODE *) 0x10101010; - pitem->node.previous = (ELLNODE *) 0x10101010; - pitem->list = 1; - pitem->num = i1++; - - ellAdd(&list1, &pitem->node); - - testOk1(list1.count == 1); - testOk1(list1.node.next == &pitem->node); - testOk1(list1.node.previous == &pitem->node); - testOk1(pitem->node.next == NULL); - testOk1(pitem->node.previous == NULL); - - pfirst = pitem; - while (i1 <= 21) { /* put 21 nodes into LIST1 */ - pitem = (struct myItem *) malloc(sizeof(struct myItem)); - pitem->list = 1; - pitem->num = i1++; - ellAdd(&list1, &pitem->node); - } - - testOk1(list1.count == 21); - testOk1(list1.node.next == &pfirst->node); - testOk1(list1.node.previous == &pitem->node); - testOk1(pitem->node.next == NULL); - - testOk1(ellFirst(&list1) == &pfirst->node); - testOk1(ellLast(&list1) == &pitem->node); - testOk1(ellNext(&pitem->node) == NULL); - testOk1(ellNext(&pfirst->node) == pfirst->node.next); - - testOk1(ellNth(&list1, 0) == NULL); - - pick = (struct myItem *)ellNth(&list1, 21); - testOk1(pick == pitem); - - testOk1(ellNth(&list1, 22) == NULL); - testOk1(ellNth(&list1, 1) == &pfirst->node); - testOk1(ellNth(&list1, 2) == pfirst->node.next); - testOk1(ellNth(&list1, 20) == pitem->node.previous); - - testOk1(ellPrevious(&pitem->node) == pitem->node.previous); - testOk1(ellPrevious(&pfirst->node) == NULL); - testOk1(ellPrevious(pfirst->node.next) == &pfirst->node); - - pick = (struct myItem *)ellGet(&list1); - testOk1(pick == pfirst); - testOk1(list1.node.next == pfirst->node.next); - - ellAdd(&list2, &pick->node); - - pick = (struct myItem *)ellGet(&list2); - testOk1(pick == pfirst); - testOk1(list2.node.next == NULL); - testOk1(list2.node.previous == NULL); - - testOk1(ellCount(&list1) == 20); - testOk1(ellCount(&list2) == 0); - - ellConcat(&list1, &list2); - - testOk1(ellCount(&list1) == 20); - testOk1(ellCount(&list2) == 0); - testOk1(list1.node.previous == &pitem->node); - - ellAdd(&list2, &pick->node); - ellConcat(&list1, &list2); - - testOk1(ellCount(&list1) == 21); - testOk1(ellCount(&list2) == 0); - testOk1(list1.node.previous == &pick->node); - testOk1(list2.node.next == NULL); - testOk1(list2.node.previous == NULL); - - ellDelete(&list1, &pick->node); - testOk1(ellCount(&list1) == 20); - - ellAdd(&list2, &pick->node); - ellConcat(&list2, &list1); - testOk1(ellFind(&list1, &pick->node) == -1); /* empty list */ - testOk1(ellFind(&list2, &pick->node) == pick->num); /* first node */ - - pick = (struct myItem *)ellNth(&list2, 18); - testOk1(ellFind(&list2, &pick->node) == 18); /* 18th node */ - - ellDelete(&list2, &pick->node); - ellInsert(&list2, NULL, &pick->node); /* move #18 to top */ - testOk1(ellCount(&list2) == 21); - testOk1(((struct myItem *)list2.node.next)->num == 18); - - testOk1(ellFind(&list2, ellNth(&list2, 21)) == 21); - - pick = (struct myItem *)ellGet(&list2); - pitem = (struct myItem *)ellNth(&list2, 17); - ellInsert(&list2, &pitem->node, &pick->node); - testOk1(ellFind(&list2, ellNth(&list2, 21)) == 21); - - testOk1(((struct myItem *)ellFirst(&list2))->num == 1); - testOk1(((struct myItem *)ellNth(&list2,17))->num == 17); - testOk1(((struct myItem *)ellNth(&list2,18))->num == 18); - - pick = (struct myItem *)ellLast(&list2); - pitem = (struct myItem *) malloc(sizeof(struct myItem)); - ellInsert(&list2, &pick->node, &pitem->node); - testOk1(ellCount(&list2) == 22); - testOk1(ellFind(&list2, ellNth(&list2, 22)) == 22); - - ellDelete(&list2, &pitem->node); - free(pitem); - - ellExtract(&list2, ellNth(&list2,9), ellNth(&list2, 19), &list1); - testOk1(ellCount(&list2) == 10); - testOk1(ellCount(&list1) == 11); - - testOk1(ellFind(&list2, ellNth(&list2, 10)) == 10); - testOk1(ellFind(&list1, ellNth(&list1, 11)) == 11); - - ellFree(&list2); - testOk1(ellCount(&list2) == 0); - - pick = (struct myItem *)ellFirst(&list1); - i1 = 1; - while(pick != NULL) { - pick->num = i1++; - pick = (struct myItem *)ellNext(&pick->node); - } - pick = (struct myItem *)ellFirst(&list1); - testOk1(pick != NULL); - - pitem = (struct myItem *)ellNStep(&pick->node, 3); - testOk1(pitem != NULL); - testOk1(pitem->num == 4); - - pitem = (struct myItem *)ellNStep(&pick->node, 30); - testOk1(pitem == NULL); - - pitem = (struct myItem *)ellNStep(&pick->node, 10); - testOk1(pitem != NULL); - testOk1(pitem->num == 11); - - pitem = (struct myItem *)ellNStep(&pitem->node, 0); - testOk1(pitem->num == 11); - - pitem = (struct myItem *)ellNStep(&pitem->node, -4); - testOk1(pitem->num == 7); - - ellFree2(&list1, free); - testOk1(ellCount(&list1) == 0); -} - -typedef struct { int A, B; } input_t; - -static int myItemCmp(const ELLNODE *a, const ELLNODE *b) -{ - struct myItem *A = CONTAINER(a, struct myItem, node), - *B = CONTAINER(b, struct myItem, node); - - if (A->num < B->num) return -1; - else if(A->num > B->num) return 1; - else if(A->list < B->list) return -1; - else if(A->list > B->list) return 1; - else return 0; -} - -static const input_t input[] = { - {-4, 0}, - {-5, 0}, - {0,0}, - {50,0}, - {0,1}, - {5,0}, - {5,1} -}; - -static -void testSort(const input_t *inp, size_t ninp) -{ - unsigned i; - ELLLIST list = ELLLIST_INIT; - struct myItem *alloc = calloc(ninp, sizeof(*alloc)); - - if(!alloc) testAbort("testSort allocation fails"); - - for(i=0; inum = inp[i].A; - it->list= inp[i].B; - - ellAdd(&list, &it->node); - } - - ellSortStable(&list, &myItemCmp); - - testOk(ellCount(&list)==ninp, "output length %u == %u", (unsigned)ellCount(&list), (unsigned)ninp); - if(ellCount(&list)==0) { - testSkip(ninp-1, "all items lost"); - } - - { - struct myItem *prev = CONTAINER(ellFirst(&list), struct myItem, node), - *next; - - for(next = CONTAINER(ellNext(&prev->node), struct myItem, node); - next; - prev = next, next = CONTAINER(ellNext(&next->node), struct myItem, node)) - { - int cond = (prev->numnum) || (prev->num==next->num && prev->listlist); - testOk(cond, "%d:%d < %d:%d", prev->num, prev->list, next->num, next->list); - } - } -} - -MAIN(epicsEllTest) -{ - testPlan(77); - - testList(); - testSort(input, NELEMENTS(input)); - - return testDone(); -} diff --git a/src/libCom/test/epicsEnvTest.c b/src/libCom/test/epicsEnvTest.c deleted file mode 100644 index bbce4b749..000000000 --- a/src/libCom/test/epicsEnvTest.c +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsEnvTest.c */ - -/* Author: Andrew Johnson - * Date: 2013-12-13 - */ - -/* Check environment variable APIs. - * TODO: Add tests for envDefs.h routines. - * - * The thread test is needed on VxWorks 6.x, where the OS can be - * configured to maintain separate, totally independent sets - * of environment variables for each thread. This configuration - * is not supported by EPICS which expects child threads to at - * least inherit the partent thread's environment variables. - */ - -#include -#include - -#include "envDefs.h" -#include "epicsThread.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#define PARENT "Parent" -#define CHILD "Child" - -static void child(void *arg) -{ - const char *value = getenv(PARENT); - - if (!testOk(value && (strcmp(value, PARENT) == 0), - "Child thread sees parent environment values")) { -#ifdef vxWorks - testDiag("VxWorks image needs ENV_VAR_USE_HOOKS configured as FALSE"); -#else - testDiag("Check OS configuration, environment inheritance needed"); -#endif - } - - epicsEnvSet(CHILD, CHILD); -} - -MAIN(epicsEnvTest) -{ - unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - const char *value; - - testPlan(3); - - epicsEnvSet(PARENT, PARENT); - - value = getenv(PARENT); - if (!testOk(value && (strcmp(value, PARENT) == 0), - "epicsEnvSet correctly modifies environment")) - testAbort("environment variables not working"); - - epicsThreadCreate("child", 50, stackSize, child, NULL); - epicsThreadSleep(0.1); - - value = getenv(CHILD); - if (value && (strcmp(value, CHILD) == 0)) - testDiag("Child and parent threads share a common environment"); - - value = getenv(PARENT); - testOk(value && (strcmp(value, PARENT) == 0), - "PARENT environment variable not modified"); - - testDone(); - return 0; -} - diff --git a/src/libCom/test/epicsErrlogTest.c b/src/libCom/test/epicsErrlogTest.c deleted file mode 100644 index 28d88f6af..000000000 --- a/src/libCom/test/epicsErrlogTest.c +++ /dev/null @@ -1,489 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Michael Davidsaver - * Date: 2010-09-24 - */ - -#include -#include -#include - -#include "epicsAssert.h" -#include "epicsThread.h" -#include "epicsEvent.h" -#include "dbDefs.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" -#include "iocLog.h" -#include "logClient.h" -#include "envDefs.h" -#include "osiSock.h" -#include "fdmgr.h" - -#define LOGBUFSIZE 2048 - -static -const char longmsg[]="A0123456789abcdef" - "B0123456789abcdef" - "C0123456789abcdef" - "D0123456789abcdef" - "E0123456789abcdef" - "F0123456789abcdef" - "G0123456789abcdef" - "H0123456789abcdef" - "I0123456789abcdef" - "J0123456789abcdef" - "K0123456789abcdef" - "L0123456789abcdef" - "M0123456789abcdef" - "N0123456789abcdef" - "O0123456789abcdef" - "P0123456789abcdef" - "Q0123456789abcdef" - "R0123456789abcdef" - "S0123456789abcdef" - ; -STATIC_ASSERT(NELEMENTS(longmsg)==324); - -static -const char truncmsg[]="A0123456789abcdef" - "B0123456789abcdef" - "C0123456789abcdef" - "D0123456789abcdef" - "E0123456789abcdef" - "F0123456789abcdef" - "G0123456789abcdef" - "H0123456789abcdef" - "I0123456789abcdef" - "J0123456789abcdef" - "K0123456789abcdef" - "L0123456789abcdef" - "M0123456789abcdef" - "N0123456789abcdef" - "O01<>\n" - ; -STATIC_ASSERT(NELEMENTS(truncmsg)==256); - -typedef struct { - unsigned int count; - const char* expect; - size_t checkLen; - epicsEventId jammer; - int jam; -} clientPvt; - -static void testLogPrefix(void); -static void acceptNewClient( void *pParam ); -static void readFromClient( void *pParam ); -static void testPrefixLogandCompare( const char* logmessage); - -static void *pfdctx; -static SOCKET sock; -static SOCKET insock; - -static const char* prefixactualmsg[]= { - "A message without prefix", - "A message with prefix", - "DONE" - }; -static const char *prefixstring = "fac=LI21 "; -static const char prefixexpectedmsg[] = "A message without prefix" - "fac=LI21 A message with prefix" - "fac=LI21 DONE" - ; -static char prefixmsgbuffer[1024]; - - -static -void testEqInt_(int lhs, int rhs, const char *LHS, const char *RHS) -{ - testOk(lhs==rhs, "%s (%d) == %s (%d)", LHS, lhs, RHS, rhs); -} -#define testEqInt(L, R) testEqInt_(L, R, #L, #R); -static -void logClient(void* raw, const char* msg) -{ - clientPvt *pvt = raw; - size_t len; - char show[46]; - - /* Simulate thread priority on non-realtime - * OSs like Linux. This will cause the logging - * thread to sleep with the buffer lock held. - */ - if (pvt->jam > 0) { - pvt->jam = 0; - epicsEventMustWait(pvt->jammer); - } else if (pvt->jam < 0) { - pvt->jam++; - if (pvt->jam == 0) - epicsEventMustWait(pvt->jammer); - } - - len = strlen(msg); - if (len > 45) { - /* Only show start and end of long messages */ - strncpy(show, msg, 20); - show[20] = 0; - strcat(show + 20, " ... "); - strcat(show + 25, msg + len - 20); - } - else { - strcpy(show, msg); - } - - if (pvt->checkLen) - if (!testOk(pvt->checkLen == len, "Received %d chars", (int) len)) { - testDiag("Expected %d", (int) pvt->checkLen); - if (!pvt->expect) - testDiag("Message is \"%s\"", show); - } - - if (pvt->expect) { - if (!testOk(strcmp(pvt->expect, msg) == 0, "Message is \"%s\"", show)) { - len = strlen(pvt->expect); - if (len > 45) { - testDiag("Expected \"%.20s ... %s\"", - pvt->expect, pvt->expect + len - 20); - } - else { - testDiag("Expected \"%s\"", pvt->expect); - } - } - } - - pvt->count++; -} - -MAIN(epicsErrlogTest) -{ - size_t mlen, i, N; - char msg[256]; - clientPvt pvt, pvt2; - - testPlan(32); - - strcpy(msg, truncmsg); - - errlogInit2(LOGBUFSIZE, 256); - - pvt.count = 0; - pvt2.count = 0; - - pvt.expect = NULL; - pvt2.expect = NULL; - - pvt.checkLen = 0; - pvt2.checkLen = 0; - - pvt.jam = 0; - pvt2.jam = 0; - - pvt.jammer = epicsEventMustCreate(epicsEventEmpty); - pvt2.jammer = epicsEventMustCreate(epicsEventEmpty); - - testDiag("Check listener registration"); - - errlogAddListener(&logClient, &pvt); - - pvt.expect = "Testing"; - pvt.checkLen = strlen(pvt.expect); - - errlogPrintfNoConsole("%s", pvt.expect); - errlogFlush(); - - testEqInt(pvt.count, 1); - - errlogAddListener(&logClient, &pvt2); - - pvt2.expect = pvt.expect = "Testing2"; - pvt2.checkLen = pvt.checkLen = strlen(pvt.expect); - - errlogPrintfNoConsole("%s", pvt.expect); - errlogFlush(); - - testEqInt(pvt.count, 2); - testEqInt(pvt2.count, 1); - - /* Removes the first listener */ - testOk(1 == errlogRemoveListeners(&logClient, &pvt), - "Removed 1 listener"); - - pvt2.expect = "Testing3"; - pvt2.checkLen = strlen(pvt2.expect); - - errlogPrintfNoConsole("%s", pvt2.expect); - errlogFlush(); - - testEqInt(pvt.count, 2); - testEqInt(pvt2.count, 2); - - /* Add the second listener again, then remove both instances */ - errlogAddListener(&logClient, &pvt2); - testOk(2 == errlogRemoveListeners(&logClient, &pvt2), - "Removed 2 listeners"); - - errlogPrintfNoConsole("Something different"); - errlogFlush(); - - testEqInt(pvt.count, 2); - testEqInt(pvt2.count, 2); - - /* Re-add one listener */ - errlogAddListener(&logClient, &pvt); - - testDiag("Check truncation"); - - pvt.expect = truncmsg; - pvt.checkLen = 255; - - errlogPrintfNoConsole("%s", longmsg); - errlogFlush(); - - testEqInt(pvt.count, 3); - - pvt.expect = NULL; - - testDiag("Check priority"); - /* For the following tests it is important that - * the buffer should not flush until we request it - */ - pvt.jam = 1; - - errlogPrintfNoConsole("%s", longmsg); - epicsThreadSleep(0.1); - - testEqInt(pvt.count, 3); - - epicsEventSignal(pvt.jammer); - errlogFlush(); - - testEqInt(pvt.count, 4); - - testDiag("Find buffer capacity (%u theoretical)",LOGBUFSIZE); - - pvt.checkLen = 0; - - for (mlen = 8; mlen <= 255; mlen *= 2) { - double eff; - char save = msg[mlen - 1]; - - N = LOGBUFSIZE / mlen; /* # of of messages to send */ - msg[mlen - 1] = '\0'; - pvt.count = 0; - /* pvt.checkLen = mlen - 1; */ - - pvt.jam = 1; - - for (i = 0; i < N; i++) { - errlogPrintfNoConsole("%s", msg); - } - - epicsEventSignal(pvt.jammer); - errlogFlush(); - - eff = (double) (pvt.count * mlen) / LOGBUFSIZE * 100.0; - testDiag(" For %d messages of length %d got %u (%.1f%% efficient)", - (int) N, (int) mlen, pvt.count, eff); - - msg[mlen - 1] = save; - N = pvt.count; /* Save final count for the test below */ - - /* Clear "errlog: messages were discarded" status */ - pvt.checkLen = 0; - errlogPrintfNoConsole("."); - errlogFlush(); - } - - testDiag("Checking buffer use after partial flush"); - - /* Use the numbers from the largest block size above */ - mlen /= 2; - msg[mlen - 1] = '\0'; - - pvt.jam = 1; - pvt.count = 0; - - testDiag("Filling with %d messages of size %d", (int) N, (int) mlen); - - for (i = 0; i < N; i++) { - errlogPrintfNoConsole("%s", msg); - } - epicsThreadSleep(0.1); /* should really be a second Event */ - - testEqInt(pvt.count, 0); - - /* Extract the first 2 messages, 2*(sizeof(msgNode) + 128) bytes */ - pvt.jam = -2; - epicsEventSignal(pvt.jammer); - epicsThreadSleep(0.1); - - testDiag("Drained %u messages", pvt.count); - testEqInt(pvt.count, 2); - - /* The buffer has space for 1 more message: sizeof(msgNode) + 256 bytes */ - errlogPrintfNoConsole("%s", msg); /* Use up that space */ - - testDiag("Overflow the buffer"); - errlogPrintfNoConsole("%s", msg); - - testEqInt(pvt.count, 2); - - epicsEventSignal(pvt.jammer); /* Empty */ - errlogFlush(); - - testDiag("Logged %u messages", pvt.count); - testEqInt(pvt.count, N+1); - - /* Clean up */ - testOk(1 == errlogRemoveListeners(&logClient, &pvt), - "Removed 1 listener"); - - testLogPrefix(); - - return testDone(); -} -/* - * Tests the log prefix code - * The prefix is only applied to log messages as they go out to the socket, - * so we need to create a server listening on a port, accept connections etc. - * This code is a reduced version of the code in iocLogServer. - */ -static void testLogPrefix(void) { - struct sockaddr_in serverAddr; - int status; - struct timeval timeout; - struct sockaddr_in actualServerAddr; - osiSocklen_t actualServerAddrSize; - char portstring[16]; - - - testDiag("Testing iocLogPrefix"); - - timeout.tv_sec = 5; /* in seconds */ - timeout.tv_usec = 0; - - memset((void*)prefixmsgbuffer, 0, sizeof prefixmsgbuffer); - - /* Clear "errlog: messages were discarded" status */ - errlogPrintfNoConsole("."); - errlogFlush(); - - sock = epicsSocketCreate(AF_INET, SOCK_STREAM, 0); - if (sock == INVALID_SOCKET) { - testAbort("epicsSocketCreate failed."); - } - - /* We listen on a an available port. */ - memset((void *)&serverAddr, 0, sizeof serverAddr); - serverAddr.sin_family = AF_INET; - serverAddr.sin_port = htons(0); - - status = bind (sock, (struct sockaddr *)&serverAddr, - sizeof (serverAddr) ); - if (status < 0) { - testAbort("bind failed; all ports in use?"); - } - - status = listen(sock, 10); - if (status < 0) { - testAbort("listen failed!"); - } - - /* Determine the port that the OS chose */ - actualServerAddrSize = sizeof actualServerAddr; - memset((void *)&actualServerAddr, 0, sizeof serverAddr); - status = getsockname(sock, (struct sockaddr *) &actualServerAddr, - &actualServerAddrSize); - if (status < 0) { - testAbort("Can't find port number!"); - } - - sprintf(portstring, "%d", ntohs(actualServerAddr.sin_port)); - testDiag("Listening on port %s", portstring); - - /* Set the EPICS environment variables for logging. */ - epicsEnvSet ( "EPICS_IOC_LOG_INET", "localhost" ); - epicsEnvSet ( "EPICS_IOC_LOG_PORT", portstring ); - - pfdctx = (void *) fdmgr_init(); - if (status < 0) { - testAbort("fdmgr_init failed!"); - } - - status = fdmgr_add_callback(pfdctx, sock, fdi_read, - acceptNewClient, &serverAddr); - - if (status < 0) { - testAbort("fdmgr_add_callback failed!"); - } - - testOk1(iocLogInit() == 0); - fdmgr_pend_event(pfdctx, &timeout); - - testPrefixLogandCompare(prefixactualmsg[0]); - - iocLogPrefix(prefixstring); - testPrefixLogandCompare(prefixactualmsg[1]); - testPrefixLogandCompare(prefixactualmsg[2]); - epicsSocketDestroy(sock); -} - -static void testPrefixLogandCompare( const char* logmessage ) { - struct timeval timeout; - timeout.tv_sec = 5; /* in seconds */ - timeout.tv_usec = 0; - - errlogPrintfNoConsole("%s", logmessage); - errlogFlush(); - iocLogFlush(); - fdmgr_pend_event(pfdctx, &timeout); -} - -static void acceptNewClient ( void *pParam ) -{ - osiSocklen_t addrSize; - struct sockaddr_in addr; - int status; - - addrSize = sizeof ( addr ); - insock = epicsSocketAccept ( sock, (struct sockaddr *)&addr, &addrSize ); - testOk(insock != INVALID_SOCKET && addrSize >= sizeof (addr), - "Accepted new client"); - - status = fdmgr_add_callback(pfdctx, insock, fdi_read, - readFromClient, NULL); - - testOk(status >= 0, "Client read configured"); -} - -static void readFromClient(void *pParam) -{ - char recvbuf[1024]; - int recvLength; - - memset(recvbuf, 0, 1024); - recvLength = recv(insock, recvbuf, 1024, 0); - if (recvLength > 0) { - strcat(prefixmsgbuffer, recvbuf); - - /* If we have received all of the messages. */ - if (strstr(prefixmsgbuffer, "DONE") != NULL) { - size_t msglen = strlen(prefixexpectedmsg); - int prefixcmp = strncmp(prefixexpectedmsg, prefixmsgbuffer, msglen); - - if (!testOk(prefixcmp == 0, "prefix matches")) { - testDiag("Expected '%s'\n", prefixexpectedmsg); - testDiag("Obtained '%s'\n", prefixmsgbuffer); - } - } - } -} diff --git a/src/libCom/test/epicsEventTest.cpp b/src/libCom/test/epicsEventTest.cpp deleted file mode 100644 index 7c1a24141..000000000 --- a/src/libCom/test/epicsEventTest.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsEventTest.cpp */ - -/* Author: Marty Kraimer Date: 26JAN2000 */ -/* timeout accuracy tests by Jeff Hill */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsRingPointer.h" -#include "epicsTime.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - - -typedef struct info { - epicsEventId event; - epicsMutexId lockRing; - int quit; - epicsRingPointerId ring; -} info; - -extern "C" { - -static void consumer(void *arg) -{ - info *pinfo = (info *)arg; - int errors = 0; - - testDiag("consumer: starting"); - while (!pinfo->quit) { - epicsEventStatus status = epicsEventWait(pinfo->event); - if (status != epicsEventOK) { - testDiag("consumer: epicsEventWait returned %d", status); - errors++; - } - while (epicsRingPointerGetUsed(pinfo->ring) >= 2) { - epicsRingPointerId message[2]; - for (int i = 0; i < 2; i++) { - message[i] = epicsRingPointerPop(pinfo->ring); - if (message[i] == 0) { - testDiag("consumer: epicsRingPointerPop returned 0"); - errors++; - } - } - if (message[0] != message[1]) { - testDiag("consumer: message %p %p\n", message[0], message[1]); - errors++; - } - } - } - testOk(errors == 0, "consumer: errors = %d", errors); -} - -static void producer(void *arg) -{ - info *pinfo = (info *)arg; - const char *name = epicsThreadGetNameSelf(); - epicsThreadId myId = epicsThreadGetIdSelf(); - int errors = 0; - int ntimes = 0; - - testDiag("%s: starting", name); - while(!pinfo->quit) { - ++ntimes; - epicsMutexLockStatus status = epicsMutexLock(pinfo->lockRing); - if (status != epicsMutexLockOK) { - testDiag("%s: epicsMutexLock returned %d", name, status); - errors++; - } - if (epicsRingPointerGetFree(pinfo->ring) >= 2) { - for (int i = 0; i < 2; i++) { - if (!epicsRingPointerPush(pinfo->ring, myId)) { - testDiag("%s: epicsRingPointerPush fail", name); - errors++; - } - if (i == 0 && (ntimes % 4 == 0)) - epicsThreadSleep(0.1); - } - } else { - testFail("%s: ring buffer full", name); - errors++; - } - epicsMutexUnlock(pinfo->lockRing); - epicsThreadSleep(1.0); - epicsEventMustTrigger(pinfo->event); - } - testOk(errors == 0, "%s: errors = %d", name, errors); -} - -#define SLEEPERCOUNT 3 -struct wakeInfo { - epicsEventId event; - epicsMutexId countMutex; - int count; -}; -static void sleeper(void *arg) -{ - struct wakeInfo *wp = (struct wakeInfo *)arg; - epicsEventMustWait(wp->event); - epicsMutexLock(wp->countMutex); - wp->count++; - epicsMutexUnlock(wp->countMutex); -} -static void eventWakeupTest(void) -{ - struct wakeInfo wakeInfo, *wp = &wakeInfo; - int i, c; - - wp->event = epicsEventMustCreate(epicsEventEmpty); - wp->countMutex = epicsMutexMustCreate(); - wp->count = 0; - for (i = 0 ; i < SLEEPERCOUNT ; i++) - epicsThreadCreate("Sleeper", - epicsThreadPriorityScanHigh, - epicsThreadGetStackSize(epicsThreadStackSmall), - sleeper, - wp); - epicsThreadSleep(0.5); - epicsMutexLock(wp->countMutex); - c = wp->count; - epicsMutexUnlock(wp->countMutex); - testOk(c == 0, "all threads still sleeping"); - for (i = 1 ; i <= SLEEPERCOUNT ; i++) { - epicsEventMustTrigger(wp->event); - epicsThreadSleep(0.5); - epicsMutexLock(wp->countMutex); - c = wp->count; - epicsMutexUnlock(wp->countMutex); - testOk(c == i, "%d thread%s awakened, expected %d", c, c == 1 ? "" : "s", i); - } - epicsEventDestroy(wp->event); - epicsMutexDestroy(wp->countMutex); -} - - -} // extern "C" - -static double eventWaitMeasureDelayError( const epicsEventId &id, const double & delay ) -{ - epicsTime beg = epicsTime::getCurrent(); - epicsEventWaitWithTimeout ( id, delay ); - epicsTime end = epicsTime::getCurrent(); - double meas = end - beg; - double error = fabs ( delay - meas ); - testDiag("epicsEventWaitWithTimeout(%.6f) delay error %.6f sec", - delay, error ); - return error; -} - -static void eventWaitTest() -{ - double errorSum = 0.0; - epicsEventId event = epicsEventMustCreate ( epicsEventEmpty ); - int i; - for ( i = 0u; i < 20; i++ ) { - double delay = ldexp ( 1.0 , -i ); - errorSum += eventWaitMeasureDelayError ( event, delay ); - } - errorSum += eventWaitMeasureDelayError ( event, 0.0 ); - epicsEventDestroy ( event ); - double meanError = errorSum / ( i + 1 ); - testOk(meanError < 0.05, "Average error %.6f sec", meanError); -} - - -MAIN(epicsEventTest) -{ - const int nthreads = 3; - epicsThreadId *id; - char **name; - epicsEventId event; - int status; - - testPlan(13+SLEEPERCOUNT); - - event = epicsEventMustCreate(epicsEventEmpty); - - status = epicsEventWaitWithTimeout(event, 0.0); - testOk(status == epicsEventWaitTimeout, - "epicsEventWaitWithTimeout(event, 0.0) = %d", status); - - status = epicsEventWaitWithTimeout(event, 1.0); - testOk(status == epicsEventWaitTimeout, - "epicsEventWaitWithTimeout(event, 1.0) = %d", status); - - status = epicsEventTryWait(event); - testOk(status == epicsEventWaitTimeout, - "epicsEventTryWait(event) = %d", status); - - status = epicsEventTrigger(event); - testOk(status == epicsEventOK, - "epicsEventTrigger(event) = %d", status); - status = epicsEventWaitWithTimeout(event, 1.0); - testOk(status == epicsEventOK, - "epicsEventWaitWithTimeout(event, 1.0) = %d", status); - - epicsEventMustTrigger(event); - status = epicsEventWaitWithTimeout(event,DBL_MAX); - testOk(status == epicsEventOK, - "epicsEventWaitWithTimeout(event, DBL_MAX) = %d", status); - - epicsEventMustTrigger(event); - status = epicsEventTryWait(event); - testOk(status == epicsEventOK, - "epicsEventTryWait(event) = %d", status); - - info *pinfo = (info *)calloc(1,sizeof(info)); - pinfo->event = event; - pinfo->lockRing = epicsMutexCreate(); - pinfo->ring = epicsRingPointerCreate(1024*2); - unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - - epicsThreadCreate("consumer", 50, stackSize, consumer, pinfo); - id = (epicsThreadId *)calloc(nthreads, sizeof(epicsThreadId)); - name = (char **)calloc(nthreads, sizeof(char *)); - for(int i = 0; i < nthreads; i++) { - name[i] = (char *)calloc(16, sizeof(char)); - sprintf(name[i],"producer %d",i); - id[i] = epicsThreadCreate(name[i], 40, stackSize, producer, pinfo); - epicsThreadSleep(0.1); - } - epicsThreadSleep(5.0); - - testDiag("setting quit"); - pinfo->quit = 1; - epicsThreadSleep(2.0); - - epicsEventMustTrigger(pinfo->event); - epicsThreadSleep(1.0); - - eventWaitTest(); - eventWakeupTest(); - - free(name); - free(id); - epicsRingPointerDelete(pinfo->ring); - epicsMutexDestroy(pinfo->lockRing); - epicsEventDestroy(event); - free(pinfo); - - return testDone(); -} diff --git a/src/libCom/test/epicsExitTest.c b/src/libCom/test/epicsExitTest.c deleted file mode 100644 index dc901b5ac..000000000 --- a/src/libCom/test/epicsExitTest.c +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsExitTest.cpp */ - -/* Author: Marty Kraimer Date: 09JUL2004*/ - -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsAssert.h" -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsUnitTest.h" -#include "testMain.h" - - -typedef struct info { - char name[64]; - epicsEventId terminate; - epicsEventId terminated; -}info; - -static void atExit(void *pvt) -{ - info *pinfo = (info *)pvt; - testPass("%s reached atExit", pinfo->name); - epicsEventSignal(pinfo->terminate); - /*Now wait for thread to terminate*/ - epicsEventMustWait(pinfo->terminated); - testPass("%s destroying pinfo", pinfo->name); - epicsEventDestroy(pinfo->terminate); - epicsEventDestroy(pinfo->terminated); - free(pinfo); -} - -static void atThreadExit(void *pvt) -{ - info *pinfo = (info *)pvt; - testPass("%s terminating", pinfo->name); - epicsEventSignal(pinfo->terminated); -} - -static void thread(void *arg) -{ - info *pinfo = (info *)arg; - - strcpy(pinfo->name, epicsThreadGetNameSelf()); - testDiag("%s starting", pinfo->name); - pinfo->terminate = epicsEventMustCreate(epicsEventEmpty); - pinfo->terminated = epicsEventMustCreate(epicsEventEmpty); - testOk(!epicsAtExit(atExit, pinfo), "Registered atExit(%p)", pinfo); - testOk(!epicsAtThreadExit(atThreadExit, pinfo), - "Registered atThreadExit(%p)", pinfo); - testDiag("%s waiting for atExit", pinfo->name); - epicsEventMustWait(pinfo->terminate); -} - -int count; - -static void counter(void *pvt) -{ - count++; -} - -static void mainExit(void *pvt) -{ - testPass("Reached mainExit"); - testDone(); -} - -MAIN(epicsExitTest) -{ - unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - info *pinfoA = (info *)calloc(1, sizeof(info)); - info *pinfoB = (info *)calloc(1, sizeof(info)); - - testPlan(15); - - testOk(!epicsAtExit(counter, NULL), "Registered counter()"); - count = 0; - epicsExitCallAtExits(); - testOk(count == 1, "counter() called once"); - epicsExitCallAtExits(); - testOk(count == 1, "unregistered counter() not called"); - - testOk(!epicsAtExit(mainExit, NULL), "Registered mainExit()"); - - epicsThreadCreate("threadA", 50, stackSize, thread, pinfoA); - epicsThreadSleep(0.1); - epicsThreadCreate("threadB", 50, stackSize, thread, pinfoB); - epicsThreadSleep(1.0); - - testDiag("Calling epicsExit"); - epicsExit(0); - return 0; -} diff --git a/src/libCom/test/epicsInlineTest1.c b/src/libCom/test/epicsInlineTest1.c deleted file mode 100644 index e377e5f1d..000000000 --- a/src/libCom/test/epicsInlineTest1.c +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* This test checks the variations on inline function defintions. - * - * "static inline int func(void) {...}" - * - * Consistent meaning in C89, C99, and C++ (98 and 11). - * If not inline'd results in a private symbol in each compilation unit. - * Thus the non-inline'd version is duplicated in each compilation unit. - * However, definitions in different compilation units may be different. - * - * "inline int func(void) {...}" - * Warning: Not consistent, avoid use in headers meant for C or C++ - * - * In C++ this may be safely defined in more than one compilation unit. - * Where not inlined it will result in a weak public symbol. - * Thus non-inline'd version isn't duplicated, but must be the same - * in all compilation units. - * - */ - -#include "compilerSpecific.h" -#include "epicsUnitTest.h" - -#include "testMain.h" - -static EPICS_ALWAYS_INLINE int epicsInlineTestFn1(void) -{ - return 1; -} - -/* Fails to link in C99 -inline int epicsInlineTestFn2(void) -{ - return 42; -} -*/ - -void epicsInlineTest1(void) -{ - testDiag("epicsInlineTest1()"); - testOk1(epicsInlineTestFn1()==1); - /*testOk1(epicsInlineTestFn2()==42);*/ -} - -void epicsInlineTest2(void); -void epicsInlineTest3(void); -void epicsInlineTest4(void); - -MAIN(epicsInlineTest) -{ - testPlan(6); - testDiag("Test variation on inline int func()"); - epicsInlineTest1(); - epicsInlineTest2(); - epicsInlineTest3(); - epicsInlineTest4(); - return testDone(); -} diff --git a/src/libCom/test/epicsInlineTest2.c b/src/libCom/test/epicsInlineTest2.c deleted file mode 100644 index b787276fb..000000000 --- a/src/libCom/test/epicsInlineTest2.c +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "compilerSpecific.h" -#include "epicsUnitTest.h" - -static EPICS_ALWAYS_INLINE int epicsInlineTestFn1(void) -{ - return 2; -} - -/* Fails to link in C99 -inline int epicsInlineTestFn2(void) -{ - return 42; -} -*/ - -void epicsInlineTest2(void) -{ - testDiag("epicsInlineTest2()"); - testOk1(epicsInlineTestFn1()==2); - /*testOk1(epicsInlineTestFn2()==42);*/ -} diff --git a/src/libCom/test/epicsInlineTest3.cpp b/src/libCom/test/epicsInlineTest3.cpp deleted file mode 100644 index 9647be6dc..000000000 --- a/src/libCom/test/epicsInlineTest3.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "compilerSpecific.h" -#include "epicsUnitTest.h" - -static EPICS_ALWAYS_INLINE int epicsInlineTestFn1(void) -{ - return 3; -} - -inline int epicsInlineTestFn2(void) -{ - return 42; -} - -extern "C" -void epicsInlineTest3(void) -{ - testDiag("epicsInlineTest3()"); - testOk1(epicsInlineTestFn1()==3); - testOk1(epicsInlineTestFn2()==42); -} diff --git a/src/libCom/test/epicsInlineTest4.cpp b/src/libCom/test/epicsInlineTest4.cpp deleted file mode 100644 index 545b45ffd..000000000 --- a/src/libCom/test/epicsInlineTest4.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "compilerSpecific.h" -#include "epicsUnitTest.h" - -static EPICS_ALWAYS_INLINE int epicsInlineTestFn1(void) -{ - return 4; -} - -inline int epicsInlineTestFn2(void) -{ - return 42; -} - -extern "C" -void epicsInlineTest4(void) -{ - testDiag("epicsInlineTest4()"); - testOk1(epicsInlineTestFn1()==4); - testOk1(epicsInlineTestFn2()==42); -} diff --git a/src/libCom/test/epicsMMIOTest.c b/src/libCom/test/epicsMMIOTest.c deleted file mode 100644 index 939627348..000000000 --- a/src/libCom/test/epicsMMIOTest.c +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Michael Davidsaver - */ - -#include "epicsAssert.h" -#include "epicsEndian.h" -#include "epicsTypes.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#include "epicsMMIO.h" - -#if EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG -#define BE16 0x1234 -#define BE32 0x12345678 -#define LE16 0x3412 -#define LE32 0x78563412 -#else -#define LE16 0x1234 -#define LE32 0x12345678 -#define BE16 0x3412 -#define BE32 0x78563412 -#endif - -union hydra16 { - epicsUInt16 u16; - epicsUInt8 bytes[2]; -}; - -union hydra32 { - epicsUInt32 u32; - epicsUInt8 bytes[4]; -}; - -MAIN(epicsMMIOTest) -{ - epicsUInt8 B; - union hydra16 H16; - union hydra32 H32; - - STATIC_ASSERT(sizeof(H16)==2); - STATIC_ASSERT(sizeof(H32)==4); - - testPlan(14); - - testDiag("8-bit ops"); - - iowrite8(&B, 5); - testOk1(B==5); - testOk1(ioread8(&B)==5); - - testDiag("16-bit ops"); - - nat_iowrite16(&H16.bytes, 0x1234); - testOk1(H16.u16==0x1234); - testOk1(nat_ioread16(&H16.bytes)==0x1234); - - be_iowrite16(&H16.bytes, 0x1234); - testOk1(H16.u16==BE16); - testOk1(be_ioread16(&H16.bytes)==0x1234); - - le_iowrite16(&H16.bytes, 0x1234); - testOk1(H16.u16==LE16); - testOk1(le_ioread16(&H16.bytes)==0x1234); - - testDiag("32-bit ops"); - - nat_iowrite32(&H32.bytes, 0x12345678); - testOk1(H32.u32==0x12345678); - testOk1(nat_ioread32(&H32.bytes)==0x12345678); - - be_iowrite32(&H32.bytes, 0x12345678); - testOk1(H32.u32==BE32); - testOk1(be_ioread32(&H32.bytes)==0x12345678); - - le_iowrite32(&H32.bytes, 0x12345678); - testOk1(H32.u32==LE32); - testOk1(le_ioread32(&H32.bytes)==0x12345678); - - return testDone(); -} diff --git a/src/libCom/test/epicsMathTest.c b/src/libCom/test/epicsMathTest.c deleted file mode 100644 index 8ea763cf0..000000000 --- a/src/libCom/test/epicsMathTest.c +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsMathTest.c - * - * Author Marty Kraimer - */ - -#include "epicsUnitTest.h" -#include "epicsMath.h" -#include "testMain.h" - -MAIN(epicsMathTest) -{ - double huge = 1e300; - double tiny = 1e-300; - double c; - - testPlan(35); - - testOk1(!isnan(0.0)); - testOk1(!isinf(0.0)); - - testOk1(!isnan(epicsINF)); - testOk1(isinf(epicsINF)); - testOk1(epicsINF == epicsINF); - testOk1(epicsINF > 0.0); - testOk1(epicsINF - epicsINF != 0.0); - -#if defined(_WIN64) && defined(_MSC_VER) - testTodoBegin("Known failure on windows-x64"); -#endif - testOk1(epicsINF + -epicsINF != 0.0); - testOk1(-epicsINF + epicsINF != 0.0); -#if defined(_WIN64) && defined(_MSC_VER) - testTodoEnd(); -#endif - - testOk1(isnan(epicsINF - epicsINF)); - -#if defined(_WIN64) && defined(_MSC_VER) - testTodoBegin("Known failure on windows-x64"); -#endif - testOk1(isnan(epicsINF + -epicsINF)); - testOk1(isnan(-epicsINF + epicsINF)); -#if defined(_WIN64) && defined(_MSC_VER) - testTodoEnd(); -#endif - - testOk1(isnan(epicsNAN)); - testOk1(!isinf(epicsNAN)); - testOk1(epicsNAN != epicsNAN); - testOk1(!(epicsNAN < epicsNAN)); - testOk1(!(epicsNAN <= epicsNAN)); - testOk1(!(epicsNAN == epicsNAN)); - testOk1(!(epicsNAN >= epicsNAN)); - testOk1(!(epicsNAN > epicsNAN)); - testOk1(isnan(epicsNAN - epicsNAN)); - -#if defined(_WIN64) && defined(_MSC_VER) - testTodoBegin("Known failure on windows-x64"); -#endif - testOk1(isnan(epicsNAN + -epicsNAN)); - testOk1(isnan(-epicsNAN + epicsNAN)); -#if defined(_WIN64) && defined(_MSC_VER) - testTodoEnd(); -#endif - - c = huge / tiny; - testOk(!isnan(c), "!isnan(1e300 / 1e-300)"); - testOk(isinf(c), "isinf(1e300 / 1e-300)"); - testOk(c > 0.0, "1e300 / 1e-300 > 0.0"); - - c = (-huge) / tiny; - testOk(!isnan(c), "!isnan(-1e300 / 1e-300)"); - testOk(isinf(c), "isinf(-1e300 / 1e-300)"); - testOk(c < 0.0, "-1e300 / 1e-300 < 0.0"); - - c = huge / huge; - testOk(!isnan(c), "!isnan(1e300 / 1e300)"); - testOk(!isinf(c), "!isinf(1e300 / 1e300)"); - testOk(c == 1.0, "1e300 / 1e300 == 1.0"); - - c = tiny / tiny; - testOk(!isnan(c), "!isnan(1e-300 / 1e-300)"); - testOk(!isinf(c), "!isinf(1e-300 / 1e-300)"); - testOk(c == 1.0, "1e300 / 1e-300 == 1.0"); - - return testDone(); -} diff --git a/src/libCom/test/epicsMaxThreads.c b/src/libCom/test/epicsMaxThreads.c deleted file mode 100644 index 8d0d06da5..000000000 --- a/src/libCom/test/epicsMaxThreads.c +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsMaxThreads.cpp */ - -/* Author: Marty Kraimer Date: 09JUL2004*/ - -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsEvent.h" -#include "epicsExit.h" -#include "errlog.h" -#include "testMain.h" - -static epicsEventId started; - -static void thread(void *arg) -{ - epicsEventSignal(started); - epicsThreadSuspendSelf(); -} - -MAIN(epicsMaxThreads) -{ - unsigned int stackSize; - epicsThreadId id; - int i = 0; - - stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - printf("stackSize %d\n",stackSize); - - started = epicsEventMustCreate(epicsEventEmpty); - - while(1) { - id = epicsThreadCreate("thread",50,stackSize,thread,0); - if(!id) break; - i++; - if ((i % 100) == 0) - printf ("Reached %d...\n", i); - epicsEventMustWait(started); - } - - printf("Max number of \"Small\" threads on this OS is %d\n", i); - return 0; -} diff --git a/src/libCom/test/epicsMessageQueueTest.cpp b/src/libCom/test/epicsMessageQueueTest.cpp deleted file mode 100644 index ae090fc47..000000000 --- a/src/libCom/test/epicsMessageQueueTest.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - */ -#include -#include -#include -#include - -#include "epicsMessageQueue.h" -#include "epicsThread.h" -#include "epicsExit.h" -#include "epicsEvent.h" -#include "epicsAssert.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -static const char *msg1 = "1234567890This is a very long message."; -static volatile int sendExit = 0; -static volatile int recvExit = 0; -static epicsEventId finished; -static unsigned int mediumStack; - -/* - * In Numerical Recipes in C: The Art of Scientific Computing (William H. - * Press, Brian P. Flannery, Saul A. Teukolsky, William T. Vetterling; New - * York: Cambridge University Press, 1992 (2nd ed., p. 277)), the follow- - * ing comments are made: - * "If you want to generate a random integer between 1 and 10, you - * should always do it by using high-order bits, as in - * j=1+(int) (10.0*rand()/(RAND_MAX+1.0)); - * and never by anything resembling - * j=1+(rand() % 10); - */ -static int -randBelow(int n) -{ - return (int)((double)n*rand()/(RAND_MAX+1.0)); -} - -extern "C" void -badReceiver(void *arg) -{ - epicsMessageQueue *q = (epicsMessageQueue *)arg; - char cbuf[80]; - int len; - - cbuf[0] = '\0'; - len = q->receive(cbuf, 1); - if (len < 0 && cbuf[0] == '\0') - testPass("receive into undersized buffer returned error (%d)", len); - else if (len == 1 && cbuf[0] == *msg1) - testPass("receive into undersized buffer truncated message"); - else - testFail("receive into undersized buffer returned %d", len); - - epicsThreadSleep(3.0); - - cbuf[0] = '\0'; - len = q->receive(cbuf, 1); - if (len < 0 && cbuf[0] == '\0') - testPass("receive into undersized buffer returned error (%d)", len); - else if (len == 1 && cbuf[0] == *msg1) - testPass("receive into undersized buffer truncated message"); - else - testFail("receive into undersized buffer returned %d", len); -} - -extern "C" void -receiver(void *arg) -{ - epicsMessageQueue *q = (epicsMessageQueue *)arg; - const char *myName = epicsThreadGetNameSelf(); - char cbuf[80]; - int expectmsg[4]; - int len; - int sender, msgNum; - int errors = 0; - - for (sender = 1 ; sender <= 4 ; sender++) - expectmsg[sender-1] = 1; - while (!recvExit) { - cbuf[0] = '\0'; - len = q->receive(cbuf, sizeof cbuf, 5.0); - if (len < 0 && !recvExit) { - testDiag("receiver() received unexpected timeout"); - ++errors; - } - else if (sscanf(cbuf, "Sender %d -- %d", &sender, &msgNum) == 2 && - sender >= 1 && sender <= 4) { - if (expectmsg[sender-1] != msgNum) { - ++errors; - testDiag("%s received %d '%.*s' -- expected %d", - myName, len, len, cbuf, expectmsg[sender-1]); - } - expectmsg[sender-1] = msgNum + 1; - epicsThreadSleep(0.001 * (randBelow(20))); - } - } - for (sender = 1 ; sender <= 4 ; sender++) { - if (expectmsg[sender-1] > 1) - testDiag("Received %d messages from Sender %d", - expectmsg[sender-1]-1, sender); - } - if (!testOk1(errors == 0)) - testDiag("Error count was %d", errors); - testDiag("%s exiting", myName); - epicsEventSignal(finished); -} - -extern "C" void -sender(void *arg) -{ - epicsMessageQueue *q = (epicsMessageQueue *)arg; - char cbuf[80]; - int len; - int i = 0; - - while (!sendExit) { - len = sprintf(cbuf, "%s -- %d.", epicsThreadGetNameSelf(), ++i); - while (q->trySend((void *)cbuf, len) < 0) - epicsThreadSleep(0.005 * (randBelow(5))); - epicsThreadSleep(0.005 * (randBelow(20))); - } - testDiag("%s exiting, sent %d messages", epicsThreadGetNameSelf(), i); -} - -extern "C" void messageQueueTest(void *parm) -{ - epicsThreadId myThreadId = epicsThreadGetIdSelf(); - unsigned int i; - char cbuf[80]; - int len; - int pass; - int want; - - epicsMessageQueue *q1 = new epicsMessageQueue(4, 20); - - testDiag("Simple single-thread tests:"); - i = 0; - testOk1(q1->pending() == 0); - while (q1->trySend((void *)msg1, i ) == 0) { - i++; - testOk(q1->pending() == i, "q1->pending() == %d", i); - } - testOk1(q1->pending() == 4); - - want = 0; - len = q1->receive(cbuf, sizeof cbuf); - testOk1(q1->pending() == 3); - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - - want++; - len = q1->receive(cbuf, sizeof cbuf); - testOk1(q1->pending() == 2); - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - q1->trySend((void *)msg1, i++); - - want++; - len = q1->receive(cbuf, sizeof cbuf); - testOk1(q1->pending() == 2); - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - q1->trySend((void *)msg1, i++); - testOk1(q1->pending() == 3); - - i = 3; - while ((len = q1->receive(cbuf, sizeof cbuf, 1.0)) >= 0) { - --i; - testOk(q1->pending() == i, "q1->pending() == %d", i); - want++; - if (!testOk1((len == want) & (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - } - testOk1(q1->pending() == 0); - - testDiag("Test sender timeout:"); - i = 0; - testOk1(q1->pending() == 0); - while (q1->send((void *)msg1, i, 1.0 ) == 0) { - i++; - testOk(q1->pending() == i, "q1->pending() == %d", i); - } - testOk1(q1->pending() == 4); - - want = 0; - len = q1->receive(cbuf, sizeof cbuf); - testOk1(q1->pending() == 3); - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - - want++; - len = q1->receive(cbuf, sizeof cbuf); - testOk1(q1->pending() == 2); - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - q1->send((void *)msg1, i++, 1.0); - - want++; - len = q1->receive(cbuf, sizeof cbuf); - testOk1(q1->pending() == 2); - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - q1->send((void *)msg1, i++, 1.0); - testOk1(q1->pending() == 3); - - i = 3; - while ((len = q1->receive(cbuf, sizeof cbuf, 1.0)) >= 0) { - --i; - testOk(q1->pending() == i, "q1->pending() == %d", i); - want++; - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - } - testOk1(q1->pending() == 0); - - testDiag("Test receiver with timeout:"); - for (i = 0 ; i < 4 ; i++) - testOk1 (q1->send((void *)msg1, i, 1.0) == 0); - testOk1(q1->pending() == 4); - for (i = 0 ; i < 4 ; i++) - testOk(q1->receive((void *)cbuf, sizeof cbuf, 1.0) == (int)i, - "q1->receive(...) == %d", i); - testOk1(q1->pending() == 0); - testOk1(q1->receive((void *)cbuf, sizeof cbuf, 1.0) < 0); - testOk1(q1->pending() == 0); - - testDiag("Single receiver with invalid size, single sender tests:"); - epicsThreadCreate("Bad Receiver", epicsThreadPriorityMedium, - mediumStack, badReceiver, q1); - epicsThreadSleep(1.0); - testOk(q1->send((void *)msg1, 10) == 0, "Send with waiting receiver"); - epicsThreadSleep(2.0); - testOk(q1->send((void *)msg1, 10) == 0, "Send with no receiver"); - epicsThreadSleep(2.0); - - testDiag("Single receiver, single sender tests:"); - epicsThreadSetPriority(myThreadId, epicsThreadPriorityHigh); - epicsThreadCreate("Receiver one", epicsThreadPriorityMedium, - mediumStack, receiver, q1); - for (pass = 1 ; pass <= 3 ; pass++) { - for (i = 0 ; i < 10 ; i++) { - if (q1->trySend((void *)msg1, i) < 0) - break; - if (pass >= 3) - epicsThreadSleep(0.5); - } - switch (pass) { - case 1: - if (i<6) - testDiag(" priority-based scheduler, sent %d messages", i); - epicsThreadSetPriority(myThreadId, epicsThreadPriorityLow); - break; - case 2: - if (i<10) - testDiag(" scheduler not strict priority, sent %d messages", i); - else - testDiag(" strict priority scheduler, sent 10 messages"); - break; - case 3: - testOk(i == 10, "%d of 10 messages sent with sender pauses", i); - break; - } - epicsThreadSleep(1.0); - } - - /* - * Single receiver, multiple sender tests - */ - testDiag("Single receiver, multiple sender tests:"); - testDiag("This test lasts 60 seconds..."); - testOk(!!epicsThreadCreate("Sender 1", epicsThreadPriorityLow, - mediumStack, sender, q1), - "Created Sender 1"); - testOk(!!epicsThreadCreate("Sender 2", epicsThreadPriorityMedium, - mediumStack, sender, q1), - "Created Sender 2"); - testOk(!!epicsThreadCreate("Sender 3", epicsThreadPriorityHigh, - mediumStack, sender, q1), - "Created Sender 3"); - testOk(!!epicsThreadCreate("Sender 4", epicsThreadPriorityHigh, - mediumStack, sender, q1), - "Created Sender 4"); - - for (i = 0; i < 10; i++) { - testDiag("... %2d", 10 - i); - epicsThreadSleep(6.0); - } - - sendExit = 1; - epicsThreadSleep(1.0); - recvExit = 1; - testDiag("Scheduler exiting"); -} - -MAIN(epicsMessageQueueTest) -{ - testPlan(62); - - finished = epicsEventMustCreate(epicsEventEmpty); - mediumStack = epicsThreadGetStackSize(epicsThreadStackMedium); - - epicsThreadCreate("messageQueueTest", epicsThreadPriorityMedium, - mediumStack, messageQueueTest, NULL); - - epicsEventMustWait(finished); - testDiag("Main thread signalled"); - epicsThreadSleep(1.0); - - return testDone(); -} diff --git a/src/libCom/test/epicsMutexTest.cpp b/src/libCom/test/epicsMutexTest.cpp deleted file mode 100644 index d44e5c0f1..000000000 --- a/src/libCom/test/epicsMutexTest.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsMutexTest.c */ - -/* - * Author: Marty Kraimer Date: 26JAN2000 - * Jeff Hill (added mutex performance test ) - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "epicsTime.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -typedef struct info { - int threadnum; - epicsMutexId mutex; - int quit; -}info; - -extern "C" void mutexThread(void * arg) -{ - info *pinfo = (info *)arg; - testDiag("mutexThread %d starting", pinfo->threadnum); - while (pinfo->quit--) { - epicsMutexLockStatus status = epicsMutexLock(pinfo->mutex); - testOk(status == epicsMutexLockOK, - "mutexThread %d epicsMutexLock returned %d", - pinfo->threadnum, (int)status); - epicsThreadSleep(.1); - epicsMutexUnlock(pinfo->mutex); - epicsThreadSleep(.9); - } - testDiag("mutexThread %d exiting", pinfo->threadnum); - return; -} - -inline void lockPair ( epicsMutex & mutex ) -{ - mutex.lock (); - mutex.unlock (); -} - -inline void tenLockPairs ( epicsMutex & mutex ) -{ - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); -} - -inline void tenLockPairsSquared ( epicsMutex & mutex ) -{ - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); -} - -inline void doubleRecursiveLockPair ( epicsMutex & mutex ) -{ - mutex.lock (); - mutex.lock (); - mutex.unlock (); - mutex.unlock (); -} - -inline void tenDoubleRecursiveLockPairs ( epicsMutex & mutex ) -{ - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); -} - -inline void tenDoubleRecursiveLockPairsSquared ( epicsMutex & mutex ) -{ - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); -} - -inline void quadRecursiveLockPair ( epicsMutex & mutex ) -{ - mutex.lock (); - mutex.lock (); - mutex.lock (); - mutex.lock (); - mutex.unlock (); - mutex.unlock (); - mutex.unlock (); - mutex.unlock (); -} - -inline void tenQuadRecursiveLockPairs ( epicsMutex & mutex ) -{ - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); -} - -inline void tenQuadRecursiveLockPairsSquared ( epicsMutex & mutex ) -{ - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); -} - -void epicsMutexPerformance () -{ - epicsMutex mutex; - unsigned i; - - // test a single lock pair - epicsTime begin = epicsTime::getCurrent (); - static const unsigned N = 1000; - for ( i = 0; i < N; i++ ) { - tenLockPairsSquared ( mutex ); - } - double delay = epicsTime::getCurrent () - begin; - delay /= N * 100u; // convert to delay per lock pair - delay *= 1e6; // convert to micro seconds - testDiag("lock()*1/unlock()*1 takes %f microseconds", delay); - - // test a two times recursive lock pair - begin = epicsTime::getCurrent (); - for ( i = 0; i < N; i++ ) { - tenDoubleRecursiveLockPairsSquared ( mutex ); - } - delay = epicsTime::getCurrent () - begin; - delay /= N * 100u; // convert to delay per lock pair - delay *= 1e6; // convert to micro seconds - testDiag("lock()*2/unlock()*2 takes %f microseconds", delay); - - // test a four times recursive lock pair - begin = epicsTime::getCurrent (); - for ( i = 0; i < N; i++ ) { - tenQuadRecursiveLockPairsSquared ( mutex ); - } - delay = epicsTime::getCurrent () - begin; - delay /= N * 100u; // convert to delay per lock pair - delay *= 1e6; // convert to micro seconds - testDiag("lock()*4/unlock()*4 takes %f microseconds", delay); -} - -struct verifyTryLock { - epicsMutexId mutex; - epicsEventId done; -}; - -extern "C" void verifyTryLockThread ( void *pArg ) -{ - struct verifyTryLock *pVerify = - ( struct verifyTryLock * ) pArg; - - testOk1(epicsMutexTryLock(pVerify->mutex) == epicsMutexLockTimeout); - epicsEventSignal ( pVerify->done ); -} - -void verifyTryLock () -{ - struct verifyTryLock verify; - - verify.mutex = epicsMutexMustCreate (); - verify.done = epicsEventMustCreate ( epicsEventEmpty ); - - testOk1(epicsMutexTryLock(verify.mutex) == epicsMutexLockOK); - - epicsThreadCreate ( "verifyTryLockThread", 40, - epicsThreadGetStackSize(epicsThreadStackSmall), - verifyTryLockThread, &verify ); - - testOk1(epicsEventWait ( verify.done ) == epicsEventWaitOK); - - epicsMutexUnlock ( verify.mutex ); - epicsMutexDestroy ( verify.mutex ); - epicsEventDestroy ( verify.done ); -} - -MAIN(epicsMutexTest) -{ - const int nthreads = 3; - const int nrounds = 5; - unsigned int stackSize; - epicsThreadId *id; - int i; - char **name; - void **arg; - info **pinfo; - epicsMutexId mutex; - int status; - - testPlan(5 + nthreads * nrounds); - - verifyTryLock (); - - mutex = epicsMutexMustCreate(); - status = epicsMutexLock(mutex); - testOk(status == 0, "epicsMutexLock returned %d", status); - status = epicsMutexTryLock(mutex); - testOk(status == 0, "epicsMutexTryLock returned %d", status); - epicsMutexUnlock(mutex); - epicsMutexUnlock(mutex); - - id = (epicsThreadId *)calloc(nthreads,sizeof(epicsThreadId)); - name = (char **)calloc(nthreads,sizeof(char *)); - arg = (void **)calloc(nthreads,sizeof(void *)); - pinfo = (info **)calloc(nthreads,sizeof(info *)); - stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - for(i=0; ithreadnum = i; - pinfo[i]->mutex = mutex; - pinfo[i]->quit = nrounds; - arg[i] = pinfo[i]; - id[i] = epicsThreadCreate(name[i],40,stackSize, - mutexThread, - arg[i]); - } - epicsThreadSleep(2.0 + nrounds); - - epicsMutexPerformance (); - - free(pinfo); - free(arg); - free(name); - free(id); - epicsMutexDestroy(mutex); - - return testDone(); -} diff --git a/src/libCom/test/epicsRunLibComTests.c b/src/libCom/test/epicsRunLibComTests.c deleted file mode 100644 index c4a76e777..000000000 --- a/src/libCom/test/epicsRunLibComTests.c +++ /dev/null @@ -1,120 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Run libCom tests as a batch. - * - * Do *not* include performance measurements here, they don't help to - * prove functionality (which is the point of this convenience routine). - */ - -#include -#include -#include - -int blockingSockTest(void); -int epicsAlgorithm(void); -int epicsAtomicTest(void); -int epicsCalcTest(void); -int epicsEllTest(void); -int epicsEnvTest(void); -int epicsErrlogTest(void); -int epicsEventTest(void); -int epicsExitTest(void); -int epicsMathTest(void); -int epicsMessageQueueTest(void); -int epicsMMIOTest(void); -int epicsMutexTest(void); -int epicsSockResolveTest(void); -int epicsSpinTest(void); -int epicsStackTraceTest(void); -int epicsStdioTest(void); -int epicsStdlibTest(void); -int epicsStringTest(void); -int epicsThreadHooksTest(void); -int epicsThreadOnceTest(void); -int epicsThreadPoolTest(void); -int epicsThreadPriorityTest(void); -int epicsThreadPrivateTest(void); -int epicsThreadTest(void); -int epicsTimerTest(void); -int epicsTimeTest(void); -#ifdef __rtems__ -int epicsTimeZoneTest(void); -#endif -int epicsTypesTest(void); -int epicsInlineTest(void); -int ipAddrToAsciiTest(void); -int macDefExpandTest(void); -int macLibTest(void); -int ringBytesTest(void); -int ringPointerTest(void); -int taskwdTest(void); - -void epicsRunLibComTests(void) -{ - testHarness(); - - /* - * Thread startup sets some internal variables so do it first - */ - runTest(epicsThreadTest); - - /* - * Timer tests get confused if run after some of the other tests - */ - runTest(epicsTimerTest); - - /* - * Run the regular tests in alphabetical order - */ - runTest(blockingSockTest); - runTest(epicsAlgorithm); - runTest(epicsAtomicTest); - runTest(epicsCalcTest); - runTest(epicsEllTest); - runTest(epicsEnvTest); - runTest(epicsErrlogTest); - runTest(epicsEventTest); - runTest(epicsInlineTest); - runTest(epicsMathTest); - runTest(epicsMessageQueueTest); - runTest(epicsMMIOTest); - runTest(epicsMutexTest); - runTest(epicsSockResolveTest); - runTest(epicsSpinTest); - runTest(epicsStackTraceTest); - runTest(epicsStdioTest); - runTest(epicsStdlibTest); - runTest(epicsStringTest); - runTest(epicsThreadHooksTest); - runTest(epicsThreadOnceTest); - runTest(epicsThreadPoolTest); - runTest(epicsThreadPriorityTest); - runTest(epicsThreadPrivateTest); - runTest(epicsTimeTest); -#ifdef __rtems__ - runTest(epicsTimeZoneTest); -#endif - runTest(epicsTypesTest); - runTest(ipAddrToAsciiTest); - runTest(macDefExpandTest); - runTest(macLibTest); - runTest(ringBytesTest); - runTest(ringPointerTest); - runTest(taskwdTest); - - /* - * Report now in case epicsExitTest dies - */ - testHarnessDone(); - - /* - * epicsExitTest must come last as it never returns - */ - runTest(epicsExitTest); -} diff --git a/src/libCom/test/epicsSockResolveTest.c b/src/libCom/test/epicsSockResolveTest.c deleted file mode 100644 index 8131d9dbf..000000000 --- a/src/libCom/test/epicsSockResolveTest.c +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Brookhaven Science Associates as Operator of -* Brookhaven National Lab. -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -\*************************************************************************/ - -#include "dbDefs.h" -#include "osiSock.h" - -#include "epicsUnitTest.h" -#include "testMain.h" - -#define DEFAULT_PORT 4000 - -typedef struct { - const char *input; - unsigned long IP; - unsigned short port; -} testData; - -static testData okdata[] = { - {"127.0.0.1", 0x7f000001, DEFAULT_PORT}, - {"127.0.0.1:42", 0x7f000001, 42}, - {"localhost", 0x7f000001, DEFAULT_PORT}, - {"localhost:42", 0x7f000001, 42}, - {"2424", 2424, DEFAULT_PORT}, - {"2424:42", 2424, 42}, - {"255.255.255.255", 0xffffffff, DEFAULT_PORT}, - {"255.255.255.255:65535", 0xffffffff, 65535}, -}; - -static const char * baddata[] = { - "127.0.0.1:NaN", - "127.0.0.test", - "127.0.0.test:42", - "16name.invalid", - "16name.invalid:42", - "1.2.3.4.5", - "1.2.3.4.5:6", - "1.2.3.4:5.6", - "256.255.255.255", - "255.256.255.255", - "255.255.256.255", - "255.255.255.256", - "255.255.255.255:65536", -}; - -MAIN(epicsSockResolveTest) -{ - int i; - - testPlan(3*NELEMENTS(okdata) + NELEMENTS(baddata)); - osiSockAttach(); - - { - struct in_addr addr; - - /* See RFCs 2606 and 6761 */ - if (hostToIPAddr("guaranteed.invalid.", &addr) == 0) { - testAbort("hostToIPAddr() is broken, testing not possible"); - } - } - - testDiag("Tests of aToIPAddr"); - - for (i=0; i %d", - okdata[i].input, DEFAULT_PORT, ret); - if (ret) { - testSkip(2, " aToIPAddr() failed"); - } - else { - testOk(addr.sin_addr.s_addr == htonl(okdata[i].IP), " IP correct"); - testOk(addr.sin_port == htons(okdata[i].port), " Port correct"); - } - } - - for (i=0; i %d", - baddata[i], DEFAULT_PORT, ret); - if (ret==0) { - testDiag(" IP=0x%lx, port=%d", - (unsigned long) ntohl(addr.sin_addr.s_addr), - ntohs(addr.sin_port)); - } - } - - osiSockRelease(); - return testDone(); -} diff --git a/src/libCom/test/epicsSpinTest.c b/src/libCom/test/epicsSpinTest.c deleted file mode 100644 index c45348beb..000000000 --- a/src/libCom/test/epicsSpinTest.c +++ /dev/null @@ -1,247 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - * - * based on epicsMutexTest by Marty Kraimer and Jeff Hill - * - */ - -#include -#include -#include -#include -#include -#include - -#include "epicsTime.h" -#include "epicsThread.h" -#include "epicsAtomic.h" -#include "epicsSpin.h" -#include "epicsEvent.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -typedef struct info { - int threadnum; - epicsSpinId spin; - int *counter; - int rounds; - epicsEventId done; -} info; - -#define spinDelay 0.016667 - -void spinThread(void *arg) -{ - info *pinfo = (info *) arg; - testDiag("spinThread %d starting", pinfo->threadnum); - epicsThreadSleep(0.1); /* Try to align threads */ - while (pinfo->rounds--) { - epicsThreadSleep(spinDelay); - epicsSpinLock(pinfo->spin); - pinfo->counter[0]++; - epicsSpinUnlock(pinfo->spin); - } - testDiag("spinThread %d exiting", pinfo->threadnum); - epicsEventSignal(pinfo->done); -} - -static void lockPair(struct epicsSpin *spin) -{ - epicsSpinLock(spin); - epicsSpinUnlock(spin); -} - -static void tenLockPairs(struct epicsSpin *spin) -{ - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); -} - -static void tenLockPairsSquared(struct epicsSpin *spin) -{ - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); -} - -void epicsSpinPerformance () -{ - static const unsigned N = 10000; - unsigned i; - epicsSpinId spin; - epicsTimeStamp begin; - epicsTimeStamp end; - double delay; - - /* Initialize spinlock */ - spin = epicsSpinCreate(); - if (!spin) - testAbort("epicsSpinCreate() returned NULL"); - - /* test a single lock pair */ - epicsTimeGetCurrent(&begin); - for ( i = 0; i < N; i++ ) { - tenLockPairsSquared(spin); - } - epicsTimeGetCurrent(&end); - - delay = epicsTimeDiffInSeconds(&end, &begin); - delay /= N * 100u; /* convert to delay per lock pair */ - delay *= 1e6; /* convert to micro seconds */ - testDiag("lock()*1/unlock()*1 takes %f microseconds", delay); - epicsSpinDestroy(spin); -} - -struct verifyTryLock; - -struct verifyTryLockEnt { - epicsEventId done; - struct verifyTryLock *main; -}; - -struct verifyTryLock { - epicsSpinId spin; - int flag; - struct verifyTryLockEnt *ents; -}; - -static void verifyTryLockThread(void *pArg) -{ - struct verifyTryLockEnt *pVerify = - (struct verifyTryLockEnt *) pArg; - - while(epicsAtomicGetIntT(&pVerify->main->flag)==0) { - int ret = epicsSpinTryLock(pVerify->main->spin); - if(ret!=0) { - epicsAtomicCmpAndSwapIntT(&pVerify->main->flag, 0, ret); - break; - } else - epicsSpinUnlock(pVerify->main->spin); - } - - epicsEventSignal(pVerify->done); -} - -/* Start one thread per CPU which will all try lock - * the same spinlock. They break as soon as one - * fails to take the lock. - */ -static void verifyTryLock() -{ - int N, i; - struct verifyTryLock verify; - - N = epicsThreadGetCPUs(); - if(N==1) { - testSkip(1, "verifyTryLock() only for SMP systems"); - return; - } - - verify.flag = 0; - verify.spin = epicsSpinMustCreate(); - - testDiag("Starting %d spinners", N); - - verify.ents = calloc(N, sizeof(*verify.ents)); - for(i=0; ithreadnum = i; - pinfo[i]->spin = spin; - pinfo[i]->counter = &counter; - pinfo[i]->rounds = nrounds; - pinfo[i]->done = epicsEventMustCreate(epicsEventEmpty); - id[i] = epicsThreadCreate(name[i], 40, stackSize, - spinThread, - pinfo[i]); - } - for (i = 0; i < nthreads; i++) { - epicsEventMustWait(pinfo[i]->done); - epicsEventDestroy(pinfo[i]->done); - free(name[i]); - free(pinfo[i]); - } - testOk(counter == nthreads * nrounds, "Loops run = %d (expecting %d)", - counter, nthreads * nrounds); - - free(pinfo); - free(name); - free(id); - epicsSpinDestroy(spin); - - epicsSpinPerformance(); - - return testDone(); -} diff --git a/src/libCom/test/epicsStackTraceTest.c b/src/libCom/test/epicsStackTraceTest.c deleted file mode 100644 index b89fc7836..000000000 --- a/src/libCom/test/epicsStackTraceTest.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2014 - */ - -/* - * Check stack trace functionality - */ - -#include "epicsStackTrace.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#include -#include -#include - -#define TST_BUFSZ 10000 - -#define MAXP 10 - -/* estimated size of (compiled) epicsStackTraceRecurseGbl */ -#define WINDOW_SZ 400 - -typedef struct TestDataRec_ { - char buf[TST_BUFSZ]; - int pos; -} TestDataRec, *TestData; - -typedef void (*RecFn)(int); - -/* We want a stack trace and need a few nested routines. - * The whole magic here is intended to prevent a compiler - * from optimizing the call stack away: - * - call via a volatile pointer - * - add a call to a no-op function at the end so that - * tail-call optimization doesn't eliminate the call - * stack. - * - * We use a local (static) and a global routine to test - * if the stacktrace supports either flavor. - */ - -void epicsStackTraceRecurseGbl(int lvl); -static void epicsStackTraceRecurseLcl(int lvl); - -void nopFn(int lvl) -{ -} - -RecFn volatile lfp = epicsStackTraceRecurseLcl; -RecFn volatile gfp = epicsStackTraceRecurseGbl; -RecFn volatile nfp = nopFn; - -static void -epicsStackTraceRecurseLcl(int lvl) -{ - if ( lvl ) - gfp(lvl-1); - else - epicsStackTrace(); - - /* call something so that the call through gfp() doesn't - * get optimized into a jump (tail-call optimization) - */ - nfp(0); -} - -void epicsStackTraceRecurseGbl(int lvl) -{ - if ( lvl ) - lfp(lvl-1); - else - epicsStackTrace(); - - /* call something so that the call through gfp() doesn't - * get optimized into a jump (tail-call optimization) - */ - nfp(0); -} - -static void logClient(void *ptr, const char *msg) -{ - TestData td = ptr; - size_t sz = strlen(msg); - size_t mx = sizeof(td->buf) - td->pos - 1; - - if ( sz > mx ) - sz = mx; - strncpy( td->buf+td->pos, msg, sz ); - td->pos += sz; -} - -static int -findStringOcc(const char *buf, const char *what) -{ - int rval = 0; - size_t l = strlen(what); - int ch; - - while ( (buf = strstr(buf, what)) ) { - /* Is it just a prefix? */ - ch = buf[l]; - if ( ! isalnum(ch) && '_' != ch ) { - rval++; - } - buf += l; - } - - testDiag("found %i x %s\n", rval, what); - - return rval; -} - -static int -findNumOcc(const char *buf) -{ - void *ptrs[MAXP]; - int n_ptrs = 0; - int i,j; - int rval = 0; - - while ( n_ptrs < sizeof(ptrs)/sizeof(ptrs[0]) && (buf=strchr(buf,'[')) ) { - if ( 1 == sscanf(buf+1,"%p", &ptrs[n_ptrs]) ) - n_ptrs++; - buf++; - } - /* We should find an address close to epicsStackTraceRecurseGbl twice */ - for (i=0; i= (char*)epicsStackTraceRecurseGbl && (char*)ptrs[i] < (char*)epicsStackTraceRecurseGbl + WINDOW_SZ ) { - rval ++; - testDiag("found address %p again\n", ptrs[i]); - } - } - j++; - } - } - return rval; -} - -MAIN(epicsStackTraceTest) -{ - int features, all_features; - TestDataRec testData; - int gblFound, lclFound, numFound, dynFound; - char *nl, *p; - - testData.pos = 0; - - testPlan(5); - - features = epicsStackTraceGetFeatures(); - - all_features = EPICS_STACKTRACE_LCL_SYMBOLS - | EPICS_STACKTRACE_GBL_SYMBOLS - | EPICS_STACKTRACE_DYN_SYMBOLS - | EPICS_STACKTRACE_ADDRESSES; - - if ( ! testOk( (features & ~all_features) == 0, - "epicsStackTraceGetFeatures() obtains features") ) - testAbort("epicsStackTraceGetFeatures() not working as expected"); - - testData.pos = 0; - - testDiag("calling a few nested routines and eventually dump a stack trace"); - - eltc(0); - errlogAddListener( logClient, &testData ); - gfp(3); - errlogRemoveListeners( logClient, &testData ); - eltc(1); - - /* ensure there's a terminating NUL -- we have reserved space for it */ - testData.buf[testData.pos] = 0; - - testDiag("now scan the result for what we expect"); - - dynFound = findStringOcc( testData.buf, "epicsStackTrace" ); - gblFound = findStringOcc( testData.buf, "epicsStackTraceRecurseGbl" ); - lclFound = findStringOcc( testData.buf, "epicsStackTraceRecurseLcl" ); - numFound = findNumOcc ( testData.buf ); - - if ( (features & EPICS_STACKTRACE_DYN_SYMBOLS) ) { - testOk( dynFound == 1, "dumping symbol from library" ); - } else { - testSkip(1, "no support for dumping library symbols on this platform"); - } - - if ( (features & EPICS_STACKTRACE_GBL_SYMBOLS) ) { - testOk( gblFound == 2, "dumping global symbols" ); - } else { - testSkip(1, "no support for dumping global symbols on this platform"); - } - - if ( (features & EPICS_STACKTRACE_LCL_SYMBOLS) ) { - testOk( lclFound == 2, "dumping local symbols" ); - } else { - testSkip(1, "no support for dumping local symbols on this platform"); - } - - if ( (features & EPICS_STACKTRACE_ADDRESSES) ) { - testOk( numFound > 0, "dumping addresses" ); - } else { - testSkip(1 , "no support for dumping addresses on this platform"); - } - - p = testData.buf; - while ( (nl = strchr(p,'\n')) ) { - *nl = 0; - testDiag("%s",p); - *nl = '\n'; - p = nl+1; - } - testDiag("%s", p); - - testDone(); - - return 0; -} diff --git a/src/libCom/test/epicsStdioTest.c b/src/libCom/test/epicsStdioTest.c deleted file mode 100644 index bf25784a5..000000000 --- a/src/libCom/test/epicsStdioTest.c +++ /dev/null @@ -1,141 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsStdioTest.c - * - * Author Marty Kraimer - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsStdio.h" -#include "epicsUnitTest.h" -#include "testMain.h" - - -#define LINE_1 "# This is first line of sample report\n" -#define LINE_2 "# This is second and last line of sample report\n" - -static void testEpicsSnprintf(void) { - char exbuffer[80], buffer[80]; - const int ivalue = 1234; - const float fvalue = 1.23e4f; - const char *svalue = "OneTwoThreeFour"; - const char *format = "int %d float %8.2e string %s"; - const char *expected = exbuffer; - int size; - int rtn, rlen; - -#ifdef _WIN32 -#if (defined(_MSC_VER) && _MSC_VER < 1900) || \ - (defined(_MINGW) && defined(_TWO_DIGIT_EXPONENT)) - _set_output_format(_TWO_DIGIT_EXPONENT); -#endif -#endif - - sprintf(exbuffer, format, ivalue, fvalue, svalue); - rlen = strlen(expected)+1; - - strcpy(buffer, "AAAA"); - - for (size = 1; size < strlen(expected) + 5; ++size) { - rtn = epicsSnprintf(buffer, size, format, ivalue, fvalue, svalue); - testOk(rtn <= rlen-1, "epicsSnprintf(size=%d) = %d", size, rtn); - if (rtn != rlen-1) - testDiag("Return value does not indicate buffer size needed"); - testOk(strncmp(buffer, expected, size - 1) == 0, - "buffer = '%s'", buffer); - rtn = strlen(buffer); - testOk(rtn == (size < rlen ? size : rlen) - 1, - "length = %d", rtn); - } -} - -void testStdoutRedir (const char *report) -{ - FILE *realStdout = stdout; - FILE *stream = 0; - char linebuf[80]; - size_t buflen = sizeof linebuf; - - testOk1(epicsGetStdout() == stdout); - - errno = 0; - if (!testOk1((stream = fopen(report, "w")) != NULL)) { - testDiag("'%s' could not be opened for writing: %s", - report, strerror(errno)); - testSkip(11, "Can't create stream file"); - return; - } - - epicsSetThreadStdout(stream); - testOk1(stdout == stream); - - printf(LINE_1); - printf(LINE_2); - - epicsSetThreadStdout(0); - testOk1(epicsGetStdout() == realStdout); - testOk1(stdout == realStdout); - - errno = 0; - if (!testOk1(!fclose(stream))) { - testDiag("fclose error: %s", strerror(errno)); -#ifdef vxWorks - testDiag("The above test fails if you don't cd to a writable directory"); - testDiag("before running the test. The next test will also fail..."); -#endif - } - - if (!testOk1((stream = fopen(report, "r")) != NULL)) { - testDiag("'%s' could not be opened for reading: %s", - report, strerror(errno)); - testSkip(6, "Can't reopen stream file."); - return; - } - - if (!testOk1(fgets(linebuf, buflen, stream) != NULL)) { - testDiag("File read error: %s", strerror(errno)); - testSkip(5, "Read failed."); - fclose(stream); - return; - } - testOk(strcmp(linebuf, LINE_1) == 0, "First line correct"); - - if (!testOk1(fgets(linebuf, buflen, stream) != NULL)) { - testDiag("File read error: %s", strerror(errno)); - testSkip(1, "No line to compare."); - } else - testOk(strcmp(linebuf, LINE_2) == 0, "Second line"); - - testOk(!fgets(linebuf, buflen, stream), "File ends"); - - if (!testOk1(!fclose(stream))) - testDiag("fclose error: %s\n", strerror(errno)); -} - -MAIN(epicsStdioTest) -{ - testPlan(163); - testEpicsSnprintf(); -#ifdef __rtems__ - /* ensure there is a writeable area */ - mkdir( "/tmp", S_IRWXU ); - testStdoutRedir("/tmp/report"); -#else - testStdoutRedir("report"); -#endif - return testDone(); -} diff --git a/src/libCom/test/epicsStdlibTest.c b/src/libCom/test/epicsStdlibTest.c deleted file mode 100644 index d82f834b8..000000000 --- a/src/libCom/test/epicsStdlibTest.c +++ /dev/null @@ -1,567 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsStdlibTest.c - * - * Author Andrew Johnson - */ - -#include -#include -#include -#include - -#include "epicsTypes.h" -#include "epicsStdlib.h" -#include "epicsMath.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -/* Implement the epicsParseDouble() API for checking the native stdtod() - * so we can tell the user if our epicsStrtod() wrapper is unnecessary. - */ -int -parseStrtod(const char *str, double *to, char **units) -{ - int c; - char *endp; - double value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = strtod(str, &endp); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == ERANGE) - return (value == 0) ? S_stdlib_underflow : S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} -#define scanStrtod(str, to) !parseStrtod(str, to, NULL) - - -MAIN(epicsStdlibTest) -{ - unsigned long u; - long l; - unsigned long long ull; - long long ll; - double d; - float f; - char *endp; - epicsInt8 i8; - epicsUInt8 u8; - epicsInt16 i16; - epicsUInt16 u16; - epicsInt32 i32; - epicsUInt32 u32; - epicsInt64 i64; - epicsUInt64 u64; - - testPlan(199); - - testOk(epicsParseLong("", &l, 0, NULL) == S_stdlib_noConversion, - "Long '' => noConversion"); - testOk(epicsParseULong("", &u, 0, NULL) == S_stdlib_noConversion, - "ULong '' => noConversion"); - testOk(epicsParseLLong("", &ll, 0, NULL) == S_stdlib_noConversion, - "LLong '' => noConversion"); - testOk(epicsParseULLong("", &ull, 0, NULL) == S_stdlib_noConversion, - "ULLong '' => noConversion"); - testOk(epicsParseFloat("", &f, NULL) == S_stdlib_noConversion, - "Float '' => noConversion"); - testOk(epicsParseDouble("", &d, NULL) == S_stdlib_noConversion, - "Double '' => noConversion"); - - testOk(epicsParseLong("\t \n", &l, 0, NULL) == S_stdlib_noConversion, - "Long '\\t 1\\n' => noConversion"); - testOk(epicsParseULong("\t \n", &u, 0, NULL) == S_stdlib_noConversion, - "ULong '\\t 1\\n' => noConversion"); - testOk(epicsParseLLong("\t \n", &ll, 0, NULL) == S_stdlib_noConversion, - "LLong '\\t 1\\n' => noConversion"); - testOk(epicsParseULLong("\t \n", &ull, 0, NULL) == S_stdlib_noConversion, - "ULLong '\\t 1\\n' => noConversion"); - testOk(epicsParseFloat("\t \n", &f, NULL) == S_stdlib_noConversion, - "Float '\\t 1\\n' => noConversion"); - testOk(epicsParseDouble("\t \n", &d, NULL) == S_stdlib_noConversion, - "Double '\\t 1\\n' => noConversion"); - - testOk(epicsParseLong("!", &l, 0, NULL) == S_stdlib_noConversion, - "Long '!' => noConversion"); - testOk(epicsParseULong("!", &u, 0, NULL) == S_stdlib_noConversion, - "ULong '!' => noConversion"); - testOk(epicsParseLLong("!", &ll, 0, NULL) == S_stdlib_noConversion, - "LLong '!' => noConversion"); - testOk(epicsParseULLong("!", &ull, 0, NULL) == S_stdlib_noConversion, - "ULLong '!' => noConversion"); - testOk(epicsParseFloat("!", &f, NULL) == S_stdlib_noConversion, - "Float '!' => noConversion"); - testOk(epicsParseDouble("!", &d, NULL) == S_stdlib_noConversion, - "Double '!' => noConversion"); - - testOk(epicsScanLong("0", &l, 0) && l == 0, "Long '0'"); - testOk(epicsScanULong("0", &u, 0) && u == 0, "ULong '0'"); - testOk(epicsScanLLong("0", &ll, 0) && ll == 0, "LLong '0'"); - testOk(epicsScanULLong("0", &ull, 0) && ull == 0, "ULLong '0'"); - testOk(epicsScanFloat("0", &f) && f == 0, "Float '0'"); - testOk(epicsScanDouble("0", &d) && d == 0, "Double '0'"); - - testOk(epicsScanLong("\t 1\n", &l, 0) && l == 1, "Long '\\t 1\\n'"); - testOk(epicsScanULong("\t 1\n", &u, 0) && u == 1, "ULong '\\t 1\\n'"); - testOk(epicsScanLLong("\t 1\n", &ll, 0) && ll == 1, "LLong '\\t 1\\n'"); - testOk(epicsScanULLong("\t 1\n", &ull, 0) && ull == 1, "ULLong '\\t 1\\n'"); - testOk(epicsScanFloat("\t 1\n", &f) && f == 1, "Float '\\t 1\\n'"); - testOk(epicsScanDouble("\t 1\n", &d) && d == 1, "Double '\\t 1\\n'"); - - testOk(epicsScanLong("-1", &l, 0) && l == -1, "Long '-1'"); - testOk(epicsScanULong("-1", &u, 0) && u + 1 == 0, "ULong '-1'"); - testOk(epicsScanLLong("-1", &ll, 0) && ll == -1, "LLong '-1'"); - testOk(epicsScanULLong("-1", &ull, 0) && ull + 1 == 0, "ULLong '-1'"); - testOk(epicsScanFloat("-1", &f) && f == -1, "Float '-1'"); - testOk(epicsScanDouble("-1", &d) && d == -1, "Double '-1'"); - - testOk(epicsParseLong("2!", &l, 0, NULL) == S_stdlib_extraneous, - "Long '2!' => extraneous"); - testOk(epicsParseULong("2!", &u, 0, NULL) == S_stdlib_extraneous, - "ULong '2!' => extraneous"); - testOk(epicsParseLLong("2!", &ll, 0, NULL) == S_stdlib_extraneous, - "LLong '2!' => extraneous"); - testOk(epicsParseULLong("2!", &ull, 0, NULL) == S_stdlib_extraneous, - "ULLong '2!' => extraneous"); - testOk(epicsParseFloat("2!", &f, NULL) == S_stdlib_extraneous, - "Float '2!' => extraneous"); - testOk(epicsParseDouble("2!", &d, NULL) == S_stdlib_extraneous, - "Double '2!' => extraneous"); - - testOk(epicsParseLong("3 \n\t!", &l, 0, NULL) == S_stdlib_extraneous, - "Long '3 \\n\\t!' => extraneous"); - testOk(epicsParseULong("3 \n\t!", &u, 0, NULL) == S_stdlib_extraneous, - "ULong '3 \\n\\t!' => extraneous"); - testOk(epicsParseLLong("3 \n\t!", &ll, 0, NULL) == S_stdlib_extraneous, - "LLong '3 \\n\\t!' => extraneous"); - testOk(epicsParseULLong("3 \n\t!", &ull, 0, NULL) == S_stdlib_extraneous, - "ULLong '3 \\n\\t!' => extraneous"); - testOk(epicsParseFloat("3 \n\t!", &f, NULL) == S_stdlib_extraneous, - "Float '3 \\n\\t!' => extraneous"); - testOk(epicsParseDouble("3 \n\t!", &d, NULL) == S_stdlib_extraneous, - "Double '3 \\n\\t!' => extraneous"); - - testOk(!epicsParseLong("2!", &l, 0, &endp) && *endp == '!', - "Long '2!' => units='!'"); - testOk(!epicsParseULong("2!", &u, 0, &endp) && *endp == '!', - "ULong '2!' => units='!'"); - testOk(!epicsParseLLong("2!", &ll, 0, &endp) && *endp == '!', - "LLong '2!' => units='!'"); - testOk(!epicsParseULLong("2!", &ull, 0, &endp) && *endp == '!', - "ULLong '2!' => units='!'"); - testOk(!epicsParseFloat("2!", &f, &endp) && *endp == '!', - "Float '2!' => units='!'"); - testOk(!epicsParseDouble("2!", &d, &endp) && *endp == '!', - "Double '2!' => units='!'"); - - testOk(!epicsParseLong("3 \n\t!", &l, 0, &endp) && *endp == '!', - "Long '3 \\n\\t!' => units='!'"); - testOk(!epicsParseULong("3 \n\t!", &u, 0, &endp) && *endp == '!', - "ULong '3 \\n\\t!' => units='!'"); - testOk(!epicsParseLLong("3 \n\t!", &ll, 0, &endp) && *endp == '!', - "LLong '3 \\n\\t!' => units='!'"); - testOk(!epicsParseULLong("3 \n\t!", &ull, 0, &endp) && *endp == '!', - "ULLong '3 \\n\\t!' => units='!'"); - testOk(!epicsParseFloat("3 \n\t!", &f, &endp) && *endp == '!', - "Float '3 \\n\\t!' => units='!'"); - testOk(!epicsParseDouble("3 \n\t!", &d, &endp) && *endp == '!', - "Double '3 \\n\\t!' => units='!'"); - - testOk(epicsScanLong("0x0", &l, 0) && l == 0, "Long '0x0'"); - testOk(epicsScanULong("0x0", &u, 0) && u == 0, "ULong '0x0'"); - testOk(epicsScanLLong("0x0", &ll, 0) && ll == 0, "LLong '0x0'"); - testOk(epicsScanULLong("0x0", &ull, 0) && ull == 0, "ULLong '0x0'"); - testOk(epicsScanFloat("0x0", &f) && f == 0, "Float '0x0'"); - testOk(epicsScanDouble("0x0", &d) && d == 0, "Double '0x0'"); - - testOk(epicsScanLong("0x1", &l, 0) && l == 1, "Long '0x1'"); - testOk(epicsScanULong("0x1", &u, 0) && u == 1, "ULong '0x1'"); - testOk(epicsScanLLong("0x1", &ll, 0) && ll == 1, "LLong '0x1'"); - testOk(epicsScanULLong("0x1", &ull, 0) && ull == 1, "ULLong '0x1'"); - testOk(epicsScanFloat("0x1", &f) && f == 1, "Float '0x1'"); - testOk(epicsScanDouble("0x1", &d) && d == 1, "Double '0x1'"); - - testOk(epicsScanLong("+0x1", &l, 0) && l == 1, "Long '+0x1'"); - testOk(epicsScanULong("+0x1", &u, 0) && u == 1, "ULong '+0x1'"); - testOk(epicsScanLLong("+0x1", &ll, 0) && ll == 1, "LLong '+0x1'"); - testOk(epicsScanULLong("+0x1", &ull, 0) && ull == 1, "ULLong '+0x1'"); - testOk(epicsScanFloat("+0x1", &f) && f == 1, "Float '+0x1'"); - testOk(epicsScanDouble("+0x1", &d) && d == 1, "Double '+0x1'"); - - testOk(epicsScanLong("-0x1", &l, 0) && l == -1, "Long '-0x1'"); - testOk(epicsScanULong("-0x1", &u, 0) && u == -1, "ULong '-0x1'"); - testOk(epicsScanLLong("-0x1", &ll, 0) && ll == -1, "LLong '-0x1'"); - testOk(epicsScanULLong("-0x1", &ull, 0) && ull == -1, "ULLong '-0x1'"); - testOk(epicsScanFloat("-0x1", &f) && f == -1, "Float '-0x1'"); - testOk(epicsScanDouble("-0x1", &d) && d == -1, "Double '-0x1'"); - - testOk(epicsScanLong("0xf", &l, 0) && l == 15, "Long '0xf'"); - testOk(epicsScanULong("0xf", &u, 0) && u == 15, "ULong '0xf'"); - testOk(epicsScanLLong("0xf", &ll, 0) && ll == 15, "LLong '0xf'"); - testOk(epicsScanULLong("0xf", &ull, 0) && ull == 15, "ULLong '0xf'"); - testOk(epicsScanFloat("0xf", &f) && f == 15, "Float '0xf'"); - testOk(epicsScanDouble("0xf", &d) && d == 15, "Double '0xf'"); - - testOk(epicsScanLong("0XF", &l, 0) && l == 15, "Long '0XF'"); - testOk(epicsScanULong("0XF", &u, 0) && u == 15, "ULong '0XF'"); - testOk(epicsScanLLong("0XF", &ll, 0) && ll == 15, "LLong '0XF'"); - testOk(epicsScanULLong("0XF", &ull, 0) && ull == 15, "ULLong '0XF'"); - testOk(epicsScanFloat("0XF", &f) && f == 15, "Float '0XF'"); - testOk(epicsScanDouble("0XF", &d) && d == 15, "Double '0XF'"); - - testOk(epicsParseLong("0x0", &l, 10, NULL) == S_stdlib_extraneous, - "Long '0x0' in base 10 => extraneous"); - testOk(epicsParseULong("0x0", &u, 10, NULL) == S_stdlib_extraneous, - "ULong '0x0' in base 10 => extraneous"); - testOk(epicsParseLLong("0x0", &ll, 10, NULL) == S_stdlib_extraneous, - "LLong '0x0' in base 10 => extraneous"); - testOk(epicsParseULLong("0x0", &ull, 10, NULL) == S_stdlib_extraneous, - "ULLong '0x0' in base 10 => extraneous"); - - testOk(epicsScanLong("0x10", &l, 0) && l == 0x10, - "Long '0x10' in base 0"); - testOk(epicsScanULong("0x10", &u, 0) && u == 0x10, - "ULong '0x10' in base 0"); - testOk(epicsScanLong("0x10", &l, 16) && l == 0x10, - "Long '0x10' in base 16"); - testOk(epicsScanULong("0x10", &u, 16) && u == 0x10, - "ULong '0x10' in base 16"); - testOk(epicsScanLong("10", &l, 16) && l == 0x10, - "Long '10' in base 16"); - testOk(epicsScanULong("10", &u, 16) && u == 0x10, - "ULong '10' in base 16"); - - testOk(epicsScanLong("0x7fffffff", &l, 0) && l == 0x7fffffff, - "Long '0x7fffffff'"); - testOk(epicsScanULong("0xffffffff", &u, 0) && u == 0xffffffff, - "ULong '0xffffffff'"); - testOk(epicsScanLLong("0x7fffffffffffffff", &ll, 0) && - ll == 0x7fffffffffffffffLL, "LLong '0x7fffffffffffffff'"); - testOk(epicsScanULLong("0xffffffffffffffff", &ull, 0) && - ull == 0xffffffffffffffffULL, "ULLong '0xffffffffffffffff'"); - testOk(epicsScanFloat("0xffffff", &f) && f == 0xffffff, - "Float '0xffffff'"); - testOk(epicsScanDouble("0xffffffff", &d) && d == 0xffffffff, - "Double '0xffffffff'"); - - testOk(epicsScanLong("-0x7fffffff", &l, 0) && l == -0x7fffffff, - "Long '-0x7fffffff'"); - testOk(epicsScanULong("-0x7fffffff", &u, 0) && u == -0x7fffffff, - "ULong '-0x7fffffff'"); - testOk(epicsScanLLong("-0x7fffffffffffffff", &ll, 0) - && ll == -0x7fffffffffffffffLL, "LLong '-0x7fffffffffffffff'"); - testOk(epicsScanULLong("-0x7fffffffffffffff", &ull, 0) && - ull == -0x7fffffffffffffffULL, "ULLong '-0x7fffffffffffffff'"); - testOk(epicsScanFloat("-0xffffff", &f) && f == -0xffffff, - "Float '-0xffffff'"); - testOk(epicsScanDouble("-0x7fffffff", &d) && d == -0x7fffffff, - "Double '-0x7fffffff'"); - - testOk(!epicsParseInt8("0x7f", &i8, 0, NULL) && i8 == 0x7f, - "Int8 '0x7f'"); - testOk(!epicsParseInt8("-0x80", &i8, 0, NULL) && ((i8 + 0x80) & 0xff) == 0, - "Int8 '-0x80'"); - testOk(!epicsParseUInt8("0xff", &u8, 0, NULL) && u8 == 0xff, - "UInt8 '0xff'"); - testOk(!epicsParseUInt8("-1", &u8, 0, NULL) && u8 == 0xff, - "UInt8 '-1'"); - testOk(epicsParseInt8("0x80", &i8, 0, NULL) == S_stdlib_overflow, - "Int8 '0x80' => overflow"); - testOk(epicsParseInt8("-0x81", &i8, 0, NULL) == S_stdlib_overflow, - "Int8 '-0x81' => overflow"); - testOk(epicsParseUInt8("0x100", &u8, 0, NULL) == S_stdlib_overflow, - "UInt8 '0x100' => overflow"); - testOk(epicsParseUInt8("-0x100", &u8, 0, NULL) == S_stdlib_overflow, - "UInt8 '-0x100' => overflow"); - - testOk(!epicsParseInt16("0x7fff", &i16, 0, NULL) && i16 == 0x7fff, - "Int16 '0x7fff'"); - testOk(!epicsParseInt16("-0x8000", &i16, 0, NULL) && i16 == -0x8000, - "Int16 '-0x8000'"); - testOk(!epicsParseUInt16("0xffff", &u16, 0, NULL) && u16 == 0xffff, - "UInt16 '0xffff'"); - testOk(!epicsParseUInt16("-1", &u16, 0, NULL) && u16 == 0xffff, - "UInt16 '-1'"); - testOk(epicsParseInt16("0x8000", &i16, 0, NULL) == S_stdlib_overflow, - "Int16 '0x8000' => overflow"); - testOk(epicsParseInt16("-0x8001", &i16, 0, NULL) == S_stdlib_overflow, - "Int16 '-0x8001' => overflow"); - testOk(epicsParseUInt16("0x10000", &u16, 0, NULL) == S_stdlib_overflow, - "UInt16 '0x10000' => overflow"); - testOk(epicsParseUInt16("-0x10000", &u16, 0, NULL) == S_stdlib_overflow, - "UInt16 '-0x10000' => overflow"); - - testOk(!epicsParseInt32("0x7fffffff", &i32, 0, NULL) && i32 == 0x7fffffff, - "Int32 '0x7fffffff'"); - testOk(!epicsParseInt32("-0x80000000", &i32, 0, NULL) && i32 == -0x80000000L, - "Int32 '-0x80000000'"); - testOk(!epicsParseUInt32("0xffffffff", &u32, 0, NULL) && u32 == 0xffffffff, - "UInt32 '0xffffffff'"); - testOk(!epicsParseUInt32("-1", &u32, 0, NULL) && u32 == 0xffffffffU, - "UInt32 '-1'"); - testOk(epicsParseInt32("0x80000000", &i32, 0, NULL) == S_stdlib_overflow, - "Int32 '0x80000000' => overflow"); - testOk(epicsParseInt32("-0x80000001", &i32, 0, NULL) == S_stdlib_overflow, - "Int32 '-0x80000001' => overflow"); - testOk(epicsParseUInt32("0x100000000", &u32, 0, NULL) == S_stdlib_overflow, - "UInt32 '0x100000000' => overflow"); - testOk(epicsParseUInt32("-0x100000000", &u32, 0, NULL) == S_stdlib_overflow, - "UInt32 '-0x100000000' => overflow"); - - testOk(!epicsParseInt64("0x7fffffffffffffff", &i64, 0, NULL) && - i64 == 0x7fffffffffffffffLL, "Int64 '0x7fffffffffffffff'"); - testOk(!epicsParseInt64("-0x8000000000000000", &i64, 0, NULL) && - i64 == -0x8000000000000000LL, "Int64 '-0x8000000000000000'"); - testOk(!epicsParseUInt64("0xffffffffffffffff", &u64, 0, NULL) && - u64 == 0xffffffffffffffffULL, "UInt64 '0xffffffffffffffff'"); - testOk(!epicsParseUInt64("-1", &u64, 0, NULL) && u64 == 0xffffffffffffffffULL, - "UInt64 '-1'"); - testOk(epicsParseInt64("0x8000000000000000", &i64, 0, NULL) == S_stdlib_overflow, - "Int64 '0x8000000000000000' => overflow"); - testOk(epicsParseInt64("-0x8000000000000001", &i64, 0, NULL) == S_stdlib_overflow, - "Int64 '-0x8000000000000001' => overflow"); - testOk(epicsParseUInt64("0x10000000000000000", &u64, 0, NULL) == S_stdlib_overflow, - "UInt64 '0x10000000000000000' => overflow"); - testOk(epicsParseUInt64("-0x10000000000000000", &u64, 0, NULL) == S_stdlib_overflow, - "UInt64 '-0x10000000000000000' => overflow"); - - testOk(epicsScanFloat(".1", &f) && fabs(f - 0.1) < 1e-7, - "Float '.1'"); - testOk(epicsScanDouble(".1", &d) && fabs(d - 0.1) < 1e-15, - "Double '.1'"); - - testOk(epicsScanFloat("0.1", &f) && fabs(f - 0.1) < 1e-7, - "Float '0.1'"); - testOk(epicsScanDouble("0.1", &d) && fabs(d - 0.1) < 1e-15, - "Double '0.1'"); - - testOk(epicsScanFloat("1e-1", &f) && fabs(f - 1e-1) < 1e-7, - "Float '1e-1'"); - testOk(epicsScanDouble("1e-1", &d) && fabs(d - 1e-1) < 1e-15, - "Double '1e-1'"); - - testOk(epicsScanFloat("-.1", &f) && fabs(f + 0.1) < 1e-7, - "Float '-.1'"); - testOk(epicsScanDouble("-.1", &d) && fabs(d + 0.1) < 1e-15, - "Double '-.1'"); - - testOk(epicsScanFloat("-0.1", &f) && fabs(f + 0.1) < 1e-7, - "Float '-0.1'"); - testOk(epicsScanDouble("-0.1", &d) && fabs(d + 0.1) < 1e-15, - "Double '-0.1'"); - - testOk(epicsScanFloat("-1e-1", &f) && fabs(f + 1e-1) < 1e-7, - "Float '-1e-1'"); - testOk(epicsScanDouble("-1e-1", &d) && fabs(d + 1e-1) < 1e-15, - "Double '-1e-1'"); - - testOk(epicsScanFloat("1e-30", &f) && fabs(f - 1e-30) < 1e-36, - "Float '1e-30'"); - testOk(epicsScanDouble("1e-300", &d) && fabs(d - 1e-300) < 1e-306, - "Double '1e-300'"); - - testOk(epicsParseFloat("1e-40", &f, NULL) == S_stdlib_underflow, - "Float '1e-40' => underflow"); - testOk(epicsParseDouble("1e-330", &d, NULL) == S_stdlib_underflow, - "Double '1e-330' => underflow"); - - testOk(epicsScanFloat("1e30", &f) && fabs(f - 1e30) < 1e24, - "Float '1e30'"); - testOk(epicsScanDouble("1e300", &d) && fabs(d - 1e300) < 1e285, - "Double '1e300'"); - - testOk(epicsParseFloat("1e40", &f, NULL) == S_stdlib_overflow, - "Float '1e40' => overflow"); - testOk(epicsParseDouble("1e310", &d, NULL) == S_stdlib_overflow, - "Double '1e330' => overflow"); - - testOk(epicsScanLong("2147483647", &l, 0) && l == 2147483647, - "Long '2147483647'"); - testOk(epicsScanLong("-2147483647", &l, 0) && l == -2147483647, - "Long '-2147483647'"); - testOk(epicsScanULong("4294967295", &u, 0) && u == 4294967295u, - "ULong '4294967295'"); - testOk(epicsScanFloat("16777214", &f) && f == 16777214.0, - "Float '16777214'"); - testOk(epicsScanFloat("16777215", &f) && f == 16777215.0, - "Float '16777215'"); - testOk(epicsScanFloat("-16777215", &f) && f == -16777215.0, - "Float '-16777215'"); - testOk(epicsScanFloat("-16777216", &f) && f == -16777216.0, - "Float '-16777216'"); - testOk(epicsScanDouble("4294967294", &d) && d == 4294967294.0, - "Double '4294967294'"); - testOk(epicsScanDouble("4294967295", &d) && d == 4294967295.0, - "Double '4294967295'"); - testOk(epicsScanDouble("-4294967295", &d) && d == -4294967295.0, - "Double '-4294967295'"); - testOk(epicsScanDouble("-4294967296", &d) && d == -4294967296.0, - "Double '-4294967296'"); - - testOk(epicsScanFloat("NAN", &f) && isnan(f), "Float 'NAN'"); - testOk(epicsScanDouble("NAN", &d) && isnan(d), "Double 'NAN'"); - testOk(epicsScanFloat("Nan", &f) && isnan(f), "Float 'Nan'"); - testOk(epicsScanDouble("Nan", &d) && isnan(d), "Double 'Nan'"); -#ifdef __rtems__ - testTodoBegin("RTEMS (newlib) parser doesn't recognise 'nan()'"); -#endif - testOk(epicsScanFloat("nan()", &f) && isnan(f), "Float 'nan()'"); - testOk(epicsScanDouble("nan()", &d) && isnan(d), "Double 'nan()'"); -#ifdef __rtems__ - testTodoEnd(); -#endif - - testOk(epicsScanFloat("INF", &f) && f == epicsINF, - "Float 'INF'"); - testOk(epicsScanDouble("INF", &d) && d == epicsINF, - "Double 'INF'"); - testOk(epicsScanFloat("Infinity", &f) && f == epicsINF, - "Float 'Infinity'"); - testOk(epicsScanDouble("Infinity", &d) && d == epicsINF, - "Double 'Infinity'"); - - testOk(epicsScanFloat("+INF", &f) && f == epicsINF, - "Float '+INF'"); - testOk(epicsScanDouble("+INF", &d) && d == epicsINF, - "Double '+INF'"); - testOk(epicsScanFloat("+Infinity", &f) && f == epicsINF, - "Float '+Infinity'"); - testOk(epicsScanDouble("+Infinity", &d) && d == epicsINF, - "Double '+Infinity'"); - - testOk(epicsScanFloat("-INF", &f) && f == -epicsINF, - "Float '-INF'"); - testOk(epicsScanDouble("-INF", &d) && d == -epicsINF, - "Double '-INF'"); - testOk(epicsScanFloat("-Infinity", &f) && f == -epicsINF, - "Float '-Infinity'"); - testOk(epicsScanDouble("-Infinity", &d) && d == -epicsINF, - "Double '-Infinity'"); - -#ifdef epicsStrtod -#define CHECK_STRTOD epicsStrtod != strtod - if (epicsStrtod == strtod) - testDiag("This target defines epicsStrtod as strtod"); - else - testDiag("This target defines its own epicsStrtod macro"); -#else -#define CHECK_STRTOD 1 - testDiag("This target compiles epicsStrtod()"); -#endif - - if (CHECK_STRTOD) { - int pass = 0, fail = 0; - -#define CHECK(ok, msg) if (ok) pass++; else fail++, testDiag(msg) - - testDiag("Checking the native strtod(), only failures shown:"); - - CHECK(parseStrtod("", &d, NULL) == S_stdlib_noConversion, - " not ok - strtod('') => noConversion"); - CHECK(parseStrtod("\t \n", &d, NULL) == S_stdlib_noConversion, - " not ok - strtod('\\t 1\\n') => noConversion"); - CHECK(parseStrtod("!", &d, NULL) == S_stdlib_noConversion, - " not ok - strtod('!') => noConversion"); - CHECK(scanStrtod("0", &d) && d == 0, - " not ok - strtod('0')"); - CHECK(scanStrtod("\t 1\n", &d) && d == 1, - " not ok - strtod('\\t 1\\n')"); - CHECK(parseStrtod("2!", &d, NULL) == S_stdlib_extraneous, - " not ok - strtod('2!') => extraneous"); - CHECK(parseStrtod("3 !", &d, NULL) == S_stdlib_extraneous, - " not ok - strtod('3 !') => extraneous"); - CHECK(!parseStrtod("2!", &d, &endp) && *endp == '!', - " not ok - strtod('2!') => units='!'"); - CHECK(!parseStrtod("3 \n\t!", &d, &endp) && *endp == '!', - " not ok - strtod('3 \\n\\t!') => units='!'"); - CHECK(scanStrtod("0x0", &d) && d == 0, - " not ok - strtod('0x0')"); - CHECK(scanStrtod("0x1", &d) && d == 1, - " not ok - strtod('0x1')"); - CHECK(scanStrtod("+0x1", &d) && d == 1, - " not ok - strtod('+0x1')"); - CHECK(scanStrtod("-0x1", &d) && d == -1, - " not ok - strtod('-0x1')"); - CHECK(scanStrtod("0xf", &d) && d == 15, - " not ok - strtod('0xf')"); - CHECK(scanStrtod("0XF", &d) && d == 15, - " not ok - strtod('0XF')"); - CHECK(scanStrtod("0xffffffff", &d) && d == 0xffffffff, - " not ok - strtod('0xffffffff')"); - CHECK(scanStrtod("-0x7fffffff", &d) && d == -0x7fffffffl, - " not ok - strtod('-0x7fffffff')"); - CHECK(scanStrtod(".1", &d) && fabs(d - 0.1) < 1e-15, - " not ok - strtod('.1')"); - CHECK(scanStrtod("0.1", &d) && fabs(d - 0.1) < 1e-15, - " not ok - strtod('0.1')"); - CHECK(scanStrtod("1e-1", &d) && fabs(d - 1e-1) < 1e-15, - " not ok - strtod('1e-1')"); - CHECK(scanStrtod("-.1", &d) && fabs(d + 0.1) < 1e-15, - " not ok - strtod('-.1')"); - CHECK(scanStrtod("-0.1", &d) && fabs(d + 0.1) < 1e-15, - " not ok - strtod('-0.1')"); - CHECK(scanStrtod("-1e-1", &d) && fabs(d + 1e-1) < 1e-15, - " not ok - strtod('-1e-1')"); - CHECK(scanStrtod("1e-300", &d) && fabs(d - 1e-300) < 1e-306, - " not ok - strtod('1e-300')"); - CHECK(parseStrtod("1e-400", &d, NULL) == S_stdlib_underflow, - " not ok - strtod('1e-400') => underflow"); - CHECK(scanStrtod("4294967294", &d) && d == 4294967294.0, - " not ok - strtod('4294967294')"); - CHECK(scanStrtod("4294967295", &d) && d == 4294967295.0, - " not ok - strtod('4294967295')"); - CHECK(scanStrtod("-4294967295", &d) && d == -4294967295.0, - " not ok - strtod('-4294967295')"); - CHECK(scanStrtod("-4294967296", &d) && d == -4294967296.0, - " not ok - strtod('-4294967296')"); - CHECK(scanStrtod("NAN", &d) && isnan(d), - " not ok - strtod('NAN')"); - CHECK(scanStrtod("Nan", &d) && isnan(d), - " not ok - strtod('Nan')"); - CHECK(scanStrtod("nan()", &d) && isnan(d), - " not ok - strtod('nan()')"); - CHECK(scanStrtod("INF", &d) && d == epicsINF, - " not ok - strtod('INF')"); - CHECK(scanStrtod("Infinity", &d) && d == epicsINF, - " not ok - strtod('Infinity')"); - CHECK(scanStrtod("+INF", &d) && d == epicsINF, - " not ok - strtod('+INF')"); - CHECK(scanStrtod("+Infinity", &d) && d == epicsINF, - " not ok - strtod('+Infinity')"); - CHECK(scanStrtod("-INF", &d) && d == -epicsINF, - " not ok - strtod('-INF')"); - CHECK(scanStrtod("-Infinity", &d) && d == -epicsINF, - " not ok - strtod('-Infinity')"); - - if (fail) - testDiag("The native strtod() passed %d and failed %d tests", - pass, fail); - else { - testDiag("The native strtod() passed all %d tests", pass); -#ifndef epicsStrtod - testDiag("The compiled epicsStrtod() should not be needed"); -#endif - } - } - - return testDone(); -} diff --git a/src/libCom/test/epicsStringTest.c b/src/libCom/test/epicsStringTest.c deleted file mode 100644 index 3e4aed7e7..000000000 --- a/src/libCom/test/epicsStringTest.c +++ /dev/null @@ -1,327 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Marty Kraimer - */ - -#include -#include -#include - -#include "epicsUnitTest.h" -#include "epicsString.h" -#include "testMain.h" - -static -void testChars(void) { - int i; - char input[2] = {0, 0}; - char escaped[20]; - char result[20]; - size_t s, t, needed; - - for (i = 255; i >= 0; --i) { - input[0] = i; - needed = epicsStrnEscapedFromRawSize(input, 1); - s = epicsStrnEscapedFromRaw(escaped, sizeof(escaped), input, 1); - t = epicsStrnRawFromEscaped(result, sizeof(result), escaped, s); - testOk(needed == s && t == 1 && - result[0] == input[0] && result[1] == 0, - "escaped char 0x%2.2x -> \"%s\" (%d) -> 0x%2.2x", - input[0] & 0xff, escaped, (int) needed, result[0] & 0xff); - } -} - -static -void testGlob(void) { - testOk1(epicsStrGlobMatch("xyz","xyz")); - testOk1(!epicsStrGlobMatch("xyz","xyzm")); - testOk1(!epicsStrGlobMatch("xyzm","xyz")); - testOk1(!epicsStrGlobMatch("","xyzm")); - testOk1(!epicsStrGlobMatch("xyz","")); - testOk1(epicsStrGlobMatch("","")); - - testOk1(epicsStrGlobMatch("","*")); - testOk1(!epicsStrGlobMatch("","?")); - testOk1(!epicsStrGlobMatch("","?*")); - - testOk1(epicsStrGlobMatch("hello","h*o")); - testOk1(!epicsStrGlobMatch("hello","h*x")); - testOk1(!epicsStrGlobMatch("hellx","h*o")); - - testOk1(epicsStrGlobMatch("hello","he?lo")); - testOk1(!epicsStrGlobMatch("hello","he?xo")); - testOk1(epicsStrGlobMatch("hello","he??o")); - testOk1(!epicsStrGlobMatch("helllo","he?lo")); - - testOk1(epicsStrGlobMatch("hello world","he*o w*d")); - testOk1(!epicsStrGlobMatch("hello_world","he*o w*d")); - testOk1(epicsStrGlobMatch("hello world","he**d")); - - testOk1(epicsStrGlobMatch("hello hello world","he*o w*d")); - - testOk1(!epicsStrGlobMatch("hello hello xorld","he*o w*d")); - - testOk1(epicsStrGlobMatch("hello","he*")); - testOk1(epicsStrGlobMatch("hello","*lo")); - testOk1(epicsStrGlobMatch("hello","*")); -} - -MAIN(epicsStringTest) -{ - const char * const empty = ""; - const char * const space = " "; - const char * const A = "A"; - const char * const ABCD = "ABCD"; - const char * const ABCDE = "ABCDE"; - const char * const a = "a"; - const char * const abcd = "abcd"; - const char * const abcde = "abcde"; - char result[8]; - char *s; - int status; - - testPlan(406); - - testChars(); - - testOk1(epicsStrnCaseCmp(empty, "", 0) == 0); - testOk1(epicsStrnCaseCmp(empty, "", 1) == 0); - testOk1(epicsStrnCaseCmp(space, empty, 1) > 0); - testOk1(epicsStrnCaseCmp(empty, space, 1) < 0); - testOk1(epicsStrnCaseCmp(a, A, 1) == 0); - testOk1(epicsStrnCaseCmp(a, A, 2) == 0); - testOk1(epicsStrnCaseCmp(abcd, ABCD, 2) == 0); - testOk1(epicsStrnCaseCmp(abcd, ABCD, 4) == 0); - testOk1(epicsStrnCaseCmp(abcd, ABCD, 1000) == 0); - testOk1(epicsStrnCaseCmp(abcd, ABCDE, 2) == 0); - testOk1(epicsStrnCaseCmp(abcd, ABCDE, 4) == 0); - testOk1(epicsStrnCaseCmp(abcd, ABCDE, 1000) < 0); - testOk1(epicsStrnCaseCmp(abcde, ABCD, 2) == 0); - testOk1(epicsStrnCaseCmp(abcde, ABCD, 4) == 0); - testOk1(epicsStrnCaseCmp(abcde, ABCD, 1000) > 0); - - testOk1(epicsStrCaseCmp(empty, "") == 0); - testOk1(epicsStrCaseCmp(a, A) == 0); - testOk1(epicsStrCaseCmp(abcd, ABCD) == 0); - testOk1(epicsStrCaseCmp(abcd, ABCDE) < 0); - testOk1(epicsStrCaseCmp(abcde, ABCD) > 0); - testOk1(epicsStrCaseCmp(abcde, "ABCDF") < 0); - - s = epicsStrDup(abcd); - testOk(strcmp(s, abcd) == 0 && s != abcd, "epicsStrDup"); - free(s); - - testOk1(epicsStrHash(abcd, 0) != epicsStrHash("bacd", 0)); - testOk1(epicsStrHash(abcd, 0) == epicsMemHash(abcde, 4, 0)); - testOk1(epicsStrHash(abcd, 0) != epicsMemHash("abcd\0", 5, 0)); - - testOk1(epicsStrnLen("abcd", 5)==4); - testOk1(epicsStrnLen("abcd", 4)==4); - testOk1(epicsStrnLen("abcd", 3)==3); - testOk1(epicsStrnLen("abcd", 0)==0); - - testGlob(); - - memset(result, 'x', sizeof(result)); - status = epicsStrnEscapedFromRaw(result, 0, ABCD, 4); - testOk(status == 4, "epicsStrnEscapedFromRaw(out, 0) -> %d (exp. 4)", status); - testOk(result[0] == 'x', " No output"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 0, ABCD, 4); - testOk(status == 0, "epicsStrnRawFromEscaped(out, 0) -> %d (exp. 0)", status); - testOk(result[0] == 'x', " No output"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnEscapedFromRaw(result, 1, ABCD, 4); - testOk(status == 4, "epicsStrnEscapedFromRaw(out, 1) -> %d (exp. 4)", status); - testOk(result[0] == 0, " 0-terminated"); - testOk(result[1] == 'x', " No overrun"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 1, ABCD, 4); - testOk(status == 0, "epicsStrnRawFromEscaped(out, 1) -> %d (exp. 0)", status); - testOk(result[0] == 0, " 0-terminated"); - testOk(result[1] == 'x', " No overrun"); - - testDiag("Testing size = epicsStrnEscapedFromRawSize"); - - status = epicsStrnEscapedFromRawSize(ABCD, 3); - testOk(status == 3, "size(\"ABCD\", 3) -> %d (exp. 3)", status); - status = epicsStrnEscapedFromRawSize(ABCD, 4); - testOk(status == 4, "size(\"ABCD\", 4) -> %d (exp. 4)", status); - status = epicsStrnEscapedFromRawSize(ABCD, 5); - testOk(status == 8, "size(\"ABCD\", 5) -> %d (exp. 8)", status); - - testDiag("Testing esc = epicsStrnEscapedFromRaw(out, 4, ...)"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnEscapedFromRaw(result, 4, ABCD, 3); - testOk(status == 3, "esc(\"ABCD\", 3) -> %d (exp. 3)", status); - testOk(result[3] == 0, " 0-terminated"); - testOk(result[4] == 'x', " No overrun"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnEscapedFromRaw(result, 4, ABCD, 4); - testOk(status == 4, "esc(\"ABCD\", 4) -> %d (exp. 4)", status); - testOk(result[3] == 0, " 0-terminated"); - testOk(result[4] == 'x', " No overrun"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnEscapedFromRaw(result, 4, ABCD, 5); - testOk(status == 8, "esc(\"ABCD\", 5) -> %d (exp. 8)", status); - testOk(result[3] == 0, " 0-terminated"); - testOk(result[4] == 'x', " No overrun"); - - testDiag("Testing raw = epicsStrnRawFromEscaped(out, 4, ...)"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, ABCD, 0); - testOk(status == 0, "raw(\"ABCD\", 0) -> %d (exp. 0)", status); - testOk(result[0] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, ABCD, 1); - testOk(status == 1, "raw(\"ABCD\", 1) -> %d (exp. 1)", status); - testOk(result[0] == 'A', " Char '%c' (exp. 'A')", result[0]); - testOk(result[1] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, ABCD, 2); - testOk(status == 2, "raw(\"ABCD\", 2) -> %d (exp. 2)", status); - testOk(result[0] == 'A', " Char '%c' (exp. 'A')", result[0]); - testOk(result[1] == 'B', " Char '%c' (exp. 'B')", result[1]); - testOk(result[2] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, ABCD, 3); - testOk(status == 3, "raw(\"ABCD\", 3) -> %d (exp. 3)", status); - testOk(result[0] == 'A', " Char '%c' (exp. 'A')", result[0]); - testOk(result[1] == 'B', " Char '%c' (exp. 'B')", result[1]); - testOk(result[2] == 'C', " Char '%c' (exp. 'C')", result[2]); - testOk(result[3] == 0, " 0-terminated"); - testOk(result[4] == 'x', " No write outside buffer"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, ABCD, 4); - testOk(status == 3, "raw(\"ABCD\", 4) -> %d (exp. 3)", status); - testOk(result[0] == 'A', " Char '%c' (exp. 'A')", result[0]); - testOk(result[1] == 'B', " Char '%c' (exp. 'B')", result[1]); - testOk(result[2] == 'C', " Char '%c' (exp. 'C')", result[2]); - testOk(result[3] == 0, " 0-terminated"); - testOk(result[4] == 'x', " No write outside buffer"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, ABCDE, 5); - testOk(status == 3, "raw(\"ABCDE\", 5) -> %d (exp. 3)", status); - testOk(result[0] == 'A', " Char '%c' (exp. 'A')", result[0]); - testOk(result[1] == 'B', " Char '%c' (exp. 'B')", result[1]); - testOk(result[2] == 'C', " Char '%c' (exp. 'C')", result[2]); - testOk(result[3] == 0, " 0-terminated"); - testOk(result[4] == 'x', " No write outside buffer"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "A", 2); - testOk(status == 1, "raw(\"A\", 2) -> %d (exp. 1)", status); - testOk(result[0] == 'A', " Char '%c' (exp. 'A')", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\123", 1); - testOk(status == 0, "raw(\"\\123\", 1) -> %d (exp. 0)", status); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\123", 2); - testOk(status == 1, "raw(\"\\123\", 2) -> %d (exp. 1)", status); - testOk(result[0] == 1, " Octal escape (got \\%03o)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\123", 3); - testOk(status == 1, "raw(\"\\123\", 3) -> %d (exp. 1)", status); - testOk(result[0] == 012, " Octal escape (got \\%03o)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\123", 4); - testOk(status == 1, "raw(\"\\123\", 4) -> %d (exp. 1)", status); - testOk(result[0] == 0123, " Octal escape (got \\%03o)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\812", 2); - testOk(status == 1, "raw(\"\\812\", 2) -> %d (exp. 1)", status); - testOk(result[0] == '8', " Escaped '%c')", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\182", 3); - testOk(status == 2, "raw(\"\\182\", 3) -> %d (exp. 2)", status); - testOk(result[0] == 1, " Octal escape (got \\%03o)", result[0]); - testOk(result[1] == '8', " Terminated with '%c'", result[1]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\128", 4); - testOk(status == 2, "raw(\"\\128\", 4) -> %d (exp. 2)", status); - testOk(result[0] == 012, " Octal escape (got \\%03o)", result[0]); - testOk(result[1] == '8', " Terminator char got '%c'", result[1]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x12", 1); - testOk(status == 0, "raw(\"\\x12\", 1) -> %d (exp. 0)", status); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x12", 2); - testOk(status == 0, "raw(\"\\x12\", 2) -> %d (exp. 0)", status); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x12", 3); - testOk(status == 1, "raw(\"\\x12\", 3) -> %d (exp. 1)", status); - testOk(result[0] == 1, " Hex escape (got \\x%x)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x12", 4); - testOk(status == 1, "raw(\"\\x12\", 4) -> %d (exp. 1)", status); - testOk(result[0] == 0x12," Hex escape (got \\x%x)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\xaF", 4); - testOk(status == 1, "raw(\"\\xaF\", 4) -> %d (exp. 1)", status); - testOk(result[0] == '\xaF'," Hex escape (got \\x%x)", result[0] & 0xFF); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x012", 5); - testOk(status == 1, "raw(\"\\x012\", 5) -> %d (exp. 1)", status); - testOk(result[0] == 0x12," Hex escape (got \\x%x)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x0012", 6); - testOk(status == 1, "raw(\"\\x0012\", 6) -> %d (exp. 1)", status); - testOk(result[0] == 0x12," Hex escape (got \\x%x)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x1g", 4); - testOk(status == 2, "raw(\"\\x1g\", 4) -> %d (exp. 2)", status); - testOk(result[0] == 1, " Hex escape (got \\x%x)", result[0]); - testOk(result[1] == 'g', " Terminator char got '%c'", result[1]); - testOk(result[status] == 0, " 0-terminated"); - - return testDone(); -} diff --git a/src/libCom/test/epicsThreadHooksTest.c b/src/libCom/test/epicsThreadHooksTest.c deleted file mode 100644 index b6ba833e0..000000000 --- a/src/libCom/test/epicsThreadHooksTest.c +++ /dev/null @@ -1,176 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 ITER Organization -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* epicsThreadHooksTest.c */ - -#include - -#include "epicsThread.h" -#include "epicsExit.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#define MAX_THREADS 16 -#define TEST_THREADS 8 -#define NUM_HOOKS 4 - -static int order[MAX_THREADS][NUM_HOOKS]; -static int cnt[MAX_THREADS]; -static int mine[MAX_THREADS]; -static int mapped[MAX_THREADS]; -static epicsThreadId tid[MAX_THREADS]; - -static epicsMutexId tidLock; -static epicsEventId shutdown[TEST_THREADS]; - -static int newThreadIndex(epicsThreadId id) -{ - int i = 0; - - if (epicsMutexLock(tidLock)) - testAbort("newThreadIndex: Locking problem"); - - while (i < MAX_THREADS && tid[i] != 0) - i++; - if (i < MAX_THREADS) - tid[i] = id; - else - testAbort("newThreadIndex: Too many threads!"); - - epicsMutexUnlock(tidLock); - return i; -} - -static int findThreadIndex(epicsThreadId id) -{ - int i = 0; - - while (i < MAX_THREADS && tid[i] != id) - i++; - return i; -} - -static void atExitHook1 (void *arg) -{ - int no = findThreadIndex(epicsThreadGetIdSelf()); - - if (no < MAX_THREADS) - order[no][3] = cnt[no]++; -} - -static void atExitHook2 (void *arg) -{ - int no = findThreadIndex(epicsThreadGetIdSelf()); - - if (no < MAX_THREADS) - order[no][2] = cnt[no]++; -} - -static void startHook1 (epicsThreadId id) -{ - int no = newThreadIndex(id); - - if (no < MAX_THREADS) - order[no][0] = cnt[no]++; - epicsAtThreadExit(atExitHook1, NULL); -} - -static void startHook2 (epicsThreadId id) -{ - int no = findThreadIndex(id); - - if (no < MAX_THREADS) - order[no][1] = cnt[no]++; - epicsAtThreadExit(atExitHook2, NULL); -} - -static void my_thread (void *arg) -{ - int no = findThreadIndex(epicsThreadGetIdSelf()); - - if (no < MAX_THREADS) - mine[no] = 1; - epicsEventMustWait((epicsEventId) arg); -} - -static void mapper (epicsThreadId id) -{ - int no = findThreadIndex(id); - - if (no < MAX_THREADS) - mapped[no]++; -} - -MAIN(epicsThreadHooksTest) -{ - int i; - int ok; - - testPlan(TEST_THREADS + 1); - - tidLock = epicsMutexMustCreate(); - - if (epicsThreadHookAdd(startHook1)) - testAbort("startHook1 registration failed"); - if (epicsThreadHookAdd(startHook2)) - testAbort("startHook2 registration failed"); - - for (i = 0; i < TEST_THREADS; i++) { - char name[10]; - - shutdown[i] = epicsEventCreate(epicsEventEmpty); - sprintf(name, "t%d", (int) i); - epicsThreadCreate(name, epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), - my_thread, shutdown[i]); - } - epicsThreadSleep(1.0); - - epicsThreadMap(mapper); - - ok = 1; - for (i = 0; i < MAX_THREADS; i++) { - if (!mine[i]) continue; - - if (mapped[i] != 1) { - ok = 0; - testDiag("mapped[%d] = %d", i, mapped[i]); - } - } - testOk(ok, "All my tasks covered once by epicsThreadMap"); - - for (i = 0; i < TEST_THREADS; i++) { - epicsEventSignal(shutdown[i]); - } - - epicsThreadSleep(1.0); - - for (i = 0; i < MAX_THREADS; i++) { - int j; - - if (!mine[i]) continue; - - ok = 1; - for (j = 0; j < NUM_HOOKS; j++) { - if (order[i][j] != j) { - ok = 0; - testDiag("order[%d][%d] = %d", i, j, order[i][j]); - } - } - testOk(ok, "All hooks for task %d called in correct order", i); - } - - epicsThreadHookDelete(startHook1); - epicsThreadHookDelete(startHook2); - - return testDone(); -} diff --git a/src/libCom/test/epicsThreadOnceTest.c b/src/libCom/test/epicsThreadOnceTest.c deleted file mode 100644 index 2ecdf3a68..000000000 --- a/src/libCom/test/epicsThreadOnceTest.c +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "errlog.h" -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsMutex.h" -#include "epicsThread.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#define NUM_ONCE_THREADS 8 - -epicsThreadOnceId onceFlag = EPICS_THREAD_ONCE_INIT; -epicsThreadOnceId twiceFlag = EPICS_THREAD_ONCE_INIT; -epicsMutexId lock; -epicsEventId go; -epicsEventId done; - -int runCount = 0; -int initCount = 0; -char initBy[20]; -int doneCount = 0; - -void onceInit(void *ctx) -{ - initCount++; - strcpy(initBy, epicsThreadGetNameSelf()); -} - -void onceThread(void *ctx) -{ - epicsMutexMustLock(lock); - runCount++; - epicsMutexUnlock(lock); - - epicsEventMustWait(go); - epicsEventSignal(go); - - epicsThreadOnce(&onceFlag, onceInit, ctx); - testOk(initCount == 1, "%s: initCount = %d", - epicsThreadGetNameSelf(), initCount); - - epicsMutexMustLock(lock); - doneCount++; - if (doneCount == runCount) - epicsEventSignal(done); - epicsMutexUnlock(lock); -} - - -void recurseInit(void); -void onceRecurse(void *ctx) -{ - recurseInit(); -} - -void recurseInit(void) -{ - epicsThreadOnce(&twiceFlag, onceRecurse, 0); -} - -void recurseThread(void *ctx) -{ - recurseInit(); - testFail("Recursive epicsThreadOnce() not detected"); -} - - -MAIN(epicsThreadOnceTest) -{ - int i; - epicsThreadId tid; - - testPlan(3 + NUM_ONCE_THREADS); - - go = epicsEventMustCreate(epicsEventEmpty); - done = epicsEventMustCreate(epicsEventEmpty); - lock = epicsMutexMustCreate(); - - for (i = 0; i < NUM_ONCE_THREADS; i++) { - char name[20]; - - sprintf(name, "once-%d", i); - epicsThreadCreate(name, epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackSmall), - onceThread, 0); - } - epicsThreadSleep(0.1); - - testOk(runCount == NUM_ONCE_THREADS, "runCount = %d", runCount); - epicsEventSignal(go); /* Use epicsEventBroadcast(go) when available */ - epicsEventMustWait(done); - - testOk(doneCount == NUM_ONCE_THREADS, "doneCount = %d", doneCount); - testDiag("init was run by %s", initBy); - - eltc(0); - tid = epicsThreadCreate("recurse", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackSmall), - recurseThread, 0); - do { - epicsThreadSleep(0.1); - } while (!epicsThreadIsSuspended(tid)); - testPass("Recursive epicsThreadOnce() detected"); - - eltc(1); - return testDone(); -} diff --git a/src/libCom/test/epicsThreadPerform.cpp b/src/libCom/test/epicsThreadPerform.cpp deleted file mode 100644 index c8fd34515..000000000 --- a/src/libCom/test/epicsThreadPerform.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsThreadPerform.cpp */ - -/* sleep accuracy and sleep quantum tests by Jeff Hill */ -/* epicsThreadGetIdSelf performance by Jeff Hill */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsTime.h" -#include "errlog.h" -#include "testMain.h" - -static void testPriority(const char *who) -{ - epicsThreadId id; - unsigned int oldPriority,newPriority; - - id = epicsThreadGetIdSelf(); - oldPriority = epicsThreadGetPriority(id); - epicsThreadSetPriority(id,epicsThreadPriorityMax); - newPriority = epicsThreadGetPriority(id); - epicsThreadSetPriority(id,oldPriority); - printf("testPriority %s\n id %p old %u new %u\n", - who,id,oldPriority,newPriority); -} - -extern "C" void testPriorityThread(void *arg) -{ - testPriority("thread"); -} - -static void epicsThreadPriorityTest() -{ - testPriority("main error expected from epicsThreadSetPriority"); - epicsThreadCreate("testPriorityThread",epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium),testPriorityThread,0); - epicsThreadSleep(0.5); -} - - -static double threadSleepMeasureDelayError ( const double & delay ) -{ - epicsTime beg = epicsTime::getCurrent(); - epicsThreadSleep ( delay ); - epicsTime end = epicsTime::getCurrent(); - double meas = end - beg; - double error = fabs ( delay - meas ); - return error; -} - -static double measureSleepQuantum ( - const unsigned iterations, const double testInterval ) -{ - double errorSum = 0.0; - printf ( "Estimating sleep quantum" ); - fflush ( stdout ); - for ( unsigned i = 0u; i < iterations; i++ ) { - // try to guarantee a uniform probability density function - // by intentionally burning some CPU until we are less - // likely to be aligned with the schedualing clock - double interval = rand (); - interval /= RAND_MAX; - interval *= testInterval; - epicsTime start = epicsTime::getCurrent (); - epicsTime current = start; - while ( current - start < interval ) { - current = epicsTime::getCurrent (); - } - errorSum += threadSleepMeasureDelayError ( testInterval ); - if ( i % ( iterations / 10 ) == 0 ) { - printf ( "." ); - fflush ( stdout ); - } - } - printf ( "done\n" ); - - // with a uniform probability density function the - // sleep delay error mean is one half of the quantum - double quantumEstimate = 2 * errorSum / iterations; - return quantumEstimate; -} - -static void threadSleepQuantumTest () -{ - const double quantum = epicsThreadSleepQuantum (); - - double quantumEstimate = measureSleepQuantum ( 10, 10 * quantum ); - quantumEstimate = measureSleepQuantum ( 100, 2 * quantumEstimate ); - - double quantumError = fabs ( quantumEstimate - quantum ) / quantum; - const char * pTol = 0; - if ( quantumError > 0.1 ) { - pTol = "10%"; - } - else if ( quantumError > 0.01 ) { - pTol = "1%"; - } - else if ( quantumError > 0.001 ) { - pTol = "0.1%"; - } - if ( pTol ) { - printf ( - "The epicsThreadSleepQuantum() call returns %f sec.\n", - quantum ); - printf ( - "This doesnt match the quantum estimate " - "of %f sec within %s.\n", - quantumEstimate, pTol ); - } -} - - -static void threadSleepTest () -{ - static const int iterations = 20; - const double quantum = epicsThreadSleepQuantum (); - double errorSum = threadSleepMeasureDelayError ( 0.0 ); - for ( int i = 0u; i < iterations; i++ ) { - double delay = ldexp ( 1.0 , -i ); - double error = - threadSleepMeasureDelayError ( delay ); - errorSum += error; - if ( error > quantum + quantum / 8.0 ) { - printf ( "epicsThreadSleep ( %10f ) delay err %10f sec\n", - delay, error ); - } - } - double averageError = errorSum / ( iterations + 1 ); - if ( averageError > quantum ) { - printf ( "Average sleep delay error was %f sec\n", averageError ); - } -} - -static void epicsThreadGetIdSelfPerfTest () -{ - static const unsigned N = 10000; - static const double microSecPerSec = 1e6; - epicsTime begin = epicsTime::getCurrent (); - for ( unsigned i = 0u; i < N; i++ ) { - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - }; - epicsTime end = epicsTime::getCurrent (); - printf ( "It takes %f micro sec to call epicsThreadGetIdSelf ()\n", - microSecPerSec * ( end - begin ) / (10 * N) ); -} - - -static epicsThreadPrivate < bool > priv; - -static inline void callItTenTimes () -{ - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); -} - -static inline void callItTenTimesSquared () -{ - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); -} - -static void timeEpicsThreadPrivateGet () -{ - priv.set ( 0 ); - - epicsTime begin = epicsTime::getCurrent (); - static const unsigned N = 1000u; - for ( unsigned i = 0u; i < N; i++ ) { - callItTenTimesSquared (); - } - double delay = epicsTime::getCurrent() - begin; - delay /= N * 100u; // convert to sec per call - delay *= 1e6; // convert to micro sec - printf("epicsThreadPrivateGet() takes %f microseconds\n", delay); -} - - -MAIN(epicsThreadPerform) -{ - epicsThreadPriorityTest (); - threadSleepQuantumTest (); - threadSleepTest (); - epicsThreadGetIdSelfPerfTest (); - timeEpicsThreadPrivateGet (); - return 0; -} diff --git a/src/libCom/test/epicsThreadPoolTest.c b/src/libCom/test/epicsThreadPoolTest.c deleted file mode 100644 index 6a4f3f435..000000000 --- a/src/libCom/test/epicsThreadPoolTest.c +++ /dev/null @@ -1,447 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "epicsThreadPool.h" - -/* included to allow tests to peek */ -#include "../../pool/poolPriv.h" - -#include "testMain.h" -#include "epicsUnitTest.h" - -#include "cantProceed.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsThread.h" - -/* Do nothing */ -static void nullop(void) -{ - epicsThreadPool *pool; - testDiag("nullop()"); - { - epicsThreadPoolConfig conf; - epicsThreadPoolConfigDefaults(&conf); - testOk1(conf.maxThreads>0); - - testOk1((pool=epicsThreadPoolCreate(&conf))!=NULL); - if(!pool) - return; - } - - epicsThreadPoolDestroy(pool); -} - -/* Just create and destroy worker threads */ -static void oneop(void) -{ - epicsThreadPool *pool; - testDiag("oneop()"); - { - epicsThreadPoolConfig conf; - epicsThreadPoolConfigDefaults(&conf); - conf.initialThreads=2; - testOk1(conf.maxThreads>0); - - testOk1((pool=epicsThreadPoolCreate(&conf))!=NULL); - if(!pool) - return; - } - - epicsThreadPoolDestroy(pool); -} - -/* Test that Bursts of jobs will create enough threads to - * run all in parallel - */ -typedef struct { - epicsMutexId guard; - unsigned int count; - epicsEventId allrunning; - epicsEventId done; - epicsJob **job; -} countPriv; - -static void countjob(void *param, epicsJobMode mode) -{ - countPriv *cnt=param; - testOk1(mode==epicsJobModeRun||mode==epicsJobModeCleanup); - if(mode==epicsJobModeCleanup) - return; - - epicsMutexMustLock(cnt->guard); - testDiag("Job %lu", (unsigned long)cnt->count); - cnt->count--; - if(cnt->count==0) { - testDiag("All jobs running"); - epicsEventSignal(cnt->allrunning); - } - epicsMutexUnlock(cnt->guard); - - epicsEventMustWait(cnt->done); - epicsEventSignal(cnt->done); /* pass along to next thread */ -} - -/* Starts "mcnt" jobs in a pool with initial and max - * thread counts "icnt" and "mcnt". - * The test ensures that all jobs run in parallel. - * "cork" checks the function of pausing the run queue - * with epicsThreadPoolQueueRun - */ -static void postjobs(size_t icnt, size_t mcnt, int cork) -{ - size_t i; - epicsThreadPool *pool; - countPriv *priv=callocMustSucceed(1, sizeof(*priv), "postjobs priv alloc"); - priv->guard=epicsMutexMustCreate(); - priv->done=epicsEventMustCreate(epicsEventEmpty); - priv->allrunning=epicsEventMustCreate(epicsEventEmpty); - priv->count=mcnt; - priv->job=callocMustSucceed(mcnt, sizeof(*priv->job), "postjobs job array"); - - testDiag("postjobs(%lu,%lu)", (unsigned long)icnt, (unsigned long)mcnt); - - { - epicsThreadPoolConfig conf; - epicsThreadPoolConfigDefaults(&conf); - conf.initialThreads=icnt; - conf.maxThreads=mcnt; - - testOk1((pool=epicsThreadPoolCreate(&conf))!=NULL); - if(!pool) - return; - } - - if(cork) - epicsThreadPoolControl(pool, epicsThreadPoolQueueRun, 0); - - for(i=0; ijob[i] = epicsJobCreate(pool, &countjob, priv); - testOk1(priv->job[i]!=NULL); - testOk1(epicsJobQueue(priv->job[i])==0); - } - - if(cork) { - /* no jobs should have run */ - epicsMutexMustLock(priv->guard); - testOk1(priv->count==mcnt); - epicsMutexUnlock(priv->guard); - - epicsThreadPoolControl(pool, epicsThreadPoolQueueRun, 1); - } - - testDiag("Waiting for all jobs to start"); - epicsEventMustWait(priv->allrunning); - testDiag("Stop all"); - epicsEventSignal(priv->done); - - for(i=0; ijob[i]); - } - - epicsThreadPoolDestroy(pool); - epicsMutexDestroy(priv->guard); - epicsEventDestroy(priv->allrunning); - epicsEventDestroy(priv->done); - free(priv->job); - free(priv); -} - -static unsigned int flag0 = 0; - -/* Test cancel from job (no-op) - * and destroy from job (lazy free) - */ -static void cleanupjob0(void* arg, epicsJobMode mode) -{ - epicsJob *job=arg; - testOk1(mode==epicsJobModeRun||mode==epicsJobModeCleanup); - if(mode==epicsJobModeCleanup) - return; - - assert(flag0==0); - flag0=1; - - testOk1(epicsJobQueue(job)==0); - - epicsJobDestroy(job); /* delete while job is running */ -} -static void cleanupjob1(void* arg, epicsJobMode mode) -{ - epicsJob *job=arg; - testOk1(mode==epicsJobModeRun||mode==epicsJobModeCleanup); - if(mode==epicsJobModeCleanup) - return; - - testOk1(epicsJobQueue(job)==0); - - testOk1(epicsJobUnqueue(job)==0); - /* delete later after job finishes, but before pool is destroyed */ -} -static void cleanupjob2(void* arg, epicsJobMode mode) -{ - epicsJob *job=arg; - testOk1(mode==epicsJobModeRun||mode==epicsJobModeCleanup); - if(mode==epicsJobModeCleanup) - epicsJobDestroy(job); /* delete when threadpool is destroyed */ - else if(mode==epicsJobModeRun) - testOk1(epicsJobUnqueue(job)==S_pool_jobIdle); -} -static epicsJobFunction cleanupjobs[3] = {&cleanupjob0,&cleanupjob1,&cleanupjob2}; - -/* Tests three methods for job cleanup. - * 1. destroy which running - * 2. deferred cleanup after pool destroyed - * 3. immediate cleanup when pool destroyed - */ -static void testcleanup(void) -{ - int i=0; - epicsThreadPool *pool; - epicsJob *job[3]; - - testDiag("testcleanup()"); - - testOk1((pool=epicsThreadPoolCreate(NULL))!=NULL); - if(!pool) - return; - - /* unrolled so that valgrind can show which methods leaks */ - testOk1((job[0]=epicsJobCreate(pool, cleanupjobs[0], EPICSJOB_SELF))!=NULL); - testOk1((job[1]=epicsJobCreate(pool, cleanupjobs[1], EPICSJOB_SELF))!=NULL); - testOk1((job[2]=epicsJobCreate(pool, cleanupjobs[2], EPICSJOB_SELF))!=NULL); - for(i=0; i<3; i++) { - testOk1(epicsJobQueue(job[i])==0); - } - - epicsThreadPoolWait(pool, -1); - epicsJobDestroy(job[1]); - epicsThreadPoolDestroy(pool); -} - -/* Test re-add from inside job */ -typedef struct { - unsigned int count; - epicsEventId done; - epicsJob *job; - unsigned int inprogress; -} readdPriv; - -static void readdjob(void *arg, epicsJobMode mode) -{ - readdPriv *priv=arg; - testOk1(mode==epicsJobModeRun||mode==epicsJobModeCleanup); - if(mode==epicsJobModeCleanup) - return; - testOk1(priv->inprogress==0); - testDiag("count==%u", priv->count); - - if(priv->count--) { - priv->inprogress=1; - epicsJobQueue(priv->job); - epicsThreadSleep(0.05); - priv->inprogress=0; - }else{ - epicsEventSignal(priv->done); - epicsJobDestroy(priv->job); - } -} - -/* Test re-queueing a job while it is running. - * Check that a single job won't run concurrently. - */ -static void testreadd(void) { - epicsThreadPoolConfig conf; - epicsThreadPool *pool; - readdPriv *priv=callocMustSucceed(1, sizeof(*priv), "testcleanup priv"); - readdPriv *priv2=callocMustSucceed(1, sizeof(*priv), "testcleanup priv"); - - testDiag("testreadd"); - - priv->done=epicsEventMustCreate(epicsEventEmpty); - priv->count=5; - priv2->done=epicsEventMustCreate(epicsEventEmpty); - priv2->count=5; - - epicsThreadPoolConfigDefaults(&conf); - conf.maxThreads = 2; - testOk1((pool=epicsThreadPoolCreate(&conf))!=NULL); - if(!pool) - return; - - testOk1((priv->job=epicsJobCreate(pool, &readdjob, priv))!=NULL); - testOk1((priv2->job=epicsJobCreate(pool, &readdjob, priv2))!=NULL); - - testOk1(epicsJobQueue(priv->job)==0); - testOk1(epicsJobQueue(priv2->job)==0); - epicsEventMustWait(priv->done); - epicsEventMustWait(priv2->done); - - testOk1(epicsThreadPoolNThreads(pool)==2); - testDiag("epicsThreadPoolNThreads = %d", epicsThreadPoolNThreads(pool)); - - epicsThreadPoolDestroy(pool); - epicsEventDestroy(priv->done); - epicsEventDestroy(priv2->done); - free(priv); - free(priv2); - -} - -static int shouldneverrun = 0; -static int numtoolate = 0; - -/* test job canceling */ -static -void neverrun(void *arg, epicsJobMode mode) -{ - epicsJob *job=arg; - testOk1(mode==epicsJobModeCleanup); - if(mode==epicsJobModeCleanup) - epicsJobDestroy(job); - else - shouldneverrun++; -} -static epicsEventId cancel[2]; -static -void toolate(void *arg, epicsJobMode mode) -{ - epicsJob *job=arg; - if(mode==epicsJobModeCleanup){ - epicsJobDestroy(job); - return; - } - testPass("Job runs"); - numtoolate++; - epicsEventSignal(cancel[0]); - epicsEventMustWait(cancel[1]); -} - -static -void testcancel(void) -{ - epicsJob *job[2]; - epicsThreadPool *pool; - testOk1((pool=epicsThreadPoolCreate(NULL))!=NULL); - if(!pool) - return; - - cancel[0]=epicsEventCreate(epicsEventEmpty); - cancel[1]=epicsEventCreate(epicsEventEmpty); - - testOk1((job[0]=epicsJobCreate(pool, &neverrun, EPICSJOB_SELF))!=NULL); - testOk1((job[1]=epicsJobCreate(pool, &toolate, EPICSJOB_SELF))!=NULL); - - /* freeze */ - epicsThreadPoolControl(pool, epicsThreadPoolQueueRun, 0); - - testOk1(epicsJobUnqueue(job[0])==S_pool_jobIdle); /* not queued yet */ - - epicsJobQueue(job[0]); - testOk1(epicsJobUnqueue(job[0])==0); - testOk1(epicsJobUnqueue(job[0])==S_pool_jobIdle); - - epicsThreadSleep(0.01); - epicsJobQueue(job[0]); - testOk1(epicsJobUnqueue(job[0])==0); - testOk1(epicsJobUnqueue(job[0])==S_pool_jobIdle); - - epicsThreadPoolControl(pool, epicsThreadPoolQueueRun, 1); - - epicsJobQueue(job[1]); /* actually let it run this time */ - - epicsEventMustWait(cancel[0]); - testOk1(epicsJobUnqueue(job[0])==S_pool_jobIdle); - epicsEventSignal(cancel[1]); - - epicsThreadPoolDestroy(pool); - epicsEventDestroy(cancel[0]); - epicsEventDestroy(cancel[1]); - - testOk1(shouldneverrun==0); - testOk1(numtoolate==1); -} - -static -unsigned int sharedWasDeleted=0; - -static -void lastjob(void *arg, epicsJobMode mode) -{ - epicsJob *job=arg; - if(mode==epicsJobModeCleanup) { - sharedWasDeleted=1; - epicsJobDestroy(job); - } -} - -static -void testshared(void) -{ - epicsThreadPool *poolA, *poolB; - epicsThreadPoolConfig conf; - epicsJob *job; - - epicsThreadPoolConfigDefaults(&conf); - - testDiag("Check reference counting of shared pools"); - - testOk1((poolA=epicsThreadPoolGetShared(&conf))!=NULL); - - testOk1(poolA->sharedCount==1); - - testOk1((poolB=epicsThreadPoolGetShared(&conf))!=NULL); - - testOk1(poolA==poolB); - - testOk1(poolA->sharedCount==2); - - epicsThreadPoolReleaseShared(poolA); - - testOk1(poolB->sharedCount==1); - - testOk1((job=epicsJobCreate(poolB, &lastjob, EPICSJOB_SELF))!=NULL); - - epicsThreadPoolReleaseShared(poolB); - - testOk1(sharedWasDeleted==1); - - testOk1((poolA=epicsThreadPoolGetShared(&conf))!=NULL); - - testOk1(poolA->sharedCount==1); - - epicsThreadPoolReleaseShared(poolA); - -} - -MAIN(epicsThreadPoolTest) -{ - testPlan(171); - - nullop(); - oneop(); - testDiag("Queue with delayed start"); - postjobs(1,1,1); - postjobs(0,1,1); - postjobs(4,4,1); - postjobs(0,4,1); - postjobs(2,4,1); - testDiag("Queue with immediate start"); - postjobs(1,1,0); - postjobs(0,1,0); - postjobs(4,4,0); - postjobs(0,4,0); - postjobs(2,4,0); - testcleanup(); - testreadd(); - testcancel(); - testshared(); - - return testDone(); -} diff --git a/src/libCom/test/epicsThreadPriorityTest.cpp b/src/libCom/test/epicsThreadPriorityTest.cpp deleted file mode 100644 index 4f5a82d9e..000000000 --- a/src/libCom/test/epicsThreadPriorityTest.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsdThreadPriorityTest.cpp */ - -/* Author: Marty Kraimer Date: 21NOV2005 */ - -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsUnitTest.h" -#include "testMain.h" - - -typedef struct info { - epicsEventId waitForMaster; - epicsEventId waitForClient; -}info; - -extern "C" { - -static void client(void *arg) -{ - info *pinfo = (info *)arg; - epicsThreadId idSelf = epicsThreadGetIdSelf(); - int pass; - - for (pass = 0 ; pass < 3 ; pass++) { - epicsEventWaitStatus status; - status = epicsEventWait(pinfo->waitForMaster); - testOk(status == epicsEventWaitOK, - "task %p epicsEventWait returned %d", idSelf, status); - epicsThreadSleep(0.01); - epicsEventSignal(pinfo->waitForClient); - } -} - -static void runThreadPriorityTest(void *arg) -{ - epicsEventId testComplete = (epicsEventId) arg; - unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - - epicsThreadId myId = epicsThreadGetIdSelf(); - epicsThreadSetPriority(myId, 50); - - info *pinfo = (info *)calloc(1, sizeof(info)); - pinfo->waitForMaster = epicsEventMustCreate(epicsEventEmpty); - pinfo->waitForClient = epicsEventMustCreate(epicsEventEmpty); - - epicsThreadId clientId = epicsThreadCreate("client", - 50, stackSize, client, pinfo); - epicsEventSignal(pinfo->waitForMaster); - - epicsEventWaitStatus status; - status = epicsEventWaitWithTimeout(pinfo->waitForClient, 0.1); - if (!testOk(status == epicsEventWaitOK, - "epicsEventWaitWithTimeout returned %d", status)) { - testSkip(2, "epicsEventWaitWithTimeout failed"); - goto done; - } - - epicsThreadSetPriority(clientId, 20); - /* expect that client will not be able to run */ - epicsEventSignal(pinfo->waitForMaster); - - status = epicsEventTryWait(pinfo->waitForClient); - if (status != epicsEventWaitTimeout) { - testFail("epicsEventTryWait returned %d", status); - } else { - status = epicsEventWaitWithTimeout(pinfo->waitForClient, 0.1); - if (!testOk(status == epicsEventWaitOK, - "epicsEventWaitWithTimeout returned %d", status)) { - testSkip(1, "epicsEventWaitWithTimeout failed"); - goto done; - } - } - epicsThreadSetPriority(clientId, 80); - /* expect that client will be able to run */ - epicsEventSignal(pinfo->waitForMaster); - status = epicsEventTryWait(pinfo->waitForClient); - if (status==epicsEventWaitOK) { - testPass("Strict priority scheduler"); - } else { - testDiag("No strict priority scheduler"); - status = epicsEventWaitWithTimeout(pinfo->waitForClient,.1); - testOk(status == epicsEventWaitOK, - "epicsEventWaitWithTimeout returned %d", status); - } -done: - epicsThreadSleep(1.0); - epicsEventSignal(testComplete); -} - -} /* extern "C" */ - - -MAIN(epicsThreadPriorityTest) -{ - testPlan(7); - epicsEventId testComplete = epicsEventMustCreate(epicsEventEmpty); - epicsThreadMustCreate("threadPriorityTest", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), - runThreadPriorityTest, testComplete); - epicsEventWaitStatus status = epicsEventWait(testComplete); - testOk(status == epicsEventWaitOK, - "epicsEventWait returned %d", status); - return testDone(); -} diff --git a/src/libCom/test/epicsThreadPrivateTest.cpp b/src/libCom/test/epicsThreadPrivateTest.cpp deleted file mode 100644 index 7ce28f4fd..000000000 --- a/src/libCom/test/epicsThreadPrivateTest.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Jeff Hill Date: March 28 2001 */ - -#include - -#include "epicsTime.h" -#include "epicsThread.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -static epicsThreadPrivate < bool > priv; - -extern "C" void epicsThreadPrivateTestThread ( void * ) -{ - testOk1 ( NULL == priv.get () ); - bool var = true; - priv.set ( &var ); - testOk1 ( &var == priv.get () ); -} - -MAIN(epicsThreadPrivateTest) -{ - testPlan(5); - - bool var = false; - priv.set ( &var ); - testOk1 ( &var == priv.get() ); - - epicsThreadCreate ( "epicsThreadPrivateTest", epicsThreadPriorityMax, - epicsThreadGetStackSize ( epicsThreadStackSmall ), - epicsThreadPrivateTestThread, 0 ); - epicsThreadSleep ( 1.0 ); - testOk1 ( &var == priv.get() ); - - priv.set ( NULL ); - testOk1 ( NULL == priv.get() ); - - return testDone(); -} - diff --git a/src/libCom/test/epicsThreadTest.cpp b/src/libCom/test/epicsThreadTest.cpp deleted file mode 100644 index eb26cc8bf..000000000 --- a/src/libCom/test/epicsThreadTest.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsThreadTest.cpp */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsTime.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -static epicsThreadPrivate privateKey; - -class myThread: public epicsThreadRunable { -public: - myThread(int arg,const char *name); - virtual ~myThread(); - virtual void run(); - epicsThread thread; - epicsEvent startEvt; -private: - int *argvalue; -}; - -myThread::myThread(int arg,const char *name) : - thread(*this,name,epicsThreadGetStackSize(epicsThreadStackSmall),50+arg), - argvalue(0) -{ - argvalue = new int; - *argvalue = arg; - thread.start(); -} - -myThread::~myThread() {delete argvalue;} - -void myThread::run() -{ - startEvt.signal(); - int *pset = argvalue; - privateKey.set(argvalue); - epicsThreadSleep(2.0); - int *pget = privateKey.get(); - testOk1(pget == pset); - - epicsThreadId self = epicsThreadGetIdSelf(); - testOk1(thread.getPriority() == epicsThreadGetPriority(self)); -} - - -typedef struct info { - int isOkToBlock; -} info; - -extern "C" { -static void thread(void *arg) -{ - info *pinfo = (info *)arg; - - epicsThreadSetOkToBlock(pinfo->isOkToBlock); - epicsThreadSleep(1.0); - - testOk(epicsThreadIsOkToBlock() == pinfo->isOkToBlock, - "%s epicsThreadIsOkToBlock() = %d", - epicsThreadGetNameSelf(), pinfo->isOkToBlock); - epicsThreadSleep(0.1); -} -} - - -MAIN(epicsThreadTest) -{ - testPlan(9); - - unsigned int ncpus = epicsThreadGetCPUs(); - testDiag("System has %u CPUs", ncpus); - testOk1(ncpus > 0); - - const int ntasks = 3; - myThread *myThreads[ntasks]; - - int startPriority = 0; - for (int i = 0; i < ntasks; i++) { - char name[10]; - sprintf(name, "t%d", i); - myThreads[i] = new myThread(i, name); - if (i == 0) - startPriority = myThreads[i]->thread.getPriority(); - myThreads[i]->thread.setPriority(startPriority + i); - } - - for (int i = 0; i < ntasks; i++) { - myThreads[i]->startEvt.wait(); - myThreads[i]->thread.exitWait(); - delete myThreads[i]; - } - - unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - - info infoA = {0}; - epicsThreadCreate("threadA", 50, stackSize, thread, &infoA); - - info infoB = {1}; - epicsThreadCreate("threadB", 50, stackSize, thread, &infoB); - - epicsThreadSleep(2.0); - - return testDone(); -} diff --git a/src/libCom/test/epicsTimeTest.cpp b/src/libCom/test/epicsTimeTest.cpp deleted file mode 100644 index 55ad43cdd..000000000 --- a/src/libCom/test/epicsTimeTest.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Authors: Jeff Hill, Marty Kraimer and Andrew Johnson - */ -#include -#include -#include -#include -#include -#include - -#include "epicsTime.h" -#include "epicsThread.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -using namespace std; - -/* The functionality of the old invalidFormatTest () and badNanosecTest () - * routines is incorporated into epicsTimeTest () below. - */ - -struct l_fp { /* NTP time stamp */ - epicsUInt32 l_ui; /* sec past NTP epoch */ - epicsUInt32 l_uf; /* fractional seconds */ -}; - -static const unsigned mSecPerSec = 1000u; -static const unsigned uSecPerSec = 1000u * mSecPerSec; -static const unsigned nSecPerSec = 1000u * uSecPerSec; -static const double precisionEPICS = 1.0 / nSecPerSec; - -MAIN(epicsTimeTest) -{ - const int wasteTime = 100000; - const int nTimes = 10; - - testPlan(17 + nTimes * 19); - - try { - const epicsTimeStamp epochTS = {0, 0}; - epicsTime epochET = epochTS; - struct gm_tm_nano_sec epicsEpoch = epochET; - - testOk(epicsEpoch.ansi_tm.tm_sec == 0 && - epicsEpoch.ansi_tm.tm_min == 0 && - epicsEpoch.ansi_tm.tm_hour == 0 && - epicsEpoch.ansi_tm.tm_yday == 0 && - epicsEpoch.ansi_tm.tm_year == 90, - "epicsTime_gmtime() for EPICS epoch"); - } - catch ( ... ) { - testFail("epicsTime_gmtime() failed"); - testAbort("Can't continue, check your OS!"); - } - - { // badNanosecTest - static const char * pFormat = "%a %b %d %Y %H:%M:%S.%4f"; - try { - const epicsTimeStamp badTS = {1, 1000000000}; - epicsTime ts(badTS); - char buf [32]; - ts.strftime(buf, sizeof(buf), pFormat); - testFail("nanosecond overflow returned \"%s\"", buf); - } - catch ( ... ) { - testPass("nanosecond overflow throws"); - } - } - - { // strftime() output - char buf[80]; - epicsTime et; - - const char * pFormat = "%Y-%m-%d %H:%M:%S.%f"; - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "") == 0, "undefined => '%s'", buf); - - // This is Noon GMT, when all timezones have the same date - const epicsTimeStamp tTS = {12*60*60, 98765432}; - et = tTS; - pFormat = "%Y-%m-%d %S.%09f"; // %H and %M change with timezone - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "1990-01-01 00.098765432") == 0, "'%s' => '%s'", pFormat, buf); - - pFormat = "%S.%03f"; - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "00.099") == 0, "'%s' => '%s'", pFormat, buf); - - pFormat = "%S.%04f"; - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "00.0988") == 0, "'%s' => '%s'", pFormat, buf); - - pFormat = "%S.%05f"; - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "00.09877") == 0, "'%s' => '%s'", pFormat, buf); - - pFormat = "%S.%05f %S.%05f"; - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "00.09877 00.09877") == 0, "'%s' => '%s'", pFormat, buf); - - char smbuf[5]; - pFormat = "%S.%05f"; - et.strftime(smbuf, sizeof(smbuf), pFormat); - testOk(strcmp(smbuf, "00.*") == 0, "'%s' => '%s'", pFormat, smbuf); - - pFormat = "%S.%03f"; - (et + 0.9).strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "00.999") == 0, "0.998765 => '%s'", buf); - - pFormat = "%S.%03f"; - (et + 0.901).strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "00.999") == 0, "0.999765 => '%s'", buf); - - pFormat = "%%S.%%05f"; - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "%S.%05f") == 0, "'%s' => '%s'", pFormat, buf); - - char bigBuf [512]; - memset(bigBuf, '\a', sizeof(bigBuf)); - bigBuf[ sizeof(bigBuf) - 1] = '\0'; - et.strftime(buf, sizeof(buf), bigBuf); - testOk(strcmp(buf, "") == 0, "bad format => '%s'", buf); - } - - epicsTime now; - try { - now = epicsTime::getCurrent(); - testPass("default time provider"); - } - catch ( ... ) { - testFail("epicsTime::getCurrent() throws"); - testAbort("Can't continue, check your time provider"); - } - - { - l_fp ntp = now; - epicsTime tsf = ntp; - const double diff = fabs(tsf - now); - // the difference in the precision of the two time formats - static const double precisionNTP = 1.0 / (1.0 + 0xffffffff); - testOk1(diff <= precisionEPICS + precisionNTP); - } - - testDiag("Running %d loops", nTimes); - - const epicsTime begin = epicsTime::getCurrent(); - - for (int loop = 0; loop < nTimes; ++loop) { - for (int i = 0; i < wasteTime; ++i) { - now = epicsTime::getCurrent(); - } - - const double diff = now - begin; - - if (loop == 0) { - testDiag ("%d calls to epicsTime::getCurrent() " - "averaged %6.3f usec each", wasteTime, - diff * 1e6 / wasteTime); - } - - epicsTime copy = now; - testOk1(copy == now); - testOk1(copy <= now); - testOk1(copy >= now); - - testOk1(now > begin); - testOk1(now >= begin); - testOk1(begin != now); - testOk1(begin < now); - testOk1(begin <= now); - - testOk1(now - now == 0); - testOk(fabs((now - begin) - diff) < precisionEPICS * 0.01, - "now - begin ~= diff"); - - testOk1(begin + 0 == begin); - testOk1(begin + diff == now); - testOk1(now - 0 == now); - testOk1(now - diff == begin); - - epicsTime end = begin; - end += diff; - testOk(end == now, "(begin += diff) == now"); - - end = now; - end -= diff; - testOk(end == begin, "(now -= diff) == begin"); - - // test struct tm round-trip conversion - local_tm_nano_sec ansiDate = begin; - epicsTime beginANSI = ansiDate; - testOk1(beginANSI + diff == now); - - // test struct gmtm round-trip conversion - gm_tm_nano_sec ansiGmDate = begin; - epicsTime beginGMANSI = ansiGmDate; - testOk1(beginGMANSI + diff == now); - - // test struct timespec round-trip conversion - struct timespec ts = begin; - epicsTime beginTS = ts; - testOk1(beginTS + diff == now); - } - - epicsTime ten_years_hence; - try { - now = epicsTime::getCurrent(); - ten_years_hence = now + 60 * 60 * 24 * 3652.5; - testPass("epicsTime can represent 10 years hence"); - } - catch ( ... ) { - testFail("epicsTime exception for value 10 years hence"); - } - - try { - /* This test exists because in libCom/osi/os/posix/osdTime.cpp - * the convertDoubleToWakeTime() routine limits the timeout delay - * to 10 years. libCom/timer/timerQueue.cpp returns DBL_MAX for - * queues with no timers present, and convertDoubleToWakeTime() - * has to return an absolute Posix timestamp. On 2028-01-19 any - * systems that still implement time_t as a signed 32-bit integer - * will be unable to represent that timestamp, so this will fail. - */ - time_t_wrapper os_time_t = ten_years_hence; - epicsTime then = os_time_t; // No fractional seconds - double delta = ten_years_hence - then; - - testOk(delta >= 0 && delta < 1.0, - "OS time_t can represent 10 years hence"); - } - catch ( ... ) { - testFail("OS time_t conversion exception for value 10 years hence"); - } - - return testDone(); -} diff --git a/src/libCom/test/epicsTimeZoneTest.c b/src/libCom/test/epicsTimeZoneTest.c deleted file mode 100644 index 685295fc4..000000000 --- a/src/libCom/test/epicsTimeZoneTest.c +++ /dev/null @@ -1,131 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#include "envDefs.h" -#include "epicsTime.h" -#include "epicsUnitTest.h" - -#include "testMain.h" - -#if defined(_WIN32) -# define tzset _tzset -#endif - -static -void setTZ(const char *tz) -{ - testDiag("TZ = \"%s\"", tz); - epicsEnvSet("TZ", tz); - tzset(); -} - -static -void test_localtime(time_t T, int sec, int min, int hour, - int mday, int mon, int year, - int wday, int yday, int isdst) -{ - struct tm B; - testDiag("test_localtime(%ld, ...)", (long)T); - if(epicsTime_localtime(&T, &B)!=epicsTimeOK) { - testFail("epicsTime_localtime() error"); - testSkip(9, "epicsTime_localtime() failed"); - } else { - B.tm_year += 1900; /* for readability */ - testPass("epicsTime_localtime() success"); -#define TEST(FLD) testOk(B.tm_##FLD==FLD, "%s %d==%d", #FLD, B.tm_##FLD, FLD) - TEST(sec); - TEST(min); - TEST(hour); - TEST(mday); - TEST(mon); - TEST(year); - TEST(wday); - TEST(yday); - TEST(isdst); -#undef TEST - } -} - -static -void test_gmtime(time_t T, int sec, int min, int hour, - int mday, int mon, int year, - int wday, int yday, int isdst) -{ - struct tm B; - testDiag("test_gmtime(%ld, ...)", (long)T); - if(epicsTime_gmtime(&T, &B)!=epicsTimeOK) { - testFail("epicsTime_localtime() error"); - testSkip(9, "epicsTime_localtime() failed"); - } else { - B.tm_year += 1900; /* for readability */ - testPass("epicsTime_localtime() success"); -#define TEST(FLD) testOk(B.tm_##FLD==FLD, "%s %d==%d", #FLD, B.tm_##FLD, FLD) - TEST(sec); - TEST(min); - TEST(hour); - TEST(mday); - TEST(mon); - TEST(year); - TEST(wday); - TEST(yday); - TEST(isdst); -#undef TEST - } -} - -MAIN(epicsTimeZoneTest) -{ - testPlan(160); - /* 1445259616 - * Mon Oct 19 09:00:16 2015 EDT - * Mon Oct 19 08:00:16 2015 CDT - * Mon Oct 19 03:00:16 2015 HST (no dst) - * Mon Oct 19 13:00:16 2015 UTC - */ - testDiag("POSIX 1445259616"); - setTZ("EST5EDT"); - test_localtime(1445259616ul, 16, 0, 9, 19, 9, 2015, 1, 291, 1); - test_gmtime (1445259616ul, 16, 0, 13, 19, 9, 2015, 1, 291, 0); - setTZ("CST6CDT"); - test_localtime(1445259616ul, 16, 0, 8, 19, 9, 2015, 1, 291, 1); - test_gmtime (1445259616ul, 16, 0, 13, 19, 9, 2015, 1, 291, 0); -#if defined(__rtems__) - setTZ("HST10HST10"); -#else - setTZ("HST10"); -#endif - test_localtime(1445259616ul, 16, 0, 3, 19, 9, 2015, 1, 291, 0); - test_gmtime (1445259616ul, 16, 0, 13, 19, 9, 2015, 1, 291, 0); - setTZ("UTC0"); - test_localtime(1445259616ul, 16, 0, 13, 19, 9, 2015, 1, 291, 0); - test_gmtime (1445259616ul, 16, 0, 13, 19, 9, 2015, 1, 291, 0); - /* 1421244931 - * Wed Jan 14 09:15:31 2015 EST - * Wed Jan 14 08:15:31 2015 CST - * Wed Jan 14 04:15:31 2015 HST - * Wed Jan 14 14:15:31 2015 UTC - */ - testDiag("POSIX 1421244931"); - setTZ("EST5EDT"); - test_localtime(1421244931ul, 31, 15, 9, 14, 0, 2015, 3, 13, 0); - test_gmtime (1421244931ul, 31, 15, 14, 14, 0, 2015, 3, 13, 0); - setTZ("CST6CDT"); - test_localtime(1421244931ul, 31, 15, 8, 14, 0, 2015, 3, 13, 0); - test_gmtime (1421244931ul, 31, 15, 14, 14, 0, 2015, 3, 13, 0); -#if defined(__rtems__) - setTZ("HST10HST10"); -#else - setTZ("HST10"); -#endif - test_localtime(1421244931ul, 31, 15, 4, 14, 0, 2015, 3, 13, 0); - test_gmtime (1421244931ul, 31, 15, 14, 14, 0, 2015, 3, 13, 0); - setTZ("UTC0"); - test_localtime(1421244931ul, 31, 15, 14, 14, 0, 2015, 3, 13, 0); - test_gmtime (1421244931ul, 31, 15, 14, 14, 0, 2015, 3, 13, 0); - return testDone(); -} diff --git a/src/libCom/test/epicsTimerTest.cpp b/src/libCom/test/epicsTimerTest.cpp deleted file mode 100644 index f2a510819..000000000 --- a/src/libCom/test/epicsTimerTest.cpp +++ /dev/null @@ -1,462 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include -#include - -#include "epicsTimer.h" -#include "epicsEvent.h" -#include "epicsAssert.h" -#include "epicsGuard.h" -#include "tsFreeList.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#define verify(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -class notified : public epicsTimerNotify -{ -public: - bool done; - notified() : epicsTimerNotify(), done(false) {} - - expireStatus expire(const epicsTime ¤tTime) - {done=true; return expireStatus(noRestart);} -}; - -void testRefCount() -{ - notified action; - - epicsTimerQueueActive *Q1, *Q2; - epicsTimer *T1, *T2; - - Q1 = &epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin ); - - T1 = &Q1->createTimer(); - //timer->start(action, 0.0); - - Q2 = &epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin ); - - testOk1(Q1==Q2); - - T2 = &Q2->createTimer(); - - T2->destroy(); - Q2->release(); - - T1->destroy(); - Q1->release(); -} - -static const double delayVerifyOffset = 1.0; // sec - -class delayVerify : public epicsTimerNotify { -public: - delayVerify ( double expectedDelay, epicsTimerQueue & ); - void start ( const epicsTime &expireTime ); - void setBegin ( const epicsTime & ); - double delay () const; - double checkError () const; -protected: - virtual ~delayVerify (); -private: - epicsTimer &timer; - epicsTime beginStamp; - epicsTime expireStamp; - double expectedDelay; - expireStatus expire ( const epicsTime & ); - delayVerify ( const delayVerify & ); - delayVerify & operator = ( const delayVerify & ); -}; - -static volatile unsigned expireCount; -static epicsEvent expireEvent; - -delayVerify::delayVerify ( double expectedDelayIn, epicsTimerQueue &queueIn ) : - timer ( queueIn.createTimer() ), expectedDelay ( expectedDelayIn ) -{ -} - -delayVerify::~delayVerify () -{ - this->timer.destroy (); -} - -inline void delayVerify::setBegin ( const epicsTime &beginIn ) -{ - this->beginStamp = beginIn; -} - -inline double delayVerify::delay () const -{ - return this->expectedDelay; -} - -double delayVerify::checkError () const -{ - const double messageThresh = 2.0; // percent - double actualDelay = this->expireStamp - this->beginStamp; - double measuredError = actualDelay - this->expectedDelay; - double percentError = 100.0 * fabs ( measuredError ) / this->expectedDelay; - if ( ! testOk1 ( percentError < messageThresh ) ) { - testDiag ( "delay = %f s, error = %f s (%.1f %%)", - this->expectedDelay, measuredError, percentError ); - } - return measuredError; -} - -inline void delayVerify::start ( const epicsTime &expireTime ) -{ - this->timer.start ( *this, expireTime ); -} - -epicsTimerNotify::expireStatus delayVerify::expire ( const epicsTime ¤tTime ) -{ - this->expireStamp = currentTime; - if ( --expireCount == 0u ) { - expireEvent.signal (); - } - return noRestart; -} - -// -// verify reasonable timer interval accuracy -// -void testAccuracy () -{ - static const unsigned nTimers = 25u; - delayVerify *pTimers[nTimers]; - unsigned i; - unsigned timerCount = 0; - - testDiag ( "Testing timer accuracy" ); - - epicsTimerQueueActive &queue = - epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMax ); - - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i] = new delayVerify ( i * 0.1 + delayVerifyOffset, queue ); - timerCount += pTimers[i] ? 1 : 0; - } - testOk1 ( timerCount == nTimers ); - - expireCount = nTimers; - for ( i = 0u; i < nTimers; i++ ) { - epicsTime cur = epicsTime::getCurrent (); - pTimers[i]->setBegin ( cur ); - pTimers[i]->start ( cur + pTimers[i]->delay () ); - } - while ( expireCount != 0u ) { - expireEvent.wait (); - } - double averageMeasuredError = 0.0; - for ( i = 0u; i < nTimers; i++ ) { - averageMeasuredError += pTimers[i]->checkError (); - } - averageMeasuredError /= nTimers; - testDiag ("average timer delay error %f ms", - averageMeasuredError * 1000 ); - queue.release (); -} - - -class cancelVerify : public epicsTimerNotify { -public: - cancelVerify ( epicsTimerQueue & ); - void start ( const epicsTime &expireTime ); - void cancel (); - static unsigned cancelCount; - static unsigned expireCount; -protected: - virtual ~cancelVerify (); -private: - epicsTimer &timer; - expireStatus expire ( const epicsTime & ); - cancelVerify ( const cancelVerify & ); - cancelVerify & operator = ( const cancelVerify & ); -}; - -unsigned cancelVerify::cancelCount; -unsigned cancelVerify::expireCount; - -cancelVerify::cancelVerify ( epicsTimerQueue &queueIn ) : - timer ( queueIn.createTimer () ) -{ -} - -cancelVerify::~cancelVerify () -{ - this->timer.destroy (); -} - -inline void cancelVerify::start ( const epicsTime &expireTime ) -{ - this->timer.start ( *this, expireTime ); -} - -inline void cancelVerify::cancel () -{ - this->timer.cancel (); - ++cancelVerify::cancelCount; -} - -epicsTimerNotify::expireStatus cancelVerify::expire ( const epicsTime & ) -{ - ++cancelVerify::expireCount; - double root = 3.14159; - for ( unsigned i = 0u; i < 1000; i++ ) { - root = sqrt ( root ); - } - return noRestart; -} - -// -// verify that expire() won't be called after the timer is cancelled -// -void testCancel () -{ - static const unsigned nTimers = 25u; - cancelVerify *pTimers[nTimers]; - unsigned i; - unsigned timerCount = 0; - - cancelVerify::cancelCount = 0; - cancelVerify::expireCount = 0; - - testDiag ( "Testing timer cancellation" ); - - epicsTimerQueueActive &queue = - epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin ); - - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i] = new cancelVerify ( queue ); - timerCount += pTimers[i] ? 1 : 0; - } - testOk1 ( timerCount == nTimers ); - if ( ! testOk1 ( cancelVerify::expireCount == 0 ) ) - testDiag ( "expireCount = %u", cancelVerify::expireCount ); - if ( ! testOk1 ( cancelVerify::cancelCount == 0 ) ) - testDiag ( "cancelCount = %u", cancelVerify::cancelCount ); - - testDiag ( "starting %d timers", nTimers ); - epicsTime exp = epicsTime::getCurrent () + 4.0; - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i]->start ( exp ); - } - testOk1 ( cancelVerify::expireCount == 0 ); - testOk1 ( cancelVerify::cancelCount == 0 ); - - testDiag ( "cancelling timers" ); - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i]->cancel (); - } - testOk1 ( cancelVerify::expireCount == 0 ); - testOk1 ( cancelVerify::cancelCount == nTimers ); - - testDiag ( "waiting until after timers should have expired" ); - epicsThreadSleep ( 5.0 ); - testOk1 ( cancelVerify::expireCount == 0 ); - testOk1 ( cancelVerify::cancelCount == nTimers ); - - epicsThreadSleep ( 1.0 ); - queue.release (); -} - - -class expireDestroyVerify : public epicsTimerNotify { -public: - expireDestroyVerify ( epicsTimerQueue & ); - void start ( const epicsTime &expireTime ); - static unsigned destroyCount; -protected: - virtual ~expireDestroyVerify (); -private: - epicsTimer & timer; - expireStatus expire ( const epicsTime & ); - expireDestroyVerify ( const expireDestroyVerify & ); - expireDestroyVerify & operator = ( const expireDestroyVerify & ); -}; - -unsigned expireDestroyVerify::destroyCount; - -expireDestroyVerify::expireDestroyVerify ( epicsTimerQueue & queueIn ) : - timer ( queueIn.createTimer () ) -{ -} - -expireDestroyVerify::~expireDestroyVerify () -{ - this->timer.destroy (); - ++expireDestroyVerify::destroyCount; -} - -inline void expireDestroyVerify::start ( const epicsTime & expireTime ) -{ - this->timer.start ( *this, expireTime ); -} - -epicsTimerNotify::expireStatus expireDestroyVerify::expire ( const epicsTime & ) -{ - delete this; - return noRestart; -} - -// -// verify that a timer can be destroyed in expire -// -void testExpireDestroy () -{ - static const unsigned nTimers = 25u; - expireDestroyVerify *pTimers[nTimers]; - unsigned i; - unsigned timerCount = 0; - expireDestroyVerify::destroyCount = 0; - - testDiag ( "Testing timer destruction in expire()" ); - - epicsTimerQueueActive &queue = - epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin ); - - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i] = new expireDestroyVerify ( queue ); - timerCount += pTimers[i] ? 1 : 0; - } - testOk1 ( timerCount == nTimers ); - testOk1 ( expireDestroyVerify::destroyCount == 0 ); - - testDiag ( "starting %d timers", nTimers ); - epicsTime cur = epicsTime::getCurrent (); - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i]->start ( cur ); - } - - testDiag ( "waiting until all timers should have expired" ); - epicsThreadSleep ( 5.0 ); - - testOk1 ( expireDestroyVerify::destroyCount == nTimers ); - queue.release (); -} - - -class periodicVerify : public epicsTimerNotify { -public: - periodicVerify ( epicsTimerQueue & ); - void start ( const epicsTime &expireTime ); - void cancel (); - bool verifyCount (); -protected: - virtual ~periodicVerify (); -private: - epicsTimer &timer; - unsigned nExpire; - bool cancelCalled; - expireStatus expire ( const epicsTime & ); - periodicVerify ( const periodicVerify & ); - periodicVerify & operator = ( const periodicVerify & ); -}; - -periodicVerify::periodicVerify ( epicsTimerQueue & queueIn ) : - timer ( queueIn.createTimer () ), nExpire ( 0u ), - cancelCalled ( false ) -{ -} - -periodicVerify::~periodicVerify () -{ - this->timer.destroy (); -} - -inline void periodicVerify::start ( const epicsTime &expireTime ) -{ - this->timer.start ( *this, expireTime ); -} - -inline void periodicVerify::cancel () -{ - this->timer.cancel (); - this->cancelCalled = true; -} - -inline bool periodicVerify::verifyCount () -{ - return ( this->nExpire > 1u ); -} - -epicsTimerNotify::expireStatus periodicVerify::expire ( const epicsTime & ) -{ - this->nExpire++; - double root = 3.14159; - for ( unsigned i = 0u; i < 1000; i++ ) { - root = sqrt ( root ); - } - verify ( ! this->cancelCalled ); - double delay = rand (); - delay = delay / RAND_MAX; - delay /= 10.0; - return expireStatus ( restart, delay ); -} - -// -// verify periodic timers -// -void testPeriodic () -{ - static const unsigned nTimers = 25u; - periodicVerify *pTimers[nTimers]; - unsigned i; - unsigned timerCount = 0; - - testDiag ( "Testing periodic timers" ); - - epicsTimerQueueActive &queue = - epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin ); - - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i] = new periodicVerify ( queue ); - timerCount += pTimers[i] ? 1 : 0; - } - testOk1 ( timerCount == nTimers ); - - testDiag ( "starting %d timers", nTimers ); - epicsTime cur = epicsTime::getCurrent (); - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i]->start ( cur ); - } - - testDiag ( "waiting until all timers should have expired" ); - epicsThreadSleep ( 5.0 ); - - bool notWorking = false; - for ( i = 0u; i < nTimers; i++ ) { - notWorking |= ! pTimers[i]->verifyCount (); - pTimers[i]->cancel (); - } - testOk( ! notWorking, "All timers expiring" ); - epicsThreadSleep ( 1.0 ); - queue.release (); -} - -MAIN(epicsTimerTest) -{ - testPlan(41); - testRefCount(); - testAccuracy (); - testCancel (); - testExpireDestroy (); - testPeriodic (); - return testDone(); -} diff --git a/src/libCom/test/epicsTypesTest.c b/src/libCom/test/epicsTypesTest.c deleted file mode 100644 index aa882aa9f..000000000 --- a/src/libCom/test/epicsTypesTest.c +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsTypesTest.c - * - * Size-check epicsTypes - * - */ - -#include "epicsUnitTest.h" -#include "epicsTypes.h" -#include "testMain.h" -#include "epicsAssert.h" - -/* - * Might as well check at compile-time too, since we can. - */ - -STATIC_ASSERT(sizeof(epicsInt8) == 1); -STATIC_ASSERT(sizeof(epicsUInt8) == 1); -STATIC_ASSERT(sizeof(epicsInt16) == 2); -STATIC_ASSERT(sizeof(epicsUInt16) == 2); -STATIC_ASSERT(sizeof(epicsInt32) == 4); -STATIC_ASSERT(sizeof(epicsUInt32) == 4); -STATIC_ASSERT(sizeof(epicsInt64) == 8); -STATIC_ASSERT(sizeof(epicsUInt64) == 8); -STATIC_ASSERT(sizeof(epicsFloat32) == 4); -STATIC_ASSERT(sizeof(epicsFloat64) == 8); - -MAIN(epicsTypesTest) -{ - testPlan(10); - - testOk1(sizeof(epicsInt8) == 1); - testOk1(sizeof(epicsUInt8) == 1); - - testOk1(sizeof(epicsInt16) == 2); - testOk1(sizeof(epicsUInt16) == 2); - - testOk1(sizeof(epicsInt32) == 4); - testOk1(sizeof(epicsUInt32) == 4); - - testOk1(sizeof(epicsInt64) == 8); - testOk1(sizeof(epicsUInt64) == 8); - - testOk1(sizeof(epicsFloat32) == 4); - testOk1(sizeof(epicsFloat64) == 8); - - return testDone(); -} diff --git a/src/libCom/test/epicsUnitTestTest.c b/src/libCom/test/epicsUnitTestTest.c deleted file mode 100644 index b16bad52a..000000000 --- a/src/libCom/test/epicsUnitTestTest.c +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 The University of Chicago, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Andrew Johnson - * - * Test for the unit test module... - */ - -#include "epicsUnitTest.h" - -#define testOk1_success 1 -#define testOk1_failure 0 - -int main (void) { - testPlan(11); - testOk(1, "testOk(1)"); - testOk(0, "testOk(0)"); - testPass("testPass()"); - testFail("testFail()"); - testSkip(2, "Skipping two"); - testTodoBegin("Testing Todo"); - testOk(1, "Todo pass"); - testOk(0, "Todo fail"); - testSkip(1, "Todo skip"); - testTodoEnd(); - testOk1(testOk1_success); - testOk1(testOk1_failure); - testDiag("Diagnostic"); -/* testAbort("testAbort"); */ - return testDone(); -} diff --git a/src/libCom/test/epicsUnitTestTest.plt b/src/libCom/test/epicsUnitTestTest.plt deleted file mode 100644 index 1cb9e0c1b..000000000 --- a/src/libCom/test/epicsUnitTestTest.plt +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/perl - -use strict; -use Test; - -BEGIN {plan tests => 1} - -my $prog = "./$0"; -$prog =~ s/\.t$//; - -my $expected = join '', ; - -$ENV{HARNESS_ACTIVE} = 1; -my $result = `$prog`; - -ok($result, $expected); # test output matches - -__DATA__ -1..11 -ok 1 - testOk(1) -not ok 2 - testOk(0) -ok 3 - testPass() -not ok 4 - testFail() -ok 5 # SKIP Skipping two -ok 6 # SKIP Skipping two -ok 7 - Todo pass # TODO Testing Todo -not ok 8 - Todo fail # TODO Testing Todo -ok 9 # SKIP Todo skip -ok 10 - testOk1_success -not ok 11 - testOk1_failure -# Diagnostic diff --git a/src/libCom/test/fdmgrTest.c b/src/libCom/test/fdmgrTest.c deleted file mode 100644 index e41784ccf..000000000 --- a/src/libCom/test/fdmgrTest.c +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "fdmgr.h" -#include "epicsTime.h" -#include "epicsAssert.h" -#include "cadef.h" - -#define verify(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -static const unsigned uSecPerSec = 1000000; - -typedef struct cbStructCreateDestroyFD { - fdctx *pfdm; - int trig; -} cbStructCreateDestroyFD; - -void fdHandler (void *pArg) -{ - cbStructCreateDestroyFD *pCBFD = (cbStructCreateDestroyFD *) pArg; - - printf ("triggered\n"); - pCBFD->trig = 1; -} - -void fdCreateDestroyHandler (void *pArg, int fd, int open) -{ - cbStructCreateDestroyFD *pCBFD = (cbStructCreateDestroyFD *) pArg; - int status; - - if (open) { - printf ("new fd = %d\n", fd); - status = fdmgr_add_callback (pCBFD->pfdm, fd, fdi_read, fdHandler, pArg); - verify (status==0); - } - else { - printf ("terminated fd = %d\n", fd); - status = fdmgr_clear_callback (pCBFD->pfdm, fd, fdi_read); - verify (status==0); - } -} - -typedef struct cbStuctTimer { - epicsTimeStamp time; - int done; -} cbStruct; - -void alarmCB (void *parg) -{ - cbStruct *pCBS = (cbStruct *) parg; - epicsTimeGetCurrent (&pCBS->time); - pCBS->done = 1; -} - -void testTimer (fdctx *pfdm, double delay) -{ - int status; - fdmgrAlarmId aid; - struct timeval tmo; - epicsTimeStamp begin; - cbStruct cbs; - double measuredDelay; - double measuredError; - - epicsTimeGetCurrent (&begin); - cbs.done = 0; - tmo.tv_sec = (time_t) delay; - tmo.tv_usec = (unsigned long) ((delay - tmo.tv_sec) * uSecPerSec); - aid = fdmgr_add_timeout (pfdm, &tmo, alarmCB, &cbs); - verify (aid!=fdmgrNoAlarm); - - while (!cbs.done) { - tmo.tv_sec = (time_t) delay; - tmo.tv_usec = (unsigned long) ((delay - tmo.tv_sec) * uSecPerSec); - status = fdmgr_pend_event (pfdm, &tmo); - verify (status==0); - } - - measuredDelay = epicsTimeDiffInSeconds (&cbs.time, &begin); - measuredError = fabs (measuredDelay-delay); - printf ("measured delay for %lf sec was off by %lf sec (%lf %%)\n", - delay, measuredError, 100.0*measuredError/delay); -} - -int main (int argc, char **argv) -{ - int status; - fdctx *pfdm; - cbStructCreateDestroyFD cbsfd; - struct timeval tmo; - chid chan; - - pfdm = fdmgr_init (); - verify (pfdm); - - SEVCHK (ca_task_initialize(), NULL); - cbsfd.pfdm = pfdm; - SEVCHK (ca_add_fd_registration (fdCreateDestroyHandler, &cbsfd), NULL); - - /* - * timer test - */ - testTimer (pfdm, 0.001); - testTimer (pfdm, 0.01); - testTimer (pfdm, 0.1); - testTimer (pfdm, 1.0); - - if (argc==2) { - SEVCHK(ca_search (argv[1], &chan), NULL); - } - - while (1) { - tmo.tv_sec = 0; - tmo.tv_usec = 100000; - cbsfd.trig = 0; - status = fdmgr_pend_event (pfdm, &tmo); - verify (status==0); - ca_poll (); - } - - status = fdmgr_delete (pfdm); - verify (status==0); - - printf ( "Test Complete\n" ); - - return 0; -} - diff --git a/src/libCom/test/ipAddrToAsciiTest.cpp b/src/libCom/test/ipAddrToAsciiTest.cpp deleted file mode 100644 index f9323374d..000000000 --- a/src/libCom/test/ipAddrToAsciiTest.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2017 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#define EPICS_PRIVATE_API - -#include "epicsMutex.h" -#include "epicsGuard.h" -#include "epicsThread.h" -#include "epicsEvent.h" -#include "ipAddrToAsciiAsynchronous.h" - -#include "epicsUnitTest.h" -#include "testMain.h" - -namespace { - -typedef epicsGuard Guard; -typedef epicsGuardRelease UnGuard; - -struct CB : public ipAddrToAsciiCallBack -{ - const char *name; - epicsMutex mutex; - epicsEvent starter, blocker, complete; - bool started, cont, done; - CB(const char *name) : name(name), started(false), cont(false), done(false) {} - virtual ~CB() {} - virtual void transactionComplete ( const char * pHostName ) - { - Guard G(mutex); - started = true; - starter.signal(); - testDiag("In transactionComplete(%s) for %s", pHostName, name); - while(!cont) { - UnGuard U(G); - if(!blocker.wait(2.0)) - break; - } - done = true; - complete.signal(); - } - void waitStart() - { - Guard G(mutex); - while(!started) { - UnGuard U(G); - if(!starter.wait(2.0)) - break; - } - } - void poke() - { - testDiag("Poke"); - Guard G(mutex); - cont = true; - blocker.signal(); - } - void finish() - { - testDiag("Finish"); - Guard G(mutex); - while(!done) { - UnGuard U(G); - if(!complete.wait(2.0)) - break; - } - testDiag("Finished"); - } -}; - -// ensure that lookup of 127.0.0.1 works -void doLookup(ipAddrToAsciiEngine& engine) -{ - testDiag("In doLookup"); - - ipAddrToAsciiTransaction& trn(engine.createTransaction()); - CB cb("cb"); - osiSockAddr addr; - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - addr.ia.sin_port = htons(42); - - testDiag("Start lookup"); - trn.ipAddrToAscii(addr, cb); - cb.poke(); - cb.finish(); - testOk1(cb.cont); - testOk1(cb.done); - - trn.release(); -} - -// Test cancel of pending transaction -void doCancel() -{ - testDiag("In doCancel"); - - ipAddrToAsciiEngine& engine1(ipAddrToAsciiEngine::allocate()); - ipAddrToAsciiEngine& engine2(ipAddrToAsciiEngine::allocate()); - - ipAddrToAsciiTransaction& trn1(engine1.createTransaction()), - & trn2(engine2.createTransaction()); - testOk1(&trn1!=&trn2); - CB cb1("cb1"), cb2("cb2"); - - osiSockAddr addr; - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - addr.ia.sin_port = htons(42); - - // ensure that the worker thread is blocked with a transaction from engine1 - testDiag("Start lookup1"); - trn1.ipAddrToAscii(addr, cb1); - testDiag("Wait start1"); - cb1.waitStart(); - - testDiag("Start lookup2"); - trn2.ipAddrToAscii(addr, cb2); - - testDiag("release engine2, implicitly cancels lookup2"); - engine2.release(); - - cb2.poke(); - testDiag("Wait for lookup2 timeout"); - cb2.finish(); - testOk1(!cb2.done); - - testDiag("Complete lookup1"); - cb1.poke(); - cb1.finish(); - testOk1(cb1.done); - - engine1.release(); - - trn1.release(); - trn2.release(); -} - -} // namespace - -MAIN(ipAddrToAsciiTest) -{ - testPlan(5); - { - ipAddrToAsciiEngine& engine(ipAddrToAsciiEngine::allocate()); - doLookup(engine); - engine.release(); - } - doCancel(); - // TODO: somehow test cancel of in-progress callback - // allow time for any un-canceled transcations to crash us... - epicsThreadSleep(1.0); - -#ifdef __linux__ - ipAddrToAsciiEngine::cleanup(); -#endif - - return testDone(); -} diff --git a/src/libCom/test/macDefExpandTest.c b/src/libCom/test/macDefExpandTest.c deleted file mode 100644 index a5e45a420..000000000 --- a/src/libCom/test/macDefExpandTest.c +++ /dev/null @@ -1,254 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include - -#include "macLib.h" -#include "envDefs.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - - -static void checkMac(MAC_HANDLE *handle, const char *name, const char *value) -{ - char buf[20]; - - buf[19]='\0'; - if(macGetValue(handle, name, buf, 19)<0) { - if(value) - testFail("Macro %s undefined, expected %s", name, value); - else - testPass("Macro %s undefined", name); - } else { - if(!value) - testFail("Macro %s is %s, expected undefined", name, buf); - else if(strcmp(value, buf)==0) - testPass("Macro %s is %s", name, value); - else - testFail("Macro %s is %s, expected %s", name, buf, value); - } -} - -static void macEnvScope(void) -{ - MAC_HANDLE *handle; - char **defines; - static const char *pairs[] = { "", "environ", NULL, NULL }; - - epicsEnvSet("C","3"); - epicsEnvSet("D","4"); - epicsEnvSet("E","5"); - - macCreateHandle(&handle, pairs); - macParseDefns(NULL, "A=1,B=2,E=15", &defines); - macInstallMacros(handle, defines); - - checkMac(handle, "A", "1"); - checkMac(handle, "B", "2"); - checkMac(handle, "C", "3"); - checkMac(handle, "D", "4"); - checkMac(handle, "E", "15"); - checkMac(handle, "F", NULL); - - { - macPushScope(handle); - - macParseDefns(NULL, "A=11,C=13,D=14,G=7", &defines); - macInstallMacros(handle, defines); - - checkMac(handle, "A", "11"); - checkMac(handle, "B", "2"); - checkMac(handle, "C", "13"); - checkMac(handle, "D", "14"); - checkMac(handle, "E", "15"); - checkMac(handle, "F", NULL); - checkMac(handle, "G", "7"); - - epicsEnvSet("D", "24"); - macPutValue(handle, "D", NULL); /* implicit when called through in iocshBody */ - epicsEnvSet("F", "6"); - macPutValue(handle, "F", NULL); /* implicit */ - epicsEnvSet("G", "17"); - macPutValue(handle, "G", NULL); /* implicit */ - - checkMac(handle, "D", "24"); - checkMac(handle, "F", "6"); - checkMac(handle, "G", "17"); - - macPopScope(handle); - } - - checkMac(handle, "A", "1"); - checkMac(handle, "B", "2"); - checkMac(handle, "C", "3"); - checkMac(handle, "D", "24"); - checkMac(handle, "E", "15"); - checkMac(handle, "F", "6"); - checkMac(handle, "G", "17"); - - { - macPushScope(handle); - - macParseDefns(NULL, "D=34,G=27", &defines); - macInstallMacros(handle, defines); - - checkMac(handle, "D", "34"); - checkMac(handle, "G", "27"); - - macPopScope(handle); - } - - checkMac(handle, "D", "24"); - - macDeleteHandle(handle); -} - -static void check(const char *str, const char *macros, const char *expect) -{ - MAC_HANDLE *handle; - char **defines; - static const char *pairs[] = { "", "environ", NULL, NULL }; - char *got; - int pass = 1; - - macCreateHandle(&handle, pairs); - macParseDefns(NULL, macros, &defines); - macInstallMacros(handle, defines); - - got = macDefExpand(str, handle); - - if (expect && !got) { - testDiag("Got NULL, expected \"%s\".\n", expect); - pass = 0; - } - else if (!expect && got) { - testDiag("Got \"%s\", expected NULL.\n", got); - pass = 0; - } - else if (expect && got && strcmp(got, expect)) { - testDiag("Got \"%s\", expected \"%s\".\n", got, expect); - pass = 0; - } - testOk(pass, "%s", str); - - macDeleteHandle(handle); -} - -MAIN(macDefExpandTest) -{ - eltc(0); - testPlan(97); - - check("FOO", "", "FOO"); - - check("${FOO}", "", NULL); - check("${FOO,BAR}", "", NULL); - check("${FOO,BAR=baz}", "", NULL); - check("${FOO,BAR=$(FOO)}", "", NULL); - check("${FOO,FOO}", "", NULL); - check("${FOO,FOO=$(FOO)}", "", NULL); - check("${FOO,BAR=baz,FUM}", "", NULL); - - check("${=}", "", ""); - check("x${=}y", "", "xy"); - - check("${,=}", "", ""); - check("x${,=}y", "", "xy"); - - check("${FOO=}", "", ""); - check("x${FOO=}y", "", "xy"); - - check("${FOO=,}", "", ""); - check("x${FOO=,}y", "", "xy"); - - check("${FOO,FOO=}", "", ""); - check("x${FOO,FOO=}y", "", "xy"); - - check("${FOO=,BAR}", "", ""); - check("x${FOO=,BAR}y", "", "xy"); - - check("${FOO=$(BAR=)}", "", ""); - check("x${FOO=$(BAR=)}y", "", "xy"); - - check("${FOO=,BAR=baz}", "", ""); - check("x${FOO=,BAR=baz}y", "", "xy"); - - check("${FOO=$(BAR),BAR=}", "", ""); - check("x${FOO=$(BAR),BAR=}y", "", "xy"); - - check("${=BAR}", "", "BAR"); - check("x${=BAR}y", "", "xBARy"); - - check("${FOO=BAR}", "", "BAR"); - check("x${FOO=BAR}y", "", "xBARy"); - - epicsEnvSet("FOO","BLETCH"); - check("${FOO}", "", "BLETCH"); - check("${FOO,FOO}", "", "BLETCH"); - check("x${FOO}y", "", "xBLETCHy"); - check("x${FOO}y${FOO}z", "", "xBLETCHyBLETCHz"); - check("${FOO=BAR}", "", "BLETCH"); - check("x${FOO=BAR}y", "", "xBLETCHy"); - check("${FOO=${BAZ}}", "", "BLETCH"); - check("${FOO=${BAZ},BAR=$(BAZ)}", "", "BLETCH"); - check("x${FOO=${BAZ}}y", "", "xBLETCHy"); - check("x${FOO=${BAZ},BAR=$(BAZ)}y", "", "xBLETCHy"); - check("${BAR=${FOO}}", "", "BLETCH"); - check("x${BAR=${FOO}}y", "", "xBLETCHy"); - check("w${BAR=x${FOO}y}z", "", "wxBLETCHyz"); - - check("${FOO,FOO=BAR}", "", "BAR"); - check("x${FOO,FOO=BAR}y", "", "xBARy"); - check("${BAR,BAR=$(FOO)}", "", "BLETCH"); - check("x${BAR,BAR=$(FOO)}y", "", "xBLETCHy"); - check("${BAR,BAR=$($(FOO)),BLETCH=GRIBBLE}", "", "GRIBBLE"); - check("x${BAR,BAR=$($(FOO)),BLETCH=GRIBBLE}y", "", "xGRIBBLEy"); - check("${$(BAR,BAR=$(FOO)),BLETCH=GRIBBLE}", "", "GRIBBLE"); - check("x${$(BAR,BAR=$(FOO)),BLETCH=GRIBBLE}y", "", "xGRIBBLEy"); - - check("${FOO}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP"); - check("x${FOO}/${BAR}y", "BAR=GLEEP", "xBLETCH/GLEEPy"); - check("${FOO,BAR}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP"); - check("${FOO,BAR=x}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP"); - check("${BAZ=BLETCH,BAR}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP"); - check("${BAZ=BLETCH,BAR=x}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP"); - - check("${${FOO}}", "BAR=GLEEP,BLETCH=BAR", "BAR"); - check("x${${FOO}}y", "BAR=GLEEP,BLETCH=BAR", "xBARy"); - check("${${FOO}=GRIBBLE}", "BAR=GLEEP,BLETCH=BAR", "BAR"); - check("x${${FOO}=GRIBBLE}y", "BAR=GLEEP,BLETCH=BAR", "xBARy"); - - check("${${FOO}}", "BAR=GLEEP,BLETCH=${BAR}", "GLEEP"); - - epicsEnvSet("FOO","${BAR}"); - check("${FOO}", "BAR=GLEEP,BLETCH=${BAR}" ,"GLEEP"); - - check("${FOO}", "BAR=${BAZ},BLETCH=${BAR}", NULL); - - check("${FOO}", "BAR=${BAZ=GRIBBLE},BLETCH=${BAR}", "GRIBBLE"); - - check("${FOO}", "BAR=${STR1},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", "VAL1"); - - check("${FOO}", "BAR=${STR2},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", "VAL2"); - - check("${FOO}", "BAR=${FOO},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", NULL); - check("${FOO,FOO=$(FOO)}", "BAR=${FOO},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", NULL); - check("${FOO=$(FOO)}", "BAR=${FOO},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", NULL); - check("${FOO=$(BAR),BAR=$(FOO)}", "BAR=${FOO},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", NULL); - - macEnvScope(); - - errlogFlush(); - eltc(1); - return testDone(); -} diff --git a/src/libCom/test/macLibTest.c b/src/libCom/test/macLibTest.c deleted file mode 100644 index 7f1e2c544..000000000 --- a/src/libCom/test/macLibTest.c +++ /dev/null @@ -1,221 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include - -#include "macLib.h" -#include "dbDefs.h" -#include "envDefs.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -MAC_HANDLE *h; - -static void check(const char *str, const char *expect) -{ - char output[MAC_SIZE] = {'\0'}; - long status = macExpandString(h, str, output, MAC_SIZE); - long expect_len = strlen(expect+1); - int expect_error = (expect[0] == '!'); - int statBad = expect_error ^ (status < 0); - int strBad = strcmp(output, expect+1); - - testOk(!statBad && !strBad, "%s => %s", str, output); - - if (strBad) { - testDiag("Got \"%s\", expected \"%s\"", output, expect+1); - } - if (statBad) { - testDiag("Return status was %ld, expected %ld", - status, expect_error ? -expect_len : expect_len); - } -} - -static void ovcheck(void) -{ - char output[54]; - long status; - - macPutValue(h, "OVVAR","abcdefghijklmnopqrstuvwxyz"); - - memset(output, '~', sizeof output); - status = macExpandString(h, "abcdefghijklmnopqrstuvwxyz$(OVVAR)", output, 52); - testOk(status == 51, "expansion returned %ld, expected 51", status); - testOk(output[50] == 'y', "final character %x, expect 79 (y)", output[50]); - testOk(output[51] == '\0', "terminator character %x, expect 0", output[51]); - testOk(output[52] == '~', "sentinel character %x, expect 7e, (~)", output[52]); - - memset(output, '~', sizeof output); - status = macExpandString(h, "abcdefghijklmnopqrstuvwxyz$(OVVAR)", output, 53); - testOk(status == 52, "expansion returned %ld, expected 52", status); - testOk(output[51] == 'z', "final character %x, expect 7a (z)", output[51]); - testOk(output[52] == '\0', "terminator character %x, expect 0", output[52]); - testOk(output[53] == '~', "sentinel character %x, expect 7e, (~)", output[53]); -} - -MAIN(macLibTest) -{ - testPlan(91); - - if (macCreateHandle(&h, NULL)) - testAbort("macCreateHandle() failed"); - macSuppressWarning(h, TRUE); - - check("FOO", " FOO"); - - check("$(FOO)", "!$(FOO,undefined)"); - check("${FOO}", "!$(FOO,undefined)"); - check("${FOO=${FOO}}", "!$(FOO,undefined)"); - check("${FOO,FOO}", "!$(FOO,undefined)"); - check("${FOO,FOO=${FOO}}", "!$(FOO,recursive)"); - check("${FOO,BAR}", "!$(FOO,undefined)"); - check("${FOO,BAR=baz}", "!$(FOO,undefined)"); - check("${FOO,BAR=${FOO}}", "!$(FOO,undefined)"); - check("${FOO,BAR=baz,FUM}", "!$(FOO,undefined)"); - check("${FOO=${BAR},BAR=${FOO}}", "!$(FOO,undefined)"); - check("${FOO,FOO=${BAR},BAR=${FOO}}", "!$(BAR,recursive)"); - - check("${=}", " "); - check("x${=}y", " xy"); - - check("${,=}", " "); - check("x${,=}y", " xy"); - - check("${FOO=}", " "); - check("x${FOO=}y", " xy"); - - check("${FOO=,}", " "); - check("x${FOO=,}y", " xy"); - - check("${FOO,FOO=}", " "); - check("x${FOO,FOO=}y", " xy"); - - check("${FOO=,BAR}", " "); - check("x${FOO=,BAR}y", " xy"); - - check("${FOO=${BAR=}}", " "); - check("x${FOO=${BAR=}}y", " xy"); - - check("${FOO=,BAR=baz}", " "); - check("x${FOO=,BAR=baz}y", " xy"); - - check("${FOO=${BAR},BAR=}", " "); - check("x${FOO=${BAR},BAR=}y", " xy"); - - check("${=BAR}", " BAR"); - check("x${=BAR}y", " xBARy"); - - check("${FOO=BAR}", " BAR"); - check("x${FOO=BAR}y", " xBARy"); - - macPutValue(h, "FOO", "BLETCH"); - /* FOO = "BLETCH" */ - check("${FOO}", " BLETCH"); - check("${FOO,FOO}", " BLETCH"); - check("x${FOO}y", " xBLETCHy"); - check("x${FOO}y${FOO}z", " xBLETCHyBLETCHz"); - check("${FOO=BAR}", " BLETCH"); - check("x${FOO=BAR}y", " xBLETCHy"); - check("${FOO=${BAZ}}", " BLETCH"); - check("${FOO=${BAZ},BAR=${BAZ}}", " BLETCH"); - check("x${FOO=${BAZ}}y", " xBLETCHy"); - check("x${FOO=${BAZ},BAR=${BAZ}}y", " xBLETCHy"); - check("${BAR=${FOO}}", " BLETCH"); - check("x${BAR=${FOO}}y", " xBLETCHy"); - check("w${BAR=x${FOO}y}z", " wxBLETCHyz"); - - check("${FOO,FOO=BAR}", " BAR"); - check("x${FOO,FOO=BAR}y", " xBARy"); - check("${BAR,BAR=${FOO}}", " BLETCH"); - check("x${BAR,BAR=${FOO}}y", " xBLETCHy"); - check("${BAR,BAR=${${FOO}},BLETCH=GRIBBLE}", " GRIBBLE"); - check("x${BAR,BAR=${${FOO}},BLETCH=GRIBBLE}y", " xGRIBBLEy"); - check("${${BAR,BAR=${FOO}},BLETCH=GRIBBLE}", " GRIBBLE"); - check("x${${BAR,BAR=${FOO}},BLETCH=GRIBBLE}y", " xGRIBBLEy"); - check("${N=${FOO}/${BAR},BAR=GLEEP}", " BLETCH/GLEEP"); - - macPutValue(h, "BAR","GLEEP"); - /* FOO = "BLETCH" */ - /* BAR = "GLEEP" */ - check("${FOO}/${BAR}", " BLETCH/GLEEP"); - check("x${FOO}/${BAR}y", " xBLETCH/GLEEPy"); - check("${FOO,BAR}/${BAR}", " BLETCH/GLEEP"); - check("${FOO,BAR=x}/${BAR}", " BLETCH/GLEEP"); - check("${BAZ=BLETCH,BAR}/${BAR}", " BLETCH/GLEEP"); - check("${BAZ=BLETCH,BAR=x}/${BAR}", " BLETCH/GLEEP"); - check("${N=${FOO}/${BAR}}", " BLETCH/GLEEP"); - - macPutValue(h, "BLETCH","BAR"); - /* FOO = "BLETCH" */ - /* BLETCH = "BAR" */ - check("${${FOO}}", " BAR"); - check("x${${FOO}}y", " xBARy"); - check("${${FOO}=GRIBBLE}", " BAR"); - check("x${${FOO}=GRIBBLE}y", " xBARy"); - - macPutValue(h, "BLETCH","${BAR}"); - /* FOO = "BLETCH" */ - /* BLETCH = "${BAR}" */ - /* BAR = "GLEEP" */ - check("${${FOO}}", " GLEEP"); - check("${BLETCH=${FOO}}", " GLEEP"); - - macPutValue(h, "FOO","${BAR}"); - /* FOO = "${BAR}" */ - /* BAR = "GLEEP" */ - check("${FOO}", " GLEEP"); - check("${FOO=BLETCH,BAR=BAZ}", " BAZ"); - - macPutValue(h, "BAR","${BAZ}"); - /* FOO = "${BAR}" */ - /* BAR = "${BAZ}" */ - check("${FOO}", "!$(BAZ,undefined)"); - - macPutValue(h, "BAR","${BAZ=GRIBBLE}"); - /* FOO = "${BAR}" */ - /* BAR = "${BAZ=GRIBBLE}" */ - check("${FOO}", " GRIBBLE"); - check("${FOO,BAZ=GEEK}", " GEEK"); - - macPutValue(h, "BAR","${STR1}"); - macPutValue(h, "STR1","VAL1"); - macPutValue(h, "STR2","VAL2"); - /* FOO = "${BAR}" */ - /* BAR = "${STR1}" */ - /* STR1 = "VAL1" */ - /* STR2 = "VAL2" */ - check("${FOO}", " VAL1"); - - macPutValue(h, "BAR","${STR2}"); - /* FOO = "${BAR}" */ - /* BAR = "${STR2}" */ - /* STR1 = "VAL1" */ - /* STR2 = "VAL2" */ - check("${FOO}", " VAL2"); - - check("$(FOO)$(FOO1)", "!VAL2$(FOO1,undefined)"); - check("$(FOO1)$(FOO)", "!$(FOO1,undefined)VAL2"); - - macPutValue(h, "BAR","${FOO}"); - /* FOO = "${BAR}" */ - /* BAR = "${FOO}" */ - check("${FOO}", "!$(BAR,recursive)"); - check("${FOO=GRIBBLE}", "!$(BAR,recursive)"); - check("${FOO=GRIBBLE,BAR=${FOO}}", "!$(BAR,recursive)"); - check("${FOO,FOO=${FOO}}", "!$(FOO,recursive)"); - check("${FOO=GRIBBLE,FOO=${FOO}}", "!$(FOO,recursive)"); - - ovcheck(); - - return testDone(); -} diff --git a/src/libCom/test/ringBytesTest.c b/src/libCom/test/ringBytesTest.c deleted file mode 100644 index 6cef93334..000000000 --- a/src/libCom/test/ringBytesTest.c +++ /dev/null @@ -1,123 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* ringBytesTest.c */ - -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsRingBytes.h" -#include "errlog.h" -#include "epicsEvent.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#define RINGSIZE 10 - -typedef struct info { - epicsEventId consumerEvent; - epicsRingBytesId ring; -}info; - -static void check(epicsRingBytesId ring, int expectedFree) -{ - int expectedUsed = RINGSIZE - expectedFree; - int expectedEmpty = (expectedUsed == 0); - int expectedFull = (expectedFree == 0); - int nFree = epicsRingBytesFreeBytes(ring); - int nUsed = epicsRingBytesUsedBytes(ring); - int isEmpty = epicsRingBytesIsEmpty(ring); - int isFull = epicsRingBytesIsFull(ring); - - testOk(nFree == expectedFree, "Free: %d == %d", nFree, expectedFree); - testOk(nUsed == expectedUsed, "Used: %d == %d", nUsed, expectedUsed); - testOk(isEmpty == expectedEmpty, "Empty: %d == %d", isEmpty, expectedEmpty); - testOk(isFull == expectedFull, "Full: %d == %d", isFull, expectedFull); -} - -MAIN(ringBytesTest) -{ - int i, n; - info *pinfo; - epicsEventId consumerEvent; - char put[RINGSIZE+1]; - char get[RINGSIZE+1]; - epicsRingBytesId ring; - - testPlan(245); - - pinfo = calloc(1,sizeof(info)); - if (!pinfo) { - testAbort("calloc failed"); - } - pinfo->consumerEvent = consumerEvent = epicsEventCreate(epicsEventEmpty); - if (!consumerEvent) { - testAbort("epicsEventCreate failed"); - } - - pinfo->ring = ring = epicsRingBytesCreate(RINGSIZE); - if (!ring) { - testAbort("epicsRingBytesCreate failed"); - } - check(ring, RINGSIZE); - - for (i = 0 ; i < sizeof(put) ; i++) - put[i] = i; - for(i = 0 ; i < RINGSIZE ; i++) { - n = epicsRingBytesPut(ring, put, i); - testOk(n==i, "ring put %d", i); - check(ring, RINGSIZE-i); - n = epicsRingBytesGet(ring, get, i); - testOk(n==i, "ring get %d", i); - check(ring, RINGSIZE); - testOk(memcmp(put,get,i)==0, "get matches write"); - } - - for(i = 0 ; i < RINGSIZE ; i++) { - n = epicsRingBytesPut(ring, put+i, 1); - testOk(n==1, "ring put 1, %d", i); - check(ring, RINGSIZE-1-i); - } - n = epicsRingBytesPut(ring, put+RINGSIZE, 1); - testOk(n==0, "put to full ring"); - check(ring, 0); - for(i = 0 ; i < RINGSIZE ; i++) { - n = epicsRingBytesGet(ring, get+i, 1); - testOk(n==1, "ring get 1, %d", i); - check(ring, 1+i); - } - testOk(memcmp(put,get,RINGSIZE)==0, "get matches write"); - n = epicsRingBytesGet(ring, get+RINGSIZE, 1); - testOk(n==0, "get from empty ring"); - check(ring, RINGSIZE); - - n = epicsRingBytesPut(ring, put, RINGSIZE+1); - testOk(n==0, "ring put beyond ring capacity (%d, expected 0)",n); - check(ring, RINGSIZE); - n = epicsRingBytesPut(ring, put, 1); - testOk(n==1, "ring put %d", 1); - check(ring, RINGSIZE-1); - n = epicsRingBytesPut(ring, put, RINGSIZE); - testOk(n==0, "ring put beyond ring capacity (%d, expected 0)",n); - check(ring, RINGSIZE-1); - n = epicsRingBytesGet(ring, get, 1); - testOk(n==1, "ring get %d", 1); - check(ring, RINGSIZE); - - epicsRingBytesDelete(ring); - epicsEventDestroy(consumerEvent); - free(pinfo); - - return testDone(); -} diff --git a/src/libCom/test/ringPointerTest.c b/src/libCom/test/ringPointerTest.c deleted file mode 100644 index 92401d123..000000000 --- a/src/libCom/test/ringPointerTest.c +++ /dev/null @@ -1,246 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2013 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* ringPointerTest.c */ - -/* Author: Marty Kraimer Date: 13OCT2000 */ - -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsRingPointer.h" -#include "errlog.h" -#include "epicsEvent.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -static -void *int2ptr(size_t i) -{ - char *zero = 0; - i = i|(i<<16); - return zero+i; -} - -static int foundCorruption; - -static -size_t ptr2int(void *p) -{ - char *zero = 0, *p2 = p; - size_t i = p2-zero; - if((i&0xffff)!=((i>>16)&0xffff)) { - testDiag("Pointer value corruption %p", p); - foundCorruption = 1; - } - return i&0xffff; -} - -static void testSingle(void) -{ - int i; - const int rsize = 100; - void *addr = 0; - epicsRingPointerId ring = epicsRingPointerCreate(rsize); - - foundCorruption = 0; - - testDiag("Testing operations w/o threading"); - - testOk1(epicsRingPointerIsEmpty(ring)); - testOk1(!epicsRingPointerIsFull(ring)); - testOk1(epicsRingPointerGetFree(ring)==rsize); - testOk1(epicsRingPointerGetSize(ring)==rsize); - testOk1(epicsRingPointerGetUsed(ring)==0); - - testOk1(epicsRingPointerPop(ring)==NULL); - - addr = int2ptr(1); - testOk1(epicsRingPointerPush(ring, addr)==1); - - testOk1(!epicsRingPointerIsEmpty(ring)); - testOk1(!epicsRingPointerIsFull(ring)); - testOk1(epicsRingPointerGetFree(ring)==rsize-1); - testOk1(epicsRingPointerGetSize(ring)==rsize); - testOk1(epicsRingPointerGetUsed(ring)==1); - - testDiag("Fill it up"); - for(i=2; i<2*rsize; i++) { - int ret; - addr = int2ptr(i); - ret = epicsRingPointerPush(ring, addr); - if(!ret) - break; - } - - /* Note: +1 because we started with 1 */ - testOk(i==rsize+1, "%d == %d", i, rsize+1); - testOk1(!epicsRingPointerIsEmpty(ring)); - testOk1(epicsRingPointerIsFull(ring)); - testOk1(epicsRingPointerGetFree(ring)==0); - testOk1(epicsRingPointerGetSize(ring)==rsize); - testOk1(epicsRingPointerGetUsed(ring)==rsize); - - testDiag("Drain it out"); - for(i=1; i<2*rsize; i++) { - addr = epicsRingPointerPop(ring); - if(addr==NULL || ptr2int(addr)!=i) - break; - } - - testOk1(!foundCorruption); - - testOk(i==rsize+1, "%d == %d", i, rsize+1); - testOk1(epicsRingPointerIsEmpty(ring)); - testOk1(!epicsRingPointerIsFull(ring)); - testOk1(epicsRingPointerGetFree(ring)==rsize); - testOk1(epicsRingPointerGetSize(ring)==rsize); - testOk1(epicsRingPointerGetUsed(ring)==0); - - testDiag("Fill it up again"); - for(i=2; i<2*rsize; i++) { - int ret; - addr = int2ptr(i); - ret = epicsRingPointerPush(ring, addr); - if(!ret) - break; - } - - testDiag("flush"); - testOk1(epicsRingPointerIsFull(ring)); - epicsRingPointerFlush(ring); - - testOk1(epicsRingPointerIsEmpty(ring)); - testOk1(!epicsRingPointerIsFull(ring)); - testOk1(epicsRingPointerGetFree(ring)==rsize); - testOk1(epicsRingPointerGetSize(ring)==rsize); - testOk1(epicsRingPointerGetUsed(ring)==0); - - epicsRingPointerDelete(ring); -} - -typedef struct { - epicsRingPointerId ring; - epicsEventId sync, wait; - int stop; - void *lastaddr; -} pairPvt; - -static void pairConsumer(void *raw) -{ - pairPvt *pvt = raw; - void *prev = pvt->lastaddr; - - epicsEventMustTrigger(pvt->sync); - - while(1) { - size_t c,p; - - epicsEventMustWait(pvt->wait); - if(pvt->stop) - break; - - pvt->lastaddr = epicsRingPointerPop(pvt->ring); - c = ptr2int(pvt->lastaddr); - p = ptr2int(prev); - if(p+1!=c) { - testFail("consumer skip %p %p", prev, pvt->lastaddr); - break; - } - prev = pvt->lastaddr; - } - - pvt->stop = 1; - epicsEventMustTrigger(pvt->sync); -} - -static void testPair(int locked) -{ - unsigned int myprio = epicsThreadGetPrioritySelf(), consumerprio; - pairPvt pvt; - const int rsize = 100; - int i, expect; - epicsRingPointerId ring; - if(locked) - ring = epicsRingPointerLockedCreate(rsize); - else - ring = epicsRingPointerCreate(rsize); - - pvt.ring = ring; - pvt.sync = epicsEventCreate(epicsEventEmpty); - pvt.wait = epicsEventCreate(epicsEventEmpty); - pvt.stop = 0; - pvt.lastaddr = 0; - - foundCorruption = 0; - - testDiag("single producer, single consumer with%s locking", locked?"":"out"); - - /* give the consumer thread a slightly higher priority so that - * it can preempt us on RTOS targets. On non-RTOS targets - * we expect to be preempted at some random time - */ - if(!epicsThreadLowestPriorityLevelAbove(myprio, &consumerprio)) - testAbort("Can't run test from thread with highest priority"); - - epicsThreadMustCreate("pair", consumerprio, - epicsThreadGetStackSize(epicsThreadStackSmall), - &pairConsumer, &pvt); - /* wait for worker to start */ - epicsEventMustWait(pvt.sync); - - i=1; - while(i - -#include "taskwd.h" -#include "errlog.h" -#include "epicsThread.h" -#include "epicsUnitTest.h" -#include "testMain.h" - - -void monInsert(void *usr, epicsThreadId tid) -{ - testPass("monInsert(tid=%p)", (void *)tid); -} - -void monNotify(void *usr, epicsThreadId tid, int suspended) -{ - testPass("monNotify(tid=%p, suspended=%d)", (void *)tid, suspended); - epicsThreadResume(tid); -} - -void monRemove(void *usr, epicsThreadId tid) -{ - testPass("monRemove(tid=%p)", (void *)tid); -} - -taskwdMonitor monFuncs = {monInsert, monNotify, monRemove}; - -void anyNotify(void *usr, epicsThreadId tid) -{ - testPass("anyNotify(tid=%p)", (void *)tid); -} - -void taskNotify(void *usr) -{ - testPass("taskNotify"); -} - -void testTask1(void *arg) -{ - taskwdInsert(0, taskNotify, NULL); - epicsThreadSleep(10.0); - taskwdRemove(0); -} - -void testTask2(void *arg) -{ - taskwdInsert(0, taskNotify, NULL); - testDiag("Task suspending"); - epicsThreadSuspendSelf(); - epicsThreadSleep(1.0); - testDiag("Alive again"); - epicsThreadSleep(10.0); - taskwdRemove(0); -} - -MAIN(taskwdTest) -{ - eltc(0); - testPlan(8); - - taskwdInit(); - taskwdMonitorAdd(&monFuncs, NULL); - taskwdAnyInsert(NULL, anyNotify, NULL); - - epicsThreadCreate("testTask1", epicsThreadPriorityMax, - epicsThreadGetStackSize(epicsThreadStackSmall), - testTask1, NULL); - epicsThreadSleep(1.0); - - epicsThreadCreate("testTask2", epicsThreadPriorityMax, - epicsThreadGetStackSize(epicsThreadStackSmall), - testTask2, NULL); - - /* taskwd checks tasks every 6 seconds */ - epicsThreadSleep(18.0); - - taskwdMonitorDel(&monFuncs, NULL); - taskwdAnyRemove(NULL); - - eltc(1); - return testDone(); -} - diff --git a/src/libCom/timer/Makefile b/src/libCom/timer/Makefile deleted file mode 100644 index 51094d069..000000000 --- a/src/libCom/timer/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/timer -INC += epicsTimer.h -Com_SRCS += epicsTimer.cpp -Com_SRCS += timer.cpp -Com_SRCS += timerQueue.cpp -Com_SRCS += timerQueueActive.cpp -Com_SRCS += timerQueueActiveMgr.cpp -Com_SRCS += timerQueuePassive.cpp diff --git a/src/libCom/timer/epicsTimer.cpp b/src/libCom/timer/epicsTimer.cpp deleted file mode 100644 index e55280e7e..000000000 --- a/src/libCom/timer/epicsTimer.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMath.h" -#include "epicsTimer.h" -#include "epicsGuard.h" -#include "timerPrivate.h" - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - -template class tsFreeList < epicsTimerForC, 0x20 >; - -epicsTimer::~epicsTimer () {} - -epicsTimerQueueNotify::~epicsTimerQueueNotify () {} - -epicsTimerNotify::~epicsTimerNotify () {} - -void epicsTimerNotify::show ( unsigned /* level */ ) const {} - -epicsTimerForC::epicsTimerForC ( timerQueue &queue, epicsTimerCallback pCBIn, void *pPrivateIn ) : - timer ( queue ), pCallBack ( pCBIn ), pPrivate ( pPrivateIn ) -{ -} - -epicsTimerForC::~epicsTimerForC () -{ -} - -void epicsTimerForC::destroy () -{ - timerQueue & queueTmp = this->queue; - this->~epicsTimerForC (); - queueTmp.timerForCFreeList.release ( this ); -} - -epicsTimerNotify::expireStatus epicsTimerForC::expire ( const epicsTime & ) -{ - ( *this->pCallBack ) ( this->pPrivate ); - return noRestart; -} - -epicsTimerQueueActiveForC :: - epicsTimerQueueActiveForC ( RefMgr & refMgr, - bool okToShare, unsigned priority ) : - timerQueueActive ( refMgr, okToShare, priority ) -{ - timerQueueActive::start(); -} - -epicsTimerQueueActiveForC::~epicsTimerQueueActiveForC () -{ -} - -void epicsTimerQueueActiveForC::release () -{ - _refMgr->release ( *this ); -} - -epicsTimerQueuePassiveForC::epicsTimerQueuePassiveForC ( - epicsTimerQueueNotifyReschedule pRescheduleCallbackIn, - epicsTimerQueueNotifyQuantum pSleepQuantumCallbackIn, - void * pPrivateIn ) : - timerQueuePassive ( * static_cast < epicsTimerQueueNotify * > ( this ) ), - pRescheduleCallback ( pRescheduleCallbackIn ), - pSleepQuantumCallback ( pSleepQuantumCallbackIn ), - pPrivate ( pPrivateIn ) -{ -} - -epicsTimerQueuePassiveForC::~epicsTimerQueuePassiveForC () -{ -} - -void epicsTimerQueuePassiveForC::reschedule () -{ - (*this->pRescheduleCallback) ( this->pPrivate ); -} - -double epicsTimerQueuePassiveForC::quantum () -{ - return (*this->pSleepQuantumCallback) ( this->pPrivate ); -} - -void epicsTimerQueuePassiveForC::destroy () -{ - delete this; -} - -epicsShareFunc epicsTimerNotify::expireStatus::expireStatus ( restart_t restart ) : - delay ( - DBL_MAX ) -{ - if ( restart != noRestart ) { - throw std::logic_error - ( "timer restart was requested without specifying a delay?" ); - } -} - -epicsShareFunc epicsTimerNotify::expireStatus::expireStatus - ( restart_t restartIn, const double & expireDelaySec ) : - delay ( expireDelaySec ) -{ - if ( restartIn != epicsTimerNotify::restart ) { - throw std::logic_error - ( "no timer restart was requested, but a delay was specified?" ); - } - if ( this->delay < 0.0 || !finite(this->delay) ) { - throw std::logic_error - ( "timer restart was requested, but a negative delay was specified?" ); - } -} - -epicsShareFunc bool epicsTimerNotify::expireStatus::restart () const -{ - return this->delay >= 0.0 && finite(this->delay); -} - -epicsShareFunc double epicsTimerNotify::expireStatus::expirationDelay () const -{ - if ( this->delay < 0.0 || !finite(this->delay) ) { - throw std::logic_error - ( "no timer restart was requested, but you are asking for a restart delay?" ); - } - return this->delay; -} - -extern "C" epicsTimerQueuePassiveId epicsShareAPI - epicsTimerQueuePassiveCreate ( - epicsTimerQueueNotifyReschedule pRescheduleCallbackIn, - epicsTimerQueueNotifyQuantum pSleepQuantumCallbackIn, - void * pPrivateIn ) -{ - try { - return new epicsTimerQueuePassiveForC ( - pRescheduleCallbackIn, - pSleepQuantumCallbackIn, - pPrivateIn ); - } - catch ( ... ) { - return 0; - } -} - -extern "C" void epicsShareAPI - epicsTimerQueuePassiveDestroy ( epicsTimerQueuePassiveId pQueue ) -{ - pQueue->destroy (); -} - -extern "C" double epicsShareAPI - epicsTimerQueuePassiveProcess ( epicsTimerQueuePassiveId pQueue ) -{ - try { - return pQueue->process ( epicsTime::getCurrent() ); - } - catch ( ... ) { - return 1.0; - } -} - -extern "C" epicsTimerId epicsShareAPI epicsTimerQueuePassiveCreateTimer ( - epicsTimerQueuePassiveId pQueue, epicsTimerCallback pCallback, void *pArg ) -{ - try { - return & pQueue->createTimerForC ( pCallback, pArg ); - } - catch ( ... ) { - return 0; - } -} - -extern "C" epicsShareFunc void epicsShareAPI epicsTimerQueuePassiveDestroyTimer ( - epicsTimerQueuePassiveId /* pQueue */, epicsTimerId pTmr ) -{ - pTmr->destroy (); -} - -extern "C" void epicsShareAPI epicsTimerQueuePassiveShow ( - epicsTimerQueuePassiveId pQueue, unsigned int level ) -{ - pQueue->show ( level ); -} - -extern "C" epicsTimerQueueId epicsShareAPI - epicsTimerQueueAllocate ( int okToShare, unsigned int threadPriority ) -{ - try { - epicsSingleton < timerQueueActiveMgr > :: reference ref = - timerQueueMgrEPICS.getReference (); - epicsTimerQueueActiveForC & tmr = - ref->allocate ( ref, okToShare ? true : false, threadPriority ); - return &tmr; - } - catch ( ... ) { - return 0; - } -} - -extern "C" void epicsShareAPI epicsTimerQueueRelease ( epicsTimerQueueId pQueue ) -{ - pQueue->release (); -} - -extern "C" epicsTimerId epicsShareAPI epicsTimerQueueCreateTimer ( - epicsTimerQueueId pQueue, epicsTimerCallback pCallback, void *pArg ) -{ - try { - return & pQueue->createTimerForC ( pCallback, pArg ); - } - catch ( ... ) { - return 0; - } -} - -extern "C" void epicsShareAPI epicsTimerQueueShow ( - epicsTimerQueueId pQueue, unsigned int level ) -{ - pQueue->show ( level ); -} - -extern "C" void epicsShareAPI epicsTimerQueueDestroyTimer ( - epicsTimerQueueId /* pQueue */, epicsTimerId pTmr ) -{ - pTmr->destroy (); -} - -extern "C" void epicsShareAPI epicsTimerStartTime ( - epicsTimerId pTmr, const epicsTimeStamp *pTime ) -{ - pTmr->start ( *pTmr, *pTime ); -} - -extern "C" void epicsShareAPI epicsTimerStartDelay ( - epicsTimerId pTmr, double delaySeconds ) -{ - pTmr->start ( *pTmr, delaySeconds ); -} - -extern "C" void epicsShareAPI epicsTimerCancel ( epicsTimerId pTmr ) -{ - pTmr->cancel (); -} - -extern "C" double epicsShareAPI epicsTimerGetExpireDelay ( epicsTimerId pTmr ) -{ - return pTmr->getExpireDelay (); -} - -extern "C" void epicsShareAPI epicsTimerShow ( - epicsTimerId pTmr, unsigned int level ) -{ - pTmr->timer::show ( level ); -} - diff --git a/src/libCom/timer/epicsTimer.h b/src/libCom/timer/epicsTimer.h deleted file mode 100644 index 72270f273..000000000 --- a/src/libCom/timer/epicsTimer.h +++ /dev/null @@ -1,185 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsTimer.h */ - -/* Authors: Marty Kraimer, Jeff Hill */ - -#ifndef epicsTimerH -#define epicsTimerH - -#include - -#include "shareLib.h" -#include "epicsTime.h" -#include "epicsThread.h" - -#ifdef __cplusplus - -/* - * Notes: - * 1) epicsTimer does not hold its lock when calling callbacks. - */ - -/* code using a timer must implement epicsTimerNotify */ -class epicsShareClass epicsTimerNotify { -public: - enum restart_t { noRestart, restart }; - class expireStatus { - public: - epicsShareFunc expireStatus ( restart_t ); - epicsShareFunc expireStatus ( restart_t, const double & expireDelaySec ); - epicsShareFunc bool restart () const; - epicsShareFunc double expirationDelay () const; - private: - double delay; - }; - - virtual ~epicsTimerNotify () = 0; - /* return "noRestart" or "expireStatus ( restart, 30.0 )" */ - virtual expireStatus expire ( const epicsTime & currentTime ) = 0; - virtual void show ( unsigned int level ) const; -}; - -class epicsShareClass epicsTimer { -public: - /* calls cancel (see warning below) and then destroys the timer */ - virtual void destroy () = 0; - virtual void start ( epicsTimerNotify &, const epicsTime & ) = 0; - virtual void start ( epicsTimerNotify &, double delaySeconds ) = 0; - /* WARNING: A deadlock will occur if you hold a lock while - * calling this function that you also take within the timer - * expiration callback. - */ - virtual void cancel () = 0; - struct expireInfo { - expireInfo ( bool active, const epicsTime & expireTime ); - bool active; - epicsTime expireTime; - }; - virtual expireInfo getExpireInfo () const = 0; - double getExpireDelay (); - virtual void show ( unsigned int level ) const = 0; -protected: - virtual ~epicsTimer () = 0; /* protected => delete() must not be called */ -}; - -class epicsTimerQueue { -public: - virtual epicsTimer & createTimer () = 0; - virtual void show ( unsigned int level ) const = 0; -protected: - epicsShareFunc virtual ~epicsTimerQueue () = 0; -}; - -class epicsTimerQueueActive - : public epicsTimerQueue { -public: - static epicsShareFunc epicsTimerQueueActive & allocate ( - bool okToShare, unsigned threadPriority = epicsThreadPriorityMin + 10 ); - virtual void release () = 0; -protected: - epicsShareFunc virtual ~epicsTimerQueueActive () = 0; -}; - -class epicsTimerQueueNotify { -public: - /* called when a new timer is inserted into the queue and the */ - /* delay to the next expire has changed */ - virtual void reschedule () = 0; - /* if there is a quantum in the scheduling of timer intervals */ - /* return this quantum in seconds. If unknown then return zero. */ - virtual double quantum () = 0; -protected: - epicsShareFunc virtual ~epicsTimerQueueNotify () = 0; -}; - -class epicsTimerQueuePassive - : public epicsTimerQueue { -public: - static epicsShareFunc epicsTimerQueuePassive & create ( epicsTimerQueueNotify & ); - epicsShareFunc virtual ~epicsTimerQueuePassive () = 0; /* ok to call delete */ - virtual double process ( const epicsTime & currentTime ) = 0; /* returns delay to next expire */ -}; - -inline epicsTimer::expireInfo::expireInfo ( bool activeIn, - const epicsTime & expireTimeIn ) : - active ( activeIn ), expireTime ( expireTimeIn ) -{ -} - -inline double epicsTimer::getExpireDelay () -{ - epicsTimer::expireInfo info = this->getExpireInfo (); - if ( info.active ) { - double delay = info.expireTime - epicsTime::getCurrent (); - if ( delay < 0.0 ) { - delay = 0.0; - } - return delay; - } - return - DBL_MAX; -} - -extern "C" { -#endif /* __cplusplus */ - -typedef struct epicsTimerForC * epicsTimerId; -typedef void ( *epicsTimerCallback ) ( void *pPrivate ); - -/* thread managed timer queue */ -typedef struct epicsTimerQueueActiveForC * epicsTimerQueueId; -epicsShareFunc epicsTimerQueueId epicsShareAPI - epicsTimerQueueAllocate ( int okToShare, unsigned int threadPriority ); -epicsShareFunc void epicsShareAPI - epicsTimerQueueRelease ( epicsTimerQueueId ); -epicsShareFunc epicsTimerId epicsShareAPI - epicsTimerQueueCreateTimer ( epicsTimerQueueId queueid, - epicsTimerCallback callback, void *arg ); -epicsShareFunc void epicsShareAPI - epicsTimerQueueDestroyTimer ( epicsTimerQueueId queueid, epicsTimerId id ); -epicsShareFunc void epicsShareAPI - epicsTimerQueueShow ( epicsTimerQueueId id, unsigned int level ); - -/* passive timer queue */ -typedef struct epicsTimerQueuePassiveForC * epicsTimerQueuePassiveId; -typedef void ( * epicsTimerQueueNotifyReschedule ) ( void * pPrivate ); -typedef double ( * epicsTimerQueueNotifyQuantum ) ( void * pPrivate ); -epicsShareFunc epicsTimerQueuePassiveId epicsShareAPI - epicsTimerQueuePassiveCreate ( epicsTimerQueueNotifyReschedule, - epicsTimerQueueNotifyQuantum, void *pPrivate ); -epicsShareFunc void epicsShareAPI - epicsTimerQueuePassiveDestroy ( epicsTimerQueuePassiveId ); -epicsShareFunc epicsTimerId epicsShareAPI - epicsTimerQueuePassiveCreateTimer ( - epicsTimerQueuePassiveId queueid, epicsTimerCallback pCallback, void *pArg ); -epicsShareFunc void epicsShareAPI - epicsTimerQueuePassiveDestroyTimer ( epicsTimerQueuePassiveId queueid, epicsTimerId id ); -epicsShareFunc double epicsShareAPI - epicsTimerQueuePassiveProcess ( epicsTimerQueuePassiveId ); -epicsShareFunc void epicsShareAPI - epicsTimerQueuePassiveShow ( epicsTimerQueuePassiveId id, unsigned int level ); - -/* timer */ -epicsShareFunc void epicsShareAPI - epicsTimerStartTime ( epicsTimerId id, const epicsTimeStamp *pTime ); -epicsShareFunc void epicsShareAPI - epicsTimerStartDelay ( epicsTimerId id, double delaySeconds ); -epicsShareFunc void epicsShareAPI - epicsTimerCancel ( epicsTimerId id ); -epicsShareFunc double epicsShareAPI - epicsTimerGetExpireDelay ( epicsTimerId id ); -epicsShareFunc void epicsShareAPI - epicsTimerShow ( epicsTimerId id, unsigned int level ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* epicsTimerH */ diff --git a/src/libCom/timer/timer.cpp b/src/libCom/timer/timer.cpp deleted file mode 100644 index 35d6e47bf..000000000 --- a/src/libCom/timer/timer.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsGuard.h" -#include "timerPrivate.h" -#include "errlog.h" - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template class tsFreeList < timer, 0x20 >; - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - -timer::timer ( timerQueue & queueIn ) : - queue ( queueIn ), curState ( stateLimbo ), pNotify ( 0 ) -{ -} - -timer::~timer () -{ - this->cancel (); -} - -void timer::destroy () -{ - timerQueue & queueTmp = this->queue; - this->~timer (); - queueTmp.timerFreeList.release ( this ); -} - -void timer::start ( epicsTimerNotify & notify, double delaySeconds ) -{ - this->start ( notify, epicsTime::getCurrent () + delaySeconds ); -} - -void timer::start ( epicsTimerNotify & notify, const epicsTime & expire ) -{ - epicsGuard < epicsMutex > locker ( this->queue.mutex ); - this->privateStart ( notify, expire ); -} - -void timer::privateStart ( epicsTimerNotify & notify, const epicsTime & expire ) -{ - this->pNotify = & notify; - this->exp = expire - ( this->queue.notify.quantum () / 2.0 ); - - bool reschedualNeeded = false; - if ( this->curState == stateActive ) { - // above expire time and notify will override any restart parameters - // that may be returned from the timer expire callback - return; - } - else if ( this->curState == statePending ) { - this->queue.timerList.remove ( *this ); - if ( this->queue.timerList.first() == this && - this->queue.timerList.count() > 0 ) { - reschedualNeeded = true; - } - } - -# ifdef DEBUG - unsigned preemptCount=0u; -# endif - - // - // insert into the pending queue - // - // Finds proper time sorted location using a linear search. - // - // **** this should use a binary tree ???? - // - tsDLIter < timer > pTmr = this->queue.timerList.lastIter (); - while ( true ) { - if ( ! pTmr.valid () ) { - // - // add to the beginning of the list - // - this->queue.timerList.push ( *this ); - reschedualNeeded = true; - break; - } - if ( pTmr->exp <= this->exp ) { - // - // add after the item found that expires earlier - // - this->queue.timerList.insertAfter ( *this, *pTmr ); - break; - } -# ifdef DEBUG - preemptCount++; -# endif - --pTmr; - } - - this->curState = timer::statePending; - - if ( reschedualNeeded ) { - this->queue.notify.reschedule (); - } - -# if defined(DEBUG) && 0 - this->show ( 10u ); - this->queue.show ( 10u ); -# endif - - debugPrintf ( ("Start of \"%s\" with delay %f at %p preempting %u\n", - typeid ( this->notify ).name (), - expire - epicsTime::getCurrent (), - this, preemptCount ) ); -} - -void timer::cancel () -{ - bool reschedual = false; - bool wakeupCancelBlockingThreads = false; - { - epicsGuard < epicsMutex > locker ( this->queue.mutex ); - this->pNotify = 0; - if ( this->curState == statePending ) { - this->queue.timerList.remove ( *this ); - this->curState = stateLimbo; - if ( this->queue.timerList.first() == this && - this->queue.timerList.count() > 0 ) { - reschedual = true; - } - } - else if ( this->curState == stateActive ) { - this->queue.cancelPending = true; - this->curState = timer::stateLimbo; - if ( this->queue.processThread != epicsThreadGetIdSelf() ) { - // make certain timer expire() does not run after cancel () returns, - // but dont require that lock is applied while calling expire() - while ( this->queue.cancelPending && - this->queue.pExpireTmr == this ) { - epicsGuardRelease < epicsMutex > autoRelease ( locker ); - this->queue.cancelBlockingEvent.wait (); - } - // in case other threads are waiting - wakeupCancelBlockingThreads = true; - } - } - } - if ( reschedual ) { - this->queue.notify.reschedule (); - } - if ( wakeupCancelBlockingThreads ) { - this->queue.cancelBlockingEvent.signal (); - } -} - -epicsTimer::expireInfo timer::getExpireInfo () const -{ - // taking a lock here guarantees that users will not - // see brief intervals when a timer isnt active because - // it is is canceled when start is called - epicsGuard < epicsMutex > locker ( this->queue.mutex ); - if ( this->curState == statePending || this->curState == stateActive ) { - return expireInfo ( true, this->exp ); - } - return expireInfo ( false, epicsTime() ); -} - -void timer::show ( unsigned int level ) const -{ - epicsGuard < epicsMutex > locker ( this->queue.mutex ); - double delay; - if ( this->curState == statePending || this->curState == stateActive ) { - try { - delay = this->exp - epicsTime::getCurrent(); - } - catch ( ... ) { - delay = - DBL_MAX; - } - } - else { - delay = -DBL_MAX; - } - const char *pStateName; - if ( this->curState == statePending ) { - pStateName = "pending"; - } - else if ( this->curState == stateActive ) { - pStateName = "active"; - } - else if ( this->curState == stateLimbo ) { - pStateName = "limbo"; - } - else { - pStateName = "corrupt"; - } - printf ( "timer, state = %s, delay = %f\n", - pStateName, delay ); - if ( level >= 1u && this->pNotify ) { - this->pNotify->show ( level - 1u ); - } -} - -void timer::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -void epicsTimerForC::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - diff --git a/src/libCom/timer/timerPrivate.h b/src/libCom/timer/timerPrivate.h deleted file mode 100644 index 55291309c..000000000 --- a/src/libCom/timer/timerPrivate.h +++ /dev/null @@ -1,277 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef epicsTimerPrivate_h -#define epicsTimerPrivate_h - -#include - -#include "tsFreeList.h" -#include "epicsSingleton.h" -#include "tsDLList.h" -#include "epicsTimer.h" -#include "compilerDependencies.h" - -#ifdef DEBUG -# define debugPrintf(ARGSINPAREN) printf ARGSINPAREN -#else -# define debugPrintf(ARGSINPAREN) -#endif - -template < class T > class epicsGuard; - -class timer : public epicsTimer, public tsDLNode < timer > { -public: - void destroy (); - void start ( class epicsTimerNotify &, const epicsTime & ); - void start ( class epicsTimerNotify &, double delaySeconds ); - void cancel (); - expireInfo getExpireInfo () const; - void show ( unsigned int level ) const; - void * operator new ( size_t size, tsFreeList < timer, 0x20 > & ); - epicsPlacementDeleteOperator (( void *, tsFreeList < timer, 0x20 > & )) -protected: - timer ( class timerQueue & ); - ~timer (); - timerQueue & queue; -private: - enum state { statePending = 45, stateActive = 56, stateLimbo = 78 }; - epicsTime exp; // experation time - state curState; // current state - epicsTimerNotify * pNotify; // callback - void privateStart ( epicsTimerNotify & notify, const epicsTime & ); - timer & operator = ( const timer & ); - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - void operator delete ( void * ); - friend class timerQueue; -}; - -struct epicsTimerForC : public epicsTimerNotify, public timer { -public: - void destroy (); -protected: - epicsTimerForC ( timerQueue &, epicsTimerCallback, void *pPrivateIn ); - ~epicsTimerForC (); - void * operator new ( size_t size, tsFreeList < epicsTimerForC, 0x20 > & ); - epicsPlacementDeleteOperator (( void *, tsFreeList < epicsTimerForC, 0x20 > & )) -private: - epicsTimerCallback pCallBack; - void * pPrivate; - expireStatus expire ( const epicsTime & currentTime ); - epicsTimerForC & operator = ( const epicsTimerForC & ); - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - void operator delete ( void * ); - friend class timerQueue; -}; - -using std :: type_info; - -class timerQueue : public epicsTimerQueue { -public: - timerQueue ( epicsTimerQueueNotify ¬ify ); - virtual ~timerQueue (); - epicsTimer & createTimer (); - epicsTimerForC & createTimerForC ( epicsTimerCallback pCallback, void *pArg ); - double process ( const epicsTime & currentTime ); - void show ( unsigned int level ) const; -private: - tsFreeList < timer, 0x20 > timerFreeList; - tsFreeList < epicsTimerForC, 0x20 > timerForCFreeList; - mutable epicsMutex mutex; - epicsEvent cancelBlockingEvent; - tsDLList < timer > timerList; - epicsTimerQueueNotify & notify; - timer * pExpireTmr; - epicsThreadId processThread; - epicsTime exceptMsgTimeStamp; - bool cancelPending; - static const double exceptMsgMinPeriod; - void printExceptMsg ( const char * pName, - const type_info & type ); - timerQueue ( const timerQueue & ); - timerQueue & operator = ( const timerQueue & ); - friend class timer; - friend struct epicsTimerForC; -}; - -class timerQueueActiveMgrPrivate { -public: - timerQueueActiveMgrPrivate (); -protected: - virtual ~timerQueueActiveMgrPrivate () = 0; -private: - unsigned referenceCount; - friend class timerQueueActiveMgr; -}; - -class timerQueueActiveMgr; - -class timerQueueActive : public epicsTimerQueueActive, - public epicsThreadRunable, public epicsTimerQueueNotify, - public timerQueueActiveMgrPrivate { -public: - typedef epicsSingleton < timerQueueActiveMgr > :: reference RefMgr; - timerQueueActive ( RefMgr &, bool okToShare, unsigned priority ); - void start (); - epicsTimer & createTimer (); - epicsTimerForC & createTimerForC ( epicsTimerCallback pCallback, void *pArg ); - void show ( unsigned int level ) const; - bool sharingOK () const; - unsigned threadPriority () const; -protected: - ~timerQueueActive (); - RefMgr _refMgr; -private: - timerQueue queue; - epicsEvent rescheduleEvent; - epicsEvent exitEvent; - epicsThread thread; - const double sleepQuantum; - bool okToShare; - bool exitFlag; - bool terminateFlag; - void run (); - void reschedule (); - double quantum (); - void _printLastChanceExceptionMessage ( - const char * pExceptionTypeName, - const char * pExceptionContext ); - epicsTimerQueue & getEpicsTimerQueue (); - timerQueueActive ( const timerQueueActive & ); - timerQueueActive & operator = ( const timerQueueActive & ); -}; - -class timerQueueActiveMgr { -public: - typedef epicsSingleton < timerQueueActiveMgr > :: reference RefThis; - timerQueueActiveMgr (); - ~timerQueueActiveMgr (); - epicsTimerQueueActiveForC & allocate ( RefThis &, bool okToShare, - unsigned threadPriority = epicsThreadPriorityMin + 10 ); - void release ( epicsTimerQueueActiveForC & ); -private: - epicsMutex mutex; - tsDLList < epicsTimerQueueActiveForC > sharedQueueList; - timerQueueActiveMgr ( const timerQueueActiveMgr & ); - timerQueueActiveMgr & operator = ( const timerQueueActiveMgr & ); -}; - -extern epicsSingleton < timerQueueActiveMgr > timerQueueMgrEPICS; - -class timerQueuePassive : public epicsTimerQueuePassive { -public: - timerQueuePassive ( epicsTimerQueueNotify & ); - epicsTimer & createTimer (); - epicsTimerForC & createTimerForC ( epicsTimerCallback pCallback, void *pArg ); - void show ( unsigned int level ) const; - double process ( const epicsTime & currentTime ); -protected: - timerQueue queue; - ~timerQueuePassive (); - epicsTimerQueue & getEpicsTimerQueue (); - timerQueuePassive ( const timerQueuePassive & ); - timerQueuePassive & operator = ( const timerQueuePassive & ); -}; - -struct epicsTimerQueuePassiveForC : - public epicsTimerQueueNotify, public timerQueuePassive { -public: - epicsTimerQueuePassiveForC ( - epicsTimerQueueNotifyReschedule, - epicsTimerQueueNotifyQuantum, - void * pPrivate ); - void destroy (); -protected: - ~epicsTimerQueuePassiveForC (); -private: - epicsTimerQueueNotifyReschedule pRescheduleCallback; - epicsTimerQueueNotifyQuantum pSleepQuantumCallback; - void * pPrivate; - static epicsSingleton < tsFreeList < epicsTimerQueuePassiveForC, 0x10 > > pFreeList; - void reschedule (); - double quantum (); -}; - -struct epicsTimerQueueActiveForC : public timerQueueActive, - public tsDLNode < epicsTimerQueueActiveForC > { -public: - epicsTimerQueueActiveForC ( RefMgr &, bool okToShare, unsigned priority ); - void release (); - void * operator new ( size_t ); - void operator delete ( void * ); -protected: - virtual ~epicsTimerQueueActiveForC (); -private: - epicsTimerQueueActiveForC ( const epicsTimerQueueActiveForC & ); - epicsTimerQueueActiveForC & operator = ( const epicsTimerQueueActiveForC & ); -}; - -inline bool timerQueueActive::sharingOK () const -{ - return this->okToShare; -} - -inline unsigned timerQueueActive::threadPriority () const -{ - return thread.getPriority (); -} - -inline void * timer::operator new ( size_t size, - tsFreeList < timer, 0x20 > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void timer::operator delete ( void * pCadaver, - tsFreeList < timer, 0x20 > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -inline void * epicsTimerForC::operator new ( size_t size, - tsFreeList < epicsTimerForC, 0x20 > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void epicsTimerForC::operator delete ( void * pCadaver, - tsFreeList < epicsTimerForC, 0x20 > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -inline void * epicsTimerQueueActiveForC::operator new ( size_t size ) -{ - return ::operator new ( size ); -} - -inline void epicsTimerQueueActiveForC::operator delete ( void * pCadaver ) -{ - ::operator delete ( pCadaver ); -} - -#endif // epicsTimerPrivate_h - diff --git a/src/libCom/timer/timerQueue.cpp b/src/libCom/timer/timerQueue.cpp deleted file mode 100644 index 5a798d4d4..000000000 --- a/src/libCom/timer/timerQueue.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsGuard.h" -#include "timerPrivate.h" -#include "errlog.h" - -const double timerQueue :: exceptMsgMinPeriod = 60.0 * 5.0; // seconds - -epicsTimerQueue::~epicsTimerQueue () {} - -timerQueue::timerQueue ( epicsTimerQueueNotify & notifyIn ) : - notify ( notifyIn ), - pExpireTmr ( 0 ), - processThread ( 0 ), - exceptMsgTimeStamp ( - epicsTime :: getCurrent () - exceptMsgMinPeriod ), - cancelPending ( false ) -{ -} - -timerQueue::~timerQueue () -{ - timer *pTmr; - while ( ( pTmr = this->timerList.get () ) ) { - pTmr->curState = timer::stateLimbo; - } -} - -void timerQueue :: - printExceptMsg ( const char * pName, const type_info & type ) -{ - char date[64]; - double delay; - try { - epicsTime cur = epicsTime :: getCurrent (); - delay = cur - this->exceptMsgTimeStamp; - cur.strftime ( date, sizeof ( date ), - "%a %b %d %Y %H:%M:%S.%f" ); - if ( delay >= exceptMsgMinPeriod ) { - this->exceptMsgTimeStamp = cur; - } - } - catch ( ... ) { - delay = DBL_MAX; - strcpy ( date, "UKN DATE" ); - } - if ( delay >= exceptMsgMinPeriod ) { - // we dont touch the typeid for the timer expiration - // notify interface here because they might have - // destroyed the timer during its callback - errlogPrintf ( - "timerQueue: Unexpected C++ exception \"%s\" " - "with type \"%s\" during timer expiration " - "callback at %s\n", - pName, - type.name (), - date ); - errlogFlush (); - } -} - -double timerQueue::process ( const epicsTime & currentTime ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - - if ( this->pExpireTmr ) { - // if some other thread is processing the queue - // (or if this is a recursive call) - timer * pTmr = this->timerList.first (); - if ( pTmr ) { - double delay = pTmr->exp - currentTime; - if ( delay < 0.0 ) { - delay = 0.0; - } - return delay; - } - else { - return DBL_MAX; - } - } - - // - // Tag current epired tmr so that we can detect if call back - // is in progress when canceling the timer. - // - if ( this->timerList.first () ) { - if ( currentTime >= this->timerList.first ()->exp ) { - this->pExpireTmr = this->timerList.first (); - this->timerList.remove ( *this->pExpireTmr ); - this->pExpireTmr->curState = timer::stateActive; - this->processThread = epicsThreadGetIdSelf (); -# ifdef DEBUG - this->pExpireTmr->show ( 0u ); -# endif - } - else { - double delay = this->timerList.first ()->exp - currentTime; - debugPrintf ( ( "no activity process %f to next\n", delay ) ); - return delay; - } - } - else { - return DBL_MAX; - } - -# ifdef DEBUG - unsigned N = 0u; -# endif - - double delay = DBL_MAX; - while ( true ) { - epicsTimerNotify *pTmpNotify = this->pExpireTmr->pNotify; - this->pExpireTmr->pNotify = 0; - epicsTimerNotify::expireStatus expStat ( epicsTimerNotify::noRestart ); - - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - - debugPrintf ( ( "%5u expired \"%s\" with error %f sec\n", - N++, typeid ( this->pExpireTmr->notify ).name (), - currentTime - this->pExpireTmr->exp ) ); - try { - expStat = pTmpNotify->expire ( currentTime ); - } - catch ( std::exception & except ) { - printExceptMsg ( except.what (), typeid ( except ) ); - } - catch ( ... ) { - printExceptMsg ( "non-standard exception", typeid ( void ) ); - } - } - - // - // only restart if they didnt cancel() the timer - // while the call back was running - // - if ( this->cancelPending ) { - // 1) if another thread is canceling then cancel() waits for - // the event below - // 2) if this thread is canceling in the timer callback then - // dont touch timer or notify here because the cancel might - // have occurred because they destroyed the timer in the - // callback - this->cancelPending = false; - this->cancelBlockingEvent.signal (); - } - else { - this->pExpireTmr->curState = timer::stateLimbo; - if ( this->pExpireTmr->pNotify ) { - // pNotify was cleared above so if it is valid now we know that - // someone has started the timer from another thread and that - // predominates over the restart parameters from expire. - this->pExpireTmr->privateStart ( - *this->pExpireTmr->pNotify, this->pExpireTmr->exp ); - } - else if ( expStat.restart() ) { - // restart as nec - this->pExpireTmr->privateStart ( - *pTmpNotify, currentTime + expStat.expirationDelay() ); - } - } - this->pExpireTmr = 0; - - if ( this->timerList.first () ) { - if ( currentTime >= this->timerList.first ()->exp ) { - this->pExpireTmr = this->timerList.first (); - this->timerList.remove ( *this->pExpireTmr ); - this->pExpireTmr->curState = timer::stateActive; -# ifdef DEBUG - this->pExpireTmr->show ( 0u ); -# endif - } - else { - delay = this->timerList.first ()->exp - currentTime; - this->processThread = 0; - break; - } - } - else { - this->processThread = 0; - delay = DBL_MAX; - break; - } - } - return delay; -} - -epicsTimer & timerQueue::createTimer () -{ - return * new ( this->timerFreeList ) timer ( * this ); -} - -epicsTimerForC & timerQueue::createTimerForC ( epicsTimerCallback pCallback, void *pArg ) -{ - return * new ( this->timerForCFreeList ) epicsTimerForC ( *this, pCallback, pArg ); -} - -void timerQueue::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > locker ( this->mutex ); - printf ( "epicsTimerQueue with %u items pending\n", this->timerList.count () ); - if ( level >= 1u ) { - tsDLIterConst < timer > iter = this->timerList.firstIter (); - while ( iter.valid () ) { - iter->show ( level - 1u ); - ++iter; - } - } -} diff --git a/src/libCom/timer/timerQueueActive.cpp b/src/libCom/timer/timerQueueActive.cpp deleted file mode 100644 index 5d8b72951..000000000 --- a/src/libCom/timer/timerQueueActive.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include - -#define epicsExportSharedSymbols -#include "timerPrivate.h" -#include "errlog.h" - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template class epicsSingleton < timerQueueActiveMgr >; - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - -epicsSingleton < timerQueueActiveMgr > timerQueueMgrEPICS; - -epicsTimerQueueActive::~epicsTimerQueueActive () {} - -epicsTimerQueueActive & epicsTimerQueueActive::allocate ( bool okToShare, unsigned threadPriority ) -{ - epicsSingleton < timerQueueActiveMgr >::reference pMgr = - timerQueueMgrEPICS.getReference (); - return pMgr->allocate ( pMgr, okToShare, threadPriority ); -} - -timerQueueActive :: - timerQueueActive ( RefMgr & refMgr, - bool okToShareIn, unsigned priority ) : - _refMgr ( refMgr ), queue ( *this ), thread ( *this, "timerQueue", - epicsThreadGetStackSize ( epicsThreadStackMedium ), priority ), - sleepQuantum ( epicsThreadSleepQuantum() ), okToShare ( okToShareIn ), - exitFlag ( false ), terminateFlag ( false ) -{ -} - -void timerQueueActive::start () -{ - this->thread.start (); -} - -timerQueueActive::~timerQueueActive () -{ - this->terminateFlag = true; - this->rescheduleEvent.signal (); - while ( ! this->exitFlag ) { - this->exitEvent.wait ( 1.0 ); - } - // in case other threads are waiting here also - this->exitEvent.signal (); -} - -void timerQueueActive :: _printLastChanceExceptionMessage ( - const char * pExceptionTypeName, - const char * pExceptionContext ) -{ - char date[64]; - try { - epicsTime cur = epicsTime :: getCurrent (); - cur.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S.%f"); - } - catch ( ... ) { - strcpy ( date, "" ); - } - errlogPrintf ( - "timerQueueActive: Unexpected C++ exception \"%s\" with type \"%s\" " - "while processing timer queue, at %s\n", - pExceptionContext, pExceptionTypeName, date ); -} - - -void timerQueueActive :: run () -{ - this->exitFlag = false; - while ( ! this->terminateFlag ) { - try { - double delay = this->queue.process ( epicsTime::getCurrent() ); - debugPrintf ( ( "timer thread sleeping for %g sec (max)\n", delay ) ); - this->rescheduleEvent.wait ( delay ); - } - catch ( std :: exception & except ) { - _printLastChanceExceptionMessage ( - typeid ( except ).name (), except.what () ); - epicsThreadSleep ( 10.0 ); - } - catch ( ... ) { - _printLastChanceExceptionMessage ( - "catch ( ... )", "Non-standard C++ exception" ); - epicsThreadSleep ( 10.0 ); - } - } - this->exitFlag = true; - this->exitEvent.signal (); // no access to queue after exitEvent signal -} - -epicsTimer & timerQueueActive::createTimer () -{ - return this->queue.createTimer(); -} - -epicsTimerForC & timerQueueActive::createTimerForC ( epicsTimerCallback pCallback, void * pArg ) -{ - return this->queue.createTimerForC ( pCallback, pArg ); -} - -void timerQueueActive::reschedule () -{ - this->rescheduleEvent.signal (); -} - -double timerQueueActive::quantum () -{ - return this->sleepQuantum; -} - -void timerQueueActive::show ( unsigned int level ) const -{ - printf ( "EPICS threaded timer queue at %p\n", - static_cast ( this ) ); - if ( level > 0u ) { - // specifying level one here avoids recursive - // show callback - this->thread.show ( 1u ); - this->queue.show ( level - 1u ); - printf ( "reschedule event\n" ); - this->rescheduleEvent.show ( level - 1u ); - printf ( "exit event\n" ); - this->exitEvent.show ( level - 1u ); - printf ( "exitFlag = %c, terminateFlag = %c\n", - this->exitFlag ? 'T' : 'F', - this->terminateFlag ? 'T' : 'F' ); - } -} - -epicsTimerQueue & timerQueueActive::getEpicsTimerQueue () -{ - return static_cast < epicsTimerQueue &> ( * this ); -} - diff --git a/src/libCom/timer/timerQueueActiveMgr.cpp b/src/libCom/timer/timerQueueActiveMgr.cpp deleted file mode 100644 index d6349a84c..000000000 --- a/src/libCom/timer/timerQueueActiveMgr.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsGuard.h" -#include "timerPrivate.h" - -timerQueueActiveMgr::timerQueueActiveMgr () -{ -} - -timerQueueActiveMgr::~timerQueueActiveMgr () -{ - epicsGuard < epicsMutex > locker ( this->mutex ); -} - -epicsTimerQueueActiveForC & timerQueueActiveMgr :: - allocate ( RefThis & refThis, bool okToShare, unsigned threadPriority ) -{ - epicsGuard < epicsMutex > locker ( this->mutex ); - if ( okToShare ) { - tsDLIter < epicsTimerQueueActiveForC > iter = this->sharedQueueList.firstIter (); - while ( iter.valid () ) { - if ( iter->threadPriority () == threadPriority ) { - assert ( iter->timerQueueActiveMgrPrivate::referenceCount < UINT_MAX ); - iter->timerQueueActiveMgrPrivate::referenceCount++; - return *iter; - } - iter++; - } - } - - epicsTimerQueueActiveForC & queue = - * new epicsTimerQueueActiveForC ( refThis, okToShare, threadPriority ); - queue.timerQueueActiveMgrPrivate::referenceCount = 1u; - if ( okToShare ) { - this->sharedQueueList.add ( queue ); - } - return queue; -} - -void timerQueueActiveMgr :: - release ( epicsTimerQueueActiveForC & queue ) -{ - { - epicsGuard < epicsMutex > locker ( this->mutex ); - assert ( queue.timerQueueActiveMgrPrivate::referenceCount > 0u ); - queue.timerQueueActiveMgrPrivate::referenceCount--; - if ( queue.timerQueueActiveMgrPrivate::referenceCount > 0u ) { - return; - } - else if ( queue.sharingOK () ) { - this->sharedQueueList.remove ( queue ); - } - } - // delete only after we release the guard in case the embedded - // reference is the last one and this object is destroyed - // as a side effect - timerQueueActiveMgrPrivate * pPriv = & queue; - delete pPriv; -} - -timerQueueActiveMgrPrivate::timerQueueActiveMgrPrivate () : - referenceCount ( 0u ) -{ -} - -timerQueueActiveMgrPrivate::~timerQueueActiveMgrPrivate () -{ -} diff --git a/src/libCom/timer/timerQueuePassive.cpp b/src/libCom/timer/timerQueuePassive.cpp deleted file mode 100644 index a352c5672..000000000 --- a/src/libCom/timer/timerQueuePassive.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -// -// Note, a free list for this class is not currently used because of -// entanglements between the file scope free list destructor and a -// file scope fdManager destructor which is trying to call a -// destructor for a passive timer queue which is no longer valid -// in pool. -// - -#include - -#define epicsExportSharedSymbols -#include "timerPrivate.h" - -epicsTimerQueuePassive::~epicsTimerQueuePassive () {} - -epicsTimerQueuePassive & epicsTimerQueuePassive::create ( epicsTimerQueueNotify ¬ify ) -{ - return * new timerQueuePassive ( notify ); -} - -timerQueuePassive::timerQueuePassive ( epicsTimerQueueNotify ¬ifyIn ) : - queue ( notifyIn ) {} - -timerQueuePassive::~timerQueuePassive () {} - -epicsTimer & timerQueuePassive::createTimer () -{ - return this->queue.createTimer (); -} - -epicsTimerForC & timerQueuePassive::createTimerForC ( epicsTimerCallback pCallback, void * pArg ) -{ - return this->queue.createTimerForC ( pCallback, pArg ); -} - -double timerQueuePassive::process ( const epicsTime & currentTime ) -{ - return this->queue.process ( currentTime ); -} - -void timerQueuePassive::show ( unsigned int level ) const -{ - printf ( "EPICS non-threaded timer queue at %p\n", - static_cast ( this ) ); - if ( level >=1u ) { - this->queue.show ( level - 1u ); - } -} - -epicsTimerQueue & timerQueuePassive::getEpicsTimerQueue () -{ - return static_cast < epicsTimerQueue &> ( * this ); -} - diff --git a/src/libCom/valgrind/valgrind.h b/src/libCom/valgrind/valgrind.h deleted file mode 100755 index c503172d5..000000000 --- a/src/libCom/valgrind/valgrind.h +++ /dev/null @@ -1,6587 +0,0 @@ -/* -*- c -*- - ---------------------------------------------------------------- - - Notice that the following BSD-style license applies to this one - file (valgrind.h) only. The rest of Valgrind is licensed under the - terms of the GNU General Public License, version 2, unless - otherwise indicated. See the COPYING file in the source - distribution for details. - - ---------------------------------------------------------------- - - This file is part of Valgrind, a dynamic binary instrumentation - framework. - - Copyright (C) 2000-2013 Julian Seward. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ---------------------------------------------------------------- - - Notice that the above BSD-style license applies to this one file - (valgrind.h) only. The entire rest of Valgrind is licensed under - the terms of the GNU General Public License, version 2. See the - COPYING file in the source distribution for details. - - ---------------------------------------------------------------- -*/ - - -/* This file is for inclusion into client (your!) code. - - You can use these macros to manipulate and query Valgrind's - execution inside your own programs. - - The resulting executables will still run without Valgrind, just a - little bit more slowly than they otherwise would, but otherwise - unchanged. When not running on valgrind, each client request - consumes very few (eg. 7) instructions, so the resulting performance - loss is negligible unless you plan to execute client requests - millions of times per second. Nevertheless, if that is still a - problem, you can compile with the NVALGRIND symbol defined (gcc - -DNVALGRIND) so that client requests are not even compiled in. */ - -#ifndef __VALGRIND_H -#define __VALGRIND_H - - -/* ------------------------------------------------------------------ */ -/* VERSION NUMBER OF VALGRIND */ -/* ------------------------------------------------------------------ */ - -/* Specify Valgrind's version number, so that user code can - conditionally compile based on our version number. Note that these - were introduced at version 3.6 and so do not exist in version 3.5 - or earlier. The recommended way to use them to check for "version - X.Y or later" is (eg) - -#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__) \ - && (__VALGRIND_MAJOR__ > 3 \ - || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6)) -*/ -#define __VALGRIND_MAJOR__ 3 -#define __VALGRIND_MINOR__ 10 - - -#include - -/* Nb: this file might be included in a file compiled with -ansi. So - we can't use C++ style "//" comments nor the "asm" keyword (instead - use "__asm__"). */ - -/* Derive some tags indicating what the target platform is. Note - that in this file we're using the compiler's CPP symbols for - identifying architectures, which are different to the ones we use - within the rest of Valgrind. Note, __powerpc__ is active for both - 32 and 64-bit PPC, whereas __powerpc64__ is only active for the - latter (on Linux, that is). - - Misc note: how to find out what's predefined in gcc by default: - gcc -Wp,-dM somefile.c -*/ -#undef PLAT_x86_darwin -#undef PLAT_amd64_darwin -#undef PLAT_x86_win32 -#undef PLAT_amd64_win64 -#undef PLAT_x86_linux -#undef PLAT_amd64_linux -#undef PLAT_ppc32_linux -#undef PLAT_ppc64be_linux -#undef PLAT_ppc64le_linux -#undef PLAT_arm_linux -#undef PLAT_arm64_linux -#undef PLAT_s390x_linux -#undef PLAT_mips32_linux -#undef PLAT_mips64_linux - - -#if defined(__APPLE__) && defined(__i386__) -# define PLAT_x86_darwin 1 -#elif defined(__APPLE__) && defined(__x86_64__) -# define PLAT_amd64_darwin 1 -#elif (defined(__MINGW32__) && !defined(__MINGW64__)) \ - || defined(__CYGWIN32__) \ - || (defined(_WIN32) && defined(_M_IX86) && defined(__GNUC__)) -# define PLAT_x86_win32 1 -#elif defined(__MINGW64__) \ - || (defined(_WIN64) && defined(_M_X64) && defined(__GNUC__)) -# define PLAT_amd64_win64 1 -#elif defined(__linux__) && defined(__i386__) -# define PLAT_x86_linux 1 -#elif defined(__linux__) && defined(__x86_64__) -# define PLAT_amd64_linux 1 -#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) -# define PLAT_ppc32_linux 1 -#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF != 2 -/* Big Endian uses ELF version 1 */ -# define PLAT_ppc64be_linux 1 -#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF == 2 -/* Little Endian uses ELF version 2 */ -# define PLAT_ppc64le_linux 1 -#elif defined(__linux__) && defined(__arm__) && !defined(__aarch64__) -# define PLAT_arm_linux 1 -#elif defined(__linux__) && defined(__aarch64__) && !defined(__arm__) -# define PLAT_arm64_linux 1 -#elif defined(__linux__) && defined(__s390__) && defined(__s390x__) -# define PLAT_s390x_linux 1 -#elif defined(__linux__) && defined(__mips__) && (__mips==64) -# define PLAT_mips64_linux 1 -#elif defined(__linux__) && defined(__mips__) && (__mips!=64) -# define PLAT_mips32_linux 1 -#else -/* If we're not compiling for our target platform, don't generate - any inline asms. */ -# if !defined(NVALGRIND) -# define NVALGRIND 1 -# endif -#endif - - -/* ------------------------------------------------------------------ */ -/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */ -/* in here of use to end-users -- skip to the next section. */ -/* ------------------------------------------------------------------ */ - -/* - * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client - * request. Accepts both pointers and integers as arguments. - * - * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind - * client request that does not return a value. - - * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind - * client request and whose value equals the client request result. Accepts - * both pointers and integers as arguments. Note that such calls are not - * necessarily pure functions -- they may have side effects. - */ - -#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, \ - _zzq_request, _zzq_arg1, _zzq_arg2, \ - _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default), \ - (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ - (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0) - -#define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1, \ - _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ - (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ - (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0) - -#if defined(NVALGRIND) - -/* Define NVALGRIND to completely remove the Valgrind magic sequence - from the compiled code (analogous to NDEBUG's effects on - assert()) */ -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - (_zzq_default) - -#else /* ! NVALGRIND */ - -/* The following defines the magic code sequences which the JITter - spots and handles magically. Don't look too closely at them as - they will rot your brain. - - The assembly code sequences for all architectures is in this one - file. This is because this file must be stand-alone, and we don't - want to have multiple files. - - For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default - value gets put in the return slot, so that everything works when - this is executed not under Valgrind. Args are passed in a memory - block, and so there's no intrinsic limit to the number that could - be passed, but it's currently five. - - The macro args are: - _zzq_rlval result lvalue - _zzq_default default value (result returned when running on real CPU) - _zzq_request request code - _zzq_arg1..5 request params - - The other two macros are used to support function wrapping, and are - a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the - guest's NRADDR pseudo-register and whatever other information is - needed to safely run the call original from the wrapper: on - ppc64-linux, the R2 value at the divert point is also needed. This - information is abstracted into a user-visible type, OrigFn. - - VALGRIND_CALL_NOREDIR_* behaves the same as the following on the - guest, but guarantees that the branch instruction will not be - redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64: - branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a - complete inline asm, since it needs to be combined with more magic - inline asm stuff to be useful. -*/ - -/* ------------------------- x86-{linux,darwin} ---------------- */ - -#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \ - || (defined(PLAT_x86_win32) && defined(__GNUC__)) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "roll $3, %%edi ; roll $13, %%edi\n\t" \ - "roll $29, %%edi ; roll $19, %%edi\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - __extension__ \ - ({volatile unsigned int _zzq_args[6]; \ - volatile unsigned int _zzq_result; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %EDX = client_request ( %EAX ) */ \ - "xchgl %%ebx,%%ebx" \ - : "=d" (_zzq_result) \ - : "a" (&_zzq_args[0]), "0" (_zzq_default) \ - : "cc", "memory" \ - ); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %EAX = guest_NRADDR */ \ - "xchgl %%ecx,%%ecx" \ - : "=a" (__addr) \ - : \ - : "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_EAX \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* call-noredir *%EAX */ \ - "xchgl %%edx,%%edx\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "xchgl %%edi,%%edi\n\t" \ - : : : "cc", "memory" \ - ); \ - } while (0) - -#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */ - -/* ------------------------- x86-Win32 ------------------------- */ - -#if defined(PLAT_x86_win32) && !defined(__GNUC__) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#if defined(_MSC_VER) - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - __asm rol edi, 3 __asm rol edi, 13 \ - __asm rol edi, 29 __asm rol edi, 19 - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - valgrind_do_client_request_expr((uintptr_t)(_zzq_default), \ - (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1), \ - (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3), \ - (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5)) - -static __inline uintptr_t -valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request, - uintptr_t _zzq_arg1, uintptr_t _zzq_arg2, - uintptr_t _zzq_arg3, uintptr_t _zzq_arg4, - uintptr_t _zzq_arg5) -{ - volatile uintptr_t _zzq_args[6]; - volatile unsigned int _zzq_result; - _zzq_args[0] = (uintptr_t)(_zzq_request); - _zzq_args[1] = (uintptr_t)(_zzq_arg1); - _zzq_args[2] = (uintptr_t)(_zzq_arg2); - _zzq_args[3] = (uintptr_t)(_zzq_arg3); - _zzq_args[4] = (uintptr_t)(_zzq_arg4); - _zzq_args[5] = (uintptr_t)(_zzq_arg5); - __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default - __SPECIAL_INSTRUCTION_PREAMBLE - /* %EDX = client_request ( %EAX ) */ - __asm xchg ebx,ebx - __asm mov _zzq_result, edx - } - return _zzq_result; -} - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned int __addr; \ - __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %EAX = guest_NRADDR */ \ - __asm xchg ecx,ecx \ - __asm mov __addr, eax \ - } \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_EAX ERROR - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ - __asm xchg edi,edi \ - } \ - } while (0) - -#else -#error Unsupported compiler. -#endif - -#endif /* PLAT_x86_win32 */ - -/* ------------------------ amd64-{linux,darwin} --------------- */ - -#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \ - || (defined(PLAT_amd64_win64) && defined(__GNUC__)) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \ - "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - __extension__ \ - ({ volatile unsigned long long int _zzq_args[6]; \ - volatile unsigned long long int _zzq_result; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %RDX = client_request ( %RAX ) */ \ - "xchgq %%rbx,%%rbx" \ - : "=d" (_zzq_result) \ - : "a" (&_zzq_args[0]), "0" (_zzq_default) \ - : "cc", "memory" \ - ); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %RAX = guest_NRADDR */ \ - "xchgq %%rcx,%%rcx" \ - : "=a" (__addr) \ - : \ - : "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_RAX \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* call-noredir *%RAX */ \ - "xchgq %%rdx,%%rdx\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "xchgq %%rdi,%%rdi\n\t" \ - : : : "cc", "memory" \ - ); \ - } while (0) - -#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ - -/* ------------------------- amd64-Win64 ------------------------- */ - -#if defined(PLAT_amd64_win64) && !defined(__GNUC__) - -#error Unsupported compiler. - -#endif /* PLAT_amd64_win64 */ - -/* ------------------------ ppc32-linux ------------------------ */ - -#if defined(PLAT_ppc32_linux) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rlwinm 0,0,3,0,31 ; rlwinm 0,0,13,0,31\n\t" \ - "rlwinm 0,0,29,0,31 ; rlwinm 0,0,19,0,31\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - __extension__ \ - ({ unsigned int _zzq_args[6]; \ - unsigned int _zzq_result; \ - unsigned int* _zzq_ptr; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 3,%1\n\t" /*default*/ \ - "mr 4,%2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" /*result*/ \ - : "=b" (_zzq_result) \ - : "b" (_zzq_default), "b" (_zzq_ptr) \ - : "cc", "memory", "r3", "r4"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "or 5,5,5\n\t" \ - ); \ - } while (0) - -#endif /* PLAT_ppc32_linux */ - -/* ------------------------ ppc64-linux ------------------------ */ - -#if defined(PLAT_ppc64be_linux) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - unsigned long long int r2; /* what tocptr do we need? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ - "rotldi 0,0,61 ; rotldi 0,0,51\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - __extension__ \ - ({ unsigned long long int _zzq_args[6]; \ - unsigned long long int _zzq_result; \ - unsigned long long int* _zzq_ptr; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 3,%1\n\t" /*default*/ \ - "mr 4,%2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" /*result*/ \ - : "=b" (_zzq_result) \ - : "b" (_zzq_default), "b" (_zzq_ptr) \ - : "cc", "memory", "r3", "r4"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->r2 = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "or 5,5,5\n\t" \ - ); \ - } while (0) - -#endif /* PLAT_ppc64be_linux */ - -#if defined(PLAT_ppc64le_linux) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - unsigned long long int r2; /* what tocptr do we need? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ - "rotldi 0,0,61 ; rotldi 0,0,51\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - __extension__ \ - ({ unsigned long long int _zzq_args[6]; \ - unsigned long long int _zzq_result; \ - unsigned long long int* _zzq_ptr; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 3,%1\n\t" /*default*/ \ - "mr 4,%2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" /*result*/ \ - : "=b" (_zzq_result) \ - : "b" (_zzq_default), "b" (_zzq_ptr) \ - : "cc", "memory", "r3", "r4"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->r2 = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R12 */ \ - "or 3,3,3\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "or 5,5,5\n\t" \ - ); \ - } while (0) - -#endif /* PLAT_ppc64le_linux */ - -/* ------------------------- arm-linux ------------------------- */ - -#if defined(PLAT_arm_linux) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \ - "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - __extension__ \ - ({volatile unsigned int _zzq_args[6]; \ - volatile unsigned int _zzq_result; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - __asm__ volatile("mov r3, %1\n\t" /*default*/ \ - "mov r4, %2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* R3 = client_request ( R4 ) */ \ - "orr r10, r10, r10\n\t" \ - "mov %0, r3" /*result*/ \ - : "=r" (_zzq_result) \ - : "r" (_zzq_default), "r" (&_zzq_args[0]) \ - : "cc","memory", "r3", "r4"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* R3 = guest_NRADDR */ \ - "orr r11, r11, r11\n\t" \ - "mov %0, r3" \ - : "=r" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R4 */ \ - "orr r12, r12, r12\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "orr r9, r9, r9\n\t" \ - : : : "cc", "memory" \ - ); \ - } while (0) - -#endif /* PLAT_arm_linux */ - -/* ------------------------ arm64-linux ------------------------- */ - -#if defined(PLAT_arm64_linux) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "ror x12, x12, #3 ; ror x12, x12, #13 \n\t" \ - "ror x12, x12, #51 ; ror x12, x12, #61 \n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - __extension__ \ - ({volatile unsigned long long int _zzq_args[6]; \ - volatile unsigned long long int _zzq_result; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - __asm__ volatile("mov x3, %1\n\t" /*default*/ \ - "mov x4, %2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* X3 = client_request ( X4 ) */ \ - "orr x10, x10, x10\n\t" \ - "mov %0, x3" /*result*/ \ - : "=r" (_zzq_result) \ - : "r" (_zzq_default), "r" (&_zzq_args[0]) \ - : "cc","memory", "x3", "x4"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* X3 = guest_NRADDR */ \ - "orr x11, x11, x11\n\t" \ - "mov %0, x3" \ - : "=r" (__addr) \ - : \ - : "cc", "memory", "x3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir X8 */ \ - "orr x12, x12, x12\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "orr x9, x9, x9\n\t" \ - : : : "cc", "memory" \ - ); \ - } while (0) - -#endif /* PLAT_arm64_linux */ - -/* ------------------------ s390x-linux ------------------------ */ - -#if defined(PLAT_s390x_linux) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - } - OrigFn; - -/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific - * code. This detection is implemented in platform specific toIR.c - * (e.g. VEX/priv/guest_s390_decoder.c). - */ -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "lr 15,15\n\t" \ - "lr 1,1\n\t" \ - "lr 2,2\n\t" \ - "lr 3,3\n\t" - -#define __CLIENT_REQUEST_CODE "lr 2,2\n\t" -#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t" -#define __CALL_NO_REDIR_CODE "lr 4,4\n\t" -#define __VEX_INJECT_IR_CODE "lr 5,5\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - __extension__ \ - ({volatile unsigned long long int _zzq_args[6]; \ - volatile unsigned long long int _zzq_result; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - __asm__ volatile(/* r2 = args */ \ - "lgr 2,%1\n\t" \ - /* r3 = default */ \ - "lgr 3,%2\n\t" \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - __CLIENT_REQUEST_CODE \ - /* results = r3 */ \ - "lgr %0, 3\n\t" \ - : "=d" (_zzq_result) \ - : "a" (&_zzq_args[0]), "0" (_zzq_default) \ - : "cc", "2", "3", "memory" \ - ); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - __GET_NR_CONTEXT_CODE \ - "lgr %0, 3\n\t" \ - : "=a" (__addr) \ - : \ - : "cc", "3", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_R1 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - __CALL_NO_REDIR_CODE - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - __VEX_INJECT_IR_CODE); \ - } while (0) - -#endif /* PLAT_s390x_linux */ - -/* ------------------------- mips32-linux ---------------- */ - -#if defined(PLAT_mips32_linux) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -/* .word 0x342 - * .word 0x742 - * .word 0xC2 - * .word 0x4C2*/ -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "srl $0, $0, 13\n\t" \ - "srl $0, $0, 29\n\t" \ - "srl $0, $0, 3\n\t" \ - "srl $0, $0, 19\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - __extension__ \ - ({ volatile unsigned int _zzq_args[6]; \ - volatile unsigned int _zzq_result; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - __asm__ volatile("move $11, %1\n\t" /*default*/ \ - "move $12, %2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* T3 = client_request ( T4 ) */ \ - "or $13, $13, $13\n\t" \ - "move %0, $11\n\t" /*result*/ \ - : "=r" (_zzq_result) \ - : "r" (_zzq_default), "r" (&_zzq_args[0]) \ - : "$11", "$12"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %t9 = guest_NRADDR */ \ - "or $14, $14, $14\n\t" \ - "move %0, $11" /*result*/ \ - : "=r" (__addr) \ - : \ - : "$11" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_T9 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* call-noredir *%t9 */ \ - "or $15, $15, $15\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "or $11, $11, $11\n\t" \ - ); \ - } while (0) - - -#endif /* PLAT_mips32_linux */ - -/* ------------------------- mips64-linux ---------------- */ - -#if defined(PLAT_mips64_linux) - -typedef - struct { - unsigned long long nraddr; /* where's the code? */ - } - OrigFn; - -/* dsll $0,$0, 3 - * dsll $0,$0, 13 - * dsll $0,$0, 29 - * dsll $0,$0, 19*/ -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "dsll $0,$0, 3 ; dsll $0,$0,13\n\t" \ - "dsll $0,$0,29 ; dsll $0,$0,19\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - __extension__ \ - ({ volatile unsigned long long int _zzq_args[6]; \ - volatile unsigned long long int _zzq_result; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - __asm__ volatile("move $11, %1\n\t" /*default*/ \ - "move $12, %2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* $11 = client_request ( $12 ) */ \ - "or $13, $13, $13\n\t" \ - "move %0, $11\n\t" /*result*/ \ - : "=r" (_zzq_result) \ - : "r" (_zzq_default), "r" (&_zzq_args[0]) \ - : "$11", "$12"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* $11 = guest_NRADDR */ \ - "or $14, $14, $14\n\t" \ - "move %0, $11" /*result*/ \ - : "=r" (__addr) \ - : \ - : "$11"); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_T9 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* call-noredir $25 */ \ - "or $15, $15, $15\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "or $11, $11, $11\n\t" \ - ); \ - } while (0) - -#endif /* PLAT_mips64_linux */ - -/* Insert assembly code for other platforms here... */ - -#endif /* NVALGRIND */ - - -/* ------------------------------------------------------------------ */ -/* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */ -/* ugly. It's the least-worst tradeoff I can think of. */ -/* ------------------------------------------------------------------ */ - -/* This section defines magic (a.k.a appalling-hack) macros for doing - guaranteed-no-redirection macros, so as to get from function - wrappers to the functions they are wrapping. The whole point is to - construct standard call sequences, but to do the call itself with a - special no-redirect call pseudo-instruction that the JIT - understands and handles specially. This section is long and - repetitious, and I can't see a way to make it shorter. - - The naming scheme is as follows: - - CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc} - - 'W' stands for "word" and 'v' for "void". Hence there are - different macros for calling arity 0, 1, 2, 3, 4, etc, functions, - and for each, the possibility of returning a word-typed result, or - no result. -*/ - -/* Use these to write the name of your wrapper. NOTE: duplicates - VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. NOTE also: inserts - the default behaviour equivalance class tag "0000" into the name. - See pub_tool_redir.h for details -- normally you don't need to - think about this, though. */ - -/* Use an extra level of macroisation so as to ensure the soname/fnname - args are fully macro-expanded before pasting them together. */ -#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd - -#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \ - VG_CONCAT4(_vgw00000ZU_,soname,_,fnname) - -#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \ - VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname) - -/* Use this macro from within a wrapper function to collect the - context (address and possibly other info) of the original function. - Once you have that you can then use it in one of the CALL_FN_ - macros. The type of the argument _lval is OrigFn. */ -#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval) - -/* Also provide end-user facilities for function replacement, rather - than wrapping. A replacement function differs from a wrapper in - that it has no way to get hold of the original function being - called, and hence no way to call onwards to it. In a replacement - function, VALGRIND_GET_ORIG_FN always returns zero. */ - -#define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname) \ - VG_CONCAT4(_vgr00000ZU_,soname,_,fnname) - -#define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname) \ - VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname) - -/* Derivatives of the main macros below, for calling functions - returning void. */ - -#define CALL_FN_v_v(fnptr) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_v(_junk,fnptr); } while (0) - -#define CALL_FN_v_W(fnptr, arg1) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_W(_junk,fnptr,arg1); } while (0) - -#define CALL_FN_v_WW(fnptr, arg1,arg2) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0) - -#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0) - -#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0) - -#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0) - -#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0) - -#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0) - -/* ------------------------- x86-{linux,darwin} ---------------- */ - -#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) - -/* These regs are trashed by the hidden call. No need to mention eax - as gcc can already see that, plus causes gcc to bomb. */ -#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx" - -/* Macros to save and align the stack before making a function - call and restore it afterwards as gcc may not keep the stack - pointer aligned if it doesn't realise calls are being made - to other functions. */ - -#define VALGRIND_ALIGN_STACK \ - "movl %%esp,%%edi\n\t" \ - "andl $0xfffffff0,%%esp\n\t" -#define VALGRIND_RESTORE_STACK \ - "movl %%edi,%%esp\n\t" - -/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $12, %%esp\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $8, %%esp\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $4, %%esp\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $12, %%esp\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $8, %%esp\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $4, %%esp\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $12, %%esp\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $8, %%esp\n\t" \ - "pushl 40(%%eax)\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $4, %%esp\n\t" \ - "pushl 44(%%eax)\n\t" \ - "pushl 40(%%eax)\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "pushl 48(%%eax)\n\t" \ - "pushl 44(%%eax)\n\t" \ - "pushl 40(%%eax)\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_x86_linux || PLAT_x86_darwin */ - -/* ------------------------ amd64-{linux,darwin} --------------- */ - -#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) - -/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \ - "rdi", "r8", "r9", "r10", "r11" - -/* This is all pretty complex. It's so as to make stack unwinding - work reliably. See bug 243270. The basic problem is the sub and - add of 128 of %rsp in all of the following macros. If gcc believes - the CFA is in %rsp, then unwinding may fail, because what's at the - CFA is not what gcc "expected" when it constructs the CFIs for the - places where the macros are instantiated. - - But we can't just add a CFI annotation to increase the CFA offset - by 128, to match the sub of 128 from %rsp, because we don't know - whether gcc has chosen %rsp as the CFA at that point, or whether it - has chosen some other register (eg, %rbp). In the latter case, - adding a CFI annotation to change the CFA offset is simply wrong. - - So the solution is to get hold of the CFA using - __builtin_dwarf_cfa(), put it in a known register, and add a - CFI annotation to say what the register is. We choose %rbp for - this (perhaps perversely), because: - - (1) %rbp is already subject to unwinding. If a new register was - chosen then the unwinder would have to unwind it in all stack - traces, which is expensive, and - - (2) %rbp is already subject to precise exception updates in the - JIT. If a new register was chosen, we'd have to have precise - exceptions for it too, which reduces performance of the - generated code. - - However .. one extra complication. We can't just whack the result - of __builtin_dwarf_cfa() into %rbp and then add %rbp to the - list of trashed registers at the end of the inline assembly - fragments; gcc won't allow %rbp to appear in that list. Hence - instead we need to stash %rbp in %r15 for the duration of the asm, - and say that %r15 is trashed instead. gcc seems happy to go with - that. - - Oh .. and this all needs to be conditionalised so that it is - unchanged from before this commit, when compiled with older gccs - that don't support __builtin_dwarf_cfa. Furthermore, since - this header file is freestanding, it has to be independent of - config.h, and so the following conditionalisation cannot depend on - configure time checks. - - Although it's not clear from - 'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)', - this expression excludes Darwin. - .cfi directives in Darwin assembly appear to be completely - different and I haven't investigated how they work. - - For even more entertainment value, note we have to use the - completely undocumented __builtin_dwarf_cfa(), which appears to - really compute the CFA, whereas __builtin_frame_address(0) claims - to but actually doesn't. See - https://bugs.kde.org/show_bug.cgi?id=243270#c47 -*/ -#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) -# define __FRAME_POINTER \ - ,"r"(__builtin_dwarf_cfa()) -# define VALGRIND_CFI_PROLOGUE \ - "movq %%rbp, %%r15\n\t" \ - "movq %2, %%rbp\n\t" \ - ".cfi_remember_state\n\t" \ - ".cfi_def_cfa rbp, 0\n\t" -# define VALGRIND_CFI_EPILOGUE \ - "movq %%r15, %%rbp\n\t" \ - ".cfi_restore_state\n\t" -#else -# define __FRAME_POINTER -# define VALGRIND_CFI_PROLOGUE -# define VALGRIND_CFI_EPILOGUE -#endif - -/* Macros to save and align the stack before making a function - call and restore it afterwards as gcc may not keep the stack - pointer aligned if it doesn't realise calls are being made - to other functions. */ - -#define VALGRIND_ALIGN_STACK \ - "movq %%rsp,%%r14\n\t" \ - "andq $0xfffffffffffffff0,%%rsp\n\t" -#define VALGRIND_RESTORE_STACK \ - "movq %%r14,%%rsp\n\t" - -/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned - long) == 8. */ - -/* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ - macros. In order not to trash the stack redzone, we need to drop - %rsp by 128 before the hidden call, and restore afterwards. The - nastyness is that it is only by luck that the stack still appears - to be unwindable during the hidden call - since then the behaviour - of any routine using this macro does not match what the CFI data - says. Sigh. - - Why is this important? Imagine that a wrapper has a stack - allocated local, and passes to the hidden call, a pointer to it. - Because gcc does not know about the hidden call, it may allocate - that local in the redzone. Unfortunately the hidden call may then - trash it before it comes to use it. So we must step clear of the - redzone, for the duration of the hidden call, to make it safe. - - Probably the same problem afflicts the other redzone-style ABIs too - (ppc64-linux); but for those, the stack is - self describing (none of this CFI nonsense) so at least messing - with the stack pointer doesn't give a danger of non-unwindable - stack. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $136,%%rsp\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $136,%%rsp\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $136,%%rsp\n\t" \ - "pushq 88(%%rax)\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "pushq 96(%%rax)\n\t" \ - "pushq 88(%%rax)\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ - -/* ------------------------ ppc32-linux ------------------------ */ - -#if defined(PLAT_ppc32_linux) - -/* This is useful for finding out about the on-stack stuff: - - extern int f9 ( int,int,int,int,int,int,int,int,int ); - extern int f10 ( int,int,int,int,int,int,int,int,int,int ); - extern int f11 ( int,int,int,int,int,int,int,int,int,int,int ); - extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int ); - - int g9 ( void ) { - return f9(11,22,33,44,55,66,77,88,99); - } - int g10 ( void ) { - return f10(11,22,33,44,55,66,77,88,99,110); - } - int g11 ( void ) { - return f11(11,22,33,44,55,66,77,88,99,110,121); - } - int g12 ( void ) { - return f12(11,22,33,44,55,66,77,88,99,110,121,132); - } -*/ - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* Macros to save and align the stack before making a function - call and restore it afterwards as gcc may not keep the stack - pointer aligned if it doesn't realise calls are being made - to other functions. */ - -#define VALGRIND_ALIGN_STACK \ - "mr 28,1\n\t" \ - "rlwinm 1,1,0,0,27\n\t" -#define VALGRIND_RESTORE_STACK \ - "mr 1,28\n\t" - -/* These CALL_FN_ macros assume that on ppc32-linux, - sizeof(unsigned long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "addi 1,1,-16\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "addi 1,1,-16\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "addi 1,1,-32\n\t" \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,16(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - _argvec[12] = (unsigned long)arg12; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "addi 1,1,-32\n\t" \ - /* arg12 */ \ - "lwz 3,48(11)\n\t" \ - "stw 3,20(1)\n\t" \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,16(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc32_linux */ - -/* ------------------------ ppc64-linux ------------------------ */ - -#if defined(PLAT_ppc64be_linux) - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* Macros to save and align the stack before making a function - call and restore it afterwards as gcc may not keep the stack - pointer aligned if it doesn't realise calls are being made - to other functions. */ - -#define VALGRIND_ALIGN_STACK \ - "mr 28,1\n\t" \ - "rldicr 1,1,0,59\n\t" -#define VALGRIND_RESTORE_STACK \ - "mr 1,28\n\t" - -/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned - long) == 8. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg12 */ \ - "ld 3,96(11)\n\t" \ - "std 3,136(1)\n\t" \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc64be_linux */ - -/* ------------------------- ppc64le-linux ----------------------- */ -#if defined(PLAT_ppc64le_linux) - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* Macros to save and align the stack before making a function - call and restore it afterwards as gcc may not keep the stack - pointer aligned if it doesn't realise calls are being made - to other functions. */ - -#define VALGRIND_ALIGN_STACK \ - "mr 28,1\n\t" \ - "rldicr 1,1,0,59\n\t" -#define VALGRIND_RESTORE_STACK \ - "mr 1,28\n\t" - -/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned - long) == 8. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 9, 56(12)\n\t" /* arg7->r9 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 9, 56(12)\n\t" /* arg7->r9 */ \ - "ld 10, 64(12)\n\t" /* arg8->r10 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg9 */ \ - "ld 3,72(12)\n\t" \ - "std 3,96(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 9, 56(12)\n\t" /* arg7->r9 */ \ - "ld 10, 64(12)\n\t" /* arg8->r10 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg10 */ \ - "ld 3,80(12)\n\t" \ - "std 3,104(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(12)\n\t" \ - "std 3,96(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 9, 56(12)\n\t" /* arg7->r9 */ \ - "ld 10, 64(12)\n\t" /* arg8->r10 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg11 */ \ - "ld 3,88(12)\n\t" \ - "std 3,112(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(12)\n\t" \ - "std 3,104(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(12)\n\t" \ - "std 3,96(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 9, 56(12)\n\t" /* arg7->r9 */ \ - "ld 10, 64(12)\n\t" /* arg8->r10 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg12 */ \ - "ld 3,96(12)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg11 */ \ - "ld 3,88(12)\n\t" \ - "std 3,112(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(12)\n\t" \ - "std 3,104(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(12)\n\t" \ - "std 3,96(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 9, 56(12)\n\t" /* arg7->r9 */ \ - "ld 10, 64(12)\n\t" /* arg8->r10 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc64le_linux */ - -/* ------------------------- arm-linux ------------------------- */ - -#if defined(PLAT_arm_linux) - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14" - -/* Macros to save and align the stack before making a function - call and restore it afterwards as gcc may not keep the stack - pointer aligned if it doesn't realise calls are being made - to other functions. */ - -/* This is a bit tricky. We store the original stack pointer in r10 - as it is callee-saves. gcc doesn't allow the use of r11 for some - reason. Also, we can't directly "bic" the stack pointer in thumb - mode since r13 isn't an allowed register number in that context. - So use r4 as a temporary, since that is about to get trashed - anyway, just after each use of this macro. Side effect is we need - to be very careful about any future changes, since - VALGRIND_ALIGN_STACK simply assumes r4 is usable. */ -#define VALGRIND_ALIGN_STACK \ - "mov r10, sp\n\t" \ - "mov r4, sp\n\t" \ - "bic r4, r4, #7\n\t" \ - "mov sp, r4\n\t" -#define VALGRIND_RESTORE_STACK \ - "mov sp, r10\n\t" - -/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #4 \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "push {r0} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "push {r0, r1} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #4 \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "push {r0, r1, r2} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "push {r0, r1, r2, r3} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #4 \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "ldr r4, [%1, #36] \n\t" \ - "push {r0, r1, r2, r3, r4} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #40] \n\t" \ - "push {r0} \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "ldr r4, [%1, #36] \n\t" \ - "push {r0, r1, r2, r3, r4} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #4 \n\t" \ - "ldr r0, [%1, #40] \n\t" \ - "ldr r1, [%1, #44] \n\t" \ - "push {r0, r1} \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "ldr r4, [%1, #36] \n\t" \ - "push {r0, r1, r2, r3, r4} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #40] \n\t" \ - "ldr r1, [%1, #44] \n\t" \ - "ldr r2, [%1, #48] \n\t" \ - "push {r0, r1, r2} \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "ldr r4, [%1, #36] \n\t" \ - "push {r0, r1, r2, r3, r4} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_arm_linux */ - -/* ------------------------ arm64-linux ------------------------ */ - -#if defined(PLAT_arm64_linux) - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "x0", "x1", "x2", "x3","x4", "x5", "x6", "x7", "x8", "x9", \ - "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", \ - "x18", "x19", "x20", "x30", \ - "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", \ - "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", \ - "v26", "v27", "v28", "v29", "v30", "v31" - -/* x21 is callee-saved, so we can use it to save and restore SP around - the hidden call. */ -#define VALGRIND_ALIGN_STACK \ - "mov x21, sp\n\t" \ - "bic sp, x21, #15\n\t" -#define VALGRIND_RESTORE_STACK \ - "mov sp, x21\n\t" - -/* These CALL_FN_ macros assume that on arm64-linux, - sizeof(unsigned long) == 8. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x6, [%1, #56] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x6, [%1, #56] \n\t" \ - "ldr x7, [%1, #64] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #0x20 \n\t" \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x6, [%1, #56] \n\t" \ - "ldr x7, [%1, #64] \n\t" \ - "ldr x8, [%1, #72] \n\t" \ - "str x8, [sp, #0] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #0x20 \n\t" \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x6, [%1, #56] \n\t" \ - "ldr x7, [%1, #64] \n\t" \ - "ldr x8, [%1, #72] \n\t" \ - "str x8, [sp, #0] \n\t" \ - "ldr x8, [%1, #80] \n\t" \ - "str x8, [sp, #8] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #0x30 \n\t" \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x6, [%1, #56] \n\t" \ - "ldr x7, [%1, #64] \n\t" \ - "ldr x8, [%1, #72] \n\t" \ - "str x8, [sp, #0] \n\t" \ - "ldr x8, [%1, #80] \n\t" \ - "str x8, [sp, #8] \n\t" \ - "ldr x8, [%1, #88] \n\t" \ - "str x8, [sp, #16] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11, \ - arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #0x30 \n\t" \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x6, [%1, #56] \n\t" \ - "ldr x7, [%1, #64] \n\t" \ - "ldr x8, [%1, #72] \n\t" \ - "str x8, [sp, #0] \n\t" \ - "ldr x8, [%1, #80] \n\t" \ - "str x8, [sp, #8] \n\t" \ - "ldr x8, [%1, #88] \n\t" \ - "str x8, [sp, #16] \n\t" \ - "ldr x8, [%1, #96] \n\t" \ - "str x8, [sp, #24] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_arm64_linux */ - -/* ------------------------- s390x-linux ------------------------- */ - -#if defined(PLAT_s390x_linux) - -/* Similar workaround as amd64 (see above), but we use r11 as frame - pointer and save the old r11 in r7. r11 might be used for - argvec, therefore we copy argvec in r1 since r1 is clobbered - after the call anyway. */ -#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) -# define __FRAME_POINTER \ - ,"d"(__builtin_dwarf_cfa()) -# define VALGRIND_CFI_PROLOGUE \ - ".cfi_remember_state\n\t" \ - "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */ \ - "lgr 7,11\n\t" \ - "lgr 11,%2\n\t" \ - ".cfi_def_cfa r11, 0\n\t" -# define VALGRIND_CFI_EPILOGUE \ - "lgr 11, 7\n\t" \ - ".cfi_restore_state\n\t" -#else -# define __FRAME_POINTER -# define VALGRIND_CFI_PROLOGUE \ - "lgr 1,%1\n\t" -# define VALGRIND_CFI_EPILOGUE -#endif - -/* Nb: On s390 the stack pointer is properly aligned *at all times* - according to the s390 GCC maintainer. (The ABI specification is not - precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and - VALGRIND_RESTORE_STACK are not defined here. */ - -/* These regs are trashed by the hidden call. Note that we overwrite - r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the - function a proper return address. All others are ABI defined call - clobbers. */ -#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \ - "f0","f1","f2","f3","f4","f5","f6","f7" - -/* Nb: Although r11 is modified in the asm snippets below (inside - VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for - two reasons: - (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not - modified - (2) GCC will complain that r11 cannot appear inside a clobber section, - when compiled with -O -fno-omit-frame-pointer - */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 1, 0(1)\n\t" /* target->r1 */ \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -/* The call abi has the arguments in r2-r6 and stack */ -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1, arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-168\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,168\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-176\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,176\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7 ,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-184\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,184\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7 ,arg8, arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-192\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "mvc 184(8,15), 72(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,192\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7 ,arg8, arg9, arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-200\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "mvc 184(8,15), 72(1)\n\t" \ - "mvc 192(8,15), 80(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,200\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7 ,arg8, arg9, arg10, arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-208\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "mvc 184(8,15), 72(1)\n\t" \ - "mvc 192(8,15), 80(1)\n\t" \ - "mvc 200(8,15), 88(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,208\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - _argvec[12] = (unsigned long)arg12; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-216\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "mvc 184(8,15), 72(1)\n\t" \ - "mvc 192(8,15), 80(1)\n\t" \ - "mvc 200(8,15), 88(1)\n\t" \ - "mvc 208(8,15), 96(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,216\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - - -#endif /* PLAT_s390x_linux */ - -/* ------------------------- mips32-linux ----------------------- */ - -#if defined(PLAT_mips32_linux) - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \ -"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ -"$25", "$31" - -/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "subu $29, $29, 16 \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 16\n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "subu $29, $29, 16 \n\t" \ - "lw $4, 4(%1) \n\t" /* arg1*/ \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 16 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "subu $29, $29, 16 \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 16 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "subu $29, $29, 16 \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 16 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "subu $29, $29, 16 \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 16 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 24\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 24 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 32\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "nop\n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 32 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 32\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 28(%1) \n\t" \ - "sw $4, 24($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 32 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 40\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 28(%1) \n\t" \ - "sw $4, 24($29) \n\t" \ - "lw $4, 32(%1) \n\t" \ - "sw $4, 28($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 40 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 40\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 28(%1) \n\t" \ - "sw $4, 24($29) \n\t" \ - "lw $4, 32(%1) \n\t" \ - "sw $4, 28($29) \n\t" \ - "lw $4, 36(%1) \n\t" \ - "sw $4, 32($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 40 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 48\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 28(%1) \n\t" \ - "sw $4, 24($29) \n\t" \ - "lw $4, 32(%1) \n\t" \ - "sw $4, 28($29) \n\t" \ - "lw $4, 36(%1) \n\t" \ - "sw $4, 32($29) \n\t" \ - "lw $4, 40(%1) \n\t" \ - "sw $4, 36($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 48 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 48\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 28(%1) \n\t" \ - "sw $4, 24($29) \n\t" \ - "lw $4, 32(%1) \n\t" \ - "sw $4, 28($29) \n\t" \ - "lw $4, 36(%1) \n\t" \ - "sw $4, 32($29) \n\t" \ - "lw $4, 40(%1) \n\t" \ - "sw $4, 36($29) \n\t" \ - "lw $4, 44(%1) \n\t" \ - "sw $4, 40($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 48 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 56\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 28(%1) \n\t" \ - "sw $4, 24($29) \n\t" \ - "lw $4, 32(%1) \n\t" \ - "sw $4, 28($29) \n\t" \ - "lw $4, 36(%1) \n\t" \ - "sw $4, 32($29) \n\t" \ - "lw $4, 40(%1) \n\t" \ - "sw $4, 36($29) \n\t" \ - "lw $4, 44(%1) \n\t" \ - "sw $4, 40($29) \n\t" \ - "lw $4, 48(%1) \n\t" \ - "sw $4, 44($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 56 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_mips32_linux */ - -/* ------------------------- mips64-linux ------------------------- */ - -#if defined(PLAT_mips64_linux) - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \ -"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ -"$25", "$31" - -/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" /* arg1*/ \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $10, 56(%1)\n\t" \ - "ld $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $10, 56(%1)\n\t" \ - "ld $11, 64(%1)\n\t" \ - "ld $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - "dsubu $29, $29, 8\n\t" \ - "ld $4, 72(%1)\n\t" \ - "sd $4, 0($29)\n\t" \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $10, 56(%1)\n\t" \ - "ld $11, 64(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "daddu $29, $29, 8\n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - "dsubu $29, $29, 16\n\t" \ - "ld $4, 72(%1)\n\t" \ - "sd $4, 0($29)\n\t" \ - "ld $4, 80(%1)\n\t" \ - "sd $4, 8($29)\n\t" \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $10, 56(%1)\n\t" \ - "ld $11, 64(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "daddu $29, $29, 16\n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - "dsubu $29, $29, 24\n\t" \ - "ld $4, 72(%1)\n\t" \ - "sd $4, 0($29)\n\t" \ - "ld $4, 80(%1)\n\t" \ - "sd $4, 8($29)\n\t" \ - "ld $4, 88(%1)\n\t" \ - "sd $4, 16($29)\n\t" \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $10, 56(%1)\n\t" \ - "ld $11, 64(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "daddu $29, $29, 24\n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - "dsubu $29, $29, 32\n\t" \ - "ld $4, 72(%1)\n\t" \ - "sd $4, 0($29)\n\t" \ - "ld $4, 80(%1)\n\t" \ - "sd $4, 8($29)\n\t" \ - "ld $4, 88(%1)\n\t" \ - "sd $4, 16($29)\n\t" \ - "ld $4, 96(%1)\n\t" \ - "sd $4, 24($29)\n\t" \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $10, 56(%1)\n\t" \ - "ld $11, 64(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "daddu $29, $29, 32\n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_mips64_linux */ - - -/* ------------------------------------------------------------------ */ -/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */ -/* */ -/* ------------------------------------------------------------------ */ - -/* Some request codes. There are many more of these, but most are not - exposed to end-user view. These are the public ones, all of the - form 0x1000 + small_number. - - Core ones are in the range 0x00000000--0x0000ffff. The non-public - ones start at 0x2000. -*/ - -/* These macros are used by tools -- they must be public, but don't - embed them into other programs. */ -#define VG_USERREQ_TOOL_BASE(a,b) \ - ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16)) -#define VG_IS_TOOL_USERREQ(a, b, v) \ - (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000)) - -/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! - This enum comprises an ABI exported by Valgrind to programs - which use client requests. DO NOT CHANGE THE ORDER OF THESE - ENTRIES, NOR DELETE ANY -- add new ones at the end. */ -typedef - enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, - VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, - - /* These allow any function to be called from the simulated - CPU but run on the real CPU. Nb: the first arg passed to - the function is always the ThreadId of the running - thread! So CLIENT_CALL0 actually requires a 1 arg - function, etc. */ - VG_USERREQ__CLIENT_CALL0 = 0x1101, - VG_USERREQ__CLIENT_CALL1 = 0x1102, - VG_USERREQ__CLIENT_CALL2 = 0x1103, - VG_USERREQ__CLIENT_CALL3 = 0x1104, - - /* Can be useful in regression testing suites -- eg. can - send Valgrind's output to /dev/null and still count - errors. */ - VG_USERREQ__COUNT_ERRORS = 0x1201, - - /* Allows the client program and/or gdbserver to execute a monitor - command. */ - VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202, - - /* These are useful and can be interpreted by any tool that - tracks malloc() et al, by using vg_replace_malloc.c. */ - VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301, - VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b, - VG_USERREQ__FREELIKE_BLOCK = 0x1302, - /* Memory pool support. */ - VG_USERREQ__CREATE_MEMPOOL = 0x1303, - VG_USERREQ__DESTROY_MEMPOOL = 0x1304, - VG_USERREQ__MEMPOOL_ALLOC = 0x1305, - VG_USERREQ__MEMPOOL_FREE = 0x1306, - VG_USERREQ__MEMPOOL_TRIM = 0x1307, - VG_USERREQ__MOVE_MEMPOOL = 0x1308, - VG_USERREQ__MEMPOOL_CHANGE = 0x1309, - VG_USERREQ__MEMPOOL_EXISTS = 0x130a, - - /* Allow printfs to valgrind log. */ - /* The first two pass the va_list argument by value, which - assumes it is the same size as or smaller than a UWord, - which generally isn't the case. Hence are deprecated. - The second two pass the vargs by reference and so are - immune to this problem. */ - /* both :: char* fmt, va_list vargs (DEPRECATED) */ - VG_USERREQ__PRINTF = 0x1401, - VG_USERREQ__PRINTF_BACKTRACE = 0x1402, - /* both :: char* fmt, va_list* vargs */ - VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403, - VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404, - - /* Stack support. */ - VG_USERREQ__STACK_REGISTER = 0x1501, - VG_USERREQ__STACK_DEREGISTER = 0x1502, - VG_USERREQ__STACK_CHANGE = 0x1503, - - /* Wine support */ - VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601, - - /* Querying of debug info. */ - VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701, - - /* Disable/enable error reporting level. Takes a single - Word arg which is the delta to this thread's error - disablement indicator. Hence 1 disables or further - disables errors, and -1 moves back towards enablement. - Other values are not allowed. */ - VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801, - - /* Initialise IR injection */ - VG_USERREQ__VEX_INIT_FOR_IRI = 0x1901 - } Vg_ClientRequest; - -#if !defined(__GNUC__) -# define __extension__ /* */ -#endif - - -/* Returns the number of Valgrinds this code is running under. That - is, 0 if running natively, 1 if running under Valgrind, 2 if - running under Valgrind which is running under another Valgrind, - etc. */ -#define RUNNING_ON_VALGRIND \ - (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */, \ - VG_USERREQ__RUNNING_ON_VALGRIND, \ - 0, 0, 0, 0, 0) \ - - -/* Discard translation of code in the range [_qzz_addr .. _qzz_addr + - _qzz_len - 1]. Useful if you are debugging a JITter or some such, - since it provides a way to make sure valgrind will retranslate the - invalidated area. Returns no value. */ -#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS, \ - _qzz_addr, _qzz_len, 0, 0, 0) - - -/* These requests are for getting Valgrind itself to print something. - Possibly with a backtrace. This is a really ugly hack. The return value - is the number of characters printed, excluding the "**** " part at the - start and the backtrace (if present). */ - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER) -/* Modern GCC will optimize the static routine out if unused, - and unused attribute will shut down warnings about it. */ -static int VALGRIND_PRINTF(const char *format, ...) - __attribute__((format(__printf__, 1, 2), __unused__)); -#endif -static int -#if defined(_MSC_VER) -__inline -#endif -VALGRIND_PRINTF(const char *format, ...) -{ -#if defined(NVALGRIND) - return 0; -#else /* NVALGRIND */ -#if defined(_MSC_VER) || defined(__MINGW64__) - uintptr_t _qzz_res; -#else - unsigned long _qzz_res; -#endif - va_list vargs; - va_start(vargs, format); -#if defined(_MSC_VER) || defined(__MINGW64__) - _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, - VG_USERREQ__PRINTF_VALIST_BY_REF, - (uintptr_t)format, - (uintptr_t)&vargs, - 0, 0, 0); -#else - _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, - VG_USERREQ__PRINTF_VALIST_BY_REF, - (unsigned long)format, - (unsigned long)&vargs, - 0, 0, 0); -#endif - va_end(vargs); - return (int)_qzz_res; -#endif /* NVALGRIND */ -} - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER) -static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) - __attribute__((format(__printf__, 1, 2), __unused__)); -#endif -static int -#if defined(_MSC_VER) -__inline -#endif -VALGRIND_PRINTF_BACKTRACE(const char *format, ...) -{ -#if defined(NVALGRIND) - return 0; -#else /* NVALGRIND */ -#if defined(_MSC_VER) || defined(__MINGW64__) - uintptr_t _qzz_res; -#else - unsigned long _qzz_res; -#endif - va_list vargs; - va_start(vargs, format); -#if defined(_MSC_VER) || defined(__MINGW64__) - _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, - VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, - (uintptr_t)format, - (uintptr_t)&vargs, - 0, 0, 0); -#else - _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, - VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, - (unsigned long)format, - (unsigned long)&vargs, - 0, 0, 0); -#endif - va_end(vargs); - return (int)_qzz_res; -#endif /* NVALGRIND */ -} - - -/* These requests allow control to move from the simulated CPU to the - real CPU, calling an arbitary function. - - Note that the current ThreadId is inserted as the first argument. - So this call: - - VALGRIND_NON_SIMD_CALL2(f, arg1, arg2) - - requires f to have this signature: - - Word f(Word tid, Word arg1, Word arg2) - - where "Word" is a word-sized type. - - Note that these client requests are not entirely reliable. For example, - if you call a function with them that subsequently calls printf(), - there's a high chance Valgrind will crash. Generally, your prospects of - these working are made higher if the called function does not refer to - any global variables, and does not refer to any libc or other functions - (printf et al). Any kind of entanglement with libc or dynamic linking is - likely to have a bad outcome, for tricky reasons which we've grappled - with a lot in the past. -*/ -#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \ - VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ - VG_USERREQ__CLIENT_CALL0, \ - _qyy_fn, \ - 0, 0, 0, 0) - -#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ - VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ - VG_USERREQ__CLIENT_CALL1, \ - _qyy_fn, \ - _qyy_arg1, 0, 0, 0) - -#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ - VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ - VG_USERREQ__CLIENT_CALL2, \ - _qyy_fn, \ - _qyy_arg1, _qyy_arg2, 0, 0) - -#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \ - VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ - VG_USERREQ__CLIENT_CALL3, \ - _qyy_fn, \ - _qyy_arg1, _qyy_arg2, \ - _qyy_arg3, 0) - - -/* Counts the number of errors that have been recorded by a tool. Nb: - the tool must record the errors with VG_(maybe_record_error)() or - VG_(unique_error)() for them to be counted. */ -#define VALGRIND_COUNT_ERRORS \ - (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - 0 /* default return */, \ - VG_USERREQ__COUNT_ERRORS, \ - 0, 0, 0, 0, 0) - -/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing - when heap blocks are allocated in order to give accurate results. This - happens automatically for the standard allocator functions such as - malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete, - delete[], etc. - - But if your program uses a custom allocator, this doesn't automatically - happen, and Valgrind will not do as well. For example, if you allocate - superblocks with mmap() and then allocates chunks of the superblocks, all - Valgrind's observations will be at the mmap() level and it won't know that - the chunks should be considered separate entities. In Memcheck's case, - that means you probably won't get heap block overrun detection (because - there won't be redzones marked as unaddressable) and you definitely won't - get any leak detection. - - The following client requests allow a custom allocator to be annotated so - that it can be handled accurately by Valgrind. - - VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated - by a malloc()-like function. For Memcheck (an illustrative case), this - does two things: - - - It records that the block has been allocated. This means any addresses - within the block mentioned in error messages will be - identified as belonging to the block. It also means that if the block - isn't freed it will be detected by the leak checker. - - - It marks the block as being addressable and undefined (if 'is_zeroed' is - not set), or addressable and defined (if 'is_zeroed' is set). This - controls how accesses to the block by the program are handled. - - 'addr' is the start of the usable block (ie. after any - redzone), 'sizeB' is its size. 'rzB' is the redzone size if the allocator - can apply redzones -- these are blocks of padding at the start and end of - each block. Adding redzones is recommended as it makes it much more likely - Valgrind will spot block overruns. `is_zeroed' indicates if the memory is - zeroed (or filled with another predictable value), as is the case for - calloc(). - - VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a - heap block -- that will be used by the client program -- is allocated. - It's best to put it at the outermost level of the allocator if possible; - for example, if you have a function my_alloc() which calls - internal_alloc(), and the client request is put inside internal_alloc(), - stack traces relating to the heap block will contain entries for both - my_alloc() and internal_alloc(), which is probably not what you want. - - For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out - custom blocks from within a heap block, B, that has been allocated with - malloc/calloc/new/etc, then block B will be *ignored* during leak-checking - -- the custom blocks will take precedence. - - VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK. For - Memcheck, it does two things: - - - It records that the block has been deallocated. This assumes that the - block was annotated as having been allocated via - VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. - - - It marks the block as being unaddressable. - - VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a - heap block is deallocated. - - VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For - Memcheck, it does four things: - - - It records that the size of a block has been changed. This assumes that - the block was annotated as having been allocated via - VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. - - - If the block shrunk, it marks the freed memory as being unaddressable. - - - If the block grew, it marks the new area as undefined and defines a red - zone past the end of the new block. - - - The V-bits of the overlap between the old and the new block are preserved. - - VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block - and before deallocation of the old block. - - In many cases, these three client requests will not be enough to get your - allocator working well with Memcheck. More specifically, if your allocator - writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call - will be necessary to mark the memory as addressable just before the zeroing - occurs, otherwise you'll get a lot of invalid write errors. For example, - you'll need to do this if your allocator recycles freed blocks, but it - zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK). - Alternatively, if your allocator reuses freed blocks for allocator-internal - data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary. - - Really, what's happening is a blurring of the lines between the client - program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the - memory should be considered unaddressable to the client program, but the - allocator knows more than the rest of the client program and so may be able - to safely access it. Extra client requests are necessary for Valgrind to - understand the distinction between the allocator and the rest of the - program. - - Ignored if addr == 0. -*/ -#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK, \ - addr, sizeB, rzB, is_zeroed, 0) - -/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. - Ignored if addr == 0. -*/ -#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK, \ - addr, oldSizeB, newSizeB, rzB, 0) - -/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. - Ignored if addr == 0. -*/ -#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK, \ - addr, rzB, 0, 0, 0) - -/* Create a memory pool. */ -#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \ - pool, rzB, is_zeroed, 0, 0) - -/* Destroy a memory pool. */ -#define VALGRIND_DESTROY_MEMPOOL(pool) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL, \ - pool, 0, 0, 0, 0) - -/* Associate a piece of memory with a memory pool. */ -#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC, \ - pool, addr, size, 0, 0) - -/* Disassociate a piece of memory from a memory pool. */ -#define VALGRIND_MEMPOOL_FREE(pool, addr) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE, \ - pool, addr, 0, 0, 0) - -/* Disassociate any pieces outside a particular range. */ -#define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM, \ - pool, addr, size, 0, 0) - -/* Resize and/or move a piece associated with a memory pool. */ -#define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL, \ - poolA, poolB, 0, 0, 0) - -/* Resize and/or move a piece associated with a memory pool. */ -#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE, \ - pool, addrA, addrB, size, 0) - -/* Return 1 if a mempool exists, else 0. */ -#define VALGRIND_MEMPOOL_EXISTS(pool) \ - (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ - VG_USERREQ__MEMPOOL_EXISTS, \ - pool, 0, 0, 0, 0) - -/* Mark a piece of memory as being a stack. Returns a stack id. - start is the lowest addressable stack byte, end is the highest - addressable stack byte. */ -#define VALGRIND_STACK_REGISTER(start, end) \ - (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ - VG_USERREQ__STACK_REGISTER, \ - start, end, 0, 0, 0) - -/* Unmark the piece of memory associated with a stack id as being a - stack. */ -#define VALGRIND_STACK_DEREGISTER(id) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \ - id, 0, 0, 0, 0) - -/* Change the start and end address of the stack id. - start is the new lowest addressable stack byte, end is the new highest - addressable stack byte. */ -#define VALGRIND_STACK_CHANGE(id, start, end) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE, \ - id, start, end, 0, 0) - -/* Load PDB debug info for Wine PE image_map. */ -#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \ - fd, ptr, total_size, delta, 0) - -/* Map a code address to a source file name and line number. buf64 - must point to a 64-byte buffer in the caller's address space. The - result will be dumped in there and is guaranteed to be zero - terminated. If no info is found, the first byte is set to zero. */ -#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64) \ - (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ - VG_USERREQ__MAP_IP_TO_SRCLOC, \ - addr, buf64, 0, 0, 0) - -/* Disable error reporting for this thread. Behaves in a stack like - way, so you can safely call this multiple times provided that - VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times - to re-enable reporting. The first call of this macro disables - reporting. Subsequent calls have no effect except to increase the - number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable - reporting. Child threads do not inherit this setting from their - parents -- they are always created with reporting enabled. */ -#define VALGRIND_DISABLE_ERROR_REPORTING \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \ - 1, 0, 0, 0, 0) - -/* Re-enable error reporting, as per comments on - VALGRIND_DISABLE_ERROR_REPORTING. */ -#define VALGRIND_ENABLE_ERROR_REPORTING \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \ - -1, 0, 0, 0, 0) - -/* Execute a monitor command from the client program. - If a connection is opened with GDB, the output will be sent - according to the output mode set for vgdb. - If no connection is opened, output will go to the log output. - Returns 1 if command not recognised, 0 otherwise. */ -#define VALGRIND_MONITOR_COMMAND(command) \ - VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__GDB_MONITOR_COMMAND, \ - command, 0, 0, 0, 0) - - -#undef PLAT_x86_darwin -#undef PLAT_amd64_darwin -#undef PLAT_x86_win32 -#undef PLAT_amd64_win64 -#undef PLAT_x86_linux -#undef PLAT_amd64_linux -#undef PLAT_ppc32_linux -#undef PLAT_ppc64be_linux -#undef PLAT_ppc64le_linux -#undef PLAT_arm_linux -#undef PLAT_s390x_linux -#undef PLAT_mips32_linux -#undef PLAT_mips64_linux - -#endif /* __VALGRIND_H */ diff --git a/src/libCom/yacc/ACKNOWLEDGEMENTS b/src/libCom/yacc/ACKNOWLEDGEMENTS deleted file mode 100644 index b66bb2506..000000000 --- a/src/libCom/yacc/ACKNOWLEDGEMENTS +++ /dev/null @@ -1,25 +0,0 @@ - Berkeley Yacc owes much to the unflagging efforts of Keith Bostic. -His badgering kept me working on it long after I was ready to quit. - - Berkeley Yacc is based on the excellent algorithm for computing LALR(1) -lookaheads developed by Tom Pennello and Frank DeRemer. The algorithm is -described in their almost impenetrable article in TOPLAS 4,4. - - Finally, much of the credit for the latest version must go to those -who pointed out deficiencies of my earlier releases. Among the most -prolific contributors were - - Benson I. Margulies - Dave Gentzel - Antoine Verheijen - Peter S. Housel - Dale Smith - Ozan Yigit - John Campbell - Bill Sommerfeld - Paul Hilfinger - Gary Bridgewater - Dave Bakken - Dan Lanciani - Richard Sargent - Parag Patel diff --git a/src/libCom/yacc/EPICS_READ_THIS b/src/libCom/yacc/EPICS_READ_THIS deleted file mode 100644 index c6869244a..000000000 --- a/src/libCom/yacc/EPICS_READ_THIS +++ /dev/null @@ -1,54 +0,0 @@ - -This is the source of the BSD version of yacc that is distributed in the NET2 -release of BSD Unix. We chose this over Bison due to the bison license -agreement. And if you are scratching you head over that comment, read the -addendum in the xxx-info-1 file that comes with bison. - -Anyway, this BSD-yacc has been hacked on to make it generate an all-static -parser C program so that it may be used on an IOC w/o getting things confused. -They way we intend to use it is with the epics-hacked version of flex that -also generates an all-static source program. The general idea is that -your yacc source (xxx.y) file could be formatted like this: - -========================================================= - -%% -YOUR YACC PROGRAM -%% - -int MyYaccParser(char *f1) -{ - static int FirstFlag = 1; - - printf("processing file >%s<\n", f1); - - yyin = fopen(f1, "r"); - if (!FirstFlag) yyrestart(yyin); - FirstFlag = 0; - yyparse(); - fclose(yyin); - - return(0); -} - -static int yyerror(char *str) -{ - printf("Error: %s\n", str); - return(0); -} -========================================================= - -The FirstFlag and yyrestart jazz is the flex-flavored version of how you -restart the scanner if you want to parse another file. Without it, the -scanner can only be used one time. Even if you think your code will only -be used one time, it is desireable to put in the restart stuff anyway, -because some day you (or your boss) will change your mind and without it -the IOC will crash when you make your second call to your parser. - -Note also that there is a yyerror function present. This is mandatory for the -way we are using flex. Without, results are indeterminate... because you will -end up calling some other random yyerror() in the ioc.. probably the one for -the console command interpreter. - - ---John diff --git a/src/libCom/yacc/Makefile b/src/libCom/yacc/Makefile deleted file mode 100644 index 4f2083037..000000000 --- a/src/libCom/yacc/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/yacc - -antelope_SRCS += closure.c -antelope_SRCS += error.c -antelope_SRCS += lalr.c -antelope_SRCS += lr0.c -antelope_SRCS += antelope.c -antelope_SRCS += mkpar.c -antelope_SRCS += output.c -antelope_SRCS += reader.c -antelope_SRCS += skeleton.c -antelope_SRCS += symtab.c -antelope_SRCS += verbose.c -antelope_SRCS += warshall.c -antelope_OBJS += epicsTempFile$(OBJ) - -PROD_HOST += antelope - diff --git a/src/libCom/yacc/NEW_FEATURES b/src/libCom/yacc/NEW_FEATURES deleted file mode 100644 index b030c625b..000000000 --- a/src/libCom/yacc/NEW_FEATURES +++ /dev/null @@ -1,46 +0,0 @@ - The -r option has been implemented. The -r option tells Yacc to -put the read-only tables in y.tab.c and the code and variables in -y.code.c. Keith Bostic asked for this option so that :yyfix could be -eliminated. - - The -l and -t options have been implemented. The -l option tells -Yacc not to include #line directives in the code it produces. The -t -option causes debugging code to be included in the compiled parser. - - The code for error recovery has been changed to implement the same -algorithm as AT&T Yacc. There will still be differences in the way -error recovery works because AT&T Yacc uses more default reductions -than Berkeley Yacc. - - The environment variable TMPDIR determines the directory where -temporary files will be created. If TMPDIR is defined, temporary files -will be created in the directory whose pathname is the value of TMPDIR. -By default, temporary files are created in /tmp. - - The keywords are now case-insensitive. For example, %nonassoc, -%NONASSOC, %NonAssoc, and %nOnAsSoC are all equivalent. - - Commas and semicolons that are not part of C code are treated as -commentary. - - Line-end comments, as in BCPL, are permitted. Line-end comments -begin with // and end at the next end-of-line. Line-end comments are -permitted in C code; they are converted to C comments on output. - - The form of y.output files has been changed to look more like -those produced by AT&T Yacc. - - A new kind of declaration has been added. The form of the declaration -is - - %ident string - -where string is a sequence of characters begining with a double quote -and ending with either a double quote or the next end-of-line, whichever -comes first. The declaration will cause a #ident directive to be written -near the start of the output file. - - If a parser has been compiled with debugging code, that code can be -enabled by setting an environment variable. If the environment variable -YYDEBUG is set to 0, debugging output is suppressed. If it is set to 1, -debugging output is written to standard output. diff --git a/src/libCom/yacc/NOTES b/src/libCom/yacc/NOTES deleted file mode 100644 index 9db3c96ce..000000000 --- a/src/libCom/yacc/NOTES +++ /dev/null @@ -1,9 +0,0 @@ -Berkeley Yacc reflects its origins. The reason so many routines -use exactly six register variables is that Berkeley Yacc was -developed on a VAX using PCC. PCC placed at most six variables -in registers. I went to considerable effort to find which six -variables most belonged in registers. Changes in machines and -compilers make that effort worthless, perhaps even harmful. - -The code contains many instances where address calculations are -performed in particular ways to optimize the code for the VAX. diff --git a/src/libCom/yacc/NO_WARRANTY b/src/libCom/yacc/NO_WARRANTY deleted file mode 100644 index 06e8d93a2..000000000 --- a/src/libCom/yacc/NO_WARRANTY +++ /dev/null @@ -1,3 +0,0 @@ - Berkeley Yacc is distributed with no warranty whatever. The author -and any other contributors take no responsibility for the consequences of -its use. diff --git a/src/libCom/yacc/README b/src/libCom/yacc/README deleted file mode 100644 index 091f23343..000000000 --- a/src/libCom/yacc/README +++ /dev/null @@ -1,23 +0,0 @@ - Berkeley Yacc is an LALR(1) parser generator. Berkeley Yacc has been made -as compatible as possible with AT&T Yacc. Berkeley Yacc can accept any input -specification that conforms to the AT&T Yacc documentation. Specifications -that take advantage of undocumented features of AT&T Yacc will probably be -rejected. - - Berkeley Yacc is distributed with no warranty whatever. The code is certain -to contain errors. Neither the author nor any contributor takes responsibility -for any consequences of its use. - - Berkeley Yacc is in the public domain. The data structures and algorithms -used in Berkeley Yacc are all either taken from documents available to the -general public or are inventions of the author. Anyone may freely distribute -source or binary forms of Berkeley Yacc whether unchanged or modified. -Distributers may charge whatever fees they can obtain for Berkeley Yacc. -Programs generated by Berkeley Yacc may be distributed freely. - - Please report bugs to - - robert.corbett@eng.Sun.COM - -Include a small example if possible. Please include the banner string from -skeleton.c with the bug report. Do not expect rapid responses. diff --git a/src/libCom/yacc/antelope.c b/src/libCom/yacc/antelope.c deleted file mode 100644 index 7143b38ff..000000000 --- a/src/libCom/yacc/antelope.c +++ /dev/null @@ -1,347 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include -#include "defs.h" -#define epicsExportSharedSymbols -#include "epicsTempFile.h" -#undef epicsExportSharedSymbols - -char dflag; -char lflag; -char rflag; -char tflag; -char vflag; - -char *symbol_prefix; -char *file_prefix = "y"; -char *myname = "yacc"; -char *temp_form = "yacc.XXXXXXX"; - -int lineno; -int outline; - -char *code_file_name; -char *defines_file_name; -char *input_file_name = ""; -char *output_file_name; -char *verbose_file_name; - -FILE *action_file; /* a temp file, used to save actions associated */ - /* with rules until the parser is written */ -FILE *code_file; /* y.code.c (used when the -r option is specified) */ -FILE *defines_file; /* y.tab.h */ -FILE *input_file; /* the input file */ -FILE *output_file; /* y.tab.c */ -FILE *text_file; /* a temp file, used to save text until all */ - /* symbols have been defined */ -FILE *union_file; /* a temp file, used to save the union */ - /* definition until all symbol have been */ - /* defined */ -FILE *verbose_file; /* y.output */ - -int nitems; -int nrules; -int nsyms; -int ntokens; -int nvars; - -int start_symbol; -char **symbol_name; -short *symbol_value; -short *symbol_prec; -char *symbol_assoc; - -short *ritem; -short *rlhs; -short *rrhs; -short *rprec; -char *rassoc; -short **derives; -char *nullable; - - -void -done(int k) -{ - if (action_file) { fclose(action_file); } - if (text_file) { fclose(text_file); } - if (union_file) { fclose(union_file); } - exit(k); -} - - -static void -onintr(int StupidInconsistantSignalTypes) -{ - done(1); -} - - -static void -set_signals(void) -{ -#ifdef SIGINT - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, onintr); -#endif -#ifdef SIGTERM - if (signal(SIGTERM, SIG_IGN) != SIG_IGN) - signal(SIGTERM, onintr); -#endif -#ifdef SIGHUP - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) - signal(SIGHUP, onintr); -#endif -} - - -static void -usage(void) -{ - fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-p symbol_prefix] filename\n", myname); - exit(1); -} - - -static int -getargs(int argc, char *argv[]) -{ - int i; - char *s; - - if (argc > 0) { - myname = strrchr(argv[0], '/'); - if (myname) myname++; - else myname = argv[0]; - } - for (i = 1; i < argc; ++i) - { - s = argv[i]; - if (*s != '-') break; - switch (*++s) - { - case '\0': - input_file = stdin; - if (i + 1 < argc) usage(); - return(0); - - case '-': - ++i; - goto no_more_options; - - case 'b': - if (*++s) - file_prefix = s; - else if (++i < argc) - file_prefix = argv[i]; - else - usage(); - continue; - - case 'd': - dflag = 1; - break; - - case 'l': - lflag = 1; - break; - - case 'p': - if (*++s) - symbol_prefix = s; - else if (++i < argc) - symbol_prefix = argv[i]; - else - usage(); - continue; - - case 'r': - rflag = 1; - break; - - case 't': - tflag = 1; - break; - - case 'v': - vflag = 1; - break; - - default: - usage(); - } - - for (;;) - { - switch (*++s) - { - case '\0': - goto end_of_option; - - case 'd': - dflag = 1; - break; - - case 'l': - lflag = 1; - break; - - case 'r': - rflag = 1; - break; - - case 't': - tflag = 1; - break; - - case 'v': - vflag = 1; - break; - - default: - usage(); - } - } -end_of_option:; - } - -no_more_options:; - if (i + 1 != argc) usage(); - input_file_name = argv[i]; - - return(0); -} - - -char * -allocate(unsigned int n) -{ - char *p; - - p = NULL; - if (n) - { - p = CALLOC(1, n); - if (!p) no_space(); - } - return (p); -} - - -static void -create_file_names(void) -{ - int len; - - len = strlen(file_prefix); - - output_file_name = MALLOC(len + 7); - if (output_file_name == 0) - no_space(); - strcpy(output_file_name, file_prefix); - strcpy(output_file_name + len, OUTPUT_SUFFIX); - - if (rflag) - { - code_file_name = MALLOC(len + 8); - if (code_file_name == 0) - no_space(); - strcpy(code_file_name, file_prefix); - strcpy(code_file_name + len, CODE_SUFFIX); - } - else - code_file_name = output_file_name; - - if (dflag) - { - defines_file_name = MALLOC(len + 7); - if (defines_file_name == 0) - no_space(); - strcpy(defines_file_name, file_prefix); - strcpy(defines_file_name + len, DEFINES_SUFFIX); - } - - if (vflag) - { - verbose_file_name = MALLOC(len + 8); - if (verbose_file_name == 0) - no_space(); - strcpy(verbose_file_name, file_prefix); - strcpy(verbose_file_name + len, VERBOSE_SUFFIX); - } -} - - -static void -open_files(void) -{ - create_file_names(); - - if (input_file == 0) - { - input_file = fopen(input_file_name, "r"); - if (input_file == 0) - open_error(input_file_name); - } - - action_file = epicsTempFile(); - if (action_file == 0) - open_error("temp action file"); - - text_file = epicsTempFile(); - if (text_file == 0) - open_error("temp text file"); - - if (vflag) - { - verbose_file = fopen(verbose_file_name, "w"); - if (verbose_file == 0) - open_error(verbose_file_name); - } - - if (dflag) - { - defines_file = fopen(defines_file_name, "w"); - if (defines_file == 0) - open_error(defines_file_name); - union_file = epicsTempFile(); - if (union_file == 0) - open_error("temp union file"); - } - - output_file = fopen(output_file_name, "w"); - if (output_file == 0) - open_error(output_file_name); - - if (rflag) - { - code_file = fopen(code_file_name, "w"); - if (code_file == 0) - open_error(code_file_name); - } - else - code_file = output_file; -} - - -int -main(int argc, char *argv[]) -{ - set_signals(); - getargs(argc, argv); - open_files(); - reader(); - lr0(); - lalr(); - make_parser(); - verbose(); - output(); - done(0); - /*NOTREACHED*/ -} diff --git a/src/libCom/yacc/closure.c b/src/libCom/yacc/closure.c deleted file mode 100644 index f08c8cd92..000000000 --- a/src/libCom/yacc/closure.c +++ /dev/null @@ -1,274 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "defs.h" - -short *itemset; -short *itemsetend; -unsigned *ruleset; - -static unsigned *first_derives; -static unsigned *EFF; - -#ifdef DEBUG -static void print_closure(int n); -static void print_EFF(void); -static void print_first_derives(void); -#endif - - -static void -set_EFF(void) -{ - unsigned *row; - int symbol; - short *sp; - int rowsize; - int i; - int rule; - - rowsize = WORDSIZE(nvars); - EFF = NEW2(nvars * rowsize, unsigned); - - row = EFF; - for (i = start_symbol; i < nsyms; i++) - { - sp = derives[i]; - for (rule = *sp; rule > 0; rule = *++sp) - { - symbol = ritem[rrhs[rule]]; - if (ISVAR(symbol)) - { - symbol -= start_symbol; - SETBIT(row, symbol); - } - } - row += rowsize; - } - - reflexive_transitive_closure(EFF, nvars); - -#ifdef DEBUG - print_EFF(); -#endif -} - - -void -set_first_derives(void) -{ - unsigned *rrow; - unsigned *vrow; - int j; - unsigned k; - unsigned cword = 0; - short *rp; - - int rule; - int i; - int rulesetsize; - int varsetsize; - - rulesetsize = WORDSIZE(nrules); - varsetsize = WORDSIZE(nvars); - first_derives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize; - - set_EFF(); - - rrow = first_derives + ntokens * rulesetsize; - for (i = start_symbol; i < nsyms; i++) - { - vrow = EFF + ((i - ntokens) * varsetsize); - k = BITS_PER_WORD; - for (j = start_symbol; j < nsyms; k++, j++) - { - if (k >= BITS_PER_WORD) - { - cword = *vrow++; - k = 0; - } - - if (cword & (1 << k)) - { - rp = derives[j]; - while ((rule = *rp++) >= 0) - { - SETBIT(rrow, rule); - } - } - } - - vrow += varsetsize; - rrow += rulesetsize; - } - -#ifdef DEBUG - print_first_derives(); -#endif - - FREE(EFF); -} - - -void -closure(short int *nucleus, int n) -{ - int ruleno; - unsigned word; - unsigned i; - short *csp; - unsigned *dsp; - unsigned *rsp; - int rulesetsize; - - short *csend; - unsigned *rsend; - int symbol; - int itemno; - - rulesetsize = WORDSIZE(nrules); - rsp = ruleset; - rsend = ruleset + rulesetsize; - for (rsp = ruleset; rsp < rsend; rsp++) - *rsp = 0; - - csend = nucleus + n; - for (csp = nucleus; csp < csend; ++csp) - { - symbol = ritem[*csp]; - if (ISVAR(symbol)) - { - dsp = first_derives + symbol * rulesetsize; - rsp = ruleset; - while (rsp < rsend) - *rsp++ |= *dsp++; - } - } - - ruleno = 0; - itemsetend = itemset; - csp = nucleus; - for (rsp = ruleset; rsp < rsend; ++rsp) - { - word = *rsp; - if (word) - { - for (i = 0; i < BITS_PER_WORD; ++i) - { - if (word & (1 << i)) - { - itemno = rrhs[ruleno+i]; - while (csp < csend && *csp < itemno) - *itemsetend++ = *csp++; - *itemsetend++ = itemno; - while (csp < csend && *csp == itemno) - ++csp; - } - } - } - ruleno += BITS_PER_WORD; - } - - while (csp < csend) - *itemsetend++ = *csp++; - -#ifdef DEBUG - print_closure(n); -#endif -} - - - -void -finalize_closure(void) -{ - FREE(itemset); - FREE(ruleset); - FREE(first_derives + ntokens * WORDSIZE(nrules)); -} - - -#ifdef DEBUG - -static void -print_closure(int n) -{ - short *isp; - - printf("\n\nn = %d\n\n", n); - for (isp = itemset; isp < itemsetend; isp++) - printf(" %d\n", *isp); -} - - -static void -print_EFF(void) -{ - int i, j; - unsigned *rowp; - unsigned word; - unsigned k; - - printf("\n\nEpsilon Free Firsts\n"); - - for (i = start_symbol; i < nsyms; i++) - { - printf("\n%s", symbol_name[i]); - rowp = EFF + ((i - start_symbol) * WORDSIZE(nvars)); - word = *rowp++; - - k = BITS_PER_WORD; - for (j = 0; j < nvars; k++, j++) - { - if (k >= BITS_PER_WORD) - { - word = *rowp++; - k = 0; - } - - if (word & (1 << k)) - printf(" %s", symbol_name[start_symbol + j]); - } - } -} - - -static void -print_first_derives(void) -{ - int i; - int j; - unsigned *rp; - unsigned cword; - unsigned k; - - printf("\n\n\nFirst Derives\n"); - - for (i = start_symbol; i < nsyms; i++) - { - printf("\n%s derives\n", symbol_name[i]); - rp = first_derives + i * WORDSIZE(nrules); - k = BITS_PER_WORD; - for (j = 0; j <= nrules; k++, j++) - { - if (k >= BITS_PER_WORD) - { - cword = *rp++; - k = 0; - } - - if (cword & (1 << k)) - printf(" %d\n", j); - } - } - - fflush(stdout); -} - -#endif diff --git a/src/libCom/yacc/defs.h b/src/libCom/yacc/defs.h deleted file mode 100644 index 36b295fa8..000000000 --- a/src/libCom/yacc/defs.h +++ /dev/null @@ -1,367 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include -#include -#include - - -/* machine-dependent definitions */ -/* the following definitions are for the Tahoe */ -/* they might have to be changed for other machines */ - -/* MAXCHAR is the largest unsigned character value */ -/* MAXSHORT is the largest value of a C short */ -/* MINSHORT is the most negative value of a C short */ -/* MAXTABLE is the maximum table size */ -/* BITS_PER_WORD is the number of bits in a C unsigned */ -/* WORDSIZE computes the number of words needed to */ -/* store n bits */ -/* BIT returns the value of the n-th bit starting */ -/* from r (0-indexed) */ -/* SETBIT sets the n-th bit starting from r */ - -#define MAXCHAR 255 -#define MAXSHORT 32767 -#define MINSHORT -32768 -#define MAXTABLE 32500 -#define BITS_PER_WORD 32 -#define WORDSIZE(n) (((n)+(BITS_PER_WORD-1))/BITS_PER_WORD) -#define BIT(r, n) ((((r)[(n)>>5])>>((n)&31))&1) -#define SETBIT(r, n) ((r)[(n)>>5]|=((unsigned)1<<((n)&31))) - - -/* character names */ - -#define NUL '\0' /* the null character */ -#define NEWLINE '\n' /* line feed */ -#define SP ' ' /* space */ -#define BS '\b' /* backspace */ -#define HT '\t' /* horizontal tab */ -#define VT '\013' /* vertical tab */ -#define CR '\r' /* carriage return */ -#define FF '\f' /* form feed */ -#define QUOTE '\'' /* single quote */ -#define DOUBLE_QUOTE '\"' /* double quote */ -#define BACKSLASH '\\' /* backslash */ - - -/* defines for constructing filenames */ - -#define CODE_SUFFIX ".code.c" -#define DEFINES_SUFFIX ".tab.h" -#define OUTPUT_SUFFIX ".tab.c" -#define VERBOSE_SUFFIX ".output" - - -/* keyword codes */ - -#define TOKEN 0 -#define LEFT 1 -#define RIGHT 2 -#define NONASSOC 3 -#define MARK 4 -#define TEXT 5 -#define TYPE 6 -#define START 7 -#define UNION 8 -#define IDENT 9 - - -/* symbol classes */ - -#define UNKNOWN 0 -#define TERM 1 -#define NONTERM 2 - - -/* the undefined value */ - -#define UNDEFINED (-1) - - -/* action codes */ - -#define SHIFT 1 -#define REDUCE 2 - - -/* character macros */ - -#define IS_IDENT(c) (isalnum(c) || (c) == '_' || (c) == '.' || (c) == '$') -#define IS_OCTAL(c) ((c) >= '0' && (c) <= '7') -#define NUMERIC_VALUE(c) ((c) - '0') - - -/* symbol macros */ - -#define ISTOKEN(s) ((s) < start_symbol) -#define ISVAR(s) ((s) >= start_symbol) - - -/* storage allocation macros */ - -#define CALLOC(k,n) (calloc((unsigned)(k),(unsigned)(n))) -#define FREE(x) (free((char*)(x))) -#define MALLOC(n) (malloc((unsigned)(n))) -#define NEW(t) ((t*)allocate(sizeof(t))) -#define NEW2(n,t) ((t*)allocate((unsigned)((n)*sizeof(t)))) -#define REALLOC(p,n) (realloc((char*)(p),(unsigned)(n))) - - -/* the structure of a symbol table entry */ - -typedef struct bucket bucket; -struct bucket -{ - struct bucket *link; - struct bucket *next; - char *name; - char *tag; - short value; - short index; - short prec; - char class; - char assoc; -}; - - -/* the structure of the LR(0) state machine */ - -typedef struct core core; -struct core -{ - struct core *next; - struct core *link; - short number; - short accessing_symbol; - short nitems; - short items[1]; -}; - - -/* the structure used to record shifts */ - -typedef struct shifts shifts; -struct shifts -{ - struct shifts *next; - short number; - short nshifts; - short shift[1]; -}; - - -/* the structure used to store reductions */ - -typedef struct reductions reductions; -struct reductions -{ - struct reductions *next; - short number; - short nreds; - short rules[1]; -}; - - -/* the structure used to represent parser actions */ - -typedef struct action action; -struct action -{ - struct action *next; - short symbol; - short number; - short prec; - char action_code; - char assoc; - char suppressed; -}; - - -/* global variables */ - -extern char dflag; -extern char lflag; -extern char rflag; -extern char tflag; -extern char vflag; -extern char *symbol_prefix; - -extern char *myname; -extern char *cptr; -extern char *line; -extern int lineno; -extern int outline; - -extern char *banner[]; -extern char *tables[]; -extern char *header[]; -extern char *body[]; -extern char *trailer[]; - -extern char *code_file_name; -extern char *defines_file_name; -extern char *input_file_name; -extern char *output_file_name; -extern char *verbose_file_name; - -extern FILE *action_file; -extern FILE *code_file; -extern FILE *defines_file; -extern FILE *input_file; -extern FILE *output_file; -extern FILE *text_file; -extern FILE *union_file; -extern FILE *verbose_file; - -extern int nitems; -extern int nrules; -extern int nsyms; -extern int ntokens; -extern int nvars; -extern int ntags; - -extern char unionized; -extern char line_format[]; - -extern int start_symbol; -extern char **symbol_name; -extern short *symbol_value; -extern short *symbol_prec; -extern char *symbol_assoc; - -extern short *ritem; -extern short *rlhs; -extern short *rrhs; -extern short *rprec; -extern char *rassoc; - -extern short **derives; -extern char *nullable; - -extern bucket *first_symbol; -extern bucket *last_symbol; - -extern int nstates; -extern core *first_state; -extern shifts *first_shift; -extern reductions *first_reduction; -extern short *accessing_symbol; -extern core **state_table; -extern shifts **shift_table; -extern reductions **reduction_table; -extern unsigned *LA; -extern short *LAruleno; -extern short *lookaheads; -extern short *goto_map; -extern short *from_state; -extern short *to_state; - -extern action **parser; -extern int SRtotal; -extern int RRtotal; -extern short *SRconflicts; -extern short *RRconflicts; -extern short *defred; -extern short *rules_used; -extern short nunused; -extern short final_state; - -/* - * global functions - */ - -#ifdef __GNUC__ -#define NORETURN __attribute__((noreturn)) -#else -#define NORETURN -#endif - -/* main.c */ -extern void done(int k) NORETURN; -extern char *allocate(unsigned int n); - -/* error.c */ -extern void no_space(void) NORETURN; -extern void fatal(char *msg) NORETURN; -extern void open_error(char *filename) NORETURN; -extern void unexpected_EOF(void) NORETURN; -extern void syntax_error(int st_lineno, char *st_line, char *st_cptr) NORETURN; -extern void unterminated_comment(int c_lineno, char *c_line, char *c_cptr) NORETURN; -extern void unterminated_string(int s_lineno, char *s_line, char *s_cptr) NORETURN; -extern void unterminated_text(int t_lineno, char *t_line, char *t_cptr) NORETURN; -extern void unterminated_union(int u_lineno, char *u_line, char *u_cptr) NORETURN; -extern void over_unionized(char *u_cptr) NORETURN; -extern void illegal_tag(int t_lineno, char *t_line, char *t_cptr) NORETURN; -extern void illegal_character(char *c_cptr) NORETURN; -extern void used_reserved(char *s) NORETURN; -extern void tokenized_start(char *s) NORETURN; -extern void retyped_warning(char *s); -extern void reprec_warning(char *s); -extern void revalued_warning(char *s); -extern void terminal_start(char *s); -extern void restarted_warning(void); -extern void no_grammar(void) NORETURN; -extern void terminal_lhs(int s_lineno) NORETURN; -extern void prec_redeclared(void); -extern void unterminated_action(int a_lineno, char *a_line, char *a_cptr) NORETURN; -extern void dollar_warning(int a_lineno, int i); -extern void dollar_error(int a_lineno, char *a_line, char *a_cptr) NORETURN; -extern void untyped_lhs(void) NORETURN; -extern void untyped_rhs(int i, char *s) NORETURN; -extern void unknown_rhs(int i) NORETURN; -extern void default_action_warning(void); -extern void undefined_goal(char *s) NORETURN; -extern void undefined_symbol_warning(char *s); - -/* symtab.c */ -extern bucket *make_bucket(char *name); -extern bucket *lookup(char *name); -extern void create_symbol_table(void); -extern void free_symbol_table(void); -extern void free_symbols(void); - -/* closure.c */ -extern void set_first_derives(void); -extern void closure(short int *nucleus, int n); -extern void finalize_closure(void); - -/* reader.c */ -extern void reader(void); - -/* lr0.c */ -extern void lr0(void); - -/* lalr.c */ -extern void lalr(void); - -/* mkpar.c */ -extern void make_parser(void); -extern void free_parser(void); - -/* warshall.c */ -extern void reflexive_transitive_closure(unsigned int *R, int n); - -/* output.c */ -extern void output(void); -extern int default_goto(int symbol); -extern int matching_vector(int vector); -extern int pack_vector(int vector); - -/* skeleton.c */ -extern void write_section(char *section[]); - -/* verbose.c */ -extern void verbose(void); - -/* system includes */ - -#include -#include -#include diff --git a/src/libCom/yacc/error.c b/src/libCom/yacc/error.c deleted file mode 100644 index d95c92a3a..000000000 --- a/src/libCom/yacc/error.c +++ /dev/null @@ -1,314 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* routines for printing error messages */ - -#include "defs.h" - - -void -fatal(char *msg) -{ - fprintf(stderr, "%s: fatal - %s\n", myname, msg); - done(2); -} - - -void -no_space(void) -{ - fprintf(stderr, "%s: fatal - out of space\n", myname); - done(2); -} - - -void -open_error(char *filename) -{ - fprintf(stderr, "%s: fatal - cannot open \"%s\"\n", myname, filename); - done(2); -} - - -void -unexpected_EOF(void) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", unexpected end-of-file\n", - myname, lineno, input_file_name); - done(1); -} - - -static int -print_pos(char *st_line, char *st_cptr) -{ - char *s; - - if (st_line == 0) return(0); - for (s = st_line; *s != '\n'; ++s) - { - if (isprint((int) *s) || *s == '\t') - putc(*s, stderr); - else - putc('?', stderr); - } - putc('\n', stderr); - for (s = st_line; s < st_cptr; ++s) - { - if (*s == '\t') - putc('\t', stderr); - else - putc(' ', stderr); - } - putc('^', stderr); - putc('\n', stderr); - return(0); -} - - -void -syntax_error(int st_lineno, char *st_line, char *st_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", syntax error\n", - myname, st_lineno, input_file_name); - print_pos(st_line, st_cptr); - done(1); -} - - -void -unterminated_comment(int c_lineno, char *c_line, char *c_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", unmatched /*\n", - myname, c_lineno, input_file_name); - print_pos(c_line, c_cptr); - done(1); -} - - -void -unterminated_string(int s_lineno, char *s_line, char *s_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", unterminated string\n", - myname, s_lineno, input_file_name); - print_pos(s_line, s_cptr); - done(1); -} - - -void -unterminated_text(int t_lineno, char *t_line, char *t_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", unmatched %%{\n", - myname, t_lineno, input_file_name); - print_pos(t_line, t_cptr); - done(1); -} - - -void -unterminated_union(int u_lineno, char *u_line, char *u_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", unterminated %%union \ -declaration\n", myname, u_lineno, input_file_name); - print_pos(u_line, u_cptr); - done(1); -} - - -void -over_unionized(char *u_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", too many %%union \ -declarations\n", myname, lineno, input_file_name); - print_pos(line, u_cptr); - done(1); -} - - -void -illegal_tag(int t_lineno, char *t_line, char *t_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", illegal tag\n", - myname, t_lineno, input_file_name); - print_pos(t_line, t_cptr); - done(1); -} - - -void -illegal_character(char *c_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", illegal character\n", - myname, lineno, input_file_name); - print_pos(line, c_cptr); - done(1); -} - - -void -used_reserved(char *s) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", illegal use of reserved symbol \ -%s\n", myname, lineno, input_file_name, s); - done(1); -} - - -void -tokenized_start(char *s) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", the start symbol %s cannot be \ -declared to be a token\n", myname, lineno, input_file_name, s); - done(1); -} - - -void -retyped_warning(char *s) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", the type of %s has been \ -redeclared\n", myname, lineno, input_file_name, s); -} - - -void -reprec_warning(char *s) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", the precedence of %s has been \ -redeclared\n", myname, lineno, input_file_name, s); -} - - -void -revalued_warning(char *s) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", the value of %s has been \ -redeclared\n", myname, lineno, input_file_name, s); -} - - -void -terminal_start(char *s) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", the start symbol %s is a \ -token\n", myname, lineno, input_file_name, s); - done(1); -} - - -void -restarted_warning(void) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", the start symbol has been \ -redeclared\n", myname, lineno, input_file_name); -} - - -void -no_grammar(void) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", no grammar has been \ -specified\n", myname, lineno, input_file_name); - done(1); -} - - -void -terminal_lhs(int s_lineno) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", a token appears on the lhs \ -of a production\n", myname, s_lineno, input_file_name); - done(1); -} - - -void -prec_redeclared(void) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", conflicting %%prec \ -specifiers\n", myname, lineno, input_file_name); -} - - -void -unterminated_action(int a_lineno, char *a_line, char *a_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", unterminated action\n", - myname, a_lineno, input_file_name); - print_pos(a_line, a_cptr); - done(1); -} - - -void -dollar_warning(int a_lineno, int i) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", $%d references beyond the \ -end of the current rule\n", myname, a_lineno, input_file_name, i); -} - - -void -dollar_error(int a_lineno, char *a_line, char *a_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", illegal $-name\n", - myname, a_lineno, input_file_name); - print_pos(a_line, a_cptr); - done(1); -} - - -void -untyped_lhs(void) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", $$ is untyped\n", - myname, lineno, input_file_name); - done(1); -} - - -void -untyped_rhs(int i, char *s) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", $%d (%s) is untyped\n", - myname, lineno, input_file_name, i, s); - done(1); -} - - -void -unknown_rhs(int i) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", $%d is untyped\n", - myname, lineno, input_file_name, i); - done(1); -} - - -void -default_action_warning(void) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", the default action assigns an \ -undefined value to $$\n", myname, lineno, input_file_name); -} - - -void -undefined_goal(char *s) -{ - fprintf(stderr, "%s: error - the start symbol %s is undefined\n", myname, s); - done(1); -} - - -void -undefined_symbol_warning(char *s) -{ - fprintf(stderr, "%s: warning - the symbol %s is undefined\n", myname, s); -} diff --git a/src/libCom/yacc/lalr.c b/src/libCom/yacc/lalr.c deleted file mode 100644 index 1c8850f60..000000000 --- a/src/libCom/yacc/lalr.c +++ /dev/null @@ -1,668 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include "defs.h" - -typedef - struct shorts - { - struct shorts *next; - short value; - } - shorts; - -int tokensetsize; -short *lookaheads; -short *LAruleno; -unsigned *LA; -short *accessing_symbol; -core **state_table; -shifts **shift_table; -reductions **reduction_table; -short *goto_map; -short *from_state; -short *to_state; - -static void set_state_table(void); -static void set_accessing_symbol(void); -static void set_shift_table(void); -static void set_reduction_table(void); -static void set_maxrhs(void); -static void initialize_LA(void); -static void set_goto_map(void); -static void initialize_F(void); -static void build_relations(void); -static void add_lookback_edge(int stateno, int ruleno, int gotono); -static short **transpose(short int **R, int n); -static void compute_FOLLOWS(void); -static void compute_lookaheads(void); -static void digraph(short **relation); -static void traverse(int i); - -static int infinity; -static int maxrhs; -static int ngotos; -static unsigned *F; -static short **includes; -static shorts **lookback; -static short **R; -static short *INDEX; -static short *VERTICES; -static int top; - - -void -lalr(void) -{ - tokensetsize = WORDSIZE(ntokens); - - set_state_table(); - set_accessing_symbol(); - set_shift_table(); - set_reduction_table(); - set_maxrhs(); - initialize_LA(); - set_goto_map(); - initialize_F(); - build_relations(); - compute_FOLLOWS(); - compute_lookaheads(); -} - - - -static void -set_state_table(void) -{ - core *sp; - - state_table = NEW2(nstates, core *); - for (sp = first_state; sp; sp = sp->next) - state_table[sp->number] = sp; -} - - - -static void -set_accessing_symbol(void) -{ - core *sp; - - accessing_symbol = NEW2(nstates, short); - for (sp = first_state; sp; sp = sp->next) - accessing_symbol[sp->number] = sp->accessing_symbol; -} - - - -static void -set_shift_table(void) -{ - shifts *sp; - - shift_table = NEW2(nstates, shifts *); - for (sp = first_shift; sp; sp = sp->next) - shift_table[sp->number] = sp; -} - - - -static void -set_reduction_table(void) -{ - reductions *rp; - - reduction_table = NEW2(nstates, reductions *); - for (rp = first_reduction; rp; rp = rp->next) - reduction_table[rp->number] = rp; -} - - - -static void -set_maxrhs(void) -{ - short *itemp; - short *item_end; - int length; - int max; - - length = 0; - max = 0; - item_end = ritem + nitems; - for (itemp = ritem; itemp < item_end; itemp++) - { - if (*itemp >= 0) - { - length++; - } - else - { - if (length > max) max = length; - length = 0; - } - } - - maxrhs = max; -} - - - -static void -initialize_LA(void) -{ - int i, j, k; - reductions *rp; - - lookaheads = NEW2(nstates + 1, short); - - k = 0; - for (i = 0; i < nstates; i++) - { - lookaheads[i] = k; - rp = reduction_table[i]; - if (rp) - k += rp->nreds; - } - lookaheads[nstates] = k; - - LA = NEW2(k * tokensetsize, unsigned); - LAruleno = NEW2(k, short); - lookback = NEW2(k, shorts *); - - k = 0; - for (i = 0; i < nstates; i++) - { - rp = reduction_table[i]; - if (rp) - { - for (j = 0; j < rp->nreds; j++) - { - LAruleno[k] = rp->rules[j]; - k++; - } - } - } -} - - -static void -set_goto_map(void) -{ - shifts *sp; - int i; - int symbol; - int k; - short *temp_map; - int state2; - int state1; - - goto_map = NEW2(nvars + 1, short) - ntokens; - temp_map = NEW2(nvars + 1, short) - ntokens; - - ngotos = 0; - for (sp = first_shift; sp; sp = sp->next) - { - for (i = sp->nshifts - 1; i >= 0; i--) - { - symbol = accessing_symbol[sp->shift[i]]; - - if (ISTOKEN(symbol)) break; - - if (ngotos == MAXSHORT) - fatal("too many gotos"); - - ngotos++; - goto_map[symbol]++; - } - } - - k = 0; - for (i = ntokens; i < nsyms; i++) - { - temp_map[i] = k; - k += goto_map[i]; - } - - for (i = ntokens; i < nsyms; i++) - goto_map[i] = temp_map[i]; - - goto_map[nsyms] = ngotos; - temp_map[nsyms] = ngotos; - - from_state = NEW2(ngotos, short); - to_state = NEW2(ngotos, short); - - for (sp = first_shift; sp; sp = sp->next) - { - state1 = sp->number; - for (i = sp->nshifts - 1; i >= 0; i--) - { - state2 = sp->shift[i]; - symbol = accessing_symbol[state2]; - - if (ISTOKEN(symbol)) break; - - k = temp_map[symbol]++; - from_state[k] = state1; - to_state[k] = state2; - } - } - - FREE(temp_map + ntokens); -} - - - -/* Map_goto maps a state/symbol pair into its numeric representation. */ - -int -map_goto(int state, int symbol) -{ - int high; - int low; - int middle; - int s; - - low = goto_map[symbol]; - high = goto_map[symbol + 1]; - - for (;;) - { - assert(low <= high); - middle = (low + high) >> 1; - s = from_state[middle]; - if (s == state) - return (middle); - else if (s < state) - low = middle + 1; - else - high = middle - 1; - } -} - - - -static void -initialize_F(void) -{ - int i; - int j; - int k; - shifts *sp; - short *edge; - unsigned *rowp; - short *rp; - short **reads; - int nedges; - int stateno; - int symbol; - int nwords; - - nwords = ngotos * tokensetsize; - F = NEW2(nwords, unsigned); - - reads = NEW2(ngotos, short *); - edge = NEW2(ngotos + 1, short); - nedges = 0; - - rowp = F; - for (i = 0; i < ngotos; i++) - { - stateno = to_state[i]; - sp = shift_table[stateno]; - - if (sp) - { - k = sp->nshifts; - - for (j = 0; j < k; j++) - { - symbol = accessing_symbol[sp->shift[j]]; - if (ISVAR(symbol)) - break; - SETBIT(rowp, symbol); - } - - for (; j < k; j++) - { - symbol = accessing_symbol[sp->shift[j]]; - if (nullable[symbol]) - edge[nedges++] = map_goto(stateno, symbol); - } - - if (nedges) - { - reads[i] = rp = NEW2(nedges + 1, short); - - for (j = 0; j < nedges; j++) - rp[j] = edge[j]; - - rp[nedges] = -1; - nedges = 0; - } - } - - rowp += tokensetsize; - } - - SETBIT(F, 0); - digraph(reads); - - for (i = 0; i < ngotos; i++) - { - if (reads[i]) - FREE(reads[i]); - } - - FREE(reads); - FREE(edge); -} - - - -static void -build_relations(void) -{ - int i; - int j; - int k; - short *rulep; - short *rp; - shifts *sp; - int length; - int nedges; - int done; - int state1; - int stateno; - int symbol1; - int symbol2; - short *shortp; - short *edge; - short *states; - short **new_includes; - - includes = NEW2(ngotos, short *); - edge = NEW2(ngotos + 1, short); - states = NEW2(maxrhs + 1, short); - - for (i = 0; i < ngotos; i++) - { - nedges = 0; - state1 = from_state[i]; - symbol1 = accessing_symbol[to_state[i]]; - - for (rulep = derives[symbol1]; *rulep >= 0; rulep++) - { - length = 1; - states[0] = state1; - stateno = state1; - - for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++) - { - symbol2 = *rp; - sp = shift_table[stateno]; - k = sp->nshifts; - - for (j = 0; j < k; j++) - { - stateno = sp->shift[j]; - if (accessing_symbol[stateno] == symbol2) break; - } - - states[length++] = stateno; - } - - add_lookback_edge(stateno, *rulep, i); - - length--; - done = 0; - while (!done) - { - done = 1; - rp--; - if (ISVAR(*rp)) - { - stateno = states[--length]; - edge[nedges++] = map_goto(stateno, *rp); - if (nullable[*rp] && length > 0) done = 0; - } - } - } - - if (nedges) - { - includes[i] = shortp = NEW2(nedges + 1, short); - for (j = 0; j < nedges; j++) - shortp[j] = edge[j]; - shortp[nedges] = -1; - } - } - - new_includes = transpose(includes, ngotos); - - for (i = 0; i < ngotos; i++) - if (includes[i]) - FREE(includes[i]); - - FREE(includes); - - includes = new_includes; - - FREE(edge); - FREE(states); -} - - -static void -add_lookback_edge(int stateno, int ruleno, int gotono) -{ - int i, k; - int found; - shorts *sp; - - i = lookaheads[stateno]; - k = lookaheads[stateno + 1]; - found = 0; - while (!found && i < k) - { - if (LAruleno[i] == ruleno) - found = 1; - else - ++i; - } - assert(found); - - sp = NEW(shorts); - sp->next = lookback[i]; - sp->value = gotono; - lookback[i] = sp; -} - - - -short ** -transpose(short int **R, int n) -{ - short **new_R; - short **temp_R; - short *nedges; - short *sp; - int i; - int k; - - nedges = NEW2(n, short); - - for (i = 0; i < n; i++) - { - sp = R[i]; - if (sp) - { - while (*sp >= 0) - nedges[*sp++]++; - } - } - - new_R = NEW2(n, short *); - temp_R = NEW2(n, short *); - - for (i = 0; i < n; i++) - { - k = nedges[i]; - if (k > 0) - { - sp = NEW2(k + 1, short); - new_R[i] = sp; - temp_R[i] = sp; - sp[k] = -1; - } - } - - FREE(nedges); - - for (i = 0; i < n; i++) - { - sp = R[i]; - if (sp) - { - while (*sp >= 0) - *temp_R[*sp++]++ = i; - } - } - - FREE(temp_R); - - return (new_R); -} - - - -static void -compute_FOLLOWS(void) -{ - digraph(includes); -} - - -static void -compute_lookaheads(void) -{ - int i, n; - unsigned *fp1, *fp2, *fp3; - shorts *sp, *next; - unsigned *rowp; - - rowp = LA; - n = lookaheads[nstates]; - for (i = 0; i < n; i++) - { - fp3 = rowp + tokensetsize; - for (sp = lookback[i]; sp; sp = sp->next) - { - fp1 = rowp; - fp2 = F + tokensetsize * sp->value; - while (fp1 < fp3) - *fp1++ |= *fp2++; - } - rowp = fp3; - } - - for (i = 0; i < n; i++) - for (sp = lookback[i]; sp; sp = next) - { - next = sp->next; - FREE(sp); - } - - FREE(lookback); - FREE(F); -} - - -static void -digraph(short **relation) -{ - int i; - - infinity = ngotos + 2; - INDEX = NEW2(ngotos + 1, short); - VERTICES = NEW2(ngotos + 1, short); - top = 0; - - R = relation; - - for (i = 0; i < ngotos; i++) - INDEX[i] = 0; - - for (i = 0; i < ngotos; i++) - { - if (INDEX[i] == 0 && R[i]) - traverse(i); - } - - FREE(INDEX); - FREE(VERTICES); -} - - - -static void -traverse(int i) -{ - unsigned *fp1; - unsigned *fp2; - unsigned *fp3; - int j; - short *rp; - - int height; - unsigned *base; - - VERTICES[++top] = i; - INDEX[i] = height = top; - - base = F + i * tokensetsize; - fp3 = base + tokensetsize; - - rp = R[i]; - if (rp) - { - while ((j = *rp++) >= 0) - { - if (INDEX[j] == 0) - traverse(j); - - if (INDEX[i] > INDEX[j]) - INDEX[i] = INDEX[j]; - - fp1 = base; - fp2 = F + j * tokensetsize; - - while (fp1 < fp3) - *fp1++ |= *fp2++; - } - } - - if (INDEX[i] == height) - { - for (;;) - { - j = VERTICES[top--]; - INDEX[j] = infinity; - - if (i == j) - break; - - fp1 = base; - fp2 = F + j * tokensetsize; - - while (fp1 < fp3) - *fp2++ = *fp1++; - } - } -} diff --git a/src/libCom/yacc/lr0.c b/src/libCom/yacc/lr0.c deleted file mode 100644 index 23b950930..000000000 --- a/src/libCom/yacc/lr0.c +++ /dev/null @@ -1,613 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "defs.h" - -extern short *itemset; -extern short *itemsetend; -extern unsigned *ruleset; - -int nstates; -core *first_state; -shifts *first_shift; -reductions *first_reduction; - -static core **state_set; -static core *this_state; -static core *last_state; -static shifts *last_shift; -static reductions *last_reduction; - -static int nshifts; -static short *shift_symbol; - -static short *redset; -static short *shiftset; - -static short **kernel_base; -static short **kernel_end; -static short *kernel_items; - -static int get_state(int symbol); -static void initialize_states(void); -static void new_itemsets(void); -static core *new_state(int symbol); -static void save_shifts(void); -static void save_reductions(void); -#ifdef DEBUG -static void print_derives(void); -#endif - - -static void -allocate_itemsets(void) -{ - short *itemp; - short *item_end; - int symbol; - int i; - int count; - int max; - short *symbol_count; - - count = 0; - symbol_count = NEW2(nsyms, short); - - item_end = ritem + nitems; - for (itemp = ritem; itemp < item_end; itemp++) - { - symbol = *itemp; - if (symbol >= 0) - { - count++; - symbol_count[symbol]++; - } - } - - kernel_base = NEW2(nsyms, short *); - kernel_items = NEW2(count, short); - - count = 0; - max = 0; - for (i = 0; i < nsyms; i++) - { - kernel_base[i] = kernel_items + count; - count += symbol_count[i]; - if (max < symbol_count[i]) - max = symbol_count[i]; - } - - shift_symbol = symbol_count; - kernel_end = NEW2(nsyms, short *); -} - -static void -allocate_storage(void) -{ - allocate_itemsets(); - shiftset = NEW2(nsyms, short); - redset = NEW2(nrules + 1, short); - state_set = NEW2(nitems, core *); -} - -static void -append_states(void) -{ - int i; - int j; - int symbol; - -#ifdef TRACE - fprintf(stderr, "Entering append_states()\n"); -#endif - for (i = 1; i < nshifts; i++) - { - symbol = shift_symbol[i]; - j = i; - while (j > 0 && shift_symbol[j - 1] > symbol) - { - shift_symbol[j] = shift_symbol[j - 1]; - j--; - } - shift_symbol[j] = symbol; - } - - for (i = 0; i < nshifts; i++) - { - symbol = shift_symbol[i]; - shiftset[i] = get_state(symbol); - } -} - -static void -free_storage(void) -{ - FREE(shift_symbol); - FREE(redset); - FREE(shiftset); - FREE(kernel_base); - FREE(kernel_end); - FREE(kernel_items); - FREE(state_set); -} - - -static void -generate_states(void) -{ - allocate_storage(); - itemset = NEW2(nitems, short); - ruleset = NEW2(WORDSIZE(nrules), unsigned); - set_first_derives(); - initialize_states(); - - while (this_state) - { - closure(this_state->items, this_state->nitems); - save_reductions(); - new_itemsets(); - append_states(); - - if (nshifts > 0) - save_shifts(); - - this_state = this_state->next; - } - - finalize_closure(); - free_storage(); -} - - - -static int -get_state(int symbol) -{ - int key; - short *isp1; - short *isp2; - short *iend; - core *sp; - int found; - int n; - -#ifdef TRACE - fprintf(stderr, "Entering get_state(%d)\n", symbol); -#endif - - isp1 = kernel_base[symbol]; - iend = kernel_end[symbol]; - n = iend - isp1; - - key = *isp1; - assert(0 <= key && key < nitems); - sp = state_set[key]; - if (sp) - { - found = 0; - while (!found) - { - if (sp->nitems == n) - { - found = 1; - isp1 = kernel_base[symbol]; - isp2 = sp->items; - - while (found && isp1 < iend) - { - if (*isp1++ != *isp2++) - found = 0; - } - } - - if (!found) - { - if (sp->link) - { - sp = sp->link; - } - else - { - sp = sp->link = new_state(symbol); - found = 1; - } - } - } - } - else - { - state_set[key] = sp = new_state(symbol); - } - - return (sp->number); -} - - -static void -initialize_states(void) -{ - int i; - short *start_derives; - core *p; - - start_derives = derives[start_symbol]; - for (i = 0; start_derives[i] >= 0; ++i) - continue; - - p = (core *) MALLOC(sizeof(core) + i*sizeof(short)); - if (p == 0) no_space(); - - p->next = 0; - p->link = 0; - p->number = 0; - p->accessing_symbol = 0; - p->nitems = i; - - for (i = 0; start_derives[i] >= 0; ++i) - p->items[i] = rrhs[start_derives[i]]; - - first_state = last_state = this_state = p; - nstates = 1; -} - -static void -new_itemsets(void) -{ - int i; - int shiftcount; - short *isp; - short *ksp; - int symbol; - - for (i = 0; i < nsyms; i++) - kernel_end[i] = 0; - - shiftcount = 0; - isp = itemset; - while (isp < itemsetend) - { - i = *isp++; - symbol = ritem[i]; - if (symbol > 0) - { - ksp = kernel_end[symbol]; - if (!ksp) - { - shift_symbol[shiftcount++] = symbol; - ksp = kernel_base[symbol]; - } - - *ksp++ = i + 1; - kernel_end[symbol] = ksp; - } - } - - nshifts = shiftcount; -} - - - -static core * -new_state(int symbol) -{ - int n; - core *p; - short *isp1; - short *isp2; - short *iend; - -#ifdef TRACE - fprintf(stderr, "Entering new_state(%d)\n", symbol); -#endif - - if (nstates >= MAXSHORT) - fatal("too many states"); - - isp1 = kernel_base[symbol]; - iend = kernel_end[symbol]; - n = iend - isp1; - - p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short))); - p->accessing_symbol = symbol; - p->number = nstates; - p->nitems = n; - - isp2 = p->items; - while (isp1 < iend) - *isp2++ = *isp1++; - - last_state->next = p; - last_state = p; - - nstates++; - - return (p); -} - - -#ifdef DEBUG -static void -show_cores(void) -{ - core *p; - int i, j, k, n; - int itemno; - - k = 0; - for (p = first_state; p; ++k, p = p->next) - { - if (k) printf("\n"); - printf("state %d, number = %d, accessing symbol = %s\n", - k, p->number, symbol_name[p->accessing_symbol]); - n = p->nitems; - for (i = 0; i < n; ++i) - { - itemno = p->items[i]; - printf("%4d ", itemno); - j = itemno; - while (ritem[j] >= 0) ++j; - printf("%s :", symbol_name[rlhs[-ritem[j]]]); - j = rrhs[-ritem[j]]; - while (j < itemno) - printf(" %s", symbol_name[ritem[j++]]); - printf(" ."); - while (ritem[j] >= 0) - printf(" %s", symbol_name[ritem[j++]]); - printf("\n"); - fflush(stdout); - } - } -} - - -static void -show_ritems(void) -{ - int i; - - for (i = 0; i < nitems; ++i) - printf("ritem[%d] = %d\n", i, ritem[i]); -} - - -static void -show_rrhs(void) -{ - int i; - - for (i = 0; i < nrules; ++i) - printf("rrhs[%d] = %d\n", i, rrhs[i]); -} - - -static void -show_shifts(void) -{ - shifts *p; - int i, j, k; - - k = 0; - for (p = first_shift; p; ++k, p = p->next) - { - if (k) printf("\n"); - printf("shift %d, number = %d, nshifts = %d\n", k, p->number, - p->nshifts); - j = p->nshifts; - for (i = 0; i < j; ++i) - printf("\t%d\n", p->shift[i]); - } -} -#endif - -static void -save_shifts(void) -{ - shifts *p; - short *sp1; - short *sp2; - short *send; - - p = (shifts *) allocate((unsigned) (sizeof(shifts) + - (nshifts - 1) * sizeof(short))); - - p->number = this_state->number; - p->nshifts = nshifts; - - sp1 = shiftset; - sp2 = p->shift; - send = shiftset + nshifts; - - while (sp1 < send) - *sp2++ = *sp1++; - - if (last_shift) - { - last_shift->next = p; - last_shift = p; - } - else - { - first_shift = p; - last_shift = p; - } -} - - -static void -save_reductions(void) -{ - short *isp; - short *rp1; - short *rp2; - int item; - int count; - reductions *p; - short *rend; - - count = 0; - for (isp = itemset; isp < itemsetend; isp++) - { - item = ritem[*isp]; - if (item < 0) - { - redset[count++] = -item; - } - } - - if (count) - { - p = (reductions *) allocate((unsigned) (sizeof(reductions) + - (count - 1) * sizeof(short))); - - p->number = this_state->number; - p->nreds = count; - - rp1 = redset; - rp2 = p->rules; - rend = rp1 + count; - - while (rp1 < rend) - *rp2++ = *rp1++; - - if (last_reduction) - { - last_reduction->next = p; - last_reduction = p; - } - else - { - first_reduction = p; - last_reduction = p; - } - } -} - -static void -set_derives(void) -{ - int i, k; - int lhs; - short *rules; - - derives = NEW2(nsyms, short *); - rules = NEW2(nvars + nrules, short); - - k = 0; - for (lhs = start_symbol; lhs < nsyms; lhs++) - { - derives[lhs] = rules + k; - for (i = 0; i < nrules; i++) - { - if (rlhs[i] == lhs) - { - rules[k] = i; - k++; - } - } - rules[k] = -1; - k++; - } - -#ifdef DEBUG - print_derives(); -#endif -} - -void -free_derives(void) -{ - FREE(derives[start_symbol]); - FREE(derives); -} - -#ifdef DEBUG -static void -print_derives(void) -{ - int i; - short *sp; - - printf("\nDERIVES\n\n"); - - for (i = start_symbol; i < nsyms; i++) - { - printf("%s derives ", symbol_name[i]); - for (sp = derives[i]; *sp >= 0; sp++) - { - printf(" %d", *sp); - } - putchar('\n'); - } - - putchar('\n'); -} -#endif - -static void -set_nullable(void) -{ - int i, j; - int empty; - int done; - - nullable = MALLOC(nsyms); - if (nullable == 0) no_space(); - - for (i = 0; i < nsyms; ++i) - nullable[i] = 0; - - done = 0; - while (!done) - { - done = 1; - for (i = 1; i < nitems; i++) - { - empty = 1; - while ((j = ritem[i]) >= 0) - { - if (!nullable[j]) - empty = 0; - ++i; - } - if (empty) - { - j = rlhs[-j]; - if (!nullable[j]) - { - nullable[j] = 1; - done = 0; - } - } - } - } - -#ifdef DEBUG - for (i = 0; i < nsyms; i++) - { - if (nullable[i]) - printf("%s is nullable\n", symbol_name[i]); - else - printf("%s is not nullable\n", symbol_name[i]); - } -#endif -} - -void -free_nullable(void) -{ - FREE(nullable); -} - -void -lr0(void) -{ - set_derives(); - set_nullable(); - generate_states(); -} diff --git a/src/libCom/yacc/mkpar.c b/src/libCom/yacc/mkpar.c deleted file mode 100644 index 5385f0e00..000000000 --- a/src/libCom/yacc/mkpar.c +++ /dev/null @@ -1,372 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "defs.h" - -action **parser; -int SRtotal; -int RRtotal; -short *SRconflicts; -short *RRconflicts; -short *defred; -short *rules_used; -short nunused; -short final_state; - -static int SRcount; -static int RRcount; - - -static action *parse_actions(int stateno); -static action *get_shifts(int stateno); -static action *add_reductions(int stateno, action *actions); -static action *add_reduce(action *actions, int ruleno, int symbol); -static void find_final_state(void); -static void unused_rules(void); -static void remove_conflicts(void); -static void total_conflicts(void); -static void defreds(void); - -void -make_parser(void) -{ - int i; - - parser = NEW2(nstates, action *); - for (i = 0; i < nstates; i++) - parser[i] = parse_actions(i); - - find_final_state(); - remove_conflicts(); - unused_rules(); - if (SRtotal + RRtotal > 0) total_conflicts(); - defreds(); -} - - -static action * -parse_actions(int stateno) -{ - action *actions; - - actions = get_shifts(stateno); - actions = add_reductions(stateno, actions); - return (actions); -} - - -static action * -get_shifts(int stateno) -{ - action *actions, *temp; - shifts *sp; - short *to_state; - int i, k; - int symbol; - - actions = 0; - sp = shift_table[stateno]; - if (sp) - { - to_state = sp->shift; - for (i = sp->nshifts - 1; i >= 0; i--) - { - k = to_state[i]; - symbol = accessing_symbol[k]; - if (ISTOKEN(symbol)) - { - temp = NEW(action); - temp->next = actions; - temp->symbol = symbol; - temp->number = k; - temp->prec = symbol_prec[symbol]; - temp->action_code = SHIFT; - temp->assoc = symbol_assoc[symbol]; - actions = temp; - } - } - } - return (actions); -} - -static action * -add_reductions(int stateno, action *actions) -{ - int i, j, m, n; - int ruleno, tokensetsize; - unsigned *rowp; - - tokensetsize = WORDSIZE(ntokens); - m = lookaheads[stateno]; - n = lookaheads[stateno + 1]; - for (i = m; i < n; i++) - { - ruleno = LAruleno[i]; - rowp = LA + i * tokensetsize; - for (j = ntokens - 1; j >= 0; j--) - { - if (BIT(rowp, j)) - actions = add_reduce(actions, ruleno, j); - } - } - return (actions); -} - - -static action * -add_reduce(action *actions, int ruleno, int symbol) -{ - action *temp, *prev, *next; - - prev = 0; - for (next = actions; next && next->symbol < symbol; next = next->next) - prev = next; - - while (next && next->symbol == symbol && next->action_code == SHIFT) - { - prev = next; - next = next->next; - } - - while (next && next->symbol == symbol && - next->action_code == REDUCE && next->number < ruleno) - { - prev = next; - next = next->next; - } - - temp = NEW(action); - temp->next = next; - temp->symbol = symbol; - temp->number = ruleno; - temp->prec = rprec[ruleno]; - temp->action_code = REDUCE; - temp->assoc = rassoc[ruleno]; - - if (prev) - prev->next = temp; - else - actions = temp; - - return (actions); -} - - -static void -find_final_state(void) -{ - int goal, i; - short *to_state; - shifts *p; - - p = shift_table[0]; - to_state = p->shift; - goal = ritem[1]; - for (i = p->nshifts - 1; i >= 0; --i) - { - final_state = to_state[i]; - if (accessing_symbol[final_state] == goal) break; - } -} - - -static void -unused_rules(void) -{ - int i; - action *p; - - rules_used = (short *) MALLOC(nrules*sizeof(short)); - if (rules_used == 0) no_space(); - - for (i = 0; i < nrules; ++i) - rules_used[i] = 0; - - for (i = 0; i < nstates; ++i) - { - for (p = parser[i]; p; p = p->next) - { - if (p->action_code == REDUCE && p->suppressed == 0) - rules_used[p->number] = 1; - } - } - - nunused = 0; - for (i = 3; i < nrules; ++i) - if (!rules_used[i]) ++nunused; - - if (nunused) - { - if (nunused == 1) - fprintf(stderr, "%s: 1 rule never reduced\n", myname); - else - fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused); - } -} - - -static void -remove_conflicts(void) -{ - int i; - int symbol; - action *p, *pref = NULL; - - SRtotal = 0; - RRtotal = 0; - SRconflicts = NEW2(nstates, short); - RRconflicts = NEW2(nstates, short); - for (i = 0; i < nstates; i++) - { - SRcount = 0; - RRcount = 0; - symbol = -1; - for (p = parser[i]; p; p = p->next) - { - if (p->symbol != symbol) - { - pref = p; - symbol = p->symbol; - } - else if (i == final_state && symbol == 0) - { - SRcount++; - p->suppressed = 1; - } - else if (pref && pref->action_code == SHIFT) - { - if (pref->prec > 0 && p->prec > 0) - { - if (pref->prec < p->prec) - { - pref->suppressed = 2; - pref = p; - } - else if (pref->prec > p->prec) - { - p->suppressed = 2; - } - else if (pref->assoc == LEFT) - { - pref->suppressed = 2; - pref = p; - } - else if (pref->assoc == RIGHT) - { - p->suppressed = 2; - } - else - { - pref->suppressed = 2; - p->suppressed = 2; - } - } - else - { - SRcount++; - p->suppressed = 1; - } - } - else - { - RRcount++; - p->suppressed = 1; - } - } - SRtotal += SRcount; - RRtotal += RRcount; - SRconflicts[i] = SRcount; - RRconflicts[i] = RRcount; - } -} - - -static void -total_conflicts(void) -{ - fprintf(stderr, "%s: ", myname); - if (SRtotal == 1) - fprintf(stderr, "1 shift/reduce conflict"); - else if (SRtotal > 1) - fprintf(stderr, "%d shift/reduce conflicts", SRtotal); - - if (SRtotal && RRtotal) - fprintf(stderr, ", "); - - if (RRtotal == 1) - fprintf(stderr, "1 reduce/reduce conflict"); - else if (RRtotal > 1) - fprintf(stderr, "%d reduce/reduce conflicts", RRtotal); - - fprintf(stderr, ".\n"); -} - - -static int -sole_reduction(int stateno) -{ - int count, ruleno; - action *p; - - count = 0; - ruleno = 0; - for (p = parser[stateno]; p; p = p->next) - { - if (p->action_code == SHIFT && p->suppressed == 0) - return 0; - else if (p->action_code == REDUCE && p->suppressed == 0) - { - if (ruleno > 0 && p->number != ruleno) - return 0; - if (p->symbol != 1) - ++count; - ruleno = p->number; - } - } - - if (count == 0) - return 0; - return ruleno; -} - - -static void -defreds(void) -{ - int i; - - defred = NEW2(nstates, short); - for (i = 0; i < nstates; i++) - defred[i] = sole_reduction(i); -} - -static void -free_action_row(action *p) -{ - action *q; - - while (p) - { - q = p->next; - FREE(p); - p = q; - } -} - -void -free_parser(void) -{ - int i; - - for (i = 0; i < nstates; i++) - free_action_row(parser[i]); - - FREE(parser); -} - diff --git a/src/libCom/yacc/output.c b/src/libCom/yacc/output.c deleted file mode 100644 index a1913ed77..000000000 --- a/src/libCom/yacc/output.c +++ /dev/null @@ -1,1247 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include "defs.h" - -static int nvectors; -static int nentries; -static short **froms; -static short **tos; -static short *tally; -static short *width; -static short *state_count; -static short *order; -static short *base; -static short *pos; -static int maxtable; -static short *table; -static short *check; -static int lowzero; -static int high; - -static void output_prefix(void); -static void output_rule_data(void); -static void output_yydefred(void); -static void output_actions(void); -static void token_actions(void); -static void goto_actions(void); -static void save_column(int symbol, int default_state); -static void sort_actions(void); -static void pack_table(void); -static void output_base(void); -static void output_table(void); -static void output_check(void); -static void output_defines(void); -static void output_stored_text(void); -static void output_debug(void); -static void output_stype(void); -static void output_trailing_text(void); -static void output_semantic_actions(void); -static void free_itemsets(void); -static void free_shifts(void); -static void free_reductions(void); - - -void -output(void) -{ - free_itemsets(); - free_shifts(); - free_reductions(); - output_prefix(); - output_stored_text(); - output_defines(); - output_rule_data(); - output_yydefred(); - output_actions(); - free_parser(); - output_debug(); - output_stype(); - if (rflag) write_section(tables); - write_section(header); - output_trailing_text(); - write_section(body); - output_semantic_actions(); - write_section(trailer); -} - - -static void -output_prefix(void) -{ - if (symbol_prefix == NULL) - symbol_prefix = "yy"; - else - { - ++outline; - fprintf(code_file, "#define yyparse %sparse\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yylex %slex\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyerror %serror\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yychar %schar\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyval %sval\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yylval %slval\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yydebug %sdebug\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yynerrs %snerrs\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyerrflag %serrflag\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyss %sss\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyssp %sssp\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyvs %svs\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyvsp %svsp\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yylhs %slhs\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yylen %slen\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yydefred %sdefred\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yydgoto %sdgoto\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yysindex %ssindex\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyrindex %srindex\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yygindex %sgindex\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yytable %stable\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yycheck %scheck\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyname %sname\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyrule %srule\n", symbol_prefix); - } - ++outline; - fprintf(code_file, "#define YYPREFIX \"%s\"\n", symbol_prefix); -} - - -static void -output_rule_data(void) -{ - int i; - int j; - - fprintf(output_file, "static short %slhs[] = {%42d,", symbol_prefix, - symbol_value[start_symbol]); - - j = 10; - for (i = 3; i < nrules; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - fprintf(output_file, "%5d,", symbol_value[rlhs[i]]); - } - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); - - fprintf(output_file, "static short %slen[] = {%42d,", symbol_prefix, 2); - - j = 10; - for (i = 3; i < nrules; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - j++; - - fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1); - } - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); -} - - -static void -output_yydefred(void) -{ - int i, j; - - fprintf(output_file, "static short %sdefred[] = {%39d,", symbol_prefix, - (defred[0] ? defred[0] - 2 : 0)); - - j = 10; - for (i = 1; i < nstates; i++) - { - if (j < 10) - ++j; - else - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - - fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0)); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); -} - - -static void -output_actions(void) -{ - nvectors = 2*nstates + nvars; - - froms = NEW2(nvectors, short *); - tos = NEW2(nvectors, short *); - tally = NEW2(nvectors, short); - width = NEW2(nvectors, short); - - token_actions(); - FREE(lookaheads); - FREE(LA); - FREE(LAruleno); - FREE(accessing_symbol); - - goto_actions(); - FREE(goto_map + ntokens); - FREE(from_state); - FREE(to_state); - - sort_actions(); - pack_table(); - output_base(); - output_table(); - output_check(); -} - - -static void -token_actions(void) -{ - int i, j; - int shiftcount, reducecount; - int max, min; - short *actionrow, *r, *s; - action *p; - - actionrow = NEW2(2*ntokens, short); - for (i = 0; i < nstates; ++i) - { - if (parser[i]) - { - for (j = 0; j < 2*ntokens; ++j) - actionrow[j] = 0; - - shiftcount = 0; - reducecount = 0; - for (p = parser[i]; p; p = p->next) - { - if (p->suppressed == 0) - { - if (p->action_code == SHIFT) - { - ++shiftcount; - actionrow[p->symbol] = p->number; - } - else if (p->action_code == REDUCE && p->number != defred[i]) - { - ++reducecount; - actionrow[p->symbol + ntokens] = p->number; - } - } - } - - tally[i] = shiftcount; - tally[nstates+i] = reducecount; - width[i] = 0; - width[nstates+i] = 0; - if (shiftcount > 0) - { - froms[i] = r = NEW2(shiftcount, short); - tos[i] = s = NEW2(shiftcount, short); - min = MAXSHORT; - max = 0; - for (j = 0; j < ntokens; ++j) - { - if (actionrow[j]) - { - if (min > symbol_value[j]) - min = symbol_value[j]; - if (max < symbol_value[j]) - max = symbol_value[j]; - *r++ = symbol_value[j]; - *s++ = actionrow[j]; - } - } - width[i] = max - min + 1; - } - if (reducecount > 0) - { - froms[nstates+i] = r = NEW2(reducecount, short); - tos[nstates+i] = s = NEW2(reducecount, short); - min = MAXSHORT; - max = 0; - for (j = 0; j < ntokens; ++j) - { - if (actionrow[ntokens+j]) - { - if (min > symbol_value[j]) - min = symbol_value[j]; - if (max < symbol_value[j]) - max = symbol_value[j]; - *r++ = symbol_value[j]; - *s++ = actionrow[ntokens+j] - 2; - } - } - width[nstates+i] = max - min + 1; - } - } - } - FREE(actionrow); -} - -static void -goto_actions(void) -{ - int i, j, k; - - state_count = NEW2(nstates, short); - - k = default_goto(start_symbol + 1); - fprintf(output_file, "static short %sdgoto[] = {%40d,", symbol_prefix, k); - save_column(start_symbol + 1, k); - - j = 10; - for (i = start_symbol + 2; i < nsyms; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - k = default_goto(i); - fprintf(output_file, "%5d,", k); - save_column(i, k); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); - FREE(state_count); -} - -int -default_goto(int symbol) -{ - int i; - int m; - int n; - int default_state; - int max; - - m = goto_map[symbol]; - n = goto_map[symbol + 1]; - - if (m == n) return (0); - - for (i = 0; i < nstates; i++) - state_count[i] = 0; - - for (i = m; i < n; i++) - state_count[to_state[i]]++; - - max = 0; - default_state = 0; - for (i = 0; i < nstates; i++) - { - if (state_count[i] > max) - { - max = state_count[i]; - default_state = i; - } - } - - return (default_state); -} - - - - -static void -save_column(int symbol, int default_state) -{ - int i; - int m; - int n; - short *sp; - short *sp1; - short *sp2; - int count; - int symno; - - m = goto_map[symbol]; - n = goto_map[symbol + 1]; - - count = 0; - for (i = m; i < n; i++) - { - if (to_state[i] != default_state) - ++count; - } - if (count == 0) return; - - symno = symbol_value[symbol] + 2*nstates; - - froms[symno] = sp1 = sp = NEW2(count, short); - tos[symno] = sp2 = NEW2(count, short); - - for (i = m; i < n; i++) - { - if (to_state[i] != default_state) - { - *sp1++ = from_state[i]; - *sp2++ = to_state[i]; - } - } - - tally[symno] = count; - width[symno] = sp1[-1] - sp[0] + 1; -} - -static void -sort_actions(void) -{ - int i; - int j; - int k; - int t; - int w; - - order = NEW2(nvectors, short); - nentries = 0; - - for (i = 0; i < nvectors; i++) - { - if (tally[i] > 0) - { - t = tally[i]; - w = width[i]; - j = nentries - 1; - - while (j >= 0 && (width[order[j]] < w)) - j--; - - while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t)) - j--; - - for (k = nentries - 1; k > j; k--) - order[k + 1] = order[k]; - - order[j + 1] = i; - nentries++; - } - } -} - - -static void -pack_table(void) -{ - int i; - int place; - int state; - - base = NEW2(nvectors, short); - pos = NEW2(nentries, short); - - maxtable = 1000; - table = NEW2(maxtable, short); - check = NEW2(maxtable, short); - - lowzero = 0; - high = 0; - - for (i = 0; i < maxtable; i++) - check[i] = -1; - - for (i = 0; i < nentries; i++) - { - state = matching_vector(i); - - if (state < 0) - place = pack_vector(i); - else - place = base[state]; - - pos[i] = place; - base[order[i]] = place; - } - - for (i = 0; i < nvectors; i++) - { - if (froms[i]) - FREE(froms[i]); - if (tos[i]) - FREE(tos[i]); - } - - FREE(froms); - FREE(tos); - FREE(pos); -} - - -/* The function matching_vector determines if the vector specified by */ -/* the input parameter matches a previously considered vector. The */ -/* test at the start of the function checks if the vector represents */ -/* a row of shifts over terminal symbols or a row of reductions, or a */ -/* column of shifts over a nonterminal symbol. Berkeley Yacc does not */ -/* check if a column of shifts over a nonterminal symbols matches a */ -/* previously considered vector. Because of the nature of LR parsing */ -/* tables, no two columns can match. Therefore, the only possible */ -/* match would be between a row and a column. Such matches are */ -/* unlikely. Therefore, to save time, no attempt is made to see if a */ -/* column matches a previously considered vector. */ -/* */ -/* Matching_vector is poorly designed. The test could easily be made */ -/* faster. Also, it depends on the vectors being in a specific */ -/* order. */ - -int -matching_vector(int vector) -{ - int i; - int j; - int k; - int t; - int w; - int match; - int prev; - - i = order[vector]; - if (i >= 2*nstates) - return (-1); - - t = tally[i]; - w = width[i]; - - for (prev = vector - 1; prev >= 0; prev--) - { - j = order[prev]; - if (width[j] != w || tally[j] != t) - return (-1); - - match = 1; - for (k = 0; match && k < t; k++) - { - if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k]) - match = 0; - } - - if (match) - return (j); - } - - return (-1); -} - - - -int -pack_vector(int vector) -{ - int i, j, k, l; - int t; - int loc; - int ok; - short *from; - short *to; - int newmax; - - i = order[vector]; - t = tally[i]; - assert(t); - - from = froms[i]; - to = tos[i]; - - j = lowzero - from[0]; - for (k = 1; k < t; ++k) - if (lowzero - from[k] > j) - j = lowzero - from[k]; - for (;; ++j) - { - if (j == 0) - continue; - ok = 1; - for (k = 0; ok && k < t; k++) - { - loc = j + from[k]; - if (loc >= maxtable) - { - if (loc >= MAXTABLE) - fatal("maximum table size exceeded"); - - newmax = maxtable; - do { newmax += 200; } while (newmax <= loc); - table = (short *) REALLOC(table, newmax*sizeof(short)); - if (table == 0) no_space(); - check = (short *) REALLOC(check, newmax*sizeof(short)); - if (check == 0) no_space(); - for (l = maxtable; l < newmax; ++l) - { - table[l] = 0; - check[l] = -1; - } - maxtable = newmax; - } - - if (check[loc] != -1) - ok = 0; - } - for (k = 0; ok && k < vector; k++) - { - if (pos[k] == j) - ok = 0; - } - if (ok) - { - for (k = 0; k < t; k++) - { - loc = j + from[k]; - table[loc] = to[k]; - check[loc] = from[k]; - if (loc > high) high = loc; - } - - while (check[lowzero] != -1) - ++lowzero; - - return (j); - } - } -} - - - -static void -output_base(void) -{ - int i, j; - - fprintf(output_file, "static short %ssindex[] = {%39d,", symbol_prefix, base[0]); - - j = 10; - for (i = 1; i < nstates; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - fprintf(output_file, "%5d,", base[i]); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\nstatic short %srindex[] = {%39d,", symbol_prefix, - base[nstates]); - - j = 10; - for (i = nstates + 1; i < 2*nstates; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - fprintf(output_file, "%5d,", base[i]); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\nstatic short %sgindex[] = {%39d,", symbol_prefix, - base[2*nstates]); - - j = 10; - for (i = 2*nstates + 1; i < nvectors - 1; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - fprintf(output_file, "%5d,", base[i]); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); - FREE(base); -} - - - -static void -output_table(void) -{ - int i; - int j; - - ++outline; - fprintf(code_file, "#define YYTABLESIZE %d\n", high); - fprintf(output_file, "static short %stable[] = {%40d,", symbol_prefix, - table[0]); - - j = 10; - for (i = 1; i <= high; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - fprintf(output_file, "%5d,", table[i]); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); - FREE(table); -} - - - -static void -output_check(void) -{ - int i; - int j; - - fprintf(output_file, "static short %scheck[] = {%40d,", symbol_prefix, - check[0]); - - j = 10; - for (i = 1; i <= high; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - fprintf(output_file, "%5d,", check[i]); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); - FREE(check); -} - - -static int -is_C_identifier(char *name) -{ - char *s; - int c; - - s = name; - c = *s; - if (c == '"') - { - c = *++s; - if (!isalpha(c) && c != '_' && c != '$') - return (0); - while ((c = *++s) != '"') - { - if (!isalnum(c) && c != '_' && c != '$') - return (0); - } - return (1); - } - - if (!isalpha(c) && c != '_' && c != '$') - return (0); - while ((c = *++s)) - { - if (!isalnum(c) && c != '_' && c != '$') - return (0); - } - return (1); -} - - -static void -output_defines(void) -{ - int c, i; - char *s; - - for (i = 2; i < ntokens; ++i) - { - s = symbol_name[i]; - if (is_C_identifier(s)) - { - fprintf(code_file, "#define "); - if (dflag) fprintf(defines_file, "#define "); - c = *s; - if (c == '"') - { - while ((c = *++s) != '"') - { - putc(c, code_file); - if (dflag) putc(c, defines_file); - } - } - else - { - do - { - putc(c, code_file); - if (dflag) putc(c, defines_file); - } - while ((c = *++s)); - } - ++outline; - fprintf(code_file, " %d\n", symbol_value[i]); - if (dflag) fprintf(defines_file, " %d\n", symbol_value[i]); - } - } - - ++outline; - fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]); - - if (dflag && unionized) - { - rewind(union_file); - while ((c = getc(union_file)) != EOF) - putc(c, defines_file); - fprintf(defines_file, " YYSTYPE;\nstatic YYSTYPE %slval;\n", - symbol_prefix); - } -} - - -static void -output_stored_text(void) -{ - int c; - FILE *in, *out; - - rewind(text_file); - in = text_file; - if ((c = getc(in)) == EOF) - return; - out = code_file; - if (c == '\n') - ++outline; - putc(c, out); - while ((c = getc(in)) != EOF) - { - if (c == '\n') - ++outline; - putc(c, out); - } - if (!lflag) - fprintf(out, line_format, ++outline + 1, code_file_name); -} - - -static void -output_debug(void) -{ - int i, j, k, max; - char **symnam, *s; - - ++outline; - fprintf(code_file, "#define YYFINAL %d\n", final_state); - outline += 3; - fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n", - tflag); - if (rflag) - fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n", - tflag); - - max = 0; - for (i = 2; i < ntokens; ++i) - if (symbol_value[i] > max) - max = symbol_value[i]; - ++outline; - fprintf(code_file, "#define YYMAXTOKEN %d\n", max); - - symnam = (char **) MALLOC((max+1)*sizeof(char *)); - if (symnam == 0) no_space(); - - /* Note that it is not necessary to initialize the element */ - /* symnam[max]. */ - for (i = 0; i < max; ++i) - symnam[i] = 0; - for (i = ntokens - 1; i >= 2; --i) - symnam[symbol_value[i]] = symbol_name[i]; - symnam[0] = "end-of-file"; - - if (!rflag) ++outline; - fprintf(output_file, "#if YYDEBUG\nstatic char *%sname[] = {", symbol_prefix); - j = 80; - for (i = 0; i <= max; ++i) - { - if ((s = symnam[i])) - { - if (s[0] == '"') - { - k = 7; - while (*++s != '"') - { - ++k; - if (*s == '\\') - { - k += 2; - if (*++s == '\\') - ++k; - } - } - j += k; - if (j > 80) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = k; - } - fprintf(output_file, "\"\\\""); - s = symnam[i]; - while (*++s != '"') - { - if (*s == '\\') - { - fprintf(output_file, "\\\\"); - if (*++s == '\\') - fprintf(output_file, "\\\\"); - else - putc(*s, output_file); - } - else - putc(*s, output_file); - } - fprintf(output_file, "\\\"\","); - } - else if (s[0] == '\'') - { - if (s[1] == '"') - { - j += 7; - if (j > 80) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 7; - } - fprintf(output_file, "\"'\\\"'\","); - } - else - { - k = 5; - while (*++s != '\'') - { - ++k; - if (*s == '\\') - { - k += 2; - if (*++s == '\\') - ++k; - } - } - j += k; - if (j > 80) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = k; - } - fprintf(output_file, "\"'"); - s = symnam[i]; - while (*++s != '\'') - { - if (*s == '\\') - { - fprintf(output_file, "\\\\"); - if (*++s == '\\') - fprintf(output_file, "\\\\"); - else - putc(*s, output_file); - } - else - putc(*s, output_file); - } - fprintf(output_file, "'\","); - } - } - else - { - k = strlen(s) + 3; - j += k; - if (j > 80) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = k; - } - putc('"', output_file); - do { putc(*s, output_file); } while (*++s); - fprintf(output_file, "\","); - } - } - else - { - j += 2; - if (j > 80) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 2; - } - fprintf(output_file, "0,"); - } - } - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); - FREE(symnam); - - if (!rflag) ++outline; - fprintf(output_file, "static char *%srule[] = {\n", symbol_prefix); - for (i = 2; i < nrules; ++i) - { - fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]); - for (j = rrhs[i]; ritem[j] > 0; ++j) - { - s = symbol_name[ritem[j]]; - if (s[0] == '"') - { - fprintf(output_file, " \\\""); - while (*++s != '"') - { - if (*s == '\\') - { - if (s[1] == '\\') - fprintf(output_file, "\\\\\\\\"); - else - fprintf(output_file, "\\\\%c", s[1]); - ++s; - } - else - putc(*s, output_file); - } - fprintf(output_file, "\\\""); - } - else if (s[0] == '\'') - { - if (s[1] == '"') - fprintf(output_file, " '\\\"'"); - else if (s[1] == '\\') - { - if (s[2] == '\\') - fprintf(output_file, " '\\\\\\\\"); - else - fprintf(output_file, " '\\\\%c", s[2]); - s += 2; - while (*++s != '\'') - putc(*s, output_file); - putc('\'', output_file); - } - else - fprintf(output_file, " '%c'", s[1]); - } - else - fprintf(output_file, " %s", s); - } - if (!rflag) ++outline; - fprintf(output_file, "\",\n"); - } - - if (!rflag) outline += 2; - fprintf(output_file, "};\n#endif\n"); -} - - -static void -output_stype(void) -{ - if (!unionized && ntags == 0) - { - outline += 3; - fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n"); - } -} - - -static void -output_trailing_text(void) -{ - int c, last; - FILE *in, *out; - - if (line == 0) - return; - - in = input_file; - out = code_file; - c = *cptr; - if (c == '\n') - { - ++lineno; - if ((c = getc(in)) == EOF) - return; - if (!lflag) - { - ++outline; - fprintf(out, line_format, lineno, input_file_name); - } - if (c == '\n') - ++outline; - putc(c, out); - last = c; - } - else - { - if (!lflag) - { - ++outline; - fprintf(out, line_format, lineno, input_file_name); - } - do { putc(c, out); } while ((c = *++cptr) != '\n'); - ++outline; - putc('\n', out); - last = '\n'; - } - - while ((c = getc(in)) != EOF) - { - if (c == '\n') - ++outline; - putc(c, out); - last = c; - } - - if (last != '\n') - { - ++outline; - putc('\n', out); - } - if (!lflag) - fprintf(out, line_format, ++outline + 1, code_file_name); -} - - -static void -output_semantic_actions(void) -{ - int c, last; - FILE *out; - - rewind(action_file); - - if ((c = getc(action_file)) == EOF) - return; - - out = code_file; - last = c; - if (c == '\n') - ++outline; - putc(c, out); - while ((c = getc(action_file)) != EOF) - { - if (c == '\n') - ++outline; - putc(c, out); - last = c; - } - - if (last != '\n') - { - ++outline; - putc('\n', out); - } - - if (!lflag) - fprintf(out, line_format, ++outline + 1, code_file_name); -} - - -static void -free_itemsets(void) -{ - core *cp, *next; - - FREE(state_table); - for (cp = first_state; cp; cp = next) - { - next = cp->next; - FREE(cp); - } -} - - -static void -free_shifts(void) -{ - shifts *sp, *next; - - FREE(shift_table); - for (sp = first_shift; sp; sp = next) - { - next = sp->next; - FREE(sp); - } -} - - -static void -free_reductions(void) -{ - reductions *rp, *next; - - FREE(reduction_table); - for (rp = first_reduction; rp; rp = next) - { - next = rp->next; - FREE(rp); - } -} diff --git a/src/libCom/yacc/reader.c b/src/libCom/yacc/reader.c deleted file mode 100644 index 93a1a42de..000000000 --- a/src/libCom/yacc/reader.c +++ /dev/null @@ -1,1805 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include "defs.h" - -/* The line size must be a positive integer. One hundred was chosen */ -/* because few lines in Yacc input grammars exceed 100 characters. */ -/* Note that if a line exceeds LINESIZE characters, the line buffer */ -/* will be expanded to accomodate it. */ - -#define LINESIZE 100 - -char *cache; -int cinc, cache_size; - -int ntags, tagmax; -char **tag_table; - -char saw_eof, unionized; -char *cptr, *line; -int linesize; - -bucket *goal; -int prec; -int gensym; -char last_was_action; - -int maxitems; -bucket **pitem; - -int maxrules; -bucket **plhs; - -int name_pool_size; -char *name_pool; - -char line_format[] = "#line %d \"%s\"\n"; - -#define static - -static void start_rule(bucket *bp, int s_lineno); - - -static void -cachec(int c) -{ - assert(cinc >= 0); - if (cinc >= cache_size) - { - cache_size += 256; - cache = REALLOC(cache, cache_size); - if (cache == 0) no_space(); - } - cache[cinc] = c; - ++cinc; -} - - -static void -get_line(void) -{ - FILE *f = input_file; - int c; - int i; - - if (saw_eof || (c = getc(f)) == EOF) - { - if (line) { FREE(line); line = 0; } - cptr = 0; - saw_eof = 1; - return; - } - - if (line == 0 || linesize != (LINESIZE + 1)) - { - if (line) FREE(line); - linesize = LINESIZE + 1; - line = MALLOC(linesize); - if (line == 0) no_space(); - } - - i = 0; - ++lineno; - for (;;) - { - line[i] = c; - if (c == '\n') { cptr = line; return; } - if (++i >= linesize) - { - linesize += LINESIZE; - line = REALLOC(line, linesize); - if (line == 0) no_space(); - } - c = getc(f); - if (c == EOF) - { - line[i] = '\n'; - saw_eof = 1; - cptr = line; - return; - } - } -} - - -static char * -dup_line(void) -{ - char *p, *s, *t; - - if (line == 0) return (0); - s = line; - while (*s != '\n') ++s; - p = MALLOC(s - line + 1); - if (p == 0) no_space(); - - s = line; - t = p; - while ((*t++ = *s++) != '\n') continue; - return (p); -} - - -static void -skip_comment(void) -{ - char *s; - - int st_lineno = lineno; - char *st_line = dup_line(); - char *st_cptr = st_line + (cptr - line); - - s = cptr + 2; - for (;;) - { - if (*s == '*' && s[1] == '/') - { - cptr = s + 2; - FREE(st_line); - return; - } - if (*s == '\n') - { - get_line(); - if (line == 0) - unterminated_comment(st_lineno, st_line, st_cptr); - s = cptr; - } - else - ++s; - } -} - - -static int -nextc(void) -{ - char *s; - - if (line == 0) - { - get_line(); - if (line == 0) - return (EOF); - } - - s = cptr; - for (;;) - { - switch (*s) - { - case '\n': - get_line(); - if (line == 0) return (EOF); - s = cptr; - break; - - case ' ': - case '\t': - case '\f': - case '\r': - case '\v': - case ',': - case ';': - ++s; - break; - - case '\\': - cptr = s; - return ('%'); - - case '/': - if (s[1] == '*') - { - cptr = s; - skip_comment(); - s = cptr; - break; - } - else if (s[1] == '/') - { - get_line(); - if (line == 0) return (EOF); - s = cptr; - break; - } - /* fall through */ - - default: - cptr = s; - return (*s); - } - } -} - - -static int -keyword(void) -{ - int c; - char *t_cptr = cptr; - - c = *++cptr; - if (isalpha(c)) - { - cinc = 0; - for (;;) - { - if (isalpha(c)) - { - if (isupper(c)) c = tolower(c); - cachec(c); - } - else if (isdigit(c) || c == '_' || c == '.' || c == '$') - cachec(c); - else - break; - c = *++cptr; - } - cachec(NUL); - - if (strcmp(cache, "token") == 0 || strcmp(cache, "term") == 0) - return (TOKEN); - if (strcmp(cache, "type") == 0) - return (TYPE); - if (strcmp(cache, "left") == 0) - return (LEFT); - if (strcmp(cache, "right") == 0) - return (RIGHT); - if (strcmp(cache, "nonassoc") == 0 || strcmp(cache, "binary") == 0) - return (NONASSOC); - if (strcmp(cache, "start") == 0) - return (START); - if (strcmp(cache, "union") == 0) - return (UNION); - if (strcmp(cache, "ident") == 0) - return (IDENT); - } - else - { - ++cptr; - if (c == '{') - return (TEXT); - if (c == '%' || c == '\\') - return (MARK); - if (c == '<') - return (LEFT); - if (c == '>') - return (RIGHT); - if (c == '0') - return (TOKEN); - if (c == '2') - return (NONASSOC); - } - syntax_error(lineno, line, t_cptr); - /*NOTREACHED*/ -} - - -static void -copy_ident(void) -{ - int c; - FILE *f = output_file; - - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (c != '"') syntax_error(lineno, line, cptr); - ++outline; - fprintf(f, "#ident \""); - for (;;) - { - c = *++cptr; - if (c == '\n') - { - fprintf(f, "\"\n"); - return; - } - putc(c, f); - if (c == '"') - { - putc('\n', f); - ++cptr; - return; - } - } -} - - -static void -copy_text(void) -{ - int c; - int quote; - FILE *f = text_file; - int need_newline = 0; - int t_lineno = lineno; - char *t_line = dup_line(); - char *t_cptr = t_line + (cptr - line - 2); - - if (*cptr == '\n') - { - get_line(); - if (line == 0) - unterminated_text(t_lineno, t_line, t_cptr); - } - if (!lflag) fprintf(f, line_format, lineno, input_file_name); - -loop: - c = *cptr++; - switch (c) - { - case '\n': - next_line: - putc('\n', f); - need_newline = 0; - get_line(); - if (line) goto loop; - unterminated_text(t_lineno, t_line, t_cptr); - - case '\'': - case '"': - { - int s_lineno = lineno; - char *s_line = dup_line(); - char *s_cptr = s_line + (cptr - line - 1); - - quote = c; - putc(c, f); - for (;;) - { - c = *cptr++; - putc(c, f); - if (c == quote) - { - need_newline = 1; - FREE(s_line); - goto loop; - } - if (c == '\n') - unterminated_string(s_lineno, s_line, s_cptr); - if (c == '\\') - { - c = *cptr++; - putc(c, f); - if (c == '\n') - { - get_line(); - if (line == 0) - unterminated_string(s_lineno, s_line, s_cptr); - } - } - } - } - - case '/': - putc(c, f); - need_newline = 1; - c = *cptr; - if (c == '/') - { - putc('*', f); - while ((c = *++cptr) != '\n') - { - if (c == '*' && cptr[1] == '/') - fprintf(f, "* "); - else - putc(c, f); - } - fprintf(f, "*/"); - goto next_line; - } - if (c == '*') - { - int c_lineno = lineno; - char *c_line = dup_line(); - char *c_cptr = c_line + (cptr - line - 1); - - putc('*', f); - ++cptr; - for (;;) - { - c = *cptr++; - putc(c, f); - if (c == '*' && *cptr == '/') - { - putc('/', f); - ++cptr; - FREE(c_line); - goto loop; - } - if (c == '\n') - { - get_line(); - if (line == 0) - unterminated_comment(c_lineno, c_line, c_cptr); - } - } - } - need_newline = 1; - goto loop; - - case '%': - case '\\': - if (*cptr == '}') - { - if (need_newline) putc('\n', f); - ++cptr; - FREE(t_line); - return; - } - /* fall through */ - - default: - putc(c, f); - need_newline = 1; - goto loop; - } -} - - -static void -copy_union(void) -{ - int c; - int quote; - int depth; - int u_lineno = lineno; - char *u_line = dup_line(); - char *u_cptr = u_line + (cptr - line - 6); - - if (unionized) over_unionized(cptr - 6); - unionized = 1; - - if (!lflag) - fprintf(text_file, line_format, lineno, input_file_name); - - fprintf(text_file, "typedef union"); - if (dflag) fprintf(union_file, "typedef union"); - - depth = 0; -loop: - c = *cptr++; - putc(c, text_file); - if (dflag) putc(c, union_file); - switch (c) - { - case '\n': - next_line: - get_line(); - if (line == 0) unterminated_union(u_lineno, u_line, u_cptr); - goto loop; - - case '{': - ++depth; - goto loop; - - case '}': - if (--depth == 0) - { - fprintf(text_file, " YYSTYPE;\n"); - FREE(u_line); - return; - } - goto loop; - - case '\'': - case '"': - { - int s_lineno = lineno; - char *s_line = dup_line(); - char *s_cptr = s_line + (cptr - line - 1); - - quote = c; - for (;;) - { - c = *cptr++; - putc(c, text_file); - if (dflag) putc(c, union_file); - if (c == quote) - { - FREE(s_line); - goto loop; - } - if (c == '\n') - unterminated_string(s_lineno, s_line, s_cptr); - if (c == '\\') - { - c = *cptr++; - putc(c, text_file); - if (dflag) putc(c, union_file); - if (c == '\n') - { - get_line(); - if (line == 0) - unterminated_string(s_lineno, s_line, s_cptr); - } - } - } - } - - case '/': - c = *cptr; - if (c == '/') - { - putc('*', text_file); - if (dflag) putc('*', union_file); - while ((c = *++cptr) != '\n') - { - if (c == '*' && cptr[1] == '/') - { - fprintf(text_file, "* "); - if (dflag) fprintf(union_file, "* "); - } - else - { - putc(c, text_file); - if (dflag) putc(c, union_file); - } - } - fprintf(text_file, "*/\n"); - if (dflag) fprintf(union_file, "*/\n"); - goto next_line; - } - if (c == '*') - { - int c_lineno = lineno; - char *c_line = dup_line(); - char *c_cptr = c_line + (cptr - line - 1); - - putc('*', text_file); - if (dflag) putc('*', union_file); - ++cptr; - for (;;) - { - c = *cptr++; - putc(c, text_file); - if (dflag) putc(c, union_file); - if (c == '*' && *cptr == '/') - { - putc('/', text_file); - if (dflag) putc('/', union_file); - ++cptr; - FREE(c_line); - goto loop; - } - if (c == '\n') - { - get_line(); - if (line == 0) - unterminated_comment(c_lineno, c_line, c_cptr); - } - } - } - goto loop; - - default: - goto loop; - } -} - - -static int -hexval(int c) -{ - if (c >= '0' && c <= '9') - return (c - '0'); - if (c >= 'A' && c <= 'F') - return (c - 'A' + 10); - if (c >= 'a' && c <= 'f') - return (c - 'a' + 10); - return (-1); -} - - -static bucket * -get_literal(void) -{ - int c, quote; - int i; - int n; - char *s; - bucket *bp; - int s_lineno = lineno; - char *s_line = dup_line(); - char *s_cptr = s_line + (cptr - line); - - quote = *cptr++; - cinc = 0; - for (;;) - { - c = *cptr++; - if (c == quote) break; - if (c == '\n') unterminated_string(s_lineno, s_line, s_cptr); - if (c == '\\') - { - char *c_cptr = cptr - 1; - - c = *cptr++; - switch (c) - { - case '\n': - get_line(); - if (line == 0) unterminated_string(s_lineno, s_line, s_cptr); - continue; - - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - n = c - '0'; - c = *cptr; - if (IS_OCTAL(c)) - { - n = (n << 3) + (c - '0'); - c = *++cptr; - if (IS_OCTAL(c)) - { - n = (n << 3) + (c - '0'); - ++cptr; - } - } - if (n > MAXCHAR) illegal_character(c_cptr); - c = n; - break; - - case 'x': - c = *cptr++; - n = hexval(c); - if (n < 0 || n >= 16) - illegal_character(c_cptr); - for (;;) - { - c = *cptr; - i = hexval(c); - if (i < 0 || i >= 16) break; - ++cptr; - n = (n << 4) + i; - if (n > MAXCHAR) illegal_character(c_cptr); - } - c = n; - break; - - case 'a': c = 7; break; - case 'b': c = '\b'; break; - case 'f': c = '\f'; break; - case 'n': c = '\n'; break; - case 'r': c = '\r'; break; - case 't': c = '\t'; break; - case 'v': c = '\v'; break; - } - } - cachec(c); - } - FREE(s_line); - - n = cinc; - s = MALLOC(n); - if (s == 0) no_space(); - - for (i = 0; i < n; ++i) - s[i] = cache[i]; - - cinc = 0; - if (n == 1) - cachec('\''); - else - cachec('"'); - - for (i = 0; i < n; ++i) - { - c = ((unsigned char *)s)[i]; - if (c == '\\' || c == cache[0]) - { - cachec('\\'); - cachec(c); - } - else if (isprint(c)) - cachec(c); - else - { - cachec('\\'); - switch (c) - { - case 7: cachec('a'); break; - case '\b': cachec('b'); break; - case '\f': cachec('f'); break; - case '\n': cachec('n'); break; - case '\r': cachec('r'); break; - case '\t': cachec('t'); break; - case '\v': cachec('v'); break; - default: - cachec(((c >> 6) & 7) + '0'); - cachec(((c >> 3) & 7) + '0'); - cachec((c & 7) + '0'); - break; - } - } - } - - if (n == 1) - cachec('\''); - else - cachec('"'); - - cachec(NUL); - bp = lookup(cache); - bp->class = TERM; - if (n == 1 && bp->value == UNDEFINED) - bp->value = *(unsigned char *)s; - FREE(s); - - return (bp); -} - - -static int -is_reserved(char *name) -{ - char *s; - - if (strcmp(name, ".") == 0 || - strcmp(name, "$accept") == 0 || - strcmp(name, "$end") == 0) - return (1); - - if (name[0] == '$' && name[1] == '$' && isdigit((int) name[2])) - { - s = name + 3; - while (isdigit((int) *s)) ++s; - if (*s == NUL) return (1); - } - - return (0); -} - - -static bucket * -get_name(void) -{ - int c; - - cinc = 0; - for (c = *cptr; IS_IDENT(c); c = *++cptr) - cachec(c); - cachec(NUL); - - if (is_reserved(cache)) used_reserved(cache); - - return (lookup(cache)); -} - - -static int -get_number(void) -{ - int c; - int n; - - n = 0; - for (c = *cptr; isdigit(c); c = *++cptr) - n = 10*n + (c - '0'); - - return (n); -} - - -static char * -get_tag(void) -{ - int c; - int i; - char *s; - int t_lineno = lineno; - char *t_line = dup_line(); - char *t_cptr = t_line + (cptr - line); - - ++cptr; - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (!isalpha(c) && c != '_' && c != '$') - illegal_tag(t_lineno, t_line, t_cptr); - - cinc = 0; - do { cachec(c); c = *++cptr; } while (IS_IDENT(c)); - cachec(NUL); - - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (c != '>') - illegal_tag(t_lineno, t_line, t_cptr); - ++cptr; - - for (i = 0; i < ntags; ++i) - { - if (strcmp(cache, tag_table[i]) == 0) - return (tag_table[i]); - } - - if (ntags >= tagmax) - { - tagmax += 16; - tag_table = (char **) - (tag_table ? REALLOC(tag_table, tagmax*sizeof(char *)) - : MALLOC(tagmax*sizeof(char *))); - if (tag_table == 0) no_space(); - } - - s = MALLOC(cinc); - if (s == 0) no_space(); - strcpy(s, cache); - tag_table[ntags] = s; - ++ntags; - FREE(t_line); - return (s); -} - - -static void -declare_tokens(int assoc) -{ - int c; - bucket *bp; - int value; - char *tag = 0; - - if (assoc != TOKEN) ++prec; - - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (c == '<') - { - tag = get_tag(); - c = nextc(); - if (c == EOF) unexpected_EOF(); - } - - for (;;) - { - if (isalpha(c) || c == '_' || c == '.' || c == '$') - bp = get_name(); - else if (c == '\'' || c == '"') - bp = get_literal(); - else - return; - - if (bp == goal) tokenized_start(bp->name); - bp->class = TERM; - - if (tag) - { - if (bp->tag && tag != bp->tag) - retyped_warning(bp->name); - bp->tag = tag; - } - - if (assoc != TOKEN) - { - if (bp->prec && prec != bp->prec) - reprec_warning(bp->name); - bp->assoc = assoc; - bp->prec = prec; - } - - c = nextc(); - if (c == EOF) unexpected_EOF(); - value = UNDEFINED; - if (isdigit(c)) - { - value = get_number(); - if (bp->value != UNDEFINED && value != bp->value) - revalued_warning(bp->name); - bp->value = value; - c = nextc(); - if (c == EOF) unexpected_EOF(); - } - } -} - - -static void -declare_types(void) -{ - int c; - bucket *bp; - char *tag; - - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (c != '<') syntax_error(lineno, line, cptr); - tag = get_tag(); - - for (;;) - { - c = nextc(); - if (isalpha(c) || c == '_' || c == '.' || c == '$') - bp = get_name(); - else if (c == '\'' || c == '"') - bp = get_literal(); - else - return; - - if (bp->tag && tag != bp->tag) - retyped_warning(bp->name); - bp->tag = tag; - } -} - - -static void -declare_start(void) -{ - int c; - bucket *bp; - - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (!isalpha(c) && c != '_' && c != '.' && c != '$') - syntax_error(lineno, line, cptr); - bp = get_name(); - if (bp->class == TERM) - terminal_start(bp->name); - if (goal && goal != bp) - restarted_warning(); - goal = bp; -} - - -static void -read_declarations(void) -{ - int c, k; - - cache_size = 256; - cache = MALLOC(cache_size); - if (cache == 0) no_space(); - - for (;;) - { - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (c != '%') syntax_error(lineno, line, cptr); - switch (k = keyword()) - { - case MARK: - return; - - case IDENT: - copy_ident(); - break; - - case TEXT: - copy_text(); - break; - - case UNION: - copy_union(); - break; - - case TOKEN: - case LEFT: - case RIGHT: - case NONASSOC: - declare_tokens(k); - break; - - case TYPE: - declare_types(); - break; - - case START: - declare_start(); - break; - } - } -} - - -static void -initialize_grammar(void) -{ - nitems = 4; - maxitems = 300; - pitem = (bucket **) MALLOC(maxitems*sizeof(bucket *)); - if (pitem == 0) no_space(); - pitem[0] = 0; - pitem[1] = 0; - pitem[2] = 0; - pitem[3] = 0; - - nrules = 3; - maxrules = 100; - plhs = (bucket **) MALLOC(maxrules*sizeof(bucket *)); - if (plhs == 0) no_space(); - plhs[0] = 0; - plhs[1] = 0; - plhs[2] = 0; - rprec = (short *) MALLOC(maxrules*sizeof(short)); - if (rprec == 0) no_space(); - rprec[0] = 0; - rprec[1] = 0; - rprec[2] = 0; - rassoc = (char *) MALLOC(maxrules*sizeof(char)); - if (rassoc == 0) no_space(); - rassoc[0] = TOKEN; - rassoc[1] = TOKEN; - rassoc[2] = TOKEN; -} - - -static void -expand_items(void) -{ - maxitems += 300; - pitem = (bucket **) REALLOC(pitem, maxitems*sizeof(bucket *)); - if (pitem == 0) no_space(); -} - - -static void -expand_rules(void) -{ - maxrules += 100; - plhs = (bucket **) REALLOC(plhs, maxrules*sizeof(bucket *)); - if (plhs == 0) no_space(); - rprec = (short *) REALLOC(rprec, maxrules*sizeof(short)); - if (rprec == 0) no_space(); - rassoc = (char *) REALLOC(rassoc, maxrules*sizeof(char)); - if (rassoc == 0) no_space(); -} - - -static void -advance_to_start(void) -{ - int c; - bucket *bp; - char *s_cptr; - int s_lineno; - - for (;;) - { - c = nextc(); - if (c != '%') break; - s_cptr = cptr; - switch (keyword()) - { - case MARK: - no_grammar(); - - case TEXT: - copy_text(); - break; - - case START: - declare_start(); - break; - - default: - syntax_error(lineno, line, s_cptr); - } - } - - c = nextc(); - if (!isalpha(c) && c != '_' && c != '.' && c != '_') - syntax_error(lineno, line, cptr); - bp = get_name(); - if (goal == 0) - { - if (bp->class == TERM) - terminal_start(bp->name); - goal = bp; - } - - s_lineno = lineno; - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (c != ':') syntax_error(lineno, line, cptr); - start_rule(bp, s_lineno); - ++cptr; -} - - -static void -start_rule(bucket *bp, int s_lineno) -{ - if (bp->class == TERM) - terminal_lhs(s_lineno); - bp->class = NONTERM; - if (nrules >= maxrules) - expand_rules(); - plhs[nrules] = bp; - rprec[nrules] = UNDEFINED; - rassoc[nrules] = TOKEN; -} - - -static void -end_rule(void) -{ - int i; - - if (!last_was_action && plhs[nrules]->tag) - { - for (i = nitems - 1; pitem[i]; --i) continue; - if (pitem[i+1] == 0 || pitem[i+1]->tag != plhs[nrules]->tag) - default_action_warning(); - } - - last_was_action = 0; - if (nitems >= maxitems) expand_items(); - pitem[nitems] = 0; - ++nitems; - ++nrules; -} - - -static void -insert_empty_rule(void) -{ - bucket *bp, **bpp; - - assert(cache); - sprintf(cache, "$$%d", ++gensym); - bp = make_bucket(cache); - last_symbol->next = bp; - last_symbol = bp; - bp->tag = plhs[nrules]->tag; - bp->class = NONTERM; - - if ((nitems += 2) > maxitems) - expand_items(); - bpp = pitem + nitems - 1; - *bpp-- = bp; - while ((bpp[0] = bpp[-1])) --bpp; - - if (++nrules >= maxrules) - expand_rules(); - plhs[nrules] = plhs[nrules-1]; - plhs[nrules-1] = bp; - rprec[nrules] = rprec[nrules-1]; - rprec[nrules-1] = 0; - rassoc[nrules] = rassoc[nrules-1]; - rassoc[nrules-1] = TOKEN; -} - - -static void -add_symbol(void) -{ - int c; - bucket *bp; - int s_lineno = lineno; - - c = *cptr; - if (c == '\'' || c == '"') - bp = get_literal(); - else - bp = get_name(); - - c = nextc(); - if (c == ':') - { - end_rule(); - start_rule(bp, s_lineno); - ++cptr; - return; - } - - if (last_was_action) - insert_empty_rule(); - last_was_action = 0; - - if (++nitems > maxitems) - expand_items(); - pitem[nitems-1] = bp; -} - - -static void -copy_action(void) -{ - int c; - int i, n; - int depth; - int quote; - char *tag; - FILE *f = action_file; - int a_lineno = lineno; - char *a_line = dup_line(); - char *a_cptr = a_line + (cptr - line); - - if (last_was_action) - insert_empty_rule(); - last_was_action = 1; - - fprintf(f, "case %d:\n", nrules - 2); - if (!lflag) - fprintf(f, line_format, lineno, input_file_name); - if (*cptr == '=') ++cptr; - - n = 0; - for (i = nitems - 1; pitem[i]; --i) ++n; - - depth = 0; -loop: - c = *cptr; - if (c == '$') - { - if (cptr[1] == '<') - { - int d_lineno = lineno; - char *d_line = dup_line(); - char *d_cptr = d_line + (cptr - line); - - ++cptr; - tag = get_tag(); - c = *cptr; - if (c == '$') - { - fprintf(f, "yyval.%s", tag); - ++cptr; - FREE(d_line); - goto loop; - } - else if (isdigit(c)) - { - i = get_number(); - if (i > n) dollar_warning(d_lineno, i); - fprintf(f, "yyvsp[%d].%s", i - n, tag); - FREE(d_line); - goto loop; - } - else if (c == '-' && isdigit((int) cptr[1])) - { - ++cptr; - i = -get_number() - n; - fprintf(f, "yyvsp[%d].%s", i, tag); - FREE(d_line); - goto loop; - } - else - dollar_error(d_lineno, d_line, d_cptr); - } - else if (cptr[1] == '$') - { - if (ntags) - { - tag = plhs[nrules]->tag; - if (tag == 0) untyped_lhs(); - fprintf(f, "yyval.%s", tag); - } - else - fprintf(f, "yyval"); - cptr += 2; - goto loop; - } - else if (isdigit((int) cptr[1])) - { - ++cptr; - i = get_number(); - if (ntags) - { - if (i <= 0 || i > n) - unknown_rhs(i); - tag = pitem[nitems + i - n - 1]->tag; - if (tag == 0) untyped_rhs(i, pitem[nitems + i - n - 1]->name); - fprintf(f, "yyvsp[%d].%s", i - n, tag); - } - else - { - if (i > n) - dollar_warning(lineno, i); - fprintf(f, "yyvsp[%d]", i - n); - } - goto loop; - } - else if (cptr[1] == '-') - { - cptr += 2; - i = get_number(); - if (ntags) - unknown_rhs(-i); - fprintf(f, "yyvsp[%d]", -i - n); - goto loop; - } - } - if (isalpha(c) || c == '_' || c == '$') - { - do - { - putc(c, f); - c = *++cptr; - } while (isalnum(c) || c == '_' || c == '$'); - goto loop; - } - putc(c, f); - ++cptr; - switch (c) - { - case '\n': - next_line: - get_line(); - if (line) goto loop; - unterminated_action(a_lineno, a_line, a_cptr); - - case ';': - if (depth > 0) goto loop; - fprintf(f, "\nbreak;\n"); - FREE(a_line); - return; - - case '{': - ++depth; - goto loop; - - case '}': - if (--depth > 0) goto loop; - fprintf(f, "\nbreak;\n"); - FREE(a_line); - return; - - case '\'': - case '"': - { - int s_lineno = lineno; - char *s_line = dup_line(); - char *s_cptr = s_line + (cptr - line - 1); - - quote = c; - for (;;) - { - c = *cptr++; - putc(c, f); - if (c == quote) - { - FREE(s_line); - goto loop; - } - if (c == '\n') - unterminated_string(s_lineno, s_line, s_cptr); - if (c == '\\') - { - c = *cptr++; - putc(c, f); - if (c == '\n') - { - get_line(); - if (line == 0) - unterminated_string(s_lineno, s_line, s_cptr); - } - } - } - } - - case '/': - c = *cptr; - if (c == '/') - { - putc('*', f); - while ((c = *++cptr) != '\n') - { - if (c == '*' && cptr[1] == '/') - fprintf(f, "* "); - else - putc(c, f); - } - fprintf(f, "*/\n"); - goto next_line; - } - if (c == '*') - { - int c_lineno = lineno; - char *c_line = dup_line(); - char *c_cptr = c_line + (cptr - line - 1); - - putc('*', f); - ++cptr; - for (;;) - { - c = *cptr++; - putc(c, f); - if (c == '*' && *cptr == '/') - { - putc('/', f); - ++cptr; - FREE(c_line); - goto loop; - } - if (c == '\n') - { - get_line(); - if (line == 0) - unterminated_comment(c_lineno, c_line, c_cptr); - } - } - } - goto loop; - - default: - goto loop; - } -} - - -static int -mark_symbol(void) -{ - int c; - bucket *bp; - - c = cptr[1]; - if (c == '%' || c == '\\') - { - cptr += 2; - return (1); - } - - if (c == '=') - cptr += 2; - else if ((c == 'p' || c == 'P') && - ((c = cptr[2]) == 'r' || c == 'R') && - ((c = cptr[3]) == 'e' || c == 'E') && - ((c = cptr[4]) == 'c' || c == 'C') && - ((c = cptr[5], !IS_IDENT(c)))) - cptr += 5; - else - syntax_error(lineno, line, cptr); - - c = nextc(); - if (isalpha(c) || c == '_' || c == '.' || c == '$') - bp = get_name(); - else if (c == '\'' || c == '"') - bp = get_literal(); - else - { - syntax_error(lineno, line, cptr); - /*NOTREACHED*/ - } - - if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules]) - prec_redeclared(); - - rprec[nrules] = bp->prec; - rassoc[nrules] = bp->assoc; - return (0); -} - - -static void -read_grammar(void) -{ - int c; - - initialize_grammar(); - advance_to_start(); - - for (;;) - { - c = nextc(); - if (c == EOF) break; - if (isalpha(c) || c == '_' || c == '.' || c == '$' || c == '\'' || - c == '"') - add_symbol(); - else if (c == '{' || c == '=') - copy_action(); - else if (c == '|') - { - end_rule(); - start_rule(plhs[nrules-1], 0); - ++cptr; - } - else if (c == '%') - { - if (mark_symbol()) break; - } - else - syntax_error(lineno, line, cptr); - } - end_rule(); -} - - -static void -free_tags(void) -{ - int i; - - if (tag_table == 0) return; - - for (i = 0; i < ntags; ++i) - { - assert(tag_table[i]); - FREE(tag_table[i]); - } - FREE(tag_table); -} - - -static void -pack_names(void) -{ - bucket *bp; - char *p, *s, *t; - - name_pool_size = 13; /* 13 == sizeof("$end") + sizeof("$accept") */ - for (bp = first_symbol; bp; bp = bp->next) - name_pool_size += strlen(bp->name) + 1; - name_pool = MALLOC(name_pool_size); - if (name_pool == 0) no_space(); - - strcpy(name_pool, "$accept"); - strcpy(name_pool+8, "$end"); - t = name_pool + 13; - for (bp = first_symbol; bp; bp = bp->next) - { - p = t; - s = bp->name; - while ((*t++ = *s++)) continue; - FREE(bp->name); - bp->name = p; - } -} - - -static void -check_symbols(void) -{ - bucket *bp; - - if (goal->class == UNKNOWN) - undefined_goal(goal->name); - - for (bp = first_symbol; bp; bp = bp->next) - { - if (bp->class == UNKNOWN) - { - undefined_symbol_warning(bp->name); - bp->class = TERM; - } - } -} - - -static void -pack_symbols(void) -{ - bucket *bp; - bucket **v; - int i, j, k, n; - - nsyms = 2; - ntokens = 1; - for (bp = first_symbol; bp; bp = bp->next) - { - ++nsyms; - if (bp->class == TERM) ++ntokens; - } - start_symbol = ntokens; - nvars = nsyms - ntokens; - - symbol_name = (char **) MALLOC(nsyms*sizeof(char *)); - if (symbol_name == 0) no_space(); - symbol_value = (short *) MALLOC(nsyms*sizeof(short)); - if (symbol_value == 0) no_space(); - symbol_prec = (short *) MALLOC(nsyms*sizeof(short)); - if (symbol_prec == 0) no_space(); - symbol_assoc = MALLOC(nsyms); - if (symbol_assoc == 0) no_space(); - - v = (bucket **) MALLOC(nsyms*sizeof(bucket *)); - if (v == 0) no_space(); - - v[0] = 0; - v[start_symbol] = 0; - - i = 1; - j = start_symbol + 1; - for (bp = first_symbol; bp; bp = bp->next) - { - if (bp->class == TERM) - v[i++] = bp; - else - v[j++] = bp; - } - assert(i == ntokens && j == nsyms); - - for (i = 1; i < ntokens; ++i) - v[i]->index = i; - - goal->index = start_symbol + 1; - k = start_symbol + 2; - while (++i < nsyms) - if (v[i] != goal) - { - v[i]->index = k; - ++k; - } - - goal->value = 0; - k = 1; - for (i = start_symbol + 1; i < nsyms; ++i) - { - if (v[i] != goal) - { - v[i]->value = k; - ++k; - } - } - - k = 0; - for (i = 1; i < ntokens; ++i) - { - n = v[i]->value; - if (n > 256) - { - for (j = k++; j > 0 && symbol_value[j-1] > n; --j) - symbol_value[j] = symbol_value[j-1]; - symbol_value[j] = n; - } - } - - if (v[1]->value == UNDEFINED) - v[1]->value = 256; - - j = 0; - n = 257; - for (i = 2; i < ntokens; ++i) - { - if (v[i]->value == UNDEFINED) - { - while (j < k && n == symbol_value[j]) - { - while (++j < k && n == symbol_value[j]) continue; - ++n; - } - v[i]->value = n; - ++n; - } - } - - symbol_name[0] = name_pool + 8; - symbol_value[0] = 0; - symbol_prec[0] = 0; - symbol_assoc[0] = TOKEN; - for (i = 1; i < ntokens; ++i) - { - symbol_name[i] = v[i]->name; - symbol_value[i] = v[i]->value; - symbol_prec[i] = v[i]->prec; - symbol_assoc[i] = v[i]->assoc; - } - symbol_name[start_symbol] = name_pool; - symbol_value[start_symbol] = -1; - symbol_prec[start_symbol] = 0; - symbol_assoc[start_symbol] = TOKEN; - for (++i; i < nsyms; ++i) - { - k = v[i]->index; - symbol_name[k] = v[i]->name; - symbol_value[k] = v[i]->value; - symbol_prec[k] = v[i]->prec; - symbol_assoc[k] = v[i]->assoc; - } - - FREE(v); -} - - -static void -pack_grammar(void) -{ - int i, j; - int assoc, prec; - - ritem = (short *) MALLOC(nitems*sizeof(short)); - if (ritem == 0) no_space(); - rlhs = (short *) MALLOC(nrules*sizeof(short)); - if (rlhs == 0) no_space(); - rrhs = (short *) MALLOC((nrules+1)*sizeof(short)); - if (rrhs == 0) no_space(); - rprec = (short *) REALLOC(rprec, nrules*sizeof(short)); - if (rprec == 0) no_space(); - rassoc = REALLOC(rassoc, nrules); - if (rassoc == 0) no_space(); - - ritem[0] = -1; - ritem[1] = goal->index; - ritem[2] = 0; - ritem[3] = -2; - rlhs[0] = 0; - rlhs[1] = 0; - rlhs[2] = start_symbol; - rrhs[0] = 0; - rrhs[1] = 0; - rrhs[2] = 1; - - j = 4; - for (i = 3; i < nrules; ++i) - { - rlhs[i] = plhs[i]->index; - rrhs[i] = j; - assoc = TOKEN; - prec = 0; - while (pitem[j]) - { - ritem[j] = pitem[j]->index; - if (pitem[j]->class == TERM) - { - prec = pitem[j]->prec; - assoc = pitem[j]->assoc; - } - ++j; - } - ritem[j] = -i; - ++j; - if (rprec[i] == UNDEFINED) - { - rprec[i] = prec; - rassoc[i] = assoc; - } - } - rrhs[i] = j; - - FREE(plhs); - FREE(pitem); -} - - -static void -print_grammar(void) -{ - int i, j, k; - int spacing = 0; - FILE *f = verbose_file; - - if (!vflag) return; - - k = 1; - for (i = 2; i < nrules; ++i) - { - if (rlhs[i] != rlhs[i-1]) - { - if (i != 2) fprintf(f, "\n"); - fprintf(f, "%4d %s :", i - 2, symbol_name[rlhs[i]]); - spacing = strlen(symbol_name[rlhs[i]]) + 1; - } - else - { - fprintf(f, "%4d ", i - 2); - j = spacing; - while (--j >= 0) putc(' ', f); - putc('|', f); - } - - while (ritem[k] >= 0) - { - fprintf(f, " %s", symbol_name[ritem[k]]); - ++k; - } - ++k; - putc('\n', f); - } -} - - -void -reader(void) -{ - write_section(banner); - create_symbol_table(); - read_declarations(); - read_grammar(); - free_symbol_table(); - free_tags(); - pack_names(); - check_symbols(); - pack_symbols(); - pack_grammar(); - free_symbols(); - print_grammar(); -} diff --git a/src/libCom/yacc/skeleton.c b/src/libCom/yacc/skeleton.c deleted file mode 100644 index ab683c666..000000000 --- a/src/libCom/yacc/skeleton.c +++ /dev/null @@ -1,302 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include "defs.h" - -/* If the skeleton is changed, the banner should be changed so that */ -/* the altered version can be easily distinguished from the original. */ -/* */ -/* The #defines included with the banner are there because they are */ -/* useful in subsequent code. The macros #defined in the header or */ -/* the body either are not useful outside of semantic actions or */ -/* are conditional. */ - -char *banner[] = -{ - "#define YYBYACC 1", - "#define YYMAJOR 1", - "#define YYMINOR 9", - "#define yyclearin (yychar=(-1))", - "#define yyerrok (yyerrflag=0)", - "#define YYRECOVERING (yyerrflag!=0)", - "static int yyparse(void);",/* JRW */ - 0 -}; - - -char *tables[] = -{ - "static short yylhs[];", /* JRW */ - "static short yylen[];", /* JRW */ - "static short yydefred[];", /* JRW */ - "static short yydgoto[];", /* JRW */ - "static short yysindex[];", /* JRW */ - "static short yyrindex[];", /* JRW */ - "static short yygindex[];", /* JRW */ - "static short yytable[];", /* JRW */ - "static short yycheck[];", /* JRW */ - "#if YYDEBUG", - "static char *yyname[];", /* JRW */ - "static char *yyrule[];", /* JRW */ - "#endif", - 0 -}; - - -char *header[] = -{ - "#ifdef YYSTACKSIZE", - "#undef YYMAXDEPTH", - "#define YYMAXDEPTH YYSTACKSIZE", - "#else", - "#ifdef YYMAXDEPTH", - "#define YYSTACKSIZE YYMAXDEPTH", - "#else", - "#define YYSTACKSIZE 500", - "#define YYMAXDEPTH 500", - "#endif", - "#endif", - "#if YYDEBUG", /* MRK */ - "static int yydebug;", /* JRW */ - "#endif", /* MRK */ - "static int yynerrs;", /* JRW */ - "static int yyerrflag;", /* JRW */ - "static int yychar;", /* JRW */ - "static short *yyssp;", /* JRW */ - "static YYSTYPE *yyvsp;", /* JRW */ - "static YYSTYPE yyval;", /* JRW */ - "static YYSTYPE yylval;", /* JRW */ - "static short yyss[YYSTACKSIZE];", /* JRW */ - "static YYSTYPE yyvs[YYSTACKSIZE];", /* JRW */ - "#define yystacksize YYSTACKSIZE", - 0 -}; - - -char *body[] = -{ - "#define YYABORT goto yyabort", - "#define YYREJECT goto yyabort", - "#define YYACCEPT goto yyaccept", - "#define YYERROR goto yyerrlab", - "static int", /* JRW */ - "yyparse(void)", /* JRW */ - "{", - " int yym, yyn, yystate;", - "#if YYDEBUG", - " char *yys;", - " extern char *getenv();", - "", - " if ((yys = getenv(\"YYDEBUG\")))", - " {", - " yyn = *yys;", - " if (yyn >= '0' && yyn <= '9')", - " yydebug = yyn - '0';", - " }", - "#endif", - "", - " yynerrs = 0;", - " yyerrflag = 0;", - " yychar = (-1);", - "", - " yyssp = yyss;", - " yyvsp = yyvs;", - " *yyssp = yystate = 0;", - "", - "yyloop:", - " if ((yyn = yydefred[yystate])) goto yyreduce;", - " if (yychar < 0)", - " {", - " if ((yychar = yylex()) < 0) yychar = 0;", - "#if YYDEBUG", - " if (yydebug)", - " {", - " yys = 0;", - " if (yychar <= YYMAXTOKEN) yys = yyname[yychar];", - " if (!yys) yys = \"illegal-symbol\";", - " printf(\"%sdebug: state %d, reading %d (%s)\\n\",", - " YYPREFIX, yystate, yychar, yys);", - " }", - "#endif", - " }", - " if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&", - " yyn <= YYTABLESIZE && yycheck[yyn] == yychar)", - " {", - "#if YYDEBUG", - " if (yydebug)", - " printf(\"%sdebug: state %d, shifting to state %d\\n\",", - " YYPREFIX, yystate, yytable[yyn]);", - "#endif", - " if (yyssp >= yyss + yystacksize - 1)", - " {", - " goto yyoverflow;", - " }", - " *++yyssp = yystate = yytable[yyn];", - " *++yyvsp = yylval;", - " yychar = (-1);", - " if (yyerrflag > 0) --yyerrflag;", - " goto yyloop;", - " }", - " if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&", - " yyn <= YYTABLESIZE && yycheck[yyn] == yychar)", - " {", - " yyn = yytable[yyn];", - " goto yyreduce;", - " }", - " if (yyerrflag) goto yyinrecovery;", - " yyerror(\"syntax error\");", - " ++yynerrs;", - "yyinrecovery:", - " if (yyerrflag < 3)", - " {", - " yyerrflag = 3;", - " for (;;)", - " {", - " if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&", - " yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)", - " {", - "#if YYDEBUG", - " if (yydebug)", - " printf(\"%sdebug: state %d, error recovery shifting\\", - " to state %d\\n\", YYPREFIX, *yyssp, yytable[yyn]);", - "#endif", - " if (yyssp >= yyss + yystacksize - 1)", - " {", - " goto yyoverflow;", - " }", - " *++yyssp = yystate = yytable[yyn];", - " *++yyvsp = yylval;", - " goto yyloop;", - " }", - " else", - " {", - "#if YYDEBUG", - " if (yydebug)", - " printf(\"%sdebug: error recovery discarding state %d\ -\\n\",", - " YYPREFIX, *yyssp);", - "#endif", - " if (yyssp <= yyss) goto yyabort;", - " --yyssp;", - " --yyvsp;", - " }", - " }", - " }", - " else", - " {", - " if (yychar == 0) goto yyabort;", - "#if YYDEBUG", - " if (yydebug)", - " {", - " yys = 0;", - " if (yychar <= YYMAXTOKEN) yys = yyname[yychar];", - " if (!yys) yys = \"illegal-symbol\";", - " printf(\"%sdebug: state %d, error recovery discards token %d\ - (%s)\\n\",", - " YYPREFIX, yystate, yychar, yys);", - " }", - "#endif", - " yychar = (-1);", - " goto yyloop;", - " }", - "yyreduce:", - "#if YYDEBUG", - " if (yydebug)", - " printf(\"%sdebug: state %d, reducing by rule %d (%s)\\n\",", - " YYPREFIX, yystate, yyn, yyrule[yyn]);", - "#endif", - " yym = yylen[yyn];", - " yyval = yyvsp[1-yym];", - " switch (yyn)", - " {", - 0 -}; - - -char *trailer[] = -{ - " }", - " yyssp -= yym;", - " yystate = *yyssp;", - " yyvsp -= yym;", - " yym = yylhs[yyn];", - " if (yystate == 0 && yym == 0)", - " {", - "#if YYDEBUG", - " if (yydebug)", - " printf(\"%sdebug: after reduction, shifting from state 0 to\\", - " state %d\\n\", YYPREFIX, YYFINAL);", - "#endif", - " yystate = YYFINAL;", - " *++yyssp = YYFINAL;", - " *++yyvsp = yyval;", - " if (yychar < 0)", - " {", - " if ((yychar = yylex()) < 0) yychar = 0;", - "#if YYDEBUG", - " if (yydebug)", - " {", - " yys = 0;", - " if (yychar <= YYMAXTOKEN) yys = yyname[yychar];", - " if (!yys) yys = \"illegal-symbol\";", - " printf(\"%sdebug: state %d, reading %d (%s)\\n\",", - " YYPREFIX, YYFINAL, yychar, yys);", - " }", - "#endif", - " }", - " if (yychar == 0) goto yyaccept;", - " goto yyloop;", - " }", - " if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&", - " yyn <= YYTABLESIZE && yycheck[yyn] == yystate)", - " yystate = yytable[yyn];", - " else", - " yystate = yydgoto[yym];", - "#if YYDEBUG", - " if (yydebug)", - " printf(\"%sdebug: after reduction, shifting from state %d \\", - "to state %d\\n\", YYPREFIX, *yyssp, yystate);", - "#endif", - " if (yyssp >= yyss + yystacksize - 1)", - " {", - " goto yyoverflow;", - " }", - " *++yyssp = yystate;", - " *++yyvsp = yyval;", - " goto yyloop;", - "yyoverflow:", - " yyerror(\"yacc stack overflow\");", - "yyabort:", - " return (1);", - "yyaccept:", - " return (0);", - "}", - 0 -}; - - -void -write_section(char *section[]) -{ - int c; - int i; - char *s; - FILE *f; - - f = code_file; - for (i = 0; (s = section[i]); ++i) - { - ++outline; - while ((c = *s)) - { - putc(c, f); - ++s; - } - putc('\n', f); - } -} diff --git a/src/libCom/yacc/symtab.c b/src/libCom/yacc/symtab.c deleted file mode 100644 index 486835a21..000000000 --- a/src/libCom/yacc/symtab.c +++ /dev/null @@ -1,126 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include "defs.h" - - -/* TABLE_SIZE is the number of entries in the symbol table. */ -/* TABLE_SIZE must be a power of two. */ - -#define TABLE_SIZE 1024 - - -bucket **symbol_table; -bucket *first_symbol; -bucket *last_symbol; - - -static int -hash(char *name) -{ - char *s; - int c, k; - - assert(name && *name); - s = name; - k = *s; - while ((c = *++s)) - k = (31*k + c) & (TABLE_SIZE - 1); - - return (k); -} - - -bucket * -make_bucket(char *name) -{ - bucket *bp; - - assert(name); - bp = (bucket *) MALLOC(sizeof(bucket)); - if (bp == 0) no_space(); - bp->link = 0; - bp->next = 0; - bp->name = MALLOC(strlen(name) + 1); - if (bp->name == 0) no_space(); - bp->tag = 0; - bp->value = UNDEFINED; - bp->index = 0; - bp->prec = 0; - bp-> class = UNKNOWN; - bp->assoc = TOKEN; - - if (bp->name == 0) no_space(); - strcpy(bp->name, name); - - return (bp); -} - - -bucket * -lookup(char *name) -{ - bucket *bp, **bpp; - - bpp = symbol_table + hash(name); - bp = *bpp; - - while (bp) - { - if (strcmp(name, bp->name) == 0) return (bp); - bpp = &bp->link; - bp = *bpp; - } - - *bpp = bp = make_bucket(name); - last_symbol->next = bp; - last_symbol = bp; - - return (bp); -} - -void -create_symbol_table(void) -{ - int i; - bucket *bp; - - symbol_table = (bucket **) MALLOC(TABLE_SIZE*sizeof(bucket *)); - if (symbol_table == 0) no_space(); - for (i = 0; i < TABLE_SIZE; i++) - symbol_table[i] = 0; - - bp = make_bucket("error"); - bp->index = 1; - bp->class = TERM; - - first_symbol = bp; - last_symbol = bp; - symbol_table[hash("error")] = bp; -} - - -void -free_symbol_table(void) -{ - FREE(symbol_table); - symbol_table = 0; -} - - -void -free_symbols(void) -{ - bucket *p, *q; - - for (p = first_symbol; p; p = q) - { - q = p->next; - FREE(p); - } -} diff --git a/src/libCom/yacc/verbose.c b/src/libCom/yacc/verbose.c deleted file mode 100644 index eb03cf386..000000000 --- a/src/libCom/yacc/verbose.c +++ /dev/null @@ -1,349 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "defs.h" - -static short *null_rules; - -static void log_unused(void); -static void log_conflicts(void); -static void print_state(int state); -static void print_conflicts(int state); -static void print_core(int state); -static void print_nulls(int state); -static void print_actions(int state); -static void print_shifts(action *p); -static void print_reductions(action *p, int defred); -static void print_gotos(int stateno); - - -void -verbose(void) -{ - int i; - - if (!vflag) return; - - null_rules = (short *) MALLOC(nrules*sizeof(short)); - if (null_rules == 0) no_space(); - fprintf(verbose_file, "\f\n"); - for (i = 0; i < nstates; i++) - print_state(i); - FREE(null_rules); - - if (nunused) - log_unused(); - if (SRtotal || RRtotal) - log_conflicts(); - - fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens, nvars); - fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates); -} - - -static void -log_unused(void) -{ - int i; - short *p; - - fprintf(verbose_file, "\n\nRules never reduced:\n"); - for (i = 3; i < nrules; ++i) - { - if (!rules_used[i]) - { - fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]); - for (p = ritem + rrhs[i]; *p >= 0; ++p) - fprintf(verbose_file, " %s", symbol_name[*p]); - fprintf(verbose_file, " (%d)\n", i - 2); - } - } -} - - -static void -log_conflicts(void) -{ - int i; - - fprintf(verbose_file, "\n\n"); - for (i = 0; i < nstates; i++) - { - if (SRconflicts[i] || RRconflicts[i]) - { - fprintf(verbose_file, "State %d contains ", i); - if (SRconflicts[i] == 1) - fprintf(verbose_file, "1 shift/reduce conflict"); - else if (SRconflicts[i] > 1) - fprintf(verbose_file, "%d shift/reduce conflicts", - SRconflicts[i]); - if (SRconflicts[i] && RRconflicts[i]) - fprintf(verbose_file, ", "); - if (RRconflicts[i] == 1) - fprintf(verbose_file, "1 reduce/reduce conflict"); - else if (RRconflicts[i] > 1) - fprintf(verbose_file, "%d reduce/reduce conflicts", - RRconflicts[i]); - fprintf(verbose_file, ".\n"); - } - } -} - - -static void -print_state(int state) -{ - if (state) - fprintf(verbose_file, "\n\n"); - if (SRconflicts[state] || RRconflicts[state]) - print_conflicts(state); - fprintf(verbose_file, "state %d\n", state); - print_core(state); - print_nulls(state); - print_actions(state); -} - - -static void -print_conflicts(int state) -{ - int symbol, act = 0, number = 0; - action *p; - - symbol = -1; - for (p = parser[state]; p; p = p->next) - { - if (p->suppressed == 2) - continue; - - if (p->symbol != symbol) - { - symbol = p->symbol; - number = p->number; - if (p->action_code == SHIFT) - act = SHIFT; - else - act = REDUCE; - } - else if (p->suppressed == 1) - { - if (state == final_state && symbol == 0) - { - fprintf(verbose_file, "%d: shift/reduce conflict \ -(accept, reduce %d) on $end\n", state, p->number - 2); - } - else - { - if (act == SHIFT) - { - fprintf(verbose_file, "%d: shift/reduce conflict \ -(shift %d, reduce %d) on %s\n", state, number, p->number - 2, - symbol_name[symbol]); - } - else - { - fprintf(verbose_file, "%d: reduce/reduce conflict \ -(reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2, - symbol_name[symbol]); - } - } - } - } -} - - -static void -print_core(int state) -{ - int i; - int k; - int rule; - core *statep; - short *sp; - short *sp1; - - statep = state_table[state]; - k = statep->nitems; - - for (i = 0; i < k; i++) - { - sp1 = sp = ritem + statep->items[i]; - - while (*sp >= 0) ++sp; - rule = -(*sp); - fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]); - - for (sp = ritem + rrhs[rule]; sp < sp1; sp++) - fprintf(verbose_file, "%s ", symbol_name[*sp]); - - putc('.', verbose_file); - - while (*sp >= 0) - { - fprintf(verbose_file, " %s", symbol_name[*sp]); - sp++; - } - fprintf(verbose_file, " (%d)\n", -2 - *sp); - } -} - - -static void -print_nulls(int state) -{ - action *p; - int i, j, k, nnulls; - - nnulls = 0; - for (p = parser[state]; p; p = p->next) - { - if (p->action_code == REDUCE && - (p->suppressed == 0 || p->suppressed == 1)) - { - i = p->number; - if (rrhs[i] + 1 == rrhs[i+1]) - { - for (j = 0; j < nnulls && i > null_rules[j]; ++j) - continue; - - if (j == nnulls) - { - ++nnulls; - null_rules[j] = i; - } - else if (i != null_rules[j]) - { - ++nnulls; - for (k = nnulls - 1; k > j; --k) - null_rules[k] = null_rules[k-1]; - null_rules[j] = i; - } - } - } - } - - for (i = 0; i < nnulls; ++i) - { - j = null_rules[i]; - fprintf(verbose_file, "\t%s : . (%d)\n", symbol_name[rlhs[j]], - j - 2); - } - fprintf(verbose_file, "\n"); -} - - -static void -print_actions(int stateno) -{ - action *p; - shifts *sp; - int as; - - if (stateno == final_state) - fprintf(verbose_file, "\t$end accept\n"); - - p = parser[stateno]; - if (p) - { - print_shifts(p); - print_reductions(p, defred[stateno]); - } - - sp = shift_table[stateno]; - if (sp && sp->nshifts > 0) - { - as = accessing_symbol[sp->shift[sp->nshifts - 1]]; - if (ISVAR(as)) - print_gotos(stateno); - } -} - - -static void -print_shifts(action *p) -{ - int count; - action *q; - - count = 0; - for (q = p; q; q = q->next) - { - if (q->suppressed < 2 && q->action_code == SHIFT) - ++count; - } - - if (count > 0) - { - for (; p; p = p->next) - { - if (p->action_code == SHIFT && p->suppressed == 0) - fprintf(verbose_file, "\t%s shift %d\n", - symbol_name[p->symbol], p->number); - } - } -} - - -static void -print_reductions(action *p, int defred) -{ - int k, anyreds; - action *q; - - anyreds = 0; - for (q = p; q ; q = q->next) - { - if (q->action_code == REDUCE && q->suppressed < 2) - { - anyreds = 1; - break; - } - } - - if (anyreds == 0) - fprintf(verbose_file, "\t. error\n"); - else - { - for (; p; p = p->next) - { - if (p->action_code == REDUCE && p->number != defred) - { - k = p->number - 2; - if (p->suppressed == 0) - fprintf(verbose_file, "\t%s reduce %d\n", - symbol_name[p->symbol], k); - } - } - - if (defred > 0) - fprintf(verbose_file, "\t. reduce %d\n", defred - 2); - } -} - - -static void -print_gotos(int stateno) -{ - int i, k; - int as; - short *to_state; - shifts *sp; - - putc('\n', verbose_file); - sp = shift_table[stateno]; - to_state = sp->shift; - for (i = 0; i < sp->nshifts; ++i) - { - k = to_state[i]; - as = accessing_symbol[k]; - if (ISVAR(as)) - fprintf(verbose_file, "\t%s goto %d\n", symbol_name[as], k); - } -} - diff --git a/src/libCom/yacc/warshall.c b/src/libCom/yacc/warshall.c deleted file mode 100644 index 4477074c5..000000000 --- a/src/libCom/yacc/warshall.c +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include "defs.h" - -static void -transitive_closure(unsigned int *R, int n) -{ - int rowsize; - unsigned i; - unsigned *rowj; - unsigned *rp; - unsigned *rend; - unsigned *ccol; - unsigned *relend; - unsigned *cword; - unsigned *rowi; - - rowsize = WORDSIZE(n); - relend = R + n*rowsize; - - cword = R; - i = 0; - rowi = R; - while (rowi < relend) - { - ccol = cword; - rowj = R; - - while (rowj < relend) - { - if (*ccol & (1 << i)) - { - rp = rowi; - rend = rowj + rowsize; - while (rowj < rend) - *rowj++ |= *rp++; - } - else - { - rowj += rowsize; - } - - ccol += rowsize; - } - - if (++i >= BITS_PER_WORD) - { - i = 0; - cword++; - } - - rowi += rowsize; - } -} - -void -reflexive_transitive_closure(unsigned int *R, int n) -{ - int rowsize; - unsigned i; - unsigned *rp; - unsigned *relend; - - transitive_closure(R, n); - - rowsize = WORDSIZE(n); - relend = R + n*rowsize; - - i = 0; - rp = R; - while (rp < relend) - { - *rp |= (1 << i); - if (++i >= BITS_PER_WORD) - { - i = 0; - rp++; - } - - rp += rowsize; - } -} diff --git a/src/libCom/yacc/yacc.html b/src/libCom/yacc/yacc.html deleted file mode 100644 index 1258b439f..000000000 --- a/src/libCom/yacc/yacc.html +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - -
-
-
-
-

NAME

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

SYNOPSIS

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

DESCRIPTION

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

FILES

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

DIAGNOSTICS

-     If there are rules that are never  reduced,  the  number  of
-     such  rules is reported on standard error.  If there are any
-     LALR(1) conflicts, the number of conflicts  is  reported  on
-     standard error.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Man(1) output converted with -man2html -
- - diff --git a/src/libCom/yajl/Makefile b/src/libCom/yajl/Makefile deleted file mode 100644 index 39146ca79..000000000 --- a/src/libCom/yajl/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/yacc - -# Yet Another JSON Library -SRC_DIRS += $(LIBCOM)/yajl -INC += yajl_alloc.h -INC += yajl_common.h -INC += yajl_gen.h -INC += yajl_parse.h -# The other yajl_*.h files are for internal use only - -Com_SRCS += yajl.c -Com_SRCS += yajl_alloc.c -Com_SRCS += yajl_buf.c -Com_SRCS += yajl_encode.c -Com_SRCS += yajl_gen.c -Com_SRCS += yajl_lex.c -Com_SRCS += yajl_parser.c diff --git a/src/libCom/yajl/yajl.c b/src/libCom/yajl/yajl.c deleted file mode 100644 index 063e8f8b9..000000000 --- a/src/libCom/yajl/yajl.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "yajl_parse.h" -#include "yajl_lex.h" -#include "yajl_parser.h" -#include "yajl_alloc.h" - -const char * -yajl_status_to_string(yajl_status stat) -{ - const char * statStr = "unknown"; - switch (stat) { - case yajl_status_ok: - statStr = "ok, no error"; - break; - case yajl_status_client_canceled: - statStr = "client canceled parse"; - break; - case yajl_status_insufficient_data: - statStr = "eof was met before the parse could complete"; - break; - case yajl_status_error: - statStr = "parse error"; - break; - } - return statStr; -} - -yajl_handle -yajl_alloc(const yajl_callbacks * callbacks, - const yajl_parser_config * config, - const yajl_alloc_funcs * afs, - void * ctx) -{ - unsigned int allowComments = 0; - unsigned int validateUTF8 = 0; - yajl_handle hand = NULL; - yajl_alloc_funcs afsBuffer; - - /* first order of business is to set up memory allocation routines */ - if (afs != NULL) { - if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL) - { - return NULL; - } - } else { - yajl_set_default_alloc_funcs(&afsBuffer); - afs = &afsBuffer; - } - - hand = (yajl_handle) YA_MALLOC(afs, sizeof(struct yajl_handle_t)); - - /* copy in pointers to allocation routines */ - memcpy((void *) &(hand->alloc), (void *) afs, sizeof(yajl_alloc_funcs)); - - if (config != NULL) { - allowComments = config->allowComments; - validateUTF8 = config->checkUTF8; - } - - hand->callbacks = callbacks; - hand->ctx = ctx; - hand->lexer = yajl_lex_alloc(&(hand->alloc), allowComments, validateUTF8); - hand->bytesConsumed = 0; - hand->decodeBuf = yajl_buf_alloc(&(hand->alloc)); - yajl_bs_init(hand->stateStack, &(hand->alloc)); - - yajl_bs_push(hand->stateStack, yajl_state_start); - - return hand; -} - -void -yajl_free(yajl_handle handle) -{ - yajl_bs_free(handle->stateStack); - yajl_buf_free(handle->decodeBuf); - yajl_lex_free(handle->lexer); - YA_FREE(&(handle->alloc), handle); -} - -yajl_status -yajl_parse(yajl_handle hand, const unsigned char * jsonText, - unsigned int jsonTextLen) -{ - yajl_status status; - status = yajl_do_parse(hand, jsonText, jsonTextLen); - return status; -} - -yajl_status -yajl_parse_complete(yajl_handle hand) -{ - /* The particular case we want to handle is a trailing number. - * Further input consisting of digits could cause our interpretation - * of the number to change (buffered "1" but "2" comes in). - * A very simple approach to this is to inject whitespace to terminate - * any number in the lex buffer. - */ - return yajl_parse(hand, (const unsigned char *)" ", 1); -} - -unsigned char * -yajl_get_error(yajl_handle hand, int verbose, - const unsigned char * jsonText, unsigned int jsonTextLen) -{ - return yajl_render_error_string(hand, jsonText, jsonTextLen, verbose); -} - -unsigned int -yajl_get_bytes_consumed(yajl_handle hand) -{ - if (!hand) return 0; - else return hand->bytesConsumed; -} - - -void -yajl_free_error(yajl_handle hand, unsigned char * str) -{ - /* use memory allocation functions if set */ - YA_FREE(&(hand->alloc), str); -} - -/* XXX: add utility routines to parse from file */ diff --git a/src/libCom/yajl/yajl_alloc.c b/src/libCom/yajl/yajl_alloc.c deleted file mode 100644 index 2f6e5650c..000000000 --- a/src/libCom/yajl/yajl_alloc.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file yajl_alloc.h - * default memory allocation routines for yajl which use malloc/realloc and - * free - */ - -#include - -#define epicsExportSharedSymbols -#include "yajl_alloc.h" - -static void * yajl_internal_malloc(void *ctx, unsigned int sz) -{ - return malloc(sz); -} - -static void * yajl_internal_realloc(void *ctx, void * previous, - unsigned int sz) -{ - return realloc(previous, sz); -} - -static void yajl_internal_free(void *ctx, void * ptr) -{ - free(ptr); -} - -void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf) -{ - yaf->malloc = yajl_internal_malloc; - yaf->free = yajl_internal_free; - yaf->realloc = yajl_internal_realloc; - yaf->ctx = NULL; -} - diff --git a/src/libCom/yajl/yajl_alloc.h b/src/libCom/yajl/yajl_alloc.h deleted file mode 100644 index 3935eef58..000000000 --- a/src/libCom/yajl/yajl_alloc.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file yajl_alloc.h - * default memory allocation routines for yajl which use malloc/realloc and - * free - */ - -#ifndef __YAJL_ALLOC_H__ -#define __YAJL_ALLOC_H__ - -#include "yajl_common.h" - -#define YA_MALLOC(afs, sz) (afs)->malloc((afs)->ctx, (sz)) -#define YA_FREE(afs, ptr) (afs)->free((afs)->ctx, (ptr)) -#define YA_REALLOC(afs, ptr, sz) (afs)->realloc((afs)->ctx, (ptr), (sz)) - -YAJL_API void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf); - -#endif diff --git a/src/libCom/yajl/yajl_buf.c b/src/libCom/yajl/yajl_buf.c deleted file mode 100644 index 132633c9a..000000000 --- a/src/libCom/yajl/yajl_buf.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "yajl_buf.h" - -#define YAJL_BUF_INIT_SIZE 2048 - -struct yajl_buf_t { - unsigned int len; - unsigned int used; - unsigned char * data; - yajl_alloc_funcs * alloc; -}; - -static -void yajl_buf_ensure_available(yajl_buf buf, unsigned int want) -{ - unsigned int need; - - assert(buf != NULL); - - /* first call */ - if (buf->data == NULL) { - buf->len = YAJL_BUF_INIT_SIZE; - buf->data = (unsigned char *) YA_MALLOC(buf->alloc, buf->len); - buf->data[0] = 0; - } - - need = buf->len; - - while (want >= (need - buf->used)) need <<= 1; - - if (need != buf->len) { - buf->data = (unsigned char *) YA_REALLOC(buf->alloc, buf->data, need); - buf->len = need; - } -} - -yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc) -{ - yajl_buf b = YA_MALLOC(alloc, sizeof(struct yajl_buf_t)); - memset((void *) b, 0, sizeof(struct yajl_buf_t)); - b->alloc = alloc; - return b; -} - -void yajl_buf_free(yajl_buf buf) -{ - assert(buf != NULL); - if (buf->data) YA_FREE(buf->alloc, buf->data); - YA_FREE(buf->alloc, buf); -} - -void yajl_buf_append(yajl_buf buf, const void * data, unsigned int len) -{ - yajl_buf_ensure_available(buf, len); - if (len > 0) { - assert(data != NULL); - memcpy(buf->data + buf->used, data, len); - buf->used += len; - buf->data[buf->used] = 0; - } -} - -void yajl_buf_clear(yajl_buf buf) -{ - buf->used = 0; - if (buf->data) buf->data[buf->used] = 0; -} - -const unsigned char * yajl_buf_data(yajl_buf buf) -{ - return buf->data; -} - -unsigned int yajl_buf_len(yajl_buf buf) -{ - return buf->used; -} - -void -yajl_buf_truncate(yajl_buf buf, unsigned int len) -{ - assert(len <= buf->used); - buf->used = len; -} diff --git a/src/libCom/yajl/yajl_buf.h b/src/libCom/yajl/yajl_buf.h deleted file mode 100644 index a6dcbe9a5..000000000 --- a/src/libCom/yajl/yajl_buf.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __YAJL_BUF_H__ -#define __YAJL_BUF_H__ - -#include "yajl_common.h" -#include "yajl_alloc.h" - -/* - * Implementation/performance notes. If this were moved to a header - * only implementation using #define's where possible we might be - * able to sqeeze a little performance out of the guy by killing function - * call overhead. YMMV. - */ - -/** - * yajl_buf is a buffer with exponential growth. the buffer ensures that - * you are always null padded. - */ -typedef struct yajl_buf_t * yajl_buf; - -/* allocate a new buffer */ -yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc); - -/* free the buffer */ -void yajl_buf_free(yajl_buf buf); - -/* append a number of bytes to the buffer */ -void yajl_buf_append(yajl_buf buf, const void * data, unsigned int len); - -/* empty the buffer */ -void yajl_buf_clear(yajl_buf buf); - -/* get a pointer to the beginning of the buffer */ -const unsigned char * yajl_buf_data(yajl_buf buf); - -/* get the length of the buffer */ -unsigned int yajl_buf_len(yajl_buf buf); - -/* truncate the buffer */ -void yajl_buf_truncate(yajl_buf buf, unsigned int len); - -#endif diff --git a/src/libCom/yajl/yajl_bytestack.h b/src/libCom/yajl/yajl_bytestack.h deleted file mode 100644 index 3b49d17f9..000000000 --- a/src/libCom/yajl/yajl_bytestack.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * A header only implementation of a simple stack of bytes, used in YAJL - * to maintain parse state. - */ - -#ifndef __YAJL_BYTESTACK_H__ -#define __YAJL_BYTESTACK_H__ - -#include "yajl_common.h" - -#define YAJL_BS_INC 128 - -typedef struct yajl_bytestack_t -{ - unsigned char * stack; - unsigned int size; - unsigned int used; - yajl_alloc_funcs * yaf; -} yajl_bytestack; - -/* initialize a bytestack */ -#define yajl_bs_init(obs, _yaf) { \ - (obs).stack = NULL; \ - (obs).size = 0; \ - (obs).used = 0; \ - (obs).yaf = (_yaf); \ - } \ - - -/* initialize a bytestack */ -#define yajl_bs_free(obs) \ - if ((obs).stack) (obs).yaf->free((obs).yaf->ctx, (obs).stack); - -#define yajl_bs_current(obs) \ - (assert((obs).used > 0), (obs).stack[(obs).used - 1]) - -#define yajl_bs_push(obs, byte) { \ - if (((obs).size - (obs).used) == 0) { \ - (obs).size += YAJL_BS_INC; \ - (obs).stack = (obs).yaf->realloc((obs).yaf->ctx,\ - (void *) (obs).stack, (obs).size);\ - } \ - (obs).stack[((obs).used)++] = (byte); \ -} - -/* removes the top item of the stack, returns nothing */ -#define yajl_bs_pop(obs) { ((obs).used)--; } - -#define yajl_bs_set(obs, byte) \ - (obs).stack[((obs).used) - 1] = (byte); - - -#endif diff --git a/src/libCom/yajl/yajl_common.h b/src/libCom/yajl/yajl_common.h deleted file mode 100644 index b9badbf1e..000000000 --- a/src/libCom/yajl/yajl_common.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __YAJL_COMMON_H__ -#define __YAJL_COMMON_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define YAJL_MAX_DEPTH 128 - -#define YAJL_API epicsShareFunc - -/** pointer to a malloc function, supporting client overriding memory - * allocation routines */ -typedef void * (*yajl_malloc_func)(void *ctx, unsigned int sz); - -/** pointer to a free function, supporting client overriding memory - * allocation routines */ -typedef void (*yajl_free_func)(void *ctx, void * ptr); - -/** pointer to a realloc function which can resize an allocation. */ -typedef void * (*yajl_realloc_func)(void *ctx, void * ptr, unsigned int sz); - -/** A structure which can be passed to yajl_*_alloc routines to allow the - * client to specify memory allocation functions to be used. */ -typedef struct -{ - /** pointer to a function that can allocate uninitialized memory */ - yajl_malloc_func malloc; - /** pointer to a function that can resize memory allocations */ - yajl_realloc_func realloc; - /** pointer to a function that can free memory allocated using - * reallocFunction or mallocFunction */ - yajl_free_func free; - /** a context pointer that will be passed to above allocation routines */ - void * ctx; -} yajl_alloc_funcs; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/yajl/yajl_encode.c b/src/libCom/yajl/yajl_encode.c deleted file mode 100644 index d6f9dc0fe..000000000 --- a/src/libCom/yajl/yajl_encode.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "yajl_encode.h" - -static void CharToHex(unsigned char c, char * hexBuf) -{ - const char * hexchar = "0123456789ABCDEF"; - hexBuf[0] = hexchar[c >> 4]; - hexBuf[1] = hexchar[c & 0x0F]; -} - -void -yajl_string_encode(yajl_buf buf, const unsigned char * str, - unsigned int len) -{ - yajl_string_encode2((const yajl_print_t) &yajl_buf_append, buf, str, len); -} - -void -yajl_string_encode2(const yajl_print_t print, - void * ctx, - const unsigned char * str, - unsigned int len) -{ - unsigned int beg = 0; - unsigned int end = 0; - char hexBuf[7]; - hexBuf[0] = '\\'; hexBuf[1] = 'u'; hexBuf[2] = '0'; hexBuf[3] = '0'; - hexBuf[6] = 0; - - while (end < len) { - const char * escaped = NULL; - switch (str[end]) { - case '\r': escaped = "\\r"; break; - case '\n': escaped = "\\n"; break; - case '\\': escaped = "\\\\"; break; - /* case '/': escaped = "\\/"; break; */ - case '"': escaped = "\\\""; break; - case '\f': escaped = "\\f"; break; - case '\b': escaped = "\\b"; break; - case '\t': escaped = "\\t"; break; - default: - if ((unsigned char) str[end] < 32) { - CharToHex(str[end], hexBuf + 4); - escaped = hexBuf; - } - break; - } - if (escaped != NULL) { - print(ctx, (const char *) (str + beg), end - beg); - print(ctx, escaped, (unsigned int)strlen(escaped)); - beg = ++end; - } else { - ++end; - } - } - print(ctx, (const char *) (str + beg), end - beg); -} - -static void hexToDigit(unsigned int * val, const unsigned char * hex) -{ - unsigned int i; - for (i=0;i<4;i++) { - unsigned char c = hex[i]; - if (c >= 'A') c = (c & ~0x20) - 7; - c -= '0'; - assert(!(c & 0xF0)); - *val = (*val << 4) | c; - } -} - -static void Utf32toUtf8(unsigned int codepoint, char * utf8Buf) -{ - if (codepoint < 0x80) { - utf8Buf[0] = (char) codepoint; - utf8Buf[1] = 0; - } else if (codepoint < 0x0800) { - utf8Buf[0] = (char) ((codepoint >> 6) | 0xC0); - utf8Buf[1] = (char) ((codepoint & 0x3F) | 0x80); - utf8Buf[2] = 0; - } else if (codepoint < 0x10000) { - utf8Buf[0] = (char) ((codepoint >> 12) | 0xE0); - utf8Buf[1] = (char) (((codepoint >> 6) & 0x3F) | 0x80); - utf8Buf[2] = (char) ((codepoint & 0x3F) | 0x80); - utf8Buf[3] = 0; - } else if (codepoint < 0x200000) { - utf8Buf[0] =(char)((codepoint >> 18) | 0xF0); - utf8Buf[1] =(char)(((codepoint >> 12) & 0x3F) | 0x80); - utf8Buf[2] =(char)(((codepoint >> 6) & 0x3F) | 0x80); - utf8Buf[3] =(char)((codepoint & 0x3F) | 0x80); - utf8Buf[4] = 0; - } else { - utf8Buf[0] = '?'; - utf8Buf[1] = 0; - } -} - -void yajl_string_decode(yajl_buf buf, const unsigned char * str, - unsigned int len) -{ - unsigned int beg = 0; - unsigned int end = 0; - - while (end < len) { - if (str[end] == '\\') { - char utf8Buf[5]; - const char * unescaped = "?"; - yajl_buf_append(buf, str + beg, end - beg); - switch (str[++end]) { - case 'r': unescaped = "\r"; break; - case 'n': unescaped = "\n"; break; - case '\\': unescaped = "\\"; break; - case '/': unescaped = "/"; break; - case '"': unescaped = "\""; break; - case 'f': unescaped = "\f"; break; - case 'b': unescaped = "\b"; break; - case 't': unescaped = "\t"; break; - case 'u': { - unsigned int codepoint = 0; - hexToDigit(&codepoint, str + ++end); - end+=3; - /* check if this is a surrogate */ - if ((codepoint & 0xFC00) == 0xD800) { - end++; - if (str[end] == '\\' && str[end + 1] == 'u') { - unsigned int surrogate = 0; - hexToDigit(&surrogate, str + end + 2); - codepoint = - (((codepoint & 0x3F) << 10) | - ((((codepoint >> 6) & 0xF) + 1) << 16) | - (surrogate & 0x3FF)); - end += 5; - } else { - unescaped = "?"; - break; - } - } - - Utf32toUtf8(codepoint, utf8Buf); - unescaped = utf8Buf; - - if (codepoint == 0) { - yajl_buf_append(buf, unescaped, 1); - beg = ++end; - continue; - } - - break; - } - default: - assert("this should never happen" == NULL); - } - yajl_buf_append(buf, unescaped, (unsigned int)strlen(unescaped)); - beg = ++end; - } else { - end++; - } - } - yajl_buf_append(buf, str + beg, end - beg); -} diff --git a/src/libCom/yajl/yajl_encode.h b/src/libCom/yajl/yajl_encode.h deleted file mode 100644 index 3e3b0923d..000000000 --- a/src/libCom/yajl/yajl_encode.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __YAJL_ENCODE_H__ -#define __YAJL_ENCODE_H__ - -#include "yajl_buf.h" -#include "yajl_gen.h" - -void yajl_string_encode2(const yajl_print_t printer, - void * ctx, - const unsigned char * str, - unsigned int length); - -void yajl_string_encode(yajl_buf buf, const unsigned char * str, - unsigned int length); - -void yajl_string_decode(yajl_buf buf, const unsigned char * str, - unsigned int length); - -#endif diff --git a/src/libCom/yajl/yajl_gen.c b/src/libCom/yajl/yajl_gen.c deleted file mode 100644 index 8d93e2726..000000000 --- a/src/libCom/yajl/yajl_gen.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMath.h" -#include "yajl_gen.h" -#include "yajl_buf.h" -#include "yajl_encode.h" - -typedef enum { - yajl_gen_start, - yajl_gen_map_start, - yajl_gen_map_key, - yajl_gen_map_val, - yajl_gen_array_start, - yajl_gen_in_array, - yajl_gen_complete, - yajl_gen_error -} yajl_gen_state; - -struct yajl_gen_t -{ - unsigned int depth; - unsigned int pretty; - const char * indentString; - yajl_gen_state state[YAJL_MAX_DEPTH]; - yajl_print_t print; - void * ctx; /* yajl_buf */ - /* memory allocation routines */ - yajl_alloc_funcs alloc; -}; - -yajl_gen -yajl_gen_alloc(const yajl_gen_config * config, - const yajl_alloc_funcs * afs) -{ - return yajl_gen_alloc2(NULL, config, afs, NULL); -} - -yajl_gen -yajl_gen_alloc2(const yajl_print_t callback, - const yajl_gen_config * config, - const yajl_alloc_funcs * afs, - void * ctx) -{ - yajl_gen g = NULL; - yajl_alloc_funcs afsBuffer; - - /* first order of business is to set up memory allocation routines */ - if (afs != NULL) { - if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL) - { - return NULL; - } - } else { - yajl_set_default_alloc_funcs(&afsBuffer); - afs = &afsBuffer; - } - - g = (yajl_gen) YA_MALLOC(afs, sizeof(struct yajl_gen_t)); - if (!g) return NULL; - - memset((void *) g, 0, sizeof(struct yajl_gen_t)); - /* copy in pointers to allocation routines */ - memcpy((void *) &(g->alloc), (void *) afs, sizeof(yajl_alloc_funcs)); - - if (config) { - const char *indent = config->indentString; - g->pretty = config->beautify; - g->indentString = config->indentString; - if (indent) { - for (; *indent; indent++) { - if (*indent != '\n' - && *indent != '\v' - && *indent != '\f' - && *indent != '\t' - && *indent != '\r' - && *indent != ' ') { - g->indentString = NULL; - break; - } - } - } - if (!g->indentString) { - g->indentString = " "; - } - } - - if (callback) { - g->print = callback; - g->ctx = ctx; - } else { - g->print = (yajl_print_t)&yajl_buf_append; - g->ctx = yajl_buf_alloc(&(g->alloc)); - } - - return g; -} - -void -yajl_gen_free(yajl_gen g) -{ - if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_free((yajl_buf)g->ctx); - YA_FREE(&(g->alloc), g); -} - -#define INSERT_SEP \ - if (g->state[g->depth] == yajl_gen_map_key || \ - g->state[g->depth] == yajl_gen_in_array) { \ - g->print(g->ctx, ",", 1); \ - if (g->pretty) g->print(g->ctx, "\n", 1); \ - } else if (g->state[g->depth] == yajl_gen_map_val) { \ - g->print(g->ctx, ":", 1); \ - if (g->pretty) g->print(g->ctx, " ", 1); \ - } - -#define INSERT_WHITESPACE \ - if (g->pretty) { \ - if (g->state[g->depth] != yajl_gen_map_val) { \ - unsigned int _i; \ - for (_i=0;_idepth;_i++) \ - g->print(g->ctx, \ - g->indentString, \ - (unsigned int)strlen(g->indentString)); \ - } \ - } - -#define ENSURE_NOT_KEY \ - if (g->state[g->depth] == yajl_gen_map_key || \ - g->state[g->depth] == yajl_gen_map_start) { \ - return yajl_gen_keys_must_be_strings; \ - } \ - -/* check that we're not complete, or in error state. in a valid state - * to be generating */ -#define ENSURE_VALID_STATE \ - if (g->state[g->depth] == yajl_gen_error) { \ - return yajl_gen_in_error_state;\ - } else if (g->state[g->depth] == yajl_gen_complete) { \ - return yajl_gen_generation_complete; \ - } - -#define INCREMENT_DEPTH \ - if (++(g->depth) >= YAJL_MAX_DEPTH) return yajl_max_depth_exceeded; - -#define DECREMENT_DEPTH \ - if (--(g->depth) >= YAJL_MAX_DEPTH) return yajl_max_depth_exceeded; - -#define APPENDED_ATOM \ - switch (g->state[g->depth]) { \ - case yajl_gen_start: \ - g->state[g->depth] = yajl_gen_complete; \ - break; \ - case yajl_gen_map_start: \ - case yajl_gen_map_key: \ - g->state[g->depth] = yajl_gen_map_val; \ - break; \ - case yajl_gen_array_start: \ - g->state[g->depth] = yajl_gen_in_array; \ - break; \ - case yajl_gen_map_val: \ - g->state[g->depth] = yajl_gen_map_key; \ - break; \ - default: \ - break; \ - } \ - -#define FINAL_NEWLINE \ - if (g->pretty && g->state[g->depth] == yajl_gen_complete) \ - g->print(g->ctx, "\n", 1); - -yajl_gen_status -yajl_gen_integer(yajl_gen g, long int number) -{ - char i[32]; - ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - sprintf(i, "%ld", number); - g->print(g->ctx, i, (unsigned int)strlen(i)); - APPENDED_ATOM; - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_double(yajl_gen g, double number) -{ - char i[32]; - ENSURE_VALID_STATE; ENSURE_NOT_KEY; - if (isnan(number) || isinf(number)) return yajl_gen_invalid_number; - INSERT_SEP; INSERT_WHITESPACE; - sprintf(i, "%.20g", number); - g->print(g->ctx, i, (unsigned int)strlen(i)); - APPENDED_ATOM; - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_number(yajl_gen g, const char * s, unsigned int l) -{ - ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - g->print(g->ctx, s, l); - APPENDED_ATOM; - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_string(yajl_gen g, const unsigned char * str, - unsigned int len) -{ - ENSURE_VALID_STATE; INSERT_SEP; INSERT_WHITESPACE; - g->print(g->ctx, "\"", 1); - yajl_string_encode2(g->print, g->ctx, str, len); - g->print(g->ctx, "\"", 1); - APPENDED_ATOM; - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_null(yajl_gen g) -{ - ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - g->print(g->ctx, "null", strlen("null")); - APPENDED_ATOM; - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_bool(yajl_gen g, int boolean) -{ - const char * val = boolean ? "true" : "false"; - - ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - g->print(g->ctx, val, (unsigned int)strlen(val)); - APPENDED_ATOM; - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_map_open(yajl_gen g) -{ - ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - INCREMENT_DEPTH; - - g->state[g->depth] = yajl_gen_map_start; - g->print(g->ctx, "{", 1); - if (g->pretty) g->print(g->ctx, "\n", 1); - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_map_close(yajl_gen g) -{ - ENSURE_VALID_STATE; - DECREMENT_DEPTH; - - if (g->pretty) g->print(g->ctx, "\n", 1); - APPENDED_ATOM; - INSERT_WHITESPACE; - g->print(g->ctx, "}", 1); - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_array_open(yajl_gen g) -{ - ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - INCREMENT_DEPTH; - g->state[g->depth] = yajl_gen_array_start; - g->print(g->ctx, "[", 1); - if (g->pretty) g->print(g->ctx, "\n", 1); - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_array_close(yajl_gen g) -{ - ENSURE_VALID_STATE; - DECREMENT_DEPTH; - if (g->pretty) g->print(g->ctx, "\n", 1); - APPENDED_ATOM; - INSERT_WHITESPACE; - g->print(g->ctx, "]", 1); - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_get_buf(yajl_gen g, const unsigned char ** buf, - unsigned int * len) -{ - if (g->print != (yajl_print_t)&yajl_buf_append) return yajl_gen_no_buf; - *buf = yajl_buf_data((yajl_buf)g->ctx); - *len = yajl_buf_len((yajl_buf)g->ctx); - return yajl_gen_status_ok; -} - -void -yajl_gen_clear(yajl_gen g) -{ - if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_clear((yajl_buf)g->ctx); -} diff --git a/src/libCom/yajl/yajl_gen.h b/src/libCom/yajl/yajl_gen.h deleted file mode 100644 index 34b147596..000000000 --- a/src/libCom/yajl/yajl_gen.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file yajl_gen.h - * Interface to YAJL's JSON generation facilities. - */ - -#ifndef __YAJL_GEN_H__ -#define __YAJL_GEN_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - /** generator status codes */ - typedef enum { - /** no error */ - yajl_gen_status_ok = 0, - /** at a point where a map key is generated, a function other than - * yajl_gen_string was called */ - yajl_gen_keys_must_be_strings, - /** YAJL's maximum generation depth was exceeded. see - * YAJL_MAX_DEPTH */ - yajl_max_depth_exceeded, - /** A generator function (yajl_gen_XXX) was called while in an error - * state */ - yajl_gen_in_error_state, - /** A complete JSON document has been generated */ - yajl_gen_generation_complete, - /** yajl_gen_double was passed an invalid floating point value - * (infinity or NaN). */ - yajl_gen_invalid_number, - /** A print callback was passed in, so there is no internal - * buffer to get from */ - yajl_gen_no_buf - } yajl_gen_status; - - /** an opaque handle to a generator */ - typedef struct yajl_gen_t * yajl_gen; - - /** a callback used for "printing" the results. */ - typedef void (*yajl_print_t)(void * ctx, - const char * str, - unsigned int len); - - /** configuration structure for the generator */ - typedef struct { - /** generate indented (beautiful) output */ - unsigned int beautify; - /** an opportunity to define an indent string. such as \\t or - * some number of spaces. default is four spaces ' '. This - * member is only relevant when beautify is true */ - const char * indentString; - } yajl_gen_config; - - /** allocate a generator handle - * \param config a pointer to a structure containing parameters which - * configure the behavior of the json generator - * \param allocFuncs an optional pointer to a structure which allows - * the client to overide the memory allocation - * used by yajl. May be NULL, in which case - * malloc/free/realloc will be used. - * - * \returns an allocated handle on success, NULL on failure (bad params) - */ - YAJL_API yajl_gen yajl_gen_alloc(const yajl_gen_config * config, - const yajl_alloc_funcs * allocFuncs); - - /** allocate a generator handle that will print to the specified - * callback rather than storing the results in an internal buffer. - * \param callback a pointer to a printer function. May be NULL - * in which case, the results will be store in an - * internal buffer. - * \param config a pointer to a structure containing parameters - * which configure the behavior of the json - * generator. - * \param allocFuncs an optional pointer to a structure which allows - * the client to overide the memory allocation - * used by yajl. May be NULL, in which case - * malloc/free/realloc will be used. - * \param ctx a context pointer that will be passed to the - * printer callback. - * - * \returns an allocated handle on success, NULL on failure (bad params) - */ - YAJL_API yajl_gen yajl_gen_alloc2(const yajl_print_t callback, - const yajl_gen_config * config, - const yajl_alloc_funcs * allocFuncs, - void * ctx); - - /** free a generator handle */ - YAJL_API void yajl_gen_free(yajl_gen handle); - - YAJL_API yajl_gen_status yajl_gen_integer(yajl_gen hand, long int number); - /** generate a floating point number. number may not be infinity or - * NaN, as these have no representation in JSON. In these cases the - * generator will return 'yajl_gen_invalid_number' */ - YAJL_API yajl_gen_status yajl_gen_double(yajl_gen hand, double number); - YAJL_API yajl_gen_status yajl_gen_number(yajl_gen hand, - const char * num, - unsigned int len); - YAJL_API yajl_gen_status yajl_gen_string(yajl_gen hand, - const unsigned char * str, - unsigned int len); - YAJL_API yajl_gen_status yajl_gen_null(yajl_gen hand); - YAJL_API yajl_gen_status yajl_gen_bool(yajl_gen hand, int boolean); - YAJL_API yajl_gen_status yajl_gen_map_open(yajl_gen hand); - YAJL_API yajl_gen_status yajl_gen_map_close(yajl_gen hand); - YAJL_API yajl_gen_status yajl_gen_array_open(yajl_gen hand); - YAJL_API yajl_gen_status yajl_gen_array_close(yajl_gen hand); - - /** access the null terminated generator buffer. If incrementally - * outputing JSON, one should call yajl_gen_clear to clear the - * buffer. This allows stream generation. */ - YAJL_API yajl_gen_status yajl_gen_get_buf(yajl_gen hand, - const unsigned char ** buf, - unsigned int * len); - - /** clear yajl's output buffer, but maintain all internal generation - * state. This function will not "reset" the generator state, and is - * intended to enable incremental JSON outputing. */ - YAJL_API void yajl_gen_clear(yajl_gen hand); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/yajl/yajl_lex.c b/src/libCom/yajl/yajl_lex.c deleted file mode 100644 index 3abd21698..000000000 --- a/src/libCom/yajl/yajl_lex.c +++ /dev/null @@ -1,738 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "yajl_lex.h" -#include "yajl_buf.h" - -#ifdef YAJL_LEXER_DEBUG -static const char * -tokToStr(yajl_tok tok) -{ - switch (tok) { - case yajl_tok_bool: return "bool"; - case yajl_tok_colon: return "colon"; - case yajl_tok_comma: return "comma"; - case yajl_tok_eof: return "eof"; - case yajl_tok_error: return "error"; - case yajl_tok_left_brace: return "brace"; - case yajl_tok_left_bracket: return "bracket"; - case yajl_tok_null: return "null"; - case yajl_tok_integer: return "integer"; - case yajl_tok_double: return "double"; - case yajl_tok_right_brace: return "brace"; - case yajl_tok_right_bracket: return "bracket"; - case yajl_tok_string: return "string"; - case yajl_tok_string_with_escapes: return "string_with_escapes"; - } - return "unknown"; -} -#endif - -/* Impact of the stream parsing feature on the lexer: - * - * YAJL support stream parsing. That is, the ability to parse the first - * bits of a chunk of JSON before the last bits are available (still on - * the network or disk). This makes the lexer more complex. The - * responsibility of the lexer is to handle transparently the case where - * a chunk boundary falls in the middle of a token. This is - * accomplished is via a buffer and a character reading abstraction. - * - * Overview of implementation - * - * When we lex to end of input string before end of token is hit, we - * copy all of the input text composing the token into our lexBuf. - * - * Every time we read a character, we do so through the readChar function. - * readChar's responsibility is to handle pulling all chars from the buffer - * before pulling chars from input text - */ - -struct yajl_lexer_t { - /* the overal line and char offset into the data */ - unsigned int lineOff; - unsigned int charOff; - - /* error */ - yajl_lex_error error; - - /* a input buffer to handle the case where a token is spread over - * multiple chunks */ - yajl_buf buf; - - /* in the case where we have data in the lexBuf, bufOff holds - * the current offset into the lexBuf. */ - unsigned int bufOff; - - /* are we using the lex buf? */ - unsigned int bufInUse; - - /* shall we allow comments? */ - unsigned int allowComments; - - /* shall we validate utf8 inside strings? */ - unsigned int validateUTF8; - - yajl_alloc_funcs * alloc; -}; - -#define readChar(lxr, txt, off) \ - (((lxr)->bufInUse && yajl_buf_len((lxr)->buf) && lxr->bufOff < yajl_buf_len((lxr)->buf)) ? \ - (*((const unsigned char *) yajl_buf_data((lxr)->buf) + ((lxr)->bufOff)++)) : \ - ((txt)[(*(off))++])) - -#define unreadChar(lxr, off) ((*(off) > 0) ? (*(off))-- : ((lxr)->bufOff--)) - -yajl_lexer -yajl_lex_alloc(yajl_alloc_funcs * alloc, - unsigned int allowComments, unsigned int validateUTF8) -{ - yajl_lexer lxr = (yajl_lexer) YA_MALLOC(alloc, sizeof(struct yajl_lexer_t)); - memset((void *) lxr, 0, sizeof(struct yajl_lexer_t)); - lxr->buf = yajl_buf_alloc(alloc); - lxr->allowComments = allowComments; - lxr->validateUTF8 = validateUTF8; - lxr->alloc = alloc; - return lxr; -} - -void -yajl_lex_free(yajl_lexer lxr) -{ - yajl_buf_free(lxr->buf); - YA_FREE(lxr->alloc, lxr); - return; -} - -/* a lookup table which lets us quickly determine three things: - * VEC - valid escaped conrol char - * IJC - invalid json char - * VHC - valid hex char - * note. the solidus '/' may be escaped or not. - * note. the - */ -#define VEC 1 -#define IJC 2 -#define VHC 4 -static const char charLookupTable[256] = -{ -/*00*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC , -/*08*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC , -/*10*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC , -/*18*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC , - -/*20*/ 0 , 0 , VEC|IJC, 0 , 0 , 0 , 0 , 0 , -/*28*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , VEC , -/*30*/ VHC , VHC , VHC , VHC , VHC , VHC , VHC , VHC , -/*38*/ VHC , VHC , 0 , 0 , 0 , 0 , 0 , 0 , - -/*40*/ 0 , VHC , VHC , VHC , VHC , VHC , VHC , 0 , -/*48*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -/*50*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -/*58*/ 0 , 0 , 0 , 0 , VEC|IJC, 0 , 0 , 0 , - -/*60*/ 0 , VHC , VEC|VHC, VHC , VHC , VHC , VEC|VHC, 0 , -/*68*/ 0 , 0 , 0 , 0 , 0 , 0 , VEC , 0 , -/*70*/ 0 , 0 , VEC , 0 , VEC , 0 , 0 , 0 , -/*78*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - -/* include these so we don't have to always check the range of the char */ - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 -}; - -/** process a variable length utf8 encoded codepoint. - * - * returns: - * yajl_tok_string - if valid utf8 char was parsed and offset was - * advanced - * yajl_tok_eof - if end of input was hit before validation could - * complete - * yajl_tok_error - if invalid utf8 was encountered - * - * NOTE: on error the offset will point to the first char of the - * invalid utf8 */ -#define UTF8_CHECK_EOF if (*offset >= jsonTextLen) { return yajl_tok_eof; } - -static yajl_tok -yajl_lex_utf8_char(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int * offset, - unsigned char curChar) -{ - if (curChar <= 0x7f) { - /* single byte */ - return yajl_tok_string; - } else if ((curChar >> 5) == 0x6) { - /* two byte */ - UTF8_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if ((curChar >> 6) == 0x2) return yajl_tok_string; - } else if ((curChar >> 4) == 0x0e) { - /* three byte */ - UTF8_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if ((curChar >> 6) == 0x2) { - UTF8_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if ((curChar >> 6) == 0x2) return yajl_tok_string; - } - } else if ((curChar >> 3) == 0x1e) { - /* four byte */ - UTF8_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if ((curChar >> 6) == 0x2) { - UTF8_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if ((curChar >> 6) == 0x2) { - UTF8_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if ((curChar >> 6) == 0x2) return yajl_tok_string; - } - } - } - - return yajl_tok_error; -} - -/* lex a string. input is the lexer, pointer to beginning of - * json text, and start of string (offset). - * a token is returned which has the following meanings: - * yajl_tok_string: lex of string was successful. offset points to - * terminating '"'. - * yajl_tok_eof: end of text was encountered before we could complete - * the lex. - * yajl_tok_error: embedded in the string were unallowable chars. offset - * points to the offending char - */ -#define STR_CHECK_EOF \ -if (*offset >= jsonTextLen) { \ - tok = yajl_tok_eof; \ - goto finish_string_lex; \ -} - -static yajl_tok -yajl_lex_string(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int * offset) -{ - yajl_tok tok = yajl_tok_error; - int hasEscapes = 0; - - for (;;) { - unsigned char curChar; - - STR_CHECK_EOF; - - curChar = readChar(lexer, jsonText, offset); - - /* quote terminates */ - if (curChar == '"') { - tok = yajl_tok_string; - break; - } - /* backslash escapes a set of control chars, */ - else if (curChar == '\\') { - hasEscapes = 1; - STR_CHECK_EOF; - - /* special case \u */ - curChar = readChar(lexer, jsonText, offset); - if (curChar == 'u') { - unsigned int i = 0; - - for (i=0;i<4;i++) { - STR_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if (!(charLookupTable[curChar] & VHC)) { - /* back up to offending char */ - unreadChar(lexer, offset); - lexer->error = yajl_lex_string_invalid_hex_char; - goto finish_string_lex; - } - } - } else if (!(charLookupTable[curChar] & VEC)) { - /* back up to offending char */ - unreadChar(lexer, offset); - lexer->error = yajl_lex_string_invalid_escaped_char; - goto finish_string_lex; - } - } - /* when not validating UTF8 it's a simple table lookup to determine - * if the present character is invalid */ - else if(charLookupTable[curChar] & IJC) { - /* back up to offending char */ - unreadChar(lexer, offset); - lexer->error = yajl_lex_string_invalid_json_char; - goto finish_string_lex; - } - /* when in validate UTF8 mode we need to do some extra work */ - else if (lexer->validateUTF8) { - yajl_tok t = yajl_lex_utf8_char(lexer, jsonText, jsonTextLen, - offset, curChar); - - if (t == yajl_tok_eof) { - tok = yajl_tok_eof; - goto finish_string_lex; - } else if (t == yajl_tok_error) { - lexer->error = yajl_lex_string_invalid_utf8; - goto finish_string_lex; - } - } - /* accept it, and move on */ - } - finish_string_lex: - /* tell our buddy, the parser, wether he needs to process this string - * again */ - if (hasEscapes && tok == yajl_tok_string) { - tok = yajl_tok_string_with_escapes; - } - - return tok; -} - -#define RETURN_IF_EOF if (*offset >= jsonTextLen) return yajl_tok_eof; - -static yajl_tok -yajl_lex_number(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int * offset) -{ - /** XXX: numbers are the only entities in json that we must lex - * _beyond_ in order to know that they are complete. There - * is an ambiguous case for integers at EOF. */ - - unsigned char c; - - yajl_tok tok = yajl_tok_integer; - - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - - /* optional leading minus */ - if (c == '-') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } - - /* a single zero, or a series of integers */ - if (c == '0') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } else if (c >= '1' && c <= '9') { - do { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } while (c >= '0' && c <= '9'); - } else { - unreadChar(lexer, offset); - lexer->error = yajl_lex_missing_integer_after_minus; - return yajl_tok_error; - } - - /* optional fraction (indicates this is floating point) */ - if (c == '.') { - int numRd = 0; - - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - - while (c >= '0' && c <= '9') { - numRd++; - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } - - if (!numRd) { - unreadChar(lexer, offset); - lexer->error = yajl_lex_missing_integer_after_decimal; - return yajl_tok_error; - } - tok = yajl_tok_double; - } - - /* optional exponent (indicates this is floating point) */ - if (c == 'e' || c == 'E') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - - /* optional sign */ - if (c == '+' || c == '-') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } - - if (c >= '0' && c <= '9') { - do { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } while (c >= '0' && c <= '9'); - } else { - unreadChar(lexer, offset); - lexer->error = yajl_lex_missing_integer_after_exponent; - return yajl_tok_error; - } - tok = yajl_tok_double; - } - - /* we always go "one too far" */ - unreadChar(lexer, offset); - - return tok; -} - -static yajl_tok -yajl_lex_comment(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int * offset) -{ - unsigned char c; - - yajl_tok tok = yajl_tok_comment; - - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - - /* either slash or star expected */ - if (c == '/') { - /* now we throw away until end of line */ - do { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } while (c != '\n'); - } else if (c == '*') { - /* now we throw away until end of comment */ - for (;;) { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - if (c == '*') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - if (c == '/') { - break; - } else { - unreadChar(lexer, offset); - } - } - } - } else { - lexer->error = yajl_lex_invalid_char; - tok = yajl_tok_error; - } - - return tok; -} - -yajl_tok -yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int * offset, - const unsigned char ** outBuf, unsigned int * outLen) -{ - yajl_tok tok = yajl_tok_error; - unsigned char c; - unsigned int startOffset = *offset; - - *outBuf = NULL; - *outLen = 0; - - for (;;) { - assert(*offset <= jsonTextLen); - - if (*offset >= jsonTextLen) { - tok = yajl_tok_eof; - goto lexed; - } - - c = readChar(lexer, jsonText, offset); - - switch (c) { - case '{': - tok = yajl_tok_left_bracket; - goto lexed; - case '}': - tok = yajl_tok_right_bracket; - goto lexed; - case '[': - tok = yajl_tok_left_brace; - goto lexed; - case ']': - tok = yajl_tok_right_brace; - goto lexed; - case ',': - tok = yajl_tok_comma; - goto lexed; - case ':': - tok = yajl_tok_colon; - goto lexed; - case '\t': case '\n': case '\v': case '\f': case '\r': case ' ': - startOffset++; - break; - case 't': { - const char * want = "rue"; - do { - if (*offset >= jsonTextLen) { - tok = yajl_tok_eof; - goto lexed; - } - c = readChar(lexer, jsonText, offset); - if (c != *want) { - unreadChar(lexer, offset); - lexer->error = yajl_lex_invalid_string; - tok = yajl_tok_error; - goto lexed; - } - } while (*(++want)); - tok = yajl_tok_bool; - goto lexed; - } - case 'f': { - const char * want = "alse"; - do { - if (*offset >= jsonTextLen) { - tok = yajl_tok_eof; - goto lexed; - } - c = readChar(lexer, jsonText, offset); - if (c != *want) { - unreadChar(lexer, offset); - lexer->error = yajl_lex_invalid_string; - tok = yajl_tok_error; - goto lexed; - } - } while (*(++want)); - tok = yajl_tok_bool; - goto lexed; - } - case 'n': { - const char * want = "ull"; - do { - if (*offset >= jsonTextLen) { - tok = yajl_tok_eof; - goto lexed; - } - c = readChar(lexer, jsonText, offset); - if (c != *want) { - unreadChar(lexer, offset); - lexer->error = yajl_lex_invalid_string; - tok = yajl_tok_error; - goto lexed; - } - } while (*(++want)); - tok = yajl_tok_null; - goto lexed; - } - case '"': { - tok = yajl_lex_string(lexer, (const unsigned char *) jsonText, - jsonTextLen, offset); - goto lexed; - } - case '-': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': { - /* integer parsing wants to start from the beginning */ - unreadChar(lexer, offset); - tok = yajl_lex_number(lexer, (const unsigned char *) jsonText, - jsonTextLen, offset); - goto lexed; - } - case '/': - /* hey, look, a probable comment! If comments are disabled - * it's an error. */ - if (!lexer->allowComments) { - unreadChar(lexer, offset); - lexer->error = yajl_lex_unallowed_comment; - tok = yajl_tok_error; - goto lexed; - } - /* if comments are enabled, then we should try to lex - * the thing. possible outcomes are - * - successful lex (tok_comment, which means continue), - * - malformed comment opening (slash not followed by - * '*' or '/') (tok_error) - * - eof hit. (tok_eof) */ - tok = yajl_lex_comment(lexer, (const unsigned char *) jsonText, - jsonTextLen, offset); - if (tok == yajl_tok_comment) { - /* "error" is silly, but that's the initial - * state of tok. guilty until proven innocent. */ - tok = yajl_tok_error; - yajl_buf_clear(lexer->buf); - lexer->bufInUse = 0; - startOffset = *offset; - break; - } - /* hit error or eof, bail */ - goto lexed; - default: - lexer->error = yajl_lex_invalid_char; - tok = yajl_tok_error; - goto lexed; - } - } - - - lexed: - /* need to append to buffer if the buffer is in use or - * if it's an EOF token */ - if (tok == yajl_tok_eof || lexer->bufInUse) { - if (!lexer->bufInUse) yajl_buf_clear(lexer->buf); - lexer->bufInUse = 1; - yajl_buf_append(lexer->buf, jsonText + startOffset, *offset - startOffset); - lexer->bufOff = 0; - - if (tok != yajl_tok_eof) { - *outBuf = yajl_buf_data(lexer->buf); - *outLen = yajl_buf_len(lexer->buf); - lexer->bufInUse = 0; - } - } else if (tok != yajl_tok_error) { - *outBuf = jsonText + startOffset; - *outLen = *offset - startOffset; - } - - /* special case for strings. skip the quotes. */ - if (tok == yajl_tok_string || tok == yajl_tok_string_with_escapes) - { - assert(*outLen >= 2); - (*outBuf)++; - *outLen -= 2; - } - - -#ifdef YAJL_LEXER_DEBUG - if (tok == yajl_tok_error) { - printf("lexical error: %s\n", - yajl_lex_error_to_string(yajl_lex_get_error(lexer))); - } else if (tok == yajl_tok_eof) { - printf("EOF hit\n"); - } else { - printf("lexed %s: '", tokToStr(tok)); - fwrite(*outBuf, 1, *outLen, stdout); - printf("'\n"); - } -#endif - - return tok; -} - -const char * -yajl_lex_error_to_string(yajl_lex_error error) -{ - switch (error) { - case yajl_lex_e_ok: - return "ok, no error"; - case yajl_lex_string_invalid_utf8: - return "invalid bytes in UTF8 string."; - case yajl_lex_string_invalid_escaped_char: - return "inside a string, '\\' occurs before a character " - "which it may not."; - case yajl_lex_string_invalid_json_char: - return "invalid character inside string."; - case yajl_lex_string_invalid_hex_char: - return "invalid (non-hex) character occurs after '\\u' inside " - "string."; - case yajl_lex_invalid_char: - return "invalid char in json text."; - case yajl_lex_invalid_string: - return "invalid string in json text."; - case yajl_lex_missing_integer_after_exponent: - return "malformed number, a digit is required after the exponent."; - case yajl_lex_missing_integer_after_decimal: - return "malformed number, a digit is required after the " - "decimal point."; - case yajl_lex_missing_integer_after_minus: - return "malformed number, a digit is required after the " - "minus sign."; - case yajl_lex_unallowed_comment: - return "probable comment found in input text, comments are " - "not enabled."; - } - return "unknown error code"; -} - - -/** allows access to more specific information about the lexical - * error when yajl_lex_lex returns yajl_tok_error. */ -yajl_lex_error -yajl_lex_get_error(yajl_lexer lexer) -{ - if (lexer == NULL) return (yajl_lex_error) -1; - return lexer->error; -} - -unsigned int yajl_lex_current_line(yajl_lexer lexer) -{ - return lexer->lineOff; -} - -unsigned int yajl_lex_current_char(yajl_lexer lexer) -{ - return lexer->charOff; -} - -yajl_tok yajl_lex_peek(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int offset) -{ - const unsigned char * outBuf; - unsigned int outLen; - unsigned int bufLen = yajl_buf_len(lexer->buf); - unsigned int bufOff = lexer->bufOff; - unsigned int bufInUse = lexer->bufInUse; - yajl_tok tok; - - tok = yajl_lex_lex(lexer, jsonText, jsonTextLen, &offset, - &outBuf, &outLen); - - lexer->bufOff = bufOff; - lexer->bufInUse = bufInUse; - yajl_buf_truncate(lexer->buf, bufLen); - - return tok; -} diff --git a/src/libCom/yajl/yajl_lex.h b/src/libCom/yajl/yajl_lex.h deleted file mode 100644 index 559e54dba..000000000 --- a/src/libCom/yajl/yajl_lex.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __YAJL_LEX_H__ -#define __YAJL_LEX_H__ - -#include "yajl_common.h" - -typedef enum { - yajl_tok_bool, - yajl_tok_colon, - yajl_tok_comma, - yajl_tok_eof, - yajl_tok_error, - yajl_tok_left_brace, - yajl_tok_left_bracket, - yajl_tok_null, - yajl_tok_right_brace, - yajl_tok_right_bracket, - - /* we differentiate between integers and doubles to allow the - * parser to interpret the number without re-scanning */ - yajl_tok_integer, - yajl_tok_double, - - /* we differentiate between strings which require further processing, - * and strings that do not */ - yajl_tok_string, - yajl_tok_string_with_escapes, - - /* comment tokens are not currently returned to the parser, ever */ - yajl_tok_comment -} yajl_tok; - -typedef struct yajl_lexer_t * yajl_lexer; - -yajl_lexer yajl_lex_alloc(yajl_alloc_funcs * alloc, - unsigned int allowComments, - unsigned int validateUTF8); - -void yajl_lex_free(yajl_lexer lexer); - -/** - * run/continue a lex. "offset" is an input/output parameter. - * It should be initialized to zero for a - * new chunk of target text, and upon subsetquent calls with the same - * target text should passed with the value of the previous invocation. - * - * the client may be interested in the value of offset when an error is - * returned from the lexer. This allows the client to render useful -n * error messages. - * - * When you pass the next chunk of data, context should be reinitialized - * to zero. - * - * Finally, the output buffer is usually just a pointer into the jsonText, - * however in cases where the entity being lexed spans multiple chunks, - * the lexer will buffer the entity and the data returned will be - * a pointer into that buffer. - * - * This behavior is abstracted from client code except for the performance - * implications which require that the client choose a reasonable chunk - * size to get adequate performance. - */ -yajl_tok yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int * offset, - const unsigned char ** outBuf, unsigned int * outLen); - -/** have a peek at the next token, but don't move the lexer forward */ -yajl_tok yajl_lex_peek(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int offset); - - -typedef enum { - yajl_lex_e_ok = 0, - yajl_lex_string_invalid_utf8, - yajl_lex_string_invalid_escaped_char, - yajl_lex_string_invalid_json_char, - yajl_lex_string_invalid_hex_char, - yajl_lex_invalid_char, - yajl_lex_invalid_string, - yajl_lex_missing_integer_after_decimal, - yajl_lex_missing_integer_after_exponent, - yajl_lex_missing_integer_after_minus, - yajl_lex_unallowed_comment -} yajl_lex_error; - -const char * yajl_lex_error_to_string(yajl_lex_error error); - -/** allows access to more specific information about the lexical - * error when yajl_lex_lex returns yajl_tok_error. */ -yajl_lex_error yajl_lex_get_error(yajl_lexer lexer); - -/** get the current offset into the most recently lexed json string. */ -unsigned int yajl_lex_current_offset(yajl_lexer lexer); - -/** get the number of lines lexed by this lexer instance */ -unsigned int yajl_lex_current_line(yajl_lexer lexer); - -/** get the number of chars lexed by this lexer instance since the last - * \n or \r */ -unsigned int yajl_lex_current_char(yajl_lexer lexer); - -#endif diff --git a/src/libCom/yajl/yajl_parse.h b/src/libCom/yajl/yajl_parse.h deleted file mode 100644 index a70a8fd56..000000000 --- a/src/libCom/yajl/yajl_parse.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file yajl_parse.h - * Interface to YAJL's JSON parsing facilities. - */ - -#ifndef __YAJL_PARSE_H__ -#define __YAJL_PARSE_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - /** error codes returned from this interface */ - typedef enum { - /** no error was encountered */ - yajl_status_ok, - /** a client callback returned zero, stopping the parse */ - yajl_status_client_canceled, - /** The parse cannot yet complete because more json input text - * is required, call yajl_parse with the next buffer of input text. - * (pertinent only when stream parsing) */ - yajl_status_insufficient_data, - /** An error occured during the parse. Call yajl_get_error for - * more information about the encountered error */ - yajl_status_error - } yajl_status; - - /** attain a human readable, english, string for an error */ - YAJL_API const char * yajl_status_to_string(yajl_status code); - - /** an opaque handle to a parser */ - typedef struct yajl_handle_t * yajl_handle; - - /** yajl is an event driven parser. this means as json elements are - * parsed, you are called back to do something with the data. The - * functions in this table indicate the various events for which - * you will be called back. Each callback accepts a "context" - * pointer, this is a void * that is passed into the yajl_parse - * function which the client code may use to pass around context. - * - * All callbacks return an integer. If non-zero, the parse will - * continue. If zero, the parse will be canceled and - * yajl_status_client_canceled will be returned from the parse. - * - * Note about handling of numbers: - * yajl will only convert numbers that can be represented in a double - * or a long int. All other numbers will be passed to the client - * in string form using the yajl_number callback. Furthermore, if - * yajl_number is not NULL, it will always be used to return numbers, - * that is yajl_integer and yajl_double will be ignored. If - * yajl_number is NULL but one of yajl_integer or yajl_double are - * defined, parsing of a number larger than is representable - * in a double or long int will result in a parse error. - */ - typedef struct { - int (* yajl_null)(void * ctx); - int (* yajl_boolean)(void * ctx, int boolVal); - int (* yajl_integer)(void * ctx, long integerVal); - int (* yajl_double)(void * ctx, double doubleVal); - /** A callback which passes the string representation of the number - * back to the client. Will be used for all numbers when present */ - int (* yajl_number)(void * ctx, const char * numberVal, - unsigned int numberLen); - - /** strings are returned as pointers into the JSON text when, - * possible, as a result, they are _not_ null padded */ - int (* yajl_string)(void * ctx, const unsigned char * stringVal, - unsigned int stringLen); - - int (* yajl_start_map)(void * ctx); - int (* yajl_map_key)(void * ctx, const unsigned char * key, - unsigned int stringLen); - int (* yajl_end_map)(void * ctx); - - int (* yajl_start_array)(void * ctx); - int (* yajl_end_array)(void * ctx); - } yajl_callbacks; - - /** configuration structure for the generator */ - typedef struct { - /** if nonzero, javascript style comments will be allowed in - * the json input, both slash star and slash slash */ - unsigned int allowComments; - /** if nonzero, invalid UTF8 strings will cause a parse - * error */ - unsigned int checkUTF8; - } yajl_parser_config; - - /** allocate a parser handle - * \param callbacks a yajl callbacks structure specifying the - * functions to call when different JSON entities - * are encountered in the input text. May be NULL, - * which is only useful for validation. - * \param config configuration parameters for the parse. - * \param ctx a context pointer that will be passed to callbacks. - */ - YAJL_API yajl_handle yajl_alloc(const yajl_callbacks * callbacks, - const yajl_parser_config * config, - const yajl_alloc_funcs * allocFuncs, - void * ctx); - - /** free a parser handle */ - YAJL_API void yajl_free(yajl_handle handle); - - /** Parse some json! - * \param hand - a handle to the json parser allocated with yajl_alloc - * \param jsonText - a pointer to the UTF8 json text to be parsed - * \param jsonTextLength - the length, in bytes, of input text - */ - YAJL_API yajl_status yajl_parse(yajl_handle hand, - const unsigned char * jsonText, - unsigned int jsonTextLength); - - /** Parse any remaining buffered json. - * Since yajl is a stream-based parser, without an explicit end of - * input, yajl sometimes can't decide if content at the end of the - * stream is valid or not. For example, if "1" has been fed in, - * yajl can't know whether another digit is next or some character - * that would terminate the integer token. - * - * \param hand - a handle to the json parser allocated with yajl_alloc - */ - YAJL_API yajl_status yajl_parse_complete(yajl_handle hand); - - /** get an error string describing the state of the - * parse. - * - * If verbose is non-zero, the message will include the JSON - * text where the error occured, along with an arrow pointing to - * the specific char. - * - * \returns A dynamically allocated string will be returned which should - * be freed with yajl_free_error - */ - YAJL_API unsigned char * yajl_get_error(yajl_handle hand, int verbose, - const unsigned char * jsonText, - unsigned int jsonTextLength); - - /** - * get the amount of data consumed from the last chunk passed to YAJL. - * - * In the case of a successful parse this can help you understand if - * the entire buffer was consumed (which will allow you to handle - * "junk at end of input". - * - * In the event an error is encountered during parsing, this function - * affords the client a way to get the offset into the most recent - * chunk where the error occured. 0 will be returned if no error - * was encountered. - */ - YAJL_API unsigned int yajl_get_bytes_consumed(yajl_handle hand); - - /** free an error returned from yajl_get_error */ - YAJL_API void yajl_free_error(yajl_handle hand, unsigned char * str); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/yajl/yajl_parser.c b/src/libCom/yajl/yajl_parser.c deleted file mode 100644 index bbcf80880..000000000 --- a/src/libCom/yajl/yajl_parser.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "yajl_lex.h" -#include "yajl_parser.h" -#include "yajl_encode.h" -#include "yajl_bytestack.h" - -unsigned char * -yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText, - unsigned int jsonTextLen, int verbose) -{ - unsigned int offset = hand->bytesConsumed; - unsigned char * str; - const char * errorType = NULL; - const char * errorText = NULL; - char text[72]; - const char * arrow = " (right here) ------^\n"; - - if (yajl_bs_current(hand->stateStack) == yajl_state_parse_error) { - errorType = "parse"; - errorText = hand->parseError; - } else if (yajl_bs_current(hand->stateStack) == yajl_state_lexical_error) { - errorType = "lexical"; - errorText = yajl_lex_error_to_string(yajl_lex_get_error(hand->lexer)); - } else { - errorType = "unknown"; - } - - { - unsigned int memneeded = 0; - memneeded += strlen(errorType); - memneeded += strlen(" error"); - if (errorText != NULL) { - memneeded += strlen(": "); - memneeded += strlen(errorText); - } - str = (unsigned char *) YA_MALLOC(&(hand->alloc), memneeded + 2); - str[0] = 0; - strcat((char *) str, errorType); - strcat((char *) str, " error"); - if (errorText != NULL) { - strcat((char *) str, ": "); - strcat((char *) str, errorText); - } - strcat((char *) str, "\n"); - } - - /* now we append as many spaces as needed to make sure the error - * falls at char 41, if verbose was specified */ - if (verbose) { - unsigned int start, end, i; - unsigned int spacesNeeded; - - spacesNeeded = (offset < 30 ? 40 - offset : 10); - start = (offset >= 30 ? offset - 30 : 0); - end = (offset + 30 > jsonTextLen ? jsonTextLen : offset + 30); - - for (i=0;ialloc), (unsigned int)(strlen((char *) str) + - strlen((char *) text) + - strlen(arrow) + 1)); - newStr[0] = 0; - strcat((char *) newStr, (char *) str); - strcat((char *) newStr, text); - strcat((char *) newStr, arrow); - YA_FREE(&(hand->alloc), str); - str = (unsigned char *) newStr; - } - } - return str; -} - -/* check for client cancelation */ -#define _CC_CHK(x) \ - if (!(x)) { \ - yajl_bs_set(hand->stateStack, yajl_state_parse_error); \ - hand->parseError = \ - "client cancelled parse via callback return value"; \ - return yajl_status_client_canceled; \ - } - - -yajl_status -yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, - unsigned int jsonTextLen) -{ - yajl_tok tok; - const unsigned char * buf; - unsigned int bufLen; - unsigned int * offset = &(hand->bytesConsumed); - - *offset = 0; - - - around_again: - switch (yajl_bs_current(hand->stateStack)) { - case yajl_state_parse_complete: - return yajl_status_ok; - case yajl_state_lexical_error: - case yajl_state_parse_error: - return yajl_status_error; - case yajl_state_start: - case yajl_state_map_need_val: - case yajl_state_array_need_val: - case yajl_state_array_start: { - /* for arrays and maps, we advance the state for this - * depth, then push the state of the next depth. - * If an error occurs during the parsing of the nesting - * enitity, the state at this level will not matter. - * a state that needs pushing will be anything other - * than state_start */ - yajl_state stateToPush = yajl_state_start; - - tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, - offset, &buf, &bufLen); - - switch (tok) { - case yajl_tok_eof: - return yajl_status_insufficient_data; - case yajl_tok_error: - yajl_bs_set(hand->stateStack, yajl_state_lexical_error); - goto around_again; - case yajl_tok_string: - if (hand->callbacks && hand->callbacks->yajl_string) { - _CC_CHK(hand->callbacks->yajl_string(hand->ctx, - buf, bufLen)); - } - break; - case yajl_tok_string_with_escapes: - if (hand->callbacks && hand->callbacks->yajl_string) { - yajl_buf_clear(hand->decodeBuf); - yajl_string_decode(hand->decodeBuf, buf, bufLen); - _CC_CHK(hand->callbacks->yajl_string( - hand->ctx, yajl_buf_data(hand->decodeBuf), - yajl_buf_len(hand->decodeBuf))); - } - break; - case yajl_tok_bool: - if (hand->callbacks && hand->callbacks->yajl_boolean) { - _CC_CHK(hand->callbacks->yajl_boolean(hand->ctx, - *buf == 't')); - } - break; - case yajl_tok_null: - if (hand->callbacks && hand->callbacks->yajl_null) { - _CC_CHK(hand->callbacks->yajl_null(hand->ctx)); - } - break; - case yajl_tok_left_bracket: - if (hand->callbacks && hand->callbacks->yajl_start_map) { - _CC_CHK(hand->callbacks->yajl_start_map(hand->ctx)); - } - stateToPush = yajl_state_map_start; - break; - case yajl_tok_left_brace: - if (hand->callbacks && hand->callbacks->yajl_start_array) { - _CC_CHK(hand->callbacks->yajl_start_array(hand->ctx)); - } - stateToPush = yajl_state_array_start; - break; - case yajl_tok_integer: - /* - * note. strtol does not respect the length of - * the lexical token. in a corner case where the - * lexed number is a integer with a trailing zero, - * immediately followed by the end of buffer, - * sscanf could run off into oblivion and cause a - * crash. for this reason we copy the integer - * (and doubles), into our parse buffer (the same - * one used for unescaping strings), before - * calling strtol. yajl_buf ensures null padding, - * so we're safe. - */ - if (hand->callbacks) { - if (hand->callbacks->yajl_number) { - _CC_CHK(hand->callbacks->yajl_number( - hand->ctx,(const char *) buf, bufLen)); - } else if (hand->callbacks->yajl_integer) { - long int i = 0; - yajl_buf_clear(hand->decodeBuf); - yajl_buf_append(hand->decodeBuf, buf, bufLen); - buf = yajl_buf_data(hand->decodeBuf); - i = strtol((const char *) buf, NULL, 10); - if ((i == LONG_MIN || i == LONG_MAX) && - errno == ERANGE) - { - yajl_bs_set(hand->stateStack, - yajl_state_parse_error); - hand->parseError = "integer overflow" ; - /* try to restore error offset */ - if (*offset >= bufLen) *offset -= bufLen; - else *offset = 0; - goto around_again; - } - _CC_CHK(hand->callbacks->yajl_integer(hand->ctx, - i)); - } - } - break; - case yajl_tok_double: - if (hand->callbacks) { - if (hand->callbacks->yajl_number) { - _CC_CHK(hand->callbacks->yajl_number( - hand->ctx, (const char *) buf, bufLen)); - } else if (hand->callbacks->yajl_double) { - double d = 0.0; - yajl_buf_clear(hand->decodeBuf); - yajl_buf_append(hand->decodeBuf, buf, bufLen); - buf = yajl_buf_data(hand->decodeBuf); - d = strtod((char *) buf, NULL); - if ((d == HUGE_VAL || d == -HUGE_VAL) && - errno == ERANGE) - { - yajl_bs_set(hand->stateStack, - yajl_state_parse_error); - hand->parseError = "numeric (floating point) " - "overflow"; - /* try to restore error offset */ - if (*offset >= bufLen) *offset -= bufLen; - else *offset = 0; - goto around_again; - } - _CC_CHK(hand->callbacks->yajl_double(hand->ctx, - d)); - } - } - break; - case yajl_tok_right_brace: { - if (yajl_bs_current(hand->stateStack) == - yajl_state_array_start) - { - if (hand->callbacks && - hand->callbacks->yajl_end_array) - { - _CC_CHK(hand->callbacks->yajl_end_array(hand->ctx)); - } - yajl_bs_pop(hand->stateStack); - goto around_again; - } - /* intentional fall-through */ - } - case yajl_tok_colon: - case yajl_tok_comma: - case yajl_tok_right_bracket: - yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = - "unallowed token at this point in JSON text"; - goto around_again; - default: - yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = "invalid token, internal error"; - goto around_again; - } - /* got a value. transition depends on the state we're in. */ - { - yajl_state s = yajl_bs_current(hand->stateStack); - if (s == yajl_state_start) { - yajl_bs_set(hand->stateStack, yajl_state_parse_complete); - } else if (s == yajl_state_map_need_val) { - yajl_bs_set(hand->stateStack, yajl_state_map_got_val); - } else { - yajl_bs_set(hand->stateStack, yajl_state_array_got_val); - } - } - if (stateToPush != yajl_state_start) { - yajl_bs_push(hand->stateStack, stateToPush); - } - - goto around_again; - } - case yajl_state_map_start: - case yajl_state_map_need_key: { - /* only difference between these two states is that in - * start '}' is valid, whereas in need_key, we've parsed - * a comma, and a string key _must_ follow */ - tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, - offset, &buf, &bufLen); - switch (tok) { - case yajl_tok_eof: - return yajl_status_insufficient_data; - case yajl_tok_error: - yajl_bs_set(hand->stateStack, yajl_state_lexical_error); - goto around_again; - case yajl_tok_string_with_escapes: - if (hand->callbacks && hand->callbacks->yajl_map_key) { - yajl_buf_clear(hand->decodeBuf); - yajl_string_decode(hand->decodeBuf, buf, bufLen); - buf = yajl_buf_data(hand->decodeBuf); - bufLen = yajl_buf_len(hand->decodeBuf); - } - /* intentional fall-through */ - case yajl_tok_string: - if (hand->callbacks && hand->callbacks->yajl_map_key) { - _CC_CHK(hand->callbacks->yajl_map_key(hand->ctx, buf, - bufLen)); - } - yajl_bs_set(hand->stateStack, yajl_state_map_sep); - goto around_again; - case yajl_tok_right_bracket: - if (yajl_bs_current(hand->stateStack) == - yajl_state_map_start) - { - if (hand->callbacks && hand->callbacks->yajl_end_map) { - _CC_CHK(hand->callbacks->yajl_end_map(hand->ctx)); - } - yajl_bs_pop(hand->stateStack); - goto around_again; - } - default: - yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = - "invalid object key (must be a string)"; - goto around_again; - } - } - case yajl_state_map_sep: { - tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, - offset, &buf, &bufLen); - switch (tok) { - case yajl_tok_colon: - yajl_bs_set(hand->stateStack, yajl_state_map_need_val); - goto around_again; - case yajl_tok_eof: - return yajl_status_insufficient_data; - case yajl_tok_error: - yajl_bs_set(hand->stateStack, yajl_state_lexical_error); - goto around_again; - default: - yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = "object key and value must " - "be separated by a colon (':')"; - goto around_again; - } - } - case yajl_state_map_got_val: { - tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, - offset, &buf, &bufLen); - switch (tok) { - case yajl_tok_right_bracket: - if (hand->callbacks && hand->callbacks->yajl_end_map) { - _CC_CHK(hand->callbacks->yajl_end_map(hand->ctx)); - } - yajl_bs_pop(hand->stateStack); - goto around_again; - case yajl_tok_comma: - yajl_bs_set(hand->stateStack, yajl_state_map_need_key); - goto around_again; - case yajl_tok_eof: - return yajl_status_insufficient_data; - case yajl_tok_error: - yajl_bs_set(hand->stateStack, yajl_state_lexical_error); - goto around_again; - default: - yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = "after key and value, inside map, " - "I expect ',' or '}'"; - /* try to restore error offset */ - if (*offset >= bufLen) *offset -= bufLen; - else *offset = 0; - goto around_again; - } - } - case yajl_state_array_got_val: { - tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, - offset, &buf, &bufLen); - switch (tok) { - case yajl_tok_right_brace: - if (hand->callbacks && hand->callbacks->yajl_end_array) { - _CC_CHK(hand->callbacks->yajl_end_array(hand->ctx)); - } - yajl_bs_pop(hand->stateStack); - goto around_again; - case yajl_tok_comma: - yajl_bs_set(hand->stateStack, yajl_state_array_need_val); - goto around_again; - case yajl_tok_eof: - return yajl_status_insufficient_data; - case yajl_tok_error: - yajl_bs_set(hand->stateStack, yajl_state_lexical_error); - goto around_again; - default: - yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = - "after array element, I expect ',' or ']'"; - goto around_again; - } - } - } - - abort(); - return yajl_status_error; -} - diff --git a/src/libCom/yajl/yajl_parser.h b/src/libCom/yajl/yajl_parser.h deleted file mode 100644 index 2d59882a3..000000000 --- a/src/libCom/yajl/yajl_parser.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. Neither the name of Lloyd Hilaiel nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __YAJL_PARSER_H__ -#define __YAJL_PARSER_H__ - -#include "yajl_parse.h" -#include "yajl_bytestack.h" -#include "yajl_buf.h" - - -typedef enum { - yajl_state_start = 0, - yajl_state_parse_complete, - yajl_state_parse_error, - yajl_state_lexical_error, - yajl_state_map_start, - yajl_state_map_sep, - yajl_state_map_need_val, - yajl_state_map_got_val, - yajl_state_map_need_key, - yajl_state_array_start, - yajl_state_array_got_val, - yajl_state_array_need_val -} yajl_state; - -struct yajl_handle_t { - const yajl_callbacks * callbacks; - void * ctx; - yajl_lexer lexer; - const char * parseError; - /* the number of bytes consumed from the last client buffer, - * in the case of an error this will be an error offset, in the - * case of an error this can be used as the error offset */ - unsigned int bytesConsumed; - /* temporary storage for decoded strings */ - yajl_buf decodeBuf; - /* a stack of states. access with yajl_state_XXX routines */ - yajl_bytestack stateStack; - /* memory allocation routines */ - yajl_alloc_funcs alloc; -}; - -yajl_status -yajl_do_parse(yajl_handle handle, const unsigned char * jsonText, - unsigned int jsonTextLen); - -unsigned char * -yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText, - unsigned int jsonTextLen, int verbose); - - -#endif diff --git a/src/std/Makefile b/src/std/Makefile index dcfcb6a22..20a8658cb 100644 --- a/src/std/Makefile +++ b/src/std/Makefile @@ -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. #************************************************************************* -TOP=../.. +TOP = ../.. include $(TOP)/configure/CONFIG STDDIR=$(TOP)/src/std @@ -27,4 +27,3 @@ include $(TOP)/configure/RULES include $(STDDIR)/rec/RULES include $(STDDIR)/softIoc/RULES - diff --git a/src/std/filters/Makefile b/src/std/filters/Makefile index d4539898f..6b4dc7917 100644 --- a/src/std/filters/Makefile +++ b/src/std/filters/Makefile @@ -2,7 +2,7 @@ # 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. +# in file LICENSE that is included with this distribution. #************************************************************************* # This is a Makefile fragment, see src/std/Makefile. diff --git a/src/std/rec/Makefile b/src/std/rec/Makefile index 561058620..b2c0512ed 100644 --- a/src/std/rec/Makefile +++ b/src/std/rec/Makefile @@ -4,7 +4,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/std/Makefile. diff --git a/src/template/base/Makefile b/src/template/Makefile similarity index 69% rename from src/template/base/Makefile rename to src/template/Makefile index bfc6de244..5b9c38ec4 100644 --- a/src/template/base/Makefile +++ b/src/template/Makefile @@ -1,24 +1,9 @@ -TOP=../../.. +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 @@ -63,23 +48,6 @@ 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 @@ -93,7 +61,4 @@ 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/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/ext/Makefile b/src/template/ext/Makefile deleted file mode 100644 index 06c529aa1..000000000 --- a/src/template/ext/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -TOP=../../.. - -include $(TOP)/configure/CONFIG - -TEMPLATES_DIR = makeBaseExt - -TEMPLATES += top/Makefile -TEMPLATES += top/README -TEMPLATES += top/configure/CONFIG -TEMPLATES += top/configure/CONFIG_SITE -TEMPLATES += top/configure/Makefile -TEMPLATES += top/configure/RELEASE -TEMPLATES += top/configure/RULES -TEMPLATES += top/configure/RULES_DIRS -TEMPLATES += top/configure/RULES_TOP -TEMPLATES += top/configure/RULES_PYTHON -TEMPLATES += top/configure/RULES_IDL - -TEMPLATES += $(subst ../,,$(wildcard ../top/configure/os/CONFIG*)) - -TEMPLATES += top/src/Makefile - -TEMPLATES += top/exampleExt/Makefile -TEMPLATES += top/exampleExt/caExample.c -TEMPLATES += top/exampleExt/RELEASE_NOTES.HTM - -TEMPLATES += top/simpleExt/Makefile - -SCRIPTS_HOST += makeBaseExt.pl - -include $(TOP)/configure/RULES - diff --git a/src/template/ext/makeBaseExt.pl b/src/template/ext/makeBaseExt.pl deleted file mode 100644 index a3bf895d8..000000000 --- a/src/template/ext/makeBaseExt.pl +++ /dev/null @@ -1,307 +0,0 @@ -#!/usr/bin/env perl - -# Authors: Ralph Lange, Marty Kraimer, Andrew Johnson and Janet Anderson - -use Cwd; -use Getopt::Std; -use File::Copy; -use File::Find; -use File::Path; - -$user = GetUser(); -$cwd = cwd(); -$eEXTTYPE = $ENV{EPICS_MBE_DEF_EXT_TYPE}; -$eTOP = $ENV{EPICS_MBE_TEMPLATE_TOP}; -$eBASE = $ENV{EPICS_MBE_BASE}; - -get_commandline_opts(); # Read and check options - -$extname = "@ARGV"; - -# -# Declare two default callback routines for file copy plus two -# hook routines to add conversions -# These may be overriden within $top/$exttypename/Replace.pl - -# First: the hooks -sub ReplaceFilenameHook { return $_[0]; } -sub ReplaceLineHook { return $_[0]; } - -# ReplaceFilename -# called with the source (template) file or directory name, returns -# the "real" name (which gets the target after $top is removed) -# Empty string: Don't copy this file -sub ReplaceFilename { # (filename) - my($file) = $_[0]; - $file =~ s|.*/CVS/?.*||; # Ignore CVS files - if ($ext) { # exttypenameExt itself is dynamic, too - $file =~ s|/$exttypename|/$extdir|; - $file =~ s|/$extdir/configure|/configure/$exttype|; - } - $file =~ s|_EXTNAME_|$extname|; - $file =~ s|_EXTTYPE_|$exttype|; - # We don't want the Replace overrides - $file =~ s|.*/$extdir/Replace.pl$||; - $file = ReplaceFilenameHook($file); # Call the user-defineable hook - return $file; -} - -# ReplaceLine -# called with one line of a file, returns the line after replacing -# this and that -sub ReplaceLine { # (line) - my($line) = $_[0]; - $line =~ s/_USER_/$user/o; - $line =~ s/_EPICS_BASE_/$epics_base/o; - $line =~ s/_ARCH_/$arch/o; - $line =~ s/_EXTNAME_/$extname/o; - $line =~ s/_EXTTYPE_/$exttype/o; - $line =~ s/_TEMPLATE_TOP_/$top/o; - $line = ReplaceLineHook($line); # Call the user-defineable hook - return $line; -} - -# Source replace overrides for file copy -if (-r "$top/$exttypename/Replace.pl") { - require "$top/$exttypename/Replace.pl"; -} - -# -# Copy files and trees from (non-Ext) if not present -# -opendir TOPDIR, "$top" or die "Can't open $top: $!"; -foreach $f ( grep !/^\.\.?$|^[^\/]*(Ext)/, readdir TOPDIR ) { - if (-f "$f") { - CopyFile("$top/$f") unless (-e "$f"); - } else { - $note = yes if ("$f" eq "src" && -e "$f"); - find(\&FCopyTree, "$top/$f") unless (-e "$f"); - } -} -closedir TOPDIR; - -# -# Create ext directories (if any names given) -# -$cwdsave = $cwd; -$cwd = "$cwd/src"; -foreach $ext ( @ARGV ) { - ($extname = $ext) =~ s/Ext$//; - $extdir = $extname; - if (-d "src/$extdir") { - print "Extention $extname is already there!\n"; - next; - } - print "Creating template structure " - . "for $extname (of type $exttypename)\n" if $Debug; - find(\&FCopyTree, "$top/$exttypename/"); - if ($note) { - print "\nNOTE: You must add the line \"DIRS += $extname\" to src/Makefile.\n\n"; - } -} -$cwd = $cwdsave; - -exit 0; # END OF SCRIPT - -# -# Get commandline options and check for validity -# -sub get_commandline_opts { #no args - ($len = @ARGV) and getopts("ldit:T:b:a:") or Cleanup(1); - -# Debug option - $Debug = 1 if $opt_d; - -# Locate epics_base - my ($command) = UnixPath($0); - if ($opt_b) { # first choice is -b base - $epics_base = UnixPath($opt_b); - } elsif (-r "configure/RELEASE") { # second choice is configure/RELEASE - open(IN, "configure/RELEASE") or die "Cannot open configure/RELEASE"; - while () { - chomp; - s/EPICS_BASE\s*=\s*// and $epics_base = UnixPath($_), break; - } - close IN; - } elsif ($eBASE) { # third choice is env var EPICS_MBE_BASE - $epics_base = UnixPath($eBASE); - } elsif ($command =~ m|/bin/|) { # assume script was called with full path to base - $epics_base = $command; - $epics_base =~ s|(/.*)/bin/.*makeBaseExt.*|$1|; - } - "$epics_base" or Cleanup(1, "Cannot find EPICS base"); - -# Locate template top directory - if ($opt_T) { # first choice is -T templ-top - $top = UnixPath($opt_T); - } elsif (-r "configure/RELEASE") { # second choice is configure/RELEASE - open(IN, "configure/RELEASE") or die "Cannot open configure/RELEASE"; - while () { - chomp; - s/TEMPLATE_TOP\s*=\s*// and $top = UnixPath($_), break; - } - close IN; - } - if("$top" eq "") { - if ($eTOP) { # third choice is $ENV{EPICS_MBE_TEMPL_TOP} - $top = UnixPath($eTOP); - } else { # use templates from EPICS base - $top = $epics_base . "/templates/makeBaseExt/top"; - } - } - "$top" or Cleanup(1, "Cannot find template top directory"); - -# Print extension type list? - if ($opt_l) { - ListExtTypes(); - exit 0; # finished for -l command - } - -# Extention template type - if ($opt_t) { # first choice is -t type - $exttype = $opt_t; - } elsif ($eEXTTYPE) { # second choice is $ENV{EPICS_DEFAULT_EXT_TYPE} - $exttype = $eEXTTYPE; - } elsif (-r "$top/defaultExt") {# third choice is (a link) in the $top dir - $exttype = "default"; - } elsif (-r "$top/exampleExt") {# fourth choice is (a link) in the $top dir - $exttype = "example"; - } - $exttype =~ s/Ext$//; - "$exttype" or Cleanup(1, "Cannot find default extension type"); - $exttypename = $exttype . "Ext"; - -# Valid $exttypename? - unless (-r "$top/$exttypename") { - print "Template for extension type '$exttype' is unreadable or does not exist.\n"; - ListExtTypes(); - exit 1; - } - - print "\nCommand line / environment options validated:\n" - . " Templ-Top: $top\n" - . "Templ-Type: $exttype\n" - . "Templ-Name: $exttypename\n" - . "EPICS-Base: $epics_base\n\n" if $Debug; - -} - -# -# List extension types -# -sub ListExtTypes { # no args - print "Valid extension types are:\n"; - foreach $name (<$top/*Ext>) { - $name =~ s|$top/||; - $name =~ s|Ext||; - printf "\t$name\n" if ($name && -r "$top/$name" . "Ext"); - } -} - -# -# Copy a file with replacements -# -sub CopyFile { # (source) - $source = $_[0]; - $target = ReplaceFilename($source); - - if ($target) { - $target =~ s|$top/||; - open(INP, "<$source") and open(OUT, ">$target") - or die "$! Copying $source -> $target"; - - print "Copying file $source -> $target\n" if $Debug; - while () { - print OUT ReplaceLine($_); - } - close INP; close OUT; - } -} - -# -# Find() callback for file or structure copy -# -sub FCopyTree { - chdir $cwd; # Sigh - if (-d $File::Find::name - and ($dir = ReplaceFilename($File::Find::name))) { - $dir =~ s|$top/||; - print "Creating directory $dir\n" if $Debug; - mkpath($dir); - } else { - CopyFile($File::Find::name); - } - chdir $File::Find::dir; -} - -# -# Cleanup and exit -# -sub Cleanup { # (return-code [ messsage-line1, line 2, ... ]) - my ($rtncode, @message) = @_; - - foreach $line ( @message ) { - print "$line\n"; - } - - print </bin//makeBaseExt.pl -t example example - -EOF - - exit $rtncode; -} - -sub GetUser { # no args - my ($user); - - # add to this list if new possibilities arise, - # currently it's UNIX and WIN32: - $user = $ENV{USER} || $ENV{USERNAME} || Win32::LoginName(); - - unless ($user) { - print "I cannot figure out your user name.\n"; - print "What shall you be called ?\n"; - print ">"; - $user = ; - chomp $user; - } - die "No user name" unless $user; - return $user; -} - -# replace "\" by "/" (for WINxx) -sub UnixPath { # path - my($newpath) = $_[0]; - $newpath =~ s|\\|/|go; - return $newpath; -} diff --git a/src/template/ext/top/Makefile b/src/template/ext/top/Makefile deleted file mode 100644 index 91e678167..000000000 --- a/src/template/ext/top/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# Makefile at the top of an extensions tree - -TOP = . -include $(TOP)/configure/CONFIG -DIRS += configure -DIRS += src -include $(TOP)/configure/RULES_TOP - - diff --git a/src/template/ext/top/README b/src/template/ext/top/README deleted file mode 100644 index c0e91eb9c..000000000 --- a/src/template/ext/top/README +++ /dev/null @@ -1,5 +0,0 @@ -Notes: - -Each time you add a new extension in the src directory you -must add the extension directory name to src/Makefile. - diff --git a/src/template/ext/top/configure/CONFIG b/src/template/ext/top/configure/CONFIG deleted file mode 100644 index 321f6cea2..000000000 --- a/src/template/ext/top/configure/CONFIG +++ /dev/null @@ -1,43 +0,0 @@ -# CONFIG - Load build configuration data -# -# Do not make changes in this file, any site-specific -# overrides should be given in a CONFIG_SITE file. - -# Where the build rules come from -RULES = $(EPICS_BASE) - -INSTALL_IDLFILE = $(INSTALL) - -include $(TOP)/configure/RELEASE --include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH) --include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common - -ifdef T_A - -include $(TOP)/configure/RELEASE.Common.$(T_A) - -include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A) -endif - -CONFIG = $(RULES)/configure -include $(CONFIG)/CONFIG - -# Override some Base definitions -INSTALL_LOCATION = $(TOP) - -# CONFIG_SITE files contain build configuration overrides -include $(TOP)/configure/CONFIG_SITE - -# Host-arch specific settings --include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).Common - -ifdef INSTALL_LOCATION_EXTENSIONS - INSTALL_LOCATION = $(INSTALL_LOCATION_EXTENSIONS) -endif - -ifdef T_A - # Target-arch specific settings - -include $(TOP)/configure/os/CONFIG_SITE.Common.$(T_A) - - # Host & target specific combination settings - -include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) -endif - diff --git a/src/template/ext/top/configure/CONFIG_SITE b/src/template/ext/top/configure/CONFIG_SITE deleted file mode 100644 index 4ef88cedf..000000000 --- a/src/template/ext/top/configure/CONFIG_SITE +++ /dev/null @@ -1,20 +0,0 @@ -# CONFIG_SITE -# -# Make any extensions-specific changes to the EPICS build -# configuration variables in this file. -# -# Host/target specific settings are in os subdirectory files named -# os/CONFIG_SITE.$(EPICS_HOST_ARCH).Common -# os/CONFIG_SITE.Common.$(T_A) -# os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) - -# Extensions are not normally built for cross targets -CROSS_COMPILER_TARGET_ARCHS = - -# If you don't want to install into $(TOP) then -# define INSTALL_LOCATION here -#INSTALL_LOCATION= - -# Extensions don't normally build shared libraries -SHARED_LIBRARIES = NO - diff --git a/src/template/ext/top/configure/Makefile b/src/template/ext/top/configure/Makefile deleted file mode 100644 index 6e6609842..000000000 --- a/src/template/ext/top/configure/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# Makefile in extensions/configure directory - -TOP=.. - -include $(TOP)/configure/CONFIG - -TARGETS = $(CONFIG_TARGETS) - -include $(TOP)/configure/RULES - diff --git a/src/template/ext/top/configure/RELEASE b/src/template/ext/top/configure/RELEASE deleted file mode 100644 index 2a7ad2714..000000000 --- a/src/template/ext/top/configure/RELEASE +++ /dev/null @@ -1,23 +0,0 @@ -# RELEASE Locations of external modules -# -# NOTE: The build does not check dependancies on files -# external to this application. Thus you should run -# "gnumake clean uninstall install" in the top directory -# each time EPICS_BASE or any other external module that -# is defined in a RELEASE* file gets rebuilt. -# -# Host/target specific paths can be specified in files named -# RELEASE.$(EPICS_HOST_ARCH).Common -# RELEASE.Common.$(T_A) -# RELEASE.$(EPICS_HOST_ARCH).$(T_A) - -# Define INSTALL_LOCATION in CONFIG_SITE - -EPICS_EXTENSIONS = $(TOP) - -# Locations of external modules - -# OAG_APPS may be needed by the SDDS extension -#OAG_APPS = $(TOP)/../../oag/apps - -EPICS_BASE = _EPICS_BASE_ diff --git a/src/template/ext/top/configure/RULES b/src/template/ext/top/configure/RULES deleted file mode 100644 index 7592a37c6..000000000 --- a/src/template/ext/top/configure/RULES +++ /dev/null @@ -1,9 +0,0 @@ -# extensions/configure/RULES - -include $(CONFIG)/RULES --include $(TOP)/configure/RULES_PYTHON --include $(TOP)/configure/RULES_IDL - -ifdef BASE_3_15 - -include $(TOP)/configure/RULES_JAVA -endif diff --git a/src/template/ext/top/configure/RULES_DIRS b/src/template/ext/top/configure/RULES_DIRS deleted file mode 100644 index dd6904367..000000000 --- a/src/template/ext/top/configure/RULES_DIRS +++ /dev/null @@ -1,3 +0,0 @@ -# extensions/configure/RULES_DIRS - -include $(CONFIG)/RULES_DIRS diff --git a/src/template/ext/top/configure/RULES_IDL b/src/template/ext/top/configure/RULES_IDL deleted file mode 100644 index 3610bcc21..000000000 --- a/src/template/ext/top/configure/RULES_IDL +++ /dev/null @@ -1,30 +0,0 @@ -# extensions/configure/RULES_IDL - -ifdef T_A -ifeq ($(findstring Host,$(VALID_BUILDS)),Host) - -INSTALL_IDL = $(INSTALL_LOCATION)/idllib -DIRECTORY_TARGETS += $(INSTALL_IDL) - -ifneq ($(strip $(IDLS_$(OS_CLASS))),) -IDLS += $(subst -nil-,,$(IDLS_$(OS_CLASS))) -else -ifdef IDLS_DEFAULT -IDLS += $(IDLS_DEFAULT) -endif -endif - -INSTALL_IDLS =$(IDLS:%=$(INSTALL_IDL)/%) - -buildInstall : $(INSTALL_IDLS) - -$(INSTALL_IDL)/%: % - @echo "Installing idl program $@" - @$(INSTALL_IDLFILE) -d -m 644 $< $(INSTALL_IDL) - -$(INSTALL_IDL)/%: ../% - @echo "Installing idl program $@" - @$(INSTALL_IDLFILE) -d -m 644 $< $(INSTALL_IDL) - -endif -endif diff --git a/src/template/ext/top/configure/RULES_JAVA b/src/template/ext/top/configure/RULES_JAVA deleted file mode 100644 index b6ffa3f0f..000000000 --- a/src/template/ext/top/configure/RULES_JAVA +++ /dev/null @@ -1,158 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - - -ifeq ($(BUILD_CLASS),HOST) - -#------------------------------------------------------- -# java jdk1.1.5 definitions - -INSTALL_JAVA = $(INSTALL_LOCATION)/javalib -UNINSTALL_DIRS += $(INSTALL_JAVA) - -JAVA_INC = $(JAVA_DIR)/include -JAVA_BIN = $(JAVA_DIR)/bin -JAVA_INCLUDES += -I$(JAVA_INC) -I$(JAVA_INC)/$(word 1, $(subst -, ,$(T_A))) -I$(COMMON_DIR) - -JAVACCMD = $(subst \,/,$(JAVA_BIN)/javac$(EXE) $(CLASSPATH) $(SOURCEPATH) $(JAVACFLAGS)) -JAVAHCMD = $(subst \,/,$(JAVA_BIN)/javah$(EXE) -d $(COMMON_DIR) -force $(CLASSPATH) $(JAVAHFLAGS)) -JARCMD = $(subst \,/,$(JAVA_BIN)/jar$(EXE) $(JAR_OPTIONS) $@ $(JARINPUT) $(JARPACKAGES)) - -#------------------------------------------------------- -vpath %.java .. -vpath %.jar .. $(COMMON_DIR) - -empty:= -space:= $(empty) $(empty) -CLASSPATH = -classpath $(subst $(space),:,$(strip $(USR_PRECLASSPATH) $(INSTALL_JAVA) $(USR_CLASSPATH))) -SOURCEPATH = -sourcepath .:..:../.. - -#------------------------------------------------------- -# Java directory - -ifdef JAVA -JAVA_DIRECTORY_TARGETS += $(INSTALL_JAVA) -endif - -#------------------------------------------------------- -# Java native method C header files - -JAVAHFLAGS += $(USR_JAVAHFLAGS) -JAVAINC_CLASSFILES += $(addprefix $(INSTALL_JAVA)/,$(subst _,/,$(subst .h,.class,$(JAVAINC)))) -JAVAINC_CLASSNAMES += $(subst _,.,$(subst .h,,$(JAVAINC))) -COMMON_JAVAINC += $(addprefix $(COMMON_DIR)/,$(JAVAINC)) - -#------------------------------------------------------- -# Java class files - -JAVACFLAGS += $(USR_JAVACFLAGS) -CLASSES += $(subst .java,.class,$(JAVA)) -INSTALL_CLASSES = $(addprefix $(INSTALL_JAVA)/,$(CLASSES)) - -TESTCLASSES += $(subst .java,.class,$(notdir $(TESTJAVA))) -COMMON_TESTCLASSES += $(addprefix $(COMMON_DIR)/,$(TESTCLASSES)) -DEPTESTJAVA += $(subst .class,.java,$(TESTCLASSES)) - -#------------------------------------------------------- -# Java jar file - -INSTALL_JAR =$(addprefix $(INSTALL_JAVA)/,$(JAR)) -JARMANIFEST += $(firstword $(MANIFEST) $(JAR_MANIFEST)) -JARDEPFILES += $(addprefix $(INSTALL_JAVA)/,$(subst .java,.class,$(JAVA)) $(JAR_INPUT)) -JARINPUT += $(foreach inp,$(JAR_INPUT),-C $(INSTALL_JAVA) $(subst .java,.class,$(inp))) -JARPACKAGES += $(foreach pkg,$(JAR_PACKAGES),-C $(INSTALL_JAVA) $(subst .,/,$(pkg))) -PACKAGEDIRS += $(foreach pkg,$(JAR_PACKAGES),$(addprefix $(INSTALL_JAVA)/,$(subst .,/,$(pkg)))) - -ifneq ($(JARMANIFEST),) -JAR_OPTIONS = cvmf $(JARMANIFEST) -else -JAR_OPTIONS = cvf -endif - -#------------------------------------------------------- -# Java doc definitions -ifdef JAVADOC -JAVADOCFLAGS += $(USR_JAVADOCFLAGS) -JAVADOCCMD = $(subst \,/,$(JAVA_BIN)/javadoc$(EXE) $(CLASSPATH) $(SOURCEPATH) $(JAVADOCFLAGS)) -INSTALL_JAVADOC = $(addprefix $(INSTALL_HTML)/,$(JAVADOC))/index.html -endif - -#------------------------------------------------------- -# Java rules - -all: install - -install: buildInstall - -buildInstall : build - -rebuild: clean install - -inc: $(JAVA_DIRECTORY_TARGETS) $(INSTALL_CLASSES) $(COMMON_JAVAINC) - -build: inc - -build: $(COMMON_TESTCLASSES) - -buildInstall : $(INSTALL_JAR) $(INSTALL_JAVADOC) - -#This clean works only from O.* dirs. -buildclean: - @$(RMDIR) $(INSTALL_CLASSES) $(PACKAGEDIRS) - @$(RM) $(INSTALL_JAR) $(INSTALL_JAVADOC) - @$(RM) $(COMMON_TESTCLASSES) $(COMMON_JAVAINC) - -ifdef JAVA_DIRECTORY_TARGETS -$(JAVA_DIRECTORY_TARGETS): - $(MKDIR) $@ -endif - -$(COMMON_JAVAINC):$(JAVAINC_CLASSFILES) - $(ECHO) Creating header files $(COMMON_JAVAINC) - @$(RM) $@ - $(JAVAHCMD) $(JAVAINC_CLASSNAMES) - -$(COMMON_TESTCLASSES): $(addprefix ../,$(DEPTESTJAVA)) - $(ECHO) Creating test java class files $(COMMON_TESTCLASSES) - @$(RM) $@ - $(JAVACCMD) -d $(COMMON_DIR) $^ - -$(INSTALL_CLASSES): $(addprefix ../,$(JAVA)) - $(ECHO) Creating java class files - @$(RM) $@ - $(JAVACCMD) -d $(INSTALL_JAVA) $^ - -$(INSTALL_JAVADOC): $(addprefix ../,$(JAVA)) - $(ECHO) Creating java doc files - @$(RM) $@ - $(JAVADOCCMD) -d $(addprefix $(INSTALL_HTML)/,$(JAVADOC)) $^ - -$(COMMON_DIR)/%.jar: $(JARDEPFILES) - $(ECHO) Creating java jar file $@ - @$(RM) $@ - $(JARCMD) - -$(INSTALL_JAVA)/%.jar: $(COMMON_DIR)/%.jar - $(ECHO) "Installing java jar file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -$(INSTALL_JAVA)/%.jar: %.jar - $(ECHO) "Installing java jar file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -$(addprefix $(INSTALL_JAVA)/, $(JARINPUT)): $(INSTALL_JAVA)/%: ../% - $(ECHO) "Installing jar input file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -.PHONY: all install buildInstall rebuild clean build inc - -.PRECIOUS: $(COMMON_JAVAINC) - -endif diff --git a/src/template/ext/top/configure/RULES_PYTHON b/src/template/ext/top/configure/RULES_PYTHON deleted file mode 100644 index 49dffa02b..000000000 --- a/src/template/ext/top/configure/RULES_PYTHON +++ /dev/null @@ -1,54 +0,0 @@ -# extensions/configure/RULES_PYTHON - -ifdef T_A -ifeq ($(findstring Host,$(VALID_BUILDS)),Host) - -SWIG ?= swig - -vpath %.py $(USR_VPATH) $(ALL_SRC_DIRS) - -# The optional PYTHON_INSTALL_LOCATION environment variable -# should be set to /site-packages -PYTHON_INSTALL_LOCATION ?= $(INSTALL_LOCATION)/lang/python - -INSTALL_PYTHON = $(PYTHON_INSTALL_LOCATION)/$(PYTHON_PACKAGE) - -PYTHON_PACKAGE_PTH = $(addsuffix .pth,$(PYTHON_PACKAGE)) -INSTALL_PYTHON_PACKAGE_PTH = $(addprefix $(PYTHON_INSTALL_LOCATION)/,$(PYTHON_PACKAGE_PTH)) - -PYTHON_SCRIPTS = $(filter-out $(LOADABLE_LIBRARY),$(PYTHON_MODULES)) -PYTHON_LIBRARY = $(filter $(LOADABLE_LIBRARY),$(PYTHON_MODULES)) -PYTHON_SHRLIBNAME = $(PYTHON_LIBRARY:%=$(LOADABLE_SHRLIB_PREFIX)%$(LOADABLE_SHRLIB_SUFFIX)) - -INSTALL_PYTHONS = $(addprefix $(INSTALL_PYTHON)/,$(PYTHON_SCRIPTS)) -INSTALL_PYTHONS += $(addprefix $(INSTALL_PYTHON)/,$(PYTHON_SHRLIBNAME)) - -buildInstall: $(INSTALL_PYTHONS) $(INSTALL_PYTHON_PACKAGE_PTH) - -$(INSTALL_PYTHON)/%: % - @echo "Installing python modules $@" - @$(INSTALL) -d -m 644 $< $(INSTALL_PYTHON) - -$(INSTALL_PYTHON)/%: ../% - @echo "Installing python modules $@" - @$(INSTALL) -d -m 644 $< $(INSTALL_PYTHON) - -$(PYTHON_INSTALL_LOCATION)/%: % - @echo "Installing python pth file $@" - @$(INSTALL) -d -m 644 $< $(PYTHON_INSTALL_LOCATION) - -$(PYTHON_PACKAGE_PTH): - @echo $(PYTHON_PACKAGE) > $@ - -%_wrap.c: ../%.i - $(SWIG) -python -o $@ $< - -ifdef BASE_3_15 -clean: -else -clean:: -endif - @$(RM) *.py *.so *.pth - -endif -endif diff --git a/src/template/ext/top/configure/RULES_TOP b/src/template/ext/top/configure/RULES_TOP deleted file mode 100644 index 1f81d3d39..000000000 --- a/src/template/ext/top/configure/RULES_TOP +++ /dev/null @@ -1,4 +0,0 @@ -# extensions/configure/RULES_TOP - -include $(CONFIG)/RULES_TOP - diff --git a/src/template/ext/top/configure/os/CONFIG.linux-x86.linux-386 b/src/template/ext/top/configure/os/CONFIG.linux-x86.linux-386 deleted file mode 100644 index ed73b3464..000000000 --- a/src/template/ext/top/configure/os/CONFIG.linux-x86.linux-386 +++ /dev/null @@ -1,2 +0,0 @@ - -include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86 diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.Common.Common b/src/template/ext/top/configure/os/CONFIG_SITE.Common.Common deleted file mode 100644 index 21363a633..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.Common.Common +++ /dev/null @@ -1,10 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# java jdk definitions -#CLASSPATH += -classpath .:..:$(INSTALL_JAVA):$(JAVA_DIR)/bin/../classes:$(JAVA_DIR)/bin/../lib/classes.zip -#JAVACCMD = $(subst \,/,$(JAVA_DIR)/bin/javac$(EXE) $(CLASSPATH) $(JAVAC_FLAGS) ) -#JAVAHCMD = $(subst \,/,$(JAVA_DIR)/bin/javah$(EXE) -jni $(CLASSPATH) $(JAVAH_FLAGS)) -#JARCMD = $(subst \,/,$(JAVA_DIR)/bin/jar$(EXE) $(JAR_OPTIONS) $(MANIFEST) $(JAR) $(JAR_INPUT)) - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.aix-ppc-gnu.aix-ppc-gnu b/src/template/ext/top/configure/os/CONFIG_SITE.aix-ppc-gnu.aix-ppc-gnu deleted file mode 100644 index 19d65aead..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.aix-ppc-gnu.aix-ppc-gnu +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.aix-ppc.aix-ppc - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.aix-ppc.aix-ppc b/src/template/ext/top/configure/os/CONFIG_SITE.aix-ppc.aix-ppc deleted file mode 100644 index 3f40e0b37..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.aix-ppc.aix-ppc +++ /dev/null @@ -1,77 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common - -# sun X11 -X11_LIB = /usr/openwin/lib -X11_INC = /usr/openwin/include -# mit X11 -#X11_LIB = /opt/X11R5/lib -#X11_INC = /opt/X11R5/include -# osf motif -#MOTIF_INC = /opt/local/Motif2.0/include -#MOTIF_LIB = /opt/local/Motif2.0/lib -# sun SDK motif -#MOTIF_INC = /opt/SUNWmotif/include -#MOTIF_LIB = /opt/SUNWmotif/lib -# sun 5.4,5.6 SDK motif -MOTIF_INC = /usr/dt/include -MOTIF_LIB = /usr/dt/lib -OPENWIN = /usr/openwin - -INTERVIEWS_BIN=/usr/local/interviews/bin/O.solaris -INTERVIEWS_LIB=/usr/local/interviews/lib/O.solaris -IV_INC=/usr/local/interviews/include -IV-2_6_INC=/usr/local/interviews/include/IV-2_6 -IV_BIN=/usr/local/interviews/bin/O.solaris -IV_LIB=/usr/local/interviews/lib/O.solaris - -WINGZ_INC = /opt/local/Wingz2/incl -WINGZ_LIB = /opt/local/Wingz2/lib -#MATHEMATICA = /usr/local/math -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -XRTGRAPH_EXTENSIONS = YES -XRTGRAPH = /opt/local/xrtgraph -QUESTWIN = /usr/local/questwin - -TK_LIB = /opt/local/lib -TK_INC = /opt/local/include -TCL_LIB = /opt/local/lib -TCL_INC = /opt/local/include -DP_LIB = /opt/local/lib -DP_INC = /opt/local/include -BLT_LIB = /opt/local/lib -BLT_INC = /opt/local/include - -IDL = /usr/local/idl -# IDL=$(IDL)/external/rpc is the sun4 version -IDLRPC = $(IDL)/external/rpc.solaris - -ZLIB_PREFIX = /usr/local/oag -ZLIB = $(notdir $(wildcard $(ZLIB_PREFIX)/lib/libz.a)) -ifeq ($(ZLIB) , libz.a) -ZLIB_LIB = $(ZLIB_PREFIX)/lib -ZLIB_INC = -I$(ZLIB_PREFIX)/include -ZLIB_CFLAG = -DzLib -ZLIB_PROD_LIB = z -z_DIR=$(ZLIB_PREFIX)/lib -else -ZLIB_LIB = -ZLIB_INC = -ZLIB_CFLAG = -ZLIB_PROD_LIB = -z_DIR= -endif - -PYTHON_DIR=/opt/local/lib/python2.2 -PYTHON_INCLUDE=/opt/local/include/python2.2 - -JAVA_DIR=/usr/java diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 b/src/template/ext/top/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 deleted file mode 100644 index f1745159b..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 +++ /dev/null @@ -1,54 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common --include $(TOP)/configure/os/CONFIG_SITE.win32-x86.win32-x86 - -# ---------- java definitions -JAVA_DIR=c:/j2sdk1.4.1_01 - -# ---------- tcl/tk definitions -TCL = c:\\Tcl -TK_LIB = $(TCL)/lib -TK_INC = $(TCL)/include -TCL_LIB = $(TCL)/lib -TCL_INC = $(TCL)/include -DP_LIB = $(TCL)/lib -DP_INC = $(TCL)/include -BLT_LIB = $(TCL)/lib -BLT_INC = $(TCL)/include - -IDL = /usr/local/idl -# IDL=$(IDL)/external/rpc is the sun4 version -IDLRPC = $(IDL)/external/rpc.solaris - -#X11_LIB = c:/cygwin/lib -#X11_INC = c:/cygwin/include - -#MOTIF_LIB = $(X11_LIB) -#MOTIF_INC = $(X11_INC) - -OPENWIN = -INTERVIEWS_BIN = -WINGZ_INC = -WINGZ_LIB = -MATHEMATICA = -QUESTWIN = - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -XRTGRAPH_EXTENSIONS = NO -XRTGRAPH = - -SCIPLOT = ../../src/medmdev/medm - -# z library created in SDDS extension -ZLIB_CFLAG = -DzLib -ZLIB_PROD_LIB = z -z_DIR = $(EPICS_EXTENSIONS_LIB) diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.darwin-ppc.darwin-ppc b/src/template/ext/top/configure/os/CONFIG_SITE.darwin-ppc.darwin-ppc deleted file mode 100644 index d8fb7c158..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.darwin-ppc.darwin-ppc +++ /dev/null @@ -1,81 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common - -PYTHON_DIR=/usr/lib/python2.2 -PYTHON_INCLUDE=/System/Library/Frameworks/Python.framework/Versions/2.3/include/python2.3 - -# Following 3 for SDDS -#USE_GD_LIBRARY=1 -#USE_RUNCONTROL=1 -#USE_LOGDAEMON=1 - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - -# -# XDarwin -# -X11_LIB=/usr/X11R6/lib -X11_INC=/usr/X11R6/include/X11 -XPM_LIB=/usr/X11R6/lib -XPM_INC=/usr/X11R6/include/X11 - -# -# Fink OpenMotif -# -MOTIF_LIB=/sw/lib -MOTIF_INC=/sw/include - -# -# DarwinPorts OpenMotif -# -#MOTIF_LIB=/opt/local/lib -#MOTIF_INC=/opt/local/include - -# -# Interviews -# -IV_INC= -IV-2_6_INC= -IV_BIN= -IV_LIB= - -OPENWIN = -WINGZ_INC = -WINGZ_LIB = -MATHEMATICA = - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -#XRTGRAPH_EXTENSIONS = YES -#XRTGRAPH = /opt/local/xrtgraph - -SCIPLOT = YES -QUESTWIN = - -TK_LIB = /sw/lib -TK_INC = /sw/include -TCL_LIB = /sw/lib -TCL_INC = /sw/include -DP_LIB = /sw/lib -DP_INC = /sw/include -BLT_LIB = /sw/lib -BLT_INC = /sw/include - -# -# Preliminary JAVA support -# -JAVA_DIR=/System/Library/Frameworks/JavaVM.framework/Home -JAVA_INC=/System/Library/Frameworks/JavaVM.framework/Headers -JAVA_INCLUDES = -I$(JAVA_INC) - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.darwin-ppcx86.darwin-ppcx86 b/src/template/ext/top/configure/os/CONFIG_SITE.darwin-ppcx86.darwin-ppcx86 deleted file mode 100644 index 6e31ffdb4..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.darwin-ppcx86.darwin-ppcx86 +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.darwin-ppc.darwin-ppc - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.darwin-x86.darwin-x86 b/src/template/ext/top/configure/os/CONFIG_SITE.darwin-x86.darwin-x86 deleted file mode 100644 index 9e98c70ef..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.darwin-x86.darwin-x86 +++ /dev/null @@ -1,81 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common - -PYTHON_DIR=/usr/lib/python2.2 -PYTHON_INCLUDE=/System/Library/Frameworks/Python.framework/Versions/2.3/include/python2.3 - -# Following 3 for SDDS -#USE_GD_LIBRARY=1 -#USE_RUNCONTROL=1 -#USE_LOGDAEMON=1 - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - -# -# XDarwin -# -X11_LIB=/usr/X11R6/lib -X11_INC=/usr/X11R6/include -XPM_LIB=/usr/X11R6/lib -XPM_INC=/usr/X11R6/include - -# -# Fink OpenMotif -# -#MOTIF_LIB=/sw/lib -#MOTIF_INC=/sw/include - -# -# DarwinPorts OpenMotif -# -MOTIF_LIB=/opt/local/lib -MOTIF_INC=/opt/local/include - -# -# Interviews -# -IV_INC= -IV-2_6_INC= -IV_BIN= -IV_LIB= - -OPENWIN = -WINGZ_INC = -WINGZ_LIB = -MATHEMATICA = - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -#XRTGRAPH_EXTENSIONS = YES -#XRTGRAPH = /opt/local/xrtgraph - -SCIPLOT = YES -QUESTWIN = - -TK_LIB = /sw/lib -TK_INC = /sw/include -TCL_LIB = /sw/lib -TCL_INC = /sw/include -DP_LIB = /sw/lib -DP_INC = /sw/include -BLT_LIB = /sw/lib -BLT_INC = /sw/include - -# -# Preliminary JAVA support -# -JAVA_DIR=/System/Library/Frameworks/JavaVM.framework/Home -JAVA_INC=/System/Library/Frameworks/JavaVM.framework/Headers -JAVA_INCLUDES = -I$(JAVA_INC) - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.freebsd-x86_64.freebsd-x86_64 b/src/template/ext/top/configure/os/CONFIG_SITE.freebsd-x86_64.freebsd-x86_64 deleted file mode 100644 index c4d1d5670..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.freebsd-x86_64.freebsd-x86_64 +++ /dev/null @@ -1,10 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.linux-ppc.linux-ppc b/src/template/ext/top/configure/os/CONFIG_SITE.linux-ppc.linux-ppc deleted file mode 100644 index 4d78b29d7..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.linux-ppc.linux-ppc +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86-debug.linux-x86-debug b/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86-debug.linux-x86-debug deleted file mode 100644 index 4d78b29d7..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86-debug.linux-x86-debug +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86.linux-athlon b/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86.linux-athlon deleted file mode 100644 index 25036ccac..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86.linux-athlon +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - - --include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86 diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86.linux-x86 b/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86.linux-x86 deleted file mode 100644 index 8641a9d27..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86.linux-x86 +++ /dev/null @@ -1,57 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common - -#X11_LIB=/usr/X11R6/lib -#X11_INC=/usr/X11R6/include -#MOTIF_LIB=/usr/X11R6/lib -#MOTIF_INC=/usr/X11R6/include - -#With the release of Fedora Core 5 the -#X11 and MOTIF libraries now live at /usr/lib -X11_LIB=/usr/lib -X11_INC=/usr/include -MOTIF_LIB=/usr/lib -MOTIF_INC=/usr/include - -OPENWIN = -WINGZ = -MATHEMATICA = -QUESTWIN = -TK_TCL = /usr/lib -IDL = - -#JAVA_DIR=/usr/local/java -#JAVA_DIR=/usr/java/j2sdk1.4.1 -JAVA_DIR=/usr -JAVA_INC=$(JAVA_DIR)/include - -INTERVIEWS_BIN=/usr/local/interviews/bin/O.Linux - -IV_INC=/usr/local/interviews/include -IV_BIN=/usr/local/interviews/bin/O.Linux -IV_LIB=/usr/local/interviews/lib/O.Linux - -PYTHON_DIR=/usr/lib/python2.2 -PYTHON_INCLUDE=/usr/include/python2.2 - -CLAPACK_LIB = /usr/local/oag/3rdParty/CLAPACK/Linux_P4SSE2/lib -ATLAS_LIB = /usr/local/oag/3rdParty/ATLAS/Linux_P4SSE2/lib -F2C_LIB = /usr/local/oag/3rdParty/F2C/Linux_P4SSE2/lib -CLAPACK_INCLUDE = /usr/local/oag/3rdParty/CLAPACK/Linux_P4SSE2/include -ATLAS_INCLUDE = /usr/local/oag/3rdParty/ATLAS/Linux_P4SSE2/include - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -#XRTGRAPH_EXTENSIONS = YES -#XRTGRAPH = /usr/local/xrtgraph -# Define SCIPLOT = YES if no XRT/graph 3.x -SCIPLOT=YES - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86_64-debug.linux-x86_64-debug b/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86_64-debug.linux-x86_64-debug deleted file mode 100644 index 4d78b29d7..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86_64-debug.linux-x86_64-debug +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86_64.linux-x86_64 b/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86_64.linux-x86_64 deleted file mode 100644 index 8d1386636..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86_64.linux-x86_64 +++ /dev/null @@ -1,34 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86 - -X11_LIB=/usr/lib64 -X11_INC=/usr/include - -# OpenMotif location -MOTIF_LIB=/usr/lib64 -MOTIF_INC=/usr/include -#MOTIF_LIB=/usr/X11R6/lib64 -#MOTIF_INC=/usr/X11R6/include - -# testing pre-compiled versions -CLAPACK_LIB = /usr/local/oag/3rdParty/ATLAS/Linux_Core2Duo64SSE3/lib -ATLAS_LIB = /usr/local/oag/3rdParty/ATLAS/Linux_Core2Duo64SSE3/lib -ATLAS_INCLUDE = /usr/local/oag/3rdParty/ATLAS/Linux_Core2Duo64SSE3/include - -JAVA_DIR=/usr - -# Sciplot and XRTgraph used by medm -SCIPLOT=YES -#XRTGRAPH_EXTENSIONS = YES -#XRTGRAPH = /usr/local/xrtgraph64 -XRTGRAPH_EXTENSIONS = -XRTGRAPH = - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc-debug.solaris-sparc-debug b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc-debug.solaris-sparc-debug deleted file mode 100644 index b0b61ce0a..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc-debug.solaris-sparc-debug +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc-gnu.solaris-sparc-gnu b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc-gnu.solaris-sparc-gnu deleted file mode 100644 index b0b61ce0a..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc-gnu.solaris-sparc-gnu +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc deleted file mode 100644 index bd113bea3..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc +++ /dev/null @@ -1,90 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common - -# sun X11 -X11_LIB = /usr/openwin/lib -X11_INC = /usr/openwin/include -# mit X11 -#X11_LIB = /opt/X11R5/lib -#X11_INC = /opt/X11R5/include -# osf motif -#MOTIF_INC = /opt/local/Motif2.0/include -#MOTIF_LIB = /opt/local/Motif2.0/lib -# sun SDK motif -#MOTIF_INC = /opt/SUNWmotif/include -#MOTIF_LIB = /opt/SUNWmotif/lib -# sun 5.4,5.6 SDK motif -MOTIF_INC = /usr/dt/include -MOTIF_LIB = /usr/dt/lib -OPENWIN = /usr/openwin - -INTERVIEWS_BIN=/usr/local/interviews/bin/O.solaris -INTERVIEWS_LIB=/usr/local/interviews/lib/O.solaris -IV_INC=/usr/local/interviews/include -IV-2_6_INC=/usr/local/interviews/include/IV-2_6 -IV_BIN=/usr/local/interviews/bin/O.solaris -IV_LIB=/usr/local/interviews/lib/O.solaris - -WINGZ_INC = /opt/local/Wingz2/incl -WINGZ_LIB = /opt/local/Wingz2/lib -#MATHEMATICA = /usr/local/math - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -#XRTGRAPH_EXTENSIONS = YES -#XRTGRAPH = /opt/local/xrtgraph -SCIPLOT = YES - -QUESTWIN = /usr/local/questwin - -TK_LIB = /opt/local/lib -TK_INC = /opt/local/include -TCL_LIB = /opt/local/lib -TCL_INC = /opt/local/include -DP_LIB = /opt/local/lib -DP_INC = /opt/local/include -BLT_LIB = /opt/local/lib -BLT_INC = /opt/local/include - -IDL = /usr/local/idl -# IDL=$(IDL)/external/rpc is the sun4 version -IDLRPC = $(IDL)/external/rpc.solaris - -# sun 5.4 -#JAVA_DIR=/opt/local/java -# sun 5.6 -JAVA_DIR=/usr/java -JAVA_INC=$(JAVA_DIR)/include - -ZLIB_PREFIX = /usr/local/oag -ZLIB = $(notdir $(wildcard $(ZLIB_PREFIX)/lib/libz.a)) -ifeq ($(ZLIB) , libz.a) -ZLIB_LIB = $(ZLIB_PREFIX)/lib -ZLIB_INC = -I$(ZLIB_PREFIX)/include -ZLIB_CFLAG = -DzLib -ZLIB_PROD_LIB = z -z_DIR=$(ZLIB_PREFIX)/lib -else -ZLIB_LIB = -ZLIB_INC = -ZLIB_CFLAG = -ZLIB_PROD_LIB = -z_DIR= -endif - -PYTHON_DIR=/opt/local/lib/python2.2 -PYTHON_INCLUDE=/opt/local/include/python2.2 - -CLAPACK_LIB = /usr/local/oag/3rdParty/CLAPACK/SunOS_SunUS5/lib -ATLAS_LIB = /usr/local/oag/3rdParty/ATLAS/SunOS_SunUS5/lib -F2C_LIB = /usr/local/oag/3rdParty/F2C/SunOS_SunUS5/lib -CLAPACK_INCLUDE = /usr/local/oag/3rdParty/CLAPACK/SunOS_SunUS5/include -ATLAS_INCLUDE = /usr/local/oag/3rdParty/ATLAS/SunOS_SunUS5/include diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc64-gnu.solaris-sparc64-gnu b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc64-gnu.solaris-sparc64-gnu deleted file mode 100644 index e8b88e0de..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc64-gnu.solaris-sparc64-gnu +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-sparc64.solaris-sparc64 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc64.solaris-sparc64 b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc64.solaris-sparc64 deleted file mode 100644 index 87628e74e..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc64.solaris-sparc64 +++ /dev/null @@ -1,24 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc - -FORCE_ZLIB_BUILD=YES - -CLAPACK_LIB = /usr/local/oag/3rdParty/CLAPACK/SunOS_SunUSIII_4/lib -ATLAS_LIB = /usr/local/oag/3rdParty/ATLAS/SunOS_SunUSIII_4/lib -F2C_LIB = /usr/local/oag/3rdParty/F2C/SunOS_SunUSIII_4/lib -CLAPACK_INCLUDE = /usr/local/oag/3rdParty/CLAPACK/SunOS_SunUSIII_4/include -ATLAS_INCLUDE = /usr/local/oag/3rdParty/ATLAS/SunOS_SunUSIII_4/include - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -#XRTGRAPH_EXTENSIONS = -#XRTGRAPH = -SCIPLOT = YES diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86-debug.solaris-x86-debug b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86-debug.solaris-x86-debug deleted file mode 100644 index 2c322fcfa..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86-debug.solaris-x86-debug +++ /dev/null @@ -1,6 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - --include $(TOP)/configure/os/CONFIG_SITE.solaris-x86.solaris-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86-gnu.solaris-x86-gnu b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86-gnu.solaris-x86-gnu deleted file mode 100644 index bf9746289..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86-gnu.solaris-x86-gnu +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-x86.solaris-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86.solaris-x86 b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86.solaris-x86 deleted file mode 100644 index 299dc0834..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86.solaris-x86 +++ /dev/null @@ -1,20 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc - -#XRTGRAPH_EXTENSIONS= -#XRTGRAPH= -SCIPLOT=YES - -X11_LIB = /usr/lib -X11_INC = /usr/include -MOTIF_INC = /usr/include -MOTIF_LIB = /usr/lib - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86_64.solaris-x86_64 b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86_64.solaris-x86_64 deleted file mode 100644 index 9ac039a5b..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86_64.solaris-x86_64 +++ /dev/null @@ -1,14 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-x86.solaris-x86 - -XRTGRAPH= -SCIPLOT=YES - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-cygwin.win32-x86-cygwin b/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-cygwin.win32-x86-cygwin deleted file mode 100644 index f6ca56942..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-cygwin.win32-x86-cygwin +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-debug.win32-x86-debug b/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-debug.win32-x86-debug deleted file mode 100644 index ebc1b8238..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-debug.win32-x86-debug +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.win32-x86.win32-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-mingw.win32-x86-mingw b/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-mingw.win32-x86-mingw deleted file mode 100644 index f6ca56942..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-mingw.win32-x86-mingw +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86.win32-x86 b/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86.win32-x86 deleted file mode 100644 index 8118893a7..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86.win32-x86 +++ /dev/null @@ -1,216 +0,0 @@ -# -# CONFIG_SITE.win32-x86.win32-x86,v 1.3 2003/09/03 19:06:10 jba Exp -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common - -# If objects were compiled with different default runtime libraries -# (not a good idea), specify which one you want to use in the product -# by making it the default and the others nodefault. Use -# WIN32_RUNTIME = MD, MT, or ML in Makefile.Host if you want to do -# this. It will avoid LNK4098 warnings. -# msvcrt.lib -MD Multi-thread DLL -# msvcrtd.lib -MDd Multi-thread DLL, Debug -# libcmt.lib -MT Multi-thread -# libcmtd.lib -MTd Multi-thread, Debug -# libc.lib -ML Single-thread -# libcd.lib -MLd Single-thread, Debug - -# MD Multi-thread DLL product -ARCH_DEP_LDFLAGS_MD_NO += /DEFAULTLIB:"msvcrtd.lib" -ARCH_DEP_LDFLAGS_MD_NO += /NODEFAULTLIB:"msvcrt.lib" -ARCH_DEP_LDFLAGS_MD_YES += /DEFAULTLIB:"msvcrt.lib" -ARCH_DEP_LDFLAGS_MD_YES += /NODEFAULTLIB:"msvcrtd.lib" -ARCH_DEP_LDFLAGS_MD += $(ARCH_DEP_LDFLAGS_MD_$(HOST_OPT)) -ARCH_DEP_LDFLAGS_MD += /NODEFAULTLIB:"libcmt.lib" -ARCH_DEP_LDFLAGS_MD += /NODEFAULTLIB:"libcmtd.lib" -ARCH_DEP_LDFLAGS_MD += /NODEFAULTLIB:"libc.lib" -ARCH_DEP_LDFLAGS_MD += /NODEFAULTLIB:"libcd.lib" - -# MT Multi-threaded product -ARCH_DEP_LDFLAGS_MT_NO += /DEFAULTLIB:"libcmtd.lib" -ARCH_DEP_LDFLAGS_MT_NO += /NODEFAULTLIB:"libcmt.lib" -ARCH_DEP_LDFLAGS_MT_YES += /DEFAULTLIB:"libcmt.lib" -ARCH_DEP_LDFLAGS_MT_YES += /NODEFAULTLIB:"libcmtd.lib" -ARCH_DEP_LDFLAGS_MT += $(ARCH_DEP_LDFLAGS_MT_$(HOST_OPT)) -ARCH_DEP_LDFLAGS_MT += /NODEFAULTLIB:"msvcrt.lib" -ARCH_DEP_LDFLAGS_MT += /NODEFAULTLIB:"msvcrtd.lib" -ARCH_DEP_LDFLAGS_MT += /NODEFAULTLIB:"libc.lib" -ARCH_DEP_LDFLAGS_MT += /NODEFAULTLIB:"libcd.lib" - -# ML Single-threaded product -ARCH_DEP_LDFLAGS_ML_NO += /DEFAULTLIB:"libcd.lib" -ARCH_DEP_LDFLAGS_ML_NO += /NODEFAULTLIB:"libc.lib" -ARCH_DEP_LDFLAGS_ML_YES += /DEFAULTLIB:"libc.lib" -ARCH_DEP_LDFLAGS_ML_YES += /NODEFAULTLIB:"libcd.lib" -ARCH_DEP_LDFLAGS_ML += $(ARCH_DEP_LDFLAGS_ML_$(HOST_OPT)) -ARCH_DEP_LDFLAGS_ML += /NODEFAULTLIB:"msvcrt.lib" -ARCH_DEP_LDFLAGS_ML += /NODEFAULTLIB:"msvcrtd.lib" -ARCH_DEP_LDFLAGS_ML += /NODEFAULTLIB:"libcmt.lib" -ARCH_DEP_LDFLAGS_ML += /NODEFAULTLIB:"libcmtd.lib" - -ARCH_DEP_LDFLAGS += $(ARCH_DEP_LDFLAGS_$(WIN32_RUNTIME)) - -# ---------- java definitions -JAVA_DIR=c:/j2sdk1.4.1_01 - -# ---------- tcl/tk definitions -TCL = c:\\Tcl -TK_LIB = $(TCL)/lib -TK_INC = $(TCL)/include -TCL_LIB = $(TCL)/lib -TCL_INC = $(TCL)/include -DP_LIB = $(TCL)/lib -DP_INC = $(TCL)/include -BLT_LIB = $(TCL)/lib -BLT_INC = $(TCL)/include - -IDL = /usr/local/idl -# IDL=$(IDL)/external/rpc is the sun4 version -IDLRPC = $(IDL)/external/rpc.solaris - -OPENWIN = -INTERVIEWS_BIN = -WINGZ_INC = -WINGZ_LIB = -MATHEMATICA = -QUESTWIN = - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -XRTGRAPH_EXTENSIONS = NO -#XRTGRAPH = - -SCIPLOT = YES - -# z library created in SDDS extension -ZLIB_CFLAG = -DzLib -ZLIB_PROD_LIB = z -z_DIR = $(EPICS_EXTENSIONS_LIB) - -CLAPACK_INCLUDE = c:/CLAPACK/include -CLAPACK_LIB = c:/CLAPACK/lib - -EXCEED = Exceed13.0 - -ifeq ($(EXCEED),Exceed5) - X11_LIB = c:/exceed5/xdk/lib - X11_INC = c:/exceed5/xdk/include - EXCEED_XLIBS=xmstatic xt xlibgui xlib xmu - xmstatic_DIR=$(X11_LIB) - xt_DIR=$(X11_LIB) - xlibgui_DIR=$(X11_LIB) - xlib_DIR=$(X11_LIB) - xmu_DIR=$(X11_LIB) - EXCEED_CFLAGS= -endif -ifeq ($(EXCEED),Exceed6.0) - X11_LIB = c:/exceed/xdk/lib - X11_INC = c:/exceed/xdk/include - EXCEED_XLIBS=xmstatic HCLXt xlibgui xlib HCLXmu - xmstatic_DIR=$(X11_LIB) - HCLXt_DIR=$(X11_LIB) - xlibgui_DIR=$(X11_LIB) - xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS= -endif -ifeq ($(EXCEED),Exceed6.1) - X11_LIB = c:/exceed/xdk/lib - X11_INC = c:/exceed/xdk/include - EXCEED_XLIBS=XmStatic XmStatXt xlibgui xlib HCLXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - xlibgui_DIR=$(X11_LIB) - xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC -endif -ifeq ($(EXCEED),Exceed6.2) - X11_LIB = c:/exceed/xdk/lib - X11_INC = c:/exceed/xdk/include - EXCEED_XLIBS=XmStatic XmStatXt xlibgui Xlib hclXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - xlibgui_DIR=$(X11_LIB) - Xlib_DIR=$(X11_LIB) - hclXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC -endif -ifeq ($(EXCEED),Exceed7.0) - X11_LIB = c:/Exceed/Exceed/xdk/lib - X11_INC = c:/Exceed/Exceed/xdk/include - EXCEED_XLIBS=XmStatic XmStatXt XlibGui Xlib HCLXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - XlibGui_DIR=$(X11_LIB) - Xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC /DMOTIFAPP -endif -ifeq ($(EXCEED),Exceed7.10) - X11_LIB = c:/Exceed7.10/XDK/lib - X11_INC = c:/Exceed7.10/XDK/include - EXCEED_XLIBS=XmStatic XmStatXt XlibGui Xlib HCLXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - XlibGui_DIR=$(X11_LIB) - Xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC /DMOTIFAPP -endif -ifeq ($(EXCEED),Exceed10.0) - XDK=C:/Exceed10.0/xdk - X11_LIB = $(XDK)/lib - X11_INC = $(XDK)/include - #X11_LIB = c:/Exceed10.0/XDK/lib - #X11_INC = c:/Exceed10.0/XDK/include - EXCEED_XLIBS=XmStatic XmStatXt Xlib HCLXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - Xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC /DMOTIFAPP -endif -ifeq ($(EXCEED),Exceed12.0) - XDK=C:/Exceed12.0/XDK - X11_LIB = $(XDK)/lib - X11_INC = $(XDK)/include - EXCEED_XLIBS=XmStatic XmStatXt Xlib HCLXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - Xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC /DMOTIFAPP -endif -ifeq ($(EXCEED),Exceed13.0) - XDK=C:/Exceed13.0/XDK - X11_LIB = $(XDK)/lib - X11_INC = $(XDK)/include - EXCEED_XLIBS=XmStatic XmStatXt Xlib HCLXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - Xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC /DMOTIFAPP -endif - - -###################################################### -# Override for XFree86/LessTif -#X11_LIB = c:/Cygwin/usr/X11R6/lib -#X11_INC = c:/Cygwin/usr/X11R6/include -#EXCEED_XLIBS = Xm Xt Xp Xmu X11 Xext -#EXCEED_CFLAGS = -###################################################### - -MOTIF_LIB = $(X11_LIB) -MOTIF_INC = $(X11_INC) - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.windows-x64.windows-x64 b/src/template/ext/top/configure/os/CONFIG_SITE.windows-x64.windows-x64 deleted file mode 100644 index 68a0c149a..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.windows-x64.windows-x64 +++ /dev/null @@ -1,6 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - --include $(TOP)/configure/os/CONFIG_SITE.win32-x86.win32-x86 - diff --git a/src/template/ext/top/exampleExt/Makefile b/src/template/ext/top/exampleExt/Makefile deleted file mode 100644 index 618991fa7..000000000 --- a/src/template/ext/top/exampleExt/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -TOP=../.. -include $(TOP)/configure/CONFIG - -PROD_HOST = caExample -caExample_SRCS += caExample.c -caExample_LIBS += $(EPICS_BASE_HOST_LIBS) - -#caExample_CFLAGS += #C source file compiler flags, e.g. -DMYDEF=3 -#caExample_LDFLAGS += #Linker flags, e.g. -L$(MOTIF_LIB) -L$(X11_LIB) -#caExample_SYS_LIBS_solaris += #System libraries for OS_CLASS solaris, e.g. socket - -include $(TOP)/configure/RULES - diff --git a/src/template/ext/top/exampleExt/RELEASE_NOTES.HTM b/src/template/ext/top/exampleExt/RELEASE_NOTES.HTM deleted file mode 100644 index 56dce9346..000000000 --- a/src/template/ext/top/exampleExt/RELEASE_NOTES.HTM +++ /dev/null @@ -1,16 +0,0 @@ - - - -
-

caExample Release Notes

-

author name

-
- -
- -

05 Oct 2000 - v1.0

- -

Initial version

- - - diff --git a/src/template/ext/top/exampleExt/caExample.c b/src/template/ext/top/exampleExt/caExample.c deleted file mode 100644 index cc342e237..000000000 --- a/src/template/ext/top/exampleExt/caExample.c +++ /dev/null @@ -1,25 +0,0 @@ -/*caExample.c*/ -#include -#include -#include -#include - -#include "cadef.h" - -int main(int argc,char **argv) -{ - double data; - chid mychid; - - if(argc != 2) { - fprintf(stderr,"usage: caExample pvname\n"); - exit(1); - } - SEVCHK(ca_context_create(ca_disable_preemptive_callback),"ca_context_create"); - SEVCHK(ca_create_channel(argv[1],NULL,NULL,10,&mychid),"ca_create_channel failure"); - SEVCHK(ca_pend_io(5.0),"ca_pend_io failure"); - SEVCHK(ca_get(DBR_DOUBLE,mychid,(void *)&data),"ca_get failure"); - SEVCHK(ca_pend_io(5.0),"ca_pend_io failure"); - printf("%s %f\n",argv[1],data); - return(0); -} diff --git a/src/template/ext/top/simpleExt/Makefile b/src/template/ext/top/simpleExt/Makefile deleted file mode 100644 index 52cfac525..000000000 --- a/src/template/ext/top/simpleExt/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -TOP=../.. -include $(TOP)/configure/CONFIG - -# Product -#PROD_HOST = caExample -#caExample_SRCS += caExample.cc -#caExample_CFLAGS += -#caExample_LDFLAGS += -#caExample_LIBS += ca Com -#ca_LIB=$(EPICS_BASE_LIB) -#Com_LIB=$(EPICS_BASE_LIB) - -# Library -#LIBRARY_HOST = abc -#abc_SRCS += abc.c -#abc_DLL_LIBS = ca Com - - -include $(TOP)/configure/RULES - - diff --git a/src/template/ext/top/src/Makefile b/src/template/ext/top/src/Makefile deleted file mode 100644 index d672087ca..000000000 --- a/src/template/ext/top/src/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -TOP = .. -include $(TOP)/configure/CONFIG - -DIRS += _EXTNAME_ - -include $(TOP)/configure/RULES_DIRS - diff --git a/src/template/base/top/Makefile b/src/template/top/Makefile similarity index 100% rename from src/template/base/top/Makefile rename to src/template/top/Makefile diff --git a/src/template/base/top/caClientApp/Makefile b/src/template/top/caClientApp/Makefile similarity index 100% rename from src/template/base/top/caClientApp/Makefile rename to src/template/top/caClientApp/Makefile diff --git a/src/template/base/top/caClientApp/caExample.c b/src/template/top/caClientApp/caExample.c similarity index 100% rename from src/template/base/top/caClientApp/caExample.c rename to src/template/top/caClientApp/caExample.c diff --git a/src/template/base/top/caClientApp/caMonitor.c b/src/template/top/caClientApp/caMonitor.c similarity index 100% rename from src/template/base/top/caClientApp/caMonitor.c rename to src/template/top/caClientApp/caMonitor.c diff --git a/src/template/base/top/caServerApp/Makefile b/src/template/top/caServerApp/Makefile similarity index 100% rename from src/template/base/top/caServerApp/Makefile rename to src/template/top/caServerApp/Makefile diff --git a/src/template/base/top/caServerApp/README b/src/template/top/caServerApp/README similarity index 100% rename from src/template/base/top/caServerApp/README rename to src/template/top/caServerApp/README diff --git a/src/template/base/top/caServerApp/exAsyncPV.cc b/src/template/top/caServerApp/exAsyncPV.cc similarity index 100% rename from src/template/base/top/caServerApp/exAsyncPV.cc rename to src/template/top/caServerApp/exAsyncPV.cc diff --git a/src/template/base/top/caServerApp/exChannel.cc b/src/template/top/caServerApp/exChannel.cc similarity index 100% rename from src/template/base/top/caServerApp/exChannel.cc rename to src/template/top/caServerApp/exChannel.cc diff --git a/src/template/base/top/caServerApp/exPV.cc b/src/template/top/caServerApp/exPV.cc similarity index 100% rename from src/template/base/top/caServerApp/exPV.cc rename to src/template/top/caServerApp/exPV.cc diff --git a/src/template/base/top/caServerApp/exScalarPV.cc b/src/template/top/caServerApp/exScalarPV.cc similarity index 100% rename from src/template/base/top/caServerApp/exScalarPV.cc rename to src/template/top/caServerApp/exScalarPV.cc diff --git a/src/template/base/top/caServerApp/exServer.cc b/src/template/top/caServerApp/exServer.cc similarity index 100% rename from src/template/base/top/caServerApp/exServer.cc rename to src/template/top/caServerApp/exServer.cc diff --git a/src/template/base/top/caServerApp/exServer.h b/src/template/top/caServerApp/exServer.h similarity index 100% rename from src/template/base/top/caServerApp/exServer.h rename to src/template/top/caServerApp/exServer.h diff --git a/src/template/base/top/caServerApp/exVectorPV.cc b/src/template/top/caServerApp/exVectorPV.cc similarity index 100% rename from src/template/base/top/caServerApp/exVectorPV.cc rename to src/template/top/caServerApp/exVectorPV.cc diff --git a/src/template/base/top/caServerApp/main.cc b/src/template/top/caServerApp/main.cc similarity index 100% rename from src/template/base/top/caServerApp/main.cc rename to src/template/top/caServerApp/main.cc diff --git a/src/ca/legacy/pcas/example/directoryService/test.adl b/src/template/top/caServerApp/test.adl similarity index 100% rename from src/ca/legacy/pcas/example/directoryService/test.adl rename to src/template/top/caServerApp/test.adl diff --git a/src/ca/legacy/pcas/example/directoryService/vxEntry.cc b/src/template/top/caServerApp/vxEntry.cc similarity index 100% rename from src/ca/legacy/pcas/example/directoryService/vxEntry.cc rename to src/template/top/caServerApp/vxEntry.cc diff --git a/src/template/base/top/configure/CONFIG b/src/template/top/configure/CONFIG similarity index 100% rename from src/template/base/top/configure/CONFIG rename to src/template/top/configure/CONFIG diff --git a/src/template/base/top/configure/CONFIG_SITE b/src/template/top/configure/CONFIG_SITE similarity index 100% rename from src/template/base/top/configure/CONFIG_SITE rename to src/template/top/configure/CONFIG_SITE diff --git a/src/template/base/top/configure/Makefile b/src/template/top/configure/Makefile similarity index 100% rename from src/template/base/top/configure/Makefile rename to src/template/top/configure/Makefile diff --git a/src/template/base/top/configure/RELEASE b/src/template/top/configure/RELEASE similarity index 100% rename from src/template/base/top/configure/RELEASE rename to src/template/top/configure/RELEASE diff --git a/src/template/base/top/configure/RULES b/src/template/top/configure/RULES similarity index 100% rename from src/template/base/top/configure/RULES rename to src/template/top/configure/RULES diff --git a/src/template/base/top/configure/RULES.ioc b/src/template/top/configure/RULES.ioc similarity index 100% rename from src/template/base/top/configure/RULES.ioc rename to src/template/top/configure/RULES.ioc diff --git a/src/template/base/top/configure/RULES_DIRS b/src/template/top/configure/RULES_DIRS similarity index 100% rename from src/template/base/top/configure/RULES_DIRS rename to src/template/top/configure/RULES_DIRS diff --git a/src/template/base/top/configure/RULES_TOP b/src/template/top/configure/RULES_TOP similarity index 100% rename from src/template/base/top/configure/RULES_TOP rename to src/template/top/configure/RULES_TOP diff --git a/src/template/base/top/exampleApp/Db/Makefile b/src/template/top/exampleApp/Db/Makefile similarity index 100% rename from src/template/base/top/exampleApp/Db/Makefile rename to src/template/top/exampleApp/Db/Makefile diff --git a/src/template/base/top/exampleApp/Db/_APPNAME_Version.db b/src/template/top/exampleApp/Db/_APPNAME_Version.db similarity index 100% rename from src/template/base/top/exampleApp/Db/_APPNAME_Version.db rename to src/template/top/exampleApp/Db/_APPNAME_Version.db diff --git a/src/template/base/top/exampleApp/Db/dbExample1.db b/src/template/top/exampleApp/Db/dbExample1.db similarity index 100% rename from src/template/base/top/exampleApp/Db/dbExample1.db rename to src/template/top/exampleApp/Db/dbExample1.db diff --git a/src/template/base/top/exampleApp/Db/dbExample2.db b/src/template/top/exampleApp/Db/dbExample2.db similarity index 100% rename from src/template/base/top/exampleApp/Db/dbExample2.db rename to src/template/top/exampleApp/Db/dbExample2.db diff --git a/src/template/base/top/exampleApp/Db/dbSubExample.db b/src/template/top/exampleApp/Db/dbSubExample.db similarity index 100% rename from src/template/base/top/exampleApp/Db/dbSubExample.db rename to src/template/top/exampleApp/Db/dbSubExample.db diff --git a/src/template/base/top/exampleApp/Db/user.substitutions b/src/template/top/exampleApp/Db/user.substitutions similarity index 100% rename from src/template/base/top/exampleApp/Db/user.substitutions rename to src/template/top/exampleApp/Db/user.substitutions diff --git a/src/template/base/top/exampleApp/Makefile b/src/template/top/exampleApp/Makefile similarity index 100% rename from src/template/base/top/exampleApp/Makefile rename to src/template/top/exampleApp/Makefile diff --git a/src/template/base/top/exampleApp/src/Makefile b/src/template/top/exampleApp/src/Makefile similarity index 100% rename from src/template/base/top/exampleApp/src/Makefile rename to src/template/top/exampleApp/src/Makefile diff --git a/src/template/base/top/exampleApp/src/_APPNAME_Hello.c b/src/template/top/exampleApp/src/_APPNAME_Hello.c similarity index 100% rename from src/template/base/top/exampleApp/src/_APPNAME_Hello.c rename to src/template/top/exampleApp/src/_APPNAME_Hello.c diff --git a/src/template/base/top/exampleApp/src/_APPNAME_Hello.dbd b/src/template/top/exampleApp/src/_APPNAME_Hello.dbd similarity index 100% rename from src/template/base/top/exampleApp/src/_APPNAME_Hello.dbd rename to src/template/top/exampleApp/src/_APPNAME_Hello.dbd diff --git a/src/template/base/top/exampleApp/src/_APPNAME_Main.cpp b/src/template/top/exampleApp/src/_APPNAME_Main.cpp similarity index 100% rename from src/template/base/top/exampleApp/src/_APPNAME_Main.cpp rename to src/template/top/exampleApp/src/_APPNAME_Main.cpp diff --git a/src/template/base/top/exampleApp/src/dbSubExample.c b/src/template/top/exampleApp/src/dbSubExample.c similarity index 100% rename from src/template/base/top/exampleApp/src/dbSubExample.c rename to src/template/top/exampleApp/src/dbSubExample.c diff --git a/src/template/base/top/exampleApp/src/dbSubExample.dbd b/src/template/top/exampleApp/src/dbSubExample.dbd similarity index 100% rename from src/template/base/top/exampleApp/src/dbSubExample.dbd rename to src/template/top/exampleApp/src/dbSubExample.dbd diff --git a/src/template/base/top/exampleApp/src/devXxxSoft.c b/src/template/top/exampleApp/src/devXxxSoft.c similarity index 100% rename from src/template/base/top/exampleApp/src/devXxxSoft.c rename to src/template/top/exampleApp/src/devXxxSoft.c diff --git a/src/template/base/top/exampleApp/src/dev_APPNAME_Version.c b/src/template/top/exampleApp/src/dev_APPNAME_Version.c similarity index 100% rename from src/template/base/top/exampleApp/src/dev_APPNAME_Version.c rename to src/template/top/exampleApp/src/dev_APPNAME_Version.c diff --git a/src/template/base/top/exampleApp/src/dev_APPNAME_Version.dbd b/src/template/top/exampleApp/src/dev_APPNAME_Version.dbd similarity index 100% rename from src/template/base/top/exampleApp/src/dev_APPNAME_Version.dbd rename to src/template/top/exampleApp/src/dev_APPNAME_Version.dbd diff --git a/src/template/base/top/exampleApp/src/initTrace.c b/src/template/top/exampleApp/src/initTrace.c similarity index 100% rename from src/template/base/top/exampleApp/src/initTrace.c rename to src/template/top/exampleApp/src/initTrace.c diff --git a/src/template/base/top/exampleApp/src/initTrace.dbd b/src/template/top/exampleApp/src/initTrace.dbd similarity index 100% rename from src/template/base/top/exampleApp/src/initTrace.dbd rename to src/template/top/exampleApp/src/initTrace.dbd diff --git a/src/template/base/top/exampleApp/src/sncExample.dbd b/src/template/top/exampleApp/src/sncExample.dbd similarity index 100% rename from src/template/base/top/exampleApp/src/sncExample.dbd rename to src/template/top/exampleApp/src/sncExample.dbd diff --git a/src/template/base/top/exampleApp/src/sncExample.stt b/src/template/top/exampleApp/src/sncExample.stt similarity index 100% rename from src/template/base/top/exampleApp/src/sncExample.stt rename to src/template/top/exampleApp/src/sncExample.stt diff --git a/src/template/base/top/exampleApp/src/sncProgram.st b/src/template/top/exampleApp/src/sncProgram.st similarity index 100% rename from src/template/base/top/exampleApp/src/sncProgram.st rename to src/template/top/exampleApp/src/sncProgram.st diff --git a/src/template/base/top/exampleApp/src/xxxRecord.c b/src/template/top/exampleApp/src/xxxRecord.c similarity index 100% rename from src/template/base/top/exampleApp/src/xxxRecord.c rename to src/template/top/exampleApp/src/xxxRecord.c diff --git a/src/template/base/top/exampleApp/src/xxxRecord.dbd b/src/template/top/exampleApp/src/xxxRecord.dbd similarity index 100% rename from src/template/base/top/exampleApp/src/xxxRecord.dbd rename to src/template/top/exampleApp/src/xxxRecord.dbd diff --git a/src/template/base/top/exampleApp/src/xxxSupport.dbd b/src/template/top/exampleApp/src/xxxSupport.dbd similarity index 100% rename from src/template/base/top/exampleApp/src/xxxSupport.dbd rename to src/template/top/exampleApp/src/xxxSupport.dbd diff --git a/src/template/base/top/exampleBoot/Makefile b/src/template/top/exampleBoot/Makefile similarity index 100% rename from src/template/base/top/exampleBoot/Makefile rename to src/template/top/exampleBoot/Makefile diff --git a/src/template/base/top/exampleBoot/ioc/Makefile@Common b/src/template/top/exampleBoot/ioc/Makefile@Common similarity index 100% rename from src/template/base/top/exampleBoot/ioc/Makefile@Common rename to src/template/top/exampleBoot/ioc/Makefile@Common diff --git a/src/template/base/top/exampleBoot/ioc/Makefile@cygwin b/src/template/top/exampleBoot/ioc/Makefile@cygwin similarity index 100% rename from src/template/base/top/exampleBoot/ioc/Makefile@cygwin rename to src/template/top/exampleBoot/ioc/Makefile@cygwin diff --git a/src/template/base/top/exampleBoot/ioc/Makefile@vxWorks b/src/template/top/exampleBoot/ioc/Makefile@vxWorks similarity index 100% rename from src/template/base/top/exampleBoot/ioc/Makefile@vxWorks rename to src/template/top/exampleBoot/ioc/Makefile@vxWorks diff --git a/src/template/base/top/exampleBoot/ioc/Makefile@win32 b/src/template/top/exampleBoot/ioc/Makefile@win32 similarity index 100% rename from src/template/base/top/exampleBoot/ioc/Makefile@win32 rename to src/template/top/exampleBoot/ioc/Makefile@win32 diff --git a/src/template/base/top/exampleBoot/ioc/Makefile@windows b/src/template/top/exampleBoot/ioc/Makefile@windows similarity index 100% rename from src/template/base/top/exampleBoot/ioc/Makefile@windows rename to src/template/top/exampleBoot/ioc/Makefile@windows diff --git a/src/template/base/top/exampleBoot/ioc/README@Common b/src/template/top/exampleBoot/ioc/README@Common similarity index 100% rename from src/template/base/top/exampleBoot/ioc/README@Common rename to src/template/top/exampleBoot/ioc/README@Common diff --git a/src/template/base/top/exampleBoot/ioc/README@RTEMS b/src/template/top/exampleBoot/ioc/README@RTEMS similarity index 100% rename from src/template/base/top/exampleBoot/ioc/README@RTEMS rename to src/template/top/exampleBoot/ioc/README@RTEMS diff --git a/src/template/base/top/exampleBoot/ioc/README@vxWorks b/src/template/top/exampleBoot/ioc/README@vxWorks similarity index 100% rename from src/template/base/top/exampleBoot/ioc/README@vxWorks rename to src/template/top/exampleBoot/ioc/README@vxWorks diff --git a/src/template/base/top/exampleBoot/ioc/st.cmd@Common b/src/template/top/exampleBoot/ioc/st.cmd@Common similarity index 100% rename from src/template/base/top/exampleBoot/ioc/st.cmd@Common rename to src/template/top/exampleBoot/ioc/st.cmd@Common diff --git a/src/template/base/top/exampleBoot/ioc/st.cmd@RTEMS b/src/template/top/exampleBoot/ioc/st.cmd@RTEMS similarity index 100% rename from src/template/base/top/exampleBoot/ioc/st.cmd@RTEMS rename to src/template/top/exampleBoot/ioc/st.cmd@RTEMS diff --git a/src/template/base/top/exampleBoot/ioc/st.cmd@vxWorks b/src/template/top/exampleBoot/ioc/st.cmd@vxWorks similarity index 100% rename from src/template/base/top/exampleBoot/ioc/st.cmd@vxWorks rename to src/template/top/exampleBoot/ioc/st.cmd@vxWorks diff --git a/src/template/base/top/exampleBoot/nfsCommands@RTEMS b/src/template/top/exampleBoot/nfsCommands@RTEMS similarity index 100% rename from src/template/base/top/exampleBoot/nfsCommands@RTEMS rename to src/template/top/exampleBoot/nfsCommands@RTEMS diff --git a/src/template/base/top/exampleBoot/nfsCommands@vxWorks b/src/template/top/exampleBoot/nfsCommands@vxWorks similarity index 100% rename from src/template/base/top/exampleBoot/nfsCommands@vxWorks rename to src/template/top/exampleBoot/nfsCommands@vxWorks diff --git a/src/template/base/top/iocApp/Db/Makefile b/src/template/top/iocApp/Db/Makefile similarity index 100% rename from src/template/base/top/iocApp/Db/Makefile rename to src/template/top/iocApp/Db/Makefile diff --git a/src/template/base/top/iocApp/Makefile b/src/template/top/iocApp/Makefile similarity index 100% rename from src/template/base/top/iocApp/Makefile rename to src/template/top/iocApp/Makefile diff --git a/src/template/base/top/iocApp/src/Makefile b/src/template/top/iocApp/src/Makefile similarity index 100% rename from src/template/base/top/iocApp/src/Makefile rename to src/template/top/iocApp/src/Makefile diff --git a/src/template/base/top/iocApp/src/_APPNAME_Main.cpp b/src/template/top/iocApp/src/_APPNAME_Main.cpp similarity index 100% rename from src/template/base/top/iocApp/src/_APPNAME_Main.cpp rename to src/template/top/iocApp/src/_APPNAME_Main.cpp diff --git a/src/template/base/top/iocBoot/Makefile b/src/template/top/iocBoot/Makefile similarity index 100% rename from src/template/base/top/iocBoot/Makefile rename to src/template/top/iocBoot/Makefile diff --git a/src/template/base/top/iocBoot/ioc/Makefile@Common b/src/template/top/iocBoot/ioc/Makefile@Common similarity index 100% rename from src/template/base/top/iocBoot/ioc/Makefile@Common rename to src/template/top/iocBoot/ioc/Makefile@Common diff --git a/src/template/base/top/iocBoot/ioc/Makefile@cygwin b/src/template/top/iocBoot/ioc/Makefile@cygwin similarity index 100% rename from src/template/base/top/iocBoot/ioc/Makefile@cygwin rename to src/template/top/iocBoot/ioc/Makefile@cygwin diff --git a/src/template/base/top/iocBoot/ioc/Makefile@vxWorks b/src/template/top/iocBoot/ioc/Makefile@vxWorks similarity index 100% rename from src/template/base/top/iocBoot/ioc/Makefile@vxWorks rename to src/template/top/iocBoot/ioc/Makefile@vxWorks diff --git a/src/template/base/top/iocBoot/ioc/Makefile@win32 b/src/template/top/iocBoot/ioc/Makefile@win32 similarity index 100% rename from src/template/base/top/iocBoot/ioc/Makefile@win32 rename to src/template/top/iocBoot/ioc/Makefile@win32 diff --git a/src/template/base/top/iocBoot/ioc/Makefile@windows b/src/template/top/iocBoot/ioc/Makefile@windows similarity index 100% rename from src/template/base/top/iocBoot/ioc/Makefile@windows rename to src/template/top/iocBoot/ioc/Makefile@windows diff --git a/src/template/base/top/iocBoot/ioc/st.cmd@Common b/src/template/top/iocBoot/ioc/st.cmd@Common similarity index 100% rename from src/template/base/top/iocBoot/ioc/st.cmd@Common rename to src/template/top/iocBoot/ioc/st.cmd@Common diff --git a/src/template/base/top/iocBoot/ioc/st.cmd@Cross b/src/template/top/iocBoot/ioc/st.cmd@Cross similarity index 100% rename from src/template/base/top/iocBoot/ioc/st.cmd@Cross rename to src/template/top/iocBoot/ioc/st.cmd@Cross diff --git a/src/template/base/top/iocBoot/ioc/st.cmd@RTEMS b/src/template/top/iocBoot/ioc/st.cmd@RTEMS similarity index 100% rename from src/template/base/top/iocBoot/ioc/st.cmd@RTEMS rename to src/template/top/iocBoot/ioc/st.cmd@RTEMS diff --git a/src/template/base/top/iocBoot/ioc/st.cmd@vxWorks b/src/template/top/iocBoot/ioc/st.cmd@vxWorks similarity index 100% rename from src/template/base/top/iocBoot/ioc/st.cmd@vxWorks rename to src/template/top/iocBoot/ioc/st.cmd@vxWorks diff --git a/src/template/base/top/iocBoot/nfsCommands@RTEMS b/src/template/top/iocBoot/nfsCommands@RTEMS similarity index 100% rename from src/template/base/top/iocBoot/nfsCommands@RTEMS rename to src/template/top/iocBoot/nfsCommands@RTEMS diff --git a/src/template/base/top/iocBoot/nfsCommands@vxWorks b/src/template/top/iocBoot/nfsCommands@vxWorks similarity index 100% rename from src/template/base/top/iocBoot/nfsCommands@vxWorks rename to src/template/top/iocBoot/nfsCommands@vxWorks diff --git a/src/template/base/top/supportApp/Db/Makefile b/src/template/top/supportApp/Db/Makefile similarity index 100% rename from src/template/base/top/supportApp/Db/Makefile rename to src/template/top/supportApp/Db/Makefile diff --git a/src/template/base/top/supportApp/Makefile b/src/template/top/supportApp/Makefile similarity index 100% rename from src/template/base/top/supportApp/Makefile rename to src/template/top/supportApp/Makefile diff --git a/src/template/base/top/supportApp/src/Makefile b/src/template/top/supportApp/src/Makefile similarity index 100% rename from src/template/base/top/supportApp/src/Makefile rename to src/template/top/supportApp/src/Makefile diff --git a/src/template/base/top/supportApp/src/_APPNAME_.dbd b/src/template/top/supportApp/src/_APPNAME_.dbd similarity index 100% rename from src/template/base/top/supportApp/src/_APPNAME_.dbd rename to src/template/top/supportApp/src/_APPNAME_.dbd 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 index e7457ae67..cba84fcb9 100644 --- a/src/tools/Makefile +++ b/src/tools/Makefile @@ -2,7 +2,7 @@ # 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. +# in file LICENSE that is included with this distribution. #************************************************************************* TOP=../.. @@ -11,13 +11,6 @@ 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 @@ -34,63 +27,13 @@ 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/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/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/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/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/useManifestTool.pl b/src/tools/useManifestTool.pl deleted file mode 100644 index 9e59e9f1f..000000000 --- a/src/tools/useManifestTool.pl +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env perl -# -# Use MS Visual C++ compiler version number to determine if -# we want to use the Manifest Tool (status=1) or not (status=0) -# -# VC compiler versions >= 14.00 will have status=1 -# VC compiler versions 10.00 - 13.10 will have status=0 -# EPICS builds with older VC compilers is not supported -# - -my $versionString=`cl 2>&1`; - -if ($versionString =~ m/Version 16./) { - $status=0; -} elsif ($versionString =~ m/Version 15./){ - $status=1; -} elsif ($versionString =~ m/Version 14./){ - $status=1; -} elsif ($versionString =~ m/Version 13.10/){ - $status=0; -} elsif ($versionString =~ m/Version 13.0/){ - $status=0; -} elsif ($versionString =~ m/Version 12./){ - $status=0; -} elsif ($versionString =~ m/Version 11./){ - $status=0; -} elsif ($versionString =~ m/Version 10./){ - $status=0; -} else { - $status=0; -} -print "$status\n"; -exit; diff --git a/startup/EpicsHostArch b/startup/EpicsHostArch deleted file mode 100755 index 8861ac56c..000000000 --- a/startup/EpicsHostArch +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/sh -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# -# EpicsHostArch - returns the Epics host architecture suitable -# for assigning to the EPICS_HOST_ARCH variable - -if [ "x${1}" != "x" ] -then - suffix="-"${1} -else - suffix="" -fi - -sysname=`uname` - -case $sysname in - Linux ) - os=linux - cpu=`uname -m` - case $cpu in - i386 | i486 | i586 | i686 ) - cpu=x86 ;; - x86_64 ) - ;; # $cpu is correct - armv6l | armv7l ) - cpu=arm ;; - esac - echo ${os}-${cpu}${suffix} - ;; - Darwin ) - os=darwin - cpu=`uname -m` - case $cpu in - "Power Macintosh") - cpu=ppc ;; - i386 | x86_64 ) - cpu=x86 ;; - esac - echo ${os}-${cpu}${suffix} - ;; - SunOS ) - version=`uname -r | sed '1s/^\([0-9]*\).*$/\1/'` - if [ ${version} -ge 5 ]; then - os=solaris - else - os=sun4 - fi - cpu=`uname -m` - case $cpu in - sun4*) - cpu=sparc - ;; - i86pc) - cpu=x86 - ;; - esac - echo ${os}-${cpu}${suffix} - ;; - * ) - sysname=`uname -o` - case $sysname in - Cygwin ) - os=cygwin - cpu=`uname -m` - case $cpu in i386 | i486 | i586 | i686 ) - cpu=x86 - ;; - esac - echo ${os}-${cpu}${suffix} - ;; - * ) - echo unsupported - ;; - esac - ;; -esac - diff --git a/startup/EpicsHostArch.pl b/startup/EpicsHostArch.pl deleted file mode 100755 index 09f7ffddd..000000000 --- a/startup/EpicsHostArch.pl +++ /dev/null @@ -1,47 +0,0 @@ -eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*- - if $running_under_some_shell; # EpicsHostArch.pl -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# Returns the Epics host architecture suitable -# for assigning to the EPICS_HOST_ARCH variable - -use Config; -use POSIX; - -$suffix=""; -$suffix="-".$ARGV[0] if ($ARGV[0] ne ""); - -$EpicsHostArch = GetEpicsHostArch(); -print "$EpicsHostArch$suffix"; - -sub GetEpicsHostArch { # no args - $arch=$Config{'archname'}; - if ($arch =~ /sun4-solaris/) { return "solaris-sparc"; - } elsif ($arch =~ m/i86pc-solaris/) { return "solaris-x86"; - } elsif ($arch =~ m/i[3-6]86-linux/){ return "linux-x86"; - } elsif ($arch =~ m/x86_64-linux/) { return "linux-x86_64"; - } elsif ($arch =~ m/arm-linux/) { return "linux-arm"; - } elsif ($arch =~ m/MSWin32-x86/) { return "win32-x86"; - } elsif ($arch =~ m/MSWin32-x64/) { return "windows-x64"; - } elsif ($arch =~ m/cygwin/) { - my($kernel, $hostname, $release, $version, $cpu) = POSIX::uname(); - if ($cpu =~ m/x86_64/) { return "cygwin-x86_64"; } - return "cygwin-x86"; - } elsif ($arch =~ m/darwin/) { - my($kernel, $hostname, $release, $version, $cpu) = POSIX::uname(); - if ($cpu =~ m/Power Macintosh/) { return "darwin-ppc"; } - elsif ($cpu =~ m/i386/) { return "darwin-x86"; } - elsif ($cpu =~ m/x86_64/) { return "darwin-x86"; } - else { return "unsupported"; } - } else { return "unsupported"; } -} - -#EOF EpicsHostArch.pl - diff --git a/startup/Site.cshrc b/startup/Site.cshrc deleted file mode 100755 index 24f34abb9..000000000 --- a/startup/Site.cshrc +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/csh -f -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# Site-specific EPICS environment settings -# -# sites should modify these definitions - -# Location of epics base -if ( ! $?EPICS_BASE ) then - set EPICS_BASE=/usr/local/epics/base -endif - -# Location of epics extensions -if ( ! $?EPICS_EXTENSIONS ) then - setenv EPICS_EXTENSIONS /usr/local/epics/extensions -endif - -# Postscript printer definition needed by some extensions (eg medm, dp, dm, ...) -if ( ! $?PSPRINTTER ) then - setenv PSPRINTER lp -endif - -# Needed only by medm extension -#setenv EPICS_DISPLAY_PATH -# Needed only by medm extension -setenv BROWSER firefox - -# Needed only by orbitscreen extension -if ( ! $?ORBITSCREENHOME ) then - setenv ORBITSCREENHOME $EPICS_EXTENSIONS/src/orbitscreen -endif - -# Needed only by adt extension -if ( ! $?ADTHOME ) then - setenv ADTHOME /usr/local/oag/apps/src/appconfig/adt - echo $ADTHOME -endif - -# Needed only by ar extension (archiver) -setenv EPICS_AR_PORT 7002 - -# Needed for java extensions -if ( $?CLASSPATH ) then - setenv CLASSPATH "${CLASSPATH}:${EPICS_EXTENSIONS}/javalib" -else - setenv CLASSPATH "${EPICS_EXTENSIONS}/javalib" -endif - -# Allow private versions of extensions without a bin subdir -if ( $?EPICS_EXTENSIONS_PVT ) then - set path = ( $path $EPICS_EXTENSIONS_PVT) -endif - -################################################################## - -# Start of set R3.14 environment variables - -setenv EPICS_HOST_ARCH `$EPICS_BASE/startup/EpicsHostArch.pl` - -# Allow private versions of base -if ( $?EPICS_BASE_PVT ) then - if ( -e $EPICS_BASE_PVT/bin/$EPICS_HOST_ARCH ) then - set path = ( $path $EPICS_BASE_PVT/bin/$EPICS_HOST_ARCH) - endif -endif - -# Allow private versions of extensions -if ( $?EPICS_EXTENSIONS_PVT ) then - if ( -e $EPICS_EXTENSIONS_PVT/bin/$EPICS_HOST_ARCH ) then - set path = ( $path $EPICS_EXTENSIONS_PVT/bin/$EPICS_HOST_ARCH) - endif -endif -set path = ( $path $EPICS_EXTENSIONS/bin/$EPICS_HOST_ARCH ) - -# End of set R3.14 environment variables -################################################################## diff --git a/startup/Site.profile b/startup/Site.profile deleted file mode 100755 index 677001401..000000000 --- a/startup/Site.profile +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/sh -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# Site-specific EPICS environment settings -# -# sites should modify these definitions - -# Location of epics base -if [ -z "${MY_EPICS_BASE}" ] ; then - MY_EPICS_BASE=/usr/local/epics/base -fi - -# Location of epics extensions (medm, msi, etc.) -if [ -z "${EPICS_EXTENSIONS}" ] ; then - EPICS_EXTENSIONS=/usr/local/epics/extensions -fi - -# Postscript printer definition needed by some extensions (eg medm, dp, dm, ...) -if [ -z "${PSPRINTER}" ] ; then - export PSPRINTER=lp -fi - -#Needed only by the idl and ezcaIDL extensions. -#export EPICS_EXTENSIONS - -# Needed only by medm extension -#export EPICS_DISPLAY_PATH=/path/to/adl/files -export BROWSER=firefox - -# Needed only by orbitscreen extension -#if [ -z "${ORBITSCREENHOME}" ] ; then -# export "ORBITSCREENHOME=${EPICS_EXTENSIONS/src/orbitscreen}" -#fi - -# Needed only by adt extension -#if [ -z "${ADTHOME}" ] ; then -# ADTHOME= -# export ADTHOME -#fi - -# Needed only by ar extension (archiver) -#EPICS_AR_PORT=7002 -#export EPICS_AR_PORT - -# Needed for java extensions -if [ -z "${CLASSPATH}" ] ; then - CLASSPATH="${EPICS_EXTENSIONS}/javalib" -else - CLASSPATH="${CLASSPATH}:${EPICS_EXTENSIONS}/javalib" -fi -export CLASSPATH - -# Allow private versions of extensions without a bin subdir -if [ -n "${EPICS_EXTENSIONS_PVT}" ] ; then - PATH="${PATH}:${EPICS_EXTENSIONS_PVT}" -fi - -#--------------------------------------------------------------- -# Start of set R3.14 environment variables -# -EPICS_HOST_ARCH=`"${MY_EPICS_BASE}"/startup/EpicsHostArch.pl` -export EPICS_HOST_ARCH - -# Allow private versions of base -if [ -n "${EPICS_BASE_PVT}" ] ; then - if [ -d "${EPICS_BASE_PVT}/bin/${EPICS_HOST_ARCH}" ]; then - PATH="${PATH}:${EPICS_BASE_PVT}/bin/${EPICS_HOST_ARCH}" - fi -fi - -# Allow private versions of extensions -if [ -n "${EPICS_EXTENSIONS_PVT}" ] ; then - if [ -d "${EPICS_EXTENSIONS_PVT}/bin/${EPICS_HOST_ARCH}" ]; then - PATH="${PATH}:${EPICS_EXTENSIONS_PVT}/bin/${EPICS_HOST_ARCH}" - fi -fi -PATH="${PATH}:${EPICS_EXTENSIONS}/bin/${EPICS_HOST_ARCH}" - -# End of set R3.14 environment variables - -#--------------------------------------------------------------- diff --git a/startup/cygwin.bat b/startup/cygwin.bat deleted file mode 100755 index ff75b5335..000000000 --- a/startup/cygwin.bat +++ /dev/null @@ -1,122 +0,0 @@ -@ECHO OFF -REM ************************************************************************* -REM Copyright (c) 2002 The University of Chicago, as Operator of Argonne -REM National Laboratory. -REM Copyright (c) 2002 The Regents of the University of California, as -REM Operator of Los Alamos National Laboratory. -REM EPICS BASE Versions 3.13.7 -REM and higher are distributed subject to a Software License Agreement found -REM in file LICENSE that is included with this distribution. -REM ************************************************************************* -REM -REM Site-specific EPICS environment settings -REM -REM sites should modify these definitions - -REM ====================================================== -REM ====== REQUIRED ENVIRONMENT VARIABLES FOLLOW ====== -REM ====================================================== - -REM ====================================================== -REM ---------------- WINDOWS --------------------------- -REM ====================================================== -REM ----- WIN95 ----- -REM set PATH=C:\WINDOWS;C:\WINDOWS\COMMAND -REM ----- WINNT, WIN2000 ----- -REM set PATH=C:\WINNT;C:\WINNT\SYSTEM32 -REM ----- WINXP, Vista, Windows 7 ----- -set PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\SYSTEM32\Wbem - -REM ====================================================== -REM ---------------- make and perl --------------------- -REM ====================================================== - -REM --------------- ActiveState perl ------------------- -set PATH=C:\Perl\bin;%PATH% - -REM --------------- mingw make ------------------------ -REM set PATH=C:\mingw-make\bin;%PATH% -REM set PATH=C:\mingw-make82-3\bin;%PATH% - -REM --------------- gnuwin32 make ---------------------- -set PATH=C:\gnuwin32\bin;%PATH% - -REM ====================================================== -REM ---------------- cygwin tools ------------------------ -REM ====================================================== -REM (make & perl if above perl and make are REMs) -REM Dont use cygwin GNU make and Perl! -REM cygwin contains tk/tcl, vim, perl, and many unix tools -REM need grep from here NOT from cvs directory -set PATH=%PATH%;.;.. -set PATH=%PATH%;c:\cygwin\bin - -REM ====================================================== -REM --------------- EPICS -------------------------------- -REM ====================================================== -set EPICS_HOST_ARCH=cygwin-x86 -set PATH=%PATH%;G:\epics\base\bin\%EPICS_HOST_ARCH% -set PATH=%PATH%;G:\epics\extensions\bin\%EPICS_HOST_ARCH% - -REM ====================================================== -REM ------- OPTIONAL ENVIRONMENT VARIABLES FOLLOW -------- -REM ====================================================== - -REM ====================================================== -REM ----------------- remote CVS ------------------------- -REM ====================================================== -REM set CVS_RSH=c:/cygwin/bin/ssh.exe -REM set CVSROOT=:ext:jba@aps.anl.gov:/usr/local/epicsmgr/cvsroot -REM set HOME=c:/users/%USERNAME% -REM set HOME=c:/users/jba - -REM ====================================================== -REM ------------------- Bazaar --------------------------- -REM ====================================================== -set PATH=%PATH%;C:\Program files\Bazaar - -REM ====================================================== -REM ----------------- GNU make flags --------------------- -REM ====================================================== -set MAKEFLAGS=-w - -REM ====================================================== -REM -------------- vim (use cygwin vim ) ----------------- -REM ====================================================== -REM HOME needed by vim to write .viminfo file. -REM VIM needed by vim to find _vimrc file. -REM set VIM=c:\cygwin - -REM ====================================================== -REM --------------- Epics Channel Access ----------------- -REM Modify and uncomment the following lines -REM to override the base/configure/CONFIG_ENV defaults -REM ====================================================== -REM set EPICS_CA_ADDR_LIST=n.n.n.n n.n.n.n -REM set EPICS_CA_AUTO_ADDR_LIST=YES - -REM set EPICS_CA_CONN_TMO=30.0 -REM set EPICS_CA_BEACON_PERIOD=15.0 -REM set EPICS_CA_REPEATER_PORT=5065 -REM set EPICS_CA_SERVER_PORT=5064 -REM set EPICS_TS_MIN_WEST=420 - -REM ====================================================== -REM --------------- JAVA --------------------------------- -REM ====================================================== -REM Needed for java extensions -REM set CLASSPATH=G:\epics\extensions\javalib -REM set PATH=%PATH%;C:\j2sdk1.4.1_01\bin -REM set CLASSPATH=%CLASSPATH%;C:\j2sdk1.4.1_01\lib\tools.jar - -REM ====================================================== -REM --------------- Exceed ------------------------------- -REM Needed for X11 extensions -REM ====================================================== -REM set EX_VER=7.10 -REM set EX_VER=12.00 -REM set EX_VER=14.00 -REM set PATH=%PATH%;C:\Exceed%EX_VER%\XDK\ -REM set PATH=%PATH%;C:\Program Files\Hummingbird\Connectivity\%EX_VER%\Exceed\ - - diff --git a/startup/win32.bat b/startup/win32.bat deleted file mode 100755 index af9155dd7..000000000 --- a/startup/win32.bat +++ /dev/null @@ -1,147 +0,0 @@ -@ECHO OFF -REM ************************************************************************* -REM Copyright (c) 2002 The University of Chicago, as Operator of Argonne -REM National Laboratory. -REM Copyright (c) 2002 The Regents of the University of California, as -REM Operator of Los Alamos National Laboratory. -REM EPICS BASE Versions 3.13.7 -REM and higher are distributed subject to a Software License Agreement found -REM in file LICENSE that is included with this distribution. -REM ************************************************************************* -REM -REM Site-specific EPICS environment settings -REM -REM sites should modify these definitions - -REM ====================================================== -REM ====== REQUIRED ENVIRONMENT VARIABLES FOLLOW ====== -REM ====================================================== - -REM ====================================================== -REM ---------------- WINDOWS --------------------------- -REM ====================================================== -REM ----- WIN95 ----- -REM set PATH=C:\WINDOWS;C:\WINDOWS\COMMAND -REM ----- WINNT, WIN2000 ----- -REM set PATH=C:\WINNT;C:\WINNT\SYSTEM32 -REM ----- WINXP, Vista, Windows 7 ----- -set PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\SYSTEM32\Wbem - -REM ====================================================== -REM ---------------- make and perl --------------------- -REM ====================================================== - -REM --------------- ActiveState perl ------------------- -set PATH=C:\Perl\bin;%PATH% - -REM --------------- mingw make ------------------------ -REM set PATH=C:\mingw-make\bin;%PATH% -REM set PATH=C:\mingw-make82-3\bin;%PATH% - -REM --------------- gnuwin32 make ---------------------- -set PATH=C:\gnuwin32\bin;%PATH% - -REM ====================================================== -REM ---------------- cygwin tools ------------------------ -REM ====================================================== -REM (make & perl if above perl and make are REMs) -REM Dont use cygwin GNU make and Perl! -REM cygwin contains tk/tcl, vim, perl, and many unix tools -REM need grep from here NOT from cvs directory -REM set PATH=%PATH%;.;.. -REM set PATH=%PATH%;c:\cygwin\bin - -REM ====================================================== -REM --------------- Visual c++ ------------------------- -REM ====================================================== - -REM ------ Microsoft Visual Studio 2005 ------ -REM call "C:\Program files\Microsoft Visual Studio 8\VC\vcvarsall.bat" x86_amd64 -REM set PATH=%PATH%;C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin -REM set INCLUDE=%INCLUDE%;C:\Program Files\Microsoft SDKs\Windows\v6.0A\include -REM REM set LIBPATH=%LIBPATH%;C:\Program Files\Microsoft SDKs\Windows\v6.0A\lib -REM set LIB=%LIB%;C:\Program Files\Microsoft SDKs\Windows\v6.0A\lib - -REM ------ Microsoft Visual Studio 2008 ------ -REM call "C:\Program files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat" -REM call "C:\Program files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86_amd64 -REM set PATH=C:\Program Files\Microsoft SDKs\Windows\v7.0\bin;%PATH% -REM set INCLUDE=C:\Program Files\Microsoft SDKs\Windows\v7.0\include;%INCLUDE% -REM set LIBPATH=C:\Program Files\Microsoft SDKs\Windows\v7.0\lib;%LIBPATH% -REM set LIB=C:\Program Files\Microsoft SDKs\Windows\v7.0\lib;%LIB% - -REM ----- Visual Studion 2010 ----- -REM -- windows-x64 --- -REM call "C:\Program files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x64 -REM -- win32-x86 --- -call "C:\Program files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86 - -REM ====================================================== -REM --------------- EPICS -------------------------------- -REM ====================================================== -REM set EPICS_HOST_ARCH=windows-x64 -set EPICS_HOST_ARCH=win32-x86 -set PATH=%PATH%;G:\epics\base\bin\%EPICS_HOST_ARCH% -set PATH=%PATH%;G:\epics\extensions\bin\%EPICS_HOST_ARCH% - -REM ====================================================== -REM ------- OPTIONAL ENVIRONMENT VARIABLES FOLLOW -------- -REM ====================================================== - -REM ====================================================== -REM ----------------- remote CVS ------------------------- -REM ====================================================== -REM set CVS_RSH=c:/cygwin/bin/ssh.exe -REM set CVSROOT=:ext:jba@aps.anl.gov:/usr/local/epicsmgr/cvsroot -REM set HOME=c:/users/%USERNAME% -REM set HOME=c:/users/jba - -REM ====================================================== -REM ------------------- Bazaar --------------------------- -REM ====================================================== -set PATH=%PATH%;C:\Program files\Bazaar - -REM ====================================================== -REM ----------------- GNU make flags --------------------- -REM ====================================================== -set MAKEFLAGS=-w - -REM ====================================================== -REM -------------- vim (use cygwin vim ) ----------------- -REM ====================================================== -REM HOME needed by vim to write .viminfo file. -REM VIM needed by vim to find _vimrc file. -REM set VIM=c:\cygwin - -REM ====================================================== -REM --------------- Epics Channel Access ----------------- -REM Modify and uncomment the following lines -REM to override the base/configure/CONFIG_ENV defaults -REM ====================================================== -REM set EPICS_CA_ADDR_LIST=n.n.n.n n.n.n.n -REM set EPICS_CA_AUTO_ADDR_LIST=YES - -REM set EPICS_CA_CONN_TMO=30.0 -REM set EPICS_CA_BEACON_PERIOD=15.0 -REM set EPICS_CA_REPEATER_PORT=5065 -REM set EPICS_CA_SERVER_PORT=5064 -REM set EPICS_TS_MIN_WEST=420 - -REM ====================================================== -REM --------------- JAVA --------------------------------- -REM ====================================================== -REM Needed for java extensions -REM set CLASSPATH=G:\epics\extensions\javalib -REM set PATH=%PATH%;C:\j2sdk1.4.1_01\bin -REM set CLASSPATH=%CLASSPATH%;C:\j2sdk1.4.1_01\lib\tools.jar - -REM ====================================================== -REM --------------- Exceed ------------------------------- -REM Needed for X11 extensions -REM ====================================================== -REM set EX_VER=7.10 -REM set EX_VER=12.00 -REM set EX_VER=14.00 -REM set PATH=%PATH%;C:\Exceed%EX_VER%\XDK\ -REM set PATH=%PATH%;C:\Program Files\Hummingbird\Connectivity\%EX_VER%\Exceed\ - diff --git a/src/ca/legacy/pcas/Makefile b/test/Makefile similarity index 71% rename from src/ca/legacy/pcas/Makefile rename to test/Makefile index 04884424e..b47389f94 100644 --- a/src/ca/legacy/pcas/Makefile +++ b/test/Makefile @@ -4,17 +4,18 @@ # Copyright (c) 2002 The Regents of the University of California, as # Operator of 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. #************************************************************************* -TOP=../../../.. - +TOP = .. include $(TOP)/configure/CONFIG -DIRS = build example +DIRS += ioc/db +DIRS += ioc/dbtemplate -example_DEPEND_DIRS = build - -include $(TOP)/configure/RULES_DIRS +DIRS += std/rec +DIRS += std/filters +DIRS += tools +include $(TOP)/configure/RULES_TOP diff --git a/src/ioc/db/test/Makefile b/test/ioc/db/Makefile similarity index 98% rename from src/ioc/db/test/Makefile rename to test/ioc/db/Makefile index 37ec3da74..357520b24 100644 --- a/src/ioc/db/test/Makefile +++ b/test/ioc/db/Makefile @@ -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 the file LICENSE that is included with this distribution. +# in the file LICENSE that is included with this distribution. #************************************************************************* -TOP=../../../.. +TOP = ../../.. include $(TOP)/configure/CONFIG # Allow access to private headers in db/ @@ -192,4 +192,3 @@ 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/test/ioc/db/arrRecord.c similarity index 100% rename from src/ioc/db/test/arrRecord.c rename to test/ioc/db/arrRecord.c diff --git a/src/ioc/db/test/arrRecord.dbd b/test/ioc/db/arrRecord.dbd similarity index 100% rename from src/ioc/db/test/arrRecord.dbd rename to test/ioc/db/arrRecord.dbd diff --git a/src/ioc/db/test/arrShorthandTest.c b/test/ioc/db/arrShorthandTest.c similarity index 100% rename from src/ioc/db/test/arrShorthandTest.c rename to test/ioc/db/arrShorthandTest.c diff --git a/src/ioc/db/test/benchdbConvert.c b/test/ioc/db/benchdbConvert.c similarity index 100% rename from src/ioc/db/test/benchdbConvert.c rename to test/ioc/db/benchdbConvert.c diff --git a/src/ioc/db/test/callbackParallelTest.c b/test/ioc/db/callbackParallelTest.c similarity index 100% rename from src/ioc/db/test/callbackParallelTest.c rename to test/ioc/db/callbackParallelTest.c diff --git a/src/ioc/db/test/callbackTest.c b/test/ioc/db/callbackTest.c similarity index 100% rename from src/ioc/db/test/callbackTest.c rename to test/ioc/db/callbackTest.c diff --git a/src/ioc/db/test/chfPluginTest.c b/test/ioc/db/chfPluginTest.c similarity index 100% rename from src/ioc/db/test/chfPluginTest.c rename to test/ioc/db/chfPluginTest.c diff --git a/src/ioc/db/test/dbBadLink.db b/test/ioc/db/dbBadLink.db similarity index 100% rename from src/ioc/db/test/dbBadLink.db rename to test/ioc/db/dbBadLink.db diff --git a/src/ioc/db/test/dbCACTest.cpp b/test/ioc/db/dbCACTest.cpp similarity index 100% rename from src/ioc/db/test/dbCACTest.cpp rename to test/ioc/db/dbCACTest.cpp diff --git a/src/ioc/db/test/dbCaLinkTest.c b/test/ioc/db/dbCaLinkTest.c similarity index 100% rename from src/ioc/db/test/dbCaLinkTest.c rename to test/ioc/db/dbCaLinkTest.c diff --git a/src/ioc/db/test/dbCaLinkTest1.db b/test/ioc/db/dbCaLinkTest1.db similarity index 100% rename from src/ioc/db/test/dbCaLinkTest1.db rename to test/ioc/db/dbCaLinkTest1.db diff --git a/src/ioc/db/test/dbCaLinkTest2.db b/test/ioc/db/dbCaLinkTest2.db similarity index 100% rename from src/ioc/db/test/dbCaLinkTest2.db rename to test/ioc/db/dbCaLinkTest2.db diff --git a/src/ioc/db/test/dbCaLinkTest3.db b/test/ioc/db/dbCaLinkTest3.db similarity index 100% rename from src/ioc/db/test/dbCaLinkTest3.db rename to test/ioc/db/dbCaLinkTest3.db diff --git a/src/ioc/db/test/dbCaStats.db b/test/ioc/db/dbCaStats.db similarity index 100% rename from src/ioc/db/test/dbCaStats.db rename to test/ioc/db/dbCaStats.db diff --git a/src/ioc/db/test/dbCaStatsTest.c b/test/ioc/db/dbCaStatsTest.c similarity index 100% rename from src/ioc/db/test/dbCaStatsTest.c rename to test/ioc/db/dbCaStatsTest.c diff --git a/src/ioc/db/test/dbChArrTest.cpp b/test/ioc/db/dbChArrTest.cpp similarity index 100% rename from src/ioc/db/test/dbChArrTest.cpp rename to test/ioc/db/dbChArrTest.cpp diff --git a/src/ioc/db/test/dbChArrTest.db b/test/ioc/db/dbChArrTest.db similarity index 100% rename from src/ioc/db/test/dbChArrTest.db rename to test/ioc/db/dbChArrTest.db diff --git a/src/ioc/db/test/dbChannelTest.c b/test/ioc/db/dbChannelTest.c similarity index 100% rename from src/ioc/db/test/dbChannelTest.c rename to test/ioc/db/dbChannelTest.c diff --git a/src/ioc/db/test/dbLinkdset.c b/test/ioc/db/dbLinkdset.c similarity index 100% rename from src/ioc/db/test/dbLinkdset.c rename to test/ioc/db/dbLinkdset.c diff --git a/src/ioc/db/test/dbLinkdset.dbd b/test/ioc/db/dbLinkdset.dbd similarity index 100% rename from src/ioc/db/test/dbLinkdset.dbd rename to test/ioc/db/dbLinkdset.dbd diff --git a/src/ioc/db/test/dbLockTest.c b/test/ioc/db/dbLockTest.c similarity index 100% rename from src/ioc/db/test/dbLockTest.c rename to test/ioc/db/dbLockTest.c diff --git a/src/ioc/db/test/dbLockTest.db b/test/ioc/db/dbLockTest.db similarity index 100% rename from src/ioc/db/test/dbLockTest.db rename to test/ioc/db/dbLockTest.db diff --git a/src/ioc/db/test/dbPutGetTest.c b/test/ioc/db/dbPutGetTest.c similarity index 100% rename from src/ioc/db/test/dbPutGetTest.c rename to test/ioc/db/dbPutGetTest.c diff --git a/src/ioc/db/test/dbPutGetTest.db b/test/ioc/db/dbPutGetTest.db similarity index 100% rename from src/ioc/db/test/dbPutGetTest.db rename to test/ioc/db/dbPutGetTest.db diff --git a/src/ioc/db/test/dbPutLinkTest.c b/test/ioc/db/dbPutLinkTest.c similarity index 100% rename from src/ioc/db/test/dbPutLinkTest.c rename to test/ioc/db/dbPutLinkTest.c diff --git a/src/ioc/db/test/dbPutLinkTest.db b/test/ioc/db/dbPutLinkTest.db similarity index 100% rename from src/ioc/db/test/dbPutLinkTest.db rename to test/ioc/db/dbPutLinkTest.db diff --git a/src/ioc/db/test/dbPutLinkTestJ.db b/test/ioc/db/dbPutLinkTestJ.db similarity index 100% rename from src/ioc/db/test/dbPutLinkTestJ.db rename to test/ioc/db/dbPutLinkTestJ.db diff --git a/src/ioc/db/test/dbScanTest.c b/test/ioc/db/dbScanTest.c similarity index 100% rename from src/ioc/db/test/dbScanTest.c rename to test/ioc/db/dbScanTest.c diff --git a/src/ioc/db/test/dbShutdownTest.c b/test/ioc/db/dbShutdownTest.c similarity index 100% rename from src/ioc/db/test/dbShutdownTest.c rename to test/ioc/db/dbShutdownTest.c diff --git a/src/ioc/db/test/dbStateTest.c b/test/ioc/db/dbStateTest.c similarity index 100% rename from src/ioc/db/test/dbStateTest.c rename to test/ioc/db/dbStateTest.c diff --git a/src/ioc/db/test/dbStaticTest.c b/test/ioc/db/dbStaticTest.c similarity index 100% rename from src/ioc/db/test/dbStaticTest.c rename to test/ioc/db/dbStaticTest.c diff --git a/src/ioc/db/test/dbStaticTest.db b/test/ioc/db/dbStaticTest.db similarity index 100% rename from src/ioc/db/test/dbStaticTest.db rename to test/ioc/db/dbStaticTest.db diff --git a/src/ioc/db/test/dbStressLock.c b/test/ioc/db/dbStressLock.c similarity index 100% rename from src/ioc/db/test/dbStressLock.c rename to test/ioc/db/dbStressLock.c diff --git a/src/ioc/db/test/dbStressLock.db b/test/ioc/db/dbStressLock.db similarity index 100% rename from src/ioc/db/test/dbStressLock.db rename to test/ioc/db/dbStressLock.db diff --git a/src/ioc/db/test/devx.c b/test/ioc/db/devx.c similarity index 100% rename from src/ioc/db/test/devx.c rename to test/ioc/db/devx.c diff --git a/src/ioc/db/test/devx.dbd b/test/ioc/db/devx.dbd similarity index 100% rename from src/ioc/db/test/devx.dbd rename to test/ioc/db/devx.dbd diff --git a/src/ioc/db/test/devx.h b/test/ioc/db/devx.h similarity index 100% rename from src/ioc/db/test/devx.h rename to test/ioc/db/devx.h diff --git a/src/ioc/db/test/epicsRunDbTests.c b/test/ioc/db/epicsRunDbTests.c similarity index 100% rename from src/ioc/db/test/epicsRunDbTests.c rename to test/ioc/db/epicsRunDbTests.c diff --git a/src/ioc/db/test/jlinkz.c b/test/ioc/db/jlinkz.c similarity index 100% rename from src/ioc/db/test/jlinkz.c rename to test/ioc/db/jlinkz.c diff --git a/src/ioc/db/test/jlinkz.dbd b/test/ioc/db/jlinkz.dbd similarity index 100% rename from src/ioc/db/test/jlinkz.dbd rename to test/ioc/db/jlinkz.dbd diff --git a/src/ioc/db/test/jlinkz.h b/test/ioc/db/jlinkz.h similarity index 100% rename from src/ioc/db/test/jlinkz.h rename to test/ioc/db/jlinkz.h diff --git a/src/ioc/db/test/recGblCheckDeadbandTest.c b/test/ioc/db/recGblCheckDeadbandTest.c similarity index 100% rename from src/ioc/db/test/recGblCheckDeadbandTest.c rename to test/ioc/db/recGblCheckDeadbandTest.c diff --git a/src/ioc/db/test/rtemsTestHarness.c b/test/ioc/db/rtemsTestHarness.c similarity index 100% rename from src/ioc/db/test/rtemsTestHarness.c rename to test/ioc/db/rtemsTestHarness.c diff --git a/src/ioc/db/test/scanIoTest.c b/test/ioc/db/scanIoTest.c similarity index 100% rename from src/ioc/db/test/scanIoTest.c rename to test/ioc/db/scanIoTest.c diff --git a/src/ioc/db/test/scanIoTest.db b/test/ioc/db/scanIoTest.db similarity index 100% rename from src/ioc/db/test/scanIoTest.db rename to test/ioc/db/scanIoTest.db diff --git a/src/ioc/db/test/testdbConvert.c b/test/ioc/db/testdbConvert.c similarity index 100% rename from src/ioc/db/test/testdbConvert.c rename to test/ioc/db/testdbConvert.c diff --git a/src/ioc/db/test/xLink.c b/test/ioc/db/xLink.c similarity index 100% rename from src/ioc/db/test/xLink.c rename to test/ioc/db/xLink.c diff --git a/src/ioc/db/test/xLink.dbd b/test/ioc/db/xLink.dbd similarity index 100% rename from src/ioc/db/test/xLink.dbd rename to test/ioc/db/xLink.dbd diff --git a/src/ioc/db/test/xRecord.c b/test/ioc/db/xRecord.c similarity index 100% rename from src/ioc/db/test/xRecord.c rename to test/ioc/db/xRecord.c diff --git a/src/ioc/db/test/xRecord.db b/test/ioc/db/xRecord.db similarity index 100% rename from src/ioc/db/test/xRecord.db rename to test/ioc/db/xRecord.db diff --git a/src/ioc/db/test/xRecord.dbd b/test/ioc/db/xRecord.dbd similarity index 100% rename from src/ioc/db/test/xRecord.dbd rename to test/ioc/db/xRecord.dbd diff --git a/src/ioc/dbtemplate/test/Makefile b/test/ioc/dbtemplate/Makefile similarity index 89% rename from src/ioc/dbtemplate/test/Makefile rename to test/ioc/dbtemplate/Makefile index fb03b54cf..ff861695b 100644 --- a/src/ioc/dbtemplate/test/Makefile +++ b/test/ioc/dbtemplate/Makefile @@ -2,9 +2,10 @@ # 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. +# in the file LICENSE that is included with this distribution. #************************************************************************* -TOP=../../../.. + +TOP = ../../.. include $(TOP)/configure/CONFIG diff --git a/src/ioc/dbtemplate/test/dbltExpand.c b/test/ioc/dbtemplate/dbltExpand.c similarity index 100% rename from src/ioc/dbtemplate/test/dbltExpand.c rename to test/ioc/dbtemplate/dbltExpand.c diff --git a/src/ioc/dbtemplate/test/msi.plt b/test/ioc/dbtemplate/msi.plt similarity index 100% rename from src/ioc/dbtemplate/test/msi.plt rename to test/ioc/dbtemplate/msi.plt diff --git a/src/ioc/dbtemplate/test/t1-include.txt b/test/ioc/dbtemplate/t1-include.txt similarity index 100% rename from src/ioc/dbtemplate/test/t1-include.txt rename to test/ioc/dbtemplate/t1-include.txt diff --git a/src/ioc/dbtemplate/test/t1-result.txt b/test/ioc/dbtemplate/t1-result.txt similarity index 100% rename from src/ioc/dbtemplate/test/t1-result.txt rename to test/ioc/dbtemplate/t1-result.txt diff --git a/src/ioc/dbtemplate/test/t1-template.txt b/test/ioc/dbtemplate/t1-template.txt similarity index 100% rename from src/ioc/dbtemplate/test/t1-template.txt rename to test/ioc/dbtemplate/t1-template.txt diff --git a/src/ioc/dbtemplate/test/t2-result.txt b/test/ioc/dbtemplate/t2-result.txt similarity index 100% rename from src/ioc/dbtemplate/test/t2-result.txt rename to test/ioc/dbtemplate/t2-result.txt diff --git a/src/ioc/dbtemplate/test/t2-substitution.txt b/test/ioc/dbtemplate/t2-substitution.txt similarity index 100% rename from src/ioc/dbtemplate/test/t2-substitution.txt rename to test/ioc/dbtemplate/t2-substitution.txt diff --git a/src/ioc/dbtemplate/test/t2-template.txt b/test/ioc/dbtemplate/t2-template.txt similarity index 100% rename from src/ioc/dbtemplate/test/t2-template.txt rename to test/ioc/dbtemplate/t2-template.txt diff --git a/src/ioc/dbtemplate/test/t3-result.txt b/test/ioc/dbtemplate/t3-result.txt similarity index 100% rename from src/ioc/dbtemplate/test/t3-result.txt rename to test/ioc/dbtemplate/t3-result.txt diff --git a/src/ioc/dbtemplate/test/t3-substitution.txt b/test/ioc/dbtemplate/t3-substitution.txt similarity index 100% rename from src/ioc/dbtemplate/test/t3-substitution.txt rename to test/ioc/dbtemplate/t3-substitution.txt diff --git a/src/ioc/dbtemplate/test/t3-template.txt b/test/ioc/dbtemplate/t3-template.txt similarity index 100% rename from src/ioc/dbtemplate/test/t3-template.txt rename to test/ioc/dbtemplate/t3-template.txt diff --git a/src/ioc/dbtemplate/test/t4-result.txt b/test/ioc/dbtemplate/t4-result.txt similarity index 100% rename from src/ioc/dbtemplate/test/t4-result.txt rename to test/ioc/dbtemplate/t4-result.txt diff --git a/src/ioc/dbtemplate/test/t4-substitution.txt b/test/ioc/dbtemplate/t4-substitution.txt similarity index 100% rename from src/ioc/dbtemplate/test/t4-substitution.txt rename to test/ioc/dbtemplate/t4-substitution.txt diff --git a/src/ioc/dbtemplate/test/t5-result.txt b/test/ioc/dbtemplate/t5-result.txt similarity index 100% rename from src/ioc/dbtemplate/test/t5-result.txt rename to test/ioc/dbtemplate/t5-result.txt diff --git a/src/ioc/dbtemplate/test/t5-substitute.txt b/test/ioc/dbtemplate/t5-substitute.txt similarity index 100% rename from src/ioc/dbtemplate/test/t5-substitute.txt rename to test/ioc/dbtemplate/t5-substitute.txt diff --git a/src/ioc/dbtemplate/test/t5-template.txt b/test/ioc/dbtemplate/t5-template.txt similarity index 100% rename from src/ioc/dbtemplate/test/t5-template.txt rename to test/ioc/dbtemplate/t5-template.txt diff --git a/src/ioc/dbtemplate/test/t6-result.txt b/test/ioc/dbtemplate/t6-result.txt similarity index 100% rename from src/ioc/dbtemplate/test/t6-result.txt rename to test/ioc/dbtemplate/t6-result.txt diff --git a/src/ioc/dbtemplate/test/t6-substitute.txt b/test/ioc/dbtemplate/t6-substitute.txt similarity index 100% rename from src/ioc/dbtemplate/test/t6-substitute.txt rename to test/ioc/dbtemplate/t6-substitute.txt diff --git a/src/ioc/dbtemplate/test/t6-template.txt b/test/ioc/dbtemplate/t6-template.txt similarity index 100% rename from src/ioc/dbtemplate/test/t6-template.txt rename to test/ioc/dbtemplate/t6-template.txt diff --git a/src/ioc/dbtemplate/test/t8-result.txt b/test/ioc/dbtemplate/t8-result.txt similarity index 100% rename from src/ioc/dbtemplate/test/t8-result.txt rename to test/ioc/dbtemplate/t8-result.txt diff --git a/src/ioc/dbtemplate/test/t9-result.txt b/test/ioc/dbtemplate/t9-result.txt similarity index 100% rename from src/ioc/dbtemplate/test/t9-result.txt rename to test/ioc/dbtemplate/t9-result.txt diff --git a/src/std/filters/test/Makefile b/test/std/filters/Makefile similarity index 96% rename from src/std/filters/test/Makefile rename to test/std/filters/Makefile index 6e6ad79c6..540a4d76c 100644 --- a/src/std/filters/test/Makefile +++ b/test/std/filters/Makefile @@ -4,9 +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 the file LICENSE that is included with this distribution. +# in the file LICENSE that is included with this distribution. #************************************************************************* -TOP=../../../.. + +TOP = ../../.. include $(TOP)/configure/CONFIG diff --git a/src/std/filters/test/arrRecord.c b/test/std/filters/arrRecord.c similarity index 100% rename from src/std/filters/test/arrRecord.c rename to test/std/filters/arrRecord.c diff --git a/src/std/filters/test/arrRecord.dbd b/test/std/filters/arrRecord.dbd similarity index 100% rename from src/std/filters/test/arrRecord.dbd rename to test/std/filters/arrRecord.dbd diff --git a/src/std/filters/test/arrTest.cpp b/test/std/filters/arrTest.cpp similarity index 100% rename from src/std/filters/test/arrTest.cpp rename to test/std/filters/arrTest.cpp diff --git a/src/std/filters/test/arrTest.db b/test/std/filters/arrTest.db similarity index 100% rename from src/std/filters/test/arrTest.db rename to test/std/filters/arrTest.db diff --git a/src/std/filters/test/dbndTest.c b/test/std/filters/dbndTest.c similarity index 100% rename from src/std/filters/test/dbndTest.c rename to test/std/filters/dbndTest.c diff --git a/src/std/filters/test/epicsRunFilterTests.c b/test/std/filters/epicsRunFilterTests.c similarity index 100% rename from src/std/filters/test/epicsRunFilterTests.c rename to test/std/filters/epicsRunFilterTests.c diff --git a/src/std/filters/test/rtemsTestHarness.c b/test/std/filters/rtemsTestHarness.c similarity index 100% rename from src/std/filters/test/rtemsTestHarness.c rename to test/std/filters/rtemsTestHarness.c diff --git a/src/std/filters/test/syncTest.c b/test/std/filters/syncTest.c similarity index 100% rename from src/std/filters/test/syncTest.c rename to test/std/filters/syncTest.c diff --git a/src/std/filters/test/tsTest.c b/test/std/filters/tsTest.c similarity index 100% rename from src/std/filters/test/tsTest.c rename to test/std/filters/tsTest.c diff --git a/src/std/filters/test/xRecord.c b/test/std/filters/xRecord.c similarity index 100% rename from src/std/filters/test/xRecord.c rename to test/std/filters/xRecord.c diff --git a/src/std/filters/test/xRecord.db b/test/std/filters/xRecord.db similarity index 100% rename from src/std/filters/test/xRecord.db rename to test/std/filters/xRecord.db diff --git a/src/std/filters/test/xRecord.dbd b/test/std/filters/xRecord.dbd similarity index 100% rename from src/std/filters/test/xRecord.dbd rename to test/std/filters/xRecord.dbd diff --git a/src/std/rec/test/Makefile b/test/std/rec/Makefile similarity index 99% rename from src/std/rec/test/Makefile rename to test/std/rec/Makefile index 5a591b230..70bff0f32 100644 --- a/src/std/rec/test/Makefile +++ b/test/std/rec/Makefile @@ -6,8 +6,8 @@ # EPICS BASE is distributed subject to a Software License Agreement found # in the file LICENSE that is included with this distribution. #************************************************************************* -TOP=../../../.. +TOP = ../../.. include $(TOP)/configure/CONFIG TESTLIBRARY = dbRecStdTest diff --git a/src/std/rec/test/analogMonitorTest.c b/test/std/rec/analogMonitorTest.c similarity index 100% rename from src/std/rec/test/analogMonitorTest.c rename to test/std/rec/analogMonitorTest.c diff --git a/src/std/rec/test/analogMonitorTest.db b/test/std/rec/analogMonitorTest.db similarity index 100% rename from src/std/rec/test/analogMonitorTest.db rename to test/std/rec/analogMonitorTest.db diff --git a/src/std/rec/test/arrayOpTest.c b/test/std/rec/arrayOpTest.c similarity index 100% rename from src/std/rec/test/arrayOpTest.c rename to test/std/rec/arrayOpTest.c diff --git a/src/std/rec/test/arrayOpTest.db b/test/std/rec/arrayOpTest.db similarity index 100% rename from src/std/rec/test/arrayOpTest.db rename to test/std/rec/arrayOpTest.db diff --git a/src/std/rec/test/asTest.c b/test/std/rec/asTest.c similarity index 100% rename from src/std/rec/test/asTest.c rename to test/std/rec/asTest.c diff --git a/src/std/rec/test/asTest.db b/test/std/rec/asTest.db similarity index 100% rename from src/std/rec/test/asTest.db rename to test/std/rec/asTest.db diff --git a/src/std/rec/test/asTest.dbd b/test/std/rec/asTest.dbd similarity index 100% rename from src/std/rec/test/asTest.dbd rename to test/std/rec/asTest.dbd diff --git a/src/std/rec/test/asTestLib.c b/test/std/rec/asTestLib.c similarity index 100% rename from src/std/rec/test/asTestLib.c rename to test/std/rec/asTestLib.c diff --git a/src/std/rec/test/asyncSoftTest.c b/test/std/rec/asyncSoftTest.c similarity index 100% rename from src/std/rec/test/asyncSoftTest.c rename to test/std/rec/asyncSoftTest.c diff --git a/src/std/rec/test/asyncSoftTest.db b/test/std/rec/asyncSoftTest.db similarity index 100% rename from src/std/rec/test/asyncSoftTest.db rename to test/std/rec/asyncSoftTest.db diff --git a/src/std/rec/test/compressTest.c b/test/std/rec/compressTest.c similarity index 100% rename from src/std/rec/test/compressTest.c rename to test/std/rec/compressTest.c diff --git a/src/std/rec/test/compressTest.db b/test/std/rec/compressTest.db similarity index 100% rename from src/std/rec/test/compressTest.db rename to test/std/rec/compressTest.db diff --git a/src/std/rec/test/epicsRunRecordTests.c b/test/std/rec/epicsRunRecordTests.c similarity index 100% rename from src/std/rec/test/epicsRunRecordTests.c rename to test/std/rec/epicsRunRecordTests.c diff --git a/src/std/rec/test/linkInitTest.c b/test/std/rec/linkInitTest.c similarity index 100% rename from src/std/rec/test/linkInitTest.c rename to test/std/rec/linkInitTest.c diff --git a/src/std/rec/test/linkInitTest.db b/test/std/rec/linkInitTest.db similarity index 100% rename from src/std/rec/test/linkInitTest.db rename to test/std/rec/linkInitTest.db diff --git a/src/std/rec/test/linkRetargetLink.db b/test/std/rec/linkRetargetLink.db similarity index 100% rename from src/std/rec/test/linkRetargetLink.db rename to test/std/rec/linkRetargetLink.db diff --git a/src/std/rec/test/linkRetargetLinkTest.c b/test/std/rec/linkRetargetLinkTest.c similarity index 100% rename from src/std/rec/test/linkRetargetLinkTest.c rename to test/std/rec/linkRetargetLinkTest.c diff --git a/src/std/rec/test/recMiscTest.c b/test/std/rec/recMiscTest.c similarity index 100% rename from src/std/rec/test/recMiscTest.c rename to test/std/rec/recMiscTest.c diff --git a/src/std/rec/test/recMiscTest.db b/test/std/rec/recMiscTest.db similarity index 100% rename from src/std/rec/test/recMiscTest.db rename to test/std/rec/recMiscTest.db diff --git a/src/std/rec/test/regressArray1.db b/test/std/rec/regressArray1.db similarity index 100% rename from src/std/rec/test/regressArray1.db rename to test/std/rec/regressArray1.db diff --git a/src/std/rec/test/regressHex.db b/test/std/rec/regressHex.db similarity index 100% rename from src/std/rec/test/regressHex.db rename to test/std/rec/regressHex.db diff --git a/src/std/rec/test/regressLinkMS.db b/test/std/rec/regressLinkMS.db similarity index 100% rename from src/std/rec/test/regressLinkMS.db rename to test/std/rec/regressLinkMS.db diff --git a/src/std/rec/test/regressTest.c b/test/std/rec/regressTest.c similarity index 100% rename from src/std/rec/test/regressTest.c rename to test/std/rec/regressTest.c diff --git a/src/std/rec/test/rtemsTestHarness.c b/test/std/rec/rtemsTestHarness.c similarity index 100% rename from src/std/rec/test/rtemsTestHarness.c rename to test/std/rec/rtemsTestHarness.c diff --git a/src/std/rec/test/softTest.c b/test/std/rec/softTest.c similarity index 100% rename from src/std/rec/test/softTest.c rename to test/std/rec/softTest.c diff --git a/src/std/rec/test/softTest.db b/test/std/rec/softTest.db similarity index 100% rename from src/std/rec/test/softTest.db rename to test/std/rec/softTest.db diff --git a/src/tools/test/Breaktable.plt b/test/tools/Breaktable.plt similarity index 100% rename from src/tools/test/Breaktable.plt rename to test/tools/Breaktable.plt diff --git a/src/tools/test/DBD.plt b/test/tools/DBD.plt similarity index 100% rename from src/tools/test/DBD.plt rename to test/tools/DBD.plt diff --git a/src/tools/test/Device.plt b/test/tools/Device.plt similarity index 100% rename from src/tools/test/Device.plt rename to test/tools/Device.plt diff --git a/src/tools/test/Driver.plt b/test/tools/Driver.plt similarity index 100% rename from src/tools/test/Driver.plt rename to test/tools/Driver.plt diff --git a/src/tools/test/Function.plt b/test/tools/Function.plt similarity index 100% rename from src/tools/test/Function.plt rename to test/tools/Function.plt diff --git a/src/tools/test/Makefile b/test/tools/Makefile similarity index 86% rename from src/tools/test/Makefile rename to test/tools/Makefile index 2fed19509..e246a90a1 100644 --- a/src/tools/test/Makefile +++ b/test/tools/Makefile @@ -2,10 +2,10 @@ # 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. +# in the file LICENSE that is included with this distribution. #************************************************************************* -TOP=../../.. +TOP = ../.. include $(TOP)/configure/CONFIG TESTS += Breaktable @@ -18,10 +18,8 @@ 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/test/tools/Menu.plt similarity index 100% rename from src/tools/test/Menu.plt rename to test/tools/Menu.plt diff --git a/src/tools/test/Recfield.plt b/test/tools/Recfield.plt similarity index 100% rename from src/tools/test/Recfield.plt rename to test/tools/Recfield.plt diff --git a/src/tools/test/Recordtype.plt b/test/tools/Recordtype.plt similarity index 100% rename from src/tools/test/Recordtype.plt rename to test/tools/Recordtype.plt diff --git a/src/tools/test/Registrar.plt b/test/tools/Registrar.plt similarity index 100% rename from src/tools/test/Registrar.plt rename to test/tools/Registrar.plt diff --git a/src/tools/test/Variable.plt b/test/tools/Variable.plt similarity index 100% rename from src/tools/test/Variable.plt rename to test/tools/Variable.plt diff --git a/src/tools/test/macLib.plt b/test/tools/macLib.plt similarity index 100% rename from src/tools/test/macLib.plt rename to test/tools/macLib.plt