Compare commits
194 Commits
R7.0.8.1
...
PSI-7.0.6.
| Author | SHA1 | Date | |
|---|---|---|---|
| 565ccae0b5 | |||
| ddfa24e15d | |||
| 6dc7224cea | |||
| 25a2258663 | |||
|
|
13bd6bac5f | ||
| 39de02f350 | |||
| efd9e7908a | |||
| 96fe9306c7 | |||
| 0caa5a045c | |||
| 4ffa5c8c88 | |||
| 5e076e6d30 | |||
| dcb2c5affd | |||
| 3ac3906fea | |||
| 2d597a68b9 | |||
| 1bfe3dec3c | |||
| ea0b05c32b | |||
| 9c64469f1e | |||
| 2a4ebdf347 | |||
| d5756faef4 | |||
| 77fb5cf425 | |||
| 46141e98d5 | |||
| 5ac51f86ad | |||
| 0af4fce080 | |||
| 4fb42763a2 | |||
| 211d29c0e1 | |||
| da7bca9c16 | |||
| ec346a7b8d | |||
| 81d1082bfd | |||
| 3f8cee7d73 | |||
| aae9d68818 | |||
| f43d21eab3 | |||
| 9e1e4ddd91 | |||
| 8d1cd837d1 | |||
| dc277d1d99 | |||
|
|
b7ad6d906a | ||
|
|
3cfc16f5ff | ||
|
|
05bf567f3b | ||
|
|
ff1b9d4250 | ||
|
|
9b9de013db | ||
|
|
c546f6da23 | ||
| 8a08974f15 | |||
| 04d23354b9 | |||
| ddad6e7b6f | |||
| 9a17604e70 | |||
| c7e3359f08 | |||
| 16d068353a | |||
| f7b4c91163 | |||
| 55536a13db | |||
| 66abb7116f | |||
| bb89d5d24e | |||
| ad7a2ddf65 | |||
| 19031a7d11 | |||
| 1c9887bd45 | |||
| 209b979e56 | |||
| 34ce5c1d21 | |||
| 605aff2461 | |||
| ba1c40df7c | |||
| e25dafa9ca | |||
| ce78836328 | |||
| 8225c313b9 | |||
| be78b33570 | |||
| 9926fe3036 | |||
|
|
718390cfba | ||
|
|
6f864fc10e | ||
|
|
4b6cb2bcdd | ||
|
|
c866609f24 | ||
|
|
ee193edd42 | ||
|
|
40c55d65b3 | ||
|
|
a83b3a5331 | ||
|
|
65098a4120 | ||
|
|
0650fba936 | ||
|
|
16244acd3c | ||
|
|
fe52b0aa1a | ||
|
|
2af0fe894e | ||
|
|
387481799b | ||
|
|
d606155f17 | ||
|
|
c4d639e72a | ||
|
|
19d10b3161 | ||
|
|
220e2f9b12 | ||
|
|
3661874c92 | ||
|
|
a9a3ce535c | ||
|
|
6a81b2c6a0 | ||
|
|
139fac2928 | ||
| dcc6a36bf7 | |||
| 3b7fd004b8 | |||
| 2796764905 | |||
| 4c27619ee9 | |||
| a40737c06b | |||
| 34aebf7eea | |||
| da350d0d54 | |||
| 243807cbe5 | |||
| b3c18ebc4e | |||
| f25f067e9c | |||
| 74d269304c | |||
| c949cb5c8c | |||
| 2495919611 | |||
| 7ed4f6c704 | |||
| eb828f3807 | |||
| a98708302b | |||
| 0dae3e206f | |||
| 505e6f45c1 | |||
| 424de7d9c4 | |||
| 1a0de528e1 | |||
| d795dd76a6 | |||
|
|
45924d28e0 | ||
|
|
b1d0a0d036 | ||
|
|
45e9cf9a94 | ||
|
|
a8dcff2f0d | ||
| 53a7d25923 | |||
|
|
c701e7e98e | ||
|
|
bf8e097756 | ||
|
|
837a2bbdde | ||
|
|
6fb361a965 | ||
| 1db2cba81d | |||
| ce43a67cbd | |||
| 7ac8f056ed | |||
| d157e96aac | |||
| 1d1e3e9527 | |||
| 48d37e6b45 | |||
| 5d03f20831 | |||
| 9e72edb544 | |||
| 4476c71f62 | |||
| e9471b3072 | |||
| 4082cb27c3 | |||
| 88cdffddb6 | |||
| b27d1416b5 | |||
| ab97b5fe54 | |||
| bbaa207603 | |||
|
|
605937bbac | ||
|
|
594fcb9a0d | ||
|
|
e033c0cfb2 | ||
|
|
53ebbab941 | ||
| 86adc529ef | |||
| 3a774d37f8 | |||
| 5f6b1e2b16 | |||
| 584caf54b2 | |||
| d602c1cdcb | |||
| 12ce14b6e5 | |||
| e02709b3a4 | |||
| b19709039d | |||
| 3c4ffbf267 | |||
| 4942da0c88 | |||
| 5f547257ac | |||
| 1b99366887 | |||
| 871af36ac5 | |||
| 0ad6d2aec9 | |||
| 8837d2f275 | |||
| 09a17127a9 | |||
| 3699c5bc4c | |||
| 157b0867fa | |||
| 56529964f3 | |||
| c28e240fce | |||
| b04b2dab22 | |||
| 8edcd7b07f | |||
| ca78451122 | |||
| 4cc44e3dce | |||
| e81d3a1d7d | |||
| 53dd61b80a | |||
| 5b754d320f | |||
| 2be2658cfc | |||
| 2b157096e6 | |||
| 71eaddfd84 | |||
| 5589deb3ad | |||
| 0bb80e373b | |||
| 4acdd83984 | |||
| d12d38f970 | |||
| 74d9749255 | |||
| 3276ada78a | |||
| de378eec34 | |||
| dbb2d875fb | |||
| c7f966a1f5 | |||
| 7889dda6f8 | |||
| a2ccf3b631 | |||
| 57db34b303 | |||
| 4f790758af | |||
| ce9dfc6bb4 | |||
| 4f40ad1927 | |||
| a42a4010d6 | |||
| a2aa17fafc | |||
| 5bf2784db2 | |||
| 7a4e7b7600 | |||
| 70aa23513f | |||
| 71ded2f25f | |||
| 11103351b2 | |||
| 146a413977 | |||
| 4e44550f62 | |||
| 9952470486 | |||
| 02d30dedbc | |||
| 5ed0fe52a0 | |||
| 42b1f774da | |||
| 7738b68320 | |||
| 1199fabe90 | |||
| 1aefc5f2f0 | |||
| 6f666c6c22 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -26,3 +26,6 @@
|
||||
path = .ci
|
||||
url = https://github.com/epics-base/ci-scripts
|
||||
branch = master
|
||||
[submodule "modules/pcas"]
|
||||
path = modules/pcas
|
||||
url = https://github.com/epics-modules/pcas
|
||||
|
||||
7
Makefile
7
Makefile
@@ -23,3 +23,10 @@ DIRS += modules
|
||||
modules_DEPEND_DIRS = src
|
||||
|
||||
include $(TOP)/configure/RULES_TOP
|
||||
|
||||
UNINSTALL_DIRS += $(INSTALL_LOCATION)/src
|
||||
copysrc:
|
||||
tar cf - --exclude-vcs --exclude-backups --exclude=O.* modules/*/src | tar xf - -C $(INSTALL_LOCATION)
|
||||
|
||||
tar:
|
||||
tar cfjP epics_base-$(EPICS_VERSION_NUMBER).tar.bz2 $(INSTALL_LOCATION)
|
||||
|
||||
@@ -33,7 +33,11 @@ CODE_CFLAGS = $(PROF_CFLAGS_$(PROFILE)) $(GPROF_CFLAGS_$(GPROF))
|
||||
CODE_CFLAGS += $(ASAN_FLAGS_$(ENABLE_ASAN))
|
||||
WARN_CFLAGS_YES = -Wall -Werror-implicit-function-declaration
|
||||
WARN_CFLAGS_NO = -w
|
||||
OPT_CFLAGS_YES = -O3
|
||||
# It makes sense to include debugging symbols even in optimized builds
|
||||
# in case you want to attach gdb to the process or examine a core-dump.
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES = -O3 -g
|
||||
OPT_CFLAGS_NO = -g
|
||||
|
||||
PROF_CXXFLAGS_YES = -p
|
||||
@@ -42,7 +46,7 @@ CODE_CXXFLAGS = $(PROF_CXXFLAGS_$(PROFILE)) $(GPROF_CXXFLAGS_$(GPROF))
|
||||
CODE_CXXFLAGS += $(ASAN_FLAGS_$(ENABLE_ASAN))
|
||||
WARN_CXXFLAGS_YES = -Wall
|
||||
WARN_CXXFLAGS_NO = -w
|
||||
OPT_CXXFLAGS_YES = -O3
|
||||
OPT_CXXFLAGS_YES = -O3 -g
|
||||
OPT_CXXFLAGS_NO = -g
|
||||
|
||||
CODE_LDFLAGS = $(PROF_CXXFLAGS_$(PROFILE)) $(GPROF_CXXFLAGS_$(GPROF))
|
||||
|
||||
@@ -157,7 +157,9 @@ USE_POSIX_THREAD_PRIORITY_SCHEDULING = YES
|
||||
|
||||
# Site version number, if set will append '-' and this string to the
|
||||
# EPICS version number string that is reported by many tools.
|
||||
EPICS_SITE_VERSION =
|
||||
ifeq ($(INSTALL_LOCATION),$(EPICS_BASE))
|
||||
EPICS_SITE_VERSION=$(shell $(PERL) -MPOSIX -e 'print strftime "%Y-%m-%d", localtime')
|
||||
endif
|
||||
|
||||
# For GNU compiler, use pipes rather than temporary files for
|
||||
# communication between the various stages of compilation.
|
||||
|
||||
@@ -100,6 +100,23 @@ include $(CONFIG)/RULES_FILE_TYPE
|
||||
|
||||
include $(CONFIG)/RULES.Db
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Do not build anything if current path matches SKIP_BUILDS
|
||||
|
||||
ifneq (,$(strip $(SKIP_BUILDS)))
|
||||
CURRENT_MODULE=$(subst modules/,,$(subst $(realpath $(TOP)/..)/,,$(subst $(realpath $(dir $(lastword $(MAKEFILE_LIST)))..)/,,$(realpath ..))))
|
||||
ifneq ($(filter $(SKIP_BUILDS) $(addsuffix /%,$(SKIP_BUILDS)),$(CURRENT_MODULE)),)
|
||||
$(info Skipping $(CURRENT_MODULE) for $(T_A))
|
||||
PROD=
|
||||
TESTPROD=
|
||||
LIBRARY=
|
||||
TESTLIBRARY=
|
||||
LOADABLE_LIBRARY=
|
||||
TESTS=
|
||||
SRC_FILES=
|
||||
endif
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Include defines and rules for prod, library and test* targets
|
||||
|
||||
@@ -226,7 +243,7 @@ $(LOADABLE_SHRLIBNAME): FINAL_DIR=$(INSTALL_SHRLIB)
|
||||
|
||||
$(TESTPRODNAME) $(PRODNAME): $(PRODUCT_OBJS) $(PROD_RESS) $(PROD_DEPLIBS)
|
||||
|
||||
$(TESTPRODNAME) $(PRODNAME): %$(EXE): | $(INSTALL_LIB)
|
||||
$(TESTPRODNAME) $(PRODNAME): %$(EXE):
|
||||
@$(RM) $@
|
||||
$(LINK.cpp)
|
||||
$(MT_EXE_COMMAND)
|
||||
@@ -329,10 +346,6 @@ $(LOADABLE_SHRLIBNAME): $(LOADABLE_SHRLIB_PREFIX)%$(LOADABLE_SHRLIB_SUFFIX):
|
||||
$(LINK.shrlib)
|
||||
$(MT_DLL_COMMAND)
|
||||
|
||||
$(LIBNAME) $(SHRLIBNAME) $(LOADABLE_SHRLIBNAME): | $(INSTALL_LIB)
|
||||
$(INSTALL_LIB):
|
||||
@$(MKDIR) $@
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# C++ munching for VxWorks
|
||||
|
||||
|
||||
2
configure/os/CONFIG.Common.RHEL7-x86_64
Normal file
2
configure/os/CONFIG.Common.RHEL7-x86_64
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
1
configure/os/CONFIG.Common.RHEL7-x86_64-clang
Normal file
1
configure/os/CONFIG.Common.RHEL7-x86_64-clang
Normal file
@@ -0,0 +1 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
2
configure/os/CONFIG.Common.RHEL8-x86_64
Normal file
2
configure/os/CONFIG.Common.RHEL8-x86_64
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
3
configure/os/CONFIG.Common.RHEL8-x86_64-clang
Normal file
3
configure/os/CONFIG.Common.RHEL8-x86_64-clang
Normal file
@@ -0,0 +1,3 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
|
||||
STD_CXXFLAGS = -std=c++2a
|
||||
@@ -32,7 +32,7 @@ OP_SYS_LDFLAGS += -Wl,-Ttext,0x100000
|
||||
|
||||
|
||||
# This check must appear after the above include
|
||||
ifneq ($(RTEMS_VERSION),5)
|
||||
ifneq ($(firstword $(subst ., ,$(RTEMS_VERSION))),5)
|
||||
$(info *** This target is not compatible with the configured RTEMS version.)
|
||||
$(info *** Build the RTEMS-pc386 (-qemu) target for RTEMS 4.x)
|
||||
$(error Can't continue)
|
||||
|
||||
2
configure/os/CONFIG.Common.RTEMS49-pc386
Normal file
2
configure/os/CONFIG.Common.RTEMS49-pc386
Normal file
@@ -0,0 +1,2 @@
|
||||
RTEMS_VERSION = 4.9
|
||||
include $(CONFIG)/os/CONFIG.Common.RTEMS-pc386
|
||||
2
configure/os/CONFIG.Common.RTEMS51-pc686
Normal file
2
configure/os/CONFIG.Common.RTEMS51-pc686
Normal file
@@ -0,0 +1,2 @@
|
||||
RTEMS_VERSION = 5
|
||||
include $(CONFIG)/os/CONFIG.Common.RTEMS-pc686
|
||||
7
configure/os/CONFIG.Common.SL6-x86
Normal file
7
configure/os/CONFIG.Common.SL6-x86
Normal file
@@ -0,0 +1,7 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86
|
||||
|
||||
ARCH_DEP_CFLAGS += -march=i686
|
||||
|
||||
# have no full C++11
|
||||
STD_CXXFLAGS = -std=c++0x
|
||||
5
configure/os/CONFIG.Common.SL6-x86_64
Normal file
5
configure/os/CONFIG.Common.SL6-x86_64
Normal file
@@ -0,0 +1,5 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
|
||||
# have no full C++11
|
||||
STD_CXXFLAGS = -std=c++0x
|
||||
1
configure/os/CONFIG.Common.SL6-x86_64-clang
Normal file
1
configure/os/CONFIG.Common.SL6-x86_64-clang
Normal file
@@ -0,0 +1 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
8
configure/os/CONFIG.Common.T2-ppc604
Normal file
8
configure/os/CONFIG.Common.T2-ppc604
Normal file
@@ -0,0 +1,8 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 5.5.1
|
||||
WIND_BASE = /afs/psi.ch/project/vxworks/Tornado2.2.1
|
||||
|
||||
#there is a problem with our ccppc and optimization
|
||||
# -O0 works, -O and -O1 and higher are buggy
|
||||
OPT_CFLAGS_YES = -O0
|
||||
OPT_CXXFLAGS_YES = -O0
|
||||
2
configure/os/CONFIG.Common.V62-ppc604
Normal file
2
configure/os/CONFIG.Common.V62-ppc604
Normal file
@@ -0,0 +1,2 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.2
|
||||
5
configure/os/CONFIG.Common.V63-ppc603
Normal file
5
configure/os/CONFIG.Common.V63-ppc603
Normal file
@@ -0,0 +1,5 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc603_long
|
||||
VXWORKS_VERSION = 6.3
|
||||
|
||||
# Buggy "uninitialized variable" warning produces many false positives
|
||||
ARCH_DEP_CXXFLAGS += -Wno-uninitialized
|
||||
5
configure/os/CONFIG.Common.V63-ppc604
Normal file
5
configure/os/CONFIG.Common.V63-ppc604
Normal file
@@ -0,0 +1,5 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.3
|
||||
|
||||
# Buggy "uninitialized variable" warning produces many false positives
|
||||
ARCH_DEP_CXXFLAGS += -Wno-uninitialized
|
||||
5
configure/os/CONFIG.Common.V64-ppc604
Normal file
5
configure/os/CONFIG.Common.V64-ppc604
Normal file
@@ -0,0 +1,5 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.4
|
||||
|
||||
# Buggy "uninitialized variable" warning produces many false positives
|
||||
ARCH_DEP_CXXFLAGS += -Wno-uninitialized
|
||||
2
configure/os/CONFIG.Common.V66-ppc603
Normal file
2
configure/os/CONFIG.Common.V66-ppc603
Normal file
@@ -0,0 +1,2 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc603_long
|
||||
VXWORKS_VERSION = 6.6
|
||||
2
configure/os/CONFIG.Common.V66-ppc604
Normal file
2
configure/os/CONFIG.Common.V66-ppc604
Normal file
@@ -0,0 +1,2 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.6
|
||||
8
configure/os/CONFIG.Common.V67-ppc604
Normal file
8
configure/os/CONFIG.Common.V67-ppc604
Normal file
@@ -0,0 +1,8 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.7
|
||||
|
||||
# needed when including memPartLib.h, e.g. through moduleLib.h or loadLib.h
|
||||
ARCH_DEP_CFLAGS += -D_VSB_CONFIG_FILE='<../lib/h/config/vsbConfig.h>'
|
||||
|
||||
# compiler tries to access license server (even though no license isneeded)
|
||||
export LM_LICENSE_FILE=37000@lic-windriver.psi.ch
|
||||
3
configure/os/CONFIG.Common.V69-ppc32
Normal file
3
configure/os/CONFIG.Common.V69-ppc32
Normal file
@@ -0,0 +1,3 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc32
|
||||
VXWORKS_VERSION = 6.9
|
||||
#export LD_LIBRARY_PATH=$(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib
|
||||
6
configure/os/CONFIG.Common.V69-ppc604
Normal file
6
configure/os/CONFIG.Common.V69-ppc604
Normal file
@@ -0,0 +1,6 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.9
|
||||
#export LD_LIBRARY_PATH=$(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib
|
||||
|
||||
# -fno-implicit-fp causes error: "unable to find a register to spill in class 'FLOAT_REGS'"
|
||||
ARCH_DEP_CFLAGS = -mcpu=604 -mstrict-align
|
||||
20
configure/os/CONFIG.Common.deb10-x86_64
Normal file
20
configure/os/CONFIG.Common.deb10-x86_64
Normal file
@@ -0,0 +1,20 @@
|
||||
# Cross Debian 10 with gcc 8.3
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = x86_64
|
||||
|
||||
LDLIBS_SHARED_YES=LDLIBS
|
||||
|
||||
SDK = gcc
|
||||
SDK_DIR = /opt/xgcc/gcc-8.3.0-deb10
|
||||
GNU_ARCH = x86_64-deb10-linux-gnu
|
||||
SDKTARGETSYSROOT=$(SDK_DIR)/$(GNU_ARCH)/sys-root/
|
||||
GNU_DIR = $(SDK_DIR)
|
||||
GNU_BIN = $(GNU_DIR)/bin/
|
||||
GNU_TARGET_INCLUDE_DIR =
|
||||
GNU_TARGET=x86_64-deb10-linux-gnu
|
||||
|
||||
ARCH_DEP_CPPFLAGS =
|
||||
AS=$(GNU_BIN)/$(GNU_TARGET)-as
|
||||
25
configure/os/CONFIG.Common.eldk42-ppc4xxFP
Normal file
25
configure/os/CONFIG.Common.eldk42-ppc4xxFP
Normal file
@@ -0,0 +1,25 @@
|
||||
# DeltaTau PowerPMAC with ELDK 4.2
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_NCURSES
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
ELDK=/opt/eldk-4.2
|
||||
GNU_TARGET=ppc_4xxFP
|
||||
GNU_DIR=$(ELDK)/usr
|
||||
|
||||
# This cross tool chain is installed in a somehow weired way
|
||||
# Without the following lines it does not work on RHEL7
|
||||
# but it worked on SL6
|
||||
ARCH_DEP_CXXFLAGS += -I $(ELDK)/$(GNU_TARGET)/usr/include/c++/4.2.2
|
||||
ARCH_DEP_CXXFLAGS += -I $(ELDK)/$(GNU_TARGET)/usr/include/c++/4.2.2/powerpc-linux
|
||||
ARCH_DEP_CXXFLAGS += -I $(ELDK)/$(GNU_TARGET)/usr/include/c++/4.2.2/backward
|
||||
|
||||
ARCH_DEP_LDFLAGS += -Wl,-rpath-link,$(ELDK)/$(GNU_TARGET)/lib
|
||||
ARCH_DEP_LDFLAGS += -Wl,-rpath-link,$(ELDK)/$(GNU_TARGET)/usr/lib
|
||||
|
||||
# have no C++11
|
||||
STD_CXXFLAGS =
|
||||
17
configure/os/CONFIG.Common.eldk51-ppc4xxSF
Normal file
17
configure/os/CONFIG.Common.eldk51-ppc4xxSF
Normal file
@@ -0,0 +1,17 @@
|
||||
# Virtex FPGA embedded Processor with ELDK 5.1
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = eldk
|
||||
SDK_DIR = /opt/eldk-5.1
|
||||
SDK_HOST_ARCH = $(GNU_HOST_ARCH)-$(SDK)-$(GNU_HOST_OS)
|
||||
GNU_TARGET = powerpc-4xx-softfloat
|
||||
GNU_ARCH = ppc405-linux
|
||||
GNU_DIR = $(SDK_DIR)/$(GNU_TARGET)/sysroots/$(SDK_HOST_ARCH)/usr
|
||||
GNU_BIN = $(GNU_DIR)/bin/$(GNU_ARCH)
|
||||
|
||||
# have no full C++11
|
||||
STD_CXXFLAGS = -std=c++0x
|
||||
18
configure/os/CONFIG.Common.eldk52-e500v2
Normal file
18
configure/os/CONFIG.Common.eldk52-e500v2
Normal file
@@ -0,0 +1,18 @@
|
||||
# IOxOS IFC1210 with ELDK 5.2
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = eldk
|
||||
SDK_DIR = /opt/eldk-5.2
|
||||
SDK_HOST_ARCH = $(GNU_HOST_ARCH)-$(SDK)-$(GNU_HOST_OS)
|
||||
GNU_TARGET = powerpc-e500v2
|
||||
GNU_ARCH = ppce500v2-linux-gnuspe
|
||||
GNU_DIR = $(SDK_DIR)/$(GNU_TARGET)/sysroots/$(SDK_HOST_ARCH)/usr
|
||||
GNU_BIN = $(GNU_DIR)/bin/$(GNU_ARCH)
|
||||
GNU_TARGET_INCLUDE_DIR =
|
||||
|
||||
# have no full C++11
|
||||
STD_CXXFLAGS = -std=c++0x
|
||||
21
configure/os/CONFIG.Common.eldk53-ppc4xxFP
Normal file
21
configure/os/CONFIG.Common.eldk53-ppc4xxFP
Normal file
@@ -0,0 +1,21 @@
|
||||
# DeltaTau PowerPMAC with ELDK 5.3
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = eldk
|
||||
SDK_DIR = /opt/eldk-5.3
|
||||
SDK_HOST_ARCH = $(GNU_HOST_ARCH)-$(SDK)-$(GNU_HOST_OS)
|
||||
GNU_ARCH = ppc440e-linux
|
||||
SDKTARGETSYSROOT=$(SDK_DIR)/powerpc-4xx/sysroots
|
||||
GNU_DIR = $(SDKTARGETSYSROOT)/$(SDK_HOST_ARCH)/usr
|
||||
GNU_BIN = $(GNU_DIR)/bin/$(GNU_ARCH)
|
||||
GNU_TARGET_INCLUDE_DIR =
|
||||
GNU_TARGET=powerpc-linux
|
||||
|
||||
ARCH_DEP_CPPFLAGS = -m32 -mcpu=440fp -mhard-float
|
||||
ARCH_DEP_CPPFLAGS += --sysroot=$(SDKTARGETSYSROOT)/$(GNU_ARCH)
|
||||
ARCH_DEP_LDFLAGS = --sysroot=$(SDKTARGETSYSROOT)/$(GNU_ARCH)
|
||||
AS=$(GNU_BIN)/$(GNU_TARGET)-as
|
||||
23
configure/os/CONFIG.Common.fslqoriq20-e6500_64
Normal file
23
configure/os/CONFIG.Common.fslqoriq20-e6500_64
Normal file
@@ -0,0 +1,23 @@
|
||||
# IOxOS IFC1211 with Freescale QorIQ 2.0 toolchain
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = fslsdk
|
||||
SDK_DIR = /opt/fsl-qoriq/2.0
|
||||
SDK_HOST_ARCH = $(GNU_HOST_ARCH_64)-$(SDK)-$(GNU_HOST_OS)
|
||||
SDK_TARGET = ppc64e6500-fsl-linux
|
||||
GNU_TARGET = powerpc64-fsl-linux
|
||||
SDKTARGETSYSROOT = $(SDK_DIR)/sysroots/$(SDK_TARGET)
|
||||
GNU_DIR = $(SDK_DIR)/sysroots/$(SDK_HOST_ARCH)/usr
|
||||
GNU_BIN = $(GNU_DIR)/bin/$(GNU_TARGET)
|
||||
|
||||
ARCH_DEP_CPPFLAGS = --sysroot=$(SDKTARGETSYSROOT)
|
||||
ARCH_DEP_CFLAGS = -mcpu=e6500 -m64 -mhard-float
|
||||
ARCH_DEP_LDFLAGS = --sysroot=$(SDKTARGETSYSROOT)
|
||||
|
||||
# warning -O2 and higher are broken!
|
||||
#OPT_CFLAGS_YES = -O1
|
||||
#OPT_CXXFLAGS_YES = -O1
|
||||
21
configure/os/CONFIG.Common.gcc8-ppc4xxFP
Normal file
21
configure/os/CONFIG.Common.gcc8-ppc4xxFP
Normal file
@@ -0,0 +1,21 @@
|
||||
# DeltaTau PowerPMAC with gcc 8.5
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = ppc
|
||||
|
||||
SDK = gcc
|
||||
SDK_DIR = /opt/xgcc/gcc-8.5.0
|
||||
GNU_ARCH = powerpc-ppmac-linux-gnu
|
||||
SDKTARGETSYSROOT=$(SDK_DIR)/$(GNU_ARCH)/sys-root/
|
||||
GNU_DIR = $(SDK_DIR)
|
||||
GNU_BIN = $(GNU_DIR)/bin/
|
||||
GNU_TARGET_INCLUDE_DIR =
|
||||
GNU_TARGET=powerpc-ppmac-linux-gnu
|
||||
|
||||
ARCH_DEP_CPPFLAGS = -m32 -mcpu=440fp -mhard-float
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath,/opt/xgcc/gcc-8.5.0/$(GNU_ARCH)/lib
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(SDKTARGETSYSROOT)/lib/powerpc-linux-gnu/
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(SDKTARGETSYSROOT)/usr/lib/powerpc-linux-gnu/
|
||||
AS=$(GNU_BIN)/$(GNU_TARGET)-as
|
||||
5
configure/os/CONFIG.Common.linux-clang
Normal file
5
configure/os/CONFIG.Common.linux-clang
Normal file
@@ -0,0 +1,5 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
GNU = NO
|
||||
CMPLR_CLASS = clang
|
||||
CC = clang
|
||||
CCC = clang++
|
||||
23
configure/os/CONFIG.Common.moxa42-armv6l
Normal file
23
configure/os/CONFIG.Common.moxa42-armv6l
Normal file
@@ -0,0 +1,23 @@
|
||||
# Moxa DA-66x with SDK 4.2 and ARM7 processor
|
||||
|
||||
# Include definitions common to all Linux ARM targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-arm
|
||||
|
||||
GNU_DIR=/afs/psi.ch/project/embeddedlinux/moxa/arm-linux-4.4.2-v4
|
||||
GNU_TARGET=arm
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(GNU_DIR)/arm-none-linux-gnueabi/lib
|
||||
ARCH_DEP_LDFLAGS+=-Wl,-rpath-link,$(INSTALL_LIB)
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_NCURSES
|
||||
|
||||
# suppress note "the mangling of 'va_list' has changed in GCC 4.4"
|
||||
ARCH_DEP_CXXFLAGS += -Wno-psabi
|
||||
|
||||
ARCH_DEP_CFLAGS += -funwind-tables
|
||||
|
||||
# have no full C++11
|
||||
STD_CXXFLAGS = -std=c++0x
|
||||
|
||||
# accept4() exists but does not work
|
||||
# Give fake __rtems__ macro to posix/osdSock.c because that disables accept4()
|
||||
osdSock_CFLAGS += -D__rtems__
|
||||
18
configure/os/CONFIG.Common.mvl40-xscale_be
Normal file
18
configure/os/CONFIG.Common.mvl40-xscale_be
Normal file
@@ -0,0 +1,18 @@
|
||||
# Moxa DA-66x with Montavista Linux 4.0
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_CURSES
|
||||
|
||||
ARCH_CLASS = xscale
|
||||
|
||||
GNU_DIR=/afs/psi.ch/project/embeddedlinux/moxa/xscale_be/armv5teb-montavista-linuxeabi
|
||||
|
||||
ARCH_DEP_CFLAGS += -funwind-tables
|
||||
|
||||
# have no C++11
|
||||
STD_CXXFLAGS =
|
||||
|
||||
# Cannot build PVA because of missing boost support
|
||||
SKIP_BUILDS = pv% normativeTypes
|
||||
18
configure/os/CONFIG.Common.nilrt7-armv7a
Normal file
18
configure/os/CONFIG.Common.nilrt7-armv7a
Normal file
@@ -0,0 +1,18 @@
|
||||
# National Instruments CompactRIO running LabView RT 19.5.1
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = arm
|
||||
|
||||
GNU_TARGET = arm-linux-gnu
|
||||
|
||||
SYSROOT = /opt/LabVIEW-RT-19.5.1/arm/sysroots/armv7a-vfp-neon-nilrt-linux-gnueabi
|
||||
|
||||
ARCH_DEP_CPPFLAGS += -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon
|
||||
ARCH_DEP_CPPFLAGS += --sysroot=$(SYSROOT)
|
||||
ARCH_DEP_CPPFLAGS += -I$(SYSROOT)/usr/include/c++/4.7.2/arm-nilrt-linux-gnueabi/
|
||||
ARCH_DEP_CPPFLAGS += -I$(SYSROOT)/usr/include/c++/4.7.2/
|
||||
ARCH_DEP_LDFLAGS += --sysroot=$(SYSROOT)
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_NCURSES
|
||||
41
configure/os/CONFIG.Common.raspbian-arm
Normal file
41
configure/os/CONFIG.Common.raspbian-arm
Normal file
@@ -0,0 +1,41 @@
|
||||
# RaspberryPi with github.com/raspberrypi/tools toolchain
|
||||
# Tested on:
|
||||
# * Raspberry 3B+ Raspbian 9
|
||||
# * Raspberry 2 Raspbian 7
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
# Using readline:
|
||||
# Due to missing/messed up libs in the toolchain, readline needs copies of
|
||||
# libtinfo.so.5.9 and libreadline.so.6.2 from a Raspbian 7 rootfs
|
||||
# /lib/arm-linux-gnueabihf/ to the toolchain, e.g.
|
||||
# $(SDK_DIR)/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf/
|
||||
# and manually created links libtinfo.so.5 and libreadline.so.
|
||||
# For gcc-linaro-arm-linux-gnueabihf-raspbian, an existing incompatible
|
||||
# libtinfo.so.5 is in the way. Remove it.
|
||||
# (Built with glibc 2.16 like installed on Raspbian 9 but toolchain uses glibc 2.13.)
|
||||
# Also copy /usr/include/readline/ directory from some readline 6 installation
|
||||
# to $(SDK_DIR)/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/libc/usr/include/
|
||||
|
||||
ARCH_CLASS = arm
|
||||
|
||||
SDK_DIR = /opt/raspberrypi/arm-bcm2708
|
||||
|
||||
# Available SDK_TARGETs:
|
||||
|
||||
# gcc 4.8.3 for 32 bit hosts with GLIBC 2.3 or higher
|
||||
SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian
|
||||
|
||||
# gcc 4.8.3 for 64 bit hosts with GLIBC 2.14 or higher
|
||||
# SDK_TARGET = gcc-linaro-arm-linux-gnueabihf-raspbian-x64
|
||||
|
||||
# gcc 4.7.1 for 64 bit hosts with GLIBC 2.8 or higher
|
||||
# SDK_TARGET = arm-linux-gnueabihf
|
||||
|
||||
# gcc 4.7.1 for 32 bit hosts with GLIBC 2.4 or higher
|
||||
# SDK_TARGET = arm-bcm2708hardfp-linux-gnueabi
|
||||
# SDK_TARGET = arm-bcm2708-linux-gnueabi
|
||||
|
||||
GNU_DIR = $(SDK_DIR)/$(SDK_TARGET)
|
||||
GNU_TARGET = $(if $(filter arm-bcm2708%,SDK_TARGET),$(SDK_TARGET),arm-linux-gnueabihf)
|
||||
18
configure/os/CONFIG.Common.yocto21-aarch64
Normal file
18
configure/os/CONFIG.Common.yocto21-aarch64
Normal file
@@ -0,0 +1,18 @@
|
||||
# XILINX Zynq with Yocto 2.1 / Petalinux toolchain
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = arm64
|
||||
|
||||
SDK = petalinux
|
||||
SDK_DIR = /opt/petalinux-gfa/2018.1
|
||||
SDK_HOST_ARCH = $(GNU_HOST_ARCH_64)-$(SDK)-$(GNU_HOST_OS)
|
||||
SDK_TARGET = aarch64-xilinx-linux
|
||||
GNU_TARGET = $(SDK_TARGET)
|
||||
SDKTARGETSYSROOT = $(SDK_DIR)/sysroots/$(SDK_TARGET)
|
||||
GNU_DIR = $(SDK_DIR)/sysroots/$(SDK_HOST_ARCH)/usr
|
||||
GNU_BIN = $(GNU_DIR)/bin/$(GNU_TARGET)
|
||||
|
||||
ARCH_DEP_CPPFLAGS = --sysroot=$(SDKTARGETSYSROOT)
|
||||
ARCH_DEP_LDFLAGS = --sysroot=$(SDKTARGETSYSROOT)
|
||||
20
configure/os/CONFIG.Common.yocto40-aarch64
Normal file
20
configure/os/CONFIG.Common.yocto40-aarch64
Normal file
@@ -0,0 +1,20 @@
|
||||
# XILINX Zynq with Yocto 4.0 toolchain
|
||||
|
||||
# Include definitions common to all Linux targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
|
||||
ARCH_CLASS = arm64
|
||||
|
||||
SDK = pokysdk
|
||||
SDK_DIR = /opt/yocto40-aarch64
|
||||
SDK_HOST_ARCH = $(GNU_HOST_ARCH_64)-$(SDK)-$(GNU_HOST_OS)
|
||||
SDK_TARGET = cortexa53-poky-linux
|
||||
GNU_TARGET = aarch64-poky-linux
|
||||
SDKTARGETSYSROOT = $(SDK_DIR)/sysroots/$(SDK_TARGET)
|
||||
GNU_DIR = $(SDK_DIR)/sysroots/$(SDK_HOST_ARCH)/usr
|
||||
GNU_BIN = $(GNU_DIR)/bin/$(GNU_TARGET)
|
||||
|
||||
ARCH_DEP_CPPFLAGS = --sysroot=$(SDKTARGETSYSROOT) -mcpu=cortex-a53 -march=armv8-a+crc
|
||||
ARCH_DEP_LDFLAGS = --sysroot=$(SDKTARGETSYSROOT)
|
||||
|
||||
STD_CXXFLAGS = -std=c++23
|
||||
21
configure/os/CONFIG.Cross_64.RHEL7-x86_64
Normal file
21
configure/os/CONFIG.Cross_64.RHEL7-x86_64
Normal file
@@ -0,0 +1,21 @@
|
||||
# "cross compile" for RHEL7-x86_64 on other 64 bit Linux version
|
||||
# Expects RHEL7 RPMs c++ and readline-devel installed in $(SYSROOT)
|
||||
# This can be installed on RHEL7 with:
|
||||
# yum install --installroot=$(SYSROOT) <packages>
|
||||
# (Assuming $(SYSROOT) is on a shared network volume.)
|
||||
# Optionally use a newer toolset (installed on $(SYSROOT)).
|
||||
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
|
||||
SYSROOT = /opt/RHEL7
|
||||
TOOLSET_LOCATION = /opt/rh
|
||||
|
||||
# Do NOT set GNU_BIN (or else ...)!
|
||||
TOOLSET_DIR = $(TOOLSET:%=$(TOOLSET_LOCATION)/%/root)
|
||||
CC = $(SYSROOT)$(TOOLSET_DIR)/bin/gcc
|
||||
CCC = $(SYSROOT)$(TOOLSET_DIR)/bin/g++
|
||||
# Set LD_LIBRARY_PATH and BFLAG only with TOOLSET
|
||||
LD_LIBRARY_PATH = $(if $(TOOLSET),$(SYSROOT)$(TOOLSET_DIR)/lib64)
|
||||
BFLAG = $(if $(TOOLSET),-B$(SYSROOT)$(TOOLSET_DIR)/bin)
|
||||
TARGET_CPPFLAGS += --sysroot=$(SYSROOT) $(BFLAG)
|
||||
TARGET_LDFLAGS += --sysroot=$(SYSROOT) $(BFLAG)
|
||||
4
configure/os/CONFIG.Linux.win32-x86
Normal file
4
configure/os/CONFIG.Linux.win32-x86
Normal file
@@ -0,0 +1,4 @@
|
||||
include $(CONFIG)/os/CONFIG.win32-x86.win32-x86
|
||||
|
||||
PATH := /opt/wine-msvc-2017/bin/x86:$(PATH)
|
||||
export WINEPREFIX = $(HOME)/.wine-$(EPICS_HOST_ARCH)
|
||||
4
configure/os/CONFIG.Linux.windows-x64
Normal file
4
configure/os/CONFIG.Linux.windows-x64
Normal file
@@ -0,0 +1,4 @@
|
||||
include $(CONFIG)/os/CONFIG.windows-x64.windows-x64
|
||||
|
||||
PATH := /opt/wine-msvc-2017/bin/x64:$(PATH)
|
||||
export WINEPREFIX = $(HOME)/.wine-$(EPICS_HOST_ARCH)
|
||||
3
configure/os/CONFIG.RHEL7-x86_64.Common
Normal file
3
configure/os/CONFIG.RHEL7-x86_64.Common
Normal file
@@ -0,0 +1,3 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86_64.Common
|
||||
2
configure/os/CONFIG.RHEL7-x86_64.RHEL7-x86_64
Normal file
2
configure/os/CONFIG.RHEL7-x86_64.RHEL7-x86_64
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
6
configure/os/CONFIG.RHEL7-x86_64.SL6-x86
Normal file
6
configure/os/CONFIG.RHEL7-x86_64.SL6-x86
Normal file
@@ -0,0 +1,6 @@
|
||||
# "cross compile" for older Linux version (32 bit)
|
||||
# It was neccessary to install 32 bit compatibility libraries manually
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.RHEL7-x86_64.SL6-x86_64
|
||||
TARGET_LDFLAGS = -B /usr/lib/x86_64-redhat-linux6E/lib
|
||||
16
configure/os/CONFIG.RHEL7-x86_64.SL6-x86_64
Normal file
16
configure/os/CONFIG.RHEL7-x86_64.SL6-x86_64
Normal file
@@ -0,0 +1,16 @@
|
||||
# "cross compile" for older Linux version
|
||||
# Use older compiler and older libraries
|
||||
# Used packages:
|
||||
# compat-gcc-44-c++-4.4.7
|
||||
# compat-gcc-44-4.4.7
|
||||
# compat-glibc-headers-2.12
|
||||
# compat-glibc-2.12
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
CC = $(GNU_BIN)/$(CMPLR_PREFIX)gcc44
|
||||
CCC = $(GNU_BIN)/$(CMPLR_PREFIX)g++44
|
||||
|
||||
TARGET_CPPFLAGS = -isystem /usr/lib/x86_64-redhat-linux6E/include
|
||||
TARGET_LDFLAGS = -B /usr/lib/x86_64-redhat-linux6E/lib64
|
||||
LINK.cpp += --as-needed -lc -lm -lrt -lpthread -lreadline -ltinfo
|
||||
1
configure/os/CONFIG.RHEL7-x86_64.win32-x86
Normal file
1
configure/os/CONFIG.RHEL7-x86_64.win32-x86
Normal file
@@ -0,0 +1 @@
|
||||
include $(CONFIG)/os/CONFIG.Linux.win32-x86
|
||||
1
configure/os/CONFIG.RHEL7-x86_64.windows-x64
Normal file
1
configure/os/CONFIG.RHEL7-x86_64.windows-x64
Normal file
@@ -0,0 +1 @@
|
||||
include $(CONFIG)/os/CONFIG.Linux.windows-x64
|
||||
3
configure/os/CONFIG.RHEL8-x86_64.Common
Normal file
3
configure/os/CONFIG.RHEL8-x86_64.Common
Normal file
@@ -0,0 +1,3 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86_64.Common
|
||||
4
configure/os/CONFIG.RHEL8-x86_64.RHEL7-x86_64
Normal file
4
configure/os/CONFIG.RHEL8-x86_64.RHEL7-x86_64
Normal file
@@ -0,0 +1,4 @@
|
||||
include $(CONFIG)/os/CONFIG.Cross_64.RHEL7-x86_64
|
||||
|
||||
#TOOLSET = devtoolset-11
|
||||
#STD_CXXFLAGS = -std=c++17
|
||||
8
configure/os/CONFIG.RHEL8-x86_64.RHEL8-x86_64
Normal file
8
configure/os/CONFIG.RHEL8-x86_64.RHEL8-x86_64
Normal file
@@ -0,0 +1,8 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
|
||||
# Use gcc 11 from gcc-toolset-11
|
||||
GNU_BIN = /opt/rh/gcc-toolset-11/root/usr/bin
|
||||
# Fix bug in gcc-toolset-11 calling the old assembler
|
||||
TARGET_CFLAGS += -B$(GNU_BIN)
|
||||
STD_CXXFLAGS = -std=c++17
|
||||
1
configure/os/CONFIG.RHEL8-x86_64.nilrt7-armv7a
Normal file
1
configure/os/CONFIG.RHEL8-x86_64.nilrt7-armv7a
Normal file
@@ -0,0 +1 @@
|
||||
GNU_BIN=/opt/RHEL7/bin
|
||||
1
configure/os/CONFIG.RHEL8-x86_64.win32-x86
Normal file
1
configure/os/CONFIG.RHEL8-x86_64.win32-x86
Normal file
@@ -0,0 +1 @@
|
||||
include $(CONFIG)/os/CONFIG.Linux.win32-x86
|
||||
1
configure/os/CONFIG.RHEL8-x86_64.windows-x64
Normal file
1
configure/os/CONFIG.RHEL8-x86_64.windows-x64
Normal file
@@ -0,0 +1 @@
|
||||
include $(CONFIG)/os/CONFIG.Linux.windows-x64
|
||||
2
configure/os/CONFIG.SL6-x86.Common
Normal file
2
configure/os/CONFIG.SL6-x86.Common
Normal file
@@ -0,0 +1,2 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
2
configure/os/CONFIG.SL6-x86.SL6-x86
Normal file
2
configure/os/CONFIG.SL6-x86.SL6-x86
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
3
configure/os/CONFIG.SL6-x86_64.Common
Normal file
3
configure/os/CONFIG.SL6-x86_64.Common
Normal file
@@ -0,0 +1,3 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86_64.Common
|
||||
2
configure/os/CONFIG.SL6-x86_64.SL6-x86
Normal file
2
configure/os/CONFIG.SL6-x86_64.SL6-x86
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
2
configure/os/CONFIG.SL6-x86_64.SL6-x86_64
Normal file
2
configure/os/CONFIG.SL6-x86_64.SL6-x86_64
Normal file
@@ -0,0 +1,2 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
@@ -24,6 +24,9 @@
|
||||
#RTEMS_VERSION = 5
|
||||
#RTEMS_BASE = /usr/local/vw/rtems/rtems-5.1
|
||||
|
||||
# PSI:
|
||||
RTEMS_BASE = /opt/rtems/$(RTEMS_VERSION)
|
||||
|
||||
# Cross-compile toolchain in $(RTEMS_TOOLS)/bin
|
||||
#
|
||||
RTEMS_TOOLS = $(RTEMS_BASE)
|
||||
|
||||
2
configure/os/CONFIG_SITE.Common.UnixCommon
Normal file
2
configure/os/CONFIG_SITE.Common.UnixCommon
Normal file
@@ -0,0 +1,2 @@
|
||||
SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)
|
||||
LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)
|
||||
2
configure/os/CONFIG_SITE.Common.deb10-x86_64
Normal file
2
configure/os/CONFIG_SITE.Common.deb10-x86_64
Normal file
@@ -0,0 +1,2 @@
|
||||
# Debian 10
|
||||
COMMANDLINE_LIBRARY=READLINE_NCURSES
|
||||
2
configure/os/CONFIG_SITE.Common.gcc8-ppc4xxFP
Normal file
2
configure/os/CONFIG_SITE.Common.gcc8-ppc4xxFP
Normal file
@@ -0,0 +1,2 @@
|
||||
# DeltaTau PowerPMAC with gcc
|
||||
COMMANDLINE_LIBRARY=READLINE
|
||||
@@ -8,3 +8,7 @@
|
||||
# They must be set in the host+target specific file instead:
|
||||
# CONFIG_SITE.<linux-arch>.<linux-arch>
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
CODE_CPPFLAGS += -fno-strict-aliasing
|
||||
USR_CXXFLAGS += $(STD_CXXFLAGS)
|
||||
STD_CXXFLAGS = -std=c++11
|
||||
|
||||
@@ -18,8 +18,83 @@ VXWORKS_VERSION = 6.9
|
||||
# architecture by adding it to an appropriate
|
||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).vxWorksCommon file.
|
||||
|
||||
#### Fixes for CONFIG.Common.vxWorksCommon #######
|
||||
|
||||
VX_GNU_VERSION_7 = 4.8.1.11
|
||||
|
||||
|
||||
# These are needed for vxWorks 6.x; the GNU toolset version number
|
||||
# is in the path to the compiler tools:
|
||||
VX_GNU_VERSION_5 = 2.96
|
||||
VX_GNU_VERSION_6 = $(VX_GNU_VERSION_$(VXWORKS_VERSION))
|
||||
VX_GNU_VERSION = $(VX_GNU_VERSION_$(VXWORKS_MAJOR_VERSION))
|
||||
VX_GNU_MAJOR_VERSION = $(firstword $(subst ., ,$(VX_GNU_VERSION)))
|
||||
VX_GNU_MINOR_VERSION = $(word 2,$(subst ., ,$(VX_GNU_VERSION)))
|
||||
|
||||
# gcc version before 3.4 are "old" and need special treatment
|
||||
VX_OLD_GCC_2 = OLD
|
||||
VX_OLD_GCC_3.3 = OLD
|
||||
VX_OLD_GCC_3 = $(VX_OLD_GCC_3.$(VX_GNU_MINOR_VERSION))
|
||||
VX_OLD_GCC = $(VX_OLD_GCC_$(VX_GNU_MAJOR_VERSION))
|
||||
|
||||
# vxWorks directory definitions
|
||||
VX_DIR_5 = $(WIND_BASE)
|
||||
VX_DIR_6 = $(WIND_BASE)/vxworks-$(VXWORKS_VERSION)
|
||||
VX_DIR_7 = $(WIND_BASE)/vxworks-$(VXWORKS_VERSION)/pkgs/os
|
||||
VX_DIR = $(VX_DIR_$(VXWORKS_MAJOR_VERSION))
|
||||
|
||||
VX_INCLUDE_DIRS_5 = $(VX_DIR)/target/h
|
||||
VX_INCLUDE_DIRS_6 = $(VX_DIR)/target/h
|
||||
VX_INCLUDE_DIRS_6 += $(VX_DIR)/target/h/wrn/coreip
|
||||
VX_INCLUDE_DIRS_7 = $(VX_DIR)/core/kernel-1.2.8.0/h
|
||||
VX_INCLUDE_DIRS_7 += $(VX_DIR)/lang-lib/libc-1.0.0.1/libc-kernel-1.0.8.0/h
|
||||
VX_INCLUDE_DIRS_7 += $(VX_DIR)/utils/ostools-1.0.5.0/h
|
||||
VX_INCLUDE_DIRS_7 += $(VX_DIR)/utils/ostools-1.0.5.0/shareh
|
||||
VX_INCLUDE_DIRS_7 += $(VX_DIR)/arch/ppc-1.3.4.0/kernel/base/h/
|
||||
VX_INCLUDE_DIRS_7 += $(VX_DIR)/arch/ppc-1.3.4.0/kernel/60x/h/arch/ppc/
|
||||
VX_INCLUDE_DIRS_7 += $(WIND_BASE)/vxworks-$(VXWORKS_VERSION)/samples/prebuilt_projects/vsb_vxsim_linux/krnl/h/public
|
||||
GNU_TARGET_INCLUDE_DIR = $(VX_INCLUDE_DIRS_$(VXWORKS_MAJOR_VERSION))
|
||||
|
||||
TARGET_CPPFLAGS_5 = -isystem $(VX_DIR)/target/h
|
||||
TARGET_CPPFLAGS_6 = -isystem $(VX_DIR)/target/h
|
||||
TARGET_CPPFLAGS_7 = -isystem $(VX_DIR)/core/kernel-1.2.8.0/h -D_VSB_CONFIG_FILE='<$(WIND_BASE)/vxworks-$(VXWORKS_VERSION)/samples/prebuilt_projects/vsb_vxsim_linux/h/config/vsbConfig.h>'
|
||||
TARGET_CPPFLAGS = $(TARGET_CPPFLAGS_$(VXWORKS_MAJOR_VERSION))
|
||||
|
||||
# vxWorks GNU directories
|
||||
|
||||
GNU_DIR_5 = $(WIND_BASE)/host/$(WIND_HOST_TYPE)
|
||||
GNU_DIR_6 = $(WIND_BASE)/gnu/$(VX_GNU_VERSION)-vxworks-$(VXWORKS_VERSION)/$(WIND_HOST_TYPE)
|
||||
GNU_DIR_7 = $(WIND_BASE)/compilers/gnu-$(VX_GNU_VERSION)/$(WIND_HOST_TYPE)
|
||||
GNU_DIR = $(GNU_DIR_$(VXWORKS_MAJOR_VERSION))
|
||||
|
||||
# Operating system flags
|
||||
OP_SYS_CFLAGS += -fno-strict-aliasing
|
||||
|
||||
OP_SYS_INCLUDE_CPPFLAGS_5 += -include $(VX_DIR)/target/h/vxWorks.h
|
||||
OP_SYS_INCLUDE_CPPFLAGS_5 += -I$(EPICS_BASE)/include/os/vxWorks/vxWorks5
|
||||
OP_SYS_INCLUDE_CPPFLAGS_6 += -include $(VX_DIR)/target/h/vxWorks.h
|
||||
OP_SYS_INCLUDE_CPPFLAGS_7 += -include vxWorks.h
|
||||
OP_SYS_INCLUDE_CPPFLAGS = $(OP_SYS_INCLUDE_CPPFLAGS_$(VXWORKS_MAJOR_VERSION))
|
||||
|
||||
OP_SYS_LDFLAGS += $(OP_SYS_LDFLAGS_$@)
|
||||
OP_SYS_LDFLAGS_softIoc = -whole-archive
|
||||
OP_SYS_LDFLAGS_softIocPVA = -whole-archive
|
||||
|
||||
# code flags (delete -fno-implicit-templates)
|
||||
CODE_CXXFLAGS =
|
||||
|
||||
# WIND_BASE is where you installed the Wind River software.
|
||||
|
||||
#WIND_BASE = /usr/local/vw/tornado22-$(ARCH_CLASS)
|
||||
WIND_BASE = /usr/local/vw/vxWorks-$(VXWORKS_VERSION)
|
||||
#WIND_BASE = /usr/local/vw/vxWorks-$(VXWORKS_VERSION)
|
||||
#WIND_BASE = /ade/vxWorks/$(VXWORKS_VERSION)
|
||||
WIND_BASE = /afs/psi.ch/project/vxworks/VxWorks$(VXWORKS_VERSION)
|
||||
|
||||
#--------------------------------------------------
|
||||
# Modules we cannot build with old compiler
|
||||
|
||||
PV_MODULES = pv% normativeTypes
|
||||
SKIP_BUILDS_5 = $(PV_MODULES)
|
||||
SKIP_BUILDS_OLD = $(PV_MODULES)
|
||||
SKIP_BUILDS_6 = $(SKIP_BUILDS_$(VX_OLD_GCC))
|
||||
SKIP_BUILDS = $(SKIP_BUILDS_$(VXWORKS_MAJOR_VERSION))
|
||||
|
||||
18
configure/os/CONFIG_SITE.RHEL7-x86_64.Common
Normal file
18
configure/os/CONFIG_SITE.RHEL7-x86_64.Common
Normal file
@@ -0,0 +1,18 @@
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.Common
|
||||
|
||||
# Improved error checking with clang
|
||||
CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86_64-clang
|
||||
CROSS_COMPILER_RUNTEST_ARCHS += RHEL7-x86_64-clang
|
||||
|
||||
# Build for old SL6 64 bit
|
||||
CROSS_COMPILER_TARGET_ARCHS += SL6-x86_64
|
||||
CROSS_COMPILER_RUNTEST_ARCHS += SL6-x86_64
|
||||
|
||||
# Build for old SL6 32 bit
|
||||
CROSS_COMPILER_TARGET_ARCHS += SL6-x86
|
||||
CROSS_COMPILER_RUNTEST_ARCHS += SL6-x86
|
||||
|
||||
# NI Linux Real-Time 7.x
|
||||
# requires RPM gcc-c++-arm-linux-gnu
|
||||
# Not available on RHEL8
|
||||
CROSS_COMPILER_TARGET_ARCHS += nilrt7-armv7a
|
||||
11
configure/os/CONFIG_SITE.RHEL8-x86_64.Common
Normal file
11
configure/os/CONFIG_SITE.RHEL8-x86_64.Common
Normal file
@@ -0,0 +1,11 @@
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.Common
|
||||
|
||||
# Improved error checking with clang
|
||||
CROSS_COMPILER_TARGET_ARCHS += RHEL8-x86_64-clang
|
||||
|
||||
# Build for old RHEL7 64 bit
|
||||
CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86_64
|
||||
|
||||
# NI Linux Real-Time 7.x
|
||||
# requires RPM gcc-c++-arm-linux-gnu
|
||||
CROSS_COMPILER_TARGET_ARCHS += nilrt7-armv7a
|
||||
1
configure/os/CONFIG_SITE.SL6-x86.Common
Normal file
1
configure/os/CONFIG_SITE.SL6-x86.Common
Normal file
@@ -0,0 +1 @@
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86.Common
|
||||
7
configure/os/CONFIG_SITE.SL6-x86_64.Common
Normal file
7
configure/os/CONFIG_SITE.SL6-x86_64.Common
Normal file
@@ -0,0 +1,7 @@
|
||||
# Build 32 bit version as a cross architecture
|
||||
#CROSS_COMPILER_TARGET_ARCHS += SL6-x86
|
||||
|
||||
# Improved error checking with clang
|
||||
#CROSS_COMPILER_TARGET_ARCHS += SL6-x86_64-clang
|
||||
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.Common
|
||||
@@ -5,3 +5,56 @@
|
||||
|
||||
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-ppc32
|
||||
#CROSS_COMPILER_TARGET_ARCHS = RTEMS-mvme2100 RTEMS-pc386-qemu
|
||||
|
||||
INSTALL_LOCATION=/usr/local/epics/base-$(EPICS_VERSION).$(EPICS_REVISION).$(EPICS_MODIFICATION)
|
||||
|
||||
GNU_HOST_ARCH=i686
|
||||
GNU_HOST_OS=linux
|
||||
|
||||
# LD_LIBRARY_PATH may cause problems for eldk53-ppc4xxFP
|
||||
LD_LIBRARY_PATH=
|
||||
|
||||
# vxWorks 5.5 for MVxxxx boards
|
||||
CROSS_COMPILER_TARGET_ARCHS += T2-ppc604
|
||||
|
||||
# vxWorks 6.7 for MVxxxx boards
|
||||
#CROSS_COMPILER_TARGET_ARCHS += V67-ppc604
|
||||
|
||||
# vxWorks 6.9 for MVxxxx boards
|
||||
CROSS_COMPILER_TARGET_ARCHS += V69-ppc604
|
||||
#CROSS_COMPILER_TARGET_ARCHS += V69-ppc32
|
||||
|
||||
# NI compact RIO
|
||||
CROSS_COMPILER_TARGET_ARCHS += V63-ppc603
|
||||
|
||||
# MOXA montavista linux (No PVA because of missing boost support)
|
||||
CROSS_COMPILER_TARGET_ARCHS += mvl40-xscale_be
|
||||
|
||||
# MOXA SDK 4.2
|
||||
CROSS_COMPILER_TARGET_ARCHS += moxa42-armv6l
|
||||
|
||||
# Virtex embedded PPC
|
||||
CROSS_COMPILER_TARGET_ARCHS += eldk51-ppc4xxSF
|
||||
|
||||
# IOxOS IFC1210
|
||||
CROSS_COMPILER_TARGET_ARCHS += eldk52-e500v2
|
||||
|
||||
# DeltaTau PowerPMAC
|
||||
CROSS_COMPILER_TARGET_ARCHS += eldk42-ppc4xxFP
|
||||
CROSS_COMPILER_TARGET_ARCHS += eldk53-ppc4xxFP
|
||||
|
||||
# Test other vxWorks versions
|
||||
#CROSS_COMPILER_TARGET_ARCHS += V66-ppc603
|
||||
#CROSS_COMPILER_TARGET_ARCHS += V66-ppc604
|
||||
#CROSS_COMPILER_TARGET_ARCHS += V63-ppc604
|
||||
#CROSS_COMPILER_TARGET_ARCHS += V64-ppc604
|
||||
# (No PVA because of old compiler)
|
||||
#CROSS_COMPILER_TARGET_ARCHS += V62-ppc604
|
||||
|
||||
# Raspberry Pi
|
||||
CROSS_COMPILER_TARGET_ARCHS += raspbian-arm
|
||||
|
||||
# RTEMS (Can only have 1 RTEMS major version in 1 EPICS installation
|
||||
# because they overwrite their header files.)
|
||||
#CROSS_COMPILER_TARGET_ARCHS += RTEMS49-pc386
|
||||
CROSS_COMPILER_TARGET_ARCHS += RTEMS51-pc686
|
||||
|
||||
@@ -3,13 +3,6 @@
|
||||
# Site specific definitions for linux-x86 host - linux-x86 target builds
|
||||
#-------------------------------------------------------
|
||||
|
||||
# It makes sense to include debugging symbols even in optimized builds
|
||||
# in case you want to attach gdb to the process or examine a core-dump.
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES += -g
|
||||
OPT_CXXFLAGS_YES += -g
|
||||
|
||||
# Uncomment the followings lines to build with CLANG instead of GCC.
|
||||
#
|
||||
#GNU = NO
|
||||
|
||||
@@ -7,3 +7,22 @@
|
||||
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
|
||||
#CROSS_COMPILER_TARGET_ARCHS = RTEMS-mvme2100
|
||||
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86.Common
|
||||
|
||||
GNU_HOST_ARCH_64=x86_64
|
||||
|
||||
# Windows cross builds using Wine
|
||||
CROSS_COMPILER_TARGET_ARCHS += win32-x86 windows-x64
|
||||
|
||||
# IOxOS IFC1211
|
||||
CROSS_COMPILER_TARGET_ARCHS += fslqoriq20-e6500_64
|
||||
|
||||
# Zynq
|
||||
CROSS_COMPILER_TARGET_ARCHS += yocto21-aarch64
|
||||
CROSS_COMPILER_TARGET_ARCHS += yocto40-aarch64
|
||||
|
||||
# Debian 10
|
||||
CROSS_COMPILER_TARGET_ARCHS += deb10-x86_64
|
||||
|
||||
# Newer DeltaTau PowerPMAC
|
||||
CROSS_COMPILER_TARGET_ARCHS += gcc8-ppc4xxFP
|
||||
|
||||
@@ -3,13 +3,6 @@
|
||||
# Site specific definitions for linux-x86_64 host - linux-x86_64 target builds
|
||||
#-------------------------------------------------------
|
||||
|
||||
# It makes sense to include debugging symbols even in optimized builds
|
||||
# in case you want to attach gdb to the process or examine a core-dump.
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES += -g
|
||||
OPT_CXXFLAGS_YES += -g
|
||||
|
||||
# Uncomment the followings lines to build with CLANG instead of GCC.
|
||||
#
|
||||
#GNU = NO
|
||||
|
||||
@@ -133,6 +133,33 @@ make INSTALL_LOCATION=/tmp/build FINAL_LOCATION=/usr/lib/epics
|
||||
`FINAL_LOCATION` is now correctly used in systemd and sysv init scripts
|
||||
`caRepeater.service`, `S99caRepeater`, and `S99logServer`.
|
||||
|
||||
### epicsEnvShow accepts glob pattern
|
||||
|
||||
The optional argument to epicsEnvShow can now be a glob pattern.
|
||||
|
||||
### New function `epicsStrnGlobMatch()`
|
||||
|
||||
The function `epicsStrnGlobMatch(char* str, size_t len, char* pattern)`
|
||||
works exactly the same as `epicsStrGlobMatch()` but takes an additional
|
||||
length arguments which limits the number of characters of `str` to match.
|
||||
|
||||
### Glob pattern allowed in `var` command
|
||||
|
||||
When used with one argument, the `var` command can be used with a glob pattern
|
||||
for printing matching variables.
|
||||
|
||||
### Fix for input links marked "special"
|
||||
|
||||
The calcout record (and a number of synApps record types) marks its input
|
||||
link fields with the attribute `special(SPC_MOD)` and provides code in
|
||||
the record's `special()` routine to reinitialize the related value field
|
||||
whenever the input link field is set to a numeric constant. Unfortunately the
|
||||
changes to the link handling code broke this behaviour (reported as Launchpad
|
||||
[bug #1824277](https://bugs.launchpad.net/epics-base/+bug/1824277))
|
||||
back in the Base 3.16.1 release. This issue has been fixed in Base, although
|
||||
external record types may require some fixing to ensure they are correctly
|
||||
checking for and initializing the link in their `special()` routine.
|
||||
|
||||
### IOCsh sets `${PWD}`
|
||||
|
||||
IOC shell will now ensure `${PWD}` is set on startup,
|
||||
@@ -222,6 +249,33 @@ that the variables referenced by output pointers are initialized.
|
||||
```
|
||||
|
||||
|
||||
### Timeouts for Unit Test Programs
|
||||
|
||||
The unit test programs that are run by the `make runtests` or `make tapfiles`
|
||||
commands get executed by a `.t` wrapper script which is normally generated by
|
||||
the EPICS `makeTestfile.pl` program. Those generated wrapper scripts now
|
||||
impose a time-limit on the test program they execute, and will kill it if it
|
||||
runs for longer than 500 seconds (8 minutes 20) without exiting. That
|
||||
time-limit can be changed for any such test by modifying the Makefile which
|
||||
creates and runs the `.t` wrapper script.
|
||||
|
||||
Setting the environment variable `EPICS_UNITTEST_TIMEOUT` to the desired
|
||||
number of seconds while the Makefile is generating the test script changes the
|
||||
timeout in that script. For example:
|
||||
|
||||
```
|
||||
TESTSCRIPTS_HOST += hourLongTest.t
|
||||
hourLongTest.t: export EPICS_UNITTEST_TIMEOUT=3600
|
||||
```
|
||||
|
||||
When selecting such a timeout remember that different Continuous Integration
|
||||
systems such as GitHub Actions and Appveyor run on processors with different
|
||||
speeds, so allow enough head-room for slower systems to complete the test.
|
||||
|
||||
Test programs written directly in Perl as a `.plt` script should implement a
|
||||
similar timeout for themselves. The "netget" test in Base does this in a way
|
||||
that works on Windows as well as Unix-like hosts.
|
||||
|
||||
### Timeouts for Unit Test Programs
|
||||
|
||||
The unit test programs that are run by the `make runtests` or `make tapfiles`
|
||||
|
||||
@@ -37,6 +37,9 @@ pva2pva_DEPEND_DIRS = pvAccess
|
||||
SUBMODULES += example
|
||||
example_DEPEND_DIRS = pva2pva pvaClient
|
||||
|
||||
SUBMODULES += pcas
|
||||
pcas_DEPEND_DIRS = ca
|
||||
|
||||
# Allow sites to add extra submodules
|
||||
-include Makefile.local
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ INC += dbState.h
|
||||
INC += db_access_routines.h
|
||||
INC += db_convert.h
|
||||
INC += dbUnitTest.h
|
||||
INC += dbCaPvt.h
|
||||
|
||||
# Generate menuGlobal.dbd, not really by concatenation, see RULES
|
||||
DBDCAT += menuGlobal.dbd
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "dbFldTypes.h"
|
||||
#include "dbLink.h"
|
||||
#include "link.h"
|
||||
#include "errlog.h"
|
||||
|
||||
/**************************** Convert functions ****************************/
|
||||
|
||||
@@ -178,17 +179,23 @@ static long dbConstLoadLS(struct link *plink, char *pbuffer, epicsUInt32 size,
|
||||
epicsUInt32 *plen)
|
||||
{
|
||||
const char *pstr = plink->value.constantStr;
|
||||
long status;
|
||||
|
||||
if (!pstr)
|
||||
return S_db_badField;
|
||||
|
||||
return dbLSConvertJSON(pstr, pbuffer, size, plen);
|
||||
status = dbLSConvertJSON(pstr, pbuffer, size, plen);
|
||||
if (status)
|
||||
errlogPrintf("... while parsing link %s.%s\n",
|
||||
plink->precord->name, dbLinkFieldName(plink));
|
||||
return status;
|
||||
}
|
||||
|
||||
static long dbConstLoadArray(struct link *plink, short dbrType, void *pbuffer,
|
||||
long *pnReq)
|
||||
{
|
||||
const char *pstr = plink->value.constantStr;
|
||||
long status;
|
||||
|
||||
if (!pstr)
|
||||
return S_db_badField;
|
||||
@@ -197,7 +204,11 @@ static long dbConstLoadArray(struct link *plink, short dbrType, void *pbuffer,
|
||||
if (dbrType == DBF_MENU || dbrType == DBF_ENUM || dbrType == DBF_DEVICE)
|
||||
dbrType = DBF_USHORT;
|
||||
|
||||
return dbPutConvertJSON(pstr, dbrType, pbuffer, pnReq);
|
||||
status = dbPutConvertJSON(pstr, dbrType, pbuffer, pnReq);
|
||||
if (status)
|
||||
errlogPrintf("... while parsing link %s.%s\n",
|
||||
plink->precord->name, dbLinkFieldName(plink));
|
||||
return status;
|
||||
}
|
||||
|
||||
static long dbConstGetNelements(const struct link *plink, long *nelements)
|
||||
|
||||
@@ -26,14 +26,16 @@ typedef struct parseContext {
|
||||
short dbrType;
|
||||
short dbrSize;
|
||||
char *pdest;
|
||||
int elems;
|
||||
size_t elems;
|
||||
} parseContext;
|
||||
|
||||
static int dbcj_null(void *ctx) {
|
||||
errlogPrintf("dbConvertJSON: Null objects not supported\n");
|
||||
return 0; /* Illegal */
|
||||
}
|
||||
|
||||
static int dbcj_boolean(void *ctx, int val) {
|
||||
errlogPrintf("dbConvertJSON: Boolean not supported\n");
|
||||
return 0; /* Illegal */
|
||||
}
|
||||
|
||||
@@ -50,10 +52,6 @@ static int dbcj_integer(void *ctx, long long num) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dblsj_integer(void *ctx, long long num) {
|
||||
return 0; /* Illegal */
|
||||
}
|
||||
|
||||
static int dbcj_double(void *ctx, double num) {
|
||||
parseContext *parser = (parseContext *) ctx;
|
||||
FASTCONVERT conv = dbFastPutConvertRoutine[DBF_DOUBLE][parser->dbrType];
|
||||
@@ -66,19 +64,23 @@ static int dbcj_double(void *ctx, double num) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dblsj_double(void *ctx, double num) {
|
||||
return 0; /* Illegal */
|
||||
}
|
||||
|
||||
static int dbcj_string(void *ctx, const unsigned char *val, size_t len) {
|
||||
parseContext *parser = (parseContext *) ctx;
|
||||
char *pdest = parser->pdest;
|
||||
|
||||
/* Not attempting to handle char-array fields here, they need more
|
||||
* metadata about the field than we have available at the moment.
|
||||
*/
|
||||
if (parser->dbrType == DBF_CHAR || parser->dbrType == DBF_UCHAR) {
|
||||
/* Treating char array as long string */
|
||||
if (len > parser->elems)
|
||||
len = parser->elems;
|
||||
strncpy(pdest, (const char *) val, len);
|
||||
parser->elems -= len;
|
||||
parser->pdest += len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (parser->dbrType != DBF_STRING) {
|
||||
errlogPrintf("dbConvertJSON: String provided, numeric value(s) expected\n");
|
||||
errlogPrintf("dbConvertJSON: String \"%.*s\" provided, numeric value expected\n",
|
||||
(int)len, val);
|
||||
return 0; /* Illegal */
|
||||
}
|
||||
|
||||
@@ -93,39 +95,11 @@ static int dbcj_string(void *ctx, const unsigned char *val, size_t len) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dblsj_string(void *ctx, const unsigned char *val, size_t len) {
|
||||
parseContext *parser = (parseContext *) ctx;
|
||||
char *pdest = parser->pdest;
|
||||
|
||||
if (parser->dbrType != DBF_STRING) {
|
||||
errlogPrintf("dbConvertJSON: dblsj_string dbrType error\n");
|
||||
return 0; /* Illegal */
|
||||
}
|
||||
|
||||
if (parser->elems > 0) {
|
||||
if (len > parser->dbrSize - 1)
|
||||
len = parser->dbrSize - 1;
|
||||
strncpy(pdest, (const char *) val, len);
|
||||
pdest[len] = 0;
|
||||
parser->pdest = pdest + len;
|
||||
parser->elems = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dbcj_start_map(void *ctx) {
|
||||
errlogPrintf("dbConvertJSON: Map type not supported\n");
|
||||
return 0; /* Illegal */
|
||||
}
|
||||
|
||||
static int dbcj_map_key(void *ctx, const unsigned char *key, size_t len) {
|
||||
return 0; /* Illegal */
|
||||
}
|
||||
|
||||
static int dbcj_end_map(void *ctx) {
|
||||
return 0; /* Illegal */
|
||||
}
|
||||
|
||||
static int dbcj_start_array(void *ctx) {
|
||||
parseContext *parser = (parseContext *) ctx;
|
||||
|
||||
@@ -135,32 +109,35 @@ static int dbcj_start_array(void *ctx) {
|
||||
return (parser->depth == 1);
|
||||
}
|
||||
|
||||
static int dbcj_end_array(void *ctx) {
|
||||
parseContext *parser = (parseContext *) ctx;
|
||||
|
||||
parser->depth--;
|
||||
return (parser->depth == 0);
|
||||
}
|
||||
|
||||
|
||||
static yajl_callbacks dbcj_callbacks = {
|
||||
dbcj_null, dbcj_boolean, dbcj_integer, dbcj_double, NULL, dbcj_string,
|
||||
dbcj_start_map, dbcj_map_key, dbcj_end_map,
|
||||
dbcj_start_array, dbcj_end_array
|
||||
dbcj_start_map, NULL, NULL,
|
||||
dbcj_start_array, NULL
|
||||
};
|
||||
|
||||
long dbPutConvertJSON(const char *json, short dbrType,
|
||||
void *pdest, long *pnRequest)
|
||||
{
|
||||
parseContext context, *parser = &context;
|
||||
yajl_alloc_funcs dbcj_alloc;
|
||||
yajl_handle yh;
|
||||
yajl_status ys;
|
||||
size_t jlen = strlen(json);
|
||||
long status;
|
||||
|
||||
if(INVALID_DB_REQ(dbrType))
|
||||
if (INVALID_DB_REQ(dbrType)) {
|
||||
errlogPrintf("dbConvertJSON: Invalid dbrType %d\n", dbrType);
|
||||
return S_db_badDbrtype;
|
||||
}
|
||||
|
||||
if (!jlen) {
|
||||
*pnRequest = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!jlen) {
|
||||
*pnRequest = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
parser->depth = 0;
|
||||
parser->dbrType = dbrType;
|
||||
@@ -168,10 +145,11 @@ long dbPutConvertJSON(const char *json, short dbrType,
|
||||
parser->pdest = pdest;
|
||||
parser->elems = *pnRequest;
|
||||
|
||||
yajl_set_default_alloc_funcs(&dbcj_alloc);
|
||||
yh = yajl_alloc(&dbcj_callbacks, &dbcj_alloc, parser);
|
||||
if (!yh)
|
||||
yh = yajl_alloc(&dbcj_callbacks, NULL, parser);
|
||||
if (!yh) {
|
||||
errlogPrintf("dbConvertJSON: out of memory\n");
|
||||
return S_db_noMemory;
|
||||
}
|
||||
|
||||
ys = yajl_parse(yh, (const unsigned char *) json, jlen);
|
||||
if (ys == yajl_status_ok)
|
||||
@@ -183,36 +161,23 @@ long dbPutConvertJSON(const char *json, short dbrType,
|
||||
status = 0;
|
||||
break;
|
||||
|
||||
case yajl_status_error: {
|
||||
unsigned char *err = yajl_get_error(yh, 1,
|
||||
(const unsigned char *) json, jlen);
|
||||
fprintf(stderr, "dbConvertJSON: %s\n", err);
|
||||
yajl_free_error(yh, err);
|
||||
default: {
|
||||
unsigned char *err = yajl_get_error(yh, 1,
|
||||
(const unsigned char *) json, jlen);
|
||||
errlogPrintf("dbConvertJSON: %s", err);
|
||||
yajl_free_error(yh, err);
|
||||
status = S_db_badField;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
status = S_db_badField;
|
||||
}
|
||||
|
||||
yajl_free(yh);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static yajl_callbacks dblsj_callbacks = {
|
||||
dbcj_null, dbcj_boolean, dblsj_integer, dblsj_double, NULL, dblsj_string,
|
||||
dbcj_start_map, dbcj_map_key, dbcj_end_map,
|
||||
dbcj_start_array, dbcj_end_array
|
||||
};
|
||||
|
||||
long dbLSConvertJSON(const char *json, char *pdest, epicsUInt32 size,
|
||||
epicsUInt32 *plen)
|
||||
{
|
||||
parseContext context, *parser = &context;
|
||||
yajl_alloc_funcs dbcj_alloc;
|
||||
yajl_handle yh;
|
||||
yajl_status ys;
|
||||
size_t jlen = strlen(json);
|
||||
long nRequest = size-1;
|
||||
long status;
|
||||
|
||||
if (!size) {
|
||||
@@ -220,36 +185,8 @@ long dbLSConvertJSON(const char *json, char *pdest, epicsUInt32 size,
|
||||
return 0;
|
||||
}
|
||||
|
||||
parser->depth = 0;
|
||||
parser->dbrType = DBF_STRING;
|
||||
parser->dbrSize = size;
|
||||
parser->pdest = pdest;
|
||||
parser->elems = 1;
|
||||
|
||||
yajl_set_default_alloc_funcs(&dbcj_alloc);
|
||||
yh = yajl_alloc(&dblsj_callbacks, &dbcj_alloc, parser);
|
||||
if (!yh)
|
||||
return S_db_noMemory;
|
||||
|
||||
ys = yajl_parse(yh, (const unsigned char *) json, jlen);
|
||||
|
||||
switch (ys) {
|
||||
case yajl_status_ok:
|
||||
*plen = (char *) parser->pdest - pdest + 1;
|
||||
status = 0;
|
||||
break;
|
||||
|
||||
case yajl_status_error: {
|
||||
unsigned char *err = yajl_get_error(yh, 1,
|
||||
(const unsigned char *) json, jlen);
|
||||
fprintf(stderr, "dbLoadLS_JSON: %s\n", err);
|
||||
yajl_free_error(yh, err);
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
status = S_db_badField;
|
||||
}
|
||||
|
||||
yajl_free(yh);
|
||||
status = dbPutConvertJSON(json, DBF_CHAR, pdest, &nRequest);
|
||||
pdest[nRequest++] = 0;
|
||||
*plen = nRequest;
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -789,6 +789,18 @@ static void db_queue_event_log (evSubscrip *pevent, db_field_log *pLog)
|
||||
|
||||
LOCKEVQUE (ev_que);
|
||||
|
||||
/* if we have an event on the queue and both the last
|
||||
* event on the queue and the current event are empty,
|
||||
* simply ignore duplicate events.
|
||||
*/
|
||||
if (pevent->npend > 0u
|
||||
&& !dbfl_has_copy(*pevent->pLastLog)
|
||||
&& !dbfl_has_copy(pLog)) {
|
||||
db_delete_field_log(pLog);
|
||||
UNLOCKEVQUE (ev_que);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* add to task local event que
|
||||
*/
|
||||
|
||||
@@ -234,7 +234,7 @@ static const iocshArg dbtgfArg0 = { "record name",iocshArgString};
|
||||
static const iocshArg * const dbtgfArgs[1] = {&dbtgfArg0};
|
||||
static const iocshFuncDef dbtgfFuncDef = {"dbtgf",1,dbtgfArgs,
|
||||
"Database Test Get Field.\n"
|
||||
"Get field with different DBR_* types"};
|
||||
"Get field with different DBR_* types\n"};
|
||||
static void dbtgfCallFunc(const iocshArgBuf *args) { dbtgf(args[0].sval);}
|
||||
|
||||
/* dbtpf */
|
||||
@@ -283,7 +283,7 @@ static const iocshArg * const dbtpnArgs[2] = {&dbtpnArg0,&dbtpnArg1};
|
||||
static const iocshFuncDef dbtpnFuncDef = {"dbtpn",2,dbtpnArgs,
|
||||
"Database Put Notify\n"
|
||||
"Without value, begin async. processing and get\n"
|
||||
"With value, begin put, process, and get"};
|
||||
"With value, begin put, process, and get\n"};
|
||||
static void dbtpnCallFunc(const iocshArgBuf *args)
|
||||
{ dbtpn(args[0].sval,args[1].sval);}
|
||||
|
||||
|
||||
@@ -613,8 +613,10 @@ long dbtpn(char *pname, char *pvalue)
|
||||
ptpnInfo = dbCalloc(1, sizeof(tpnInfo));
|
||||
ptpnInfo->ppn = ppn;
|
||||
ptpnInfo->callbackDone = epicsEventCreate(epicsEventEmpty);
|
||||
strncpy(ptpnInfo->buffer, pvalue, 80);
|
||||
ptpnInfo->buffer[79] = 0;
|
||||
if (pvalue) {
|
||||
strncpy(ptpnInfo->buffer, pvalue, sizeof(ptpnInfo->buffer));
|
||||
ptpnInfo->buffer[sizeof(ptpnInfo->buffer)-1] = 0;
|
||||
}
|
||||
|
||||
ppn->usrPvt = ptpnInfo;
|
||||
epicsThreadCreate("dbtpn", epicsThreadPriorityHigh,
|
||||
|
||||
@@ -996,8 +996,12 @@ static void printBuffer(
|
||||
i = 0;
|
||||
while (len > 0) {
|
||||
int chunk = (len > MAXLINE - 5) ? MAXLINE - 5 : len;
|
||||
|
||||
sprintf(pmsg, "\"%.*s\"", chunk, (char *)pbuffer + i);
|
||||
strcpy(pmsg, "\"");
|
||||
while (epicsStrnEscapedFromRawSize((char *)pbuffer + i, chunk) >= MAXLINE - 5)
|
||||
chunk--;
|
||||
epicsStrnEscapedFromRaw(pmsg+1, MAXLINE - 5,
|
||||
(char *)pbuffer + i, chunk);
|
||||
strcat(pmsg, "\"");
|
||||
len -= chunk; i += chunk;
|
||||
if (len > 0)
|
||||
strcat(pmsg, " +");
|
||||
|
||||
@@ -318,7 +318,7 @@ void recGblGetTimeStampSimm(void *pvoid, const epicsEnum16 simm, struct link *si
|
||||
} else {
|
||||
if (simm != menuSimmNO) {
|
||||
if (siol && !dbLinkIsConstant(siol)) {
|
||||
if (dbGetTimeStamp(siol, &prec->time))
|
||||
if (dbGetTimeStampTag(siol, &prec->time, &prec->utag))
|
||||
errlogPrintf("recGblGetTimeStampSimm: dbGetTimeStamp (sim mode) failed, %s.SIOL = %s\n",
|
||||
prec->name, siol->value.pv_link.pvname);
|
||||
return;
|
||||
|
||||
@@ -2197,12 +2197,12 @@ long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec)
|
||||
*/
|
||||
|
||||
} else if(dbCanSetLink(plink, &link_info, devsup)!=0) {
|
||||
errlogPrintf("Error: %s.%s: can't initialize link type %d with \"%s\" (type %d)\n",
|
||||
prec->name, pflddes->name, plink->type, plink->text, link_info.ltype);
|
||||
errlogPrintf("Error: %s.%s: can't initialize link type %s with \"%s\" (type %s)\n",
|
||||
prec->name, pflddes->name, pamaplinkType[plink->type].strvalue, plink->text, pamaplinkType[link_info.ltype].strvalue);
|
||||
|
||||
} else if(dbSetLink(plink, &link_info, devsup)) {
|
||||
errlogPrintf("Error: %s.%s: failed to initialize link type %d with \"%s\" (type %d)\n",
|
||||
prec->name, pflddes->name, plink->type, plink->text, link_info.ltype);
|
||||
errlogPrintf("Error: %s.%s: failed to initialize link type %s with \"%s\" (type %s)\n",
|
||||
prec->name, pflddes->name, pamaplinkType[plink->type].strvalue, plink->text, pamaplinkType[link_info.ltype].strvalue);
|
||||
}
|
||||
free(plink->text);
|
||||
plink->text = NULL;
|
||||
@@ -2274,8 +2274,8 @@ long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
|
||||
len -= (parm - pstr);
|
||||
}
|
||||
|
||||
/* generalized extraction of ID charactor and integer pairs (eg. "#C15 S14") */
|
||||
ret = sscanf(pinfo->target, "# %c%d %c%d %c%d %c%d %c%d %c",
|
||||
/* generalized extraction of ID character and integer pairs (eg. "#C15 S14") */
|
||||
ret = sscanf(pinfo->target, "# %c%i %c%i %c%i %c%i %c%i %c",
|
||||
&pinfo->hwid[0], &pinfo->hwnums[0],
|
||||
&pinfo->hwid[1], &pinfo->hwnums[1],
|
||||
&pinfo->hwid[2], &pinfo->hwnums[2],
|
||||
|
||||
@@ -16,6 +16,7 @@ caserverio_INCLUDES = -I$(SRC)/ca/client
|
||||
camessage_INCLUDES = -I$(SRC)/ca/client
|
||||
|
||||
INC += rsrv.h
|
||||
INC += server.h
|
||||
|
||||
DBD += rsrv.dbd
|
||||
|
||||
|
||||
@@ -280,6 +280,37 @@ static void log_header (
|
||||
struct channel_in_use *pciu;
|
||||
char hostName[256];
|
||||
|
||||
const char * cmd_str [] = {
|
||||
"CA_PROTO_VERSION",
|
||||
"CA_PROTO_EVENT_ADD",
|
||||
"CA_PROTO_EVENT_CANCEL",
|
||||
"CA_PROTO_READ",
|
||||
"CA_PROTO_WRITE",
|
||||
"CA_PROTO_SNAPSHOT",
|
||||
"CA_PROTO_SEARCH",
|
||||
"CA_PROTO_BUILD",
|
||||
"CA_PROTO_EVENTS_OFF",
|
||||
"CA_PROTO_EVENTS_ON",
|
||||
"CA_PROTO_READ_SYNC",
|
||||
"CA_PROTO_ERROR",
|
||||
"CA_PROTO_CLEAR_CHANNEL",
|
||||
"CA_PROTO_RSRV_IS_UP",
|
||||
"CA_PROTO_NOT_FOUND",
|
||||
"CA_PROTO_READ_NOTIFY",
|
||||
"CA_PROTO_READ_BUILD",
|
||||
"REPEATER_CONFIRM",
|
||||
"CA_PROTO_CREATE_CHAN",
|
||||
"CA_PROTO_WRITE_NOTIFY",
|
||||
"CA_PROTO_CLIENT_NAME",
|
||||
"CA_PROTO_HOST_NAME",
|
||||
"CA_PROTO_ACCESS_RIGHTS",
|
||||
"CA_PROTO_ECHO",
|
||||
"REPEATER_REGISTER",
|
||||
"CA_PROTO_SIGNAL",
|
||||
"CA_PROTO_CREATE_CH_FAIL",
|
||||
"CA_PROTO_SERVER_DISCONN"
|
||||
};
|
||||
|
||||
ipAddrToDottedIP (&client->addr, hostName, sizeof(hostName));
|
||||
|
||||
pciu = MPTOPCIU(mp);
|
||||
@@ -289,8 +320,10 @@ static void log_header (
|
||||
hostName, pContext);
|
||||
}
|
||||
|
||||
epicsPrintf ( "CAS: Request from %s => cmmd=%d cid=0x%x type=%d count=%d postsize=%u\n",
|
||||
hostName, mp->m_cmmd, mp->m_cid, mp->m_dataType, mp->m_count, mp->m_postsize);
|
||||
epicsPrintf ( "CAS: %s Request from %s => cmmd=%d (%s) cid=0x%x type=%d count=%d postsize=%u version=%u\n",
|
||||
client->proto==IPPROTO_TCP ? "TCP" : "UDP",
|
||||
hostName, mp->m_cmmd, mp->m_cmmd <= CA_PROTO_LAST_CMMD ? cmd_str[mp->m_cmmd] : "invalid",
|
||||
mp->m_cid, mp->m_dataType, mp->m_count, mp->m_postsize, client->minor_version_number);
|
||||
|
||||
epicsPrintf ( "CAS: Request from %s => available=0x%x \tN=%u paddr=%p\n",
|
||||
hostName, mp->m_available, mnum, (pciu ? (void *)&pciu->dbch : NULL));
|
||||
@@ -319,6 +352,18 @@ unsigned lineno
|
||||
SEND_UNLOCK ( client );
|
||||
}
|
||||
|
||||
/*
|
||||
* bad_udp_cmd_beacon()
|
||||
*/
|
||||
static int bad_udp_cmd_beacon ( caHdrLargeArray *mp,
|
||||
void *pPayload, struct client *pClient )
|
||||
{
|
||||
if (CASDEBUG > 0)
|
||||
log_header ("got a beacon on the wrong UDP port",
|
||||
pClient, mp, pPayload, 0);
|
||||
return RSRV_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* bad_udp_cmd_action()
|
||||
*/
|
||||
@@ -363,6 +408,8 @@ static int tcp_version_action ( caHdrLargeArray *mp, void *pPayload,
|
||||
|
||||
client->minor_version_number = mp->m_count;
|
||||
|
||||
DLOG(3, ("TCP set version %u\n", client->minor_version_number));
|
||||
|
||||
if (!CA_VSUPPORTED(mp->m_count)) {
|
||||
DLOG ( 2, ( "CAS: Ignore version from unsupported client %u\n", mp->m_count ) );
|
||||
return RSRV_ERROR;
|
||||
@@ -1213,6 +1260,7 @@ static int claim_ciu_action ( caHdrLargeArray *mp,
|
||||
struct dbChannel *dbch;
|
||||
char *pName = (char *) pPayload;
|
||||
|
||||
DLOG (3, ("claim_ciu_action: version = %u\n", mp->m_available));
|
||||
/*
|
||||
* The available field is used (abused)
|
||||
* here to communicate the miner version number
|
||||
@@ -2121,6 +2169,8 @@ static int udp_version_action ( caHdrLargeArray *mp, void *pPayload, struct clie
|
||||
{
|
||||
client->minor_version_number = mp->m_count;
|
||||
|
||||
DLOG (3, ("UDP set version %u\n", client->minor_version_number));
|
||||
|
||||
if (!CA_VSUPPORTED(mp->m_count)) {
|
||||
DLOG ( 2, ( "CAS: Ignore version from unsupported client %u\n", mp->m_count ) );
|
||||
return RSRV_ERROR;
|
||||
@@ -2174,6 +2224,9 @@ static int search_reply_udp ( caHdrLargeArray *mp, void *pPayload, struct client
|
||||
size_t spaceNeeded;
|
||||
size_t reasonableMonitorSpace = 10;
|
||||
|
||||
DLOG (3, epicsPrintf("UDP search for \"%.*s\" by %s@%s client version %u, m_count = %u\n",
|
||||
mp->m_postsize, pName, client->pUserName, client->pHostName, client->minor_version_number, mp->m_count));
|
||||
|
||||
if (!CA_VSUPPORTED(mp->m_count)) {
|
||||
DLOG ( 2, ( "CAS: Ignore search from unsupported client %u\n", mp->m_count ) );
|
||||
return RSRV_ERROR;
|
||||
@@ -2261,6 +2314,9 @@ static int search_reply_tcp (
|
||||
size_t spaceNeeded;
|
||||
size_t reasonableMonitorSpace = 10;
|
||||
|
||||
DLOG (3, ("TCP search for \"%.*s\" by %s@%s client version %u, m_count = %u\n",
|
||||
mp->m_postsize, pName, client->pUserName, client->pHostName, client->minor_version_number, mp->m_count));
|
||||
|
||||
if (!CA_VSUPPORTED(mp->m_count)) {
|
||||
DLOG ( 2, ( "CAS: Ignore search from unsupported client %u\n", mp->m_count ) );
|
||||
return RSRV_ERROR;
|
||||
@@ -2368,7 +2424,7 @@ static const pProtoStubUDP udpJumpTable[] =
|
||||
bad_udp_cmd_action,
|
||||
bad_udp_cmd_action,
|
||||
bad_udp_cmd_action,
|
||||
bad_udp_cmd_action,
|
||||
bad_udp_cmd_beacon,
|
||||
bad_udp_cmd_action,
|
||||
bad_udp_cmd_action,
|
||||
bad_udp_cmd_action,
|
||||
@@ -2449,6 +2505,7 @@ int camessage ( struct client *client )
|
||||
pBody = ( void * ) ( mp + 1 );
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* ignore deprecated clients, but let newer clients identify themselves. */
|
||||
if (msg.m_cmmd!=CA_PROTO_VERSION && !CA_VSUPPORTED(client->minor_version_number)) {
|
||||
if (client->proto==IPPROTO_TCP) {
|
||||
@@ -2470,6 +2527,7 @@ int camessage ( struct client *client )
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* disconnect clients that dont send 8 byte
|
||||
|
||||
@@ -108,6 +108,7 @@ static long add_record(dbCommon *pcommon)
|
||||
|
||||
recGblRecordError(status, (void *)prec,
|
||||
"devSiSoftCallback (add_record) linked record not found");
|
||||
free(pdevPvt);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -359,16 +359,16 @@ static void checkAlarms(int64inRecord *prec, epicsTimeStamp *timeLast)
|
||||
}
|
||||
|
||||
/* DELTA calculates the absolute difference between its arguments
|
||||
* expressed as an unsigned 32-bit integer */
|
||||
* expressed as an unsigned 64-bit integer */
|
||||
#define DELTA(last, val) \
|
||||
((epicsUInt32) ((last) > (val) ? (last) - (val) : (val) - (last)))
|
||||
((epicsUInt64) ((last) > (val) ? (last) - (val) : (val) - (last)))
|
||||
|
||||
static void monitor(int64inRecord *prec)
|
||||
{
|
||||
unsigned short monitor_mask = recGblResetAlarms(prec);
|
||||
|
||||
if (prec->mdel < 0 ||
|
||||
DELTA(prec->mlst, prec->val) > (epicsUInt32) prec->mdel) {
|
||||
DELTA(prec->mlst, prec->val) > (epicsUInt64) prec->mdel) {
|
||||
/* post events for value change */
|
||||
monitor_mask |= DBE_VALUE;
|
||||
/* update last value monitored */
|
||||
@@ -376,7 +376,7 @@ static void monitor(int64inRecord *prec)
|
||||
}
|
||||
|
||||
if (prec->adel < 0 ||
|
||||
DELTA(prec->alst, prec->val) > (epicsUInt32) prec->adel) {
|
||||
DELTA(prec->alst, prec->val) > (epicsUInt64) prec->adel) {
|
||||
/* post events for archive value change */
|
||||
monitor_mask |= DBE_LOG;
|
||||
/* update last archive value monitored */
|
||||
|
||||
@@ -99,6 +99,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
prompt("Word")
|
||||
promptgroup("50 - Output")
|
||||
asl(ASL0)
|
||||
special(SPC_RESET)
|
||||
pp(TRUE)
|
||||
}
|
||||
field(OMSL,DBF_MENU) {
|
||||
|
||||
@@ -139,6 +139,7 @@ static long process(struct dbCommon *pcommon)
|
||||
if (!pact && prec->pact)
|
||||
return 0;
|
||||
|
||||
prec->pact = TRUE;
|
||||
prec->udf = FALSE;
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ if ($opt_D) { # Output dependencies only
|
||||
}
|
||||
|
||||
$Text::Wrap::columns = 75;
|
||||
$Text::Wrap::huge = "overflow";
|
||||
|
||||
# Eliminate chars not allowed in C symbol names
|
||||
my $c_bad_ident_chars = '[^0-9A-Za-z_]';
|
||||
|
||||
27
modules/database/test/std/rec/regressCalcout.db
Normal file
27
modules/database/test/std/rec/regressCalcout.db
Normal file
@@ -0,0 +1,27 @@
|
||||
record(calcout, "cout") {
|
||||
field(INPA, "99")
|
||||
field(INPB, "99")
|
||||
field(INPC, "99")
|
||||
field(INPD, "99")
|
||||
}
|
||||
record(ai, "ain") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
}
|
||||
record(bi, "bin") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
}
|
||||
record(int64in, "iin") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
}
|
||||
record(longin, "lin") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
}
|
||||
record(mbbi, "min") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
}
|
||||
record(mbbiDirect, "din") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
}
|
||||
record(stringin, "sin") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
}
|
||||
@@ -134,15 +134,63 @@ void testCADisconn(void)
|
||||
testdbPutFieldFail(-1, "ai:disconn.PROC", DBF_LONG, 1);
|
||||
testdbGetFieldEqual("ai:disconn.SEVR", DBF_LONG, INVALID_ALARM);
|
||||
testdbGetFieldEqual("ai:disconn.STAT", DBF_LONG, LINK_ALARM);
|
||||
|
||||
testIocShutdownOk();
|
||||
testdbCleanup();
|
||||
}
|
||||
|
||||
/* lp:1824277 Regression in calcout, setting links at runtime */
|
||||
static void
|
||||
testSpecialLinks(void)
|
||||
{
|
||||
testDiag("In testSpecialLinks()");
|
||||
|
||||
startRegressTestIoc("regressCalcout.db");
|
||||
|
||||
testdbPutFieldOk("cout.INPA", DBF_STRING, "10");
|
||||
testdbGetFieldEqual("cout.A", DBF_LONG, 10);
|
||||
testdbGetFieldEqual("cout.INAV", DBF_LONG, calcoutINAV_CON);
|
||||
testdbPutFieldOk("cout.A", DBF_LONG, 15);
|
||||
testdbPutFieldOk("cout.INPB", DBF_STRING, "{\"const\":20}");
|
||||
testdbGetFieldEqual("cout.B", DBF_LONG, 20);
|
||||
testdbGetFieldEqual("cout.INBV", DBF_LONG, calcoutINAV_CON);
|
||||
testdbPutFieldOk("cout.B", DBF_LONG, 25);
|
||||
testdbPutFieldOk("cout.INPC", DBF_STRING, "cout.A");
|
||||
testdbGetFieldEqual("cout.C", DBF_LONG, 99);
|
||||
testdbGetFieldEqual("cout.INCV", DBF_LONG, calcoutINAV_LOC);
|
||||
testdbPutFieldOk("cout.INPD", DBF_STRING, "no-such-pv");
|
||||
testdbGetFieldEqual("cout.D", DBF_LONG, 99);
|
||||
testdbGetFieldEqual("cout.INDV", DBF_LONG, calcoutINAV_EXT_NC);
|
||||
|
||||
eltc(0);
|
||||
testdbPutFieldOk("ain.INP", DBF_STRING, "cout");
|
||||
testdbPutFieldFail(S_db_badField, "ain.INP", DBF_STRING, "{\"const\":1}");
|
||||
testdbPutFieldOk("bin.INP", DBF_STRING, "cout");
|
||||
testdbPutFieldFail(S_db_badField, "bin.INP", DBF_STRING, "{\"const\":1}");
|
||||
testdbPutFieldOk("iin.INP", DBF_STRING, "cout");
|
||||
testdbPutFieldFail(S_db_badField, "iin.INP", DBF_STRING, "{\"const\":1}");
|
||||
testdbPutFieldOk("lin.INP", DBF_STRING, "cout");
|
||||
testdbPutFieldFail(S_db_badField, "lin.INP", DBF_STRING, "{\"const\":1}");
|
||||
testdbPutFieldOk("min.INP", DBF_STRING, "cout");
|
||||
testdbPutFieldFail(S_db_badField, "min.INP", DBF_STRING, "{\"const\":1}");
|
||||
testdbPutFieldOk("din.INP", DBF_STRING, "cout");
|
||||
testdbPutFieldFail(S_db_badField, "din.INP", DBF_STRING, "{\"const\":1}");
|
||||
testdbPutFieldOk("sin.INP", DBF_STRING, "cout");
|
||||
testdbPutFieldFail(S_db_badField, "sin.INP", DBF_STRING, "{\"const\":1}");
|
||||
eltc(1);
|
||||
|
||||
testIocShutdownOk();
|
||||
testdbCleanup();
|
||||
}
|
||||
|
||||
|
||||
MAIN(regressTest)
|
||||
{
|
||||
testPlan(34);
|
||||
testPlan(62);
|
||||
testArrayLength1();
|
||||
testHexConstantLinks();
|
||||
testLinkMS();
|
||||
testCADisconn();
|
||||
testSpecialLinks();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
@@ -221,6 +221,7 @@ LIBCOM_API long
|
||||
int cond_count = 0;
|
||||
char * const pdest = pout;
|
||||
char *pnext;
|
||||
const char* psrc_orig = psrc;
|
||||
|
||||
if (psrc == NULL || *psrc == '\0' ||
|
||||
pout == NULL || perror == NULL) {
|
||||
@@ -427,10 +428,12 @@ LIBCOM_API long
|
||||
pstacktop--;
|
||||
}
|
||||
|
||||
/*
|
||||
if (cond_count != 0) {
|
||||
*perror = CALC_ERR_CONDITIONAL;
|
||||
goto bad;
|
||||
}
|
||||
*/
|
||||
if (runtime_depth > 1) {
|
||||
*perror = CALC_ERR_TOOMANY;
|
||||
goto bad;
|
||||
@@ -475,8 +478,12 @@ LIBCOM_API long
|
||||
*pout = END_EXPRESSION;
|
||||
|
||||
if (cond_count != 0) {
|
||||
fprintf(stderr, "Deprecated CALC \"%s\": %s\n",
|
||||
psrc_orig, calcErrorStr(CALC_ERR_CONDITIONAL));
|
||||
/*
|
||||
*perror = CALC_ERR_CONDITIONAL;
|
||||
goto bad;
|
||||
*/
|
||||
}
|
||||
if (operand_needed || runtime_depth != 1) {
|
||||
*perror = CALC_ERR_INCOMPLETE;
|
||||
|
||||
1
modules/libcom/src/env/envDefs.h
vendored
1
modules/libcom/src/env/envDefs.h
vendored
@@ -76,6 +76,7 @@ LIBCOM_API extern const ENV_PARAM EPICS_IOC_LOG_FILE_COMMAND;
|
||||
LIBCOM_API extern const ENV_PARAM IOCSH_PS1;
|
||||
LIBCOM_API extern const ENV_PARAM IOCSH_HISTSIZE;
|
||||
LIBCOM_API extern const ENV_PARAM IOCSH_HISTEDIT_DISABLE;
|
||||
LIBCOM_API extern const ENV_PARAM EPICS_MUTEX_USE_PRIORITY_INHERITANCE;
|
||||
LIBCOM_API extern const ENV_PARAM *env_param_list[];
|
||||
|
||||
struct in_addr;
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
#include <errno.h>
|
||||
|
||||
#define ERRLOG_INIT
|
||||
#include "adjustment.h"
|
||||
#include "dbDefs.h"
|
||||
#include "epicsThread.h"
|
||||
#include "cantProceed.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsString.h"
|
||||
#include "epicsInterrupt.h"
|
||||
#include "errMdef.h"
|
||||
#include "errSymTbl.h"
|
||||
@@ -35,8 +35,20 @@
|
||||
#include "epicsExit.h"
|
||||
|
||||
|
||||
#define BUFFER_SIZE 1280
|
||||
#define MAX_MESSAGE_SIZE 256
|
||||
#define MIN_BUFFER_SIZE 1280
|
||||
#define MIN_MESSAGE_SIZE 256
|
||||
#define MAX_MESSAGE_SIZE 0x00ffffff
|
||||
|
||||
/* errlog buffers contain null terminated strings, each prefixed
|
||||
* with a 1 byte header containing flags.
|
||||
*/
|
||||
/* State of entries in a buffer. */
|
||||
#define ERL_STATE_MASK 0xc0
|
||||
#define ERL_STATE_FREE 0x00
|
||||
#define ERL_STATE_WRITE 0x80
|
||||
#define ERL_STATE_READY 0x40
|
||||
/* should this message be echoed to the console? */
|
||||
#define ERL_LOCALECHO 0x20
|
||||
|
||||
/*Declare storage for errVerbose */
|
||||
int errVerbose = 0;
|
||||
@@ -44,137 +56,183 @@ int errVerbose = 0;
|
||||
static void errlogExitHandler(void *);
|
||||
static void errlogThread(void);
|
||||
|
||||
static char *msgbufGetFree(int noConsoleMessage);
|
||||
static void msgbufSetSize(int size); /* Send 'size' chars plus trailing '\0' */
|
||||
static char *msgbufGetSend(int *noConsoleMessage);
|
||||
static void msgbufFreeSend(void);
|
||||
|
||||
typedef struct listenerNode{
|
||||
ELLNODE node;
|
||||
errlogListener listener;
|
||||
void *pPrivate;
|
||||
} listenerNode;
|
||||
|
||||
/*each message consists of a msgNode immediately followed by the message */
|
||||
typedef struct msgNode {
|
||||
ELLNODE node;
|
||||
char *message;
|
||||
int length;
|
||||
int noConsoleMessage;
|
||||
} msgNode;
|
||||
typedef struct {
|
||||
char *base;
|
||||
size_t pos;
|
||||
size_t nchar;
|
||||
} buffer_t;
|
||||
|
||||
static struct {
|
||||
epicsEventId waitForWork; /*errlogThread waits for this*/
|
||||
epicsMutexId msgQueueLock;
|
||||
/* const after errlogInit() */
|
||||
size_t maxMsgSize;
|
||||
/* alloc size of both buffer_t::base */
|
||||
size_t bufSize;
|
||||
int errlogInitFailed;
|
||||
|
||||
epicsMutexId listenerLock;
|
||||
epicsEventId waitForFlush; /*errlogFlush waits for this*/
|
||||
epicsEventId flush; /*errlogFlush sets errlogThread does a Try*/
|
||||
epicsMutexId flushLock;
|
||||
epicsEventId waitForExit; /*errlogExitHandler waits for this*/
|
||||
int atExit; /*TRUE when errlogExitHandler is active*/
|
||||
ELLLIST listenerList;
|
||||
ELLLIST msgQueue;
|
||||
msgNode *pnextSend;
|
||||
int errlogInitFailed;
|
||||
int buffersize;
|
||||
int maxMsgSize;
|
||||
int msgNeeded;
|
||||
|
||||
/* notify when log->size!=0 */
|
||||
epicsEventId waitForWork;
|
||||
/* signals when worker increments flushSeq */
|
||||
epicsEventId waitForSeq;
|
||||
epicsMutexId msgQueueLock;
|
||||
|
||||
/* guarded by msgQueueLock */
|
||||
int atExit;
|
||||
int sevToLog;
|
||||
int toConsole;
|
||||
FILE *console;
|
||||
int missedMessages;
|
||||
char *pbuffer;
|
||||
} pvtData;
|
||||
|
||||
/* A loop counter maintained by errlogThread. */
|
||||
epicsUInt32 flushSeq;
|
||||
unsigned long nFlushers;
|
||||
unsigned long nLost;
|
||||
|
||||
/*
|
||||
* vsnprintf with truncation message
|
||||
/* 'log' and 'print' combine to form a double buffer. */
|
||||
buffer_t *log;
|
||||
buffer_t *print;
|
||||
|
||||
/* actual storage which 'log' and 'print' point to */
|
||||
buffer_t bufs[2];
|
||||
} pvt;
|
||||
|
||||
/* Returns an pointer to pvt.maxMsgSize bytes, or NULL if ring buffer is full.
|
||||
* When !NULL, caller _must_ later msgbufCommit()
|
||||
*/
|
||||
static int tvsnPrint(char *str, size_t size, const char *format, va_list ap)
|
||||
static
|
||||
char* msgbufAlloc(void)
|
||||
{
|
||||
static const char tmsg[] = "<<TRUNCATED>>\n";
|
||||
int nchar = epicsVsnprintf(str, size, format ? format : "", ap);
|
||||
char *ret = NULL;
|
||||
|
||||
if (nchar >= size) {
|
||||
if (size > sizeof tmsg)
|
||||
strcpy(str + size - sizeof tmsg, tmsg);
|
||||
nchar = size - 1;
|
||||
if (epicsInterruptIsInterruptContext()) {
|
||||
epicsInterruptContextMessage
|
||||
("errlog called from interrupt level\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
errlogInit(0);
|
||||
epicsMutexMustLock(pvt.msgQueueLock); /* matched in msgbufCommit() */
|
||||
if(pvt.bufSize - pvt.log->pos - pvt.log->nchar >= 1+pvt.maxMsgSize) {
|
||||
/* there is enough space for the worst cast */
|
||||
ret = pvt.log->base + pvt.log->pos;
|
||||
if (pvt.log->nchar) {
|
||||
/* append to last message */
|
||||
return ret + 1 + pvt.log->nchar;
|
||||
}
|
||||
/* new message */
|
||||
ret[0] = ERL_STATE_WRITE;
|
||||
ret++;
|
||||
}
|
||||
|
||||
if(!ret) {
|
||||
pvt.nLost++;
|
||||
epicsMutexUnlock(pvt.msgQueueLock);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
size_t msgbufCommit(size_t nchar, int localEcho)
|
||||
{
|
||||
int isOkToBlock = epicsThreadIsOkToBlock();
|
||||
int wasEmpty = pvt.log->pos==0;
|
||||
int atExit = pvt.atExit;
|
||||
char *start = pvt.log->base + pvt.log->pos + pvt.log->nchar;
|
||||
|
||||
/* nchar returned by snprintf() is >= maxMsgSize when truncated */
|
||||
if(nchar >= pvt.maxMsgSize) {
|
||||
const char *trunc = "<<TRUNCATED>>\n";
|
||||
nchar = pvt.maxMsgSize - 1u;
|
||||
|
||||
strcpy(start + 1u + nchar - strlen(trunc), trunc);
|
||||
/* assert(strlen(start+1u)==nchar); */
|
||||
}
|
||||
|
||||
start[1u + nchar] = '\0';
|
||||
|
||||
if(localEcho && isOkToBlock && atExit) {
|
||||
/* errlogThread is not running, so we print directly
|
||||
* and then abandon the buffer.
|
||||
*/
|
||||
fprintf(pvt.console, "%s", start);
|
||||
|
||||
} else if (start[nchar] != '\n') {
|
||||
/* incomplete message, prepare to append */
|
||||
pvt.log->nchar += nchar;
|
||||
|
||||
} else {
|
||||
pvt.log->base[pvt.log->pos] = ERL_STATE_READY | (localEcho ? ERL_LOCALECHO : 0);
|
||||
|
||||
pvt.log->pos += 1 + pvt.log->nchar + nchar + 1;
|
||||
pvt.log->nchar = 0;
|
||||
}
|
||||
|
||||
epicsMutexUnlock(pvt.msgQueueLock); /* matched in msgbufAlloc() */
|
||||
|
||||
if(wasEmpty && !atExit && !pvt.log->nchar)
|
||||
epicsEventMustTrigger(pvt.waitForWork);
|
||||
|
||||
if(localEcho && isOkToBlock && !atExit)
|
||||
errlogFlush();
|
||||
|
||||
return nchar;
|
||||
}
|
||||
|
||||
static
|
||||
void errlogSequence(void)
|
||||
{
|
||||
int wakeNext = 0;
|
||||
size_t seq;
|
||||
|
||||
if (pvt.atExit)
|
||||
return;
|
||||
|
||||
epicsMutexMustLock(pvt.msgQueueLock);
|
||||
pvt.nFlushers++;
|
||||
seq = pvt.flushSeq;
|
||||
|
||||
while(seq == pvt.flushSeq && !pvt.atExit) {
|
||||
epicsMutexUnlock(pvt.msgQueueLock);
|
||||
/* force worker to wake and increment seq */
|
||||
epicsEventMustTrigger(pvt.waitForWork);
|
||||
epicsEventMustWait(pvt.waitForSeq);
|
||||
epicsMutexMustLock(pvt.msgQueueLock);
|
||||
}
|
||||
|
||||
pvt.nFlushers--;
|
||||
wakeNext = pvt.nFlushers!=0u;
|
||||
epicsMutexUnlock(pvt.msgQueueLock);
|
||||
|
||||
if(wakeNext)
|
||||
epicsEventMustTrigger(pvt.waitForSeq);
|
||||
}
|
||||
|
||||
int errlogPrintf(const char *pFormat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
char *pbuffer;
|
||||
int nchar;
|
||||
int isOkToBlock;
|
||||
|
||||
if (epicsInterruptIsInterruptContext()) {
|
||||
epicsInterruptContextMessage
|
||||
("errlogPrintf called from interrupt level\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
errlogInit(0);
|
||||
isOkToBlock = epicsThreadIsOkToBlock();
|
||||
|
||||
if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {
|
||||
FILE *console = pvtData.console ? pvtData.console : stderr;
|
||||
|
||||
va_start(pvar, pFormat);
|
||||
nchar = vfprintf(console, pFormat, pvar);
|
||||
va_end (pvar);
|
||||
fflush(console);
|
||||
}
|
||||
|
||||
if (pvtData.atExit)
|
||||
return nchar;
|
||||
|
||||
pbuffer = msgbufGetFree(isOkToBlock);
|
||||
if (!pbuffer)
|
||||
return 0;
|
||||
|
||||
va_start(pvar, pFormat);
|
||||
nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar);
|
||||
va_end(pvar);
|
||||
msgbufSetSize(nchar);
|
||||
return nchar;
|
||||
int ret;
|
||||
va_list args;
|
||||
va_start(args, pFormat);
|
||||
ret = errlogVprintf(pFormat, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int errlogVprintf(const char *pFormat,va_list pvar)
|
||||
{
|
||||
int nchar;
|
||||
char *pbuffer;
|
||||
int isOkToBlock;
|
||||
FILE *console;
|
||||
int nchar = 0;
|
||||
char *buf = msgbufAlloc();
|
||||
|
||||
if (epicsInterruptIsInterruptContext()) {
|
||||
epicsInterruptContextMessage
|
||||
("errlogVprintf called from interrupt level\n");
|
||||
return 0;
|
||||
if(buf) {
|
||||
nchar = epicsVsnprintf(buf, pvt.maxMsgSize, pFormat, pvar);
|
||||
nchar = msgbufCommit(nchar, pvt.toConsole);
|
||||
}
|
||||
|
||||
errlogInit(0);
|
||||
if (pvtData.atExit)
|
||||
return 0;
|
||||
isOkToBlock = epicsThreadIsOkToBlock();
|
||||
|
||||
pbuffer = msgbufGetFree(isOkToBlock);
|
||||
if (!pbuffer) {
|
||||
console = pvtData.console ? pvtData.console : stderr;
|
||||
vfprintf(console, pFormat, pvar);
|
||||
fflush(console);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar);
|
||||
if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {
|
||||
console = pvtData.console ? pvtData.console : stderr;
|
||||
fprintf(console, "%s", pbuffer);
|
||||
fflush(console);
|
||||
}
|
||||
msgbufSetSize(nchar);
|
||||
return nchar;
|
||||
}
|
||||
|
||||
@@ -188,14 +246,6 @@ int errlogPrintfNoConsole(const char *pFormat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
int nchar;
|
||||
|
||||
if (epicsInterruptIsInterruptContext()) {
|
||||
epicsInterruptContextMessage
|
||||
("errlogPrintfNoConsole called from interrupt level\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
errlogInit(0);
|
||||
va_start(pvar, pFormat);
|
||||
nchar = errlogVprintfNoConsole(pFormat, pvar);
|
||||
va_end(pvar);
|
||||
@@ -204,25 +254,13 @@ int errlogPrintfNoConsole(const char *pFormat, ...)
|
||||
|
||||
int errlogVprintfNoConsole(const char *pFormat, va_list pvar)
|
||||
{
|
||||
int nchar;
|
||||
char *pbuffer;
|
||||
int nchar = 0;
|
||||
char *buf = msgbufAlloc();
|
||||
|
||||
if (epicsInterruptIsInterruptContext()) {
|
||||
epicsInterruptContextMessage
|
||||
("errlogVprintfNoConsole called from interrupt level\n");
|
||||
return 0;
|
||||
if(buf) {
|
||||
nchar = epicsVsnprintf(buf, pvt.maxMsgSize, pFormat, pvar);
|
||||
nchar = msgbufCommit(nchar, 0);
|
||||
}
|
||||
|
||||
errlogInit(0);
|
||||
if (pvtData.atExit)
|
||||
return 0;
|
||||
|
||||
pbuffer = msgbufGetFree(1);
|
||||
if (!pbuffer)
|
||||
return 0;
|
||||
|
||||
nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar);
|
||||
msgbufSetSize(nchar);
|
||||
return nchar;
|
||||
}
|
||||
|
||||
@@ -231,29 +269,6 @@ int errlogSevPrintf(errlogSevEnum severity, const char *pFormat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
int nchar;
|
||||
int isOkToBlock;
|
||||
|
||||
if (epicsInterruptIsInterruptContext()) {
|
||||
epicsInterruptContextMessage
|
||||
("errlogSevPrintf called from interrupt level\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
errlogInit(0);
|
||||
if (pvtData.sevToLog > severity)
|
||||
return 0;
|
||||
|
||||
isOkToBlock = epicsThreadIsOkToBlock();
|
||||
if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {
|
||||
FILE *console = pvtData.console ? pvtData.console : stderr;
|
||||
|
||||
fprintf(console, "sevr=%s ", errlogGetSevEnumString(severity));
|
||||
va_start(pvar, pFormat);
|
||||
vfprintf(console, pFormat, pvar);
|
||||
va_end(pvar);
|
||||
fflush(console);
|
||||
}
|
||||
|
||||
va_start(pvar, pFormat);
|
||||
nchar = errlogSevVprintf(severity, pFormat, pvar);
|
||||
va_end(pvar);
|
||||
@@ -262,35 +277,15 @@ int errlogSevPrintf(errlogSevEnum severity, const char *pFormat, ...)
|
||||
|
||||
int errlogSevVprintf(errlogSevEnum severity, const char *pFormat, va_list pvar)
|
||||
{
|
||||
char *pnext;
|
||||
int nchar;
|
||||
int totalChar = 0;
|
||||
int isOkToBlock;
|
||||
int nchar = 0;
|
||||
char *buf = msgbufAlloc();
|
||||
|
||||
if (epicsInterruptIsInterruptContext()) {
|
||||
epicsInterruptContextMessage
|
||||
("errlogSevVprintf called from interrupt level\n");
|
||||
return 0;
|
||||
if(buf) {
|
||||
nchar = sprintf(buf, "sevr=%s ", errlogGetSevEnumString(severity));
|
||||
if(nchar < pvt.maxMsgSize)
|
||||
nchar += epicsVsnprintf(buf + nchar, pvt.maxMsgSize - nchar, pFormat, pvar);
|
||||
nchar = msgbufCommit(nchar, pvt.toConsole);
|
||||
}
|
||||
|
||||
errlogInit(0);
|
||||
if (pvtData.atExit)
|
||||
return 0;
|
||||
|
||||
isOkToBlock = epicsThreadIsOkToBlock();
|
||||
pnext = msgbufGetFree(isOkToBlock);
|
||||
if (!pnext)
|
||||
return 0;
|
||||
|
||||
nchar = sprintf(pnext, "sevr=%s ", errlogGetSevEnumString(severity));
|
||||
pnext += nchar; totalChar += nchar;
|
||||
nchar = tvsnPrint(pnext, pvtData.maxMsgSize - totalChar - 1, pFormat, pvar);
|
||||
pnext += nchar; totalChar += nchar;
|
||||
if (pnext[-1] != '\n') {
|
||||
strcpy(pnext,"\n");
|
||||
totalChar++;
|
||||
}
|
||||
msgbufSetSize(totalChar);
|
||||
return nchar;
|
||||
}
|
||||
|
||||
@@ -306,13 +301,19 @@ const char * errlogGetSevEnumString(errlogSevEnum severity)
|
||||
void errlogSetSevToLog(errlogSevEnum severity)
|
||||
{
|
||||
errlogInit(0);
|
||||
pvtData.sevToLog = severity;
|
||||
epicsMutexMustLock(pvt.msgQueueLock);
|
||||
pvt.sevToLog = severity;
|
||||
epicsMutexUnlock(pvt.msgQueueLock);
|
||||
}
|
||||
|
||||
errlogSevEnum errlogGetSevToLog(void)
|
||||
{
|
||||
errlogSevEnum ret;
|
||||
errlogInit(0);
|
||||
return pvtData.sevToLog;
|
||||
epicsMutexMustLock(pvt.msgQueueLock);
|
||||
ret = pvt.sevToLog;
|
||||
epicsMutexUnlock(pvt.msgQueueLock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void errlogAddListener(errlogListener listener, void *pPrivate)
|
||||
@@ -320,16 +321,16 @@ void errlogAddListener(errlogListener listener, void *pPrivate)
|
||||
listenerNode *plistenerNode;
|
||||
|
||||
errlogInit(0);
|
||||
if (pvtData.atExit)
|
||||
if (pvt.atExit)
|
||||
return;
|
||||
|
||||
plistenerNode = callocMustSucceed(1,sizeof(listenerNode),
|
||||
"errlogAddListener");
|
||||
epicsMutexMustLock(pvtData.listenerLock);
|
||||
epicsMutexMustLock(pvt.listenerLock);
|
||||
plistenerNode->listener = listener;
|
||||
plistenerNode->pPrivate = pPrivate;
|
||||
ellAdd(&pvtData.listenerList,&plistenerNode->node);
|
||||
epicsMutexUnlock(pvtData.listenerLock);
|
||||
ellAdd(&pvt.listenerList,&plistenerNode->node);
|
||||
epicsMutexUnlock(pvt.listenerLock);
|
||||
}
|
||||
|
||||
int errlogRemoveListeners(errlogListener listener, void *pPrivate)
|
||||
@@ -338,46 +339,42 @@ int errlogRemoveListeners(errlogListener listener, void *pPrivate)
|
||||
int count = 0;
|
||||
|
||||
errlogInit(0);
|
||||
if (!pvtData.atExit)
|
||||
epicsMutexMustLock(pvtData.listenerLock);
|
||||
epicsMutexMustLock(pvt.listenerLock);
|
||||
|
||||
plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList);
|
||||
plistenerNode = (listenerNode *)ellFirst(&pvt.listenerList);
|
||||
while (plistenerNode) {
|
||||
listenerNode *pnext = (listenerNode *)ellNext(&plistenerNode->node);
|
||||
|
||||
if (plistenerNode->listener == listener &&
|
||||
plistenerNode->pPrivate == pPrivate) {
|
||||
ellDelete(&pvtData.listenerList, &plistenerNode->node);
|
||||
ellDelete(&pvt.listenerList, &plistenerNode->node);
|
||||
free(plistenerNode);
|
||||
++count;
|
||||
}
|
||||
plistenerNode = pnext;
|
||||
}
|
||||
|
||||
if (!pvtData.atExit)
|
||||
epicsMutexUnlock(pvtData.listenerLock);
|
||||
|
||||
if (count == 0) {
|
||||
FILE *console = pvtData.console ? pvtData.console : stderr;
|
||||
|
||||
fprintf(console,
|
||||
"errlogRemoveListeners: No listeners found\n");
|
||||
}
|
||||
epicsMutexUnlock(pvt.listenerLock);
|
||||
return count;
|
||||
}
|
||||
|
||||
int eltc(int yesno)
|
||||
{
|
||||
errlogInit(0);
|
||||
errlogFlush();
|
||||
pvtData.toConsole = yesno;
|
||||
epicsMutexMustLock(pvt.msgQueueLock);
|
||||
pvt.toConsole = yesno;
|
||||
epicsMutexUnlock(pvt.msgQueueLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int errlogSetConsole(FILE *stream)
|
||||
{
|
||||
errlogInit(0);
|
||||
pvtData.console = stream;
|
||||
epicsMutexMustLock(pvt.msgQueueLock);
|
||||
pvt.console = stream ? stream : stderr;
|
||||
epicsMutexUnlock(pvt.msgQueueLock);
|
||||
/* make sure worker has stopped writing to the previous stream */
|
||||
errlogSequence();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -385,115 +382,93 @@ void errPrintf(long status, const char *pFileName, int lineno,
|
||||
const char *pformat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
char *pnext;
|
||||
int nchar;
|
||||
int totalChar=0;
|
||||
int isOkToBlock;
|
||||
char name[256];
|
||||
int nchar = 0;
|
||||
char *buf = msgbufAlloc();
|
||||
|
||||
if (epicsInterruptIsInterruptContext()) {
|
||||
epicsInterruptContextMessage("errPrintf called from interrupt level\n");
|
||||
return;
|
||||
}
|
||||
|
||||
errlogInit(0);
|
||||
isOkToBlock = epicsThreadIsOkToBlock();
|
||||
if (status == 0)
|
||||
status = errno;
|
||||
|
||||
if (status > 0) {
|
||||
errSymLookup(status, name, sizeof(name));
|
||||
}
|
||||
|
||||
if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {
|
||||
FILE *console = pvtData.console ? pvtData.console : stderr;
|
||||
|
||||
if (pFileName)
|
||||
fprintf(console, "filename=\"%s\" line number=%d\n",
|
||||
pFileName, lineno);
|
||||
if (status > 0)
|
||||
fprintf(console, "%s ", name);
|
||||
|
||||
va_start(pvar, pformat);
|
||||
vfprintf(console, pformat, pvar);
|
||||
va_end(pvar);
|
||||
fputc('\n', console);
|
||||
fflush(console);
|
||||
}
|
||||
|
||||
if (pvtData.atExit)
|
||||
return;
|
||||
|
||||
pnext = msgbufGetFree(isOkToBlock);
|
||||
if (!pnext)
|
||||
return;
|
||||
|
||||
if (pFileName) {
|
||||
nchar = sprintf(pnext,"filename=\"%s\" line number=%d\n",
|
||||
pFileName, lineno);
|
||||
pnext += nchar; totalChar += nchar;
|
||||
}
|
||||
|
||||
if (status > 0) {
|
||||
nchar = sprintf(pnext,"%s ",name);
|
||||
pnext += nchar; totalChar += nchar;
|
||||
}
|
||||
va_start(pvar, pformat);
|
||||
nchar = tvsnPrint(pnext, pvtData.maxMsgSize - totalChar - 1, pformat, pvar);
|
||||
va_end(pvar);
|
||||
if (nchar>0) {
|
||||
pnext += nchar;
|
||||
totalChar += nchar;
|
||||
|
||||
if(buf) {
|
||||
char name[256] = "";
|
||||
|
||||
if (status > 0) {
|
||||
errSymLookup(status, name, sizeof(name));
|
||||
}
|
||||
|
||||
nchar = epicsSnprintf(buf, pvt.maxMsgSize, "%s%sfilename=\"%s\" line number=%d",
|
||||
name, status ? " " : "", pFileName, lineno);
|
||||
if(nchar < pvt.maxMsgSize)
|
||||
nchar += epicsVsnprintf(buf + nchar, pvt.maxMsgSize - nchar, pformat, pvar);
|
||||
msgbufCommit(nchar, pvt.toConsole);
|
||||
}
|
||||
strcpy(pnext, "\n");
|
||||
totalChar++ ; /*include the \n */
|
||||
msgbufSetSize(totalChar);
|
||||
|
||||
va_end(pvar);
|
||||
}
|
||||
|
||||
|
||||
static void errlogExitHandler(void *pvt)
|
||||
/* On *NIX. also RTEM and vxWorks during controlled shutdown.
|
||||
* On Windows when main() explicitly calls epicsExit(0), like default IOC main().
|
||||
* Switch to sync. print and join errlogThread.
|
||||
*
|
||||
* On Windows otherwise, errlogThread killed by exit(), and this handler is never
|
||||
* invoked. Use of errlog from OS atexit() handler is undefined.
|
||||
*/
|
||||
static void errlogExitHandler(void *raw)
|
||||
{
|
||||
pvtData.atExit = 1;
|
||||
epicsEventSignal(pvtData.waitForWork);
|
||||
epicsEventMustWait(pvtData.waitForExit);
|
||||
epicsThreadId tid = raw;
|
||||
epicsMutexMustLock(pvt.msgQueueLock);
|
||||
pvt.atExit = 1;
|
||||
epicsMutexUnlock(pvt.msgQueueLock);
|
||||
epicsEventSignal(pvt.waitForWork);
|
||||
epicsThreadMustJoin(tid);
|
||||
}
|
||||
|
||||
struct initArgs {
|
||||
int bufsize;
|
||||
int maxMsgSize;
|
||||
size_t bufsize;
|
||||
size_t maxMsgSize;
|
||||
};
|
||||
|
||||
static void errlogInitPvt(void *arg)
|
||||
{
|
||||
struct initArgs *pconfig = (struct initArgs *) arg;
|
||||
epicsThreadId tid;
|
||||
epicsThreadId tid = NULL;
|
||||
epicsThreadOpts topts = EPICS_THREAD_OPTS_INIT;
|
||||
|
||||
pvtData.errlogInitFailed = TRUE;
|
||||
pvtData.buffersize = pconfig->bufsize;
|
||||
pvtData.maxMsgSize = pconfig->maxMsgSize;
|
||||
pvtData.msgNeeded = adjustToWorstCaseAlignment(pvtData.maxMsgSize +
|
||||
sizeof(msgNode));
|
||||
ellInit(&pvtData.listenerList);
|
||||
ellInit(&pvtData.msgQueue);
|
||||
pvtData.toConsole = TRUE;
|
||||
pvtData.console = NULL;
|
||||
pvtData.waitForWork = epicsEventMustCreate(epicsEventEmpty);
|
||||
pvtData.listenerLock = epicsMutexMustCreate();
|
||||
pvtData.msgQueueLock = epicsMutexMustCreate();
|
||||
pvtData.waitForFlush = epicsEventMustCreate(epicsEventEmpty);
|
||||
pvtData.flush = epicsEventMustCreate(epicsEventEmpty);
|
||||
pvtData.flushLock = epicsMutexMustCreate();
|
||||
pvtData.waitForExit = epicsEventMustCreate(epicsEventEmpty);
|
||||
pvtData.pbuffer = callocMustSucceed(1, pvtData.buffersize,
|
||||
"errlogInitPvt");
|
||||
topts.priority = epicsThreadPriorityLow;
|
||||
topts.stackSize = epicsThreadStackSmall;
|
||||
topts.joinable = 1;
|
||||
|
||||
/* Use of *Must* alloc functions would recurse on failure since
|
||||
* cantProceed() calls us.
|
||||
*/
|
||||
|
||||
pvt.errlogInitFailed = TRUE;
|
||||
pvt.bufSize = pconfig->bufsize;
|
||||
pvt.maxMsgSize = pconfig->maxMsgSize;
|
||||
ellInit(&pvt.listenerList);
|
||||
pvt.toConsole = TRUE;
|
||||
pvt.console = stderr;
|
||||
pvt.waitForWork = epicsEventCreate(epicsEventEmpty);
|
||||
pvt.listenerLock = epicsMutexCreate();
|
||||
pvt.msgQueueLock = epicsMutexCreate();
|
||||
pvt.waitForSeq = epicsEventCreate(epicsEventEmpty);
|
||||
pvt.log = &pvt.bufs[0];
|
||||
pvt.print = &pvt.bufs[1];
|
||||
pvt.log->base = calloc(1, pvt.bufSize);
|
||||
pvt.print->base = calloc(1, pvt.bufSize);
|
||||
|
||||
errSymBld(); /* Better not to do this lazily... */
|
||||
|
||||
tid = epicsThreadCreate("errlog", epicsThreadPriorityLow,
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
(EPICSTHREADFUNC)errlogThread, 0);
|
||||
if(pvt.waitForWork
|
||||
&& pvt.listenerLock
|
||||
&& pvt.msgQueueLock
|
||||
&& pvt.waitForSeq
|
||||
&& pvt.log->base
|
||||
&& pvt.print->base
|
||||
) {
|
||||
tid = epicsThreadCreateOpt("errlog", (EPICSTHREADFUNC)errlogThread, 0, &topts);
|
||||
}
|
||||
if (tid) {
|
||||
pvtData.errlogInitFailed = FALSE;
|
||||
pvt.errlogInitFailed = FALSE;
|
||||
epicsAtExit(errlogExitHandler, tid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -503,19 +478,21 @@ int errlogInit2(int bufsize, int maxMsgSize)
|
||||
static epicsThreadOnceId errlogOnceFlag = EPICS_THREAD_ONCE_INIT;
|
||||
struct initArgs config;
|
||||
|
||||
if (pvtData.atExit)
|
||||
if (pvt.atExit)
|
||||
return 0;
|
||||
|
||||
if (bufsize < BUFFER_SIZE)
|
||||
bufsize = BUFFER_SIZE;
|
||||
if (bufsize < MIN_BUFFER_SIZE)
|
||||
bufsize = MIN_BUFFER_SIZE;
|
||||
config.bufsize = bufsize;
|
||||
|
||||
if (maxMsgSize < MAX_MESSAGE_SIZE)
|
||||
if (maxMsgSize < MIN_MESSAGE_SIZE)
|
||||
maxMsgSize = MIN_MESSAGE_SIZE;
|
||||
else if (maxMsgSize > MAX_MESSAGE_SIZE)
|
||||
maxMsgSize = MAX_MESSAGE_SIZE;
|
||||
config.maxMsgSize = maxMsgSize;
|
||||
|
||||
epicsThreadOnce(&errlogOnceFlag, errlogInitPvt, &config);
|
||||
if (pvtData.errlogInitFailed) {
|
||||
if (pvt.errlogInitFailed) {
|
||||
fprintf(stderr,"errlogInit failed\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -524,172 +501,88 @@ int errlogInit2(int bufsize, int maxMsgSize)
|
||||
|
||||
int errlogInit(int bufsize)
|
||||
{
|
||||
return errlogInit2(bufsize, MAX_MESSAGE_SIZE);
|
||||
return errlogInit2(bufsize, MIN_MESSAGE_SIZE);
|
||||
}
|
||||
|
||||
void errlogFlush(void)
|
||||
{
|
||||
int count;
|
||||
|
||||
/* wait for both buffers to be handled to know that all currently
|
||||
* logged message have been seen/sent.
|
||||
*/
|
||||
errlogInit(0);
|
||||
if (pvtData.atExit)
|
||||
return;
|
||||
|
||||
/*If nothing in queue dont wake up errlogThread*/
|
||||
epicsMutexMustLock(pvtData.msgQueueLock);
|
||||
count = ellCount(&pvtData.msgQueue);
|
||||
epicsMutexUnlock(pvtData.msgQueueLock);
|
||||
if (count <= 0)
|
||||
return;
|
||||
|
||||
/*must let errlogThread empty queue*/
|
||||
epicsMutexMustLock(pvtData.flushLock);
|
||||
epicsEventSignal(pvtData.flush);
|
||||
epicsEventSignal(pvtData.waitForWork);
|
||||
epicsEventMustWait(pvtData.waitForFlush);
|
||||
epicsMutexUnlock(pvtData.flushLock);
|
||||
errlogSequence();
|
||||
errlogSequence();
|
||||
}
|
||||
|
||||
static void errlogThread(void)
|
||||
{
|
||||
listenerNode *plistenerNode;
|
||||
int noConsoleMessage;
|
||||
char *pmessage;
|
||||
epicsMutexMustLock(pvt.msgQueueLock);
|
||||
while (!pvt.atExit) {
|
||||
pvt.flushSeq++;
|
||||
|
||||
epicsAtExit(errlogExitHandler,0);
|
||||
while (TRUE) {
|
||||
epicsEventMustWait(pvtData.waitForWork);
|
||||
while ((pmessage = msgbufGetSend(&noConsoleMessage))) {
|
||||
epicsMutexMustLock(pvtData.listenerLock);
|
||||
if (pvtData.toConsole && !noConsoleMessage) {
|
||||
FILE *console = pvtData.console ? pvtData.console : stderr;
|
||||
if(pvt.log->pos==0u) {
|
||||
int wakeFlusher = pvt.nFlushers!=0;
|
||||
epicsMutexUnlock(pvt.msgQueueLock);
|
||||
if(wakeFlusher)
|
||||
epicsEventMustTrigger(pvt.waitForSeq);
|
||||
epicsEventMustWait(pvt.waitForWork);
|
||||
epicsMutexMustLock(pvt.msgQueueLock);
|
||||
|
||||
fprintf(console, "%s", pmessage);
|
||||
} else {
|
||||
/* snapshot and swap buffers for use while unlocked */
|
||||
unsigned long nLost = pvt.nLost;
|
||||
FILE *console = pvt.toConsole ? pvt.console : NULL;
|
||||
size_t pos = 0u;
|
||||
buffer_t *print;
|
||||
|
||||
{
|
||||
buffer_t *temp = pvt.log;
|
||||
pvt.log = pvt.print;
|
||||
pvt.print = print = temp;
|
||||
}
|
||||
|
||||
pvt.nLost = 0u;
|
||||
epicsMutexUnlock(pvt.msgQueueLock);
|
||||
|
||||
while(pos < print->pos) {
|
||||
listenerNode *plistenerNode;
|
||||
const char* base = print->base + pos;
|
||||
size_t mlen = epicsStrnLen(base+1u, pvt.bufSize - pos);
|
||||
|
||||
if((base[0]&ERL_STATE_MASK) != ERL_STATE_READY || mlen>=pvt.bufSize - pos) {
|
||||
fprintf(stderr, "Logic Error: errlog buffer corruption. %02x, %zu\n",
|
||||
(unsigned)base[0], mlen);
|
||||
/* try to reset and recover */
|
||||
break;
|
||||
}
|
||||
|
||||
if(base[0]&ERL_LOCALECHO && console) {
|
||||
fprintf(console, "%s", base+1u);
|
||||
}
|
||||
|
||||
epicsMutexMustLock(pvt.listenerLock);
|
||||
plistenerNode = (listenerNode *)ellFirst(&pvt.listenerList);
|
||||
while (plistenerNode) {
|
||||
(*plistenerNode->listener)(plistenerNode->pPrivate, base+1u);
|
||||
plistenerNode = (listenerNode *)ellNext(&plistenerNode->node);
|
||||
}
|
||||
epicsMutexUnlock(pvt.listenerLock);
|
||||
|
||||
pos += 1u + mlen+1u;
|
||||
}
|
||||
|
||||
memset(print->base, 0, pvt.bufSize);
|
||||
print->pos = 0u;
|
||||
|
||||
if(nLost && console)
|
||||
fprintf(console, "errlog: lost %lu messages\n", nLost);
|
||||
|
||||
if(console)
|
||||
fflush(console);
|
||||
}
|
||||
|
||||
plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList);
|
||||
while (plistenerNode) {
|
||||
(*plistenerNode->listener)(plistenerNode->pPrivate, pmessage);
|
||||
plistenerNode = (listenerNode *)ellNext(&plistenerNode->node);
|
||||
}
|
||||
epicsMutexMustLock(pvt.msgQueueLock);
|
||||
|
||||
epicsMutexUnlock(pvtData.listenerLock);
|
||||
msgbufFreeSend();
|
||||
}
|
||||
|
||||
if (pvtData.atExit)
|
||||
break;
|
||||
if (epicsEventTryWait(pvtData.flush) != epicsEventWaitOK)
|
||||
continue;
|
||||
|
||||
epicsThreadSleep(.2); /*just wait an extra .2 seconds*/
|
||||
epicsEventSignal(pvtData.waitForFlush);
|
||||
}
|
||||
epicsEventSignal(pvtData.waitForExit);
|
||||
}
|
||||
|
||||
|
||||
static msgNode * msgbufGetNode(void)
|
||||
{
|
||||
char *pbuffer = pvtData.pbuffer;
|
||||
char *pnextFree;
|
||||
msgNode *pnextSend;
|
||||
|
||||
if (ellCount(&pvtData.msgQueue) == 0 ) {
|
||||
pnextFree = pbuffer; /* Reset if empty */
|
||||
}
|
||||
else {
|
||||
msgNode *pfirst = (msgNode *)ellFirst(&pvtData.msgQueue);
|
||||
msgNode *plast = (msgNode *)ellLast(&pvtData.msgQueue);
|
||||
char *plimit = pbuffer + pvtData.buffersize;
|
||||
|
||||
pnextFree = plast->message + adjustToWorstCaseAlignment(plast->length);
|
||||
if (pfirst > plast) {
|
||||
plimit = (char *)pfirst;
|
||||
}
|
||||
else if (pnextFree + pvtData.msgNeeded > plimit) {
|
||||
pnextFree = pbuffer; /* Hit end, wrap to start */
|
||||
plimit = (char *)pfirst;
|
||||
}
|
||||
if (pnextFree + pvtData.msgNeeded > plimit) {
|
||||
return 0; /* No room */
|
||||
}
|
||||
}
|
||||
|
||||
pnextSend = (msgNode *)pnextFree;
|
||||
pnextSend->message = pnextFree + sizeof(msgNode);
|
||||
pnextSend->length = 0;
|
||||
return pnextSend;
|
||||
}
|
||||
|
||||
static char * msgbufGetFree(int noConsoleMessage)
|
||||
{
|
||||
msgNode *pnextSend;
|
||||
|
||||
if (epicsMutexLock(pvtData.msgQueueLock) != epicsMutexLockOK)
|
||||
return 0;
|
||||
|
||||
if ((ellCount(&pvtData.msgQueue) == 0) && pvtData.missedMessages) {
|
||||
int nchar;
|
||||
|
||||
pnextSend = msgbufGetNode();
|
||||
nchar = sprintf(pnextSend->message,
|
||||
"errlog: %d messages were discarded\n", pvtData.missedMessages);
|
||||
pnextSend->length = nchar + 1;
|
||||
pvtData.missedMessages = 0;
|
||||
ellAdd(&pvtData.msgQueue, &pnextSend->node);
|
||||
}
|
||||
|
||||
pvtData.pnextSend = pnextSend = msgbufGetNode();
|
||||
if (pnextSend) {
|
||||
pnextSend->noConsoleMessage = noConsoleMessage;
|
||||
pnextSend->length = 0;
|
||||
return pnextSend->message; /* NB: msgQueueLock is still locked */
|
||||
}
|
||||
|
||||
++pvtData.missedMessages;
|
||||
epicsMutexUnlock(pvtData.msgQueueLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msgbufSetSize(int size)
|
||||
{
|
||||
msgNode *pnextSend = pvtData.pnextSend;
|
||||
|
||||
pnextSend->length = size+1;
|
||||
ellAdd(&pvtData.msgQueue, &pnextSend->node);
|
||||
epicsMutexUnlock(pvtData.msgQueueLock);
|
||||
epicsEventSignal(pvtData.waitForWork);
|
||||
}
|
||||
|
||||
|
||||
static char * msgbufGetSend(int *noConsoleMessage)
|
||||
{
|
||||
msgNode *pnextSend;
|
||||
|
||||
epicsMutexMustLock(pvtData.msgQueueLock);
|
||||
pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue);
|
||||
epicsMutexUnlock(pvtData.msgQueueLock);
|
||||
if (!pnextSend)
|
||||
return 0;
|
||||
|
||||
*noConsoleMessage = pnextSend->noConsoleMessage;
|
||||
return pnextSend->message;
|
||||
}
|
||||
|
||||
static void msgbufFreeSend(void)
|
||||
{
|
||||
msgNode *pnextSend;
|
||||
|
||||
epicsMutexMustLock(pvtData.msgQueueLock);
|
||||
pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue);
|
||||
if (!pnextSend) {
|
||||
FILE *console = pvtData.console ? pvtData.console : stderr;
|
||||
|
||||
fprintf(console, "errlog: msgbufFreeSend logic error\n");
|
||||
epicsThreadSuspendSelf();
|
||||
}
|
||||
ellDelete(&pvtData.msgQueue, &pnextSend->node);
|
||||
epicsMutexUnlock(pvtData.msgQueueLock);
|
||||
epicsMutexUnlock(pvt.msgQueueLock);
|
||||
}
|
||||
|
||||
@@ -41,4 +41,3 @@ LIBCOM_API size_t epicsStdCall freeListItemsAvail(void *pvt);
|
||||
#endif
|
||||
|
||||
#endif /*INCfreeListh*/
|
||||
|
||||
@@ -113,6 +113,7 @@ int main(void)
|
||||
|
||||
pserver->pfdctx = (void *) fdmgr_init();
|
||||
if (!pserver->pfdctx) {
|
||||
free(pserver);
|
||||
fprintf(stderr, "iocLogServer: %s\n", strerror(errno));
|
||||
return IOCLS_ERROR;
|
||||
}
|
||||
|
||||
@@ -568,6 +568,186 @@ static MAC_ENTRY *create( MAC_HANDLE *handle, const char *name, int special )
|
||||
return entry;
|
||||
}
|
||||
|
||||
#define SUCCESS 0
|
||||
#define NOVALUE 1
|
||||
#define UNTERMINATED 2
|
||||
#define DIVZERO 3
|
||||
|
||||
static int parseExpr( const char** pp, int* v, int level );
|
||||
|
||||
/* Value is a number or an expression in () */
|
||||
static int parseValue( const char** pp, int* v )
|
||||
{
|
||||
int status;
|
||||
int val;
|
||||
const char *p = *pp;
|
||||
int neg = 0;
|
||||
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
if (*p == '+' || *p == '-') neg = *p++ == '-';
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
if (*p == '(')
|
||||
{
|
||||
p++;
|
||||
if ((status = parseExpr(&p, &val, 0)) != SUCCESS) return status;
|
||||
if (*p++ != ')')
|
||||
{
|
||||
printf("macLib: missing ) after '%s'\n", *pp);
|
||||
return UNTERMINATED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char* e;
|
||||
val = strtol(p, &e, 0);
|
||||
if (e == p) return NOVALUE;
|
||||
p = e;
|
||||
}
|
||||
if (neg) val = -val;
|
||||
*pp = p;
|
||||
*v = val;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Expr is a sum or product of Values or a conditional */
|
||||
static int parseExpr( const char** pp, int* v, int level )
|
||||
{
|
||||
const char *p = *pp;
|
||||
int o = 0;
|
||||
int val0, val1, val2;
|
||||
int status = SUCCESS;
|
||||
int stat1, stat2;
|
||||
|
||||
val0 = 0;
|
||||
/* handle sums and differences */
|
||||
do {
|
||||
if ((stat1 = parseValue(&p, &val1)) != SUCCESS)
|
||||
{
|
||||
if (o && stat1 == NOVALUE)
|
||||
printf ("macLib: missing operand after '%c'\n", o);
|
||||
return stat1;
|
||||
}
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
o = *p;
|
||||
/* handle products and quotients */
|
||||
while (o == '*' || o == '/' || o == '%')
|
||||
{
|
||||
p++;
|
||||
if ((stat2 = parseValue(&p, &val2)) != SUCCESS)
|
||||
{
|
||||
if (stat2 == NOVALUE)
|
||||
printf ("macLib: missing operand after '%c'\n", o);
|
||||
return stat2;
|
||||
}
|
||||
if (o == '*') val1 *= val2;
|
||||
else if (val2 == 0)
|
||||
{
|
||||
status = DIVZERO;
|
||||
val1 = 1;
|
||||
}
|
||||
else if (o == '/') val1 /= val2;
|
||||
else val1 %= val2;
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
o = *p;
|
||||
}
|
||||
val0 += val1;
|
||||
} while (o == '+' || o == '-');
|
||||
|
||||
/* handle comparisons */
|
||||
o = *p;
|
||||
if (o == '<' || o == '>')
|
||||
{
|
||||
p++;
|
||||
if ((stat1 = parseExpr(&p, &val1, 1)) != SUCCESS)
|
||||
{
|
||||
if (stat1 == NOVALUE)
|
||||
printf ("macLib: missing expression after '%c'\n", o);
|
||||
return stat1;
|
||||
}
|
||||
if (o == '<')
|
||||
val0 = (val0 < val1);
|
||||
else
|
||||
val0 = (val0 > val1);
|
||||
}
|
||||
|
||||
/* handle conditionals */
|
||||
if (*p == '?' && level == 0)
|
||||
{
|
||||
p++;
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
if (*p != ':')
|
||||
{
|
||||
stat1 = parseExpr(&p, &val1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
val1 = val0;
|
||||
stat1 = status;
|
||||
}
|
||||
if (*p != ':')
|
||||
{
|
||||
printf("macLib: missing : after '%s'\n", *pp);
|
||||
return UNTERMINATED;
|
||||
}
|
||||
p++;
|
||||
stat2 = parseExpr(&p, &val2, 0);
|
||||
status = val0 ? stat1 : stat2;
|
||||
val0 = val0 ? val1 : val2;
|
||||
}
|
||||
|
||||
*v = val0;
|
||||
*pp = p;
|
||||
return status;
|
||||
}
|
||||
|
||||
static MAC_ENTRY *evalExpr( MAC_HANDLE *handle, const char *expr )
|
||||
{
|
||||
MAC_ENTRY *entry = NULL;
|
||||
int status;
|
||||
const char* p = expr;
|
||||
int value;
|
||||
char valuestr[40];
|
||||
char format[20] = "%d";
|
||||
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
if (*p == '%')
|
||||
{
|
||||
int i = 1;
|
||||
p++;
|
||||
while (i < sizeof(format) && strchr(" #-+0", *p))
|
||||
format[i++] = *p++;
|
||||
while (i < sizeof(format) && strchr("0123456789", *p))
|
||||
format[i++] = *p++;
|
||||
if (i < sizeof(format) && strchr("diouxXc", *p))
|
||||
{
|
||||
format[i++] = *p++;
|
||||
format[i] = 0;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
status = parseExpr(&p, &value, 0);
|
||||
if (status == DIVZERO)
|
||||
printf ("macLib: division by zero\n");
|
||||
if (status != SUCCESS)
|
||||
return NULL;
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
if (*p)
|
||||
{
|
||||
printf("macLib: rubbish at end of expression: %s\n", p);
|
||||
return NULL;
|
||||
}
|
||||
sprintf(valuestr, format, value);
|
||||
entry = create( handle, expr, TRUE );
|
||||
if ( entry )
|
||||
{
|
||||
entry->type = "calculation";
|
||||
if ( rawval( handle, entry, valuestr ) == NULL )
|
||||
return NULL;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up macro entry with matching "special" attribute by name
|
||||
*/
|
||||
@@ -579,6 +759,10 @@ static MAC_ENTRY *lookup( MAC_HANDLE *handle, const char *name, int special )
|
||||
printf( "lookup-> level = %d, name = %s, special = %d\n",
|
||||
handle->level, name, special );
|
||||
|
||||
if ( (special == FALSE) ) {
|
||||
entry = evalExpr( handle, name );
|
||||
if (entry) return entry;
|
||||
}
|
||||
/* search backwards so scoping works */
|
||||
for ( entry = last( handle ); entry != NULL; entry = previous( entry ) ) {
|
||||
if ( entry->special != special )
|
||||
@@ -698,6 +882,7 @@ static void trans( MAC_HANDLE *handle, MAC_ENTRY *entry, int level,
|
||||
/* return immediately if raw value is NULL */
|
||||
if ( *rawval == NULL ) return;
|
||||
|
||||
|
||||
/* discard quotes and escapes if level is > 0 (i.e. if these aren't
|
||||
the user's quotes and escapes) */
|
||||
discard = ( level > 0 );
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user