Merge branch '7.0' into add-simm-to-ao-records

This commit is contained in:
Ralph Lange
2022-05-11 10:47:12 -07:00
committed by GitHub
337 changed files with 4510 additions and 4034 deletions

View File

@@ -33,6 +33,7 @@ skip_commits:
- '.github/*'
- '.tools/*'
- '.gitattributes'
- '.lgtm.yml'
- '**/*.html'
- '**/*.md'

View File

@@ -39,6 +39,7 @@ skip_commits:
- 'startup/*'
- '.github/*'
- '.tools/*'
- '.lgtm.yml'
- '.gitattributes'
- '**/*.html'
- '**/*.md'

2
.ci

Submodule .ci updated: d675de24e6...75bae77c1d

View File

@@ -15,6 +15,7 @@ on:
- 'startup/*'
- '.appveyor/*'
- '.tools/*'
- '.lgtm.yml'
- '.gitattributes'
- '**/*.html'
- '**/*.md'
@@ -24,6 +25,7 @@ on:
- 'startup/*'
- '.appveyor/*'
- '.tools/*'
- '.lgtm.yml'
- '.gitattributes'
- '**/*.html'
- '**/*.md'
@@ -34,7 +36,7 @@ env:
EPICS_TEST_IMPRECISE_TIMING: YES
jobs:
build-base:
native:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
# Set environment variables from matrix parameters
@@ -69,10 +71,10 @@ jobs:
extra: "CMD_CXXFLAGS=-std=c++11"
name: "Ub-20 gcc-9 C++11, static"
- os: ubuntu-16.04
- os: ubuntu-20.04
cmp: clang
configuration: default
name: "Ub-16 clang-9"
name: "Ub-20 clang-10"
- os: ubuntu-20.04
cmp: clang
@@ -95,21 +97,24 @@ jobs:
test: NO
name: "Ub-20 gcc-9 + RT-5.1 beatnik"
- os: ubuntu-20.04
cmp: gcc
configuration: default
rtems: "5"
rtems_target: RTEMS-mvme3100
test: NO
name: "Ub-20 gcc-9 + RT-5.1 mvme3100"
- os: ubuntu-20.04
cmp: gcc
configuration: default
rtems: "5"
rtems_target: RTEMS-qoriq_e500
test: NO
name: "Ub-20 gcc-9 + RT-5.1 qoriq_e500"
# Only build one RTEMS target per CPU family
# unless it's running the tests
#
# - os: ubuntu-20.04
# cmp: gcc
# configuration: default
# rtems: "5"
# rtems_target: RTEMS-mvme3100
# test: NO
# name: "Ub-20 gcc-9 + RT-5.1 mvme3100"
#
# - os: ubuntu-20.04
# cmp: gcc
# configuration: default
# rtems: "5"
# rtems_target: RTEMS-qoriq_e500
# test: NO
# name: "Ub-20 gcc-9 + RT-5.1 qoriq_e500"
- os: ubuntu-20.04
cmp: gcc
@@ -133,6 +138,7 @@ jobs:
rtems: "4.10"
name: "Ub-20 gcc-9 + RT-4.10"
rtems_target: RTEMS-pc386-qemu
test: NO
- os: ubuntu-20.04
cmp: gcc
@@ -141,35 +147,6 @@ jobs:
name: "Ub-20 gcc-9 + RT-4.9"
rtems_target: RTEMS-pc386-qemu
- os: ubuntu-16.04
cmp: gcc-4.8
utoolchain: "4.8"
configuration: default
name: "Ub-16 gcc-4.8"
- os: ubuntu-16.04
cmp: gcc-4.9
utoolchain: "4.9"
configuration: default
name: "Ub-16 gcc-4.9"
- os: ubuntu-20.04
cmp: gcc-8
utoolchain: "8"
configuration: default
name: "Ub-20 gcc-8"
- os: ubuntu-20.04
cmp: gcc-9
utoolchain: "9"
configuration: default
name: "Ub-20 gcc-9"
- os: ubuntu-20.04
cmp: clang
configuration: default
name: "Ub-20 clang-10"
- os: macos-latest
cmp: clang
configuration: default
@@ -206,14 +183,86 @@ jobs:
sudo apt-get update
sudo apt-get -y install qemu-system-x86 g++-mingw-w64-x86-64 gdb
if: runner.os == 'Linux'
- name: "apt-get install ${{ matrix.cmp }}"
- name: Prepare and compile dependencies
run: python .ci/cue.py prepare
- name: Build main module
run: python .ci/cue.py build
- name: Run main module tests
run: python .ci/cue.py -T 60M test
- name: Upload tapfiles Artifact
if: ${{ always() }}
uses: actions/upload-artifact@v2
with:
name: tapfiles ${{ matrix.name }}
path: '**/O.*/*.tap'
if-no-files-found: ignore
- name: Collect and show test results
if: ${{ always() }}
run: python .ci/cue.py -T 5M test-results
docker:
name: ${{ matrix.name }}
runs-on: ubuntu-latest
container:
image: ${{ matrix.image }}
# Set environment variables from matrix parameters
env:
CMP: ${{ matrix.cmp }}
BCFG: ${{ matrix.configuration }}
EXTRA: ${{ matrix.extra }}
TEST: ${{ matrix.test }}
strategy:
fail-fast: false
matrix:
# Job names also name artifacts, character limitations apply
include:
- name: "CentOS-7"
image: centos:7
cmp: gcc
configuration: default
- name: "Fedora-33"
image: fedora:33
cmp: gcc
configuration: default
- name: "Fedora-latest"
image: fedora:latest
cmp: gcc
configuration: default
steps:
- name: "Build newer Git"
# actions/checkout@v2 wants git >=2.18
# centos:7 has 1.8
if: matrix.image=='centos:7'
run: |
sudo apt-get update
sudo apt-get -y install software-properties-common
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get -y install g++-${{ matrix.utoolchain }}
if: matrix.utoolchain
yum -y install curl make gcc curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker
curl https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.29.0.tar.gz | tar -xz
cd git-*
make -j2 prefix=/usr/local all
make prefix=/usr/local install
cd ..
rm -rf git-*
type -a git
git --version
- name: "Redhat setup"
run: |
dnfyum() {
dnf -y "$@" || yum -y "$@"
return $?
}
dnfyum install python3 gdb make perl gcc-c++ glibc-devel readline-devel ncurses-devel perl-devel perl-Test-Simple
git --version || dnfyum install git
# rather than just bite the bullet and link python3 -> python,
# people would rather just break all existing scripts...
[ -e /usr/bin/python ] || ln -sf python3 /usr/bin/python
python --version
- uses: actions/checkout@v2
with:
submodules: true
- name: Automatic core dumper analysis
uses: mdavidsaver/ci-core-dumper@master
- name: Prepare and compile dependencies
run: python .ci/cue.py prepare
- name: Build main module
@@ -226,6 +275,7 @@ jobs:
with:
name: tapfiles ${{ matrix.name }}
path: '**/O.*/*.tap'
if-no-files-found: ignore
- name: Collect and show test results
if: ${{ always() }}
run: python .ci/cue.py -T 5M test-results

50
.lgtm.yml Normal file
View File

@@ -0,0 +1,50 @@
# Configuration for lgtm.com
#
path_classifiers:
test:
- exclude: /
- test
- "modules/*/test*"
library:
- modules/libcom/src/yacc
- modules/libcom/src/flex
template:
- src/template
- modules/ca/src/template
- modules/database/src/template
extraction:
cpp:
prepare:
packages:
- "libreadline-dev"
index:
build_command:
- "g++ --version"
- "make --version"
- "perl --version"
- "make -sj2 || echo '*** Build failed, ignored for lgtm ***'"
python:
index:
include:
- src/tools
# Interpreted languages to be excluded
javascript:
index:
exclude:
- "*"
# Compiled languages to be excluded
java:
index:
build_command: "echo No Java code in this project"
csharp:
index:
build_command: "echo No C# code in this project"
go:
index:
build_command: "echo No Go code in this project"

View File

@@ -16,6 +16,10 @@ ifneq ($(wildcard $(TOP)/configure/CONFIG_BASE_VERSION),)
CONFIG = $(TOP)/configure
BASE_TOP=YES
else
ifneq ($(origin EPICS_BASE),file)
# Essential for the EPICS build system, see convertRelease.pl
$(error EPICS_BASE must be set in a configure/RELEASE file)
endif
CONFIG ?= $(EPICS_BASE)/configure
endif

View File

@@ -50,7 +50,6 @@ CODE_LDFLAGS += $(ASAN_LDFLAGS_$(ENABLE_ASAN))
PIPE_CFLAGS_YES_YES = -pipe
PIPE_CFLAGS = $(PIPE_CFLAGS_$(GCC_PIPE)_$(GNU))
PIPE_CXXFLAGS = $(PIPE_CFLAGS)
STATIC_LDFLAGS_YES = -static
STATIC_LDFLAGS_NO =

View File

@@ -31,10 +31,12 @@ endif # BASE_TOP
# Where to find the installed build tools
# Windows does not like commands with relative paths starting ../
# so TOOLS must be an absolute path, although Perl scripts are OK.
# FIND_TOOL is for scripts run before the build reaches src/tools.
# FIND_TOOL is for scripts run before the build reaches src/tools
# and must also work in submodules when EPICS_BASE is not built.
TOOLS = $(abspath $(EPICS_BASE_HOST_BIN))
FIND_TOOL = $(firstword $(wildcard $(TOOLS)/$(1) $(EPICS_BASE)/src/tools/$(1)))
FIND_TOOL = $(firstword $(wildcard $(TOOLS)/$(1) \
$(TOP)/src/tools/$(1)) $(EPICS_BASE)/src/tools/$(1))
#---------------------------------------------------------------
# EPICS Base build tools and tool flags

View File

@@ -48,11 +48,11 @@ EPICS_VERSION = 7
EPICS_REVISION = 0
# EPICS_MODIFICATION must be a number >=0 and <256
EPICS_MODIFICATION = 5
EPICS_MODIFICATION = 6
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
# Not included in the official EPICS version number if zero
EPICS_PATCH_LEVEL = 1
EPICS_PATCH_LEVEL = 2
# Immediately after an official release the EPICS_PATCH_LEVEL is incremented
# and the -DEV suffix is added (similar to the Maven -SNAPSHOT versions)

View File

@@ -1,8 +1,8 @@
# Version number for the Channel Access API and shared library
EPICS_CA_MAJOR_VERSION = 4
EPICS_CA_MINOR_VERSION = 13
EPICS_CA_MAINTENANCE_VERSION = 9
EPICS_CA_MINOR_VERSION = 14
EPICS_CA_MAINTENANCE_VERSION = 2
# Development flag, set to zero for release versions

View File

@@ -56,6 +56,7 @@ GNU_DIR = /usr
# Directories
INSTALL_LOCATION = $(TOP)
INSTALL_ABSOLUTE = $(abspath $(INSTALL_LOCATION))
INSTALL_LOCATION_LIB = $(INSTALL_LOCATION)/lib
INSTALL_LOCATION_BIN = $(INSTALL_LOCATION)/bin
@@ -71,13 +72,14 @@ INSTALL_DBD = $(INSTALL_LOCATION)/dbd
INSTALL_DB = $(INSTALL_LOCATION)/db
INSTALL_CONFIG = $(INSTALL_LOCATION)/configure
FINAL_LOCATION = $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION))
#-------------------------------------------------------
# These are default settings that may be overridden later
# Directory for OS independant build created files
COMMON_DIR = ../O.Common
# Eventual install path (to be compiled into binaries)
FINAL_LOCATION = $(INSTALL_ABSOLUTE)
# IOC's absolute path to $(TOP), may be overridden inside the application
IOCS_APPL_TOP = $(shell $(FULLPATHNAME) $(INSTALL_LOCATION))
# IOC's view of install path
IOCS_APPL_TOP = $(INSTALL_ABSOLUTE)
#-------------------------------------------------------
# Silencing the build - suppress messages during 'make -s'
@@ -133,6 +135,8 @@ LIB_SUFFIX =
SHRLIB_PREFIX = $(LIB_PREFIX)
DLLSTUB_PREFIX = $(LIB_PREFIX)
DLLSTUB_SUFFIX = $(LIB_SUFFIX)
LOADABLE_SHRLIB_PREFIX = $(SHRLIB_PREFIX)
LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX)
BUILDLIB_PREFIX_YES = $(DLLSTUB_PREFIX)
BUILDLIB_PREFIX_NO = $(LIB_PREFIX)
@@ -153,12 +157,14 @@ CMPLR_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \
ALL_SRC_DIRS = $(CMPLR_SRC_DIRS) $(OS_SRC_DIRS) $(GENERIC_SRC_DIRS)
#--------------------------------------------------
# Directory for OS independant build created files
COMMON_DIR = ../O.Common
# 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)))
INSTALL_INCLUDE_DIRS = $(INSTALL_INCLUDE)/compiler/$(CMPLR_CLASS) \
$(INSTALL_INCLUDE)/os/$(OS_CLASS) $(INSTALL_INCLUDE)
INSTALL_INCLUDES += $(addprefix -I, $(INSTALL_INCLUDE_DIRS))
SRC_INCLUDES = $(addprefix -I, $(COMMON_DIR) $(wildcard $(ALL_SRC_DIRS)))
#--------------------------------------------------
# Target filename definitions
@@ -172,23 +178,27 @@ TESTSHRLIBNAME = $(TESTSHRLIBNAME_$(SHARED_LIBRARIES))
#--------------------------------------------------
# obj files
TARGET_OBJS = $($*_LDOBJS) $(addsuffix $(OBJ),$(basename $($*_OBJS) $($*_SRCS)))
TARGET_OBJS = $($*_LDOBJS) $(addsuffix $(OBJ), \
$(basename $($*_OBJS) $($*_SRCS)))
PRODUCT_OBJS = $(addsuffix $(OBJ),$(basename $(SRCS) $(USR_SRCS) $(PROD_SRCS) $(USR_OBJS) $(PROD_OBJS)))
PRODUCT_OBJS = $(addsuffix $(OBJ), \
$(basename $(SRCS) $(USR_SRCS) $(PROD_SRCS) $(USR_OBJS) $(PROD_OBJS)))
PROD_LD_OBJS = $(TARGET_OBJS) $(PRODUCT_OBJS)
LIBRARY_OBJS = $(addsuffix $(OBJ),$(basename $(SRCS) $(USR_SRCS) $(LIB_SRCS) $(LIBSRCS) $(USR_OBJS) $(LIB_OBJS)))
LIBRARY_OBJS = $(addsuffix $(OBJ), \
$(basename $(SRCS) $(USR_SRCS) $(LIB_SRCS) $(LIBSRCS) $(USR_OBJS) $(LIB_OBJS)))
LIBRARY_LD_OBJS = $(TARGET_OBJS) $(LIBRARY_OBJS)
#--------------------------------------------------
# Windows resource files
TARGET_RESS = $(if $(RES),$(addsuffix $(RES),$(basename $($*_RCS))),)
TARGET_RESS = $(if $(RES), $(addsuffix $(RES), $(basename $($*_RCS))))
PROD_RESS = $(if $(RES),$(addsuffix $(RES),$(basename $(RCS) $(PROD_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_RESS = $(if $(RES), $(addsuffix $(RES), \
$(basename $(RCS) $(LIB_RCS) $(LIBRARY_RCS))))
LIBRARY_LD_RESS = $(TARGET_RESS) $(LIBRARY_RESS)
#--------------------------------------------------
@@ -260,20 +270,21 @@ OPT_CXXFLAGS = $(OPT_CXXFLAGS_$($(BUILD_CLASS)_OPT))
# Static build flags
STATIC_CFLAGS = $(STATIC_CFLAGS_$(STATIC_BUILD))
STATIC_CXXCFLAGS = $(STATIC_CXXFLAGS_$(STATIC_BUILD))
STATIC_CXXFLAGS = $(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)
# cflags for shared library src files
LIBRARY_SRCS = $(basename $(foreach lib, \
$(LIBRARY) $(TESTLIBRARY) $(LOADABLE_LIBRARY), \
$($(lib)_OBJSNAME) $(LIBRARY_OBJS)))
LIBRARY_SRC_CFLAGS = $(if $(findstring $*, $(LIBRARY_SRCS)), $(SHRLIB_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)
# ldflags for loadable and shared libraries
TARGET_LIB_LDFLAGS = $(if $(findstring $*, $(LOADABLE_LIBRARY)), \
$(LOADABLE_SHRLIB_LDFLAGS), $(SHRLIB_LDFLAGS))
#--------------------------------------------------
# Command-line input support default
@@ -285,31 +296,31 @@ 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)
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)
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)
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_CXXFLAGS) $(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)
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))
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) $(API_CPPFLAGS)
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) $(API_CPPFLAGS)
#--------------------------------------------------
# ar definition default
@@ -396,7 +407,7 @@ INSTALL_DOCS = $(DOCS:%= $(INSTALL_DOC)/%)
INSTALL_HTMLS = $(HTMLS:%= $(INSTALL_HTML)/$(HTMLS_DIR)/%)
INSTALL_TEMPLATE = $(addprefix $(INSTALL_TEMPLATES_SUBDIR)/, \
$(subst $(CONFIG),top/configure,$(TEMPLATES)))
$(subst $(CONFIG),top/configure,$(TEMPLATES)))
INSTALL_CONFIGS = $(CONFIGS:%= $(INSTALL_CONFIG)/%)
INSTALL_BIN_INSTALLS = $(addprefix $(INSTALL_BIN)/,$(notdir $(BIN_INSTALLS)))
@@ -431,42 +442,41 @@ INSTALL_INC += $(foreach inc, $(INC), \
$(CMPLR_INSTALL_INC) \
$(OS_INSTALL_INC) \
$(GENERIC_INSTALL_INC) \
$(GENERATED_INSTALL_INC) ) )
INSTALL_INC += $(addprefix $(INSTALL_INCLUDE)/os/$(OS_CLASS)/, $(INC_$(OS_CLASS)) )
$(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)) )
CMPLR_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/compiler/$(CMPLR_CLASS)/, \
$(foreach dir, $(CMPLR_SRC_DIRS), \
$(subst $(dir)/,, $(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)) )
OS_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/os/$(OS_CLASS)/, \
$(foreach dir, $(OS_SRC_DIRS), \
$(subst $(dir)/,, $(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)) )
GENERIC_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/, \
$(foreach dir, .. $(SRC_DIRS), \
$(subst $(dir)/,, $(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) )
#---------------------------------------------------------------
# Files listed in INC that must first be created in O.Common
COMMON_INC += $(filter $(COMMON_DIR)/%, \
$(foreach file, $(INC), \
$(firstword $(wildcard $(file) \
$(foreach dir, $(ALL_SRC_DIRS), \
$(addsuffix /$(file), $(dir)))) $(COMMON_DIR)/$(file))))
endif

View File

@@ -5,22 +5,16 @@
# in file LICENSE that is included with this distribution.
#*************************************************************************
# Set EPICS_DATABASE if necessary
ifndef EPICS_DATABASE
EPICS_DATABASE = $(if $(BUILDING_DATABASE),$(INSTALL_LOCATION),$(EPICS_BASE))
# Our locally-built tools
DBEXPAND = $(PERL) $(EPICS_BASE_HOST_BIN)/dbdExpand.pl
DBTORECORDTYPEH = $(PERL) $(EPICS_BASE_HOST_BIN)/dbdToRecordtypeH.pl
DBTOMENUH = $(PERL) $(EPICS_BASE_HOST_BIN)/dbdToMenuH.pl
DBDTOHTML = $(PERL) $(EPICS_BASE_HOST_BIN)/dbdToHtml.pl
REGISTERRECORDDEVICEDRIVER = $(PERL) $(EPICS_BASE_HOST_BIN)/registerRecordDeviceDriver.pl
# Paths to tools built here
EPICS_DATABASE_HOST_BIN = $(EPICS_DATABASE)/bin/$(EPICS_HOST_ARCH)
endif
# Set location of locally-built tools
MAKEBPT = $(EPICS_DATABASE_HOST_BIN)/makeBpt$(HOSTEXE)
DBEXPAND = $(PERL) $(EPICS_DATABASE_HOST_BIN)/dbdExpand.pl
DBTORECORDTYPEH = $(PERL) $(EPICS_DATABASE_HOST_BIN)/dbdToRecordtypeH.pl
DBTOMENUH = $(PERL) $(EPICS_DATABASE_HOST_BIN)/dbdToMenuH.pl
DBDTOHTML = $(PERL) $(EPICS_DATABASE_HOST_BIN)/dbdToHtml.pl
REGISTERRECORDDEVICEDRIVER = $(PERL) $(EPICS_DATABASE_HOST_BIN)/registerRecordDeviceDriver.pl
MSI3_15 = $(EPICS_DATABASE_HOST_BIN)/msi$(HOSTEXE)
# Windows can need these paths to be quoted
MAKEBPT = "$(EPICS_BASE_HOST_BIN)/makeBpt$(HOSTEXE)"
MSI3_15 = "$(EPICS_BASE_HOST_BIN)/msi$(HOSTEXE)"
# Libraries needed to link a basic IOC
EPICS_BASE_IOC_LIBS = dbRecStd dbCore ca Com

View File

@@ -1,7 +1,7 @@
# Version number for the database APIs and shared library
EPICS_DATABASE_MAJOR_VERSION = 3
EPICS_DATABASE_MINOR_VERSION = 19
EPICS_DATABASE_MINOR_VERSION = 21
EPICS_DATABASE_MAINTENANCE_VERSION = 1
# Development flag, set to zero for release versions

View File

@@ -5,9 +5,10 @@
# in file LICENSE that is included with this distribution.
#*************************************************************************
# Set location of locally generated tools
YACC = $(abspath $(EPICS_BASE)/bin/$(EPICS_HOST_ARCH))/antelope$(HOSTEXE)
LEX = $(abspath $(EPICS_BASE)/bin/$(EPICS_HOST_ARCH))/e_flex$(HOSTEXE) \
# Our locally-built tools
# Windows can need these paths to be quoted
YACC = "$(EPICS_BASE_HOST_BIN)/antelope$(HOSTEXE)"
LEX = "$(EPICS_BASE_HOST_BIN)/e_flex$(HOSTEXE)" \
-S$(EPICS_BASE)/include/flex.skel.static
# Default stack size for osiThread

View File

@@ -1,7 +1,7 @@
# Version number for the libcom APIs and shared library
EPICS_LIBCOM_MAJOR_VERSION = 3
EPICS_LIBCOM_MINOR_VERSION = 19
EPICS_LIBCOM_MINOR_VERSION = 21
EPICS_LIBCOM_MAINTENANCE_VERSION = 1
# Development flag, set to zero for release versions

View File

@@ -366,6 +366,7 @@ $(COMMON_DIR)/menu%.h: ../menu%.dbd
# DBD files
$(COMMON_DIR)/bpt%.dbd: bpt%.data
$(ECHO) "Converting data from $<"
@$(RM) $(notdir $@)
$(MAKEBPT) $< $(notdir $@)
@$(MV) $(notdir $@) $@
@@ -455,7 +456,7 @@ $(COMMON_DIR)/%.html: ../%.pl
$(PODTOHTML) -s -o $(notdir $@) $<
@$(MV) $(notdir $@) $@
.PRECIOUS: $(COMMON_DIR)/%.html %.html
.PRECIOUS: $(COMMON_DIR)/%.html
#---------------------------------------------------------------
# DB files

View File

@@ -207,7 +207,7 @@ endif
checkRelease:
+$(CONVERTRELEASE) checkRelease
warnRelease:
$(CONVERTRELEASE) checkRelease
-$(CONVERTRELEASE) checkRelease
noCheckRelease:
ifeq ($(EPICS_HOST_ARCH),$(T_A))
$(info Warning: RELEASE file consistency checks have been disabled)
@@ -383,6 +383,8 @@ endif
tapfiles: $(TAPFILES)
junitfiles: $(JUNITFILES)
# prevent deletion of partial output from failing tests
.PRECIOUS: $(TAPFILES) $(JUNITFILES)
test-results: tap-results
tap-results: $(TAPFILES)
@@ -561,6 +563,10 @@ $(INSTALL_DOC)/%: ../%
$(ECHO) "Installing doc $@"
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(INSTALL_DOC)
$(INSTALL_HTML)/$(HTMLS_DIR)/%: $(COMMON_DIR)/%
$(ECHO) "Installing generated html $@"
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
$(INSTALL_HTML)/$(HTMLS_DIR)/%: %
$(ECHO) "Installing html $@"
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
@@ -569,10 +575,6 @@ $(INSTALL_HTML)/$(HTMLS_DIR)/%: ../%
$(ECHO) "Installing html $@"
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
$(INSTALL_HTML)/$(HTMLS_DIR)/%: $(COMMON_DIR)/%
$(ECHO) "Installing generated html $@"
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
$(INSTALL_TEMPLATES_SUBDIR)/%: ../%
$(ECHO) "Installing $@"
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)

View File

@@ -70,12 +70,12 @@ $(EXPANDED_COM): %: %@
@$(RM) $@
$(EXPAND_TOOL) $(EXPANDFLAGS) $($@_EXPANDFLAGS) $< $@
$(EXPANDED_COMMON): $(COMMON_DIR)/%: %
@$(MV) $< $@
@$(CP) $< $@
clean: expand_clean
expand_clean:
@$(RM) $(EXPANDED) $(EXPANDED_COMMON)
@$(RM) $(EXPANDED) $(EXPANDED_COMMON) $(EXPANDED_COM)
.PRECIOUS: $(EXPANDED) $(EXPANDED_COMMON)
.PHONY: expand_clean

View File

@@ -28,7 +28,6 @@ DIRS += $(LIVE_SUBMODULES)
include $(CONFIG)/RULES_DIRS
INSTALL_LOCATION_ABS := $(abspath $(INSTALL_LOCATION))
RELEASE_LOCAL := RELEASE.$(EPICS_HOST_ARCH).local
# Ensure that RELEASE.<host>.local exists before doing anything else
@@ -40,8 +39,8 @@ RELEASE.host: $(RELEASE_LOCAL)
$(RELEASE_LOCAL): Makefile CONFIG_SITE.local
$(ECHO) Creating $@ with
$(ECHO) " $(PARENT_MODULE) = $(INSTALL_LOCATION_ABS)"
@echo $(PARENT_MODULE) = $(INSTALL_LOCATION_ABS)> $@
$(ECHO) " $(PARENT_MODULE) = $(INSTALL_ABSOLUTE)"
@echo $(PARENT_MODULE) = $(INSTALL_ABSOLUTE)> $@
realclean:
$(RM) $(wildcard RELEASE.*.local)

View File

@@ -63,7 +63,7 @@ CFLAGS = $($(BUILD_CLASS)_CFLAGS) $(POSIX_CFLAGS) $(OPT_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)
$(STATIC_CXXFLAGS) $(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)\
@@ -79,6 +79,9 @@ CPPFLAGS += $($(BUILD_CLASS)_CPPFLAGS) $(POSIX_CPPFLAGS) $(OPT_CPPFLAGS)\
ECHO = @$(if $(filter -s,$(MFLAGS)),$(NOP),echo)
# Originally set in os/CONFIG.UnixCommon.Common
MKDIR = mkdir -p
#--------------------------------------------------
# Although RTEMS uses gcc, it wants to use gcc its own way
CROSS_CPPFLAGS =

View File

@@ -19,6 +19,7 @@ define MUNCH_CMD
$(PROJECT_RELEASE)/lib/bootloader.o \
--just-symbols=$< \
-b binary rtems.gz \
--no-warn-mismatch \
-T $(PROJECT_RELEASE)/lib/ppcboot.lds \
-Map $<.map
rm -f rtems.gz

View File

@@ -1,7 +1,7 @@
#
# Author: Matt Rippa
#
RTEMS_BSP = mvme2700
RTEMS_BSP = mvme2307
RTEMS_TARGET_CPU = powerpc
ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL
ARCH_DEP_CFLAGS += -DHAVE_PPCBUG
@@ -15,6 +15,7 @@ define MUNCH_CMD
$(PROJECT_RELEASE)/lib/bootloader.o \
--just-symbols=$< \
-b binary rtems.gz \
--no-warn-mismatch \
-T $(PROJECT_RELEASE)/lib/ppcboot.lds \
-Map $<.map
rm -f rtems.gz

View File

@@ -56,7 +56,7 @@ SHRLIB_LDLIBS = $(addprefix -l, $($*_LDLIBS) $(LIB_LIBS) $(USR_LIBS)) \
SHRLIB_DEPLIB_DIRS = $(foreach word, \
$(sort $(INSTALL_LIB)/ $(dir $($*_DEPLIBS) $(SHRLIB_DEPLIBS))), \
$(shell $(FULLPATHNAME) $(word)))
$(abspath $(word)))
SHRLIBDIR_LDFLAGS += $(SHRLIB_DEPLIB_DIRS:%=-L%)
@@ -85,7 +85,7 @@ PROD_LDLIBS += $($(firstword $(LDLIBS_STATIC_$(STATIC_BUILD)) \
PROD_DEPLIB_DIRS = $(foreach word, \
$(sort $(INSTALL_LIB)/ $(dir $($*_DEPLIBS) $(PROD_DEPLIBS))), \
$(shell $(FULLPATHNAME) $(word)))
$(abspath $(word)))
PRODDIR_LDFLAGS += $(PROD_DEPLIB_DIRS:%=-L%)

View File

@@ -77,7 +77,7 @@ 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))/$@ \
-install_name $(abspath $(INSTALL_LIB))/$@ \
-compatibility_version $(EPICS_VERSION).$(EPICS_REVISION) \
-current_version $(SHRLIB_VERSION)
SHRLIB_SUFFIX_BASE = .dylib

View File

@@ -0,0 +1,21 @@
# CONFIG.Common.vxWorks-e500v2
#
# Definitions for vxWorks-e500v2 target archs (MVME2500)
# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-e500v2
#-------------------------------------------------------
# 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_CFLAGS += -te500v2 -mhard-float
ARCH_DEP_CPPFLAGS += -DCPU=PPC85XX
ARCH_DEP_CFLAGS += -DCPU_VARIANT=_ppc85XX_e500v2
ARCH_DEP_CFLAGS += -mlongcall
GNU_TARGET = powerpc-wrs-vxworks

View File

@@ -67,7 +67,7 @@ GNU = NO
# Darwin shared libraries
#
SHRLIB_LDFLAGS = -dynamiclib -flat_namespace -undefined dynamic_lookup \
-install_name $(shell $(FULLPATHNAME) $(INSTALL_LIB))/$@ \
-install_name $(abspath $(INSTALL_LIB))/$@ \
$(addprefix -compatibility_version , $(SHRLIB_VERSION)) \
$(addprefix -current_version , $(SHRLIB_VERSION))
SHRLIB_SUFFIX_BASE = .dylib

View File

@@ -34,5 +34,6 @@
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
# overridden in this file for native builds, e.g. variables such as
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
# They must be set in CONFIG_SITE.linux-aarch64.linux-aarch64 instead.
# They must be set in CONFIG_SITE.linux-aarch64.linux-aarch64 or for
# cross-builds in CONFIG_SITE.<host-arch>.linux-aarch64 instead.

View File

@@ -1,6 +1,6 @@
# CONFIG_SITE.linux-x86.linux-aarch64
# CONFIG_SITE.linux-x86_64.linux-aarch64
#
# Site specific definitions for linux-x86 host - linux-aarch64 target builds
# Site specific definitions for linux-x86_64 host - linux-aarch64 target builds
#-------------------------------------------------------
# Set GNU crosscompiler target name

View File

@@ -2300,7 +2300,7 @@ PLANTUML_JAR_PATH =
# Minimum value: 0, maximum value: 10000, default value: 50.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_GRAPH_MAX_NODES = 50
DOT_GRAPH_MAX_NODES = 100
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
# generated by dot. A depth value of 3 means that only nodes reachable from the

View File

@@ -1,184 +0,0 @@
<html>
<head>
<title>Installation notes for EPICS on Mac OS X (Darwin)</title>
</head>
<body>
<h1>Building EPICS base</h1>
<ul>
<li>
To build base:
<ol>
<li>
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):
<pre>
#
# EPICS
#
EPICS_BASE="${HOME}/src/EPICS/base"
EPICS_EXTENSIONS="${HOME}/src/EPICS/extensions"
<strong>.</strong> "${EPICS_BASE}"/startup/unix.sh
</pre>
</li>
<li>
<code>cd</code> to the EPICS base top-level source directory.
</li>
<li>
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.
</li>
<li>
Run <code>make</code>.
</li>
</ol>
</li>
<li>
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.
<p>
Information on DarwinPorts is available from
<a href="http://www.opendarwin.org/projects/darwinports/">the DarwinPorts
project page</a>.
DarwinPorts binary packages are available from
<a href="http://packages.opendarwin.org/">here</a>.
<p>
Fink may be downloaded from
<a href="http://fink.sourceforge.net/">the Source Forge</a>.
</li>
<li>
If broadcasts are not seen locally, try adding "localhost" (127.0.0.1)
to the EPICS_CA_ADDR_LIST.
</li>
</ul>
<h1>Building EPICS extensions</h1>
<p>
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.
<h1>Objective-C and AppleScript</h1>
<p>
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.
<pre>
/*
* 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 &lt;Foundation/Foundation.h&gt;
#include &lt;registryFunction.h&gt;
#include &lt;subRecord.h&gt;
#include &lt;alarm.h&gt;
#include &lt;errlog.h&gt;
#include &lt;recGbl.h&gt;
#include &lt;epicsExport.h&gt;
/*
* 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-&gt;a]];
if ([nsa executeAndReturnError:&amp;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 &lt;Foundation/Foundation.h&gt;
#include &lt;errlog.h&gt;
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:&amp;err] == nil) {
errlogPrintf("Failed to run AppleScript: %s\n",
[[err objectForKey:NSAppleScriptErrorMessage] cString]);
ret = -1;
}
[script release];
[nsa release];
[pool release];
return ret;
}
</pre>
</body>
</html>

View File

@@ -1,27 +1,28 @@
# Installation Instructions {#install}
## EPICS Base Release 7.0.5
## EPICS Base Release 7.0.x
-----
### Table of Contents
- [What is EPICS base?](#0_0_1)
- [What is new in this release?](#0_0_2)
- [Copyright](#0_0_3)
- [Supported platforms](#0_0_4)
- [Supported compilers](#0_0_5)
- [Software requirements](#0_0_6)
- [Documentation](#0_0_8)
- [Directory Structure](#0_0_10)
- [Build related components](#0_0_11)
- [Building EPICS base (Unix and Win32)](#0_0_12)
- [Example application and extension](#0_0_13)
- [Multiple host platforms](#0_0_14)
- [What is EPICS base?](#what-is-epics-base?)
- [What is new in this release?](#what-is-new-in-this-release?)
- [Copyright](#copyright)
- [Supported platforms](#supported-platforms)
- [Supported compilers](#supported-compilers)
- [Software requirements](#software-requirements)
- [Host system storage requirements](#host-system-storage-requirements)
- [Documentation](#documentation)
- [Directory Structure](#directory-structure)
- [Site-specific build configuration](#site-specific-build-configuration)
- [Building EPICS base](#building-epics-base)
- [Example application and extension](#example-application-and-extension)
- [Multiple host platforms](#multiple-host-platforms)
-----
### <span id="0_0_1">What is EPICS base?</span>
### What is EPICS base?
The Experimental Physics and Industrial Control Systems (EPICS) is an
extensible set of software components and tools with which application
@@ -33,17 +34,17 @@ function. EPICS base allows an arbitrary number of target systems,
IOCs (input/output controllers), and host systems, OPIs (operator
interfaces) of various types.
### <span id="0_0_2">What is new in this release?</span>
### What is new in this release?
Please check the `RELEASE_NOTES` file in the distribution for
Please check the `documentation/RELEASE_NOTES.md` file for
description of changes and release migration details.
### <span id="0_0_3">Copyright Licenses</span>
### Copyright
Please review the LICENSE file included in the distribution for legal
terms of usage.
Please review the `LICENSE` file included in the distribution for
legal terms of usage.
### <span id="0_0_4">Supported platforms</span>
### 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
@@ -54,7 +55,7 @@ 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.
### <span id="0_0_5">Supported compilers</span>
### 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++
@@ -63,27 +64,33 @@ 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.
### <span id="0_0_6">Software requirements</span>
### Software requirements
**GNU make**
You must use GNU make, gnumake, for any EPICS builds. Set your path so
that a gnumake version 4.1 or later is available.
#### GNU make
**Perl**
You must have Perl version 5.10 or later installed. The EPICS
You must use the GNU version of `make` for EPICS builds. Set your path
so that version 4.1 or later is available. The macOS version of `make`
is older but does still work.
#### Perl
You must have Perl version 5.10.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)**
#### Unzip and tar (Winzip on WIN32 systems)
You must have tools available to unzip and untar the EPICS base
distribution file.
**Target systems**
#### 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**
#### vxWorks
You must have vxWorks 6.8 or later installed if any of your target
systems are vxWorks systems; the C++ compiler from older versions cannot
compile recently developed code. The vxWorks installation provides the
@@ -96,127 +103,146 @@ Consult the [vxWorks 6.x](https://epics.anl.gov/base/vxWorks6.php) EPICS
web pages about and the vxWorks documentation for information about
configuring your vxWorks operating system for use with EPICS.
**RTEMS**
#### RTEMS
For RTEMS targets, you need RTEMS core and toolset version 4.9.x or
4.10.x (4.11 or 5.x are not yet supported).
4.10.x. RTEMS 5 is experimental in EPICS 7.0.6.
**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.
#### Command Line Editing
### <span id="0_0_8">Documentation</span>
GNU readline and other similar libraries can be used by the IOC shell
to provide command line editing and command line history recall. The
GNU readline development package (or Apple's emulator on macOS) must
be installed for a target when its build configuration variable
`COMMANDLINE_LIBRARY` is set to `READLINE`. The default specified in
`CONFIG_COMMON` is `EPICS`, but most linux target builds can detect if
readline is available and will then use it. RTEMS targets may be
configured to use `LIBTECLA` if available, and on vxWorks the OS's
ledLib line-editing library is normally used.
EPICS documentation is available through the [EPICS
website](https://epics.anl.gov/) at Argonne.
### Host system storage requirements
The compressed tar file is approximately 3 MB in size. The
distribution source tree takes up approximately 21 MB. A 64-bit host
architecture may need around 610 MB to compile, while cross-compiled
targets are somewhat smaller.
### Documentation
EPICS documentation is available through the [EPICS website](https://epics.anl.gov/) at Argonne.
Release specific documentation can also be found in the
base/documentation directory of the distribution.
`base/documentation` directory of the distribution.
### <span id="0_0_10">Directory Structure</span>
### Directory Structure
#### 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
base Root directory of the distribution
base/configure Build rules and OS-independent config files
base/configure/os OS-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:
#### Directories created by the build
These are created in the root directory of the installation (`base`
above) or under the directory pointed to by the `INSTALL_LOCATION`
configuration variable if that has been set.
```
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
bin Installed scripts and executables in subdirs
cfg Installed build configuration files
db Installed database files
dbd Installed database definition 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
```
### <span id="0_0_11">Build related components</span>
#### `base/documentation` Directory
#### base/documentation directory - contains setup, build, and install documents
This contains documents on how to setup, build, and install EPICS.
```
README.md Instructions for setup and building epics base
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
README.md This file
RELEASE_NOTES.md Notes on release changes
KnownProblems.html List of known problems and workarounds
```
#### base/startup directory - contains scripts to set environment and path
#### `base/startup` Directory
This contains several example scripts that show how to set up the
build environment and PATH for using EPICS. Sites would usually copy and/or modify these files as appropriate for their environment; they are not used by the build system at all.
```
EpicsHostArch Shell script to set EPICS_HOST_ARCH env variable
unix.csh C shell script to set path and env variables
unix.sh Bourne shell script to set path and env variables
win32.bat Bat file example to configure win32-x86 target
windows.bat Bat file example to configure windows-x64 target
EpicsHostArch Shell script to set EPICS_HOST_ARCH env variable
unix.csh C shell script to set path and env variables
unix.sh Bourne shell script to set path and env variables
win32.bat Bat file example to configure win32-x86 target
windows.bat Bat file example to configure windows-x64 target
```
#### base/configure directory - contains build definitions and rules
#### `base/configure` directory
This contains build-system files providing definitions and rules
required by GNU Make to build EPICS. Users should only need to modify the `CONFIG_SITE` files to configure the EPICS build.
```
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
CONFIG Main entry point for building EPICS
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 only
Sample.Makefile Sample makefile with comments
```
#### base/configure/os directory - contains os-arch specific definitions
#### `base/configure/os` Directory
Files in here provide definitions that are shared by or specific to particular host and/or target architectures. Users should only need to modify the `CONFIG_SITE` files in this directory to configure the EPICS build.
```
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
CONFIG.<host>.<target> Definitions for a specific host-target combination
CONFIG.Common.<target> Definitions for a specific target, any host
CONFIG.<host>.Common Definitions for a specific host, any target
CONFIG.UnixCommon.Common Definitions for Unix hosts, any target
CONFIG.Common.UnixCommon Definitions for Unix targets, any host
CONFIG.Common.RTEMS Definitions for all RTEMS targets, any host
CONFIG.Common.vxWorksCommon Definitions for all vxWorks targets, any host
CONFIG_SITE.<host>.<target> Local settings for a specific host-target combination
CONFIG_SITE.Common.<target> Local settings for a specific target, any host
CONFIG_SITE.<host>.Common Local settings for a specific host, any target
CONFIG_SITE.Common.RTEMS Local settings for all RTEMS targets, any host
CONFIG_SITE.Common.vxWorksCommon Local settings for all vxWorks targets, any host
```
### <span id="0_0_12">Building EPICS base (Unix and Win32)</span>
### Building EPICS base
#### Unpack file
@@ -228,74 +254,79 @@ systems.
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 this EPICS base, 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. linux-x86_64. 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
Windows). See `configure/CONFIG_SITE` for a list of supported
`EPICS_HOST_ARCH` values.
* **`EPICS_HOST_ARCH`**
* `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.
Some host builds of EPICS require that the environment variable
`EPICS_HOST_ARCH` be defined. The perl script `EpicsHostArch.pl` in the
`base/startup` directory prints the value which the build will use if
the variable is not set before the build starts. Architecture names
start with the operating system followed by a dash and the host CPU
architecture, e.g. `linux-x86_64`. Some architecture names have another
dash followed by another keyword, for example when building for Windows
but using the MinGW compiler the name must be `windows-x64-mingw`. See
`configure/CONFIG_SITE` for a list of supported host architecture names.
* `LD_LIBRARY_PATH`
EPICS 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.
* **`PATH`**
As already mentioned, you must have the `perl` executable and you may
need C and C++ compilers in your search path. When building base you
must have `echo` in your search path. For Unix host builds you will
also need `cp`, `rm`, `mv`, and `mkdir` in your search path. Some Unix
systems may also need `ar` and `ranlib`, and the C/C++ compilers may
require `as` and `ld` in your path. On Solaris systems you need
`uname` in your path.
#### Do site-specific build configuration
* **`LD_LIBRARY_PATH`**
EPICS shared libraries and executables normally contain the full path
to any libraries they require, so setting this variable is not usually
necessary. However, if you move the EPICS installation to a new
location after building it then in order for the shared libraries to
be found at runtime it may need to be set, 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.
**Site configuration**
To configure EPICS, you may want to modify the default definitions
in the following files:
### Site-specific build configuration
#### Site configuration
To configure EPICS, you may want to modify some values set in the
following files:
>>>>>>> mirror/3.15
```
configure/CONFIG_SITE Build choices. Specify target archs.
configure/CONFIG_SITE_ENV Environment variable defaults
configure/RELEASE TORNADO2 full path location
configure/CONFIG_SITE Build settings. Specify target archs.
configure/CONFIG_SITE_ENV Environment variable defaults
```
**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`.
#### Host configuration
To configure each host system, you can override the default
definitions by adding a new settings file (or editing an existing
settings file) in the `configure/os` directory with your override
definitions. The settings file has the same name as the definitions
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
configure/os/CONFIG.<host>.<host> Host self-build definitions
configure/os/CONFIG.<host>.Common Host common build definitions
configure/os/CONFIG_SITE.<host>.<host> Host self-build overrides
configure/os/CONFIG_SITE.<host>.Common Host common build overrides
```
**Target configuration**
#### 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.
definitions by adding a new settings file (or editing an existing
settings file) in the `configure/os` directory with your override
definitions. The settings file has the same name as the definitions
file to be overridden except with `CONFIG` in the name changed to
`CONFIG_SITE`.
```
configure/os/CONFIG.Common.<target> Target common settings
configure/os/CONFIG.<host>.<target> Host-target settings
configure/os/CONFIG.Common.<target> Target common definitions
configure/os/CONFIG.<host>.<target> Host-target definitions
configure/os/CONFIG_SITE.Common.<target> Target common overrides
configure/os/CONFIG_SITE.<host>.<target> Host-target overrides
```
#### Build EPICS base
@@ -305,24 +336,29 @@ by issuing the following commands in the distribution's root
directory (base):
```
gnumake clean uninstall
gnumake
make distclean
make
```
The command "gnumake clean uninstall" will remove all files and
directories generated by a previous build. The command "gnumake"
The command `make distclean` will remove all files and
directories generated by a previous build. The command `make`
will build and install everything for the configured host and
targets.
It is recommended that you do a "gnumake clean uninstall" at the
It is recommended that you do a `make distclean` at the
root directory of an EPICS directory structure before each complete
rebuild to ensure that all components will be rebuilt.
### <span id="0_0_13">Example application and extension</span>
In some cases GNU Make may have been installed as `gmake` or
`gnumake`, in which case the above commands will have to be adjusted
to match.
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.
### Example application and extension
A perl tool `makeBaseApp.pl` and several template applications are
included in the distribution. This script instantiates the selected
template into an empty directory to provide an example application
that can be built and then executed to try out this release of base.
Instructions for building and executing the EPICS example application
can be found in the section "Example Application" of Chapter 2,
@@ -335,26 +371,30 @@ 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.
Another perl script `makeBaseExt.pl` is also included in the
distribution file for creating an extensions tree and sample
application that can also be built and executed. Both these scripts
are installed into the install location `bin/<hostarch>` directory
during the base build.
### <span id="0_0_14">Multiple host platforms</span>
### 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
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`. Intermediate object files
are stored in `O.<arch>` source subdirectories during the build
process, to allow 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.

View File

@@ -2,18 +2,17 @@
These release notes describe changes that have been made since the previous
release of this series of EPICS Base. **Note that changes which were merged up
from commits to new releases in an older Base series are not described at the
top of this file but have entries that appear lower down, under the series to
which they were originally committed.** Thus it is important to read more than
just the first section to understand everything that has changed in each
release.
from commits to the 3.15 branch are not described at the top of this file but
lower down, under the 3.15 release to which they were originally committed.**
Thus it is important to read more than just the first section to understand
everything that has changed in each release.
The PVA submodules each have their own individual sets of release notes which
should also be read to understand what has changed since earlier releases.
**This version of EPICS has not been released yet.**
## Changes made on the 7.0 branch since 7.0.5
## Changes made on the 7.0 branch since 7.0.6.1
<!-- Insert new items immediately below here ... -->
@@ -24,6 +23,159 @@ SIMM=RAW support has been added for the relevant output record types
RAW simulation mode will have those records do the appropriate conversion
and write RVAL to the location pointed to by SIOL.
### Fix `CHECK_RELEASE = WARN`
This now works again, it was broken in 2019 (7.0.3.1) by an errant commit.
### Document `DISP` as design-time field
The DISP field can be set to a non-zero value to prevent records being changed
from outside the IOC (this is ancient behavior), but has never been documented
as being usable at design-time (DCT=Yes in the Record Reference tables). This
has now been changed.
### Make `epicsInt8` signed on all architectures
The `epicsInt8` and thus `DBF_CHAR` types have always been unsigned on
architectures where `char` is unsigned, for example on many PowerPC CPU
architectures. This was counter-intuitive, and resulted in IOC behavior
differing between architectures when converting `DBF_CHAR` values into a
signed integer or floating point type.
**WARNING**: This fix may change behavior of existing databases on target
architectures with unsigned `char` (mainly PowerPC) when using input links to
read from `CHAR` arrays. Architectures with signed `char` (usually x86) should
be unaffected, although some compilers might generate new warnings.
### Allow hexadecimal and octal numbers in hardware links
[GH:213](https://github.com/epics-base/epics-base/pull/213)
Several types of hardware links (`VME_IO`, `CAMAC_IO`, etc) now accept
hexadecimal and octal numbers. (Hexadecimal numbers had already been valid
up to EPICS R3.15.) This change may introduce incompatibilities when using
numbers with leading `0` as they will now be parsed as octal.
### Fix embedded implementations of `epicsEvent`
[GH:202](https://github.com/epics-base/epics-base/issues/202) and
[GH:206](https://github.com/epics-base/epics-base/pull/206)
Heinz Junkes provided a new implementation of the `epicsEvent` API suitable for
RTEMS Posix targets (RTEMS 5.1 and later). In review a few issues related to
overflow of timeout values surfaced in this and other embedded implementations,
and these were also been fixed in this Pull Request. The API documentation for
this and some other routines has also been updated.
### Breakpoint Table Names
The names of breakpoint tables were made unnecessarily strict when DBD file
processing was moved to Perl for the 3.15 release series. Table names may now
contain the special characters `_` `-` `:` `;` `.` `[` `]` `<` `>` in addition
to letters and digits.
### Fix for `undefined` in configure/RELEASE files
Prevents `Use of uninitialized value` warnings from convertRelease.pl.
### Colorized Messages for errlog
Many internal error messages now emit ANSI escape sequences to highlight the
words "ERROR" and "WARNING" in an attempt to make occurrences more noticeable
during IOC startup.
The macros `ERL_ERROR` and `ERL_WARNING` are defined for external usage,
and expand as string constants. eg.
```c
#include <errlog.h>
#ifndef ERL_ERROR
# define ERL_ERROR "ERROR"
#endif
void fn() {
...
errlogPrintf(ERL_ERROR ": something bad happens :(\n");
```
ANSI escapes are automatically removed from errlog output not destined
for a terminal. For example, for logClient, if stderr is redirected,
or if unsupported (`$TERM` not set, or Windows < 10).
### `dbnd` filter pass through `DBE_ALARM|DBE_PROPERTY`
The `dbnd` server side filter now passes through alarm and property
change events, even when not exceeding the deadband.
-----
## EPICS Release 7.0.6.1
### `mbboDirectRecord` enhancements
The bit fields `B0` - `B1F` of this record are now always updated and have a
monitor posted when the `VAL` field is set and the record processed. It is now
possible to initialize the record's value by setting the bit fields inside a
database file as long as no other method was used to initialize it (suc as
setting `VAL` directly, using `DOL`, or by an initial readback from device
support). A new internal field `OBIT` was added to store information about
monitors posted on the bit fields.
### Minimum Perl Version is now 5.10.1
Some scripts now make use of features that were introduced to this Perl version
that was released in 2009.
### DB Links to `DBF_MENU` fields fixed
[GH:183](https://github.com/epics-base/epics-base/issues/183)
These were broken in a previous release, but now work again.
### Long String access to CALC fields fixed
[GH:194](https://github.com/epics-base/epics-base/issues/194)
This was broken in a previous release, but now works again.
### Minor Changes
+ Many code comments have been spell-checked and corrected.
+ Passing a `-DDEBUG` compiler flag no longer breaks the build.
+ Parallel builds of RTEMS-mvme2100 and RTEMS-mvme2700 targets now work.
+ Illegal characters seen in JSON strings in a database file should now get a
better error message.
### Other Launchpad Bugs and GitHub Issues Fixed
+ [lp:1938459](https://bugs.launchpad.net/epics-base/+bug/1938459)
[GH:191](https://github.com/epics-base/epics-base/pull/191) int64in only
checks lower 32 bits for change
+ [lp:1941875](https://bugs.launchpad.net/epics-base/+bug/1941875) Buggy
warning message "Record/Alias name '...' should not contain non-printable ...
+ [GH:187](https://github.com/epics-base/epics-base/issues/187) waveformRecord
missing PACT=true?
+ [GH:189](https://github.com/epics-base/epics-base/pull/189) Fix a couple
memory leaks and a segfault
+ [GH:200](https://github.com/epics-base/epics-base/pull/200) and
[GH:201](https://github.com/epics-base/epics-base/pull/201) Fix timers on MS
Windows for non-EPICS threads
### Compiler interface for epicsAtomic tidied up
[GH:192](https://github.com/epics-base/epics-base/pull/192)
Both GCC and CLANG compiler intrisics used for the epicsAtomic APIs have been revised; implementations using CLANG should now run faster as they now use the compiler's built-in atomic functions instead of taking a mutex.
### The epicsTime code has been reimplemented
[GH:185](https://github.com/epics-base/epics-base/pull/185)
This was done to simplify the code and may have improved performance slightly for some uses. Support for the old NTP-specific `struct l_fp` has been dropped but all other routines and methods of the `class epicsTime` function as before.
### Updates to Record Reference documentation
Many of the built-in record types have had improvements to their documentation with additional fields added to the tables, rewrites of descriptions and links to other documents added or fixed.
-----
## EPICS Release 7.0.6
### Support for obsolete architectures removed
These target architectures have been removed:
@@ -49,7 +201,7 @@ running on RTEMS 5:
- RTEMS-beagleboneblack
- RTEMS-pc686
- RTEMS-qoriq_e500 (MVME2500)
- RTEMS-xilinx-zynq-a9_qemu
- RTEMS-xilinx_zynq_a9_qemu
- RTEMS-xilinx_zynq_zedboard
The EPICS support for RTEMS 4 has always relied on RTEMS-specific
@@ -222,7 +374,7 @@ that the variables referenced by output pointers are initialized.
```c
#ifndef HAS_ALARM_MESSAGE
# recGblSetSevrMsg(REC, STAT, SEVR, ...) recGblSetSevr(REC, STAT, SEVR)
# define recGblSetSevrMsg(REC, STAT, SEVR, ...) recGblSetSevr(REC, STAT, SEVR)
#endif
#ifndef dbGetAlarmMsg
# define dbGetAlarmMsg(LINK, STAT, SEVR, BUF, BUFLEN) dbGetAlarm(LINK, STAT, SEVR)
@@ -1930,24 +2082,53 @@ header and removed the need for dbScan.c to reach into the internals of its
# Changes incorporated from the 3.15 branch
## Changes made on the 3.15 branch since 3.15.8
## Changes from the 3.15 branch since 3.15.9
### Fix timers on MS Windows for non-EPICS threads
The waitable timer changes in 3.15.9 broke calls to `epicsThreadSleep()` and
similar routines that used timers (including `ca_pend_event()`) when made from
threads that were not started using the epicsThread APIs.
[This problem](https://github.com/epics-base/epics-base/pull/200)
[has now been fixed](https://github.com/epics-base/epics-base/pull/201).
## Changes made between 3.15.8 and 3.15.9
### Use waitable timers on Microsoft Windows
The `epicsEventWaitWithTimeout` and `epicsThreadSleep` functions have
The `epicsEventWaitWithTimeout()` and `epicsThreadSleep()` functions have
been changed to use waitable timers. On Windows 10 version 1803 or higher
they will use high resolution timers for more consistent timing.
See https://groups.google.com/a/chromium.org/g/scheduler-dev/c/0GlSPYreJeY
See [this Google Groups thread](https://groups.google.com/a/chromium.org/g/scheduler-dev/c/0GlSPYreJeY)
for a comparison of the performance of different timers.
### Build target for documentation
The build target `inc` now works again after a very long hiatus. It now
generates and installs just the dbd, header and html files, without compiling
any C/C++ code. This can be used to speed up CI jobs that only generate
documentation.
### Bug fixes
- The error status returned by a record support's `special()` method is now propagated out of the `dbPut()` routine again (broken since 3.15.0).
- [gh: #80](https://github.com/epics-base/epics-base/issues/80), VS-2015 and
later have working strtod()
- [lp: #1776141](https://bugs.launchpad.net/epics-base/+bug/1776141), Catch
buffer overflow from long link strings
- [lp: #1899697](https://bugs.launchpad.net/epics-base/+bug/1899697), Records
in wrong PHAS order
### Change to the `junitfiles` self-test build target
The names of the generated junit xml test output files have been changed
from `<testname>.xml` to `<testname>-results.xml`, to allow better
distinction from other xml files. (I.e., for easy wildcard matching.)
-----
### Fixes and code cleanups
Issues reported by various static code checkers.
## Changes made between 3.15.7 and 3.15.8

View File

@@ -37,26 +37,11 @@ that should be performed when creating production releases of EPICS Base.</p>
<h3>The Release Process</h3>
<h4>Full Process</h4>
<p>The version released on the Feature Freeze date is designated the first
pre-release, <tt>-pre1</tt>. The first release candidate <tt>-rc1</tt> is the
first version that has undergone testing by the developers and has shown no
problems that must be fixed before release. New versions should be made at about
2-weekly intervals after the <tt>-pre1</tt> release, and designated as either
pre-release or release candidate versions by the Release Manager. Release
candidates are announced to the whole community via the tech-talk mailing list,
pre-releases are announced to to the developers via the core-talk list. After a
release candidate has been available for 2 weeks without any new problems being
reported or major changes having to be committed, the final release can be
made.</p>
<h4>Short Process for Patch Releases</h4>
<p>The Patch Release date and its scope are agreed upon a few weeks ahead of the
release. If no blocking issues are raised, the release is made by the Release
Manager on or as soon as possible after that date, following the steps below
starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
<p>We used to have one written down here, but we weren't following it very
closely so now the decision to make a new release is taken during the Core
Developers bi-weekly meetings in an informal manner. The steps detailed below
were written to remind Andrew (or anyone else who does the release) about
everything that has to be done since it's so easy to miss steps.</p>
<h3>Roles</h3>
@@ -65,11 +50,11 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
<dl>
<dt><strong>Release Manager</strong> ()</dt>
<dd>Responsible for managing and tagging the release</dd>
<dt><strong>Platform Developers</strong> (optional)</dt>
<dt><strong>Platform Developers</strong> (informal)</dt>
<dd>Responsible for individual operating system platforms</dd>
<dt><strong>Application Developers</strong></dt>
<dd>Responsible for support modules that depend on EPICS Base.</dd>
<dt><strong>Website Manager</strong> (Andrew Johnson)</dt>
<dt><strong>Website Editor</strong> (Andrew Johnson)</dt>
<dd>Responsible for the EPICS website</dd>
</dl>
@@ -111,9 +96,7 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
&amp; all developers</td>
<td>Ensure that documentation will be updated before the release date:
<ul>
<li>Application Developers Guide</li>
<li>Release Notes</li>
<li>Known Problems</li>
<li>Other documents</li>
</ul>
</td>
@@ -125,87 +108,9 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
</tr>
<tr>
<td>&nbsp;</td>
<td>Website Manager</td>
<td>Release Manager</td>
<td>Create a release milestone on Launchpad. If a target release date is
known set "Date Targeted" to the expected release date. Note that
pre-release and release-candidate versions should not get Launchpad
milestones, only the final release.</td>
</tr>
<tr>
<th colspan="3">Creating pre-release and release-candidate versions</th>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Release Manager</td>
<!-- Submodules... -->
<td>Edit and commit changes to the EPICS version number file
configure/CONFIG_BASE_VERSION.</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Release Manager</td>
<td>Tag the module in Git, using these tag conventions:
<ul>
<li>
<tt>R7.0.5-pre<i>n</i></tt>
&mdash; pre-release tag
</li>
<li>
<tt>R7.0.5-rc<i>n</i></tt>
&mdash; release candidate tag
</li>
</ul>
<blockquote><tt>
cd base-7.0<br />
git tag -m 'ANJ: Tagged for 7.0.5-rc1' R7.0.5-rc1
</tt></blockquote>
Note that submodules must <em>not</em> be tagged with the version used
for the top-level, they each have their own separate version numbers
that are only tagged at the final release.</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Release Manager</td>
<td>Export the tagged version into a tarfile. The <tt>make-tar.sh</tt>
script generates a gzipped tarfile directly from the tag, excluding the
files and directories that are only used for continuous integration:
<blockquote><tt>
cd base-7.0<br />
./.tools/make-tar.sh R7.0.5-rc1 base-7.0.5-rc1.tar.gz base-7.0.5-rc1/
</tt></blockquote>
Create a GPG signature file of the tarfile as follows:
<blockquote><tt>
gpg --armor --sign --detach-sig base-7.0.5-rc1.tar.gz
</tt></blockquote>
</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Release Manager</td>
<td>Test the tarfile by extracting its contents and building it on at
least one supported platform.</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Website Manager</td>
<td>Copy the tarfile and its signature to the Base download area of the
website and add the new files to the website Base download index
page.</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Website Manager</td>
<td>Create 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.</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Website Manager</td>
<td>Create 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.</td>
known set "Date Targeted" to the expected release date.</td>
</tr>
<tr>
<th colspan="3">Testing</th>
@@ -250,11 +155,8 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
<td>Release Manager</td>
<td>Check that documentation has been updated:
<ul>
<li><a href="https://launchpad.net/epics-appdev">Application
Developers Guide</a></li>
<li>Release Notes</li>
<li>Known Problems (hopefully empty)</li>
<li>Other documents (converting...)</li>
<li>Other documents</li>
</ul>
</td>
</tr>
@@ -266,9 +168,7 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
<tr>
<td><input type="checkbox"></td>
<td>Release Manager</td>
<td>Obtain a positive <q>Ok to release</q> from all platform developers
once a release candidate version has gone for 2 weeks without any major
new issues being reported.</td>
<td>Obtain a positive <q>Ok to release</q> from developers.</td>
</tr>
<tr>
<th colspan="3">Creating the final release version</th>
@@ -277,8 +177,8 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
<td><input type="checkbox"></td>
<td>Release Manager</td>
<td>
<p>For each external submodule in turn (assuming it has not been tagged
yet):</p>
<p><b>For each external submodule</b> in turn (assuming it has not been
tagged yet):</p>
<ol>
<li>Check that the module's Release Notes have been updated to cover
all changes; add items as necessary, and set the module version
@@ -298,7 +198,7 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
<li>Tag the module:
<blockquote><tt>
git tag -m 'ANJ: Tag for EPICS 7.0.5' &lt;module-version&gt;
git tag -m 'ANJ: Tag for EPICS 7.0.6.1' &lt;module-version&gt;
</tt></blockquote>
</li>
@@ -326,15 +226,24 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
</li>
</ol>
<p>Commit all the submodule updates to the 7.0 branch.</p>
<p><b>After all submodules complete</b> commit the submodule updates
which were added for each submodule in step 4 above to the 7.0 branch
(don't push). After committing, make sure that the output from
<tt>git submodule status --cached</tt> only shows the appropriate
version tags in the right-most parenthesized column with no
<tt>-<i>n</t>-g<i>xxxxxxx</i></tt> suffix.</p>
</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Release Manager</td>
<td>Edit the main EPICS Base version file and the built-in module version
files:
<td>
<p><tt>git grep UNRELEASED</tt> and insert the release version to any
doxygen annotations that have a <tt>@since UNRELEASED</tt> comment.
Commit (don't push).</p>
<p>Edit the main EPICS Base version file and the built-in module version
files:</p>
<ul>
<li><tt>configure/CONFIG_BASE_VERSION</tt></li>
<li><tt>configure/CONFIG_LIBCOM_VERSION</tt></li>
@@ -346,6 +255,9 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
<tt>PATCH_LEVEL</tt> value should have been incremented after the
previous release tag was applied. Set all <tt>DEVELOPMENT_FLAG</tt>
values to 0 and <tt>EPICS_DEV_SNAPSHOT</tt> to the empty string.</p>
<p>Edit the headings in the Release Notes to show the appropriate
version number and remove the warning about this being an unreleased
version of EPICS.</p>
<p>Commit these changes (don't push).</p>
</td>
</tr>
@@ -355,9 +267,9 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
<td>Tag the epics-base module in Git:
<blockquote><tt>
cd base-7.0<br />
git tag -m 'ANJ: Tagged for release' R7.0.5
git tag -m 'ANJ: Tagged for release' R7.0.6.1
</tt></blockquote>
<p>Don't push these commits or the new tag to the Launchpad repository
<p>Don't push anything to the Launchpad repository
yet.</p>
</td>
</tr>
@@ -376,6 +288,9 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
release by incrementing the MAINTENANCE_VERSION or PATCH_LEVEL value
in each file. Set all <tt>DEVELOPMENT_FLAG</tt> values to 1 and
<tt>EPICS_DEV_SNAPSHOT</tt> to "-DEV".</p>
<p>Set up the headings in the Release Notes for the next release
version number and restore the warning about this being an unreleased
version of EPICS.</p>
<p>Commit these changes (don't push).</p>
</td>
</tr>
@@ -387,12 +302,12 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
files and directories that are only used for continuous integration:
<blockquote><tt>
cd base-7.0<br />
./.tools/make-tar.sh R7.0.5 ../base-7.0.5.tar.gz base-7.0.5/
./.tools/make-tar.sh R7.0.6.1 ../base-7.0.6.1.tar.gz base-7.0.6.1/
</tt></blockquote>
Create a GPG signature file of the tarfile as follows:
<blockquote><tt>
cd ..<br />
gpg --armor --sign --detach-sig base-7.0.5.tar.gz
gpg --armor --sign --detach-sig base-7.0.6.1.tar.gz
</tt></blockquote>
</td>
</tr>
@@ -412,38 +327,38 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Release Manager</td>
<td>Website Editor</td>
<td>Copy the tarfile and its signature to the Base download area of the
website.</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Website Manager</td>
<td>Website Editor</td>
<td>Update the website subdirectory that holds the release
documentation, and copy in the files from the base/documentation
directory of the tarfile.</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Website Manager</td>
<td>Website Editor</td>
<td>Update the webpage for the new release with links to the release
documents and tar file.</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Website Manager</td>
<td>Website Editor</td>
<td>Add the new release tar file to the website Base download index
page.</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Website Manager</td>
<td>Website Editor</td>
<td>Link to the release webpage from other relevent areas of the
website - update front page and sidebars.</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Website Manager</td>
<td>Website Editor</td>
<td>Add an entry to the website News page, linking to the new version
webpage.</td>
</tr>
@@ -453,17 +368,17 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Website Manager</td>
<td>Website Editor</td>
<td>Upload the tar file and its <tt>.asc</tt> signature file to the
epics-controls web-server.
<blockquote><tt>
scp base-7.0.5.tar.gz base-7.0.5.tar.gz.asc epics-controls:download/base<br />
scp base-7.0.6.1.tar.gz base-7.0.6.1.tar.gz.asc epics-controls:download/base<br />
</tt></blockquote>
</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Website Manager</td>
<td>Website Editor</td>
<td>Follow instructions on
<a href="https://epics-controls.org/resources-and-support/documents/epics-website-documentation/adding-a-page-for-a-new-release/">
Add a page for a new release</a> to create a new release webpage (not
@@ -478,7 +393,7 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>Website Manager</td>
<td>Release Manager</td>
<td>Go to the Launchpad milestone for this release. Click the Create
release button and add the release date. Put a URL for the release page
in the Release notes box, and click the Create release button. Upload

View File

@@ -88,7 +88,7 @@ const char * ca_message_text []
"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",
"Specified task isn't a member of a CA context",
"Attempt to use defunct CA feature failed",
"The supplied string is empty",
@@ -324,7 +324,7 @@ int epicsStdCall ca_create_channel (
*chanptr = pChanNotify;
pChanNotify->initiateConnect ( guard );
// no need to worry about a connect preempting here because
// the connect sequence will not start untill initiateConnect()
// the connect sequence will not start until initiateConnect()
// is called
}
catch ( cacChannel::badString & ) {
@@ -384,9 +384,9 @@ int epicsStdCall ca_clear_channel ( chid pChan )
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user creates non-preemptive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
// o user calls this function from an auxiliary thread
//
CallbackGuard cbGuard ( cac.cbMutex );
epicsGuard < epicsMutex > guard ( cac.mutex );
@@ -720,7 +720,7 @@ int epicsStdCall ca_context_status ( ca_client_context * pcac, unsigned level )
/*
* ca_current_context ()
*
* used when an auxillary thread needs to join a CA client context started
* used when an auxiliary thread needs to join a CA client context started
* by another thread
*/
// extern "C"
@@ -740,7 +740,7 @@ struct ca_client_context * epicsStdCall ca_current_context ()
/*
* ca_attach_context ()
*
* used when an auxillary thread needs to join a CA client context started
* used when an auxiliary thread needs to join a CA client context started
* by another thread
*/
// extern "C"

View File

@@ -494,7 +494,7 @@ void verifyConnectionHandlerConnect ( appChan *pChans, unsigned chanCount,
/*
* verifyBlockingConnect ()
*
* 1) verify that we dont print a disconnect message when
* 1) verify that we don't print a disconnect message when
* we delete the last channel
*
* 2) verify that we delete the connection to the IOC
@@ -645,7 +645,7 @@ void verifyBlockingConnect ( appChan *pChans, unsigned chanCount,
status = ca_pend_io ( 1e-16 );
if ( status == ECA_TIMEOUT ) {
/*
* we end up here if the channel isnt on the same host
* we end up here if the channel isn't on the same host
*/
epicsThreadSleep ( 0.1 );
ca_poll ();
@@ -1112,7 +1112,7 @@ void verifyHighThroughputRead ( chid chan, unsigned interestLevel )
unsigned i;
/*
* verify we dont jam up on many uninterrupted
* verify we don't jam up on many uninterrupted
* solicitations
*/
if ( ca_read_access (chan) ) {
@@ -1152,7 +1152,7 @@ void verifyHighThroughputWrite ( chid chan, unsigned interestLevel )
}
/*
* verify we dont jam up on many uninterrupted
* verify we don't jam up on many uninterrupted
* get callback requests
*/
void verifyHighThroughputReadCallback ( chid chan, unsigned interestLevel )
@@ -1181,7 +1181,7 @@ void verifyHighThroughputReadCallback ( chid chan, unsigned interestLevel )
}
/*
* verify we dont jam up on many uninterrupted
* verify we don't jam up on many uninterrupted
* put callback request
*/
void verifyHighThroughputWriteCallback ( chid chan, unsigned interestLevel )
@@ -1239,7 +1239,7 @@ void verifyBadString ( chid chan, unsigned interestLevel )
verify ( status == ECA_NORMAL );
if ( strcmp ( stimStr, respStr ) ) {
printf (
"Test fails if stim \"%s\" isnt roughly equiv to resp \"%s\"\n",
"Test fails if stim \"%s\" isn't roughly equiv to resp \"%s\"\n",
stimStr, respStr);
}
showProgressEnd ( interestLevel );
@@ -1395,7 +1395,7 @@ static void multiSubscrDestroyNoLateCallbackThread ( void * pParm )
/*
* raise the priority of the current thread hoping to improve our
* likelyhood of detecting a bug
* likelihood of detecting a bug
*/
priorityOfTestThread = epicsThreadGetPrioritySelf ();
epicsThreadSetPriority ( epicsThreadGetIdSelf(), epicsThreadPriorityHigh );
@@ -1445,7 +1445,7 @@ static void multiSubscrDestroyNoLateCallbackThread ( void * pParm )
}
/*
* verify that, in a preemtive callback mode client, a subscription callback never
* verify that, in a preemptive callback mode client, a subscription callback never
* comes after the subscription is destroyed
*/
static void multiSubscrDestroyNoLateCallbackTest ( const char *pName, unsigned interestLevel )
@@ -1563,7 +1563,7 @@ void multiSubscriptionDeleteTest ( chid chan, unsigned interestLevel )
/*
* singleSubscriptionDeleteTest
*
* verify that we dont fail when we repeatedly create
* verify that we don't fail when we repeatedly create
* and delete only one subscription with a high level of
* traffic on it
*/
@@ -1617,7 +1617,7 @@ void singleSubscriptionDeleteTest ( chid chan, unsigned interestLevel )
/*
* channelClearWithEventTrafficTest
*
* verify that we can delete a channel that has subcriptions
* verify that we can delete a channel that has subscriptions
* attached with heavy update traffic
*/
void channelClearWithEventTrafficTest ( const char *pName, unsigned interestLevel )
@@ -2481,7 +2481,7 @@ void monitorUpdateTest ( chid chan, unsigned interestLevel )
showProgress ( interestLevel );
/*
* attempt to uncover problems where the last event isnt sent
* attempt to uncover problems where the last event isn't sent
* and hopefully get into a flow control situation
*/
prevPassCount = 0u;
@@ -2522,7 +2522,7 @@ void monitorUpdateTest ( chid chan, unsigned interestLevel )
ca_poll (); /* emulate typical GUI */
for ( j = 0; j < NELEMENTS ( test ); j++ ) {
/*
* we shouldnt see old monitors because
* we shouldn't see old monitors because
* we resubscribed
*/
verify ( test[j].count <= i + 2 );
@@ -3016,7 +3016,7 @@ void testMultithreadSubscr ( void * pParm )
}
/*
* test installation of subscriptions similar to usage paterns
* test installation of subscriptions similar to usage patterns
* employed by modern versions of the sequencer
*/
void verifyMultithreadSubscr ( const char * pName, unsigned interestLevel )
@@ -3111,7 +3111,7 @@ void fdManagerVerify ( const char * pName, unsigned interestLevel )
status = ca_flush_io ();
verify ( status == ECA_NORMAL );
/* look for infinite loop in fd manager schedualing */
/* look for infinite loop in fd manager scheduling */
epicsTimeGetCurrent ( & begin );
eventCount = 0u;
while ( 1 ) {
@@ -3175,7 +3175,7 @@ void verifyConnectWithDisconnectedChannels (
* we should be able to connect to a valid
* channel within a reasonable delay even
* though there is one permanently
* diasconnected channel
* disconnected channel
*/
status = ca_pend_io ( timeoutToPendIO );
verify ( status == ECA_NORMAL );
@@ -3491,7 +3491,7 @@ int acctst ( const char * pName, unsigned interestLevel, unsigned channelCount,
/*
* CA pend event delay accuracy test
* (CA asssumes that search requests can be sent
* (CA assumes that search requests can be sent
* at least every 25 mS on all supported os)
*/
printf ( "\n" );

View File

@@ -130,8 +130,8 @@ bool bhe::updatePeriod (
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
// this block is entered if the beacon was created as a side effect of
// creating a connection and so we don't yet know the first beacon time
// and sequence number
//
if ( this->timeStamp == epicsTime () ) {
@@ -154,7 +154,7 @@ bool bhe::updatePeriod (
return false;
}
// 1) detect beacon duplications due to redundant routes
// 1) detect beacon duplication due to redundant routes
// 2) detect lost beacons due to input queue overrun or damage
if ( CA_V410 ( protocolRevision ) ) {
unsigned beaconSeqAdvance;
@@ -175,7 +175,7 @@ bool bhe::updatePeriod (
// 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)
// or a beacon due to input queue overrun)
if ( beaconSeqAdvance > 1 && beaconSeqAdvance < 4 ) {
logBeaconDiscard ( beaconSeqAdvance, currentTime );
return false;
@@ -244,8 +244,8 @@ bool bhe::updatePeriod (
/*
* 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.
* IOC reboots). Lower tolerance here because we
* don't 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

View File

@@ -18,7 +18,7 @@
#define INC_caProto_H
// Pick up definition of IPPORT_USERRESERVED
#include <osdSock.h>
#include <osiSock.h>
#define capStrOf(A) #A
#define capStrOfX(A) capStrOf ( A )
@@ -58,8 +58,8 @@
#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)
* 1500 (max of Ethernet and 802.{2,3} MTU) - 20(IP) - 8(UDP)
* (the MTU of Ethernet is currently independent of its speed variant)
*/
#define ETHERNET_MAX_UDP ( 1500u - 20u - 8u )
#define MAX_UDP_RECV ( 0xffff + 16u ) /* allow large frames to be received in the future */
@@ -117,7 +117,7 @@ typedef ca_uint32_t caResId;
/*
* for use with search and not_found (if search fails and
* its not a broadcast tell the client to look elesewhere)
* its not a broadcast tell the client to look elsewhere)
*/
#define DOREPLY 10u
#define DONTREPLY 5u
@@ -176,7 +176,7 @@ typedef struct ca_hdr {
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_float32_t m_toval; /* period between samples */
ca_uint16_t m_mask; /* event select mask */
ca_uint16_t m_pad; /* extend to 32 bits */
};

View File

@@ -90,7 +90,7 @@ int main(int argc, char* argv[])
(void)detachinout;
#endif
chdir ( "/" );
(void)! chdir ( "/" );
ca_repeater ();
return ( 0 );
}

View File

@@ -224,7 +224,7 @@ void ca_client_context::changeExceptionEvent (
epicsGuard < epicsMutex > guard ( this->mutex );
this->ca_exception_func = pfunc;
this->ca_exception_arg = arg;
// should block here until releated callback in progress completes
// should block here until related callback in progress completes
}
void ca_client_context::replaceErrLogHandler (
@@ -237,7 +237,7 @@ void ca_client_context::replaceErrLogHandler (
else {
this->pVPrintfFunc = epicsVprintf;
}
// should block here until releated callback in progress completes
// should block here until related callback in progress completes
}
void ca_client_context::registerForFileDescriptorCallBack (
@@ -252,7 +252,7 @@ void ca_client_context::registerForFileDescriptorCallBack (
// w/o having sent the wakeup message
this->_sendWakeupMsg ();
}
// should block here until releated callback in progress completes
// should block here until related callback in progress completes
}
int ca_client_context :: printFormated (
@@ -392,9 +392,19 @@ void ca_client_context :: vSignal (
}
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 );
try {
char date[64];
current.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S.%f");
this->printFormated ( " Current Time: %s\n", date );
}
catch ( std::exception & except ) {
errlogPrintf (
"CA client library thread \"%s\" caught C++ exception \"%s\"\n",
epicsThreadGetNameSelf (), except.what () );
epicsTimeStamp now = current;
this->printFormated ( " Current Time: %u.%u\n",
now.secPastEpoch, now.nsec );
}
/*
* Terminate execution if unsuccessful
@@ -768,9 +778,9 @@ LIBCA_API int epicsStdCall ca_clear_subscription ( evid pMon )
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user creates non-preemptive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
// o user calls this function from an auxiliary thread
//
CallbackGuard cbGuard ( cac.cbMutex );
epicsGuard < epicsMutex > guard ( cac.mutex );

View File

@@ -285,7 +285,7 @@ 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
// lock intentionally not held here so that we don't deadlock
// waiting for the UDP thread to exit while it is waiting to
// get the lock.
{
@@ -312,7 +312,7 @@ cac::~cac ()
//
// wait for all tcp threads to exit
//
// this will block for oustanding sends to go out so dont
// this will block for outstanding sends to go out so don't
// hold a lock while waiting
//
{
@@ -411,7 +411,7 @@ void cac::show (
::printf ( "Channel Access Client Context at %p for user %s\n",
static_cast <const void *> ( this ), this->pUserName );
// this also supresses the "defined, but not used"
// this also suppresses the "defined, but not used"
// warning message
::printf ( "\trevision \"%s\"\n", pVersionCAC );

View File

@@ -129,7 +129,7 @@ typedef unsigned CA_SYNC_GID;
#define CA_OP_CONN_UP 6
#define CA_OP_CONN_DOWN 7
/* depricated */
/* deprecated */
#define CA_OP_SEARCH 2
/*
@@ -464,7 +464,7 @@ LIBCA_API int epicsStdCall ca_array_get_callback
/* Specify a function to be executed whenever significant changes */
/* occur to a channel. */
/* NOTES: */
/* 1) Evid may be omited by passing a NULL pointer */
/* 1) Evid may be omitted by passing a NULL pointer */
/* */
/* 2) An array count of zero specifies the native db count */
/* */
@@ -559,19 +559,19 @@ LIBCA_API chid epicsStdCall ca_evid_to_chid ( evid id );
/*
* ca_pend_event()
*
* timeOut R wait for this delay in seconds
* timeout R wait for this delay in seconds
*/
LIBCA_API int epicsStdCall ca_pend_event (ca_real timeOut);
LIBCA_API int epicsStdCall 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
* 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)
*/
LIBCA_API int epicsStdCall ca_pend_io (ca_real timeOut);
LIBCA_API int epicsStdCall ca_pend_io (ca_real timeout);
/* calls ca_pend_io() if early is true otherwise ca_pend_event() is called */
LIBCA_API int epicsStdCall ca_pend (ca_real timeout, int early);
@@ -837,7 +837,7 @@ LIBCA_API double epicsStdCall ca_beacon_period (chid chan);
LIBCA_API double epicsStdCall ca_receive_watchdog_delay (chid chan);
/*
* used when an auxillary thread needs to join a CA client context started
* used when an auxiliary thread needs to join a CA client context started
* by another thread
*/
LIBCA_API struct ca_client_context * epicsStdCall ca_current_context ();

View File

@@ -188,7 +188,7 @@ int main ( int argc, char ** argv )
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
epicsSocketDestroy ( sock );
errlogPrintf ("casw: error from recv was = \"%s\"\n",
errlogPrintf ("casw: " ERL_ERROR " from recv was = \"%s\"\n",
sockErrBuf );
return -1;
}
@@ -224,7 +224,7 @@ int main ( int argc, char ** argv )
* always set this field to INADDR_ANY
*
* clients always assume that if this
* field is set to something that isnt INADDR_ANY
* field is set to something that isn't INADDR_ANY
* then it is the overriding IP address of the server.
*/
ina.sin_family = AF_INET;
@@ -235,7 +235,7 @@ int main ( int argc, char ** argv )
}
else {
/*
* old servers dont supply this and the
* old servers don't supply this and the
* default port must be assumed
*/
ina.sin_port = htons ( serverPort );

View File

@@ -45,7 +45,7 @@ bool comBuf::flushToWire ( wireSendAdapter & wire, const epicsTime & currentTime
return true;
}
// throwing the exception from a function that isnt inline
// throwing the exception from a function that isn't inline
// shrinks the GNU compiled object code
void comBuf::throwInsufficentBytesException ()
{

View File

@@ -88,6 +88,7 @@ public:
bool push ( const T & value );
template < class T >
unsigned push ( const T * pValue, unsigned nElem );
unsigned push ( const char * pValue, unsigned nElem );
unsigned push ( const epicsInt8 * pValue, unsigned nElem );
unsigned push ( const epicsUInt8 * pValue, unsigned nElem );
unsigned push ( const epicsOldString * pValue, unsigned nElem );
@@ -208,6 +209,11 @@ inline unsigned comBuf :: push ( const epicsUInt8 *pValue, unsigned nElem )
return copyInBytes ( pValue, nElem );
}
inline unsigned comBuf :: push ( const char *pValue, unsigned nElem )
{
return copyInBytes ( pValue, nElem );
}
inline unsigned comBuf :: push ( const epicsOldString * pValue, unsigned nElem )
{
unsigned index = this->nextWriteIndex;

View File

@@ -46,7 +46,7 @@ void comQueRecv::clear ()
this->nBytesPending = 0u;
}
unsigned comQueRecv::copyOutBytes ( epicsInt8 *pBuf, unsigned nBytes )
unsigned comQueRecv::copyOutBytes ( char *pBuf, unsigned nBytes )
{
unsigned totalBytes = 0u;
do {
@@ -196,7 +196,7 @@ epicsUInt16 comQueRecv::popUInt16 ()
if ( ! pComBuf ) {
comBuf::throwInsufficentBytesException ();
}
// try first for all in one buffer efficent version
// try first for all in one buffer efficient version
epicsUInt16 tmp = 0;
comBuf::popStatus status = pComBuf->pop ( tmp );
if ( status.success ) {
@@ -215,7 +215,7 @@ epicsUInt32 comQueRecv::popUInt32 ()
if ( ! pComBuf ) {
comBuf::throwInsufficentBytesException ();
}
// try first for all in one buffer efficent version
// try first for all in one buffer efficient version
epicsUInt32 tmp = 0;
comBuf::popStatus status = pComBuf->pop ( tmp );
if ( status.success ) {
@@ -230,7 +230,7 @@ epicsUInt32 comQueRecv::popUInt32 ()
bool comQueRecv::popOldMsgHeader ( caHdrLargeArray & msg )
{
// try first for all in one buffer efficent version
// try first for all in one buffer efficient version
comBuf * pComBuf = this->bufs.first ();
if ( ! pComBuf ) {
return false;

View File

@@ -33,7 +33,7 @@ public:
comQueRecv ( comBufMemoryManager & );
~comQueRecv ();
unsigned occupiedBytes () const;
unsigned copyOutBytes ( epicsInt8 *pBuf, unsigned nBytes );
unsigned copyOutBytes ( char *pBuf, unsigned nBytes );
unsigned removeBytes ( unsigned nBytes );
void pushLastComBufReceived ( comBuf & );
void clear ();

View File

@@ -27,17 +27,17 @@
// 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
// occurs then detect and avoid it and provide diagnostic to the user
// via special status.
// 2) Return status to the user when there is insufficent memory to
// 2) Return status to the user when there is insufficient 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
// 4) Do not allocate too much memory in exception situations (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
// 6) Message fragments must never be sent to the IOC when there isn't
// 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
@@ -45,7 +45,7 @@
//
// 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
// required. If it is a receive thread schedules 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.
@@ -58,9 +58,9 @@
// 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.
// all buffering in the system is exhausted.
// b) A user is queuing many requests that demand a response from one
// callback until all buffering in the system is exausted.
// callback until all buffering in the system is exhausted.
// c) Some combination of both (a) nad (b).
//
//

View File

@@ -35,7 +35,7 @@
#include "caerr.h"
/*
* NOOP if this isnt required
* NOOP if this isn't required
*/
#ifdef EPICS_CONVERSION_REQUIRED
@@ -326,7 +326,7 @@ arrayElementCount num /* number of values */
** int encode; boolean, if true vax to ieee
** else ieee to vax
**
** converts fields ofstruct in HOST format to ieee format
** converts fields of struct in HOST format to ieee format
** or
** converts fields of struct in NET format to fields with HOST
** format
@@ -1022,7 +1022,7 @@ arrayElementCount num /* number of values */
** int encode; boolean, if true vax to ieee
** else ieee to vax
**
** converts fields ofstruct in HOST format to ieee format
** converts fields of struct in HOST format to ieee format
** or
** converts fields of struct in NET format to fields with HOST
** format
@@ -1056,7 +1056,7 @@ arrayElementCount num /* number of values */
/****************************************************************************
** cvrt_sts_long(s,d)
**
** converts fields ofstruct in HOST format to ieee format
** converts fields of struct in HOST format to ieee format
** or
** converts fields of struct in NET format to fields with HOST
** format
@@ -1118,7 +1118,7 @@ arrayElementCount num /* number of values */
/****************************************************************************
** cvrt_time_short(s,d)
**
** converts fields ofstruct in HOST format to ieee format
** converts fields of struct in HOST format to ieee format
** or
** converts fields of struct in NET format to fields with HOST
** format
@@ -1239,7 +1239,7 @@ arrayElementCount num /* number of values */
/****************************************************************************
** cvrt_sts_char(s,d)
**
** converts fields ofstruct in HOST format to ieee format
** converts fields of struct in HOST format to ieee format
** or
** converts fields of struct in NET format to fields with HOST
** format
@@ -1274,7 +1274,7 @@ arrayElementCount num /* number of values */
/****************************************************************************
** cvrt_time_long(s,d)
**
** converts fields ofstruct in HOST format to ieee format
** converts fields of struct in HOST format to ieee format
** or
** converts fields of struct in NET format to fields with HOST
** format
@@ -1325,7 +1325,7 @@ arrayElementCount num /* number of values */
for(i=0; i<num; i++){
*pDest = dbr_ntohs( *pSrc );
/*
* dont increment these inside the MACRO
* don't increment these inside the MACRO
*/
pDest++;
pSrc++;

View File

@@ -123,7 +123,7 @@ typedef epicsOldString dbr_class_name_t;
LIBCA_API extern const int epicsTypeToDBR_XXXX [lastEpicsType+1];
/*
* The DBR_XXXX types are indicies into this array
* The DBR_XXXX types are indices into this array
*/
LIBCA_API extern const epicsType DBR_XXXXToEpicsType [LAST_BUFFER_TYPE+1];

View File

@@ -53,7 +53,7 @@ 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
// set the entire 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 );

View File

@@ -189,7 +189,7 @@ extern "C" void epicsStdCall configureChannelAccessAddressList
int yes;
/*
* dont load the list twice
* don't load the list twice
*/
assert ( ellCount (pList) == 0 );

View File

@@ -56,7 +56,7 @@ static const double CA_CONN_VERIFY_PERIOD = 30.0; /* (sec) how often to request
* monitor flow control
*
* turning this down effects maximum throughput
* because we dont get an optimal number of bytes
* because we don't get an optimal number of bytes
* per network frame
*/
static const unsigned contiguousMsgCountWhichTriggersFlowControl = 10u;

View File

@@ -57,7 +57,7 @@ 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 !!
// !! don't touch 'this' pointer after this point because object has been deleted !!
}
void * msgForMultiplyDefinedPV::operator new ( size_t size,

View File

@@ -147,14 +147,14 @@ void nciu::connect ( unsigned nativeType,
guard, this->accessRightState );
}
// channel uninstal routine grabs the callback lock so
// channel uninstall 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.
// so a channel cant be destroyed out from under us.
this->notify().connectNotify ( guard );
}

View File

@@ -32,7 +32,7 @@
// 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
// potential problems) if we don't make the baseNMIU
// destructor virtual.
#if defined ( __SUNPRO_CC ) && ( __SUNPRO_CC <= 0x540 )
# define NETIO_VIRTUAL_DESTRUCTOR

View File

@@ -591,16 +591,16 @@ void ca_client_context :: whenThereIsAnExceptionDestroySyncGroupIO (
io.destroy ( *this->pCallbackGuard.get(), guard );
}
else {
// dont reverse the lock hierarchy
// don't 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 creates non-preemptive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
// o user calls this function from an auxiliary thread
//
CallbackGuard cbGuard ( this->cbMutex );
epicsGuard < epicsMutex > guard ( this->mutex );

View File

@@ -571,7 +571,7 @@ int epicsStdCall ca_create_subscription (
oldSubscription (
guard, *pChan, pChan->io, tmpType, count, mask,
pCallBack, pCallBackArg, monixptr );
// dont touch object created after above new because
// don't touch object created after above new because
// the first callback might have canceled, and therefore
// destroyed, it
return ECA_NORMAL;

View File

@@ -41,7 +41,7 @@ oldSubscription::oldSubscription (
*pEventId = this;
}
io.subscribe ( guard, type, nElem, mask, *this, &this->id );
// Dont touch this pointer after this point because the
// Don't touch this pointer after this point because the
// 1st update callback might cancel the subscription and
// thereby destroy this object.
}

View File

@@ -79,7 +79,7 @@
/*
* these can be external since there is only one instance
* per machine so we dont care about reentrancy
* per machine so we don't care about reentrancy
*/
static tsDLList < repeaterClient > client_list;
@@ -335,7 +335,7 @@ static void fanOut ( const osiSockAddr & from, const void * pMsg,
while ( ( pclient = client_list.get () ) ) {
theClients.add ( *pclient );
/* Dont reflect back to sender */
/* Don't reflect back to sender */
if ( pclient->identicalAddress ( from ) ) {
continue;
}
@@ -392,7 +392,7 @@ static void register_new_client ( osiSockAddr & from,
* 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
* found and the loopback address when subscribing with
* the CA repeater until all CA repeaters have been updated
* to current code.
*/
@@ -452,7 +452,7 @@ static void register_new_client ( osiSockAddr & from,
}
/*
* send a noop message to all other clients so that we dont
* send a noop message to all other clients so that we don't
* accumulate sockets when there are no beacons
*/
caHdr noop;

View File

@@ -279,8 +279,8 @@ epicsTimerNotify::expireStatus searchTimer::expire (
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 ) );
debugPrintf ( ("sent %u delay Rts=%s\n",
nFrameSent, buf ) );
}
# endif
@@ -317,7 +317,7 @@ void searchTimer :: show ( unsigned level ) const
//
// Reset the delay to the next search request if we get
// at least one response. However, dont reset this delay if we
// at least one response. However, don't reset this delay if we
// get a delayed response to an old search request.
//
void searchTimer::uninstallChanDueToSuccessfulSearchResponse (

View File

@@ -82,8 +82,8 @@ private:
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 */
unsigned searchAttempts; /* num search tries after last timer expiration */
unsigned searchResponses; /* num search resp after last timer expiration */
const unsigned index;
ca_uint32_t dgSeqNoAtTimerExpireBegin;
ca_uint32_t dgSeqNoAtTimerExpireEnd;

View File

@@ -82,9 +82,9 @@ extern "C" int epicsStdCall ca_sg_delete ( const CA_SYNC_GID gid )
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user creates non-preemptive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
// o user calls this function from an auxiliary thread
//
CallbackGuard cbGuard ( pcac->cbMutex );
epicsGuard < epicsMutex > guard ( pcac->mutex );
@@ -106,9 +106,9 @@ void sync_group_reset ( ca_client_context & client, CASG & sg )
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user creates non-preemptive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
// o user calls this function from an auxiliary thread
//
CallbackGuard cbGuard ( client.cbMutex );
epicsGuard < epicsMutex > guard ( client.mutex );
@@ -219,9 +219,9 @@ extern "C" int epicsStdCall ca_sg_test ( const CA_SYNC_GID gid )
// we will definately stall out here if all of the
// following are true
//
// o user creates non-preemtive mode client library context
// o user creates non-preemptive mode client library context
// o user doesnt periodically call a ca function
// o user calls this function from an auxiillary thread
// o user calls this function from an auxiliary thread
//
CallbackGuard cbGuard ( pcac->cbMutex );
epicsGuard < epicsMutex > guard ( pcac->mutex );

View File

@@ -176,7 +176,7 @@ void tcpRecvWatchdog::sendBacklogProgressNotify (
{
guard.assertIdenticalMutex ( this->mutex );
// We dont set "beaconAnomaly" to be false here because, after we see a
// We don't 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.

View File

@@ -81,7 +81,7 @@ void tcpSendThread::run ()
while ( true ) {
// dont wait if there is still labor to be done below
// don't wait if there is still labor to be done below
if ( ! laborPending ) {
epicsGuardRelease < epicsMutex > unguard ( guard );
this->iiu.sendThreadFlushEvent.wait ();
@@ -124,7 +124,7 @@ void tcpSendThread::run ()
}
else {
// This wakes up the resp thread so that it can call
// the connect callback. This isnt maximally efficent
// the connect callback. This isn't maximally efficient
// 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.
@@ -178,7 +178,7 @@ void tcpSendThread::run ()
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf ("CAC TCP clean socket shutdown error was %s\n",
errlogPrintf ("CAC TCP clean socket shutdown " ERL_ERROR " was %s\n",
sockErrBuf );
}
}
@@ -194,7 +194,7 @@ void tcpSendThread::run ()
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf ("CAC TCP clean socket shutdown error was %s\n",
errlogPrintf ("CAC TCP clean socket shutdown " ERL_ERROR " was %s\n",
sockErrBuf );
}
}
@@ -204,7 +204,7 @@ void tcpSendThread::run ()
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
// ca_context_destroy() when a circuit isn't 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
@@ -283,7 +283,7 @@ unsigned tcpiiu::sendBytes ( const void *pBuf,
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf ( "CAC: unexpected TCP send error: %s\n",
errlogPrintf ( "CAC: unexpected TCP send " ERL_ERROR ": %s\n",
sockErrBuf );
}
@@ -322,7 +322,7 @@ void tcpiiu::recvBytes (
return;
}
// if the circuit was locally aborted then supress
// if the circuit was locally aborted then suppress
// warning messages about bad file descriptor etc
if ( this->state != iiucs_connected &&
this->state != iiucs_clean_shutdown ) {
@@ -358,9 +358,9 @@ void tcpiiu::recvBytes (
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
// the replacable printf handler isnt called here
// because it reqires a callback lock which probably
// isnt appropriate here
// the replaceable printf handler isn't called here
// because it requires a callback lock which probably
// isn't appropriate here
char name[64];
this->hostNameCacheInstance.getName (
name, sizeof ( name ) );
@@ -535,11 +535,11 @@ void tcpRecvThread::run ()
}
//
// we dont feel comfortable calling this with a lock applied
// we don't 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
// we would prefer to improve efficiency by trying, first, a
// recv with the new MSG_DONTWAIT flag set, but there isn't
// universal support
//
bool bytesArePending = this->iiu.bytesArePendingInOS ();
@@ -957,7 +957,7 @@ void tcpiiu::initiateAbortShutdown (
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf ( "CAC TCP socket linger set error was %s\n",
errlogPrintf ( "CAC TCP socket linger set " ERL_ERROR " was %s\n",
sockErrBuf );
}
this->discardingPendingData = true;
@@ -988,7 +988,7 @@ void tcpiiu::initiateAbortShutdown (
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf ("CAC TCP socket shutdown error was %s\n",
errlogPrintf ("CAC TCP socket shutdown " ERL_ERROR " was %s\n",
sockErrBuf );
}
}
@@ -1002,7 +1002,7 @@ void tcpiiu::initiateAbortShutdown (
};
//
// wake up the send thread if it isnt blocking in send()
// wake up the send thread if it isn't blocking in send()
//
this->sendThreadFlushEvent.signal ();
this->flushBlockEvent.signal ();
@@ -1058,7 +1058,7 @@ void tcpiiu::show ( unsigned level ) const
this->_receiveThreadIsBusy );
}
if ( level > 2u ) {
::printf ( "\tvirtual circuit socket identifier %d\n", this->sock );
::printf ( "\tvirtual circuit socket identifier %d\n", (int)this->sock );
::printf ( "\tsend thread flush signal:\n" );
this->sendThreadFlushEvent.show ( level-2u );
::printf ( "\tsend thread:\n" );
@@ -1580,7 +1580,7 @@ void tcpiiu::subscriptionRequest (
maxBytes = MAX_TCP;
}
unsigned dataType = subscr.getType ( guard );
// data type bounds checked when sunscription created
// data type bounds checked when subscription created
arrayElementCount maxElem = ( maxBytes - dbr_size[dataType] ) / dbr_value_size[dataType];
if ( nElem > maxElem ) {
throw cacChannel::msgBodyCacheTooSmall ();
@@ -1633,7 +1633,7 @@ void tcpiiu::subscriptionUpdateRequest (
throw cacChannel::msgBodyCacheTooSmall ();
}
comQueSendMsgMinder minder ( this->sendQue, guard );
// nElem boounds checked above
// nElem bounds checked above
this->sendQue.insertRequestHeader (
CA_PROTO_READ_NOTIFY, 0u,
static_cast < ca_uint16_t > ( dataType ),
@@ -1712,7 +1712,7 @@ 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
// Instead, the process thread schedules 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.
@@ -1817,7 +1817,7 @@ void tcpiiu::disconnectAllChannels (
}
while ( nciu * pChan = this->createRespPend.get () ) {
// we dont yet know the server's id so we cant
// we don't 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
@@ -1848,7 +1848,7 @@ void tcpiiu::disconnectAllChannels (
while ( nciu * pChan = this->unrespCircuit.get () ) {
// if we know that the circuit is unresponsive
// then we dont send a channel delete request and
// then we don't 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 );
@@ -1883,7 +1883,7 @@ void tcpiiu::unlinkAllChannels (
while ( nciu * pChan = this->createRespPend.get () ) {
pChan->channelNode::listMember =
channelNode::cs_none;
// we dont yet know the server's id so we cant
// we don't 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
@@ -1921,7 +1921,7 @@ void tcpiiu::unlinkAllChannels (
channelNode::cs_none;
pChan->disconnectAllIO ( cbGuard, guard );
// if we know that the circuit is unresponsive
// then we dont send a channel delete request and
// then we don't 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 );
@@ -1951,7 +1951,7 @@ void tcpiiu::installChannel (
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
// The tcp send thread runs at a priority below the udp thread
// so that this will not send small packets
this->sendThreadFlushEvent.signal ();
}
@@ -2060,7 +2060,7 @@ bool tcpiiu::bytesArePendingInOS () const
}
return false;
#else
osiSockIoctl_t bytesPending = 0; /* shut up purifys yapping */
osiSockIoctl_t bytesPending = 0; /* shut up Purify's yapping */
int status = socket_ioctl ( this->sock,
FIONREAD, & bytesPending );
if ( status >= 0 ) {

View File

@@ -279,7 +279,7 @@ skip_rest:
/*
* wait for the operation to complete
* (outstabnding decrements to zero)
* (outstanding decrements to zero)
*/
while(ntries){
ca_pend_event(1.0);

View File

@@ -202,7 +202,7 @@ udpiiu::udpiiu (
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf("CAC: failed to set mcast ttl %d\n", ttl);
errlogPrintf("CAC: failed to set mcast ttl %d\n", (int)ttl);
}
}
#endif
@@ -266,7 +266,7 @@ udpiiu::udpiiu (
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
epicsSocketDestroy ( this->sock );
errlogPrintf ( "CAC: getsockname () error was \"%s\"\n", sockErrBuf );
errlogPrintf ( "CAC: getsockname () " ERL_ERROR " was \"%s\"\n", sockErrBuf );
throwWithLocation ( noSocket () );
}
if ( tmpAddr.sa.sa_family != AF_INET) {
@@ -428,7 +428,7 @@ void udpRecvThread::run ()
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf ( "CAC: UDP recv error was \"%s\"\n",
errlogPrintf ( "CAC: UDP recv " ERL_ERROR " was \"%s\"\n",
sockErrBuf );
}
}
@@ -536,9 +536,9 @@ void epicsStdCall caRepeaterRegistrationMessage (
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.
* Different OS return different codes when the repeater isn't running.
* Its ok to suppress these messages because I print another warning message
* if we time out registering with the repeater.
*
* Linux returns SOCK_ECONNREFUSED
* Windows 2000 returns SOCK_ECONNRESET
@@ -673,7 +673,7 @@ bool udpiiu :: searchRespAction (
const epicsTime & currentTime )
{
/*
* we dont currently know what to do with channel's
* we don't currently know what to do with channel's
* found to be at non-IP type addresses
*/
if ( addr.sa.sa_family != AF_INET ) {
@@ -762,7 +762,7 @@ bool udpiiu::beaconAction (
* always set this field to INADDR_ANY
*
* clients always assume that if this
* field is set to something that isnt INADDR_ANY
* field is set to something that isn't INADDR_ANY
* then it is the overriding IP address of the server.
*/
ina.sin_family = AF_INET;
@@ -772,7 +772,7 @@ bool udpiiu::beaconAction (
}
else {
/*
* old servers dont supply this and the
* old servers don't supply this and the
* default port must be assumed
*/
ina.sin_port = htons ( this->serverPort );
@@ -874,7 +874,7 @@ void udpiiu::postMsg (
size = pCurMsg->m_postsize + sizeof ( *pCurMsg );
/*
* dont allow msg body extending beyond frame boundary
* don't allow msg body extending beyond frame boundary
*/
if ( size > blockSize ) {
char buf[64];
@@ -1044,7 +1044,7 @@ void udpiiu :: SearchRespCallback :: notify (
const osiSockAddr & addr, const epicsTime & currentTime )
{
/*
* we dont currently know what to do with channel's
* we don't currently know what to do with channel's
* found to be at non-IP type addresses
*/
if ( addr.sa.sa_family != AF_INET ) {
@@ -1119,7 +1119,7 @@ bool udpiiu :: datagramFlush (
{
guard.assertIdenticalMutex ( cacMutex );
// dont send the version header by itself
// don't send the version header by itself
if ( this->nBytesInXmitBuf <= sizeof ( caHdr ) ) {
return false;
}

View File

@@ -606,12 +606,12 @@ void CA_put(SV *ca_ref, SV *val, ...) {
}
} else {
union {
void *dbr;
dbr_char_t *dbr_char;
dbr_long_t *dbr_long;
dbr_double_t *dbr_double;
char *dbr_string;
void *dbr;
} p;
} p = {0};
int i;
chtype type = best_type(pch);
@@ -699,12 +699,12 @@ void CA_put_callback(SV *ca_ref, SV *sub, SV *val, ...) {
}
} else {
union {
void *dbr;
dbr_char_t *dbr_char;
dbr_long_t *dbr_long;
dbr_double_t *dbr_double;
char *dbr_string;
void *dbr;
} p;
} p = {0};
int i;
chtype type = best_type(pch);

View File

@@ -16,8 +16,8 @@
use strict;
use FindBin qw($Bin);
use lib ("$Bin/../../lib/perl");
use FindBin qw($RealBin);
use lib ("$RealBin/../../lib/perl");
use Getopt::Std;
use EPICS::Path;
@@ -26,7 +26,7 @@ use CA;
######### Globals ##########
our ($opt_h, $opt_f, $opt_r);
our $opt_d = $ENV{EPICS_CAPR_DBD_FILE} || "$Bin/../../dbd/softIoc.dbd";
our $opt_d = $ENV{EPICS_CAPR_DBD_FILE} || "$RealBin/../../dbd/softIoc.dbd";
our $opt_w = 1;
my %record = (); # Empty hash to put dbd data in

View File

@@ -256,7 +256,7 @@ static int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
for (n = 0; n < nPvs; n++) {
switch (format) {
case plain: /* Emulate old caget behaviour */
case plain: /* Emulate old caget behavior */
if (pvs[n].nElems <= 1 && fieldSeparator == ' ') printf("%-30s", pvs[n].name);
else printf("%s", pvs[n].name);
printf("%c", fieldSeparator);

View File

@@ -192,7 +192,7 @@ int caget (pv *pvs, int nPvs, OutputT format,
for (n = 0; n < nPvs; n++) {
switch (format) {
case plain: /* Emulate old caput behaviour */
case plain: /* Emulate old caput behavior */
if (pvs[n].reqElems <= 1 && fieldSeparator == ' ') printf("%-30s", pvs[n].name);
else printf("%s", pvs[n].name);
printf("%c", fieldSeparator);

View File

@@ -11,5 +11,6 @@
# This is a Makefile fragment, see src/ioc/Makefile.
$(patsubst %,$(COMMON_DIR)/%,$(BPT_DBD)) : \
$(COMMON_DIR)/bpt%.dbd : $(MAKEBPT)
$(addprefix $(COMMON_DIR)/,$(BPT_DBD)) : $(COMMON_DIR)/bpt%.dbd : \
$(EPICS_BASE_HOST_BIN)/makeBpt$(HOSTEXE)
# Don't try to use $(MAKEBPT) above

View File

@@ -85,7 +85,7 @@ static epicsEventId startStopEvent;
static char *threadNamePrefix[NUM_CALLBACK_PRIORITIES] = {
"cbLow", "cbMedium", "cbHigh"
};
#define FULL_MSG(name) "callbackRequest: " name " ring buffer full\n"
#define FULL_MSG(name) "callbackRequest: " ERL_ERROR " " name " ring buffer full\n"
static char *fullMessage[NUM_CALLBACK_PRIORITIES] = {
FULL_MSG("cbLow"), FULL_MSG("cbMedium"), FULL_MSG("cbHigh")
};
@@ -263,7 +263,9 @@ void callbackCleanup(void)
assert(epicsAtomicGetIntT(&mySet->threadsRunning)==0);
epicsEventDestroy(mySet->semWakeUp);
mySet->semWakeUp = NULL;
epicsRingPointerDelete(mySet->queue);
mySet->queue = NULL;
}
epicsTimerQueueRelease(timerQueue);
@@ -324,15 +326,19 @@ int callbackRequest(epicsCallback *pcallback)
cbQueueSet *mySet;
if (!pcallback) {
epicsInterruptContextMessage("callbackRequest: pcallback was NULL\n");
epicsInterruptContextMessage("callbackRequest: " ERL_ERROR " pcallback was NULL\n");
return S_db_notInit;
}
priority = pcallback->priority;
if (priority < 0 || priority >= NUM_CALLBACK_PRIORITIES) {
epicsInterruptContextMessage("callbackRequest: Bad priority\n");
epicsInterruptContextMessage("callbackRequest: " ERL_ERROR " Bad priority\n");
return S_db_badChoice;
}
mySet = &callbackQueue[priority];
if (!mySet->queue) {
epicsInterruptContextMessage("callbackRequest: " ERL_ERROR " Callbacks not initialized\n");
return S_db_notInit;
}
if (mySet->queueOverflow) return S_db_bufFull;
pushOK = epicsRingPointerPush(mySet->queue, pcallback);

View File

@@ -529,7 +529,7 @@ long dbProcess(dbCommon *precord)
}
}
/* If already active dont process */
/* If already active don't process */
if (precord->pact) {
unsigned short monitor_mask;
@@ -931,7 +931,7 @@ long dbGet(DBADDR *paddr, short dbrType,
no_elements = capacity = pfl->no_elements;
}
/* Update field info from record (if neccessary);
/* Update field info from record (if necessary);
* may modify paddr->pfield.
*/
if (!dbfl_has_copy(pfl) &&
@@ -1104,9 +1104,9 @@ static long dbPutFieldLink(DBADDR *paddr,
if (link_info.ltype == PV_LINK &&
(link_info.modifiers & (pvlOptCA | pvlOptCP | pvlOptCPP)) == 0) {
chan = dbChannelCreate(link_info.target);
if (chan && dbChannelOpen(chan) != 0) {
errlogPrintf("ERROR: dbPutFieldLink %s.%s=%s: dbChannelOpen() failed\n",
precord->name, pfldDes->name, link_info.target);
if (chan && (status = dbChannelOpen(chan)) != 0) {
errlogPrintf(ERL_ERROR ": dbPutFieldLink %s.%s=%s: dbChannelOpen() failed w/ 0x%lx\n",
precord->name, pfldDes->name, link_info.target, status);
goto cleanup;
}
}
@@ -1325,7 +1325,6 @@ long dbPut(DBADDR *paddr, short dbrType,
void *pfieldsave = paddr->pfield;
rset *prset = dbGetRset(paddr);
long status = 0;
long offset;
dbFldDes *pfldDes;
int isValueField;
@@ -1349,20 +1348,25 @@ long dbPut(DBADDR *paddr, short dbrType,
if (status) return status;
}
if (paddr->pfldDes->special == SPC_DBADDR &&
prset && prset->get_array_info) {
long dummy;
if (nRequest>1 || paddr->pfldDes->special == SPC_DBADDR) {
long offset = 0;
if (paddr->pfldDes->special == SPC_DBADDR &&
prset && prset->get_array_info) {
long dummy;
status = prset->get_array_info(paddr, &dummy, &offset);
/* paddr->pfield may be modified */
if (status) goto done;
status = prset->get_array_info(paddr, &dummy, &offset);
/* paddr->pfield may be modified */
if (status) goto done;
}
if (no_elements < nRequest)
nRequest = no_elements;
status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer,
nRequest, no_elements, offset);
/* update array info */
if (!status && prset->put_array_info)
if (!status && paddr->pfldDes->special == SPC_DBADDR &&
prset && prset->put_array_info) {
status = prset->put_array_info(paddr, nRequest);
}
} else {
if (nRequest < 1) {
recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM);

View File

@@ -73,7 +73,7 @@ DBCORE_API extern int dbAccessDebugPUTF;
* options has a bit set for each option that was accepted
* number_elements is actual number of elements obtained
*
* The individual items can be refered to by the expressions::
* The individual items can be referred to by the expressions::
*
* buffer.status
* buffer.severity

View File

@@ -97,7 +97,7 @@ static long FIND_CONT_NODE(
* processing in that lockset to this task. The separate task is
* used so that locksets that do not have breakpoints are isolated
* from locksets that do. This allows the processing of other
* locksets to continue uninterupted, even if they exist on the same
* locksets to continue uninterrupted, even if they exist on the same
* scan list as a lockset containing a breakpoint.
*
* An entrypoint is the first record that gets processed in a lockset.
@@ -250,7 +250,7 @@ static long FIND_CONT_NODE(
}
/*
* Initialise the breakpoint stack
* Initialize the breakpoint stack
*/
void dbBkptInit(void)
{
@@ -331,6 +331,7 @@ long dbb(const char *record_name)
if (pnode->ex_sem == NULL) {
printf(" BKPT> Out of memory\n");
dbScanUnlock(precord);
free(pnode);
epicsMutexUnlock(bkpt_stack_sem);
return(1);
}

View File

@@ -196,6 +196,73 @@ static void caLinkDec(caLink *pca)
if (callback) callback(userPvt);
}
struct waitPvt {
caLink *pca;
epicsEventId evt;
};
enum testEvent {
testEventConnect,
testEventCount,
};
static
void testdbCaWaitForEventCB(void *raw)
{
struct waitPvt *pvt = raw;
epicsMutexMustLock(pvt->pca->lock);
epicsEventMustTrigger(pvt->evt);
epicsMutexUnlock(pvt->pca->lock);
}
static
void testdbCaWaitForEvent(DBLINK *plink, unsigned long cnt, enum testEvent event)
{
caLink *pca;
epicsEventId evt = epicsEventMustCreate(epicsEventEmpty);
dbScanLock(plink->precord);
assert(plink->type==CA_LINK);
pca = (caLink *)plink->value.pv_link.pvt;
epicsMutexMustLock(pca->lock);
assert(!pca->monitor && !pca->connect && !pca->userPvt);
while(!pca->isConnected || (event==testEventCount && pca->nUpdate < cnt)) {
struct waitPvt pvt = {pca, evt};
pca->connect = &testdbCaWaitForEventCB;
pca->monitor = &testdbCaWaitForEventCB;
pca->userPvt = &pvt;
epicsMutexUnlock(pca->lock);
dbScanUnlock(plink->precord);
epicsEventMustWait(evt);
dbScanLock(plink->precord);
epicsMutexMustLock(pca->lock);
pca->connect = NULL;
pca->monitor = NULL;
pca->userPvt = NULL;
}
epicsEventDestroy(evt);
epicsMutexUnlock(pca->lock);
dbScanUnlock(plink->precord);
}
void testdbCaWaitForConnect(DBLINK *plink)
{
testdbCaWaitForEvent(plink, 0, testEventConnect);
}
void testdbCaWaitForUpdateCount(DBLINK *plink, unsigned long cnt)
{
testdbCaWaitForEvent(plink, cnt, testEventCount);
}
/* Block until worker thread has processed all previously queued actions.
* Does not prevent additional actions from being queued.
*/
@@ -232,22 +299,6 @@ void dbCaSync(void)
epicsEventDestroy(wake);
}
DBCORE_API unsigned long dbCaGetUpdateCount(struct link *plink)
{
caLink *pca = (caLink *)plink->value.pv_link.pvt;
unsigned long ret;
if (!pca) return (unsigned long)-1;
epicsMutexMustLock(pca->lock);
ret = pca->nUpdate;
epicsMutexUnlock(pca->lock);
return ret;
}
void dbCaCallbackProcess(void *userPvt)
{
struct link *plink = (struct link *)userPvt;
@@ -785,6 +836,8 @@ static void connectionCallback(struct connection_handler_args arg)
caLink *pca;
short link_action = 0;
struct link *plink;
dbCaCallback connect = 0;
void *userPvt = 0;
pca = ca_puser(arg.chid);
assert(pca);
@@ -851,11 +904,16 @@ static void connectionCallback(struct connection_handler_args arg)
}
pca->gotAttributes = 0;
if (pca->dbrType != DBR_STRING) {
/* will run connect() callback later */
link_action |= CA_GET_ATTRIBUTES;
} else {
connect = pca->connect;
userPvt = pca->userPvt;
}
done:
if (link_action) addAction(pca, link_action);
epicsMutexUnlock(pca->lock);
if (connect) connect(userPvt);
}
static void eventCallback(struct event_handler_args arg)
@@ -881,10 +939,10 @@ static void eventCallback(struct event_handler_args arg)
if (precord) {
if (arg.status != ECA_NORDACCESS &&
arg.status != ECA_GETFAIL)
errlogPrintf("dbCa: eventCallback record %s error %s\n",
errlogPrintf("dbCa: eventCallback record %s " ERL_ERROR " %s\n",
precord->name, ca_message(arg.status));
} else {
errlogPrintf("dbCa: eventCallback error %s\n",
errlogPrintf("dbCa: eventCallback " ERL_ERROR " %s\n",
ca_message(arg.status));
}
goto done;
@@ -1029,10 +1087,10 @@ static void getAttribEventCallback(struct event_handler_args arg)
if (arg.status != ECA_NORMAL) {
dbCommon *precord = plink->precord;
if (precord) {
errlogPrintf("dbCa: getAttribEventCallback record %s error %s\n",
errlogPrintf("dbCa: getAttribEventCallback record %s " ERL_ERROR " %s\n",
precord->name, ca_message(arg.status));
} else {
errlogPrintf("dbCa: getAttribEventCallback error %s\n",
errlogPrintf("dbCa: getAttribEventCallback " ERL_ERROR " %s\n",
ca_message(arg.status));
}
epicsMutexUnlock(pca->lock);
@@ -1058,6 +1116,7 @@ static void getAttribEventCallback(struct event_handler_args arg)
static void dbCaTask(void *arg)
{
epicsEventId requestSync = NULL;
taskwdInsert(0, NULL, NULL);
SEVCHK(ca_context_create(ca_enable_preemptive_callback),
"dbCaTask calling ca_context_create");
@@ -1078,13 +1137,20 @@ static void dbCaTask(void *arg)
epicsMutexMustLock(workListLock);
if (!(pca = (caLink *)ellGet(&workList))){ /* Take off list head */
if(requestSync) {
/* dbCaSync() requires workListLock to be held here */
epicsEventMustTrigger(requestSync);
requestSync = NULL;
}
epicsMutexUnlock(workListLock);
if (dbCaCtl == ctlExit) goto shutdown;
break; /* workList is empty */
}
link_action = pca->link_action;
if (link_action&CA_SYNC)
epicsEventMustTrigger((epicsEventId)pca->userPvt); /* dbCaSync() requires workListLock to be held here */
if (link_action&CA_SYNC) {
assert(!requestSync);
requestSync = pca->userPvt;
}
pca->link_action = 0;
if (link_action & CA_CLEAR_CHANNEL) --removesOutstanding;
epicsMutexUnlock(workListLock); /* Give back immediately */

View File

@@ -48,8 +48,12 @@ DBCORE_API long dbCaPutLink(struct link *plink,short dbrType,
extern struct ca_client_context * dbCaClientContext;
#ifdef EPICS_DBCA_PRIVATE_API
/* Wait CA link work queue to become empty. eg. after from dbPut() to OUT */
DBCORE_API void dbCaSync(void);
DBCORE_API unsigned long dbCaGetUpdateCount(struct link *plink);
/* Wait for the data update counter to reach the specified value. */
DBCORE_API void testdbCaWaitForUpdateCount(DBLINK *plink, unsigned long cnt);
/* Wait for CA link to become connected */
DBCORE_API void testdbCaWaitForConnect(DBLINK *plink);
#endif
/* These macros are for backwards compatibility */

View File

@@ -77,12 +77,12 @@ A set of periodic scan intervals
=back
Additional periodic scan rates may be defined for individual IOCs by making a
local copy of menuScan.dbd and adding more choices as required. Scan rates
should normally be defined in order, with the fastest rates appearing first.
Scan periods may now be specified in seconds, minutes, hours or Hertz/Hz, and
plural time units will also be accepted (seconds are used if no unit is
mentioned in the choice string). For example the rates given below are all
valid:
local copy of menuScan.dbd and adding more choices as required. Periodic scan
rates should normally be defined in order following the other scan types, with
the longest periods appearing first. Scan periods can be specified with a unit
string of C<second>/C<seconds>, C<minute>/C<minutes>, C<hour>/C<hours> or
C<Hertz>/C<Hz>. Seconds are used if no unit is included in the choice string.
For example these rates are all valid:
1 hour
0.5 hours
@@ -97,7 +97,7 @@ initialization (before the normal scan tasks are started).
The B<PHAS> field orders the records within a specific SCAN group. This is not
meaningful for passive records. All records of a specified phase are processed
before those with higher phase number. Whenever possible it is better to use
before those with higher phase number. It is generally better practice to use
linked passive records to enforce the order of processing rather than a phase
number.
@@ -109,23 +109,23 @@ The call to post_event is: post_event(short event_number).
The B<PRIO> field specifies the scheduling priority for processing records
with SCAN=C<I/O Event> and asynchronous record completion tasks.
The B<DISV> field specifies a "disable value". Record processing is
immediately terminated if the value of this field is equal to the value of the
DISA field, i.e. the record is disabled. Note that field values of a record
can be changed by database put or Channel Access, even if a record is
The B<DISV> field specifies a "disable value". Record processing cannot
begin when the value of this field is equal to the value of the DISA
field, meaning the record is disabled. Note that field values of a record
can be changed by database or Channel Access puts, even if the record is
disabled.
The B<DISA> field contains the value that is compared with DISV to determine
if the record is disabled. The value of the DISA field is obtained via SDIS if
SDIS is a database or channel access link. If SDIS is not a database or
channel access link, then DISA can be set via dbPutField or dbPutLink.
If the B<PROC> field of a record is written to, the record is processed.
The B<DISA> field contains the value that is compared with DISV to determine if
the record is disabled. A value is obtained for the DISA field from the B<SDIS>
link field before the IOC tries to process the record. If SDIS is not set, DISA
may be set by some other method to enable and disable the record.
The B<DISS> field defines the record's "disable severity". If this field is
not NO_ALARM and the record is disabled, the record will be put into alarm
with this severity and a status of DISABLE_ALARM.
If the B<PROC> field of a record is written to, the record is processed.
The B<LSET> field contains the lock set to which this record belongs. All
records linked in any way via input, output, or forward database links belong
to the same lock set. Lock sets are determined at IOC initialization time, and
@@ -135,15 +135,18 @@ The B<LCNT> field counts the number of times dbProcess finds the record active
during successive scans, i.e. PACT is TRUE. If dbProcess finds the record
active MAX_LOCK times (currently set to 10) it raises a SCAN_ALARM.
The B<PACT> field is TRUE while the record is being processed. For
The B<PACT> field is TRUE while the record is active (being processed). For
asynchronous records PACT can be TRUE from the time record processing is
started until the asynchronous completion occurs. As long as PACT is TRUE,
dbProcess will not call the record processing routine. See Application
Developers Guide for details on usage of PACT.
The B<FLNK> field is a database link to another record (the "target" record).
Processing a record with a specified FLNK field will force processing of the
target record, provided the target record's SCAN field is set to C<Passive>.
The B<FLNK> field is a link pointing to another record (the "target" record).
Processing a record with the FLNK field set will trigger processing of the
target record towards the end of processing the first record (but before PACT is
cleared), provided the target record's SCAN field is set to C<Passive>. If the
FLNK field is a Channel Access link it must point to the PROC field of the
target record.
The B<SPVT> field is for internal use by the scanning system.
@@ -227,6 +230,8 @@ The B<SPVT> field is for internal use by the scanning system.
}
field(DISP,DBF_UCHAR) {
prompt("Disable putField")
promptgroup("10 - Common")
interest(1)
}
field(PROC,DBF_UCHAR) {
prompt("Force Processing")
@@ -236,35 +241,46 @@ The B<SPVT> field is for internal use by the scanning system.
=head3 Alarm Fields
These fields indicate the status and severity of alarms, or else determine the
Alarm fields indicate the status and severity of record alarms, or determine
how and when alarms are triggered. Of course, many records have alarm-related
fields not common to all records. These fields are listed and explained in the
fields not common to all records. Those fields are listed and explained in the
appropriate section on each record.
The B<STAT> field contains the current alarm status.
The B<SEVR> field contains the current alarm severity.
These two fields are seen outside database access. The B<NSTA> and B<NSEV>
fields are used by the database access, record support, and device support
routines to set new alarm status and severity values. Whenever any software
component discovers an alarm condition, it uses the following macro function:
recGblSetSevr(precord,new_status,new_severity) This ensures that the current
alarm severity is set equal to the highest outstanding alarm. The file alarm.h
defines all allowed alarm status and severity values.
The B<AMSG> string field may contain more detailed information about the alarm.
The STAT, SEVR and AMSG fields hold alarm information as seen outside of the
database. The B<NSTA>, B<NSEV> and B<NAMSG> fields are used during record
processing by the database access, record support, and device support routines
to set new alarm status and severity values and message text. Whenever any
software component discovers an alarm condition, it calls one of these routines
to register the alarm:
recGblSetSevr(precord, new_status, new_severity);
recGblSetSevrMsg(precord, new_status, new_severity, "Message", ...);
These check the current alarm severity and update the NSTA, NSEV and NAMSG
fields if appropriate so they always relate to the highest severity alarm seen
so far during record processing. The file alarm.h defines the allowed alarm
status and severity values. Towards the end of record processing these fields
are copied into the STAT, SEVR and AMSG fields and alarm monitors triggered.
The B<ACKS> field contains the highest unacknowledged alarm severity.
The B<ACKT> field specifies if it is necessary to acknowledge transient
The B<ACKT> field specifies whether it is necessary to acknowledge transient
alarms.
The B<UDF> indicates if the record's value is B<U>nB<D>eB<F>ined. Typically
this is caused by a failure in device support, the fact that the record has
never been processed, or that the VAL field currently contains a NaN (not a
number). UDF is initialized to TRUE at IOC initialization. Record and device
support routines which write to the VAL field are responsible for setting UDF.
The B<UDF> indicates if the record's value is B<U>nB<D>eB<F>ined. Typically this
is caused by a failure in device support, the fact that the record has never
been processed, or that the VAL field currently contains a NaN (not a number) or
Inf (Infinite) value. UDF defaults to TRUE but can be set in a database file.
Record and device support routines which write to the VAL field are generally
responsible for setting and clearing UDF.
=fields STAT, SEVR, NSTA, NSEV, ACKS, ACKT, UDF
=fields STAT, SEVR, AMSG, NSTA, NSEV, NAMSG, ACKS, ACKT, UDF
=cut
@@ -422,9 +438,11 @@ The B<DPVT> field is is for private use of the device support modules.
=head3 Debugging Fields
The B<TPRO> field is used for trace processing. If this field is non-zero a
message is printed whenever this record is processed, and when any other
record in the same lock-set is processed by a database link from this record.
The B<TPRO> field can be used to trace record processing. When this field is
non-zero and the record is processed, a trace message will be be printed for
this record and any other record in the same lock-set that is triggered by a
database link from this record. The trace message includes the name of the
thread doing the processing, and the name of the record being processed.
The B<BKPT> field indicates if there is a breakpoint set at this record. This
supports setting a debug breakpoint in the record processing. STEP through
@@ -435,32 +453,27 @@ database processing can be supported using this.
=head3 Miscellaneous Fields
The B<ASG> field contains a character string value defining the access
security group for this record. If left empty, the record is placed in group
DEFAULT.
The B<ASG> string field sets the name of the access security group used for this
record. If left empty, the record is placed in group C<DEFAULT>.
The B<ASP> field is a field for private use of the access security system.
The B<ASP> field is private for use by the access security system.
The B<DISP> field controls dbPutFields to this record which are normally
issued by channel access. If the field is set to TRUE all dbPutFields
directed to this record are ignored except to the field DISP itself.
The B<DISP> field can be set to a non-zero value to reject puts from outside of
the IOC (i.e. via Channel Access or PV Access) to any field of the record other
than to the DISP field itself. Field changes and record processing can still be
instigated from inside the IOC using DB links and the IOC scan mechanisms.
The B<DTYP> field specifies the device type for the record. Each record type
has its own set of device support routines which are specified in
devSup.ASCII. If a record type does not have any associated device support,
DTYP and DSET are meaningless.
The B<DTYP> field specifies the device type for the record. Most record types
have their own set of device types which are specified in the IOC's database
definition file. If a record type does not call any device support routines,
the DTYP and DSET fields are not used.
The B<MLOK> field contains the monitor lock. The lock used by the monitor
routines when the monitor list is being used. The list is locked whenever
monitors are being scheduled, invoked, or when monitors are being added to or
removed from the list. This field is accessed only by the dbEvent routines.
The B<MLOK> field contains a mutex which is locked by the monitor routines in
dbEvent.c whenever the monitor list for this record is accessed.
The B<MLIS> field is the head of the list of monitors connected to this
The B<MLIS> field holds a linked list of client monitors connected to this
record. Each record support module is responsible for triggering monitors for
any fields that change as a result of record processing. Monitors are present
if mlis count is greater than zero. The call to trigger monitors is:
db_post_event(precord,&data,mask), where "mask" is some combination of
DBE_ALARM, DBE_VALUE, and DBE_LOG.
any fields that change as a result of record processing.
The B<PPN> field contains the address of a putNotify callback.
@@ -474,23 +487,44 @@ The B<RDES> field contains the address of dbRecordType
The B<RPRO> field specifies a reprocessing of the record when current
processing completes.
The B<TIME> field contains the time when this record was last processed in
standard format.
The B<TIME> field holds the time stamp when this record was last processed.
The B<TSE> field indicates the mechanism to use to get the time stamp. '0' -
call get time as before '-1' - call the time stamp driver and use the best
source available. '-2' - the device support provides the time stamp from the
hardware. Values between 1-255 request the time of the last occurance of a
generalTime event.
The B<UTAG> field can be used to hold a site-specific 64-bit User Tag value
that is associated with the record's time stamp.
The B<TSE> field value indicates the mechanism to use to get the time stamp:
=over
=item *
C< 0> E<mdash> Get the current time as normal
=item *
C<-1> E<mdash> Ask the time stamp driver for its best source of the current time, if
available.
=item *
C<-2> E<mdash> Device support sets the time stamp and the optional User Tag from the
hardware.
=item *
Positive values (normally between 1-255) get the time of the last occurance of
the numbered generalTime event.
=back
The B<TSEL> field contains an input link for obtaining the time stamp. If this
link references the .TIME field of a record then the time stamp of the
referenced record becomes the time stamp for this record as well. In this
case, an internal flag is set and ".TIME" is then overwritten by ".VAL". If
any other field is referenced, the field value is read and stored in the .TSE
field which is then used to acquire a timestamp.
link points to the TIME field of a record then the time stamp and User Tag of
that record are copied directly into this record (Channel Access links can only
copy the time stamp, not the User Tag). If the link points to any other field,
that field's value is read and stored in the TSE field which is then used to
provide the time stamp as described above.
=fields ASG, ASP, DISP, DTYP, MLOK, MLIS, PPN, PPNR, PUTF, RDES, RPRO, TIME, TSE, TSEL
=fields ASG, ASP, DISP, DTYP, MLOK, MLIS, PPN, PPNR, PUTF, RDES, RPRO, TIME, UTAG, TSE, TSEL
=cut

View File

@@ -63,7 +63,7 @@ cvt_st_ ## TYPE(const char *from, void *pfield, const dbAddr *paddr) { \
return epicsParse##TYPE(from, to, 0, &end); \
}
/* Instanciate for CHAR, UCHAR, SHORT, USHORT and LONG */
/* Instantiate for CHAR, UCHAR, SHORT, USHORT and LONG */
cvt_st_int(Int8)
cvt_st_int(UInt8)
cvt_st_int(Int16)
@@ -99,7 +99,7 @@ static long cvt_st_UInt32(const char *from, void *pfield, const dbAddr *paddr)
return status;
}
/* Instanciate for INT64 and UINT64 */
/* Instantiate for INT64 and UINT64 */
cvt_st_int(Int64)
cvt_st_int(UInt64)
@@ -117,7 +117,7 @@ cvt_st_ ## TYPE(const char *from, void *pfield, const dbAddr *paddr) { \
return epicsParse##TYPE(from, to, &end); \
}
/* Instanciate for FLOAT32 and FLOAT64 */
/* Instantiate for FLOAT32 and FLOAT64 */
cvt_st_float(Float32)
cvt_st_float(Float64)

View File

@@ -9,7 +9,7 @@
\*************************************************************************/
/*
* Auther Jeff Hill
* Author Jeff Hill
*/
#include <stdlib.h>

View File

@@ -98,7 +98,7 @@ static int dblsj_string(void *ctx, const unsigned char *val, size_t len) {
char *pdest = parser->pdest;
if (parser->dbrType != DBF_STRING) {
errlogPrintf("dbConvertJSON: dblsj_string dbrType error\n");
errlogPrintf("dbConvertJSON: dblsj_string dbrType " ERL_ERROR "\n");
return 0; /* Illegal */
}

View File

@@ -16,7 +16,7 @@
extern "C" {
#endif
/* This name should probably be changed to inclue "array" */
/* This name should probably be changed to include "array" */
DBCORE_API long dbPutConvertJSON(const char *json, short dbrType,
void *pdest, long *psize);
DBCORE_API long dbLSConvertJSON(const char *json, char *pdest,

View File

@@ -188,8 +188,11 @@ static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer,
&& dbChannelSpecial(chan) != SPC_ATTRIBUTE
&& ellCount(&chan->filters) == 0)
{
/* simple scalar: set up shortcut */
unsigned short dbfType = dbChannelFinalFieldType(chan);
/* Simple scalar w/o filters, so *Final* type has no additional information.
* Needed to correctly handle DBF_MENU fields, which become DBF_ENUM during
* probe of dbChannelOpen().
*/
unsigned short dbfType = dbChannelFieldType(chan);
if (dbrType < 0 || dbrType > DBR_ENUM || dbfType > DBF_DEVICE)
return S_db_badDbrtype;

View File

@@ -84,12 +84,13 @@ struct event_user {
epicsMutexId lock;
epicsEventId ppendsem; /* Wait while empty */
epicsEventId pflush_sem; /* wait for flush */
epicsEventId pexitsem; /* wait for event task to join */
EXTRALABORFUNC *extralabor_sub;/* off load to event task */
void *extralabor_arg;/* parameter to above */
epicsThreadId taskid; /* event handler task id */
struct evSubscrip *pSuicideEvent; /* event that is deleteing itself */
struct evSubscrip *pSuicideEvent; /* event that is deleting itself */
unsigned queovr; /* event que overflow count */
unsigned char pendexit; /* exit pend task */
unsigned char extra_labor; /* if set call extra labor func */
@@ -101,7 +102,7 @@ struct event_user {
/*
* Reliable intertask communication requires copying the current value of the
* channel for later queing so 3 stepper motor steps of 10 each do not turn
* channel for later queuing so 3 stepper motor steps of 10 each do not turn
* into only 10 or 20 total steps part of the time.
*/
@@ -122,6 +123,8 @@ static char *EVENT_PEND_NAME = "eventTask";
static struct evSubscrip canceledEvent;
static epicsMutexId stopSync;
static unsigned short ringSpace ( const struct event_que *pevq )
{
if ( pevq->evque[pevq->putix] == EVENTQEMPTY ) {
@@ -260,6 +263,10 @@ int dbel ( const char *pname, unsigned level )
*/
void db_init_event_freelists (void)
{
if (!stopSync) {
stopSync = epicsMutexMustCreate();
}
if (!dbevEventUserFreeList) {
freeListInitPvt(&dbevEventUserFreeList,
sizeof(struct event_user),8);
@@ -299,6 +306,9 @@ dbEventCtx db_init_events (void)
return NULL;
}
/* Flag will be cleared when event task starts */
evUser->pendexit = TRUE;
evUser->firstque.evUser = evUser;
evUser->firstque.writelock = epicsMutexCreate();
if (!evUser->firstque.writelock)
@@ -313,6 +323,9 @@ dbEventCtx db_init_events (void)
evUser->lock = epicsMutexCreate();
if (!evUser->lock)
goto fail;
evUser->pexitsem = epicsEventCreate(epicsEventEmpty);
if (!evUser->pexitsem)
goto fail;
evUser->flowCtrlMode = FALSE;
evUser->extraLaborBusy = FALSE;
@@ -327,6 +340,8 @@ fail:
epicsEventDestroy (evUser->ppendsem);
if(evUser->pflush_sem)
epicsEventDestroy (evUser->pflush_sem);
if(evUser->pexitsem)
epicsEventDestroy (evUser->pexitsem);
freeListFree(dbevEventUserFreeList,evUser);
return NULL;
}
@@ -347,6 +362,7 @@ DBCORE_API void db_cleanup_events(void)
dbevFieldLogFreeList = NULL;
}
/* intentionally leak stopSync to avoid possible shutdown races */
/*
* DB_CLOSE_EVENTS()
*
@@ -368,15 +384,31 @@ void db_close_events (dbEventCtx ctx)
* hazardous to the system's health.
*/
epicsMutexMustLock ( evUser->lock );
evUser->pendexit = TRUE;
if(!evUser->pendexit) { /* event task running */
evUser->pendexit = TRUE;
epicsMutexUnlock ( evUser->lock );
/* notify the waiting task */
epicsEventSignal(evUser->ppendsem);
/* wait for task to exit */
epicsEventMustWait(evUser->pexitsem);
epicsThreadMustJoin(evUser->taskid);
epicsMutexMustLock ( evUser->lock );
}
epicsMutexUnlock ( evUser->lock );
/* notify the waiting task */
epicsEventSignal(evUser->ppendsem);
epicsMutexMustLock (stopSync);
if(evUser->taskid)
epicsThreadMustJoin(evUser->taskid);
/* evUser has been deleted by the worker */
epicsEventDestroy(evUser->pexitsem);
epicsEventDestroy(evUser->ppendsem);
epicsEventDestroy(evUser->pflush_sem);
epicsMutexDestroy(evUser->lock);
epicsMutexUnlock (stopSync);
freeListFree(dbevEventUserFreeList, evUser);
}
/*
@@ -553,7 +585,7 @@ void db_cancel_event (dbEventSubscription event)
/*
* flag the event as canceled by NULLing out the callback handler
*
* make certain that the event isnt being accessed while
* make certain that the event isn't being accessed while
* its call back changes
*/
LOCKEVQUE (pevent->ev_que);
@@ -779,7 +811,7 @@ static void db_queue_event_log (evSubscrip *pevent, db_field_log *pLog)
pevent->nreplace++;
/*
* the event task has already been notified about
* this so we dont need to post the semaphore
* this so we don't need to post the semaphore
*/
firstEventFlag = 0;
}
@@ -812,7 +844,7 @@ static void db_queue_event_log (evSubscrip *pevent, db_field_log *pLog)
UNLOCKEVQUE (ev_que);
/*
* its more efficent to notify the event handler
* its more efficient to notify the event handler
* only after the event is ready and the lock
* is off in case it runs at a higher priority
* than the caller here.
@@ -854,6 +886,8 @@ unsigned int caEventMask
if ( (dbChannelField(pevent->chan) == (void *)pField || pField==NULL) &&
(caEventMask & pevent->select)) {
db_field_log *pLog = db_create_event_log(pevent);
if(pLog)
pLog->mask = caEventMask & pevent->select;
pLog = dbChannelRunPreChain(pevent->chan, pLog);
if (pLog) db_queue_event_log(pevent, pLog);
}
@@ -942,7 +976,7 @@ static int event_read ( struct event_que *ev_que )
* Next event pointer can be used by event tasks to determine
* if more events are waiting in the queue
*
* Must remove the lock here so that we dont deadlock if
* Must remove the lock here so that we don't deadlock if
* this calls dbGetField() and blocks on the record lock,
* dbPutField() is in progress in another task, it has the
* record lock, and it is calling db_post_events() waiting
@@ -1063,18 +1097,17 @@ static void event_task (void *pParm)
}
}
epicsEventDestroy(evUser->ppendsem);
epicsEventDestroy(evUser->pflush_sem);
epicsMutexDestroy(evUser->lock);
if (dbevEventUserFreeList)
freeListFree(dbevEventUserFreeList, evUser);
else
fprintf(stderr, "%s exiting but dbevEventUserFreeList already NULL\n",
__FUNCTION__);
taskwdRemove(epicsThreadGetIdSelf());
/* use stopSync to ensure pexitsem is not destroy'd
* until epicsEventSignal() has returned.
*/
epicsMutexMustLock (stopSync);
epicsEventSignal(evUser->pexitsem);
epicsMutexUnlock(stopSync);
return;
}
@@ -1114,6 +1147,7 @@ int db_start_events (
epicsMutexUnlock ( evUser->lock );
return DB_EVENT_ERROR;
}
evUser->pendexit = FALSE;
epicsMutexUnlock ( evUser->lock );
return DB_EVENT_OK;
}
@@ -1142,9 +1176,6 @@ void db_event_flow_ctrl_mode_on (dbEventCtx ctx)
* notify the event handler task
*/
epicsEventSignal(evUser->ppendsem);
#ifdef DEBUG
printf("fc on %lu\n", tickGet());
#endif
}
/*
@@ -1161,9 +1192,6 @@ void db_event_flow_ctrl_mode_off (dbEventCtx ctx)
* notify the event handler task
*/
epicsEventSignal (evUser->ppendsem);
#ifdef DEBUG
printf("fc off %lu\n", tickGet());
#endif
}
/*

View File

@@ -234,7 +234,7 @@ static const iocshArg dbtgfArg0 = { "record name",iocshArgString};
static const iocshArg * const dbtgfArgs[1] = {&dbtgfArg0};
static const iocshFuncDef dbtgfFuncDef = {"dbtgf",1,dbtgfArgs,
"Database Test Get Field.\n"
"Get field with different DBR_* types"};
"Get field with different DBR_* types\n"};
static void dbtgfCallFunc(const iocshArgBuf *args) { dbtgf(args[0].sval);}
/* dbtpf */
@@ -283,7 +283,7 @@ static const iocshArg * const dbtpnArgs[2] = {&dbtpnArg0,&dbtpnArg1};
static const iocshFuncDef dbtpnFuncDef = {"dbtpn",2,dbtpnArgs,
"Database Put Notify\n"
"Without value, begin async. processing and get\n"
"With value, begin put, process, and get"};
"With value, begin put, process, and get\n"};
static void dbtpnCallFunc(const iocshArgBuf *args)
{ dbtpn(args[0].sval,args[1].sval);}

View File

@@ -371,7 +371,7 @@ typedef struct lset {
* Implementations must write a trailing nil to msgbuf whenever
* @code msgbuf!=NULL && msgbuflen>0 @endcode .
*
* @since UNRELEASED
* @since 7.0.6
*/
long (*getAlarmMsg)(const struct link *plink, epicsEnum16 *status,
epicsEnum16 *severity, char *msgbuf, size_t msgbuflen);
@@ -381,7 +381,7 @@ typedef struct lset {
* Equivalent of getTimeStamp() and also copy out time tag.
* ptag may be NULL.
*
* @since Added after UNRELEASED
* @since Added after 7.0.6
*/
long (*getTimeStampTag)(const struct link *plink, epicsTimeStamp *pstamp, epicsUTag *ptag);
} lset;
@@ -428,14 +428,14 @@ DBCORE_API long dbGetAlarm(const struct link *plink, epicsEnum16 *status,
/** Get link alarm and message string.
* To ensure the complete message string is copied, ensure @code msgbuflen >= sizeof (dbCommon::amsg) @endcode .
* A trailing nil will be added whenever @code msgbuflen > 0 @endcode .
* @since UNRELEASED
* @since 7.0.6
*/
DBCORE_API long dbGetAlarmMsg(const struct link *plink, epicsEnum16 *status,
epicsEnum16 *severity, char *msgbuf, size_t msgbuflen);
#define dbGetAlarmMsg(LINK, STAT, SEVR, BUF, BUFLEN) dbGetAlarmMsg(LINK, STAT, SEVR, BUF, BUFLEN)
DBCORE_API long dbGetTimeStamp(const struct link *plink,
epicsTimeStamp *pstamp);
/** @since UNRELEASED */
/** @since 7.0.6 */
DBCORE_API long dbGetTimeStampTag(const struct link *plink,
epicsTimeStamp *pstamp, epicsUTag *ptag);
#define dbGetTimeStampTag(LINK, STAMP, TAG) dbGetTimeStampTag(LINK, STAMP, TAG)

View File

@@ -613,8 +613,10 @@ long dbtpn(char *pname, char *pvalue)
ptpnInfo = dbCalloc(1, sizeof(tpnInfo));
ptpnInfo->ppn = ppn;
ptpnInfo->callbackDone = epicsEventCreate(epicsEventEmpty);
strncpy(ptpnInfo->buffer, pvalue, 80);
ptpnInfo->buffer[79] = 0;
if (pvalue) {
strncpy(ptpnInfo->buffer, pvalue, sizeof(ptpnInfo->buffer));
ptpnInfo->buffer[sizeof(ptpnInfo->buffer)-1] = 0;
}
ppn->usrPvt = ptpnInfo;
epicsThreadCreate("dbtpn", epicsThreadPriorityHigh,

View File

@@ -130,7 +130,7 @@ DBCORE_API int dbNotifyDump(void);
* if a process request is issued and also calls the client callbacks.
*
* A process request is issued if any of the following is true.
* 1) The requester has issued a processs request and record is passive.
* 1) The requester has issued a process request and record is passive.
* 2) The requester is doing a put, the record is passive, and either
* a) The field description is process passive.
* b) The field is PROC.
@@ -156,7 +156,7 @@ DBCORE_API int dbNotifyDump(void);
* As soon as a record completes processing the field is set NULL
* ppnr pointer to processNotifyRecord, which is a private structure
* owned by dbNotify.
* dbNotify is reponsible for this structure.
* dbNotify is responsible for this structure.
*
*/
#ifdef __cplusplus

View File

@@ -110,7 +110,7 @@ extern "C" void putNotifyCompletion ( processNotify *ppn )
if ( pNtfy ) {
pBlocker->pNotify = 0;
// Its necessary to signal the initiators now before we call
// the user callback. This is less efficent, and potentially
// the user callback. This is less efficient, and potentially
// causes more thread context switching, but its probably
// unavoidable because its possible that the use callback
// might destroy this object.

View File

@@ -817,7 +817,7 @@ static void periodicTask(void *arg)
epicsTimeAddSeconds(&next, delay);
if (++overruns >= 10 &&
epicsTimeDiffInSeconds(&now, &reported) > report_delay) {
errlogPrintf("\ndbScan warning from '%s' scan thread:\n"
errlogPrintf("\ndbScan " ERL_WARNING " from '%s' scan thread:\n"
"\tScan processing averages %.3f seconds (%.3f .. %.3f).\n"
"\tOver-runs have now happened %u times in a row.\n"
"\tTo fix this, move some records to a slower scan rate.\n",

View File

@@ -1300,7 +1300,7 @@ static void dbpr_insert_msg(TAB_BUFFER *pMsgBuff,size_t len,int tab_size)
current_len = strlen(pMsgBuff->out_buff);
tot_line = current_len + len;
/* flush buffer if overflow would occor */
/* flush buffer if overflow would occur */
if (tot_line > MAXLINE)
dbpr_msg_flush(pMsgBuff, tab_size);

View File

@@ -266,7 +266,7 @@ done:
void testdbPutArrFieldOk(const char* pv, short dbrType, unsigned long count, const void *pbuf)
{
dbChannel *chan = dbChannelCreate(pv);
long status;
long status = -1;
if(!chan || (status=dbChannelOpen(chan))) {
testFail("Channel error (%p, %ld) : %s", chan, status, pv);
@@ -289,7 +289,7 @@ void testdbGetArrFieldEqual(const char* pv, short dbfType, long nRequest, unsign
const long vSize = dbValueSize(dbfType);
const long nStore = vSize * nRequest;
long status = S_dbLib_recNotFound;
char *gbuf, *gstore;
char *gbuf, *gstore = NULL;
const char *pbuf = pbufraw;
if(!chan || (status=dbChannelOpen(chan))) {

View File

@@ -7,7 +7,7 @@
\*************************************************************************/
/** @file dbUnitTest.h
* @brief Helpers for unitests of process database
* @brief Helpers for unittests of process database
* @author Michael Davidsaver, Ralph Lange
*
* @see @ref dbunittest
@@ -99,7 +99,7 @@ DBCORE_API void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap);
/** Assert that a dbPutField() array operation will complete successfully.
*
* @param pv a PV name, possibly including filter expression
* @param a DBF_\* type code (cf. dbfType in dbFldTypes.h)
* @param dbrType a DBF_\* type code (cf. dbfType in dbFldTypes.h)
* @param count Number of elements in pbuf array
* @param pbuf Array of values to write
*
@@ -114,7 +114,7 @@ DBCORE_API void testdbPutArrFieldOk(const char* pv, short dbrType, unsigned long
/**
* @param pv PV name string
* @param dbfType One of the DBF_* macros from dbAccess.h
* @param dbfType One of the DBF_\* macros from dbAccess.h
* @param nRequest Number of elements to request from pv
* @param pbufcnt Number of elements pointed to be pbuf
* @param pbuf Expected value buffer
@@ -149,7 +149,7 @@ DBCORE_API void testMonitorDestroy(testMonitor*);
*/
DBCORE_API void testMonitorWait(testMonitor*);
/** Return the number of monitor events which have occured since create,
* or a pervious reset (called reset=1).
* or a previous reset (called reset=1).
* Calling w/ reset=0 only returns the count.
* Calling w/ reset=1 resets the count to zero and ensures that the next
* wait will block unless subsequent events occur. Returns the previous

View File

@@ -27,7 +27,7 @@ DBCORE_API extern volatile int interruptAccept;
/*
* Adaptors for db_access users
* Adapters for db_access users
*/
DBCORE_API struct dbChannel * dbChannel_create(const char *pname);
DBCORE_API int dbChannel_get(struct dbChannel *chan,

View File

@@ -318,7 +318,7 @@ void recGblGetTimeStampSimm(void *pvoid, const epicsEnum16 simm, struct link *si
} else {
if (simm != menuSimmNO) {
if (siol && !dbLinkIsConstant(siol)) {
if (dbGetTimeStamp(siol, &prec->time))
if (dbGetTimeStampTag(siol, &prec->time, &prec->utag))
errlogPrintf("recGblGetTimeStampSimm: dbGetTimeStamp (sim mode) failed, %s.SIOL = %s\n",
prec->name, siol->value.pv_link.pvname);
return;

View File

@@ -29,7 +29,7 @@ extern "C" {
*
* Covers addition of dbCommon::amsg, recGblSetSevrMsg(), lset::getAlarmMsg()
*
* @since UNRELEASED
* @since 7.0.6
*/
#define HAS_ALARM_MESSAGE 1

View File

@@ -101,10 +101,6 @@ static int yyreset(void)
")" return(yytext[0]);
"," return(yytext[0]);
{doublequote}({stringchar}|{escape})*{newline} { /* bad string */
yyerrorAbort("Newline in string, closing quote missing");
}
<JSON>"null" return jsonNULL;
<JSON>"true" return jsonTRUE;
<JSON>"false" return jsonFALSE;
@@ -130,6 +126,20 @@ static int yyreset(void)
<INITIAL,JSON>{whitespace} ;
/* Error patterns */
{doublequote}({stringchar}|{escape})*{newline} {
yyerrorAbort("Newline in string, closing quote missing");
}
<JSON>{doublequote}({stringchar}|{escape})*{doublequote} {
yyerrorAbort("Bad character in JSON string");
}
<JSON>{singlequote}({stringchar}|{escape})*{singlequote} {
yyerrorAbort("Bad character in JSON string");
}
<INITIAL,JSON>. {
char message[40];
YY_BUFFER_STATE *dummy=0;

View File

@@ -37,7 +37,11 @@
#include "special.h"
#include "iocInit.h"
/* This file is included from dbYacc.y
* Duplicate some declarations to avoid warnings from analysis tools which don't know about this.
*/
static int yyerror(char *str);
static long pvt_yy_parse(void);
/*global declarations*/
char *makeDbdDepends=0;
@@ -99,8 +103,8 @@ static char *my_buffer_ptr=NULL;
static MAC_HANDLE *macHandle = NULL;
typedef struct inputFile{
ELLNODE node;
char *path;
char *filename;
const char *path;
const char *filename;
FILE *fp;
int line_num;
}inputFile;
@@ -155,7 +159,7 @@ static void *getLastTemp(void)
return(ptempListNode->item);
}
static char *dbOpenFile(DBBASE *pdbbase,const char *filename,FILE **fp)
const char *dbOpenFile(DBBASE *pdbbase,const char *filename,FILE **fp)
{
ELLLIST *ppathList = (ELLLIST *)pdbbase->pathPvt;
dbPathNode *pdbPathNode;
@@ -223,8 +227,10 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
epicsPrintf("dbReadCOM: Parser stack dirty %d\n", ellCount(&tempList));
}
if (getIocState() != iocVoid)
return -2;
if (getIocState() != iocVoid) {
status = -2;
goto cleanup;
}
if(*ppdbbase == 0) *ppdbbase = dbAllocBase();
pdbbase = *ppdbbase;
@@ -269,7 +275,7 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
if (!pinputFile->filename || !fp1) {
errPrintf(0, __FILE__, __LINE__,
"dbRead opening file %s",pinputFile->filename);
free(pinputFile->filename);
free((char*)pinputFile->filename);
free(pinputFile);
status = -1;
goto cleanup;
@@ -277,6 +283,7 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
pinputFile->fp = fp1;
} else {
pinputFile->fp = fp;
fp = NULL;
}
pinputFile->line_num = 0;
pinputFileNow = pinputFile;
@@ -332,6 +339,8 @@ cleanup:
if(my_buffer) free((void *)my_buffer);
my_buffer = NULL;
freeInputFileList();
if(fp)
fclose(fp);
return(status);
}
@@ -1063,7 +1072,7 @@ int dbRecordNameValidate(const char *name)
}
for(; *pos; i++, pos++) {
char c = *pos;
unsigned char c = *pos;
if(i==0) {
/* first character restrictions */
if(c=='-' || c=='+' || c=='[' || c=='{') {
@@ -1072,8 +1081,8 @@ int dbRecordNameValidate(const char *name)
}
/* any character restrictions */
if(c < ' ') {
errlogPrintf("Warning: Record/Alias name '%s' should not contain non-printable 0x%02u\n",
name, (unsigned)c);
errlogPrintf("Warning: Record/Alias name '%s' should not contain non-printable 0x%02x\n",
name, c);
} else if(c==' ' || c=='\t' || c=='"' || c=='\'' || c=='.' || c=='$') {
epicsPrintf("Error: Bad character '%c' in Record/Alias name \"%s\"\n",

View File

@@ -441,6 +441,9 @@ void dbFreeBase(dbBase *pdbbase)
DBENTRY dbentry;
long status;
if(!pdbbase)
return;
dbInitEntry(pdbbase,&dbentry);
status = dbFirstRecordType(&dbentry);
while(!status) {
@@ -677,7 +680,7 @@ long dbAddPath(DBBASE *pdbbase,const char *path)
if (!path) return(0); /* Empty path strings are ignored */
/* care is taken to properly deal with white space
* 1) preceding and trailing white space is removed from paths
* 2) white space inbetween path separator counts as an empty name
* 2) white space in between path separator counts as an empty name
* (see below)
*/
expectingPath = FALSE;
@@ -710,8 +713,8 @@ long dbAddPath(DBBASE *pdbbase,const char *path)
/*
* len is always nonzero because we found something that
* 1) isnt white space
* 2) isnt a path separator
* 1) isn't white space
* 2) isn't a path separator
*/
len = (plast - path) + 1;
if (dbAddOnePath (pdbbase, path, (unsigned) len)) return (-1);
@@ -722,7 +725,7 @@ long dbAddPath(DBBASE *pdbbase,const char *path)
}
/*
* an empty name at beginning, middle, or end of a path string that isnt
* an empty name at beginning, middle, or end of a path string that isn't
* empty means current directory
*/
if (expectingPath||sawMissingPath) {
@@ -2274,8 +2277,8 @@ long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
len -= (parm - pstr);
}
/* generalized extraction of ID charactor and integer pairs (eg. "#C15 S14") */
ret = sscanf(pinfo->target, "# %c%d %c%d %c%d %c%d %c%d %c",
/* generalized extraction of ID character and integer pairs (eg. "#C15 S14") */
ret = sscanf(pinfo->target, "# %c%i %c%i %c%i %c%i %c%i %c",
&pinfo->hwid[0], &pinfo->hwnums[0],
&pinfo->hwid[1], &pinfo->hwnums[1],
&pinfo->hwid[2], &pinfo->hwnums[2],
@@ -2333,11 +2336,11 @@ long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
}
pinfo->ltype = PV_LINK;
pstr = strchr(pstr, ' '); /* find start of link modifiers (can't be seperated by tabs) */
pstr = strchr(pstr, ' '); /* find start of link modifiers (can't be separated by tabs) */
if (pstr) {
*pstr++ = '\0'; /* isolate modifiers. pinfo->target is PV name only for re-use in struct pv_link */
/* Space seperation of modifiers isn't required, and other chars are ignored.
/* Space separation of modifiers isn't required, and other chars are ignored.
* Order of comparisons resolves ambiguity by checking for
* longer matches first.
* eg. "QQCPPXMSITT" is pvlOptCPP|pvlOptMSI

View File

@@ -57,8 +57,26 @@ DBCORE_API void dbCopyEntryContents(DBENTRY *pfrom,
DBCORE_API extern int dbBptNotMonotonic;
/** \brief Open .dbd or .db file and read definitions.
* \param ppdbbase The database. Typically the "pdbbase" global
* \param filename Filename to read/search. May be absolute, or relative.
* \param path If !NULL, search path when filename is relative, of for 'include' statements.
* Split by ':' or ';' (cf. OSI_PATH_LIST_SEPARATOR)
* \param substitutions If !NULL, macro definitions like "NAME=VAL,OTHER=SOME"
* \return 0 on success
*/
DBCORE_API long dbReadDatabase(DBBASE **ppdbbase,
const char *filename, const char *path, const char *substitutions);
/** \brief Read definitions from already opened .dbd or .db file.
* \param ppdbbase The database. Typically the "&pdbbase" global
* \param fp FILE* from which to read definitions. Will always be fclose()'d
* \param path If !NULL, search path when filename is relative, of for 'include' statements.
* Split by ':' or ';' (cf. OSI_PATH_LIST_SEPARATOR)
* \param substitutions If !NULL, macro definitions like "NAME=VAL,OTHER=SOME"
* \return 0 on success
*
* \note This function will always close the provided 'fp'.
*/
DBCORE_API long dbReadDatabaseFP(DBBASE **ppdbbase,
FILE *fp, const char *path, const char *substitutions);
DBCORE_API long dbPath(DBBASE *pdbbase, const char *path);

Some files were not shown because too many files have changed in this diff Show More