Compare commits

..

38 Commits

Author SHA1 Message Date
Andrew Johnson
1c3aa01846 Cleanup CONFIG_COMMON
Some checks failed
Base / Ub-20 clang-10 C++11 (push) Has been cancelled
Base / Ub-20 clang-10 (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.10 (push) Has been cancelled
Base / MacOS clang-12 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.9 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 beatnik (push) Has been cancelled
Base / CentOS-8 (push) Failing after 1s
Base / CentOS-7 (push) Failing after 6s
Base / Fedora-33 (push) Failing after 2s
Base / Fedora-latest (push) Failing after 1s
Base / Ub-20 gcc-9 + RT-5.1 pc686 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 uC5282 (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW, static (push) Has been cancelled
Base / Win2019 MSC-19, debug (push) Has been cancelled
Base / Win2019 MSC-19 (push) Has been cancelled
Base / Win2019 MSC-19, static (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-5.1 xilinx_zynq_a9_qemu (push) Has been cancelled
Base / Win2019 mingw (push) Has been cancelled
Base / Ub-20 gcc-9 C++11, static (push) Has been cancelled
Rewrote some definitions for clarity
2021-11-25 18:37:22 -06:00
Andrew Johnson
191ff137f1 configure: Use GNU Make's abspath instead of fullPathname.pl
Add new INSTALL_ABSOLUTE variable, remove duplicates.
2021-11-25 13:27:35 -06:00
Andrew Johnson
156945c458 YAJL: Handle truncated Unicode surrogates better 2021-11-25 13:27:35 -06:00
Andrew Johnson
31fcb77412 macCore: Don't pass NULL or "" into getenv() 2021-11-22 15:56:30 -06:00
Andrew Johnson
631f514c7c Test vprintf() redirection, other tweaks 2021-11-22 15:52:25 -06:00
Andrew Johnson
6e496e80d1 Redirection support for vprintf() 2021-11-22 15:51:08 -06:00
Michael Davidsaver
2256c979b0 ca: silence warning 2021-11-13 11:47:15 -08:00
Michael Davidsaver
7529577e3b Silence warning in mbbioDirectTest
GCC seems to lose track of possible output lengths
of the first sprintf() when computing possible lengths
of the second.

../mbbioDirectTest.c:44:26: warning: ‘.B’ directive writing 2 bytes into a region of size between 1 and 40 [-Wformat-overflow=]
   44 |         sprintf(field,"%s.B%X", rec, i);
2021-11-13 11:47:15 -08:00
Michael Davidsaver
1c96fd1cb4 ci: run tests for RTEMS 4.9 and 5 2021-11-09 09:33:25 -08:00
Michael Davidsaver
8d078a0c7d RTEMS: rtems_netconfig.c version test consistency
The comment above says "... no longer needed in RTEMS 4.11"
which to me says needed "< 4.11".
2021-11-09 09:32:13 -08:00
Michael Davidsaver
8a4051964f RTEMS: e1000 giant hack for QEMU w/ libbsd 2021-11-09 09:32:13 -08:00
Michael Davidsaver
5ef537684e RTEMS5: update libbsd logging
Show messages synchronously during boot,
then redirect through errlog before user app.

Disable syslog() during tests
2021-11-09 09:32:13 -08:00
Michael Davidsaver
c1dcd728d7 RTEMS5: redo dhcp handler and make NTP optional 2021-11-09 09:32:13 -08:00
Michael Davidsaver
78684e0e57 asyncSoftTest fix sync 2021-11-08 07:58:15 -08:00
Michael Davidsaver
f57acd2c10 add testdbCaWaitForConnect() 2021-11-08 07:58:15 -08:00
Michael Davidsaver
ba5ade1852 softTest fix sync 2021-11-05 08:31:17 -07:00
Michael Davidsaver
8a0fc0373b dbPutFieldLink() missing status on dbChannelOpen() error 2021-11-03 12:47:04 -07:00
Michael Davidsaver
4340e76445 drop unused dbCaGetUpdateCount() 2021-11-02 11:31:28 -07:00
Michael Davidsaver
ce910f52c3 drop usage of dbCaGetUpdateCount() 2021-11-02 11:31:26 -07:00
Michael Davidsaver
219ab33625 fix regressTest 2021-11-02 11:31:24 -07:00
Michael Davidsaver
e9e576f4bb add testdbCaWaitForUpdateCount() and fix dbCaSync()
Add testdbCaWaitForUpdateCount() to wait for CA link
data event counter.

dbCaSync() actually wait for  work queue to be empty
2021-11-02 11:31:19 -07:00
Michael Davidsaver
5bb1138b87 Revert "Another attempt to fix regressTest.c::testLinkSevr()"
This reverts commit 955dcfc7b5.
2021-11-02 10:53:21 -07:00
Andrew Johnson
955dcfc7b5 Another attempt to fix regressTest.c::testLinkSevr() 2021-10-28 13:21:03 -05:00
Andrew Johnson
07a371703f Cosmetic Release Notes change 2021-10-28 13:20:49 -05:00
Andrew Johnson
1950a8240c Fix issue reported by Matt Pearson 2021-10-26 16:46:35 -05:00
Michael Davidsaver
a662cae239 changelog 2021-10-18 10:21:28 -07:00
Michael Davidsaver
2b3c6f2e26 epicsSingleton cleanup
Inline all template methods to avoid dllimport/export issues
with some mingw.

Change dllimport/export to only include out of line
methods of SingletonUntyped.
2021-10-18 10:11:08 -07:00
Michael Davidsaver
b1d9c57101 db_field_log::mask overwrite with actual event mask.
db_create_event_log() initializes mask with pevent->select.
2021-10-18 08:45:25 -07:00
Michael Davidsaver
446e0d4af8 dbnd filter pass through DBE_ALARM|DBE_PROPERTY 2021-10-18 08:45:23 -07:00
Michael Davidsaver
2f51653a9e errlog: try to enable WIN10 terminal escape processing 2021-10-18 08:45:13 -07:00
Michael Davidsaver
b9899213d4 colorize errors and warnings
Use ERL_ERROR and ERL_WARNING

git grep -li 'errlogPrintf.*[" ]error' | xargs sed -i -E -e 's|(errlogPrintf.*[" ])(error)|\1" ERL_ERROR "|g'

git grep -li 'errlogPrintf.*[" ]warn' | xargs sed -i -E -e 's|(errlogPrintf.*[" ])(warn[a-zA-Z]*)|\1" ERL_WARNING "|g'
2021-10-18 08:45:13 -07:00
Michael Davidsaver
0c12b02d4f errlog strip ANSI escapes
Always strip for handlers, and conditionally
if stderr is not a TTY, or $TERM unset/empty.
2021-10-18 08:45:13 -07:00
Michael Davidsaver
ac12ccad38 errlog add ANSI escape macros 2021-10-18 08:45:13 -07:00
Michael Davidsaver
8fdaa13c97 errlog: eltc() re-add flush
Removal upsets dbCaLinkTest on RTEMS, which must not be
synchronizing correctly.  Re-add until this can be corrected.
2021-10-18 08:45:13 -07:00
Michael Davidsaver
29fa0621d7 Com: rewrite errlog
Switch to double buffering to allow errlogThread
to unlock while printing.
2021-10-18 08:45:13 -07:00
Michael Davidsaver
465920fcf1 ci: disable RTEMS test running 2021-10-12 10:24:22 -07:00
Michael Davidsaver
b9e9537376 regressTest: attempt to fix spurious failure 2021-10-12 10:22:31 -07:00
Andrew Johnson
fb46786ccb Update version numbers and submodules after release 2021-10-06 20:19:02 -05:00
56 changed files with 1103 additions and 880 deletions

View File

@@ -85,7 +85,6 @@ jobs:
configuration: default
rtems: "5"
rtems_target: RTEMS-pc686-qemu
test: NO
name: "Ub-20 gcc-9 + RT-5.1 pc686"
- os: ubuntu-20.04
@@ -137,6 +136,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
@@ -186,7 +186,7 @@ jobs:
- name: Build main module
run: python .ci/cue.py build
- name: Run main module tests
run: python .ci/cue.py -T 20M test
run: python .ci/cue.py -T 60M test
- name: Upload tapfiles Artifact
if: ${{ always() }}
uses: actions/upload-artifact@v2

View File

@@ -52,11 +52,11 @@ 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)
EPICS_DEV_SNAPSHOT=
EPICS_DEV_SNAPSHOT=-DEV
# No changes should be needed below here

View File

@@ -2,11 +2,11 @@
EPICS_CA_MAJOR_VERSION = 4
EPICS_CA_MINOR_VERSION = 14
EPICS_CA_MAINTENANCE_VERSION = 1
EPICS_CA_MAINTENANCE_VERSION = 2
# Development flag, set to zero for release versions
EPICS_CA_DEVELOPMENT_FLAG = 0
EPICS_CA_DEVELOPMENT_FLAG = 1
# Immediately after a release the MAINTENANCE_VERSION
# will be incremented and the DEVELOPMENT_FLAG set to 1

View File

@@ -56,6 +56,7 @@ GNU_DIR = /usr
# Directories
INSTALL_LOCATION = $(TOP)
INSTALL_ABSOLUTE = $(abspath $(INSTALL_LOCATION))
INSTALL_LOCATION_LIB = $(INSTALL_LOCATION)/lib
INSTALL_LOCATION_BIN = $(INSTALL_LOCATION)/bin
@@ -71,13 +72,14 @@ INSTALL_DBD = $(INSTALL_LOCATION)/dbd
INSTALL_DB = $(INSTALL_LOCATION)/db
INSTALL_CONFIG = $(INSTALL_LOCATION)/configure
FINAL_LOCATION = $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION))
#-------------------------------------------------------
# These are default settings that may be overridden later
# Directory for OS independant build created files
COMMON_DIR = ../O.Common
# Eventual install path (to be compiled into binaries)
FINAL_LOCATION = $(INSTALL_ABSOLUTE)
# IOC's absolute path to $(TOP), may be overridden inside the application
IOCS_APPL_TOP = $(shell $(FULLPATHNAME) $(INSTALL_LOCATION))
# IOC's view of install path
IOCS_APPL_TOP = $(INSTALL_ABSOLUTE)
#-------------------------------------------------------
# Silencing the build - suppress messages during 'make -s'
@@ -133,6 +135,8 @@ LIB_SUFFIX =
SHRLIB_PREFIX = $(LIB_PREFIX)
DLLSTUB_PREFIX = $(LIB_PREFIX)
DLLSTUB_SUFFIX = $(LIB_SUFFIX)
LOADABLE_SHRLIB_PREFIX = $(SHRLIB_PREFIX)
LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX)
BUILDLIB_PREFIX_YES = $(DLLSTUB_PREFIX)
BUILDLIB_PREFIX_NO = $(LIB_PREFIX)
@@ -153,12 +157,14 @@ CMPLR_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \
ALL_SRC_DIRS = $(CMPLR_SRC_DIRS) $(OS_SRC_DIRS) $(GENERIC_SRC_DIRS)
#--------------------------------------------------
# Directory for OS independant build created files
COMMON_DIR = ../O.Common
# compile line include directories
INSTALL_INCLUDES += \
-I$(INSTALL_INCLUDE)/compiler/$(CMPLR_CLASS) \
-I$(INSTALL_INCLUDE)/os/$(OS_CLASS) \
-I$(INSTALL_INCLUDE)
SRC_INCLUDES = -I$(COMMON_DIR) $(addprefix -I, $(wildcard $(ALL_SRC_DIRS)))
INSTALL_INCLUDE_DIRS = $(INSTALL_INCLUDE)/compiler/$(CMPLR_CLASS) \
$(INSTALL_INCLUDE)/os/$(OS_CLASS) $(INSTALL_INCLUDE)
INSTALL_INCLUDES += $(addprefix -I, $(INSTALL_INCLUDE_DIRS))
SRC_INCLUDES = $(addprefix -I, $(COMMON_DIR) $(wildcard $(ALL_SRC_DIRS)))
#--------------------------------------------------
# Target filename definitions
@@ -172,23 +178,27 @@ TESTSHRLIBNAME = $(TESTSHRLIBNAME_$(SHARED_LIBRARIES))
#--------------------------------------------------
# obj files
TARGET_OBJS = $($*_LDOBJS) $(addsuffix $(OBJ),$(basename $($*_OBJS) $($*_SRCS)))
TARGET_OBJS = $($*_LDOBJS) $(addsuffix $(OBJ), \
$(basename $($*_OBJS) $($*_SRCS)))
PRODUCT_OBJS = $(addsuffix $(OBJ),$(basename $(SRCS) $(USR_SRCS) $(PROD_SRCS) $(USR_OBJS) $(PROD_OBJS)))
PRODUCT_OBJS = $(addsuffix $(OBJ), \
$(basename $(SRCS) $(USR_SRCS) $(PROD_SRCS) $(USR_OBJS) $(PROD_OBJS)))
PROD_LD_OBJS = $(TARGET_OBJS) $(PRODUCT_OBJS)
LIBRARY_OBJS = $(addsuffix $(OBJ),$(basename $(SRCS) $(USR_SRCS) $(LIB_SRCS) $(LIBSRCS) $(USR_OBJS) $(LIB_OBJS)))
LIBRARY_OBJS = $(addsuffix $(OBJ), \
$(basename $(SRCS) $(USR_SRCS) $(LIB_SRCS) $(LIBSRCS) $(USR_OBJS) $(LIB_OBJS)))
LIBRARY_LD_OBJS = $(TARGET_OBJS) $(LIBRARY_OBJS)
#--------------------------------------------------
# Windows resource files
TARGET_RESS = $(if $(RES),$(addsuffix $(RES),$(basename $($*_RCS))),)
TARGET_RESS = $(if $(RES), $(addsuffix $(RES), $(basename $($*_RCS))))
PROD_RESS = $(if $(RES),$(addsuffix $(RES),$(basename $(RCS) $(PROD_RCS))),)
PROD_RESS = $(if $(RES), $(addsuffix $(RES), $(basename $(RCS) $(PROD_RCS))))
PROD_LD_RESS = $(TARGET_RESS) $(PROD_RESS)
LIBRARY_RESS = $(if $(RES),$(addsuffix $(RES),$(basename $(RCS) $(LIB_RCS) $(LIBRARY_RCS))),)
LIBRARY_RESS = $(if $(RES), $(addsuffix $(RES), \
$(basename $(RCS) $(LIB_RCS) $(LIBRARY_RCS))))
LIBRARY_LD_RESS = $(TARGET_RESS) $(LIBRARY_RESS)
#--------------------------------------------------
@@ -265,15 +275,16 @@ 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_CXXFLAGS) $(OP_SYS_CXXFLAGS) $(LIBRARY_SRC_CFLAGS)
CXXFLAGS = $($(BUILD_CLASS)_CXXFLAGS) $(POSIX_CXXFLAGS) $(OPT_CXXFLAGS) \
$(DEBUG_CXXFLAGS) $(PIPE_CFLAGS) $(WARN_CXXFLAGS) $(TARGET_CXXFLAGS) \
$(USR_CXXFLAGS) $(CMD_CXXFLAGS) $(ARCH_DEP_CXXFLAGS) $(CODE_CXXFLAGS) \
$(STATIC_CXXFLAGS) $(OP_SYS_CXXFLAGS) $(LIBRARY_SRC_CFLAGS)
LDFLAGS = $(OPT_LDFLAGS) $(TARGET_LDFLAGS) $(USR_LDFLAGS) $(CMD_LDFLAGS)\
$(POSIX_LDFLAGS) $(ARCH_DEP_LDFLAGS) $(DEBUG_LDFLAGS) $(OP_SYS_LDFLAGS)\
$($(BUILD_CLASS)_LDFLAGS) $(RUNTIME_LDFLAGS) $(CODE_LDFLAGS)
LDFLAGS = $(OPT_LDFLAGS) $(TARGET_LDFLAGS) $(USR_LDFLAGS) $(CMD_LDFLAGS) \
$(POSIX_LDFLAGS) $(ARCH_DEP_LDFLAGS) $(DEBUG_LDFLAGS) $(OP_SYS_LDFLAGS) \
$($(BUILD_CLASS)_LDFLAGS) $(RUNTIME_LDFLAGS) $(CODE_LDFLAGS)
LDLIBS = $(POSIX_LDLIBS) $(ARCH_DEP_LDLIBS) $(DEBUG_LDLIBS) $(OP_SYS_LDLIBS)\
$(GNU_LDLIBS_$(GNU))
LDLIBS = $(POSIX_LDLIBS) $(ARCH_DEP_LDLIBS) $(DEBUG_LDLIBS) $(OP_SYS_LDLIBS) \
$(GNU_LDLIBS_$(GNU))
CPPFLAGS = $($(BUILD_CLASS)_CPPFLAGS) $(POSIX_CPPFLAGS) $(OPT_CPPFLAGS)\
$(DEBUG_CPPFLAGS) $(WARN_CPPFLAGS) $(BASE_CPPFLAGS) $(TARGET_CPPFLAGS)\
$(USR_CPPFLAGS) $(CMD_CPPFLAGS) $(ARCH_DEP_CPPFLAGS) $(OP_SYS_CPPFLAGS)\
$(OP_SYS_INCLUDE_CPPFLAGS) $(CODE_CPPFLAGS) $(API_CPPFLAGS)
CPPFLAGS = $($(BUILD_CLASS)_CPPFLAGS) $(POSIX_CPPFLAGS) $(OPT_CPPFLAGS) \
$(DEBUG_CPPFLAGS) $(WARN_CPPFLAGS) $(BASE_CPPFLAGS) $(TARGET_CPPFLAGS) \
$(USR_CPPFLAGS) $(CMD_CPPFLAGS) $(ARCH_DEP_CPPFLAGS) $(OP_SYS_CPPFLAGS) \
$(OP_SYS_INCLUDE_CPPFLAGS) $(CODE_CPPFLAGS) $(API_CPPFLAGS)
#--------------------------------------------------
# ar definition default
@@ -396,7 +407,7 @@ INSTALL_DOCS = $(DOCS:%= $(INSTALL_DOC)/%)
INSTALL_HTMLS = $(HTMLS:%= $(INSTALL_HTML)/$(HTMLS_DIR)/%)
INSTALL_TEMPLATE = $(addprefix $(INSTALL_TEMPLATES_SUBDIR)/, \
$(subst $(CONFIG),top/configure,$(TEMPLATES)))
$(subst $(CONFIG),top/configure,$(TEMPLATES)))
INSTALL_CONFIGS = $(CONFIGS:%= $(INSTALL_CONFIG)/%)
INSTALL_BIN_INSTALLS = $(addprefix $(INSTALL_BIN)/,$(notdir $(BIN_INSTALLS)))
@@ -431,42 +442,41 @@ INSTALL_INC += $(foreach inc, $(INC), \
$(CMPLR_INSTALL_INC) \
$(OS_INSTALL_INC) \
$(GENERIC_INSTALL_INC) \
$(GENERATED_INSTALL_INC) ) )
INSTALL_INC += $(addprefix $(INSTALL_INCLUDE)/os/$(OS_CLASS)/, $(INC_$(OS_CLASS)) )
$(GENERATED_INSTALL_INC)))
INSTALL_INC += $(addprefix $(INSTALL_INCLUDE)/os/$(OS_CLASS)/, $(INC_$(OS_CLASS)))
#
# Rule 0
#
CMPLR_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/compiler/$(CMPLR_CLASS)/, $(INSTALL_INC_jjj) )
INSTALL_INC_jjj = $(foreach dir, $(CMPLR_SRC_DIRS), $(INSTALL_INC_iii) )
INSTALL_INC_iii = $(subst $(dir)/, , $(INSTALL_INC_hhh) )
INSTALL_INC_hhh = $(wildcard $(addsuffix /$(inc), $(dir)) )
CMPLR_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/compiler/$(CMPLR_CLASS)/, \
$(foreach dir, $(CMPLR_SRC_DIRS), \
$(subst $(dir)/,, $(wildcard $(addsuffix /$(inc), $(dir))))))
#
# Rule 1
#
OS_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/os/$(OS_CLASS)/, $(INSTALL_INC_ggg) )
INSTALL_INC_ggg = $(foreach dir, $(OS_SRC_DIRS), $(INSTALL_INC_fff) )
INSTALL_INC_fff = $(subst $(dir)/, , $(INSTALL_INC_eee) )
INSTALL_INC_eee = $(wildcard $(addsuffix /$(inc), $(dir)) )
OS_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/os/$(OS_CLASS)/, \
$(foreach dir, $(OS_SRC_DIRS), \
$(subst $(dir)/,, $(wildcard $(addsuffix /$(inc), $(dir))))))
#
# Rule 2
#
GENERIC_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/, $(INSTALL_INC_ccc) )
INSTALL_INC_ccc = $(foreach dir, .. $(SRC_DIRS), $(INSTALL_INC_bbb) )
INSTALL_INC_bbb = $(subst $(dir)/, , $(INSTALL_INC_aaa) )
INSTALL_INC_aaa = $(wildcard $(addsuffix /$(inc), $(dir)) )
GENERIC_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/, \
$(foreach dir, .. $(SRC_DIRS), \
$(subst $(dir)/,, $(wildcard $(addsuffix /$(inc), $(dir))))))
#
# Rule 3
#
GENERATED_INSTALL_INC = $(INSTALL_INCLUDE)/$(inc)
COMMON_INC += $(filter $(COMMON_DIR)/%, $(foreach file, $(INC), \
$(firstword $(SOURCE_INC) $(COMMON_DIR)/$(file) ) ) )
SOURCE_INC = $(wildcard $(file) $(SOURCE_INC_bbb) )
SOURCE_INC_bbb = $(foreach dir, $(ALL_SRC_DIRS), $(SOURCE_INC_aaa) )
SOURCE_INC_aaa = $(addsuffix /$(file), $(dir) )
#---------------------------------------------------------------
# Files listed in INC that must first be created in O.Common
COMMON_INC += $(filter $(COMMON_DIR)/%, \
$(foreach file, $(INC), \
$(firstword $(wildcard $(file) \
$(foreach dir, $(ALL_SRC_DIRS), \
$(addsuffix /$(file), $(dir)))) $(COMMON_DIR)/$(file))))
endif

View File

@@ -2,11 +2,11 @@
EPICS_DATABASE_MAJOR_VERSION = 3
EPICS_DATABASE_MINOR_VERSION = 21
EPICS_DATABASE_MAINTENANCE_VERSION = 0
EPICS_DATABASE_MAINTENANCE_VERSION = 1
# Development flag, set to zero for release versions
EPICS_DATABASE_DEVELOPMENT_FLAG = 0
EPICS_DATABASE_DEVELOPMENT_FLAG = 1
# Immediately after a release the MAINTENANCE_VERSION
# will be incremented and the DEVELOPMENT_FLAG set to 1

View File

@@ -2,11 +2,11 @@
EPICS_LIBCOM_MAJOR_VERSION = 3
EPICS_LIBCOM_MINOR_VERSION = 21
EPICS_LIBCOM_MAINTENANCE_VERSION = 0
EPICS_LIBCOM_MAINTENANCE_VERSION = 1
# Development flag, set to zero for release versions
EPICS_LIBCOM_DEVELOPMENT_FLAG = 0
EPICS_LIBCOM_DEVELOPMENT_FLAG = 1
# Immediately after a release the MAINTENANCE_VERSION
# will be incremented and the DEVELOPMENT_FLAG set to 1

View File

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

View File

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

View File

@@ -77,7 +77,7 @@ OP_SYS_LDFLAGS += -dynamic -Z -L$(SDK_DIR)/usr/lib -L$(SDK_DIR)/usr/lib/system
# Shared libraries
SHRLIB_VERSION = $(EPICS_VERSION).$(EPICS_REVISION).$(EPICS_MODIFICATION)
SHRLIB_LDFLAGS = -dynamiclib -flat_namespace -undefined suppress \
-install_name $(shell $(FULLPATHNAME) $(INSTALL_LIB))/$@ \
-install_name $(abspath $(INSTALL_LIB))/$@ \
-compatibility_version $(EPICS_VERSION).$(EPICS_REVISION) \
-current_version $(SHRLIB_VERSION)
SHRLIB_SUFFIX_BASE = .dylib

View File

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

View File

@@ -10,6 +10,46 @@ 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.6.1
<!-- Insert new items immediately below here ... -->
### Fix for `undefined` in configure/RELEASE files
Prevents `Use of uninitialized value` warnings from convertRelease.pl.
### Colorized Messages for errlog
Many internal error messages now emit ANSI escape sequences to highlight the
words "ERROR" and "WARNING" in an attempt to make occurrences more noticeable
during IOC startup.
The macros `ERL_ERROR` and `ERL_WARNING` are defined for external usage,
and expand as string constants. eg.
```c
#include <errlog.h>
#ifndef ERL_ERROR
# define ERL_ERROR "ERROR"
#endif
void fn() {
...
errlogPrintf(ERL_ERROR ": something bad happens :(\n");
```
ANSI escapes are automatically removed from errlog output not destined
for a terminal. For example, for logClient, if stderr is redirected,
or if unsupported (`$TERM` not set, or Windows < 10).
### `dbnd` filter pass through `DBE_ALARM|DBE_PROPERTY`
The `dbnd` server side filter now passes through alarm and property
change events, even when not exceeding the deadband.
-----
## EPICS Release 7.0.6.1
### `mbboDirectRecord` enhancements

View File

@@ -188,7 +188,7 @@ int main ( int argc, char ** argv )
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
epicsSocketDestroy ( sock );
errlogPrintf ("casw: error from recv was = \"%s\"\n",
errlogPrintf ("casw: " ERL_ERROR " from recv was = \"%s\"\n",
sockErrBuf );
return -1;
}

View File

@@ -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 );
}
}
@@ -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 );
}
@@ -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 );
}
}
@@ -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" );

View File

@@ -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 );
}
}

View File

@@ -85,7 +85,7 @@ static epicsEventId startStopEvent;
static char *threadNamePrefix[NUM_CALLBACK_PRIORITIES] = {
"cbLow", "cbMedium", "cbHigh"
};
#define FULL_MSG(name) "callbackRequest: " name " ring buffer full\n"
#define FULL_MSG(name) "callbackRequest: " ERL_ERROR " " name " ring buffer full\n"
static char *fullMessage[NUM_CALLBACK_PRIORITIES] = {
FULL_MSG("cbLow"), FULL_MSG("cbMedium"), FULL_MSG("cbHigh")
};
@@ -326,17 +326,17 @@ 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: Callbacks not initialized\n");
epicsInterruptContextMessage("callbackRequest: " ERL_ERROR " Callbacks not initialized\n");
return S_db_notInit;
}
if (mySet->queueOverflow) return S_db_bufFull;

View File

@@ -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;
}
}

View File

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

View File

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

View File

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

View File

@@ -886,6 +886,8 @@ unsigned int caEventMask
if ( (dbChannelField(pevent->chan) == (void *)pField || pField==NULL) &&
(caEventMask & pevent->select)) {
db_field_log *pLog = db_create_event_log(pevent);
if(pLog)
pLog->mask = caEventMask & pevent->select;
pLog = dbChannelRunPreChain(pevent->chan, pLog);
if (pLog) db_queue_event_log(pevent, pLog);
}

View File

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

View File

@@ -58,7 +58,7 @@ void camsgtask ( void *pParm )
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf("CAS: FIONREAD error: %s\n",
errlogPrintf("CAS: FIONREAD " ERL_ERROR ": %s\n",
sockErrBuf);
cas_send_bs_msg(client, TRUE);
}

View File

@@ -139,7 +139,7 @@ void cas_send_bs_msg ( struct client *pclient, int lock_needed )
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf ("CAS: Socket shutdown error: %s\n",
errlogPrintf ("CAS: Socket shutdown " ERL_ERROR ": %s\n",
sockErrBuf );
}
}

View File

@@ -86,7 +86,7 @@ static void req_server (void *pParm)
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf("CAS: Client accept error: %s (%d)\n",
errlogPrintf("CAS: Client accept " ERL_ERROR ": %s (%d)\n",
sockErrBuf, (int)addLen );
epicsThreadSleep(15.0);
continue;
@@ -131,7 +131,7 @@ int tryBind(SOCKET sock, const osiSockAddr* addr, const char *name)
{
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf ( "CAS: %s bind error: %s\n",
errlogPrintf ( "CAS: %s bind " ERL_ERROR ": %s\n",
name, sockErrBuf );
epicsThreadSuspendSelf ();
}
@@ -196,7 +196,7 @@ SOCKET* rsrv_grab_tcp(unsigned short *port)
char sockErrBuf[64];
epicsSocketConvertErrnoToString (
sockErrBuf, sizeof ( sockErrBuf ) );
errlogPrintf ( "CAS: getsockname error: %s\n",
errlogPrintf ( "CAS: getsockname " ERL_ERROR ": %s\n",
sockErrBuf );
epicsThreadSuspendSelf ();
ok = 0;
@@ -576,12 +576,12 @@ void rsrv_init (void)
if ( sport != ca_server_port ) {
ca_server_port = sport;
errlogPrintf ( "cas warning: Configured TCP port was unavailable.\n");
errlogPrintf ( "cas warning: Using dynamically assigned TCP port %hu,\n",
errlogPrintf ( "cas " ERL_WARNING ": Configured TCP port was unavailable.\n");
errlogPrintf ( "cas " ERL_WARNING ": Using dynamically assigned TCP port %hu,\n",
ca_server_port );
errlogPrintf ( "cas warning: but now two or more servers share the same UDP port.\n");
errlogPrintf ( "cas warning: Depending on your IP kernel this server may not be\n" );
errlogPrintf ( "cas warning: reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)\n" );
errlogPrintf ( "cas " ERL_WARNING ": but now two or more servers share the same UDP port.\n");
errlogPrintf ( "cas " ERL_WARNING ": Depending on your IP kernel this server may not be\n" );
errlogPrintf ( "cas " ERL_WARNING ": reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)\n" );
}
}

View File

@@ -94,7 +94,7 @@ void rsrv_online_notify_task(void *pParm)
epicsSocketConvertErrorToString(sockErrBuf, sizeof(sockErrBuf), err);
ipAddrToDottedIP(&pAddr->addr.ia, sockDipBuf, sizeof(sockDipBuf));
errlogPrintf ( "CAS: CA beacon send to %s error: %s\n",
errlogPrintf ( "CAS: CA beacon send to %s " ERL_ERROR ": %s\n",
sockDipBuf, sockErrBuf);
lastError[i] = err;

View File

@@ -20,7 +20,7 @@
#include <chfPlugin.h>
#include <recGbl.h>
#include <epicsExit.h>
#include <db_field_log.h>
#include <dbAccess.h>
#include <epicsExport.h>
typedef struct myStruct {
@@ -81,8 +81,8 @@ static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) {
status = dbFastGetConvertRoutine[pfl->field_type][DBR_DOUBLE]
(localAddr.pfield, (void*) &val, &localAddr);
if (!status) {
send = 0;
recGblCheckDeadband(&my->last, val, my->hyst, &send, 1);
send = pfl->mask & ~(DBE_VALUE|DBE_LOG);
recGblCheckDeadband(&my->last, val, my->hyst, &send, pfl->mask & (DBE_VALUE|DBE_LOG));
if (send && my->mode == 1) {
my->hyst = val * my->cval/100.;
}

View File

@@ -50,13 +50,6 @@ void dbTestIoc_registerRecordDeviceDriver(struct dbBase *);
static epicsEventId waitEvent;
static unsigned waitCounter;
static
void waitForUpdateN(DBLINK *plink, unsigned long n)
{
while(dbCaGetUpdateCount(plink)<n)
epicsThreadSleep(0.01);
}
static
void putLink(DBLINK *plink, short dbr, const void*buf, long nReq)
{
@@ -133,14 +126,14 @@ static void testNativeLink(void)
testOk1(psrclnk->type==CA_LINK);
waitForUpdateN(psrclnk, 1);
testdbCaWaitForUpdateCount(psrclnk, 1);
dbScanLock((dbCommon*)ptarg);
ptarg->val = 42;
db_post_events(ptarg, &ptarg->val, DBE_VALUE|DBE_ALARM|DBE_ARCHIVE);
dbScanUnlock((dbCommon*)ptarg);
waitForUpdateN(psrclnk, 2);
testdbCaWaitForUpdateCount(psrclnk, 2);
dbScanLock((dbCommon*)psrc);
/* local CA_LINK connects immediately */
@@ -218,14 +211,14 @@ static void testStringLink(void)
testOk1(psrclnk->type==CA_LINK);
waitForUpdateN(psrclnk, 1);
testdbCaWaitForUpdateCount(psrclnk, 1);
dbScanLock((dbCommon*)ptarg);
strcpy(ptarg->desc, "hello");
db_post_events(ptarg, &ptarg->desc, DBE_VALUE|DBE_ALARM|DBE_ARCHIVE);
dbScanUnlock((dbCommon*)ptarg);
waitForUpdateN(psrclnk, 2);
testdbCaWaitForUpdateCount(psrclnk, 2);
dbScanLock((dbCommon*)psrc);
/* local CA_LINK connects immediately */
@@ -400,7 +393,7 @@ static void testArrayLink(unsigned nsrc, unsigned ntarg)
testIocInitOk();
eltc(1);
waitForUpdateN(psrclnk, 1);
testdbCaWaitForUpdateCount(psrclnk, 1);
bufsrc = psrc->bptr;
buftarg= ptarg->bptr;
@@ -421,7 +414,7 @@ static void testArrayLink(unsigned nsrc, unsigned ntarg)
db_post_events(ptarg, &ptarg->val, DBE_VALUE|DBE_ALARM|DBE_ARCHIVE);
dbScanUnlock((dbCommon*)ptarg);
waitForUpdateN(psrclnk, 2);
testdbCaWaitForUpdateCount(psrclnk, 2);
dbScanLock((dbCommon*)psrc);
testDiag("fetch source.INP into source.BPTR");

View File

@@ -13,6 +13,7 @@
#include <string.h>
#include "dbAccess.h"
#include "dbStaticLib.h"
#include "dbAccessDefs.h"
#include "db_field_log.h"
@@ -46,6 +47,7 @@ static void fl_setup(dbChannel *chan, db_field_log *pfl) {
pfl->stat = prec->stat;
pfl->sevr = prec->sevr;
pfl->time = prec->time;
pfl->mask = DBE_VALUE;
pfl->field_type = dbChannelFieldType(chan);
pfl->field_size = dbChannelFieldSize(chan);
pfl->no_elements = dbChannelElements(chan);

View File

@@ -8,6 +8,8 @@
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "dbAccess.h"
#include "dbStaticLib.h"
#include "dbTest.h"
@@ -116,6 +118,8 @@ void checkAsyncOutput(const char *rec, dbCommon *async)
strcpy(proc, rec);
strcat(proc, ".PROC");
testdbCaWaitForConnect(dbGetDevLink(testdbRecordPtr(rec)));
testdbPutFieldOk(proc, DBF_CHAR, 1);
epicsEventWait(asyncEvent);

View File

@@ -33,15 +33,16 @@
#include "epicsExport.h"
static
void testmbbioFields(const char* rec, unsigned int value)
void testmbbioFields(char dir, unsigned n, unsigned int value)
{
char field[40];
unsigned int i;
testdbGetFieldEqual(rec, DBF_ULONG, value);
sprintf(field,"d%c%d", dir, n);
testdbGetFieldEqual(field, DBF_ULONG, value);
for (i=0; i < 32; i++)
{
sprintf(field,"%s.B%X", rec, i);
sprintf(field,"d%c%d.B%X", dir, n, i);
testdbGetFieldEqual(field, DBF_ULONG, (value>>i)&1);
}
}
@@ -49,16 +50,14 @@ void testmbbioFields(const char* rec, unsigned int value)
static
void testmbbioRecords(unsigned int count, unsigned int value)
{
char rec[40];
unsigned int i;
for (i = 1; i <= count; i++)
{
sprintf(rec, "do%d", i);
testDiag(" ### %s ###", rec);
testmbbioFields(rec, value);
sprintf(rec, "di%d", i);
testmbbioFields(rec, value);
testDiag(" ### do%d ###", i);
testmbbioFields('o', i, value);
testDiag(" ### di%d ###", i);
testmbbioFields('i', i, value);
}
}

View File

@@ -172,9 +172,12 @@ static
void testLinkSevr(void)
{
dbChannel *chan;
startRegressTestIoc("regressLinkSevr.db");
dbCaSync(); /* wait for CA links to connect */
dbCaSync(); /* wait for initial update */
/* wait for CA links to connect and receive an initial update */
testdbCaWaitForUpdateCount(dbGetDevLink(testdbRecordPtr("si2")), 1);
testdbCaWaitForUpdateCount(dbGetDevLink(testdbRecordPtr("li2")), 1);
chan = dbChannelCreate("ai.SEVR");
if(!chan)

View File

@@ -8,8 +8,11 @@
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "dbAccess.h"
#include "dbStaticLib.h"
#include "dbCa.h"
#include "dbTest.h"
#include "dbUnitTest.h"
#include "epicsThread.h"
@@ -60,14 +63,17 @@ void testGroup0(void)
testDiag("============ Starting %s ============", EPICS_FUNCTION);
testdbPutFieldOk("source", DBR_LONG, 1);
/* The above put sends CA monitors to all of the CA links, but
* doesn't trigger record processing (the links are not CP/CPP).
* How could we wait until all of those monitors have arrived,
* instead of just waiting for an arbitrary time period?
*/
epicsThreadSleep(1.0); /* FIXME: Wait here? */
for (rec = records; *rec; rec++) {
DBLINK* plink = dbGetDevLink(testdbRecordPtr(*rec));
if(plink->type==CA_LINK)
testdbCaWaitForUpdateCount(plink, 1);
}
testdbPutFieldOk("source", DBR_LONG, 1);
for (rec = records; *rec; rec++) {
DBLINK* plink = dbGetDevLink(testdbRecordPtr(*rec));
if(plink->type==CA_LINK)
testdbCaWaitForUpdateCount(plink, 2);
if (strncmp(*rec, "lsi0", 4) != 0)
testdbGetFieldEqual(*rec, DBR_LONG, 0);
checkDtyp(*rec);
@@ -76,8 +82,10 @@ void testGroup0(void)
}
testdbPutFieldOk("source", DBR_LONG, 0);
epicsThreadSleep(1.0); /* FIXME: Wait here as above */
for (rec = records; *rec; rec++) {
DBLINK* plink = dbGetDevLink(testdbRecordPtr(*rec));
if(plink->type==CA_LINK)
testdbCaWaitForUpdateCount(plink, 3);
doProcess(*rec);
testdbGetFieldEqual(*rec, DBR_LONG, 0);
}

View File

@@ -18,6 +18,9 @@
* Extensive tests so far only with qemu.
*/
/* trigger sys/syslog.h to emit prioritynames[] */
#define SYSLOG_NAMES
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -30,6 +33,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
@@ -93,7 +97,7 @@ epicsEventId dhcpDone;
* may provide by dhcp/bootp
* or environments from the "BIOS" like u-boot, motboot etc.
*/
char rtemsInit_NTP_server_ip[16] = "10.0.5.1";
char rtemsInit_NTP_server_ip[16] = "";
char bootp_server_name_init[128] = "1001.1001@10.0.5.1:/epics";
char bootp_boot_file_name_init[128] = "/epics/myExample/bin/RTEMS-beatnik/myExample.boot";
char bootp_cmdline_init[128] = "/epics/myExample/iocBoot/iocmyExample/st.cmd";
@@ -633,6 +637,42 @@ static void zonesetCallFunc(const iocshArgBuf *args)
zoneset(args[0].sval);
}
#ifndef RTEMS_LEGACY_STACK
static int bsd_log_to_erl(int level, const char *fmt, va_list ap)
{
return errlogVprintf(fmt, ap);
}
#endif // RTEMS_LEGACY_STACK
static void setlogmaskCallFunc(const iocshArgBuf *args)
{
const char* name = args[0].sval;
const CODE* cur;
if(!name) {
printf("Usage: setlogmask <level>\n"
"\n"
" Level names:\n");
for(cur = prioritynames; cur->c_name; cur++) {
printf(" %s\n", cur->c_name);
}
} else {
for(cur = prioritynames; cur->c_name; cur++) {
if(strcmp(name, cur->c_name)!=0)
continue;
(void)setlogmask(LOG_MASK(cur->c_val));
#ifndef RTEMS_LEGACY_STACK
rtems_bsd_setlogpriority(name);
#endif
return;
}
printf("Error: unknown log level.\n");
}
}
static const iocshArg setlogmaskArg0 = {"level name", iocshArgString};
static const iocshArg * const setlogmaskArgs[1] = {&setlogmaskArg0};
static const iocshFuncDef setlogmaskFuncDef = {"setlogmask",1,setlogmaskArgs,
"Set syslog() threshold level"};
/*
* Register RTEMS-specific commands
@@ -646,6 +686,7 @@ static void iocshRegisterRTEMS (void)
#endif
iocshRegister(&zonesetFuncDef, &zonesetCallFunc);
iocshRegister(&rtshellFuncDef, &rtshellCallFunc);
iocshRegister(&setlogmaskFuncDef, &setlogmaskCallFunc);
#if __RTEMS_MAJOR__ > 4
rtems_shell_init_environment();
#endif
@@ -685,89 +726,76 @@ exitHandler(void)
}
#ifndef RTEMS_LEGACY_STACK
static char* getPrimaryNetworkInterface(void)
{
// lookup available network interfaces
char ifnamebuf[IF_NAMESIZE];
char *ifname;
// get primary network interface
ifname = if_indextoname(1, &ifnamebuf[0]);
if (ifname == NULL) return (NULL);
printf("\n***** Primary Network interface : %s *****\n", ifname);
return (ifname);
}
static void
dhcpcd_hook_handler(rtems_dhcpcd_hook *hook, char *const *env)
{
int bound = 0;
char iName[16];
char *name;
char *value;
char * env_position;
(void)hook;
char interface[16] = "?";
char reason[16] = "?";
char new_host_name[32] = "RTEMShost";
struct dhcp_vars_t {
const char * const name;
char* var;
size_t varsize;
} dhcp_vars[] = {
#define DEFVAR(N) { #N, N, sizeof(N) }
DEFVAR(interface),
DEFVAR(reason),
DEFVAR(new_host_name),
#undef DEFVAR
#define DEFVAR(N, V) { N, V, sizeof(V) }
DEFVAR("new_ntp_servers", rtemsInit_NTP_server_ip),
DEFVAR("new_tftp_server_name", bootp_server_name_init),
DEFVAR("new_bootfile_name", bootp_boot_file_name_init),
DEFVAR("new_rtems_cmdline", bootp_cmdline_init),
#undef DEFVAR
{NULL}
};
(void)hook;
char ifnamebuf[IF_NAMESIZE];
sprintf(ifnamebuf, "%s", getPrimaryNetworkInterface());
while (*env != NULL) {
char const * interface = "interface";
char const * reason = "reason";
char const * bound_str = "BOUND";
printf("\n");
for (;NULL != *env;++env) {
printf("dhcpcd ---> '%s'\n", *env);
name = strtok_r(*env,"=", &env_position);
value = strtok_r(NULL,"=", &env_position);
printf("all out ---> %s = %s\n", name, value);
for(const struct dhcp_vars_t* var = dhcp_vars; var->name; var++) {
size_t namelen = strlen(var->name);
if (!strncmp(name, interface, strlen(interface)) &&
!strcmp(value, ifnamebuf)) {
snprintf(iName, sizeof(iName), "%s", value);
}
// assume "KEY=value" with no whitespace around '='
if(strncmp(*env, var->name, namelen)!=0 || (*env)[namelen]!='=')
continue;
if (!strncmp(name, reason, strlen(reason)) &&
!strncmp(value, bound_str, strlen(bound_str))) {
printf ("Interface %s bounded\n", iName);
bound = 1;
const char* value = *env + namelen+1;
size_t valuelen = strlen(value);
// require ordering of keys:
// interface=
// reason=
// all others...
if(var->var!=reason && var->var!=interface && !bound) {
// ignore others if !BOUND
} else if(valuelen >= var->varsize) {
printf(" Not enough space for value string. Expand buffer and recompile.\n");
} else {
memcpy(var->var, value, valuelen);
var->var[valuelen] = '\0';
printf(" '%s' = '%s'\n", var->name, var->var);
if(var->var==reason && strcmp(reason, "BOUND")==0) {
printf(" is BOUND\n");
bound = 1;
}
}
break;
}
if (bound) {
// as there is no ntp-support in rtems-libbsd, we call our own client
char const * new_ntp_servers = "new_ntp_servers";
char const * new_host_name = "new_host_name";
char const * new_tftp_server_name = "new_tftp_server_name";
if (!strncmp(name, new_ntp_servers, strlen(new_ntp_servers)))
snprintf(rtemsInit_NTP_server_ip,
sizeof(rtemsInit_NTP_server_ip),
"%s", value);
if (!strncmp(name, new_host_name, strlen(new_host_name)))
sethostname (value, strlen (value));
if (!strncmp(name, new_tftp_server_name, strlen(new_tftp_server_name))){
snprintf(rtems_bsdnet_bootp_server_name,
sizeof(bootp_server_name_init),
"%s", value);
printf(" rtems_bsdnet_bootp_server_name : %s\n", rtems_bsdnet_bootp_server_name);
}
if(!strncmp(name, "new_bootfile_name", 20)){
snprintf(rtems_bsdnet_bootp_boot_file_name,
sizeof(bootp_boot_file_name_init),
"%s", value);
printf(" rtems_bsdnet_bootp_boot_file_name : %s\n", rtems_bsdnet_bootp_boot_file_name);
}
if(!strncmp(name, "new_rtems_cmdline", 20)){
snprintf(rtems_bsdnet_bootp_cmdline,
sizeof(bootp_cmdline_init),
"%s", value);
printf(" rtems_bsdnet_bootp_cmdline : %s\n", rtems_bsdnet_bootp_cmdline);
}
}
++env;
}
if (bound)
if(bound) {
sethostname (new_host_name, strlen (new_host_name));
epicsEventSignal(dhcpDone);
printf("dhcpd BOUND\n");
}
}
static rtems_dhcpcd_hook dhcpcd_hook = {
@@ -816,10 +844,10 @@ default_network_dhcpcd(void)
static const char fhi_cfg[] =
"nodhcp6\n"
"ipv4only\n"
"option ntp_servers\n"
"option ntp-servers\n"
"option rtems_cmdline\n"
"option tftp_server_name\n"
"option bootfile_name\n"
"option tftp-server-name\n"
"option bootfile-name\n"
"define 129 string rtems_cmdline\n"
"timeout 0";
@@ -975,12 +1003,19 @@ POSIX_Init ( void *argument __attribute__((unused)))
rtems_get_version_string());
#ifndef RTEMS_LEGACY_STACK
#if defined(QEMU_FIXUPS) && defined(__i386__)
// glorious hack to stub out useless EEPROM check
// which takes sooooo longggg w/ QEMU
// Writes a 'ret' instruction to immediatly return to the caller
extern void _bsd_e1000_validate_nvm_checksum(void);
*(char*)&_bsd_e1000_validate_nvm_checksum = 0xc3;
#endif
/*
* Start network (libbsd)
*
* start qemu like this
* qemu-system-i386 -m 64 -no-reboot -serial stdio -display none \
* -net nic,model=rtl8139,macaddr=0e:b0:ba:5e:ba:11 -net user,restrict=yes \
* -net nic,model=e1000 -net user,restrict=yes \
* -append "--video=off --console=/dev/com1" -kernel libComTestHarness
*/
printf("\n***** Initializing network (libbsd, dhcpcd) *****\n");
@@ -990,9 +1025,6 @@ POSIX_Init ( void *argument __attribute__((unused)))
/* Let other tasks run to complete background work */
default_network_set_self_prio(RTEMS_MAXIMUM_PRIORITY - 1U);
/* suppress all output from bsd network initialization */
rtems_bsd_set_vprintf_handler(rtems_bsd_vprintf_handler_mute);
sc = rtems_bsd_initialize();
assert(sc == RTEMS_SUCCESSFUL);
@@ -1042,7 +1074,9 @@ POSIX_Init ( void *argument __attribute__((unused)))
/* until now there is no NTP support in libbsd -> Sebastian Huber ... */
printf("\n***** Until now no NTP support in RTEMS 5 with rtems-libbsd *****\n");
printf("\n***** Ask ntp server once... *****\n");
if (epicsNtpGetTime(rtemsInit_NTP_server_ip, &now) < 0) {
if (rtemsInit_NTP_server_ip[0]=='\0') {
printf ("***** No NTP server ...\n");
} else if (epicsNtpGetTime(rtemsInit_NTP_server_ip, &now) < 0) {
printf ("***** Can't get time from ntp ...\n");
} else {
if (clock_settime(CLOCK_REALTIME, &now) < 0){
@@ -1077,9 +1111,6 @@ POSIX_Init ( void *argument __attribute__((unused)))
rtems_bsdnet_synchronize_ntp (0, 0);
#endif // not RTEMS_LEGACY_STACK
/* show messages from network after initialization ? good idea? */
//rtems_bsd_set_vprintf_handler(bsd_vprintf_handler_old);
printf("\n***** Setting up file system *****\n");
initialize_remote_filesystem(argv, initialize_local_filesystem(argv));
fixup_hosts();
@@ -1124,6 +1155,12 @@ POSIX_Init ( void *argument __attribute__((unused)))
errlogFlush();
printf ("***** Starting EPICS application *****\n");
#ifndef RTEMS_LEGACY_STACK
// switch OS to async logging
rtems_bsd_set_vprintf_handler(bsd_log_to_erl);
#endif
#if 0
// Start an rtems shell before main, for debugging RTEMS system issues
rtems_shell_init("SHLL", RTEMS_MINIMUM_STACK_SIZE * 4,

View File

@@ -32,7 +32,7 @@
* Ticket URL: <http://devel.rtems.org/ticket/2375#comment:23>
*/
#if RTEMS_VERSION_INT<=VERSION_INT(4,10,0,0)
#if RTEMS_VERSION_INT<VERSION_INT(4,11,0,0)
extern void rtems_bsdnet_loopattach();
static struct rtems_bsdnet_ifconfig loopback_config = {
"lo0", /* name */
@@ -58,7 +58,7 @@ rtems_ne2kpci_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach);
static struct rtems_bsdnet_ifconfig ne2k_driver_config = {
"ne2", /* name */
rtems_ne2kpci_driver_attach, /* attach function */
#if RTEMS_VERSION_INT<=VERSION_INT(4,10,0,0)
#if RTEMS_VERSION_INT<VERSION_INT(4,11,0,0)
&loopback_config, /* link to next interface */
#else
NULL,
@@ -96,7 +96,7 @@ static struct rtems_bsdnet_ifconfig e3c509_driver_config = {
static struct rtems_bsdnet_ifconfig netdriver_config = {
RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */
RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */
#if RTEMS_VERSION_INT<=VERSION_INT(4,10,0,0)
#if RTEMS_VERSION_INT<VERSION_INT(4,11,0,0)
&loopback_config, /* link to next interface */
#endif
};

View File

@@ -21,15 +21,27 @@
#include "libComAPI.h"
#include "epicsAssert.h"
class LIBCOM_API SingletonUntyped {
class SingletonUntyped {
public:
SingletonUntyped ();
~SingletonUntyped ();
SingletonUntyped () :_pInstance ( 0 ), _refCount ( 0 ) {}
# if 0
~SingletonUntyped () {
// we don't assert fail on non-zero _refCount
// and or non nill _pInstance here because this
// is designed to tolerate situations where
// file scope epicsSingleton objects (which
// theoretically don't have storage lifespan
// issues) are deleted in a non-deterministic
// order
assert ( _refCount == 0 );
assert ( _pInstance == 0 );
}
# endif
typedef void * ( * PBuild ) ();
void incrRefCount ( PBuild );
LIBCOM_API void incrRefCount ( PBuild );
typedef void ( * PDestroy ) ( void * );
void decrRefCount ( PDestroy );
void * pInstance () const;
LIBCOM_API void decrRefCount ( PDestroy );
inline void * pInstance () const { return _pInstance; }
private:
void * _pInstance;
std :: size_t _refCount;
@@ -46,18 +58,56 @@ class epicsSingleton {
public:
class reference {
public:
reference ( epicsSingleton & );
reference ( const reference & );
~reference ();
reference ( epicsSingleton & es)
:_pSingleton ( & es )
{
es._singletonUntyped.
incrRefCount ( & epicsSingleton < TYPE > :: _build );
}
reference ( const reference & ref)
:_pSingleton ( ref._pSingleton )
{
assert ( _pSingleton );
_pSingleton->_singletonUntyped.
incrRefCount ( & epicsSingleton < TYPE > :: _build );
}
~reference () {
assert ( _pSingleton );
_pSingleton->_singletonUntyped.
decrRefCount ( & epicsSingleton < TYPE > :: _destroy );
}
// this somewhat convoluted reference of the return
// type ref through the epicsSingleton template is
// required for the archaic Tornado gnu compiler
typename epicsSingleton < TYPE > :: reference &
operator = ( const reference & );
TYPE * operator -> ();
const TYPE * operator -> () const;
TYPE & operator * ();
const TYPE & operator * () const;
operator = ( const reference & ref) {
if ( _pSingleton != ref._pSingleton ) {
assert ( _pSingleton );
_pSingleton->_singletonUntyped.
decrRefCount ( epicsSingleton < TYPE > :: _destroy );
_pSingleton = ref._pSingleton;
assert ( _pSingleton );
_pSingleton->_singletonUntyped.
incrRefCount ( & epicsSingleton < TYPE > :: _build );
}
return *this;
}
TYPE * operator -> () {
assert ( _pSingleton );
return reinterpret_cast < TYPE * >
( _pSingleton->_singletonUntyped.pInstance () );
}
const TYPE * operator -> () const {
assert ( _pSingleton );
return reinterpret_cast < const TYPE * >
( _pSingleton->_singletonUntyped.pInstance () );
}
TYPE & operator * () {
return * this->operator -> ();
}
const TYPE & operator * () const {
return * this->operator -> ();
}
private:
epicsSingleton * _pSingleton;
};
@@ -65,152 +115,25 @@ public:
epicsSingleton () {}
// mutex lock/unlock pair overhead incurred
// when either of these are called
reference getReference ();
const reference getReference () const;
reference getReference () {
return reference ( * this );
}
const reference getReference () const {
epicsSingleton < TYPE > * pConstCastAway =
const_cast < epicsSingleton < TYPE > * > ( this );
return pConstCastAway->getReference ();
}
private:
SingletonUntyped _singletonUntyped;
static void * _build ();
static void _destroy ( void * );
static void * _build () { return new TYPE (); }
static void _destroy ( void * pDestroyTypeless) {
TYPE * pDestroy =
reinterpret_cast < TYPE * > ( pDestroyTypeless );
delete pDestroy;
}
epicsSingleton ( const epicsSingleton & );
epicsSingleton & operator = ( const epicsSingleton & );
};
template < class TYPE >
inline epicsSingleton < TYPE > :: reference ::
reference ( epicsSingleton & es ):
_pSingleton ( & es )
{
es._singletonUntyped.
incrRefCount ( & epicsSingleton < TYPE > :: _build );
}
template < class TYPE >
inline epicsSingleton < TYPE > :: reference ::
reference ( const reference & ref ) :
_pSingleton ( ref._pSingleton )
{
assert ( _pSingleton );
_pSingleton->_singletonUntyped.
incrRefCount ( & epicsSingleton < TYPE > :: _build );
}
template < class TYPE >
inline epicsSingleton < TYPE > :: reference ::
~reference ()
{
assert ( _pSingleton );
_pSingleton->_singletonUntyped.
decrRefCount ( & epicsSingleton < TYPE > :: _destroy );
}
template < class TYPE >
typename epicsSingleton < TYPE > :: reference &
epicsSingleton < TYPE > :: reference ::
operator = ( const reference & ref )
{
if ( _pSingleton != ref._pSingleton ) {
assert ( _pSingleton );
_pSingleton->_singletonUntyped.
decrRefCount ( epicsSingleton < TYPE > :: _destroy );
_pSingleton = ref._pSingleton;
assert ( _pSingleton );
_pSingleton->_singletonUntyped.
incrRefCount ( & epicsSingleton < TYPE > :: _build );
}
return *this;
}
template < class TYPE >
inline TYPE *
epicsSingleton < TYPE > :: reference ::
operator -> ()
{
assert ( _pSingleton );
return reinterpret_cast < TYPE * >
( _pSingleton->_singletonUntyped.pInstance () );
}
template < class TYPE >
inline const TYPE *
epicsSingleton < TYPE > :: reference ::
operator -> () const
{
assert ( _pSingleton );
return reinterpret_cast < const TYPE * >
( _pSingleton->_singletonUntyped.pInstance () );
}
template < class TYPE >
inline TYPE &
epicsSingleton < TYPE > :: reference ::
operator * ()
{
return * this->operator -> ();
}
template < class TYPE >
inline const TYPE &
epicsSingleton < TYPE > :: reference ::
operator * () const
{
return * this->operator -> ();
}
inline SingletonUntyped :: SingletonUntyped () :
_pInstance ( 0 ), _refCount ( 0 )
{
}
inline void * SingletonUntyped :: pInstance () const
{
return _pInstance;
}
inline SingletonUntyped :: ~SingletonUntyped ()
{
// we don't assert fail on non-zero _refCount
// and or non nill _pInstance here because this
// is designed to tolerate situations where
// file scope epicsSingleton objects (which
// theoretically don't have storage lifespan
// issues) are deleted in a non-deterministic
// order
# if 0
assert ( _refCount == 0 );
assert ( _pInstance == 0 );
# endif
}
template < class TYPE >
void * epicsSingleton < TYPE > :: _build ()
{
return new TYPE ();
}
template < class TYPE >
void epicsSingleton < TYPE > ::
_destroy ( void * pDestroyTypeless )
{
TYPE * pDestroy =
reinterpret_cast < TYPE * > ( pDestroyTypeless );
delete pDestroy;
}
template < class TYPE >
inline typename epicsSingleton < TYPE > :: reference
epicsSingleton < TYPE > :: getReference ()
{
return reference ( * this );
}
template < class TYPE >
inline const typename epicsSingleton < TYPE > :: reference
epicsSingleton < TYPE > :: getReference () const
{
epicsSingleton < TYPE > * pConstCastAway =
const_cast < epicsSingleton < TYPE > * > ( this );
return pConstCastAway->getReference ();
}
#endif // epicsSingleton_h

View File

@@ -23,6 +23,8 @@
# define SIZE_MAX UINT_MAX
#endif
namespace {
static epicsThreadOnceId epicsSigletonOnceFlag ( EPICS_THREAD_ONCE_INIT );
static epicsMutex * pEPICSSigletonMutex = 0;
@@ -34,6 +36,8 @@ extern "C" void SingletonMutexOnce ( void * /* pParm */ )
pEPICSSigletonMutex = newEpicsMutex;
}
} // namespace
void SingletonUntyped :: incrRefCount ( PBuild pBuild )
{
epicsThreadOnce ( & epicsSigletonOnceFlag, SingletonMutexOnce, 0 );

File diff suppressed because it is too large Load Diff

View File

@@ -250,6 +250,42 @@ LIBCOM_API int errlogVprintfNoConsole(const char *pformat,va_list pvar);
*/
LIBCOM_API void errSymLookup(long status, char *pBuf, size_t bufLength);
/** @defgroup colormacros Color macros
*
* @brief Colorize string constants with ANSI terminal escapes.
*
* The ANSI_ESC_\* family of macros expand to individual escape sequences.
* The ANSI_\* family expand around a string constant to prepend a color, and append a RESET.
*
* @code
* // equivalent
* errlogPrintf(ERL_ERROR ": something is amiss\n");
* errlogPrintf(ANSI_RED("ERROR") ": something is amiss\n");
* errlogPrintf(ANSI_ESC_RED "ERROR" ANSI_ESC_RESET ": something is amiss\n");
* @endcode
*
* @since UNRELEASED
*
* @see errlogPrintf()
* @{
*/
#define ANSI_ESC_RED "\033[31;1m"
#define ANSI_ESC_GREEN "\033[32;1m"
#define ANSI_ESC_YELLOW "\033[33;1m"
#define ANSI_ESC_BLUE "\033[34;1m"
#define ANSI_ESC_MAGENTA "\033[35;1m"
#define ANSI_ESC_CYAN "\033[36;1m"
#define ANSI_ESC_RESET "\033[0m"
#define ANSI_RED(STR) ANSI_ESC_RED STR ANSI_ESC_RESET
#define ANSI_GREEN(STR) ANSI_ESC_GREEN STR ANSI_ESC_RESET
#define ANSI_YELLOW(STR) ANSI_ESC_YELLOW STR ANSI_ESC_RESET
#define ANSI_BLUE(STR) ANSI_ESC_BLUE STR ANSI_ESC_RESET
#define ANSI_MAGENTA(STR) ANSI_ESC_MAGENTA STR ANSI_ESC_RESET
#define ANSI_CYAN(STR) ANSI_ESC_CYAN STR ANSI_ESC_RESET
#define ERL_ERROR ANSI_RED("ERROR")
#define ERL_WARNING ANSI_MAGENTA("WARNING")
/** @} */
#ifdef __cplusplus
}
#endif

View File

@@ -588,7 +588,7 @@ static MAC_ENTRY *lookup( MAC_HANDLE *handle, const char *name, int special )
}
if ( (special == FALSE) && (entry == NULL) &&
(handle->flags & FLAG_USE_ENVIRONMENT) ) {
char *value = getenv(name);
char *value = name && *name ? getenv(name) : NULL;
if (value) {
entry = create( handle, name, FALSE );
if ( entry ) {

View File

@@ -28,6 +28,13 @@
# endif
#endif
#ifdef __rtems__
# include <syslog.h>
# ifndef RTEMS_LEGACY_STACK
# include <rtems/bsd/bsd.h>
# endif
#endif
#include "epicsThread.h"
#include "epicsMutex.h"
#include "epicsUnitTest.h"
@@ -95,6 +102,18 @@ static int testReportHook(int reportType, char *message, int *returnValue)
static void testOnce(void *dummy) {
testLock = epicsMutexMustCreate();
perlHarness = (getenv("HARNESS_ACTIVE") != NULL);
#ifdef __rtems__
// syslog() on RTEMS prints to stdout, which will interfere with test output.
// setlogmask() ignores empty mask, so must allow at least one level.
(void)setlogmask(LOG_MASK(LOG_CRIT));
printf("# mask syslog() output\n");
#ifndef RTEMS_LEGACY_STACK
// with libbsd setlogmask() is a no-op :(
// name strings in sys/syslog.h
rtems_bsd_setlogpriority("crit");
#endif
#endif
#ifdef _WIN32
#ifdef HAVE_SETERROMODE
/* SEM_FAILCRITICALERRORS - Don't display modal dialog

View File

@@ -118,6 +118,11 @@ int epicsStdCall epicsStdoutPrintf(const char *pFormat, ...)
return nchar;
}
int epicsStdCall epicsStdoutVPrintf(const char *pformat, va_list ap)
{
return vfprintf(epicsGetStdout(), pformat, ap);
}
int epicsStdCall epicsStdoutPuts(const char *str)
{
return fprintf(epicsGetStdout(), "%s\n", str);

View File

@@ -36,6 +36,7 @@
* - `printf` becomes epicsStdoutPrintf()
* - `puts` becomes epicsStdoutPuts()
* - `putchar` becomes epicsStdoutPutchar()
* - `vprintf` becomes epicsStdoutVPrintf()
*
* The epicsSetThreadStdin(), epicsSetThreadStdout() and epicsSetThreadStderr()
* routines allow the standard file streams to be redirected on a per thread
@@ -75,6 +76,11 @@ extern "C" {
# endif
# define printf epicsStdoutPrintf
# ifdef vprintf
# undef vprintf
# endif
# define vprintf epicsStdoutVPrintf
# ifdef puts
# undef puts
# endif
@@ -172,6 +178,8 @@ LIBCOM_API void epicsStdCall epicsSetThreadStderr(FILE *);
LIBCOM_API int epicsStdCall epicsStdoutPrintf(
const char *pformat, ...) EPICS_PRINTF_STYLE(1,2);
LIBCOM_API int epicsStdCall epicsStdoutVPrintf(
const char *pformat, va_list ap);
LIBCOM_API int epicsStdCall epicsStdoutPuts(const char *str);
LIBCOM_API int epicsStdCall epicsStdoutPutchar(int c);
@@ -185,6 +193,7 @@ using ::epicsGetStdin;
using ::epicsGetStdout;
using ::epicsGetStderr;
using ::epicsStdoutPrintf;
using ::epicsStdoutVPrintf;
using ::epicsStdoutPuts;
using ::epicsStdoutPutchar;
}

View File

@@ -36,12 +36,12 @@
#define checkStatus(status,message) \
if((status)) { \
errlogPrintf("epicsMutex %s failed: error %s\n", \
errlogPrintf("epicsMutex %s failed: " ERL_ERROR " %s\n", \
(message), strerror((status))); \
}
#define checkStatusQuit(status,message,method) \
if(status) { \
errlogPrintf("epicsMutex %s failed: error %s\n", \
errlogPrintf("epicsMutex %s failed: " ERL_ERROR " %s\n", \
(message), strerror((status))); \
cantProceed((method)); \
}

View File

@@ -34,7 +34,7 @@
#define checkStatus(status,message) \
if ((status)) { \
errlogPrintf("epicsSpin %s failed: error %s\n", \
errlogPrintf("epicsSpin %s failed: " ERL_ERROR " %s\n", \
(message), strerror((status))); \
}

View File

@@ -94,12 +94,12 @@ static epicsThreadOSD *createImplicit(void);
#define checkStatus(status,message) \
if((status)) {\
errlogPrintf("%s error %s\n",(message),strerror((status))); \
errlogPrintf("%s " ERL_ERROR " %s\n",(message),strerror((status))); \
}
#define checkStatusQuit(status,message,method) \
if(status) { \
errlogPrintf("%s error %s\n",(message),strerror((status))); \
errlogPrintf("%s " ERL_ERROR " %s\n",(message),strerror((status))); \
cantProceed((method)); \
}

View File

@@ -157,10 +157,9 @@ void yajl_string_decode(yajl_buf buf, const unsigned char * str,
end+=3;
/* check if this is a surrogate */
if ((codepoint & 0xFC00) == 0xD800) {
end++;
if (str[end] == '\\' && str[end + 1] == 'u') {
if (str[end + 1] == '\\' && str[end + 2] == 'u') {
unsigned int surrogate = 0;
hexToDigit(&surrogate, 4, str + end + 2);
hexToDigit(&surrogate, 4, str + ++end + 2);
codepoint =
(((codepoint & 0x3F) << 10) |
((((codepoint >> 6) & 0xF) + 1) << 16) |

View File

@@ -28,6 +28,11 @@
#include "envDefs.h"
#include "osiSock.h"
#include "fdmgr.h"
#include "epicsString.h"
/* private between errlog.c and this test */
LIBCOM_API
void errlogStripANSI(char *msg);
#define LOGBUFSIZE 2048
@@ -167,13 +172,40 @@ void logClient(void* raw, const char* msg)
epicsEventSignal(pvt->done);
}
static
void testANSIStrip(void)
{
char scratch[64];
char actual[128];
char input[128];
#define testEscape(INP, EXPECT) \
strcpy(scratch, INP); \
epicsStrnEscapedFromRaw(input, sizeof(input), INP, sizeof(INP)); \
errlogStripANSI(scratch); \
epicsStrnEscapedFromRaw(actual, sizeof(actual), scratch, epicsStrnLen(scratch, sizeof(scratch))); \
testOk(strcmp(scratch, EXPECT)==0, "input \"%s\" expect \"%s\" actual \"%s\"", input, EXPECT, actual)
testEscape("", "");
testEscape("hello", "hello");
testEscape("he\033[31;1mllo", "hello");
testEscape("\033[31;1mhello", "hello");
testEscape("hello\033[31;1m", "hello");
testEscape("hello\033[31;1", "hello");
testEscape("hello\033[", "hello");
testEscape("hello\033", "hello");
#undef testEscape
}
MAIN(epicsErrlogTest)
{
size_t mlen, i, N;
char msg[256];
clientPvt pvt, pvt2;
testPlan(40);
testPlan(48);
testANSIStrip();
strcpy(msg, truncmsg);
@@ -211,10 +243,11 @@ MAIN(epicsErrlogTest)
errlogAddListener(&logClient, &pvt2);
/* logClient will not see ANSI escape sequences */
pvt2.expect = pvt.expect = "Testing2";
pvt2.checkLen = pvt.checkLen = strlen(pvt.expect);
errlogPrintfNoConsole("%s", pvt.expect);
errlogPrintfNoConsole("%s", ANSI_RED("Testing2"));
errlogFlush();
epicsEventMustWait(pvt.done);
@@ -370,7 +403,8 @@ MAIN(epicsErrlogTest)
testDiag("Logged %u messages", pvt.count);
epicsEventMustWait(pvt.done);
testEqInt(pvt.count, N+1);
/* Expect N+1 messages +- 1 depending on impl */
testOk(pvt.count >= N && pvt.count<=N+2, "Logged %u messages, expected %zu", pvt.count, N+1);
/* Clean up */
testOk(1 == errlogRemoveListeners(&logClient, &pvt),

View File

@@ -64,6 +64,15 @@ static void testEpicsSnprintf(void) {
}
}
void checkVPrintf(const char *pFormat, ...)
{
va_list pvar;
va_start(pvar, pFormat);
vprintf(pFormat, pvar);
va_end(pvar);
}
void testStdoutRedir (const char *report)
{
FILE *realStdout = stdout;
@@ -85,7 +94,8 @@ void testStdoutRedir (const char *report)
testOk1(stdout == stream);
printf(LINE_1);
printf(LINE_2);
putchar('\n');
checkVPrintf(LINE_2);
epicsSetThreadStdout(0);
testOk1(epicsGetStdout() == realStdout);
@@ -113,15 +123,21 @@ void testStdoutRedir (const char *report)
fclose(stream);
return;
}
testOk(strcmp(linebuf, LINE_1) == 0, "First line correct");
testOk(strcmp(linebuf, LINE_1) == 0, "printf() line correct");
if (!testOk1(fgets(linebuf, buflen, stream) != NULL)) {
testDiag("File read error: %s", strerror(errno));
testSkip(1, "No line to compare.");
testSkip(1, "Nothing to compare.");
} else
testOk(strcmp(linebuf, LINE_2) == 0, "Second line");
testOk(strcmp(linebuf, "\n") == 0, "putchar() line correct");
testOk(!fgets(linebuf, buflen, stream), "File ends");
if (!testOk1(fgets(linebuf, buflen, stream) != NULL)) {
testDiag("File read error: %s", strerror(errno));
testSkip(1, "Nothing to compare.");
} else
testOk(strcmp(linebuf, LINE_2) == 0, "vprintf() line correct");
testOk(!fgets(linebuf, buflen, stream) && feof(stream), "End of file");
if (!testOk1(!fclose(stream)))
testDiag("fclose error: %s\n", strerror(errno));
@@ -129,7 +145,7 @@ void testStdoutRedir (const char *report)
MAIN(epicsStdioTest)
{
testPlan(163);
testPlan(165);
testEpicsSnprintf();
#ifdef __rtems__
/* ensure there is a writable area */

View File

@@ -3354,6 +3354,18 @@ sub cases {
"memory leaks:\t0"
]
},
{
name => "truncated_surrogate",
opts => [],
input => [
"\"\\uDBFF\360\237\222\200\"",
""
],
gives => [
"string: '?\360\237\222\200'",
"memory leaks:\t0"
]
},
{
name => "unescaped_bulgarian",
opts => [],

View File

@@ -67,6 +67,7 @@ sub readRelease {
my ($uvar) = m/^ undefine \s+ ($MVAR)/x;
if ($uvar ne '') {
delete $Rmacros->{$uvar};
@$Rapps = grep($_ ne $uvar, @$Rapps);
next;
}