diff --git a/.appveyor.yml b/.appveyor.yml index c830ae1a8..717373c24 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -33,6 +33,7 @@ skip_commits: - '.github/*' - '.tools/*' - '.gitattributes' + - '.lgtm.yml' - '**/*.html' - '**/*.md' diff --git a/.appveyor/epics-base-7.yml b/.appveyor/epics-base-7.yml index 4a01ccde5..0b064cd2a 100644 --- a/.appveyor/epics-base-7.yml +++ b/.appveyor/epics-base-7.yml @@ -39,6 +39,7 @@ skip_commits: - 'startup/*' - '.github/*' - '.tools/*' + - '.lgtm.yml' - '.gitattributes' - '**/*.html' - '**/*.md' diff --git a/.ci b/.ci index d675de24e..75bae77c1 160000 --- a/.ci +++ b/.ci @@ -1 +1 @@ -Subproject commit d675de24e6a2be018f6ff1dc35618c16dd621727 +Subproject commit 75bae77c1d20707a53e0ff57937491f6b8b557ba diff --git a/.github/workflows/ci-scripts-build.yml b/.github/workflows/ci-scripts-build.yml index d94fbf312..8ff677dc3 100644 --- a/.github/workflows/ci-scripts-build.yml +++ b/.github/workflows/ci-scripts-build.yml @@ -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 diff --git a/.lgtm.yml b/.lgtm.yml new file mode 100644 index 000000000..e3027329e --- /dev/null +++ b/.lgtm.yml @@ -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" + diff --git a/configure/CONFIG b/configure/CONFIG index 1c1242858..df454b29b 100644 --- a/configure/CONFIG +++ b/configure/CONFIG @@ -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 diff --git a/configure/CONFIG.gnuCommon b/configure/CONFIG.gnuCommon index 355614e1a..d3a9a41cf 100644 --- a/configure/CONFIG.gnuCommon +++ b/configure/CONFIG.gnuCommon @@ -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 = diff --git a/configure/CONFIG_BASE b/configure/CONFIG_BASE index 03d0ff7be..4b15e4cdc 100644 --- a/configure/CONFIG_BASE +++ b/configure/CONFIG_BASE @@ -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 diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION index b0c57b763..166ecba22 100644 --- a/configure/CONFIG_BASE_VERSION +++ b/configure/CONFIG_BASE_VERSION @@ -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) diff --git a/configure/CONFIG_CA_VERSION b/configure/CONFIG_CA_VERSION index af570b0e7..a1167282e 100644 --- a/configure/CONFIG_CA_VERSION +++ b/configure/CONFIG_CA_VERSION @@ -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 diff --git a/configure/CONFIG_COMMON b/configure/CONFIG_COMMON index 8bbc4a624..78abdb1b8 100644 --- a/configure/CONFIG_COMMON +++ b/configure/CONFIG_COMMON @@ -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 diff --git a/configure/CONFIG_DATABASE_MODULE b/configure/CONFIG_DATABASE_MODULE index 3376ff67c..0a5cf97d1 100644 --- a/configure/CONFIG_DATABASE_MODULE +++ b/configure/CONFIG_DATABASE_MODULE @@ -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 diff --git a/configure/CONFIG_DATABASE_VERSION b/configure/CONFIG_DATABASE_VERSION index 2205a5386..fef19b2a9 100644 --- a/configure/CONFIG_DATABASE_VERSION +++ b/configure/CONFIG_DATABASE_VERSION @@ -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 diff --git a/configure/CONFIG_LIBCOM_MODULE b/configure/CONFIG_LIBCOM_MODULE index 32bb937c2..428d17a8e 100644 --- a/configure/CONFIG_LIBCOM_MODULE +++ b/configure/CONFIG_LIBCOM_MODULE @@ -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 diff --git a/configure/CONFIG_LIBCOM_VERSION b/configure/CONFIG_LIBCOM_VERSION index 96f25ebaa..7e799cc1c 100644 --- a/configure/CONFIG_LIBCOM_VERSION +++ b/configure/CONFIG_LIBCOM_VERSION @@ -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 diff --git a/configure/RULES.Db b/configure/RULES.Db index 406c1eb16..2872e1bbb 100644 --- a/configure/RULES.Db +++ b/configure/RULES.Db @@ -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 diff --git a/configure/RULES_BUILD b/configure/RULES_BUILD index 53297af52..fd3579c14 100644 --- a/configure/RULES_BUILD +++ b/configure/RULES_BUILD @@ -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) diff --git a/configure/RULES_EXPAND b/configure/RULES_EXPAND index 16c299c6d..fcb945df3 100644 --- a/configure/RULES_EXPAND +++ b/configure/RULES_EXPAND @@ -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 diff --git a/configure/RULES_MODULES b/configure/RULES_MODULES index a0886bdf3..bed21da38 100644 --- a/configure/RULES_MODULES +++ b/configure/RULES_MODULES @@ -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..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) diff --git a/configure/os/CONFIG.Common.RTEMS b/configure/os/CONFIG.Common.RTEMS index b19b2071f..c8729f933 100644 --- a/configure/os/CONFIG.Common.RTEMS +++ b/configure/os/CONFIG.Common.RTEMS @@ -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 = diff --git a/configure/os/CONFIG.Common.RTEMS-mvme2100 b/configure/os/CONFIG.Common.RTEMS-mvme2100 index 1e222b5ab..930b33bad 100644 --- a/configure/os/CONFIG.Common.RTEMS-mvme2100 +++ b/configure/os/CONFIG.Common.RTEMS-mvme2100 @@ -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 diff --git a/configure/os/CONFIG.Common.RTEMS-mvme2700 b/configure/os/CONFIG.Common.RTEMS-mvme2700 index 655e0a5b0..0ee8ac862 100644 --- a/configure/os/CONFIG.Common.RTEMS-mvme2700 +++ b/configure/os/CONFIG.Common.RTEMS-mvme2700 @@ -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 diff --git a/configure/os/CONFIG.Common.UnixCommon b/configure/os/CONFIG.Common.UnixCommon index 1151dce3f..6163b7975 100644 --- a/configure/os/CONFIG.Common.UnixCommon +++ b/configure/os/CONFIG.Common.UnixCommon @@ -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%) diff --git a/configure/os/CONFIG.Common.iosCommon b/configure/os/CONFIG.Common.iosCommon index f9e5750e3..5c248f38a 100644 --- a/configure/os/CONFIG.Common.iosCommon +++ b/configure/os/CONFIG.Common.iosCommon @@ -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 diff --git a/configure/os/CONFIG.Common.vxWorks-e500v2 b/configure/os/CONFIG.Common.vxWorks-e500v2 new file mode 100644 index 000000000..1a7ea2bce --- /dev/null +++ b/configure/os/CONFIG.Common.vxWorks-e500v2 @@ -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 diff --git a/configure/os/CONFIG.darwinCommon.darwinCommon b/configure/os/CONFIG.darwinCommon.darwinCommon index 3ee6fd5f9..0624b0063 100644 --- a/configure/os/CONFIG.darwinCommon.darwinCommon +++ b/configure/os/CONFIG.darwinCommon.darwinCommon @@ -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 diff --git a/configure/os/CONFIG_SITE.Common.linux-aarch64 b/configure/os/CONFIG_SITE.Common.linux-aarch64 index 5c34e9e10..7da494439 100644 --- a/configure/os/CONFIG_SITE.Common.linux-aarch64 +++ b/configure/os/CONFIG_SITE.Common.linux-aarch64 @@ -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..linux-aarch64 instead. diff --git a/configure/os/CONFIG_SITE.linux-x86_64.linux-aarch64 b/configure/os/CONFIG_SITE.linux-x86_64.linux-aarch64 index f4748621f..569d1c384 100644 --- a/configure/os/CONFIG_SITE.linux-x86_64.linux-aarch64 +++ b/configure/os/CONFIG_SITE.linux-x86_64.linux-aarch64 @@ -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 diff --git a/documentation/Doxyfile@ b/documentation/Doxyfile@ index bf53ee0ce..7f6046f48 100644 --- a/documentation/Doxyfile@ +++ b/documentation/Doxyfile@ @@ -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 diff --git a/documentation/README.darwin.html b/documentation/README.darwin.html deleted file mode 100644 index dd11ce857..000000000 --- a/documentation/README.darwin.html +++ /dev/null @@ -1,184 +0,0 @@ - - -Installation notes for EPICS on Mac OS X (Darwin) - - - - -

Building EPICS base

- - -

Building EPICS extensions

-

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

Objective-C and AppleScript

-

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

-/*
- * exampleAppleScriptRecord.m 
- *
- * Simple Objective-C/AppleScript subroutine record
- *
- * To use this record in an application:
- *
- * 1) Make the following changes to the application Makefile:
- *    - Add exampleAppleScriptRecord.m to the application SRCS.
- *    - Add -framework Foundation to the application LDFLAGS.
- * 2) Add the following line to the application database description:
- *      registrar(registerExampleAppleScript)
- * 3) Add a record to the application database:
- *      record(sub,"setVolume")
- *      {
- *          field(SNAM,"exampleAppleScriptProcess")
- *      }
- */
-#import <Foundation/Foundation.h>
-#include <registryFunction.h>
-#include <subRecord.h>
-#include <alarm.h>
-#include <errlog.h>
-#include <recGbl.h>
-#include <epicsExport.h>
-
-/*
- * Shim between EPICS and NSAppleScript class.
- */
-static long
-exampleAppleScriptProcess(struct subRecord *psub)
- {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSDictionary *err;
-    NSAppleScript *nsa;
-    
-    nsa = [[NSAppleScript alloc] initWithSource:[NSString stringWithFormat:
-                @"tell application \"Finder\" to set volume %g\n", psub->a]];
-    if ([nsa executeAndReturnError:&err] == nil) {
-        errlogPrintf("Failed to run AppleScript: %s\n",
-                        [[err objectForKey:NSAppleScriptErrorMessage] cString]);
-        recGblSetSevr(psub, SOFT_ALARM, INVALID_ALARM);
-    }
-    [nsa release];
-    [pool release];
-    return 0;
-}
-
-static registryFunctionRef subRef[] = {
-    {"exampleAppleScriptProcess",(REGISTRYFUNCTION)exampleAppleScriptProcess}
-};
-
-static void registerExampleAppleScript(void)
-{
-    registryFunctionRefAdd(subRef,NELEMENTS(subRef));
-}
-epicsExportRegistrar(registerExampleAppleScript);
-
-
-==============================================================================
-/*
- * runAppleScript.m 
- *
- * Simple Objective-C/AppleScript shim to allow EPICS application to
- * send arbitrary AppleScript messages to other applications.
- *
- * To use this subroutine in an application make the following
- * changes to the application Makefile:
- * - Add runAppleScript.m to the application SRCS.
- * - Add -framework Foundation to the application LDFLAGS.
- */
-#import <Foundation/Foundation.h>
-#include <errlog.h>
-
-int
-runAppleScript(const char *format, ...)
-{
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSString *script;
-    NSMutableDictionary *err;
-    NSAppleScript *nsa;
-    va_list args;
-    int ret = 0;
-    
-    va_start(args, format);
-    script = [[NSString alloc] initWithFormat:
-                            [NSString stringWithCString:format] arguments:args];
-    va_end(args);
-    err = [NSMutableDictionary dictionaryWithCapacity:10];
-    nsa = [[NSAppleScript alloc] initWithSource:script];
-    if ([nsa executeAndReturnError:&err] == nil) {
-        errlogPrintf("Failed to run AppleScript: %s\n",
-                        [[err objectForKey:NSAppleScriptErrorMessage] cString]);
-        ret = -1;
-    }
-    [script release];
-    [nsa release];
-    [pool release];
-    return ret;
-}
-
- - diff --git a/documentation/README.md b/documentation/README.md index 7e995bfde..fa43df47e 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -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) ----- -### What is EPICS base? +### 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. -### What is new in this release? +### 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. -### Copyright Licenses +### 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. -### Supported platforms +### 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. -### Supported compilers +### 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..` if you have problems. -### Software requirements +### 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 -### Documentation +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. -### Directory Structure +### 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 ``` -### Build related components +#### `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 and DEFAULT options - CONFIG_APP_INCLUDE - CONFIG_BASE EPICS base tool and location definitions - CONFIG_BASE_VERSION Definitions for EPICS base version number - CONFIG_COMMON Definitions common to all builds - CONFIG_ENV Definitions of EPICS environment variables - CONFIG_FILE_TYPE - CONFIG_SITE Site specific make definitions - CONFIG_SITE_ENV Site defaults for EPICS environment variables - MAKEFILE Installs CONFIG* RULES* creates - RELEASE Location of external products - RULES Includes appropriate rules file - RULES.Db Rules for database and database definition files - RULES.ioc Rules for application iocBoot/ioc* directory - RULES_ARCHS Definitions and rules for building architectures - RULES_BUILD Build and install rules and definitions - RULES_DIRS Definitions and rules for building subdirectories - RULES_EXPAND - RULES_FILE_TYPE - RULES_TARGET - RULES_TOP Rules specific to a dir (uninstall and tar) - Sample.Makefile Sample makefile with comments + 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 and DEFAULT options + CONFIG_APP_INCLUDE + CONFIG_BASE EPICS base tool and location definitions + CONFIG_BASE_VERSION Definitions for EPICS base version number + CONFIG_COMMON Definitions common to all builds + CONFIG_ENV Definitions of EPICS environment variables + CONFIG_FILE_TYPE + CONFIG_SITE Site specific make definitions + CONFIG_SITE_ENV Site defaults for EPICS environment variables + MAKEFILE Installs CONFIG* RULES* creates + RELEASE Location of external products + RULES Includes appropriate rules file + RULES.Db Rules for database and database definition files + RULES.ioc Rules for application iocBoot/ioc* directory + RULES_ARCHS Definitions and rules for building architectures + RULES_BUILD Build and install rules and definitions + RULES_DIRS Definitions and rules for building subdirectories + RULES_EXPAND + RULES_FILE_TYPE + RULES_TARGET + RULES_TOP Rules specific to a dir 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.. Specific host-target build definitions - CONFIG.Common. Specific target definitions for all hosts - CONFIG..Common Specific host definitions for all targets - CONFIG.UnixCommon.Common Definitions for Unix hosts and all targets - CONFIG.Common.UnixCommon Definitions for Unix targets and all hosts - CONFIG.Common.vxWorksCommon Specific host definitions for all vx targets - CONFIG_SITE.. Site specific host-target definitions - CONFIG_SITE.Common. Site specific target defs for all hosts - CONFIG_SITE..Common Site specific host defs for all targets + CONFIG.. Definitions for a specific host-target combination + CONFIG.Common. Definitions for a specific target, any host + CONFIG..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.. Local settings for a specific host-target combination + CONFIG_SITE.Common. Local settings for a specific target, any host + CONFIG_SITE..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 ``` -### Building EPICS base (Unix and Win32) +### 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 build settings - configure/os/CONFIG..Common Host common build settings + configure/os/CONFIG.. Host self-build definitions + configure/os/CONFIG..Common Host common build definitions + configure/os/CONFIG_SITE.. Host self-build overrides + configure/os/CONFIG_SITE..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 common settings - configure/os/CONFIG.. Host-target settings + configure/os/CONFIG.Common. Target common definitions + configure/os/CONFIG.. Host-target definitions + configure/os/CONFIG_SITE.Common. Target common overrides + configure/os/CONFIG_SITE.. 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. -### Example application and extension +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/` 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/` directory +during the base build. -### Multiple host platforms +### Multiple host platforms You can build using a single EPICS directory structure on multiple host systems and for multiple cross target systems. The intermediate and binary files generated by the build will be created in separate subdirectories and installed into the appropriate separate host/target -install directories. EPICS executables and perl scripts are installed -into the `$(INSTALL_LOCATION)/bin/` directories. Libraries are -installed into $`(INSTALL_LOCATION)/lib/`. The default -definition for `$(INSTALL_LOCATION)` is `$(TOP)` which is the root -directory in the distribution directory structure, base. Created -object files are stored in `O.` source subdirectories, This -allows objects for multiple cross target architectures to be -maintained at the same time. To build EPICS base for a specific +install directories. + +EPICS executables and perl scripts are installed into the +`$(INSTALL_LOCATION)/bin/` directories. Libraries are installed +into $`(INSTALL_LOCATION)/lib/`. The default definition for +`$(INSTALL_LOCATION)` is `$(TOP)` which is the root directory in the +distribution directory structure, `base`. Intermediate object files +are stored in `O.` 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. diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 392136a7b..ff3896a4e 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -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 @@ -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 +#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 `.xml` to `-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 diff --git a/documentation/ReleaseChecklist.html b/documentation/ReleaseChecklist.html index 036f56a65..05b76ece9 100644 --- a/documentation/ReleaseChecklist.html +++ b/documentation/ReleaseChecklist.html @@ -37,26 +37,11 @@ that should be performed when creating production releases of EPICS Base.

The Release Process

-

Full Process

- -

The version released on the Feature Freeze date is designated the first -pre-release, -pre1. The first release candidate -rc1 is the -first version that has undergone 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 -pre1 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.

- -

Short Process for Patch Releases

- -

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 Release Approval.

+

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.

Roles

@@ -65,11 +50,11 @@ starting at Release Approval.

Release Manager ()
Responsible for managing and tagging the release
-
Platform Developers (optional)
+
Platform Developers (informal)
Responsible for individual operating system platforms
Application Developers
Responsible for support modules that depend on EPICS Base.
-
Website Manager (Andrew Johnson)
+
Website Editor (Andrew Johnson)
Responsible for the EPICS website
@@ -111,9 +96,7 @@ starting at Release Approval.

& all developers Ensure that documentation will be updated before the release date:
    -
  • Application Developers Guide
  • Release Notes
  • -
  • Known Problems
  • Other documents
@@ -125,87 +108,9 @@ starting at Release Approval.

  - Website Manager + Release Manager 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. - - - Creating pre-release and release-candidate versions - - - - Release Manager - - Edit and commit changes to the EPICS version number file - configure/CONFIG_BASE_VERSION. - - - - Release Manager - Tag the module in Git, using these tag conventions: -
    -
  • - R7.0.5-pren - — pre-release tag -
  • -
  • - R7.0.5-rcn - — release candidate tag -
  • -
-
- cd base-7.0
- git tag -m 'ANJ: Tagged for 7.0.5-rc1' R7.0.5-rc1 -
- Note that submodules must not 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. - - - - Release Manager - Export the tagged version into a tarfile. The make-tar.sh - script generates a gzipped tarfile directly from the tag, excluding the - files and directories that are only used for continuous integration: -
- cd base-7.0
- ./.tools/make-tar.sh R7.0.5-rc1 base-7.0.5-rc1.tar.gz base-7.0.5-rc1/ -
- Create a GPG signature file of the tarfile as follows: -
- gpg --armor --sign --detach-sig base-7.0.5-rc1.tar.gz -
- - - - - Release Manager - Test the tarfile by extracting its contents and building it on at - least one supported platform. - - - - Website Manager - 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. - - - - Website Manager - 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. - - - - Website Manager - 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. + known set "Date Targeted" to the expected release date. Testing @@ -250,11 +155,8 @@ starting at Release Approval.

Release Manager Check that documentation has been updated: @@ -266,9 +168,7 @@ starting at Release Approval.

Release Manager - Obtain a positive Ok to release from all platform developers - once a release candidate version has gone for 2 weeks without any major - new issues being reported. + Obtain a positive Ok to release from developers. Creating the final release version @@ -277,8 +177,8 @@ starting at Release Approval.

Release Manager -

For each external submodule in turn (assuming it has not been tagged - yet):

+

For each external submodule in turn (assuming it has not been + tagged yet):

  1. 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 Release Approval.

  2. Tag the module:
    - git tag -m 'ANJ: Tag for EPICS 7.0.5' <module-version> + git tag -m 'ANJ: Tag for EPICS 7.0.6.1' <module-version>
  3. @@ -326,15 +226,24 @@ starting at Release Approval.

-

Commit all the submodule updates to the 7.0 branch.

+

After all submodules complete 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 + git submodule status --cached only shows the appropriate + version tags in the right-most parenthesized column with no + -n-gxxxxxxx suffix.

Release Manager - Edit the main EPICS Base version file and the built-in module version - files: + +

git grep UNRELEASED and insert the release version to any + doxygen annotations that have a @since UNRELEASED comment. + Commit (don't push).

+

Edit the main EPICS Base version file and the built-in module version + files:

  • configure/CONFIG_BASE_VERSION
  • configure/CONFIG_LIBCOM_VERSION
  • @@ -346,6 +255,9 @@ starting at Release Approval.

    PATCH_LEVEL value should have been incremented after the previous release tag was applied. Set all DEVELOPMENT_FLAG values to 0 and EPICS_DEV_SNAPSHOT to the empty string.

    +

    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.

    Commit these changes (don't push).

    @@ -355,9 +267,9 @@ starting at Release Approval.

    Tag the epics-base module in Git:
    cd base-7.0
    - git tag -m 'ANJ: Tagged for release' R7.0.5 + git tag -m 'ANJ: Tagged for release' R7.0.6.1
    -

    Don't push these commits or the new tag to the Launchpad repository +

    Don't push anything to the Launchpad repository yet.

    @@ -376,6 +288,9 @@ starting at Release Approval.

    release by incrementing the MAINTENANCE_VERSION or PATCH_LEVEL value in each file. Set all DEVELOPMENT_FLAG values to 1 and EPICS_DEV_SNAPSHOT to "-DEV".

    +

    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.

    Commit these changes (don't push).

    @@ -387,12 +302,12 @@ starting at Release Approval.

    files and directories that are only used for continuous integration:
    cd base-7.0
    - ./.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/
    Create a GPG signature file of the tarfile as follows:
    cd ..
    - gpg --armor --sign --detach-sig base-7.0.5.tar.gz + gpg --armor --sign --detach-sig base-7.0.6.1.tar.gz
    @@ -412,38 +327,38 @@ starting at Release Approval.

    - Release Manager + Website Editor Copy the tarfile and its signature to the Base download area of the website. - Website Manager + Website Editor Update the website subdirectory that holds the release documentation, and copy in the files from the base/documentation directory of the tarfile. - Website Manager + Website Editor Update the webpage for the new release with links to the release documents and tar file. - Website Manager + Website Editor Add the new release tar file to the website Base download index page. - Website Manager + Website Editor Link to the release webpage from other relevent areas of the website - update front page and sidebars. - Website Manager + Website Editor Add an entry to the website News page, linking to the new version webpage. @@ -453,17 +368,17 @@ starting at Release Approval.

    - Website Manager + Website Editor Upload the tar file and its .asc signature file to the epics-controls web-server.
    - scp base-7.0.5.tar.gz base-7.0.5.tar.gz.asc epics-controls:download/base
    + scp base-7.0.6.1.tar.gz base-7.0.6.1.tar.gz.asc epics-controls:download/base
    - Website Manager + Website Editor Follow instructions on Add a page for a new release to create a new release webpage (not @@ -478,7 +393,7 @@ starting at Release Approval.

    - Website Manager + Release Manager 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 diff --git a/modules/ca/src/client/access.cpp b/modules/ca/src/client/access.cpp index 9c94d61c5..58cc4bca5 100644 --- a/modules/ca/src/client/access.cpp +++ b/modules/ca/src/client/access.cpp @@ -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" diff --git a/modules/ca/src/client/acctst.c b/modules/ca/src/client/acctst.c index 83d848f12..34298680c 100644 --- a/modules/ca/src/client/acctst.c +++ b/modules/ca/src/client/acctst.c @@ -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" ); diff --git a/modules/ca/src/client/bhe.cpp b/modules/ca/src/client/bhe.cpp index d7fb77785..3808f061c 100644 --- a/modules/ca/src/client/bhe.cpp +++ b/modules/ca/src/client/bhe.cpp @@ -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 diff --git a/modules/ca/src/client/caProto.h b/modules/ca/src/client/caProto.h index 397b1edaf..57b280177 100644 --- a/modules/ca/src/client/caProto.h +++ b/modules/ca/src/client/caProto.h @@ -18,7 +18,7 @@ #define INC_caProto_H // Pick up definition of IPPORT_USERRESERVED -#include +#include #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 */ }; diff --git a/modules/ca/src/client/caRepeater.cpp b/modules/ca/src/client/caRepeater.cpp index 7eaab508b..c8385ba3b 100644 --- a/modules/ca/src/client/caRepeater.cpp +++ b/modules/ca/src/client/caRepeater.cpp @@ -90,7 +90,7 @@ int main(int argc, char* argv[]) (void)detachinout; #endif - chdir ( "/" ); + (void)! chdir ( "/" ); ca_repeater (); return ( 0 ); } diff --git a/modules/ca/src/client/ca_client_context.cpp b/modules/ca/src/client/ca_client_context.cpp index 1c2f985b5..1e830fd08 100644 --- a/modules/ca/src/client/ca_client_context.cpp +++ b/modules/ca/src/client/ca_client_context.cpp @@ -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 ); diff --git a/modules/ca/src/client/cac.cpp b/modules/ca/src/client/cac.cpp index b1abfc42a..f8d1d0800 100644 --- a/modules/ca/src/client/cac.cpp +++ b/modules/ca/src/client/cac.cpp @@ -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 ( 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 ); diff --git a/modules/ca/src/client/cadef.h b/modules/ca/src/client/cadef.h index f64e3899c..12861c384 100644 --- a/modules/ca/src/client/cadef.h +++ b/modules/ca/src/client/cadef.h @@ -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 (); diff --git a/modules/ca/src/client/casw.cpp b/modules/ca/src/client/casw.cpp index 54a14036c..c9ff465f7 100644 --- a/modules/ca/src/client/casw.cpp +++ b/modules/ca/src/client/casw.cpp @@ -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 ); diff --git a/modules/ca/src/client/comBuf.cpp b/modules/ca/src/client/comBuf.cpp index 8f92170dd..5c9083ed7 100644 --- a/modules/ca/src/client/comBuf.cpp +++ b/modules/ca/src/client/comBuf.cpp @@ -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 () { diff --git a/modules/ca/src/client/comBuf.h b/modules/ca/src/client/comBuf.h index 6a4899414..3d5f58c45 100644 --- a/modules/ca/src/client/comBuf.h +++ b/modules/ca/src/client/comBuf.h @@ -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; diff --git a/modules/ca/src/client/comQueRecv.cpp b/modules/ca/src/client/comQueRecv.cpp index 026a84ced..d7d07361b 100644 --- a/modules/ca/src/client/comQueRecv.cpp +++ b/modules/ca/src/client/comQueRecv.cpp @@ -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; diff --git a/modules/ca/src/client/comQueRecv.h b/modules/ca/src/client/comQueRecv.h index ad8bead88..01c961e51 100644 --- a/modules/ca/src/client/comQueRecv.h +++ b/modules/ca/src/client/comQueRecv.h @@ -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 (); diff --git a/modules/ca/src/client/comQueSend.cpp b/modules/ca/src/client/comQueSend.cpp index e782a7017..c0c535f42 100644 --- a/modules/ca/src/client/comQueSend.cpp +++ b/modules/ca/src/client/comQueSend.cpp @@ -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). // // diff --git a/modules/ca/src/client/convert.cpp b/modules/ca/src/client/convert.cpp index e043ee2fe..361b60222 100644 --- a/modules/ca/src/client/convert.cpp +++ b/modules/ca/src/client/convert.cpp @@ -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 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 ); diff --git a/modules/ca/src/client/iocinf.cpp b/modules/ca/src/client/iocinf.cpp index 7a0853f00..b2c30f7f9 100644 --- a/modules/ca/src/client/iocinf.cpp +++ b/modules/ca/src/client/iocinf.cpp @@ -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 ); diff --git a/modules/ca/src/client/iocinf.h b/modules/ca/src/client/iocinf.h index ae775241d..0dadf44b0 100644 --- a/modules/ca/src/client/iocinf.h +++ b/modules/ca/src/client/iocinf.h @@ -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; diff --git a/modules/ca/src/client/msgForMultiplyDefinedPV.cpp b/modules/ca/src/client/msgForMultiplyDefinedPV.cpp index f65b392ef..63c00d108 100644 --- a/modules/ca/src/client/msgForMultiplyDefinedPV.cpp +++ b/modules/ca/src/client/msgForMultiplyDefinedPV.cpp @@ -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, diff --git a/modules/ca/src/client/nciu.cpp b/modules/ca/src/client/nciu.cpp index 61ccebafc..a862cb228 100644 --- a/modules/ca/src/client/nciu.cpp +++ b/modules/ca/src/client/nciu.cpp @@ -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 ); } diff --git a/modules/ca/src/client/netIO.h b/modules/ca/src/client/netIO.h index 2560663ba..e5b5814bc 100644 --- a/modules/ca/src/client/netIO.h +++ b/modules/ca/src/client/netIO.h @@ -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 diff --git a/modules/ca/src/client/oldAccess.h b/modules/ca/src/client/oldAccess.h index cace26ec1..2c39d2768 100644 --- a/modules/ca/src/client/oldAccess.h +++ b/modules/ca/src/client/oldAccess.h @@ -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 ); diff --git a/modules/ca/src/client/oldChannelNotify.cpp b/modules/ca/src/client/oldChannelNotify.cpp index 0716a430b..71688c94c 100644 --- a/modules/ca/src/client/oldChannelNotify.cpp +++ b/modules/ca/src/client/oldChannelNotify.cpp @@ -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; diff --git a/modules/ca/src/client/oldSubscription.cpp b/modules/ca/src/client/oldSubscription.cpp index b1290b2b8..72a51d9ad 100644 --- a/modules/ca/src/client/oldSubscription.cpp +++ b/modules/ca/src/client/oldSubscription.cpp @@ -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. } diff --git a/modules/ca/src/client/repeater.cpp b/modules/ca/src/client/repeater.cpp index e597d66f6..e198a25d4 100644 --- a/modules/ca/src/client/repeater.cpp +++ b/modules/ca/src/client/repeater.cpp @@ -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; diff --git a/modules/ca/src/client/searchTimer.cpp b/modules/ca/src/client/searchTimer.cpp index 5a4fa446a..60b153639 100644 --- a/modules/ca/src/client/searchTimer.cpp +++ b/modules/ca/src/client/searchTimer.cpp @@ -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 ( diff --git a/modules/ca/src/client/searchTimer.h b/modules/ca/src/client/searchTimer.h index 74c8bde6e..ca5d2c55d 100644 --- a/modules/ca/src/client/searchTimer.h +++ b/modules/ca/src/client/searchTimer.h @@ -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; diff --git a/modules/ca/src/client/syncgrp.cpp b/modules/ca/src/client/syncgrp.cpp index bee6ea8dc..4f79348fd 100644 --- a/modules/ca/src/client/syncgrp.cpp +++ b/modules/ca/src/client/syncgrp.cpp @@ -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 ); diff --git a/modules/ca/src/client/tcpRecvWatchdog.cpp b/modules/ca/src/client/tcpRecvWatchdog.cpp index 9e0bf0188..367e09237 100644 --- a/modules/ca/src/client/tcpRecvWatchdog.cpp +++ b/modules/ca/src/client/tcpRecvWatchdog.cpp @@ -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. diff --git a/modules/ca/src/client/tcpiiu.cpp b/modules/ca/src/client/tcpiiu.cpp index e601c8d24..30f6fad17 100644 --- a/modules/ca/src/client/tcpiiu.cpp +++ b/modules/ca/src/client/tcpiiu.cpp @@ -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 ) { diff --git a/modules/ca/src/client/test/ca_test.c b/modules/ca/src/client/test/ca_test.c index 0d1ec2f57..adae20b84 100644 --- a/modules/ca/src/client/test/ca_test.c +++ b/modules/ca/src/client/test/ca_test.c @@ -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); diff --git a/modules/ca/src/client/udpiiu.cpp b/modules/ca/src/client/udpiiu.cpp index 723117a71..c6ffb6def 100644 --- a/modules/ca/src/client/udpiiu.cpp +++ b/modules/ca/src/client/udpiiu.cpp @@ -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; } diff --git a/modules/ca/src/perl/Cap5.xs b/modules/ca/src/perl/Cap5.xs index cc729340a..6d06a15f1 100644 --- a/modules/ca/src/perl/Cap5.xs +++ b/modules/ca/src/perl/Cap5.xs @@ -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); diff --git a/modules/ca/src/perl/capr.pl b/modules/ca/src/perl/capr.pl index ba331cf8e..47850c9a8 100644 --- a/modules/ca/src/perl/capr.pl +++ b/modules/ca/src/perl/capr.pl @@ -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 diff --git a/modules/ca/src/tools/caget.c b/modules/ca/src/tools/caget.c index 0aa655ee5..e60f61922 100644 --- a/modules/ca/src/tools/caget.c +++ b/modules/ca/src/tools/caget.c @@ -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); diff --git a/modules/ca/src/tools/caput.c b/modules/ca/src/tools/caput.c index 62def624e..05247643a 100644 --- a/modules/ca/src/tools/caput.c +++ b/modules/ca/src/tools/caput.c @@ -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); diff --git a/modules/database/src/ioc/bpt/RULES b/modules/database/src/ioc/bpt/RULES index cf6232bc6..7239efd02 100644 --- a/modules/database/src/ioc/bpt/RULES +++ b/modules/database/src/ioc/bpt/RULES @@ -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 diff --git a/modules/database/src/ioc/db/callback.c b/modules/database/src/ioc/db/callback.c index 3fa249392..d58b8fc6f 100644 --- a/modules/database/src/ioc/db/callback.c +++ b/modules/database/src/ioc/db/callback.c @@ -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); diff --git a/modules/database/src/ioc/db/dbAccess.c b/modules/database/src/ioc/db/dbAccess.c index 8aac52f00..8fcdab8a7 100644 --- a/modules/database/src/ioc/db/dbAccess.c +++ b/modules/database/src/ioc/db/dbAccess.c @@ -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); diff --git a/modules/database/src/ioc/db/dbAccessDefs.h b/modules/database/src/ioc/db/dbAccessDefs.h index 771084170..eef5e990b 100644 --- a/modules/database/src/ioc/db/dbAccessDefs.h +++ b/modules/database/src/ioc/db/dbAccessDefs.h @@ -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 diff --git a/modules/database/src/ioc/db/dbBkpt.c b/modules/database/src/ioc/db/dbBkpt.c index 18a357ebe..de6fa3f9b 100644 --- a/modules/database/src/ioc/db/dbBkpt.c +++ b/modules/database/src/ioc/db/dbBkpt.c @@ -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); } diff --git a/modules/database/src/ioc/db/dbCa.c b/modules/database/src/ioc/db/dbCa.c index 70f939897..57cca404f 100644 --- a/modules/database/src/ioc/db/dbCa.c +++ b/modules/database/src/ioc/db/dbCa.c @@ -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 */ diff --git a/modules/database/src/ioc/db/dbCa.h b/modules/database/src/ioc/db/dbCa.h index 42ce1b338..7b6f9c090 100644 --- a/modules/database/src/ioc/db/dbCa.h +++ b/modules/database/src/ioc/db/dbCa.h @@ -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 */ diff --git a/modules/database/src/ioc/db/dbCommon.dbd.pod b/modules/database/src/ioc/db/dbCommon.dbd.pod index 5ad4627c5..c8ae7e6ba 100644 --- a/modules/database/src/ioc/db/dbCommon.dbd.pod +++ b/modules/database/src/ioc/db/dbCommon.dbd.pod @@ -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/C, C/C, C/C or +C/C. 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 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 field specifies the scheduling priority for processing records with SCAN=C and asynchronous record completion tasks. -The B 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 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 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 field of a record is written to, the record is processed. +The B 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 +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 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 field of a record is written to, the record is processed. + The B 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 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 field is TRUE while the record is being processed. For +The B 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 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. +The B 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. If the +FLNK field is a Channel Access link it must point to the PROC field of the +target record. The B field is for internal use by the scanning system. @@ -227,6 +230,8 @@ The B 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 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 field contains the current alarm status. The B field contains the current alarm severity. -These two fields are seen outside database access. The B and B -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 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, B and B 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 field contains the highest unacknowledged alarm severity. -The B field specifies if it is necessary to acknowledge transient +The B field specifies whether it is necessary to acknowledge transient alarms. -The B indicates if the record's value is BnBeBined. 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 indicates if the record's value is BnBeBined. 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 field is is for private use of the device support modules. =head3 Debugging Fields -The B 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 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 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 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 string field sets the name of the access security group used for this +record. If left empty, the record is placed in group C. -The B field is a field for private use of the access security system. +The B field is private for use by the access security system. -The B 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 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 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 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 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 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 field is the head of the list of monitors connected to this +The B 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 field contains the address of a putNotify callback. @@ -474,23 +487,44 @@ The B field contains the address of dbRecordType The B field specifies a reprocessing of the record when current processing completes. -The B