Compare commits
16 Commits
PSI-3.14
...
R3.14.12.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20d2cff501 | ||
|
|
860ce156a2 | ||
|
|
31fc35fbe8 | ||
|
|
e459e8bdd4 | ||
|
|
b558bd9b16 | ||
|
|
3c16c3c0da | ||
|
|
67844bacc3 | ||
|
|
7e7d230d8c | ||
|
|
c1ece40f41 | ||
|
|
a732539eee | ||
|
|
3bc0805a89 | ||
|
|
c72e35c769 | ||
|
|
2d9c5e99a1 | ||
|
|
ca22d50831 | ||
|
|
5cb91d9f6d | ||
|
|
91ce807e8b |
14
Makefile
14
Makefile
@@ -24,17 +24,3 @@ config_DEPEND_DIRS = src
|
||||
|
||||
include $(TOP)/configure/RULES_TOP
|
||||
|
||||
|
||||
ifneq ($(INSTALL_LOCATION),$(TOP))
|
||||
UNINSTALL_DIRS += $(INSTALL_LOCATION)/src
|
||||
copysrc:
|
||||
tar cf - --exclude=CVS --exclude=O.* src | tar xf - -C $(INSTALL_LOCATION)
|
||||
else
|
||||
copysrc:
|
||||
@echo "Not doing anything (INSTALL_LOCATION==TOP)"
|
||||
endif
|
||||
|
||||
tar:
|
||||
tar cfjP epics_base-$(EPICS_VERSION_NUMBER).tar.bz2 --exclude=*.o $(INSTALL_LOCATION)
|
||||
|
||||
.PHONY: copysrc tar
|
||||
|
||||
@@ -27,7 +27,7 @@ GPROF_CFLAGS_YES = -pg
|
||||
CODE_CFLAGS = $(PROF_CFLAGS_$(PROFILE)) $(GPROF_CFLAGS_$(GPROF))
|
||||
WARN_CFLAGS_YES = -Wall
|
||||
WARN_CFLAGS_NO = -w
|
||||
OPT_CFLAGS_YES = -O3 -g
|
||||
OPT_CFLAGS_YES = -O3
|
||||
OPT_CFLAGS_NO = -g
|
||||
|
||||
PROF_CXXFLAGS_YES = -p
|
||||
@@ -35,7 +35,7 @@ GPROF_CXXFLAGS_YES = -pg
|
||||
CODE_CXXFLAGS = $(PROF_CXXFLAGS_$(PROFILE)) $(GPROF_CXXFLAGS_$(GPROF))
|
||||
WARN_CXXFLAGS_YES = -Wall
|
||||
WARN_CXXFLAGS_NO = -w
|
||||
OPT_CXXFLAGS_YES = -O3 -g
|
||||
OPT_CXXFLAGS_YES = -O3
|
||||
OPT_CXXFLAGS_NO = -g
|
||||
|
||||
CODE_LDFLAGS = $(PROF_CXXFLAGS_$(PROFILE)) $(GPROF_CXXFLAGS_$(GPROF))
|
||||
|
||||
@@ -35,7 +35,7 @@ EPICS_BASE_HOST_LIBS += ca Com
|
||||
# Version number for base shared libraries (and win32 products)
|
||||
|
||||
ifdef BASE_TOP
|
||||
#SHRLIB_VERSION = $(EPICS_VERSION).$(EPICS_REVISION)
|
||||
SHRLIB_VERSION = $(EPICS_VERSION).$(EPICS_REVISION)
|
||||
PROD_VERSION = $(EPICS_VERSION).$(EPICS_REVISION)
|
||||
endif # BASE_TOP
|
||||
|
||||
|
||||
@@ -28,15 +28,10 @@ EPICS_MODIFICATION = 12
|
||||
|
||||
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
|
||||
# Not included if zero
|
||||
EPICS_PATCH_LEVEL = 7
|
||||
EPICS_PATCH_LEVEL = 8
|
||||
|
||||
# This will end in -DEV between official releases
|
||||
EPICS_DEV_SNAPSHOT=-DEV
|
||||
#EPICS_DEV_SNAPSHOT=-pre1
|
||||
#EPICS_DEV_SNAPSHOT=-pre1-DEV
|
||||
#EPICS_DEV_SNAPSHOT=-pre2
|
||||
#EPICS_DEV_SNAPSHOT=-pre2-DEV
|
||||
#EPICS_DEV_SNAPSHOT=-rc1
|
||||
EPICS_DEV_SNAPSHOT=-rc1
|
||||
#EPICS_DEV_SNAPSHOT=-rc1-DEV
|
||||
#EPICS_DEV_SNAPSHOT=-rc2
|
||||
#EPICS_DEV_SNAPSHOT=-rc2-DEV
|
||||
|
||||
@@ -54,6 +54,3 @@ EPICS_IOC_LOG_PORT=7004
|
||||
EPICS_CMD_PROTO_PORT=
|
||||
EPICS_AR_PORT=7002
|
||||
|
||||
# libCom
|
||||
# Whether to enable priority inheritance -- must be set to Y[ES]/y[es]/T[RUE]/t[rue]/1
|
||||
EPICS_MUTEX_USE_PRIORITY_INHERITANCE="NO"
|
||||
|
||||
@@ -170,7 +170,7 @@ CROSS_WARN=YES
|
||||
# NOTE: Set to YES only if you have existing R3.13 extensions to be
|
||||
# built with this base
|
||||
#
|
||||
COMPAT_TOOLS_313=YES
|
||||
#COMPAT_TOOLS_313=YES
|
||||
|
||||
# Create and/or install files for R3.13 ioc application and extension builds?
|
||||
# must be either YES or NO
|
||||
@@ -178,20 +178,19 @@ COMPAT_TOOLS_313=YES
|
||||
# NOTE: Set to YES only if you have existing R3.13 ioc applications
|
||||
# and extensions to be built with this base
|
||||
#
|
||||
COMPAT_313=YES
|
||||
COMPAT_313=NO
|
||||
|
||||
# Installation directory
|
||||
# If you don't want to install into $(TOP) dir then
|
||||
# define INSTALL_LOCATION here
|
||||
#INSTALL_LOCATION=<fullpathname>
|
||||
INSTALL_LOCATION=/usr/local/epics/base-3.14.12
|
||||
|
||||
# Use POSIX thread priority scheduling (YES or NO)
|
||||
USE_POSIX_THREAD_PRIORITY_SCHEDULING = YES
|
||||
|
||||
# Site version number, if set will append '-' and this string to the
|
||||
# EPICS version number string that is reported by many tools
|
||||
EPICS_SITE_VERSION=$(shell $(PERL) -MPOSIX -e 'print strftime "%Y-%m-%d_$(shell git describe --tags --dirty)", localtime')
|
||||
EPICS_SITE_VERSION =
|
||||
|
||||
# For GNU compiler, use pipes rather than temporary files for communication
|
||||
# between the various stages of compilation.
|
||||
|
||||
@@ -438,9 +438,6 @@ ifneq (,$(strip $(SHRLIB_VERSION)))
|
||||
@$(RM) $(subst $(SHRLIB_SUFFIX),$(SHRLIB_SUFFIX_BASE),$@)
|
||||
ln -s $< $(subst $(SHRLIB_SUFFIX),$(SHRLIB_SUFFIX_BASE),$@)
|
||||
endif # SHRLIB_VERSION
|
||||
else
|
||||
@$(RM) $@.3.14
|
||||
ln -s $< $@.3.14
|
||||
endif # SHRLIB_SUFFIX
|
||||
|
||||
ifneq ($(INSTALL_TCLLIB),$(INSTALL_BIN))
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
@@ -1 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
@@ -1 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
@@ -1 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
@@ -1,6 +0,0 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_NCURSES
|
||||
|
||||
ARCH_DEP_CFLAGS += -march=i686
|
||||
@@ -1,4 +0,0 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
|
||||
COMMANDLINE_LIBRARY = READLINE_NCURSES
|
||||
@@ -1,4 +0,0 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86
|
||||
|
||||
ARCH_DEP_CFLAGS += -march=i686
|
||||
@@ -1,2 +0,0 @@
|
||||
# Include definitions common to linux pentium targets
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-x86_64
|
||||
@@ -1 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linux-clang
|
||||
@@ -1,8 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 5.5
|
||||
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
|
||||
@@ -1,2 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.2
|
||||
@@ -1,5 +0,0 @@
|
||||
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
|
||||
@@ -1,5 +0,0 @@
|
||||
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
|
||||
@@ -1,2 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc603_long
|
||||
VXWORKS_VERSION = 6.6
|
||||
@@ -1,2 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long
|
||||
VXWORKS_VERSION = 6.6
|
||||
@@ -1,5 +0,0 @@
|
||||
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>'
|
||||
@@ -1,3 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc32
|
||||
VXWORKS_VERSION = 6.9
|
||||
#export LD_LIBRARY_PATH=$(WIND_BASE)/lmapi-5.0/$(WIND_HOST_TYPE)/lib
|
||||
@@ -1,3 +0,0 @@
|
||||
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
|
||||
@@ -1,22 +0,0 @@
|
||||
# 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
|
||||
@@ -1,14 +0,0 @@
|
||||
# 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)
|
||||
@@ -1,15 +0,0 @@
|
||||
# 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 =
|
||||
@@ -1,21 +0,0 @@
|
||||
# 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
|
||||
@@ -1,23 +0,0 @@
|
||||
# IOxOS IFC1211 and IFC14xx 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
|
||||
@@ -1,5 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
GNU = NO
|
||||
CMPLR_CLASS = clang
|
||||
CC = clang
|
||||
CCC = clang++
|
||||
@@ -42,5 +42,3 @@ LDLIBS_READLINE_CURSES = -lreadline -lcurses
|
||||
# Allow site overrides
|
||||
-include $(CONFIG)/os/CONFIG_SITE.Common.linuxCommon
|
||||
-include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).linuxCommon
|
||||
|
||||
CODE_CPPFLAGS += -fno-strict-aliasing
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# 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
|
||||
@@ -1,12 +0,0 @@
|
||||
# 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
|
||||
@@ -1,18 +0,0 @@
|
||||
# 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
|
||||
@@ -1,41 +0,0 @@
|
||||
# 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)
|
||||
@@ -14,11 +14,9 @@ ARCH_CLASS = ppc
|
||||
|
||||
# Architecture specific build flags
|
||||
ARCH_DEP_CPPFLAGS = -DCPU=PPC604
|
||||
ARCH_DEP_CFLAGS = -mcpu=604 -mstrict-align
|
||||
|
||||
CODE_CFLAGS_2 = -mno-implicit-fp
|
||||
CODE_CFLAGS_3 = -mno-implicit-fp
|
||||
CODE_CFLAGS_4 = -fno-implicit-fp
|
||||
CODE_CFLAGS += $(CODE_CFLAGS_$(VX_GNU_MAJOR_VERSION))
|
||||
ARCH_DEP_CFLAGS_2 = -mcpu=604 -mstrict-align -mno-implicit-fp
|
||||
ARCH_DEP_CFLAGS_3 = -mcpu=604 -mstrict-align -mno-implicit-fp
|
||||
ARCH_DEP_CFLAGS_4 = -mcpu=604 -mstrict-align -fno-implicit-fp
|
||||
ARCH_DEP_CFLAGS = $(ARCH_DEP_CFLAGS_$(VX_GNU_MAJOR_VERSION))
|
||||
|
||||
GNU_TARGET = powerpc-wrs-vxworks
|
||||
|
||||
@@ -161,9 +161,7 @@ OPT_CXXFLAGS_YES = -O2
|
||||
|
||||
#--------------------------------------------------
|
||||
# code flags
|
||||
CODE_CPPFLAGS_6 = $(CODE_CPPFLAGS_$(VXWORKS_VERSION))
|
||||
CODE_CPPFLAGS_6 += -fno-strict-aliasing
|
||||
CODE_CPPFLAGS += $(CODE_CPPFLAGS_$(VXWORKS_MAJOR_VERSION))
|
||||
CODE_CFLAGS =
|
||||
#
|
||||
# For vxWorks versions before 6.3 we need this g++ compiler flag
|
||||
CODE_CXXFLAGS_5 = -fno-implicit-templates
|
||||
@@ -171,7 +169,7 @@ CODE_CXXFLAGS_6.0 = -fno-implicit-templates
|
||||
CODE_CXXFLAGS_6.1 = -fno-implicit-templates
|
||||
CODE_CXXFLAGS_6.2 = -fno-implicit-templates
|
||||
CODE_CXXFLAGS_6 = $(CODE_CXXFLAGS_$(VXWORKS_VERSION))
|
||||
CODE_CXXFLAGS += $(CODE_CXXFLAGS_$(VXWORKS_MAJOR_VERSION))
|
||||
CODE_CXXFLAGS = $(CODE_CXXFLAGS_$(VXWORKS_MAJOR_VERSION))
|
||||
|
||||
#--------------------------------------------------
|
||||
# no shared libs for vxWorks
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# 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)
|
||||
@@ -1,21 +0,0 @@
|
||||
# "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)
|
||||
@@ -1,3 +0,0 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86_64.Common
|
||||
@@ -1,2 +0,0 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
@@ -1,14 +0,0 @@
|
||||
# "cross compile" for older Linux version
|
||||
# Use older compiler and older libraries
|
||||
# Used packages:
|
||||
# compat-gcc-44-c++-4.4
|
||||
# compat-gcc-44-4.4
|
||||
# compat-glibc-headers-2.12-4
|
||||
# It was neccessary to install 32 bit compatibility libraries manually
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
CC = $(GNU_BIN)/$(CMPLR_PREFIX)gcc44
|
||||
CCC = $(GNU_BIN)/$(CMPLR_PREFIX)g++44
|
||||
TARGET_LDFLAGS = -L /usr/lib/x86_64-redhat-linux6E/lib
|
||||
LINK.cpp += --as-needed -lc -lm -lrt -lpthread -lreadline -ltinfo
|
||||
@@ -1,14 +0,0 @@
|
||||
# "cross compile" for older Linux version
|
||||
# Use older compiler and older libraries
|
||||
# Used packages:
|
||||
# compat-gcc-44-c++-4.4
|
||||
# compat-gcc-44-4.4
|
||||
# compat-glibc-headers-2.12-4
|
||||
# compat-glibc-2.12-4
|
||||
#-------------------------------------------------------
|
||||
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
CC = $(GNU_BIN)/$(CMPLR_PREFIX)gcc44
|
||||
CCC = $(GNU_BIN)/$(CMPLR_PREFIX)g++44
|
||||
TARGET_LDFLAGS = -L /usr/lib/x86_64-redhat-linux6E/lib64
|
||||
LINK.cpp += --as-needed -lc -lm -lrt -lpthread -lreadline -ltinfo
|
||||
@@ -1 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.linux-x86_64.Common
|
||||
@@ -1 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.Cross_64.RHEL7-x86_64
|
||||
@@ -1 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
@@ -1 +0,0 @@
|
||||
GNU_BIN=/opt/RHEL7/bin
|
||||
@@ -1,3 +0,0 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.Common
|
||||
@@ -1,2 +0,0 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
@@ -1,3 +0,0 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86_64.Common
|
||||
@@ -1,2 +0,0 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
@@ -1,3 +0,0 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.Common
|
||||
@@ -1,2 +0,0 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
@@ -1,3 +0,0 @@
|
||||
#CONFIG.$(EPICS_HOST_ARCH).Common is required by build system
|
||||
#Include definitions common to linux hosts
|
||||
include $(CONFIG)/os/CONFIG.linux-x86_64.Common
|
||||
@@ -1,2 +0,0 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
@@ -1,2 +0,0 @@
|
||||
# Include common linux definitions
|
||||
include $(CONFIG)/os/CONFIG.linux-x86.linux-x86
|
||||
@@ -1,4 +0,0 @@
|
||||
COMMANDLINE_LIBRARY = READLINE
|
||||
ifeq ($(filter SL% RHEL%,$(T_A)),)
|
||||
VALID_BUILDS = Ioc
|
||||
endif
|
||||
@@ -32,6 +32,5 @@ VXWORKS_VERSION = 6.9
|
||||
|
||||
#WIND_BASE = /usr/local/vw/tornado202p1
|
||||
#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)
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# Build 32 bit version as a cross architecture
|
||||
#CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86
|
||||
|
||||
# Improved error checking with clang
|
||||
CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86_64-clang
|
||||
|
||||
# Build for old SL6 64 bit
|
||||
CROSS_COMPILER_TARGET_ARCHS += SL6-x86_64
|
||||
|
||||
# Build for old SL6 32 bit
|
||||
#CROSS_COMPILER_TARGET_ARCHS += SL6-x86
|
||||
|
||||
# Zynq
|
||||
CROSS_COMPILER_TARGET_ARCHS += yocto21-aarch64
|
||||
|
||||
# NI Linux Real-Time 7.x
|
||||
# requires RPM gcc-c++-arm-linux-gnu
|
||||
CROSS_COMPILER_TARGET_ARCHS += nilrt7-armv7a
|
||||
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.Common
|
||||
@@ -1,15 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.Common
|
||||
|
||||
# Improved error checking with clang
|
||||
# Does not compile with clang 13!
|
||||
#CROSS_COMPILER_TARGET_ARCHS += RHEL8-x86_64-clang
|
||||
|
||||
# Build for old RHEL7 64 bit
|
||||
CROSS_COMPILER_TARGET_ARCHS += RHEL7-x86_64
|
||||
|
||||
# Zynq
|
||||
CROSS_COMPILER_TARGET_ARCHS += yocto21-aarch64
|
||||
|
||||
# NI Linux Real-Time 7.x
|
||||
# requires RPM gcc-c++-arm-linux-gnu
|
||||
CROSS_COMPILER_TARGET_ARCHS += nilrt7-armv7a
|
||||
@@ -1 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86.Common
|
||||
@@ -1,3 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86.Common
|
||||
# Build 32 bit version as a cross architecture
|
||||
CROSS_COMPILER_TARGET_ARCHS += SL5-x86
|
||||
@@ -1 +0,0 @@
|
||||
include $(CONFIG)/os/CONFIG_SITE.linux-x86.Common
|
||||
@@ -1,7 +0,0 @@
|
||||
# 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
|
||||
@@ -3,46 +3,7 @@
|
||||
# Site override definitions for linux-x86 host builds
|
||||
#-------------------------------------------------------
|
||||
|
||||
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
|
||||
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 += V62-ppc604
|
||||
|
||||
# Raspberry Pi
|
||||
CROSS_COMPILER_TARGET_ARCHS += raspbian-arm
|
||||
# JBA test override values
|
||||
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040 solaris-sparc
|
||||
#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040
|
||||
#CROSS_COMPILER_TARGET_ARCHS = RTEMS-mvme2100 RTEMS-pc386 # RTEMS-mvme5500 RTEMS-mvme167
|
||||
|
||||
@@ -7,9 +7,3 @@
|
||||
#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
|
||||
|
||||
# IOxOS IFC1211
|
||||
CROSS_COMPILER_TARGET_ARCHS += fslqoriq20-e6500_64
|
||||
|
||||
@@ -4,27 +4,16 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>Known Problems in R3.14.12.1</title>
|
||||
<title>Known Problems in R3.14.12.8</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1 style="text-align: center">EPICS Base R3.14.12.1: Known Problems</h1>
|
||||
<h1 style="text-align: center">EPICS Base R3.14.12.8: Known Problems</h1>
|
||||
|
||||
<p>Any patch files linked below should be applied at the root of the
|
||||
base-3.14.12.1 tree. Download them, then use the GNU Patch program as
|
||||
follows:</p>
|
||||
|
||||
<blockquote><pre>% <b>cd <i>/path/to/</i>base-3.14.12.1</b>
|
||||
% <b>patch -p0 < <i>/path/to/</i>file.patch</b></pre></blockquote>
|
||||
|
||||
<p>The following significant problems have been reported with this
|
||||
version of EPICS Base:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>None yet.</li>
|
||||
|
||||
</ul>
|
||||
<p>This was the last release in the Base-3.14 series, so we are no longer
|
||||
tracking bugs in this branch. Please upgrade to one of the newer releases which
|
||||
have incorporated many bug fixes and new features since they branched off the
|
||||
Base-3.14 release series.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,16 +3,65 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
|
||||
<title>EPICS Base R3.14.12.7 Release Notes</title>
|
||||
<title>EPICS Base R3.14.12.8 Release Notes</title>
|
||||
</head>
|
||||
|
||||
<body lang="en">
|
||||
<h1 align="center">EPICS Base Release 3.14.12.7</h1>
|
||||
<h1 align="center">EPICS Base Release 3.14.12.8</h1>
|
||||
|
||||
<h2 align="center">Changes between 3.14.12.6 and 3.14.12.7</h2>
|
||||
<p>This is the final release in the Base-3.14 series, please upgrade to the
|
||||
Base-3.15 series or to EPICS 7.</p>
|
||||
|
||||
<h2 align="center">Changes between 3.14.12.7 and 3.14.12.8</h2>
|
||||
|
||||
<!-- Insert new items immediately below here ... -->
|
||||
|
||||
<h3>Fixes for Launchpad bugs</h3>
|
||||
|
||||
<p>The following launchpad bugs have fixes included:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://bugs.launchpad.net/epics-base/+bug/541221">
|
||||
lp: #541221</a>, 'assert (pca->pgetNative)' failed in ../dbCa.c</li>
|
||||
<li><a href="https://bugs.launchpad.net/epics-base/+bug/1747091">
|
||||
lp: #1747091</a>, epicsTimeGetEvent() / generalTime bug</li>
|
||||
<li><a href="https://bugs.launchpad.net/epics-base/+bug/1743076">
|
||||
lp: #1743076</a>, Segfault in ca_attach_context() during exits</li>
|
||||
<li><a href="https://bugs.launchpad.net/epics-base/+bug/1751380">
|
||||
lp: #1751380</a>, Deadlock in ca_clear_subscription()</li>
|
||||
<li><a href="https://bugs.launchpad.net/epics-base/+bug/1597809">
|
||||
lp: #1597809</a>, Setting NAME field in DB file may break IOC</li>
|
||||
<li><a href="https://bugs.launchpad.net/epics-base/+bug/1770292">
|
||||
lp: #1770292</a>, get_alarm_double() inconsistent across record types</li>
|
||||
<li><a href="https://bugs.launchpad.net/epics-base/+bug/1771298">
|
||||
lp: #1771298</a>, Conversion of NaN to integer relies on undefined
|
||||
behavior</li>
|
||||
</ul>
|
||||
|
||||
<h3>Updated VxWorks Timezone settings</h3>
|
||||
|
||||
<p>Removed the settings for 2017; fixed the hour of the change for MET.</p>
|
||||
|
||||
<h3>Back-port podToHtml.pl and Rules from Base-3.15</h3>
|
||||
|
||||
<p>This script permits Base to be built with Perl installations that do not
|
||||
provide the podchecker and pod2html scripts (e.g. Fedora 27).</p>
|
||||
|
||||
<h3>Fixed camonitor server side relative timestamps bug</h3>
|
||||
|
||||
<p>Initialize the first time-stamp from the first monitor, not the client-side
|
||||
current time in this configuration.</p>
|
||||
|
||||
<h3>Build changes for MSVC</h3>
|
||||
|
||||
<p>Windows builds using Visual Studio 2015 and later now use the <tt>-FS</tt>
|
||||
compiler option to allow parallel builds to work properly.</p>
|
||||
|
||||
<p>We now give the <tt>-FC</tt> option to tell the compiler to print absolute
|
||||
paths for source files in diagnostic messages.</p>
|
||||
|
||||
<h2 align="center">Changes between 3.14.12.6 and 3.14.12.7</h2>
|
||||
|
||||
<h3>Extend maximum Posix epicsEventWaitWithTimeout() delay</h3>
|
||||
|
||||
<p>The Posix implementation of epicsEventWaitWithTimeout() was limiting the
|
||||
@@ -1415,10 +1464,6 @@ giving correct initial monitor behavior in some circumstances.</p>
|
||||
|
||||
<p>Fixed a crash when ALG (algorithm) was changed to Average at runtime.</p>
|
||||
|
||||
<h4>Named Soft Events</h4>
|
||||
|
||||
<p>Soft events can now be meaningful strings instead of numbers 1-255.
|
||||
|
||||
<h4>configure/RELEASE Enhancements</h4>
|
||||
|
||||
<p>Variable definitions in a <tt>configure/RELEASE</tt> file may now use the
|
||||
|
||||
@@ -1009,7 +1009,7 @@ d:/user/R3.14.clean/epics/base/lib/WIN32-x86/</code></p>
|
||||
<h2><a name="CommandUtils">Command Line Utilities</a></h2>
|
||||
|
||||
<h3><a name="acctst">acctst</a></h3>
|
||||
<pre>acctst <PV name> [progress logging level] [channel duplication count]
|
||||
<pre>acctst <PV name> [progress logging level] [channel duplication count]
|
||||
[test repetition count] [enable preemptive callback]</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
@@ -2079,7 +2079,7 @@ example, be beneficial when tuning an archiver installation.</p>
|
||||
<p>Significant performance gains can be realized when the CA client library
|
||||
doesn't wait for a response to return from the server after each request. All
|
||||
requests which require interaction with a CA server are accumulated (buffered)
|
||||
and not forwarded to the IOC until one of <code>ca_flush_io()</code>,
|
||||
and not forwarded to the IOC until one of <code>ca_flush_io()</code>,
|
||||
<code>ca_pend_io()</code>, <code>ca_pend_event()</code>, or
|
||||
<code>ca_sg_block()</code> are called allowing several operations to be
|
||||
efficiently sent over the network together. Any process variable values written
|
||||
@@ -2103,16 +2103,16 @@ shouldn't test the success of a CA function call by checking to see if the
|
||||
returned value is zero as is the UNIX convention. Below are several methods to
|
||||
test CA function returns. See <a href="#ca_signal"><code>ca_signal()</code> and
|
||||
<code>SEVCHK()</code></a> for more information on this topic.</p>
|
||||
<pre>status = ca_XXXX();
|
||||
SEVCHK( status, "ca_XXXX() returned failure status");
|
||||
<pre>status = ca_XXXX();
|
||||
SEVCHK( status, "ca_XXXX() returned failure status");
|
||||
|
||||
if ( status & CA_M_SUCCESS ) {
|
||||
printf ( "The requested ca_XXXX() operation didn't complete successfully");
|
||||
}
|
||||
if ( status & CA_M_SUCCESS ) {
|
||||
printf ( "The requested ca_XXXX() operation didn't complete successfully");
|
||||
}
|
||||
|
||||
if ( status != ECA_NORMAL ) {
|
||||
if ( status != ECA_NORMAL ) {
|
||||
printf("The requested ca_XXXX() operation didn't complete successfully because \"%s\"\n",
|
||||
ca_message ( status ) );
|
||||
ca_message ( status ) );
|
||||
}</pre>
|
||||
|
||||
<h3><a name="Channel">Channel Access Data Types</a></h3>
|
||||
@@ -2285,7 +2285,7 @@ int main ( int argc, char ** argv )
|
||||
unsigned nBytes;
|
||||
unsigned elementCount;
|
||||
char timeString[32];
|
||||
unsigned i;
|
||||
unsigned i;
|
||||
chid chan;
|
||||
double sum;
|
||||
int status;
|
||||
@@ -2328,7 +2328,7 @@ int main ( int argc, char ** argv )
|
||||
epicsTimeToStrftime ( timeString, sizeof ( timeString ),
|
||||
"%a %b %d %Y %H:%M:%S.%f", & pTD->stamp );
|
||||
|
||||
printf ( "The sum of elements in %s at %s was %f\n",
|
||||
printf ( "The sum of elements in %s at %s was %f\n",
|
||||
argv[1], timeString, sum );
|
||||
|
||||
ca_clear_channel ( chan );
|
||||
@@ -2359,7 +2359,7 @@ executing within the user's callback function.</p>
|
||||
<pre>typedef struct event_handler_args {
|
||||
void *usr; /* user argument supplied with request */
|
||||
chanId chid; /* channel id */
|
||||
long type; /* the type of the item returned */
|
||||
long type; /* the type of the item returned */
|
||||
long count; /* the element count of the item returned */
|
||||
const void *dbr; /* a pointer to the item returned */
|
||||
int status; /* ECA_XXX status of the requested op from the server */
|
||||
@@ -2382,7 +2382,7 @@ attached to the request, an exception handler is executed in the client. The
|
||||
default exception handler prints a message on the console and exits if the
|
||||
exception condition is severe. Certain internal exceptions within the CA client
|
||||
library, and failures detected by the SEVCHK macro may also cause the exception
|
||||
handler to be invoked. To modify this behavior see
|
||||
handler to be invoked. To modify this behavior see
|
||||
<code><a href="#ca_add_exception_event">ca_add_exception_event</a>()</code>.</p>
|
||||
|
||||
<h3><a name="Server">Server and Client Share the Same Address Space on The Same
|
||||
@@ -2674,6 +2674,14 @@ automatically released by the system when the process exits and
|
||||
vxWorks or RTEMS no cleanup occurs unless the application calls
|
||||
<code>ca_context_destroy()</code>.</p>
|
||||
|
||||
<p>Note: This operation blocks until any user callbacks for any channel
|
||||
created in the current context have run to completion. If callbacks take a
|
||||
lock (mutex) then it is the user's responsibility to ensure that this lock
|
||||
is not held when <code>ca_clear_context()</code> is called, otherwise a
|
||||
deadlock may ensue. (See also
|
||||
<code><a href="#ca_clear_channel">ca_clear_channel</a>()</code> and
|
||||
<code><a href="#ca_clear_event">ca_clear_subscription</a>()</code>.)</p>
|
||||
|
||||
<h4>Returns</h4>
|
||||
|
||||
<p>ECA_NORMAL - Normal successful completion</p>
|
||||
@@ -2819,6 +2827,12 @@ efficiently sent over the network in one message.</p>
|
||||
clearing a channel does shutdown and reclaim any channel state change event
|
||||
subscriptions (monitors) registered with the channel.</p>
|
||||
|
||||
<p>Note: This operation blocks until any user callbacks for this channel
|
||||
have run to completion. If callbacks take a lock (mutex) then it is the
|
||||
user's responsibility to ensure that this lock is not held when
|
||||
<code>ca_clear_channel()</code> is called, otherwise a deadlock may ensue.
|
||||
(See also <code><a href="#ca_clear_event">ca_clear_subscription</a>()</code>.)</p>
|
||||
|
||||
<h4>Arguments</h4>
|
||||
<dl>
|
||||
<dt><code>CHID</code></dt>
|
||||
@@ -2833,16 +2847,16 @@ subscriptions (monitors) registered with the channel.</p>
|
||||
|
||||
<h3><code><a name="ca_put">ca_put()</a></code></h3>
|
||||
<pre>#include <cadef.h>
|
||||
int ca_put ( chtype TYPE,
|
||||
chid CHID, void *PVALUE );
|
||||
int ca_array_put ( chtype TYPE, unsigned long COUNT,
|
||||
int ca_put ( chtype TYPE,
|
||||
chid CHID, void *PVALUE );
|
||||
int ca_array_put ( chtype TYPE, unsigned long COUNT,
|
||||
chid CHID, const void *PVALUE);
|
||||
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
|
||||
int ca_put_callback ( chtype TYPE,
|
||||
chid CHID, const void *PVALUE,
|
||||
caEventCallBackFunc PFUNC, void *USERARG );
|
||||
int ca_array_put_callback ( chtype TYPE, unsigned long COUNT,
|
||||
chid CHID, const void *PVALUE,
|
||||
int ca_put_callback ( chtype TYPE,
|
||||
chid CHID, const void *PVALUE,
|
||||
caEventCallBackFunc PFUNC, void *USERARG );
|
||||
int ca_array_put_callback ( chtype TYPE, unsigned long COUNT,
|
||||
chid CHID, const void *PVALUE,
|
||||
caEventCallBackFunc PFUNC, void *USERARG );</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
@@ -3069,7 +3083,7 @@ when a CA get request is initiated.</p>
|
||||
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
|
||||
int ca_create_subscription ( chtype TYPE, unsigned long COUNT,
|
||||
chid CHID, unsigned long MASK,
|
||||
caEventCallBackFunc USERFUNC, void *USERARG,
|
||||
caEventCallBackFunc USERFUNC, void *USERARG,
|
||||
evid *PEVID );</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
@@ -3153,7 +3167,7 @@ indicating the current state of the channel.</p>
|
||||
<dt><code>MASK</code></dt>
|
||||
<dd>A mask with bits set for each of the event trigger types requested. The
|
||||
event trigger mask must be a <em>bitwise or</em> of one or more of the
|
||||
following constants.
|
||||
following constants.
|
||||
<ul>
|
||||
<li>DBE_VALUE - Trigger events when the channel value exceeds the
|
||||
monitor dead band</li>
|
||||
@@ -3200,6 +3214,13 @@ and not forwarded to the server until one of <code>ca_flush_io()</code>, <code>c
|
||||
<code>ca_pend_event()</code>, or <code>ca_sg_block()</code> are called. This allows several requests to be
|
||||
efficiently sent together in one message.</p>
|
||||
|
||||
<p>Note: This operation blocks until any user callbacks for this channel
|
||||
have run to completion. If callbacks take a lock (mutex) then it is the
|
||||
user's responsibility to ensure that this lock is not held when
|
||||
<code>ca_clear_subscription()</code> is called, otherwise a deadlock may
|
||||
ensue. (See also <code><a
|
||||
href="#ca_clear_channel">ca_clear_channel</a>()</code>.)</p>
|
||||
|
||||
<h4>Arguments</h4>
|
||||
<dl>
|
||||
<dt>EVID</dt>
|
||||
@@ -3364,7 +3385,7 @@ becomes full.</p>
|
||||
|
||||
<h3><code><a name="ca_signal">ca_signal()</a></code></h3>
|
||||
<pre>#include <cadef.h>
|
||||
int ca_signal ( long CA_STATUS, const char * CONTEXT_STRING );
|
||||
int ca_signal ( long CA_STATUS, const char * CONTEXT_STRING );
|
||||
void SEVCHK( CA_STATUS, CONTEXT_STRING );</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
@@ -3381,7 +3402,7 @@ recommended error handler for simple applications which do not wish to write
|
||||
code testing the status returned from each channel access call.</p>
|
||||
|
||||
<h4>Examples</h4>
|
||||
<pre>status = ca_context_create (...);
|
||||
<pre>status = ca_context_create (...);
|
||||
SEVCHK ( status, "Unable to create a CA client context" );</pre>
|
||||
|
||||
<p>If the application only wishes to print the message associated with an error
|
||||
@@ -3405,7 +3426,7 @@ this purpose.</p>
|
||||
|
||||
<h3><code><a
|
||||
name="ca_add_exception_event">ca_add_exception_event()</a></code></h3>
|
||||
<pre>#include <cadef.h>
|
||||
<pre>#include <cadef.h>
|
||||
typedef void (*pCallback) ( struct exception_handler_args HANDLERARGS );
|
||||
int ca_add_exception_event ( pCallback USERFUNC, void *USERARG );</pre>
|
||||
|
||||
@@ -3614,7 +3635,7 @@ specified channel.</p>
|
||||
<dt><code>PFUNC</code></dt>
|
||||
<dd>Pointer to a user supplied callback function. A null pointer uninstalls
|
||||
the current handler. The following arguments are passed <em>by value</em>
|
||||
to the supplied callback handler.
|
||||
to the supplied callback handler.
|
||||
<pre>typedef struct ca_access_rights {
|
||||
unsigned read_access:1;
|
||||
unsigned write_access:1;
|
||||
@@ -3954,8 +3975,8 @@ type.</p>
|
||||
prints diagnostics to standard out.</p>
|
||||
|
||||
<h4>Examples</h4>
|
||||
<pre>void ca_test_event ();
|
||||
status = ca_create_subscription ( type, chid, ca_test_event, NULL, NULL );
|
||||
<pre>void ca_test_event ();
|
||||
status = ca_create_subscription ( type, chid, ca_test_event, NULL, NULL );
|
||||
SEVCHK ( status, .... );</pre>
|
||||
|
||||
<h4>See Also</h4>
|
||||
@@ -3989,8 +4010,8 @@ outstanding within them at any given time.</p>
|
||||
</dl>
|
||||
|
||||
<h4>Examples</h4>
|
||||
<pre>CA_SYNC_GID gid;
|
||||
status = ca_sg_create ( &gid );
|
||||
<pre>CA_SYNC_GID gid;
|
||||
status = ca_sg_create ( &gid );
|
||||
SEVCHK ( status, Sync group create failed );</pre>
|
||||
|
||||
<h4>Returns</h4>
|
||||
@@ -4028,8 +4049,8 @@ int ca_sg_delete ( CA_SYNC_GID GID );</pre>
|
||||
</dl>
|
||||
|
||||
<h4>Examples</h4>
|
||||
<pre>CA_SYNC_GID gid;
|
||||
status = ca_sg_delete ( gid );
|
||||
<pre>CA_SYNC_GID gid;
|
||||
status = ca_sg_delete ( gid );
|
||||
SEVCHK ( status, Sync group delete failed );</pre>
|
||||
|
||||
<h4>Returns</h4>
|
||||
@@ -4140,7 +4161,7 @@ will not block unless additional subsequent requests are made.</p>
|
||||
</dl>
|
||||
|
||||
<h4>Examples</h4>
|
||||
<pre>CA_SYNC_GID gid;
|
||||
<pre>CA_SYNC_GID gid;
|
||||
status = ca_sg_reset(gid);</pre>
|
||||
|
||||
<h4>Returns</h4>
|
||||
@@ -4153,7 +4174,7 @@ status = ca_sg_reset(gid);</pre>
|
||||
<pre>#include <cadef.h>
|
||||
int ca_sg_put ( CA_SYNC_GID GID, chtype TYPE,
|
||||
chid CHID, void *PVALUE );
|
||||
int ca_sg_array_put ( CA_SYNC_GID GID, chtype TYPE,
|
||||
int ca_sg_array_put ( CA_SYNC_GID GID, chtype TYPE,
|
||||
unsigned long COUNT, chid CHID, void *PVALUE );</pre>
|
||||
|
||||
<p>Write a value, or array of values, to a channel and increment the outstanding
|
||||
@@ -4294,7 +4315,7 @@ reissued.</p>
|
||||
|
||||
<h3><code><a name="ca_client_status">ca_client_status()</a></code></h3>
|
||||
<pre>int ca_client_status ( unsigned level );
|
||||
int ca_context_status ( struct ca_client_context *CONTEXT,
|
||||
int ca_context_status ( struct ca_client_context *CONTEXT,
|
||||
unsigned LEVEL );</pre>
|
||||
|
||||
<h4>Description</h4>
|
||||
|
||||
@@ -765,12 +765,6 @@ void epicsShareAPI ca_detach_context ()
|
||||
}
|
||||
}
|
||||
|
||||
// backward compatibility with 3.14.8
|
||||
extern "C" void _Z17ca_detach_contextv ()
|
||||
{
|
||||
ca_detach_context();
|
||||
}
|
||||
|
||||
int epicsShareAPI ca_preemtive_callback_is_enabled ()
|
||||
{
|
||||
ca_client_context *pcac = (ca_client_context *) epicsThreadPrivateGet ( caClientContextId );
|
||||
|
||||
@@ -26,8 +26,6 @@ SRC_DIRS += $(CA)
|
||||
INC += casdef.h
|
||||
INC += casEventMask.h
|
||||
INC += caNetAddr.h
|
||||
INC += casCtx.h
|
||||
INC += caHdrLargeArray.h
|
||||
|
||||
LIBSRCS += caServer.cc
|
||||
LIBSRCS += caServerI.cc
|
||||
|
||||
@@ -646,6 +646,11 @@ caStatus casDGClient::processDG ()
|
||||
if ( status != S_cas_success ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( this->in.bytesPresent () > 0 && dgInBytesConsumed == 0 && status == S_cas_success ) {
|
||||
this->in.removeMsg ( this->in.bytesPresent() );
|
||||
}
|
||||
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ static unsigned long reqElems = 0;
|
||||
static unsigned long eventMask = DBE_VALUE | DBE_ALARM; /* Event mask used */
|
||||
static int floatAsString = 0; /* Flag: fetch floats as string */
|
||||
static int nConn = 0; /* Number of connected PVs */
|
||||
static int caDebug = 0;
|
||||
|
||||
|
||||
void usage (void)
|
||||
@@ -84,9 +83,6 @@ void usage (void)
|
||||
" -0b: Print as binary number\n"
|
||||
"Alternate output field separator:\n"
|
||||
" -F <ofs>: Use <ofs> to separate fields in output\n"
|
||||
"Debuging:\n"
|
||||
" Default: Do not print debug messages\n"
|
||||
" -d: Print debug messages to stderr\n"
|
||||
"\n"
|
||||
"Example: camonitor -f8 my_channel another_channel\n"
|
||||
" (doubles are printed as %%f with precision of 8)\n\n"
|
||||
@@ -110,11 +106,6 @@ static void event_handler (evargs args)
|
||||
{
|
||||
pv* pv = args.usr;
|
||||
|
||||
if (caDebug)
|
||||
{
|
||||
fprintf(stderr, "event_handler(%s) %s[%ld]\n %s\n",
|
||||
ca_name(args.chid), dbr_type_to_text(args.type), args.count, ca_message(args.status));
|
||||
}
|
||||
pv->status = args.status;
|
||||
if (args.status == ECA_NORMAL)
|
||||
{
|
||||
@@ -143,30 +134,9 @@ static void event_handler (evargs args)
|
||||
static void connection_handler ( struct connection_handler_args args )
|
||||
{
|
||||
pv *ppv = ( pv * ) ca_puser ( args.chid );
|
||||
if (caDebug)
|
||||
{
|
||||
fprintf(stderr, "connection_handler(%s) %s\n",
|
||||
ca_name(args.chid),
|
||||
args.op == CA_OP_CONN_UP ? "UP" :
|
||||
args.op == CA_OP_CONN_DOWN ? "DOWN" :
|
||||
"unknown op");
|
||||
}
|
||||
if ( args.op == CA_OP_CONN_UP ) {
|
||||
nConn++;
|
||||
|
||||
if (ppv->onceConnected && ppv->dbfType != ca_field_type(ppv->chid)) {
|
||||
/* Data type has changed. Rebuild connection with new type. */
|
||||
if (caDebug)
|
||||
{
|
||||
fprintf(stderr, " Data type changed %s -> %s\n",
|
||||
dbr_type_to_text(ppv->dbfType),
|
||||
dbr_type_to_text(ca_field_type(ppv->chid)));
|
||||
}
|
||||
ca_clear_subscription(ppv->evid);
|
||||
ppv->evid = NULL;
|
||||
}
|
||||
|
||||
if (!ppv->evid) {
|
||||
if (!ppv->onceConnected) {
|
||||
ppv->onceConnected = 1;
|
||||
/* Set up pv structure */
|
||||
/* ------------------- */
|
||||
@@ -197,7 +167,7 @@ static void connection_handler ( struct connection_handler_args args )
|
||||
eventMask,
|
||||
event_handler,
|
||||
(void*)ppv,
|
||||
&ppv->evid);
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
else if ( args.op == CA_OP_CONN_DOWN ) {
|
||||
@@ -239,14 +209,11 @@ int main (int argc, char *argv[])
|
||||
|
||||
LINE_BUFFER(stdout); /* Configure stdout buffering */
|
||||
|
||||
while ((opt = getopt(argc, argv, ":ndhm:sSe:f:g:l:#:0:w:t:p:F:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, ":nhm:sSe:f:g:l:#:0:w:t:p:F:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h': /* Print usage */
|
||||
usage();
|
||||
return 0;
|
||||
case 'd':
|
||||
caDebug=1;
|
||||
break;
|
||||
case 'n': /* Print ENUM as index numbers */
|
||||
enumAsNr=1;
|
||||
break;
|
||||
|
||||
@@ -78,7 +78,6 @@ typedef struct
|
||||
epicsTimeStamp tsPreviousS;
|
||||
char firstStampPrinted;
|
||||
char onceConnected;
|
||||
evid evid;
|
||||
} pv;
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ INC += dbIocRegister.h
|
||||
# The following go away what old database access goes away
|
||||
INC += db_access_routines.h
|
||||
INC += db_convert.h
|
||||
INC += dbCaPvt.h
|
||||
|
||||
DBDINC += menuAlarmSevr
|
||||
DBDINC += menuAlarmStat
|
||||
|
||||
@@ -110,7 +110,9 @@ static void callbackShutdown(void *arg)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) {
|
||||
int lockKey = epicsInterruptLock();
|
||||
int ok = epicsRingPointerPush(callbackQ[i], &exitCallback);
|
||||
epicsInterruptUnlock(lockKey);
|
||||
epicsEventSignal(callbackSem[i]);
|
||||
if (ok) epicsEventWait(startStopEvent);
|
||||
}
|
||||
@@ -126,7 +128,7 @@ static void callbackInitOnce(void *arg)
|
||||
epicsThreadId tid;
|
||||
|
||||
callbackSem[i] = epicsEventMustCreate(epicsEventEmpty);
|
||||
callbackQ[i] = epicsRingPointerLockedCreate(callbackQueueSize);
|
||||
callbackQ[i] = epicsRingPointerCreate(callbackQueueSize);
|
||||
if (callbackQ[i] == 0)
|
||||
cantProceed("epicsRingPointerCreate failed for %s\n",
|
||||
threadName[i]);
|
||||
@@ -152,6 +154,7 @@ void callbackRequest(CALLBACK *pcallback)
|
||||
{
|
||||
int priority;
|
||||
int pushOK;
|
||||
int lockKey;
|
||||
|
||||
if (!pcallback) {
|
||||
epicsInterruptContextMessage("callbackRequest: pcallback was NULL\n");
|
||||
@@ -164,7 +167,9 @@ void callbackRequest(CALLBACK *pcallback)
|
||||
}
|
||||
if (ringOverflow[priority]) return;
|
||||
|
||||
lockKey = epicsInterruptLock();
|
||||
pushOK = epicsRingPointerPush(callbackQ[priority], pcallback);
|
||||
epicsInterruptUnlock(lockKey);
|
||||
|
||||
if (!pushOK) {
|
||||
epicsInterruptContextMessage(fullMessage[priority]);
|
||||
|
||||
@@ -297,10 +297,10 @@ static void get_alarm(DBADDR *paddr, char **ppbuffer,
|
||||
if (*options & DBR_AL_LONG) {
|
||||
struct dbr_alLong *pal = (struct dbr_alLong*) pbuffer;
|
||||
|
||||
pal->upper_alarm_limit = (epicsInt32) ald.upper_alarm_limit;
|
||||
pal->upper_warning_limit = (epicsInt32) ald.upper_warning_limit;
|
||||
pal->lower_warning_limit = (epicsInt32) ald.lower_warning_limit;
|
||||
pal->lower_alarm_limit = (epicsInt32) ald.lower_alarm_limit;
|
||||
pal->upper_alarm_limit = finite(ald.upper_alarm_limit) ? (epicsInt32) ald.upper_alarm_limit : 0;
|
||||
pal->upper_warning_limit = finite(ald.upper_warning_limit) ? (epicsInt32) ald.upper_warning_limit : 0;
|
||||
pal->lower_warning_limit = finite(ald.lower_warning_limit) ? (epicsInt32) ald.lower_warning_limit : 0;
|
||||
pal->lower_alarm_limit = finite(ald.lower_alarm_limit) ? (epicsInt32) ald.lower_alarm_limit : 0;
|
||||
|
||||
if (no_data)
|
||||
*options ^= DBR_AL_LONG; /*Turn off option*/
|
||||
@@ -675,8 +675,6 @@ long epicsShareAPI dbNameToAddr(const char *pname, DBADDR *paddr)
|
||||
status = dbFindFieldPart(&dbEntry, &pname);
|
||||
if (status == S_dbLib_fieldNotFound)
|
||||
status = dbGetAttributePart(&dbEntry, &pname);
|
||||
if (status == S_dbLib_fieldNotFound)
|
||||
status = dbFindInfoPart(&dbEntry, &pname);
|
||||
if (status) goto finish;
|
||||
|
||||
paddr->precord = dbEntry.precnode->precord;
|
||||
|
||||
@@ -591,11 +591,16 @@ static void connectionCallback(struct connection_handler_args arg)
|
||||
if (pca->gotFirstConnection) {
|
||||
if (pca->nelements != ca_element_count(arg.chid) ||
|
||||
pca->dbrType != ca_field_type(arg.chid)) {
|
||||
/* BUG: We have no way to clear any old subscription with the
|
||||
* originally chosen data type/size. That will continue
|
||||
* to send us data and will result in an assert() fail.
|
||||
*/
|
||||
/* Let next dbCaGetLink and/or dbCaPutLink determine options */
|
||||
/* Size or type changed, clear everything and let the next call
|
||||
to dbCaGetLink() and/or dbCaPutLink() reset everything */
|
||||
if (pca->evidNative) {
|
||||
ca_clear_event(pca->evidNative);
|
||||
pca->evidNative = 0;
|
||||
}
|
||||
if (pca->evidString) {
|
||||
ca_clear_event(pca->evidString);
|
||||
pca->evidString = 0;
|
||||
}
|
||||
plink->value.pv_link.pvlMask &=
|
||||
~(pvlOptInpNative | pvlOptInpString |
|
||||
pvlOptOutNative | pvlOptOutString);
|
||||
@@ -969,7 +974,8 @@ static void dbCaTask(void *arg)
|
||||
status = ca_add_array_event(
|
||||
ca_field_type(pca->chid)+DBR_TIME_STRING,
|
||||
ca_element_count(pca->chid),
|
||||
pca->chid, eventCallback, pca, 0.0, 0.0, 0.0, 0);
|
||||
pca->chid, eventCallback, pca, 0.0, 0.0, 0.0,
|
||||
&pca->evidNative);
|
||||
if (status != ECA_NORMAL) {
|
||||
errlogPrintf("dbCaTask ca_add_array_event %s\n",
|
||||
ca_message(status));
|
||||
@@ -981,7 +987,8 @@ static void dbCaTask(void *arg)
|
||||
pca->pgetString = dbCalloc(1, MAX_STRING_SIZE);
|
||||
epicsMutexUnlock(pca->lock);
|
||||
status = ca_add_array_event(DBR_TIME_STRING, 1,
|
||||
pca->chid, eventCallback, pca, 0.0, 0.0, 0.0, 0);
|
||||
pca->chid, eventCallback, pca, 0.0, 0.0, 0.0,
|
||||
&pca->evidString);
|
||||
if (status != ECA_NORMAL) {
|
||||
errlogPrintf("dbCaTask ca_add_array_event %s\n",
|
||||
ca_message(status));
|
||||
|
||||
@@ -73,6 +73,8 @@ typedef struct caLink
|
||||
char *pgetString;
|
||||
void *pputNative;
|
||||
char *pputString;
|
||||
evid evidNative;
|
||||
evid evidString;
|
||||
char gotInNative;
|
||||
char gotInString;
|
||||
char gotOutNative;
|
||||
|
||||
@@ -43,11 +43,10 @@
|
||||
special(SPC_SCAN)
|
||||
interest(1)
|
||||
}
|
||||
field(EVNT,DBF_STRING) {
|
||||
prompt("Event Name")
|
||||
field(EVNT,DBF_SHORT) {
|
||||
prompt("Event Number")
|
||||
promptgroup(GUI_SCAN)
|
||||
special(SPC_SCAN)
|
||||
size(40)
|
||||
interest(1)
|
||||
}
|
||||
field(TSE,DBF_SHORT) {
|
||||
|
||||
@@ -135,7 +135,9 @@ static char *EVENT_PEND_NAME = "eventTask";
|
||||
|
||||
static struct evSubscrip canceledEvent;
|
||||
|
||||
static unsigned short ringSpace ( const struct event_que *pevq )
|
||||
static epicsMutexId stopSync;
|
||||
|
||||
static unsigned short ringSpace ( const struct event_que *pevq )
|
||||
{
|
||||
if ( pevq->evque[pevq->putix] == EVENTQEMPTY ) {
|
||||
if ( pevq->getix > pevq->putix ) {
|
||||
@@ -275,7 +277,11 @@ int epicsShareAPI dbel ( const char *pname, unsigned level )
|
||||
dbEventCtx epicsShareAPI db_init_events (void)
|
||||
{
|
||||
struct event_user * evUser;
|
||||
|
||||
|
||||
if (!stopSync) {
|
||||
stopSync = epicsMutexMustCreate();
|
||||
}
|
||||
|
||||
if (!dbevEventUserFreeList) {
|
||||
freeListInitPvt(&dbevEventUserFreeList,
|
||||
sizeof(struct event_user),8);
|
||||
@@ -335,6 +341,8 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* intentionally leak stopSync to avoid possible shutdown races */
|
||||
/*
|
||||
* DB_CLOSE_EVENTS()
|
||||
*
|
||||
@@ -370,11 +378,15 @@ void epicsShareAPI db_close_events (dbEventCtx ctx)
|
||||
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
|
||||
epicsMutexMustLock (stopSync);
|
||||
|
||||
epicsEventDestroy(evUser->pexitsem);
|
||||
epicsEventDestroy(evUser->ppendsem);
|
||||
epicsEventDestroy(evUser->pflush_sem);
|
||||
epicsMutexDestroy(evUser->lock);
|
||||
|
||||
epicsMutexUnlock (stopSync);
|
||||
|
||||
freeListFree(dbevEventUserFreeList, evUser);
|
||||
}
|
||||
|
||||
@@ -990,7 +1002,6 @@ static void event_task (void *pParm)
|
||||
} while( ! pendexit );
|
||||
|
||||
epicsMutexDestroy(evUser->firstque.writelock);
|
||||
evUser->firstque.writelock = (epicsMutexId)0xdeadbeef;
|
||||
|
||||
{
|
||||
struct event_que *nextque;
|
||||
@@ -999,7 +1010,6 @@ static void event_task (void *pParm)
|
||||
while(ev_que){
|
||||
nextque = ev_que->nextque;
|
||||
epicsMutexDestroy(ev_que->writelock);
|
||||
ev_que->writelock = (epicsMutexId)0xdeadbeef;
|
||||
freeListFree(dbevEventQueueFreeList, ev_que);
|
||||
ev_que = nextque;
|
||||
}
|
||||
@@ -1007,8 +1017,15 @@ static void event_task (void *pParm)
|
||||
|
||||
taskwdRemove(epicsThreadGetIdSelf());
|
||||
|
||||
/* use stopSync to ensure pexitsem is not destroy'd
|
||||
* until epicsEventSignal() has returned.
|
||||
*/
|
||||
epicsMutexMustLock (stopSync);
|
||||
|
||||
epicsEventSignal(evUser->pexitsem);
|
||||
|
||||
epicsMutexUnlock(stopSync);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -277,26 +277,16 @@ static void scanpplCallFunc(const iocshArgBuf *args)
|
||||
{ scanppl(args[0].dval);}
|
||||
|
||||
/* scanpel */
|
||||
static const iocshArg scanpelArg0 = { "event name",iocshArgString};
|
||||
static const iocshArg scanpelArg0 = { "event number",iocshArgInt};
|
||||
static const iocshArg * const scanpelArgs[1] = {&scanpelArg0};
|
||||
static const iocshFuncDef scanpelFuncDef = {"scanpel",1,scanpelArgs};
|
||||
static void scanpelCallFunc(const iocshArgBuf *args)
|
||||
{ scanpel(args[0].sval);}
|
||||
{ scanpel(args[0].ival);}
|
||||
|
||||
/* scanpiol */
|
||||
static const iocshFuncDef scanpiolFuncDef = {"scanpiol",0};
|
||||
static void scanpiolCallFunc(const iocshArgBuf *args) { scanpiol();}
|
||||
|
||||
/* postEvent */
|
||||
static const iocshArg postEventArg0 = { "event name",iocshArgString};
|
||||
static const iocshArg * const postEventArgs[1] = {&postEventArg0};
|
||||
static const iocshFuncDef postEventFuncDef = {"postEvent",1,postEventArgs};
|
||||
static void postEventCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
EVENTPVT pel = eventNameToHandle(args[0].sval);
|
||||
postEvent(pel);
|
||||
}
|
||||
|
||||
/* callbackSetQueueSize */
|
||||
static const iocshArg callbackSetQueueSizeArg0 = { "bufsize",iocshArgInt};
|
||||
static const iocshArg * const callbackSetQueueSizeArgs[1] =
|
||||
@@ -350,7 +340,6 @@ void epicsShareAPI dbIocRegister(void)
|
||||
iocshRegister(&scanOnceSetQueueSizeFuncDef,scanOnceSetQueueSizeCallFunc);
|
||||
iocshRegister(&scanpplFuncDef,scanpplCallFunc);
|
||||
iocshRegister(&scanpelFuncDef,scanpelCallFunc);
|
||||
iocshRegister(&postEventFuncDef,postEventCallFunc);
|
||||
iocshRegister(&scanpiolFuncDef,scanpiolCallFunc);
|
||||
|
||||
iocshRegister(&callbackSetQueueSizeFuncDef,callbackSetQueueSizeCallFunc);
|
||||
|
||||
200
src/db/dbScan.c
200
src/db/dbScan.c
@@ -19,14 +19,12 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "epicsStdioRedirect.h"
|
||||
#include "epicsString.h"
|
||||
#include "dbDefs.h"
|
||||
#include "ellLib.h"
|
||||
#include "taskwd.h"
|
||||
#include "epicsMath.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsExit.h"
|
||||
@@ -107,14 +105,13 @@ static char *priorityName[NUM_CALLBACK_PRIORITIES] = {
|
||||
|
||||
/* EVENT */
|
||||
|
||||
typedef struct event_list {
|
||||
CALLBACK callback[NUM_CALLBACK_PRIORITIES];
|
||||
scan_list scan_list[NUM_CALLBACK_PRIORITIES];
|
||||
struct event_list *next;
|
||||
char eventname[1]; /* actually arbitrary size */
|
||||
} event_list;
|
||||
static event_list * volatile pevent_list[256];
|
||||
static epicsMutexId event_lock;
|
||||
#define MAX_EVENTS 256
|
||||
typedef struct event_scan_list {
|
||||
CALLBACK callback;
|
||||
scan_list scan_list;
|
||||
} event_scan_list;
|
||||
static event_scan_list *pevent_list[NUM_CALLBACK_PRIORITIES][MAX_EVENTS];
|
||||
|
||||
|
||||
/* IO_EVENT*/
|
||||
|
||||
@@ -222,19 +219,35 @@ void scanAdd(struct dbCommon *precord)
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
"scanAdd detected illegal SCAN value");
|
||||
} else if (scan == menuScanEvent) {
|
||||
char* eventname;
|
||||
int evnt;
|
||||
int prio;
|
||||
event_list *pel;
|
||||
event_scan_list *pesl;
|
||||
|
||||
eventname = precord->evnt;
|
||||
evnt = precord->evnt;
|
||||
if (evnt < 0 || evnt >= MAX_EVENTS) {
|
||||
recGblRecordError(S_db_badField, (void *)precord,
|
||||
"scanAdd detected illegal EVNT value");
|
||||
precord->scan = menuScanPassive;
|
||||
return;
|
||||
}
|
||||
prio = precord->prio;
|
||||
if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) {
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
"scanAdd: illegal prio field");
|
||||
precord->scan = menuScanPassive;
|
||||
return;
|
||||
}
|
||||
pel = eventNameToHandle(eventname);
|
||||
if (pel) addToList(precord, &pel->scan_list[prio]);
|
||||
pesl = pevent_list[prio][evnt];
|
||||
if (pesl == NULL) {
|
||||
pesl = dbCalloc(1, sizeof(event_scan_list));
|
||||
pevent_list[prio][evnt] = pesl;
|
||||
pesl->scan_list.lock = epicsMutexMustCreate();
|
||||
callbackSetCallback(eventCallback, &pesl->callback);
|
||||
callbackSetPriority(prio, &pesl->callback);
|
||||
callbackSetUser(pesl, &pesl->callback);
|
||||
ellInit(&pesl->scan_list.list);
|
||||
}
|
||||
addToList(precord, &pesl->scan_list);
|
||||
} else if (scan == menuScanI_O_Intr) {
|
||||
io_scan_list *piosl = NULL;
|
||||
int prio;
|
||||
@@ -291,18 +304,31 @@ void scanDelete(struct dbCommon *precord)
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
"scanDelete detected illegal SCAN value");
|
||||
} else if (scan == menuScanEvent) {
|
||||
int evnt;
|
||||
int prio;
|
||||
event_list *pel;
|
||||
event_scan_list *pesl;
|
||||
scan_list *psl = 0;
|
||||
|
||||
evnt = precord->evnt;
|
||||
if (evnt < 0 || evnt >= MAX_EVENTS) {
|
||||
recGblRecordError(S_db_badField, (void *)precord,
|
||||
"scanAdd detected illegal EVNT value");
|
||||
precord->scan = menuScanPassive;
|
||||
return;
|
||||
}
|
||||
prio = precord->prio;
|
||||
if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) {
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
"scanDelete detected illegal PRIO field");
|
||||
"scanAdd: illegal prio field");
|
||||
precord->scan = menuScanPassive;
|
||||
return;
|
||||
}
|
||||
pel = eventNameToHandle(precord->evnt);
|
||||
if (pel && (psl = &pel->scan_list[prio]))
|
||||
pesl = pevent_list[prio][evnt];
|
||||
if (pesl) psl = &pesl->scan_list;
|
||||
if (!pesl || !psl)
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
"scanDelete for bad evnt");
|
||||
else
|
||||
deleteFromList(precord, psl);
|
||||
} else if (scan == menuScanI_O_Intr) {
|
||||
io_scan_list *piosl=NULL;
|
||||
@@ -384,20 +410,21 @@ int scanppl(double period) /* print periodic scan list(s) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scanpel(const char* eventname) /* print event list */
|
||||
int scanpel(int event_number) /* print event list */
|
||||
{
|
||||
char message[80];
|
||||
int prio;
|
||||
event_list *pel;
|
||||
|
||||
for (pel = pevent_list[0]; pel; pel = pel->next) {
|
||||
if (!eventname || epicsStrGlobMatch(pel->eventname, eventname)) {
|
||||
printf("Event \"%s\"\n", pel->eventname);
|
||||
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
|
||||
if (ellCount(&pel->scan_list[prio].list) == 0) continue;
|
||||
sprintf(message, " Priority %s", priorityName[prio]);
|
||||
printList(&pel->scan_list[prio], message);
|
||||
}
|
||||
int prio, evnt;
|
||||
event_scan_list *pesl;
|
||||
|
||||
for (evnt = 0; evnt < MAX_EVENTS; evnt++) {
|
||||
if (event_number && evnt<event_number) continue;
|
||||
if (event_number && evnt>event_number) break;
|
||||
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
|
||||
pesl = pevent_list[prio][evnt];
|
||||
if (!pesl) continue;
|
||||
if (ellCount(&pesl->scan_list.list) == 0) continue;
|
||||
sprintf(message, "Event %d Priority %s", evnt, priorityName[prio]);
|
||||
printList(&pesl->scan_list, message);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -423,106 +450,39 @@ int scanpiol(void) /* print io_event list */
|
||||
|
||||
static void eventCallback(CALLBACK *pcallback)
|
||||
{
|
||||
scan_list *psl;
|
||||
event_scan_list *pesl;
|
||||
|
||||
callbackGetUser(psl, pcallback);
|
||||
scanList(psl);
|
||||
callbackGetUser(pesl, pcallback);
|
||||
scanList(&pesl->scan_list);
|
||||
}
|
||||
|
||||
static void initEvent(void)
|
||||
{
|
||||
}
|
||||
int evnt, prio;
|
||||
|
||||
static void eventOnce(void *arg)
|
||||
{
|
||||
event_lock = epicsMutexMustCreate();
|
||||
}
|
||||
|
||||
event_list *eventNameToHandle(const char *eventname)
|
||||
{
|
||||
int prio;
|
||||
event_list *pel;
|
||||
static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT;
|
||||
double eventnumber = 0;
|
||||
size_t namelength;
|
||||
char* p;
|
||||
|
||||
if (!eventname) return NULL;
|
||||
while (isspace((unsigned char)eventname[0])) eventname++;
|
||||
if (!eventname[0]) return NULL;
|
||||
namelength = strlen(eventname);
|
||||
while (isspace((unsigned char)eventname[namelength-1])) namelength--;
|
||||
|
||||
/* Backward compatibility with numeric events:
|
||||
Treat any string that represents a double with an
|
||||
integer part between 0 and 255 the same as the integer
|
||||
because it is most probably a conversion from double
|
||||
like from a calc record.
|
||||
*/
|
||||
eventnumber = strtod(eventname, &p);
|
||||
if (*p == 0)
|
||||
{
|
||||
if (!finite(eventnumber))
|
||||
return NULL; /* Inf and NaN are no events */
|
||||
if (eventnumber >= 0 && eventnumber < 256)
|
||||
{
|
||||
if (eventnumber < 1)
|
||||
return NULL; /* 0 is no event */
|
||||
if ((pel = pevent_list[(int)eventnumber]) != NULL)
|
||||
return pel;
|
||||
}
|
||||
else
|
||||
eventnumber = 0; /* not a numeric event */
|
||||
}
|
||||
|
||||
epicsThreadOnce(&onceId, eventOnce, NULL);
|
||||
epicsMutexMustLock(event_lock);
|
||||
for (pel = pevent_list[0]; pel; pel=pel->next) {
|
||||
if (strncmp(pel->eventname, eventname, namelength) == 0
|
||||
&& pel->eventname[namelength] == 0)
|
||||
break;
|
||||
}
|
||||
if (pel == NULL) {
|
||||
pel = dbCalloc(1, sizeof(event_list) + namelength);
|
||||
if (eventnumber > 0)
|
||||
{
|
||||
/* backward compatibility: make all numeric events look like integers */
|
||||
sprintf(pel->eventname, "%i", (int)eventnumber);
|
||||
pevent_list[(int)eventnumber] = pel;
|
||||
}
|
||||
else
|
||||
strncpy(pel->eventname, eventname, namelength);
|
||||
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
|
||||
callbackSetUser(&pel->scan_list[prio], &pel->callback[prio]);
|
||||
callbackSetPriority(prio, &pel->callback[prio]);
|
||||
callbackSetCallback(eventCallback, &pel->callback[prio]);
|
||||
pel->scan_list[prio].lock = epicsMutexMustCreate();
|
||||
ellInit(&pel->scan_list[prio].list);
|
||||
}
|
||||
pel->next=pevent_list[0];
|
||||
pevent_list[0]=pel;
|
||||
}
|
||||
epicsMutexUnlock(event_lock);
|
||||
return pel;
|
||||
}
|
||||
|
||||
void postEvent(event_list *pel)
|
||||
{
|
||||
int prio;
|
||||
|
||||
if (scanCtl != ctlRun) return;
|
||||
if (!pel) return;
|
||||
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
|
||||
if (ellCount(&pel->scan_list[prio].list) >0)
|
||||
callbackRequest(&pel->callback[prio]);
|
||||
for (evnt = 0; evnt < MAX_EVENTS; evnt++) {
|
||||
pevent_list[prio][evnt] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* backward compatibility */
|
||||
void post_event(int event)
|
||||
{
|
||||
if (event <= 0 || event > 255) return;
|
||||
postEvent(pevent_list[event]);
|
||||
int prio;
|
||||
event_scan_list *pesl;
|
||||
|
||||
if (scanCtl != ctlRun) return;
|
||||
if (event < 0 || event >= MAX_EVENTS) {
|
||||
errMessage(-1, "illegal event passed to post_event");
|
||||
return;
|
||||
}
|
||||
for (prio=0; prio<NUM_CALLBACK_PRIORITIES; prio++) {
|
||||
pesl = pevent_list[prio][event];
|
||||
if (!pesl) continue;
|
||||
if (ellCount(&pesl->scan_list.list) >0)
|
||||
callbackRequest((void *)pesl);
|
||||
}
|
||||
}
|
||||
|
||||
void scanIoInit(IOSCANPVT *ppioscanpvt)
|
||||
|
||||
@@ -31,13 +31,10 @@ extern "C" {
|
||||
#define MAX_PHASE SHRT_MAX
|
||||
#define MIN_PHASE SHRT_MIN
|
||||
|
||||
#define HAVE_NAMED_SOFT_EVENTS
|
||||
|
||||
/*definitions for I/O Interrupt Scanning */
|
||||
struct io_scan_list;
|
||||
|
||||
typedef struct io_scan_list *IOSCANPVT;
|
||||
typedef struct event_list *EVENTPVT;
|
||||
|
||||
struct dbCommon;
|
||||
|
||||
@@ -45,8 +42,6 @@ epicsShareFunc long scanInit(void);
|
||||
epicsShareFunc void scanRun(void);
|
||||
epicsShareFunc void scanPause(void);
|
||||
|
||||
epicsShareFunc EVENTPVT eventNameToHandle(const char* event);
|
||||
epicsShareFunc void postEvent(EVENTPVT epvt);
|
||||
epicsShareFunc void post_event(int event);
|
||||
epicsShareFunc void scanAdd(struct dbCommon *);
|
||||
epicsShareFunc void scanDelete(struct dbCommon *);
|
||||
@@ -58,7 +53,7 @@ epicsShareFunc int scanOnceSetQueueSize(int size);
|
||||
epicsShareFunc int scanppl(double rate);
|
||||
|
||||
/*print event lists*/
|
||||
epicsShareFunc int scanpel(const char *event_name);
|
||||
epicsShareFunc int scanpel(int event_number);
|
||||
|
||||
/*print io_event list*/
|
||||
epicsShareFunc int scanpiol(void);
|
||||
|
||||
@@ -94,7 +94,6 @@ typedef struct dbInfoNode { /*non-field per-record information*/
|
||||
char *name;
|
||||
char *string;
|
||||
void *pointer;
|
||||
dbFldDes *pdbFldDes;
|
||||
}dbInfoNode;
|
||||
|
||||
#define DBRN_FLAGS_VISIBLE 1
|
||||
@@ -107,7 +106,6 @@ typedef struct dbRecordNode {
|
||||
char *recordname;
|
||||
ELLLIST infoList; /*LIST head of info nodes*/
|
||||
int flags;
|
||||
struct dbRecordNode *aliasedRecnode; /* NULL unless flags|DBRN_FLAGS_ISALIAS */
|
||||
}dbRecordNode;
|
||||
|
||||
/*dbRecordAttribute is for "psuedo" fields */
|
||||
|
||||
@@ -47,9 +47,6 @@ epicsExportAddress(int,dbRecordsOnceOnly);
|
||||
epicsShareDef int dbBptNotMonotonic=0;
|
||||
epicsExportAddress(int,dbBptNotMonotonic);
|
||||
|
||||
epicsShareDef int dbQuietMacroWarnings=0;
|
||||
epicsExportAddress(int,dbQuietMacroWarnings);
|
||||
|
||||
/*private routines */
|
||||
static void yyerrorAbort(char *str);
|
||||
static void allocTemp(void *pvoid);
|
||||
@@ -230,7 +227,6 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
|
||||
free((void *)macPairs);
|
||||
mac_input_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char));
|
||||
}
|
||||
macSuppressWarning(macHandle,dbQuietMacroWarnings);
|
||||
}
|
||||
pinputFile = dbCalloc(1,sizeof(inputFile));
|
||||
if (filename) {
|
||||
|
||||
@@ -1548,7 +1548,7 @@ long epicsShareAPI dbCreateRecord(DBENTRY *pdbentry,const char *precordName)
|
||||
if((status = dbAllocRecord(pdbentry,precordName))) return(status);
|
||||
pNewRecNode->recordname = dbRecordName(pdbentry);
|
||||
ellInit(&pNewRecNode->infoList);
|
||||
/* install record node in list in sorted position */
|
||||
/* install record node in list in sorted postion */
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while(status==0) {
|
||||
if(strcmp(precordName,dbGetRecordName(pdbentry)) < 0) break;
|
||||
@@ -1816,44 +1816,37 @@ long epicsShareAPI dbCreateAlias(DBENTRY *pdbentry, const char *alias)
|
||||
dbRecordNode *pnewnode;
|
||||
PVDENTRY *ppvd;
|
||||
ELLLIST *preclist = NULL;
|
||||
DBENTRY dbEntry;
|
||||
long status;
|
||||
|
||||
if (!precordType) return S_dbLib_recordTypeNotFound;
|
||||
/* alias of alias still references actual record */
|
||||
while(precnode && (precnode->flags&DBRN_FLAGS_ISALIAS))
|
||||
precnode = precnode->aliasedRecnode;
|
||||
if (!precnode) return S_dbLib_recNotFound;
|
||||
/* use copy to avoid later info fields being bound to the alias */
|
||||
dbCopyEntryContents(pdbentry, &dbEntry);
|
||||
zeroDbentry(&dbEntry);
|
||||
if (!dbFindRecord(&dbEntry, alias)) return S_dbLib_recExists;
|
||||
zeroDbentry(&dbEntry);
|
||||
dbEntry.precordType = precordType;
|
||||
zeroDbentry(pdbentry);
|
||||
if (!dbFindRecord(pdbentry, alias)) return S_dbLib_recExists;
|
||||
zeroDbentry(pdbentry);
|
||||
pdbentry->precordType = precordType;
|
||||
preclist = &precordType->recList;
|
||||
pnewnode = dbCalloc(1, sizeof(dbRecordNode));
|
||||
pnewnode->recordname = epicsStrDup(alias);
|
||||
pnewnode->precord = precnode->precord;
|
||||
pnewnode->aliasedRecnode = precnode;
|
||||
pnewnode->flags = DBRN_FLAGS_ISALIAS;
|
||||
precnode->flags |= DBRN_FLAGS_HASALIAS;
|
||||
if (!(precnode->flags & DBRN_FLAGS_ISALIAS))
|
||||
precnode->flags |= DBRN_FLAGS_HASALIAS;
|
||||
ellInit(&pnewnode->infoList);
|
||||
/* install alias node in list in sorted position */
|
||||
status = dbFirstRecord(&dbEntry);
|
||||
/* install record node in list in sorted postion */
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while (!status) {
|
||||
if (strcmp(alias, dbGetRecordName(&dbEntry)) < 0) break;
|
||||
status = dbNextRecord(&dbEntry);
|
||||
if (strcmp(alias, dbGetRecordName(pdbentry)) < 0) break;
|
||||
status = dbNextRecord(pdbentry);
|
||||
}
|
||||
if (!status) {
|
||||
precnode = dbEntry.precnode;
|
||||
precnode = pdbentry->precnode;
|
||||
ellInsert(preclist, ellPrevious(&precnode->node), &pnewnode->node);
|
||||
} else {
|
||||
ellAdd(preclist, &pnewnode->node);
|
||||
}
|
||||
precordType->no_aliases++;
|
||||
dbEntry.precnode = pnewnode;
|
||||
ppvd = dbPvdAdd(dbEntry.pdbbase, precordType, pnewnode);
|
||||
dbFinishEntry(&dbEntry);
|
||||
pdbentry->precnode = pnewnode;
|
||||
ppvd = dbPvdAdd(pdbentry->pdbbase, precordType, pnewnode);
|
||||
if (!ppvd) {errMessage(-1,"Logic Err: Could not add to PVD");return(-1);}
|
||||
return 0;
|
||||
}
|
||||
@@ -2815,32 +2808,6 @@ long epicsShareAPI dbFindInfo(DBENTRY *pdbentry,const char *name)
|
||||
return (S_dbLib_infoNotFound);
|
||||
}
|
||||
|
||||
long dbFindInfoPart(DBENTRY *pdbentry, const char **ppname)
|
||||
{
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
dbInfoNode *pinfo;
|
||||
const char *pname = *ppname;
|
||||
size_t len;
|
||||
|
||||
if (precnode->aliasedRecnode)
|
||||
precnode=precnode->aliasedRecnode;
|
||||
pinfo = (dbInfoNode *)ellFirst(&precnode->infoList);
|
||||
while (pinfo) {
|
||||
len = strlen(pinfo->name);
|
||||
if (!strncmp(pinfo->name, pname, len) &&
|
||||
(pname[len] == 0 || pname[len] == '$' || pname[len] == '{' || pname[len] == '['))
|
||||
{
|
||||
pdbentry->pinfonode = pinfo;
|
||||
pdbentry->pflddes = pinfo->pdbFldDes;
|
||||
pdbentry->pfield = pinfo->string;
|
||||
*ppname = &pname[len];
|
||||
return (0);
|
||||
}
|
||||
pinfo = (dbInfoNode *)ellNext(&pinfo->node);
|
||||
}
|
||||
return S_dbLib_fieldNotFound;
|
||||
}
|
||||
|
||||
long epicsShareAPI dbDeleteInfo(DBENTRY *pdbentry)
|
||||
{
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
@@ -2879,7 +2846,6 @@ long epicsShareAPI dbPutInfoString(DBENTRY *pdbentry,const char *string)
|
||||
if (!newstring) return (S_dbLib_outMem);
|
||||
strcpy(newstring, string);
|
||||
pinfo->string = newstring;
|
||||
pinfo->pdbFldDes->size = strlen(newstring)+1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -2906,7 +2872,6 @@ const char * epicsShareAPI dbGetInfo(DBENTRY *pdbentry,const char *name)
|
||||
|
||||
long epicsShareAPI dbPutInfo(DBENTRY *pdbentry,const char *name,const char *string)
|
||||
{
|
||||
dbFldDes *pdbFldDes;
|
||||
dbInfoNode *pinfo;
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
if (!precnode) return (S_dbLib_recNotFound);
|
||||
@@ -2931,20 +2896,6 @@ long epicsShareAPI dbPutInfo(DBENTRY *pdbentry,const char *name,const char *stri
|
||||
return (S_dbLib_outMem);
|
||||
}
|
||||
strcpy(pinfo->string, string);
|
||||
pdbFldDes = calloc(1,sizeof(dbFldDes));
|
||||
if (!pdbFldDes) {
|
||||
free(pinfo->string);
|
||||
free(pinfo->name);
|
||||
free(pinfo);
|
||||
return (S_dbLib_outMem);
|
||||
}
|
||||
pdbFldDes->name = pinfo->name;
|
||||
pdbFldDes->pdbRecordType = pdbentry->precordType;
|
||||
pdbFldDes->special = SPC_ATTRIBUTE;
|
||||
pdbFldDes->field_type = DBF_STRING;
|
||||
pdbFldDes->as_level = ASL1;
|
||||
pdbFldDes->size = strlen(string)+1;
|
||||
pinfo->pdbFldDes = pdbFldDes;
|
||||
ellAdd(&precnode->infoList,&pinfo->node);
|
||||
pdbentry->pinfonode = pinfo;
|
||||
return (0);
|
||||
|
||||
@@ -170,8 +170,6 @@ epicsShareFunc char * epicsShareAPI dbVerify(DBENTRY *pdbentry,
|
||||
epicsShareFunc char * epicsShareAPI dbGetRange(DBENTRY *pdbentry);
|
||||
epicsShareFunc int epicsShareAPI dbIsDefaultValue(DBENTRY *pdbentry);
|
||||
|
||||
epicsShareFunc long dbFindInfoPart(DBENTRY *pdbentry,
|
||||
const char **ppname);
|
||||
epicsShareFunc long epicsShareAPI dbFirstInfo(DBENTRY *pdbentry);
|
||||
epicsShareFunc long epicsShareAPI dbNextInfo(DBENTRY *pdbentry);
|
||||
epicsShareFunc long epicsShareAPI dbFindInfo(DBENTRY *pdbentry,
|
||||
|
||||
@@ -50,7 +50,7 @@ static long init_record(eventRecord *prec)
|
||||
/* INP must be CONSTANT, PV_LINK, DB_LINK or CA_LINK*/
|
||||
switch (prec->inp.type) {
|
||||
case CONSTANT:
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_STRING, &prec->val))
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_USHORT, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
break;
|
||||
case PV_LINK:
|
||||
@@ -68,20 +68,13 @@ static long init_record(eventRecord *prec)
|
||||
static long read_event(eventRecord *prec)
|
||||
{
|
||||
long status;
|
||||
char newEvent[MAX_STRING_SIZE];
|
||||
|
||||
if (prec->inp.type != CONSTANT)
|
||||
{
|
||||
status = dbGetLinkValue(&prec->inp, DBR_STRING, newEvent, 0, 0);
|
||||
if (status) return status;
|
||||
if (strcmp(newEvent, prec->val) != 0) {
|
||||
strcpy(prec->val, newEvent);
|
||||
prec->epvt = eventNameToHandle(prec->val);
|
||||
}
|
||||
status = dbGetLink(&prec->inp, DBR_USHORT, &prec->val, 0, 0);
|
||||
if (!status) {
|
||||
prec->udf = FALSE;
|
||||
if (prec->tsel.type == CONSTANT &&
|
||||
prec->tse == epicsTimeEventDeviceTime)
|
||||
dbGetTimeStamp(&prec->inp, &prec->time);
|
||||
}
|
||||
prec->udf = FALSE;
|
||||
if (prec->tsel.type == CONSTANT &&
|
||||
prec->tse == epicsTimeEventDeviceTime)
|
||||
dbGetTimeStamp(&prec->inp, &prec->time);
|
||||
return 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -17,9 +17,7 @@ epicsReadline_INCLUDES += $(INCLUDES_$(COMMANDLINE_LIBRARY))
|
||||
|
||||
#POSIX thread priority scheduling flag
|
||||
THREAD_CPPFLAGS_NO += -DDONT_USE_POSIX_THREAD_PRIORITY_SCHEDULING
|
||||
osdMutex_CPPFLAGS += $(THREAD_CPPFLAGS_$(USE_POSIX_THREAD_PRIORITY_SCHEDULING))
|
||||
osdThread_CPPFLAGS += $(THREAD_CPPFLAGS_$(USE_POSIX_THREAD_PRIORITY_SCHEDULING))
|
||||
osdSpin_CPPFLAGS += $(THREAD_CPPFLAGS_$(USE_POSIX_THREAD_PRIORITY_SCHEDULING))
|
||||
|
||||
#epicsVersion is created by this Makefile
|
||||
INC += epicsVersion.h
|
||||
@@ -162,7 +160,6 @@ INC += osdInterrupt.h
|
||||
|
||||
INC += epicsMutex.h
|
||||
INC += osdMutex.h
|
||||
INC += epicsSpin.h
|
||||
INC += epicsEvent.h
|
||||
INC += osdEvent.h
|
||||
INC += epicsMath.h
|
||||
@@ -227,7 +224,6 @@ SRCS += osdStdio.c
|
||||
|
||||
SRCS += osdThread.c
|
||||
SRCS += osdMutex.c
|
||||
SRCS += osdSpin.c
|
||||
SRCS += osdEvent.c
|
||||
SRCS += osdTime.cpp
|
||||
SRCS += osdProcess.c
|
||||
|
||||
@@ -48,6 +48,7 @@ epicsShareFunc long
|
||||
double *ptop; /* stack pointer */
|
||||
double top; /* value from top of stack */
|
||||
epicsInt32 itop; /* integer from top of stack */
|
||||
epicsUInt32 utop; /* unsigned integer from top of stack */
|
||||
int op;
|
||||
int nargs;
|
||||
|
||||
@@ -286,36 +287,30 @@ epicsShareFunc long
|
||||
*ptop = ! *ptop;
|
||||
break;
|
||||
|
||||
/* Be VERY careful converting double to int in case bit 31 is set!
|
||||
* Out-of-range errors give very different results on different sytems.
|
||||
* Convert negative doubles to signed and positive doubles to unsigned
|
||||
* first to avoid overflows if bit 32 is set.
|
||||
* The result is always signed, values with bit 31 set are negative
|
||||
* to avoid problems when writing the value to signed integer fields
|
||||
* like longout.VAL or ao.RVAL. However unsigned fields may give
|
||||
* problems on some architectures. (Fewer than giving problems with
|
||||
* signed integer. Maybe the conversion functions should handle
|
||||
* overflows better.)
|
||||
/* For bitwise operations on values with bit 31 set, double values
|
||||
* must first be cast to unsigned to correctly set that bit; the
|
||||
* double value must be negative in that case. The result must be
|
||||
* cast to a signed integer before converting to the double result.
|
||||
*/
|
||||
#define d2i(x) ((x)<0?(epicsInt32)(x):(epicsInt32)(epicsUInt32)(x))
|
||||
|
||||
case BIT_OR:
|
||||
top = *ptop--;
|
||||
*ptop = (double)(d2i(*ptop) | d2i(top));
|
||||
utop = *ptop--;
|
||||
*ptop = (epicsInt32) ((epicsUInt32) *ptop | utop);
|
||||
break;
|
||||
|
||||
case BIT_AND:
|
||||
top = *ptop--;
|
||||
*ptop = (double)(d2i(*ptop) & d2i(top));
|
||||
utop = *ptop--;
|
||||
*ptop = (epicsInt32) ((epicsUInt32) *ptop & utop);
|
||||
break;
|
||||
|
||||
case BIT_EXCL_OR:
|
||||
top = *ptop--;
|
||||
*ptop = (double)(d2i(*ptop) ^ d2i(top));
|
||||
utop = *ptop--;
|
||||
*ptop = (epicsInt32) ((epicsUInt32) *ptop ^ utop);
|
||||
break;
|
||||
|
||||
case BIT_NOT:
|
||||
*ptop = (double)~d2i(*ptop);
|
||||
utop = *ptop;
|
||||
*ptop = (epicsInt32) ~utop;
|
||||
break;
|
||||
|
||||
/* The shift operators use signed integers, so a right-shift will
|
||||
@@ -324,13 +319,13 @@ epicsShareFunc long
|
||||
*/
|
||||
|
||||
case RIGHT_SHIFT:
|
||||
top = *ptop--;
|
||||
*ptop = (double)(d2i(*ptop) >> (d2i(top) & 31));
|
||||
utop = *ptop--;
|
||||
*ptop = ((epicsInt32) (epicsUInt32) *ptop) >> (utop & 31);
|
||||
break;
|
||||
|
||||
case LEFT_SHIFT:
|
||||
top = *ptop--;
|
||||
*ptop = (double)(d2i(*ptop) << (d2i(top) & 31));
|
||||
utop = *ptop--;
|
||||
*ptop = ((epicsInt32) (epicsUInt32) *ptop) << (utop & 31);
|
||||
break;
|
||||
|
||||
case NOT_EQ:
|
||||
|
||||
@@ -421,12 +421,10 @@ epicsShareFunc long
|
||||
pstacktop--;
|
||||
}
|
||||
|
||||
/*
|
||||
* if (cond_count != 0) {
|
||||
* *perror = CALC_ERR_CONDITIONAL;
|
||||
* goto bad;
|
||||
* }
|
||||
*/
|
||||
if (cond_count != 0) {
|
||||
*perror = CALC_ERR_CONDITIONAL;
|
||||
goto bad;
|
||||
}
|
||||
if (runtime_depth > 1) {
|
||||
*perror = CALC_ERR_TOOMANY;
|
||||
goto bad;
|
||||
@@ -470,12 +468,10 @@ epicsShareFunc long
|
||||
}
|
||||
*pout = END_EXPRESSION;
|
||||
|
||||
/*
|
||||
* if (cond_count != 0) {
|
||||
* *perror = CALC_ERR_CONDITIONAL;
|
||||
* goto bad;
|
||||
* }
|
||||
*/
|
||||
if (cond_count != 0) {
|
||||
*perror = CALC_ERR_CONDITIONAL;
|
||||
goto bad;
|
||||
}
|
||||
if (operand_needed || runtime_depth != 1) {
|
||||
*perror = CALC_ERR_INCOMPLETE;
|
||||
goto bad;
|
||||
|
||||
@@ -281,13 +281,6 @@ void ellFree2 (ELLLIST *pList, FREEFUNC freeFunc)
|
||||
pList->count = 0;
|
||||
}
|
||||
|
||||
/* for backward compatibility provide a function ellFree() in addition to macro */
|
||||
#undef ellFree
|
||||
void ellFree (ELLLIST *pList)
|
||||
{
|
||||
ellFree2 (pList, free);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* This function verifies that the list is consistent.
|
||||
|
||||
1
src/libCom/env/envDefs.h
vendored
1
src/libCom/env/envDefs.h
vendored
@@ -69,7 +69,6 @@ epicsShareExtern const ENV_PARAM EPICS_CMD_PROTO_PORT;
|
||||
epicsShareExtern const ENV_PARAM EPICS_AR_PORT;
|
||||
epicsShareExtern const ENV_PARAM IOCSH_PS1;
|
||||
epicsShareExtern const ENV_PARAM IOCSH_HISTSIZE;
|
||||
epicsShareExtern const ENV_PARAM EPICS_MUTEX_USE_PRIORITY_INHERITANCE;
|
||||
|
||||
epicsShareExtern const ENV_PARAM *env_param_list[];
|
||||
|
||||
|
||||
@@ -51,8 +51,9 @@ typedef struct errnumnode {
|
||||
#define NHASH 256
|
||||
|
||||
|
||||
static ERRNUMNODE **hashtable = NULL;
|
||||
#define initialized (hashtable!=NULL)
|
||||
static ELLLIST errnumlist = ELLLIST_INIT;
|
||||
static ERRNUMNODE **hashtable;
|
||||
static int initialized = FALSE;
|
||||
extern ERRSYMTAB_ID errSymTbl;
|
||||
|
||||
/****************************************************************
|
||||
@@ -66,8 +67,12 @@ extern ERRSYMTAB_ID errSymTbl;
|
||||
int epicsShareAPI errSymBld(void)
|
||||
{
|
||||
ERRSYMBOL *errArray = errSymTbl->symbols;
|
||||
ERRNUMNODE *perrNumNode = NULL;
|
||||
ERRNUMNODE *pNextNode = NULL;
|
||||
ERRNUMNODE **phashnode = NULL;
|
||||
int i;
|
||||
int modnum;
|
||||
unsigned short hashInd;
|
||||
|
||||
if(initialized) return(0);
|
||||
hashtable = (ERRNUMNODE**)callocMustSucceed
|
||||
@@ -84,6 +89,21 @@ int epicsShareAPI errSymBld(void)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
perrNumNode = (ERRNUMNODE *) ellFirst(&errnumlist);
|
||||
while (perrNumNode) {
|
||||
/* hash each perrNumNode->errNum */
|
||||
hashInd = errhash(perrNumNode->errNum);
|
||||
phashnode = (ERRNUMNODE**)&hashtable[hashInd];
|
||||
pNextNode = (ERRNUMNODE*) *phashnode;
|
||||
/* search for last node (NULL) of hashnode linked list */
|
||||
while (pNextNode) {
|
||||
phashnode = &pNextNode->hashnode;
|
||||
pNextNode = *phashnode;
|
||||
}
|
||||
*phashnode = perrNumNode;
|
||||
perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode);
|
||||
}
|
||||
initialized = TRUE;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -105,33 +125,16 @@ unsigned short errnum;
|
||||
|
||||
/****************************************************************
|
||||
* ERRSYMBOLADD
|
||||
* adds symbols to the master hashtable as compiled from errSymTbl.c
|
||||
* adds symbols to the master errnumlist as compiled from errSymTbl.c
|
||||
***************************************************************/
|
||||
int epicsShareAPI errSymbolAdd (long errNum,char *name)
|
||||
{
|
||||
ERRNUMNODE *perrNumNode;
|
||||
ERRNUMNODE *pNextNode = NULL;
|
||||
ERRNUMNODE **phashnode = NULL;
|
||||
unsigned short hashInd;
|
||||
|
||||
if(!initialized) errSymBld();
|
||||
|
||||
perrNumNode = (ERRNUMNODE*)callocMustSucceed(1,sizeof(ERRNUMNODE),"errSymbolAdd");
|
||||
perrNumNode->errNum = errNum;
|
||||
perrNumNode->message = name;
|
||||
|
||||
/* hash each perrNumNode->errNum */
|
||||
hashInd = errhash(perrNumNode->errNum);
|
||||
phashnode = (ERRNUMNODE**)&hashtable[hashInd];
|
||||
pNextNode = (ERRNUMNODE*) *phashnode;
|
||||
/* search for last node (NULL) of hashnode linked list */
|
||||
while (pNextNode) {
|
||||
phashnode = &pNextNode->hashnode;
|
||||
pNextNode = *phashnode;
|
||||
}
|
||||
*phashnode = perrNumNode;
|
||||
perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode);
|
||||
ERRNUMNODE *pNew;
|
||||
|
||||
pNew = (ERRNUMNODE*)callocMustSucceed(1,sizeof(ERRNUMNODE),"errSymbolAdd");
|
||||
pNew->errNum = errNum;
|
||||
pNew->message = name;
|
||||
ellAdd(&errnumlist,(ELLNODE*)pNew);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "errlog.h"
|
||||
#include "logClient.h"
|
||||
#include "iocLog.h"
|
||||
#include "epicsExit.h"
|
||||
|
||||
int iocLogDisable = 0;
|
||||
|
||||
@@ -76,14 +75,6 @@ void epicsShareAPI epicsShareAPI iocLogFlush (void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* logClientDestroy()
|
||||
*/
|
||||
static void iocLogClientDestroy (logClientId id)
|
||||
{
|
||||
errlogRemoveListener (logClientSendMessage);
|
||||
}
|
||||
|
||||
/*
|
||||
* iocLogClientInit()
|
||||
*/
|
||||
@@ -100,8 +91,7 @@ static logClientId iocLogClientInit (void)
|
||||
}
|
||||
id = logClientCreate (addr, port);
|
||||
if (id != NULL) {
|
||||
errlogAddListener (logClientSendMessage, id);
|
||||
epicsAtExit (iocLogClientDestroy, id);
|
||||
errlogAddListener ( logClientSendMessage, id );
|
||||
}
|
||||
return id;
|
||||
}
|
||||
@@ -149,3 +139,13 @@ logClientId epicsShareAPI logClientInit (void)
|
||||
{
|
||||
return iocLogClientInit ();
|
||||
}
|
||||
|
||||
/*
|
||||
* logClientSendMessage (); deprecated
|
||||
*/
|
||||
void logClientSendMessage ( logClientId id, const char * message )
|
||||
{
|
||||
if ( !iocLogDisable ) {
|
||||
logClientSend (id, message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include "dbDefs.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "iocLog.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsThread.h"
|
||||
#include "epicsTime.h"
|
||||
@@ -43,7 +42,6 @@ typedef struct {
|
||||
SOCKET sock;
|
||||
epicsThreadId restartThreadId;
|
||||
epicsEventId stateChangeNotify;
|
||||
epicsEventId shutdownNotify;
|
||||
unsigned connectCount;
|
||||
unsigned nextMsgIndex;
|
||||
unsigned connected;
|
||||
@@ -53,13 +51,9 @@ typedef struct {
|
||||
} logClient;
|
||||
|
||||
static const double LOG_RESTART_DELAY = 5.0; /* sec */
|
||||
static const double LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT = 5.0; /* sec */
|
||||
static const double LOG_SERVER_SHUTDOWN_TIMEOUT = 30.0; /* sec */
|
||||
|
||||
/*
|
||||
* If set using iocLogPrefix() this string is prepended to all log messages:
|
||||
*/
|
||||
static char* logClientPrefix = NULL;
|
||||
|
||||
/*
|
||||
* logClientClose ()
|
||||
*/
|
||||
@@ -83,6 +77,8 @@ static void logClientClose ( logClient *pClient )
|
||||
pClient->sock = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
pClient->nextMsgIndex = 0u;
|
||||
memset ( pClient->msgBuf, '\0', sizeof ( pClient->msgBuf ) );
|
||||
pClient->connected = 0u;
|
||||
|
||||
/*
|
||||
@@ -110,7 +106,6 @@ static void logClientDestroy (logClientId id)
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
pClient->shutdown = 1u;
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
epicsEventSignal ( pClient->shutdownNotify );
|
||||
|
||||
/* unblock log client thread blocking in send() or connect() */
|
||||
interruptInfo =
|
||||
@@ -155,109 +150,112 @@ static void logClientDestroy (logClientId id)
|
||||
logClientClose ( pClient );
|
||||
|
||||
epicsMutexDestroy ( pClient->mutex );
|
||||
|
||||
epicsEventDestroy ( pClient->stateChangeNotify );
|
||||
epicsEventDestroy ( pClient->shutdownNotify );
|
||||
|
||||
free ( pClient );
|
||||
}
|
||||
|
||||
/*
|
||||
* logClientCheckConnection
|
||||
*/
|
||||
static void logClientCheckConnection( logClient * pClient )
|
||||
{
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
while ( pClient->connected ) {
|
||||
struct timeval timeout = { 0, 0 };
|
||||
fd_set set;
|
||||
char buffer[256];
|
||||
|
||||
FD_ZERO ( &set );
|
||||
FD_SET ( pClient->sock, &set );
|
||||
if ( select ( pClient->sock + 1, &set, NULL, NULL, &timeout ) == 0)
|
||||
break;
|
||||
if ( recv ( pClient->sock, buffer, sizeof ( buffer ), 0 ) == 0 ) {
|
||||
fprintf ( stderr, "log client: connection closed by server \"%s\"\n",
|
||||
pClient->name );
|
||||
logClientClose ( pClient );
|
||||
break;
|
||||
}
|
||||
}
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
}
|
||||
|
||||
/*
|
||||
* This method requires the pClient->mutex be owned already.
|
||||
*/
|
||||
static void sendMessageChunk(logClient * pClient, const char * message) {
|
||||
unsigned strSize;
|
||||
|
||||
strSize = strlen ( message );
|
||||
while ( strSize ) {
|
||||
unsigned msgBufBytesLeft =
|
||||
sizeof ( pClient->msgBuf ) - pClient->nextMsgIndex;
|
||||
|
||||
if ( msgBufBytesLeft < strSize && pClient->nextMsgIndex != 0u && pClient->connected)
|
||||
{
|
||||
/* buffer is full, thus flush it */
|
||||
logClientCheckConnection( pClient );
|
||||
logClientFlush ( pClient );
|
||||
msgBufBytesLeft = sizeof ( pClient->msgBuf ) - pClient->nextMsgIndex;
|
||||
}
|
||||
if ( msgBufBytesLeft == 0u ) {
|
||||
fprintf ( stderr, "log client: messages to \"%s\" are lost\n",
|
||||
pClient->name );
|
||||
break;
|
||||
}
|
||||
if ( msgBufBytesLeft > strSize) msgBufBytesLeft = strSize;
|
||||
memcpy ( & pClient->msgBuf[pClient->nextMsgIndex],
|
||||
message, msgBufBytesLeft );
|
||||
pClient->nextMsgIndex += msgBufBytesLeft;
|
||||
strSize -= msgBufBytesLeft;
|
||||
message += msgBufBytesLeft;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* logClientSend ()
|
||||
*/
|
||||
void epicsShareAPI logClientSend ( logClientId id, const char * message )
|
||||
{
|
||||
logClient * pClient = ( logClient * ) id;
|
||||
unsigned strSize;
|
||||
|
||||
if ( ! pClient || ! message ) {
|
||||
return;
|
||||
}
|
||||
|
||||
strSize = strlen ( message );
|
||||
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
|
||||
if (logClientPrefix) {
|
||||
sendMessageChunk(pClient, logClientPrefix);
|
||||
}
|
||||
sendMessageChunk(pClient, message);
|
||||
while ( strSize ) {
|
||||
unsigned msgBufBytesLeft =
|
||||
sizeof ( pClient->msgBuf ) - pClient->nextMsgIndex;
|
||||
|
||||
if ( strSize > msgBufBytesLeft ) {
|
||||
int status;
|
||||
|
||||
if ( ! pClient->connected ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( msgBufBytesLeft > 0u ) {
|
||||
memcpy ( & pClient->msgBuf[pClient->nextMsgIndex],
|
||||
message, msgBufBytesLeft );
|
||||
pClient->nextMsgIndex += msgBufBytesLeft;
|
||||
strSize -= msgBufBytesLeft;
|
||||
message += msgBufBytesLeft;
|
||||
}
|
||||
|
||||
status = send ( pClient->sock, pClient->msgBuf,
|
||||
pClient->nextMsgIndex, 0 );
|
||||
if ( status > 0 ) {
|
||||
unsigned nSent = (unsigned) status;
|
||||
if ( nSent < pClient->nextMsgIndex ) {
|
||||
unsigned newNextMsgIndex = pClient->nextMsgIndex - nSent;
|
||||
memmove ( pClient->msgBuf, & pClient->msgBuf[nSent],
|
||||
newNextMsgIndex );
|
||||
pClient->nextMsgIndex = newNextMsgIndex;
|
||||
}
|
||||
else {
|
||||
pClient->nextMsgIndex = 0u;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( ! pClient->shutdown ) {
|
||||
char sockErrBuf[64];
|
||||
if ( status ) {
|
||||
epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) );
|
||||
}
|
||||
else {
|
||||
strcpy ( sockErrBuf, "server initiated disconnect" );
|
||||
}
|
||||
fprintf ( stderr, "log client: lost contact with log server at \"%s\" because \"%s\"\n",
|
||||
pClient->name, sockErrBuf );
|
||||
}
|
||||
logClientClose ( pClient );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
memcpy ( & pClient->msgBuf[pClient->nextMsgIndex],
|
||||
message, strSize );
|
||||
pClient->nextMsgIndex += strSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
epicsMutexUnlock (pClient->mutex);
|
||||
}
|
||||
|
||||
|
||||
void epicsShareAPI logClientFlush ( logClientId id )
|
||||
{
|
||||
unsigned nSent = 0u;
|
||||
|
||||
logClient * pClient = ( logClient * ) id;
|
||||
|
||||
if ( ! pClient || ! pClient->connected ) {
|
||||
if ( ! pClient ) {
|
||||
return;
|
||||
}
|
||||
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
|
||||
while ( nSent < pClient->nextMsgIndex && pClient->connected ) {
|
||||
int status = send ( pClient->sock, pClient->msgBuf + nSent,
|
||||
pClient->nextMsgIndex - nSent, 0 );
|
||||
while ( pClient->nextMsgIndex && pClient->connected ) {
|
||||
int status = send ( pClient->sock, pClient->msgBuf,
|
||||
pClient->nextMsgIndex, 0 );
|
||||
if ( status > 0 ) {
|
||||
nSent += (unsigned) status;
|
||||
unsigned nSent = (unsigned) status;
|
||||
if ( nSent < pClient->nextMsgIndex ) {
|
||||
unsigned newNextMsgIndex = pClient->nextMsgIndex - nSent;
|
||||
memmove ( pClient->msgBuf, & pClient->msgBuf[nSent],
|
||||
newNextMsgIndex );
|
||||
pClient->nextMsgIndex = newNextMsgIndex;
|
||||
}
|
||||
else {
|
||||
pClient->nextMsgIndex = 0u;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( ! pClient->shutdown ) {
|
||||
@@ -275,11 +273,6 @@ void epicsShareAPI logClientFlush ( logClientId id )
|
||||
break;
|
||||
}
|
||||
}
|
||||
pClient->nextMsgIndex -= nSent;
|
||||
if ( nSent > 0 && pClient->nextMsgIndex > 0 ) {
|
||||
memmove ( pClient->msgBuf, & pClient->msgBuf[nSent],
|
||||
pClient->nextMsgIndex );
|
||||
}
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
}
|
||||
|
||||
@@ -384,6 +377,20 @@ static void logClientConnect (logClient *pClient)
|
||||
fprintf (stderr, "log client: unable to enable keepalive option because \"%s\"\n", sockErrBuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* we don't need full-duplex (clients only write), so we shutdown
|
||||
* the read end of our socket
|
||||
*/
|
||||
status = shutdown (pClient->sock, SHUT_RD);
|
||||
if (status < 0) {
|
||||
char sockErrBuf[64];
|
||||
epicsSocketConvertErrnoToString (
|
||||
sockErrBuf, sizeof ( sockErrBuf ) );
|
||||
fprintf (stderr, "%s:%d shutdown(%d,SHUT_RD) error was \"%s\"\n",
|
||||
__FILE__, __LINE__, pClient->sock, sockErrBuf);
|
||||
/* not fatal (although it shouldn't happen) */
|
||||
}
|
||||
|
||||
/*
|
||||
* set how long we will wait for the TCP state machine
|
||||
* to clean up when we issue a close(). This
|
||||
@@ -423,21 +430,20 @@ static void logClientRestart ( logClientId id )
|
||||
/* SMP safe state inspection */
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
while ( ! pClient->shutdown ) {
|
||||
unsigned isConn, dataToSend;
|
||||
|
||||
logClientCheckConnection( pClient );
|
||||
unsigned isConn;
|
||||
|
||||
isConn = pClient->connected;
|
||||
dataToSend = pClient->nextMsgIndex;
|
||||
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
|
||||
if ( dataToSend ) {
|
||||
if ( ! isConn ) logClientConnect ( pClient );
|
||||
if ( isConn ) {
|
||||
logClientFlush ( pClient );
|
||||
}
|
||||
|
||||
epicsEventWaitWithTimeout ( pClient->shutdownNotify, LOG_RESTART_DELAY);
|
||||
else {
|
||||
logClientConnect ( pClient );
|
||||
}
|
||||
|
||||
epicsThreadSleep ( LOG_RESTART_DELAY );
|
||||
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
}
|
||||
@@ -453,7 +459,9 @@ static void logClientRestart ( logClientId id )
|
||||
logClientId epicsShareAPI logClientCreate (
|
||||
struct in_addr server_addr, unsigned short server_port)
|
||||
{
|
||||
epicsTimeStamp begin, current;
|
||||
logClient *pClient;
|
||||
double diff;
|
||||
|
||||
pClient = calloc (1, sizeof (*pClient));
|
||||
if (pClient==NULL) {
|
||||
@@ -478,22 +486,14 @@ logClientId epicsShareAPI logClientCreate (
|
||||
pClient->shutdownConfirm = 0;
|
||||
|
||||
epicsAtExit (logClientDestroy, (void*) pClient);
|
||||
|
||||
|
||||
pClient->stateChangeNotify = epicsEventCreate (epicsEventEmpty);
|
||||
if ( ! pClient->stateChangeNotify ) {
|
||||
epicsMutexDestroy ( pClient->mutex );
|
||||
free ( pClient );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pClient->shutdownNotify = epicsEventCreate (epicsEventEmpty);
|
||||
if ( ! pClient->shutdownNotify ) {
|
||||
epicsMutexDestroy ( pClient->mutex );
|
||||
epicsEventDestroy ( pClient->stateChangeNotify );
|
||||
free ( pClient );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
pClient->restartThreadId = epicsThreadCreate (
|
||||
"logRestart", epicsThreadPriorityLow,
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
@@ -501,12 +501,33 @@ logClientId epicsShareAPI logClientCreate (
|
||||
if ( pClient->restartThreadId == NULL ) {
|
||||
epicsMutexDestroy ( pClient->mutex );
|
||||
epicsEventDestroy ( pClient->stateChangeNotify );
|
||||
epicsEventDestroy ( pClient->shutdownNotify );
|
||||
free (pClient);
|
||||
fprintf(stderr, "log client: unable to start log client connection watch dog thread\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* attempt to synchronize with circuit connect
|
||||
*/
|
||||
epicsTimeGetCurrent ( & begin );
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
do {
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
epicsEventWaitWithTimeout (
|
||||
pClient->stateChangeNotify,
|
||||
LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT / 10.0 );
|
||||
epicsTimeGetCurrent ( & current );
|
||||
diff = epicsTimeDiffInSeconds ( & current, & begin );
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
}
|
||||
while ( ! pClient->connected && diff < LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT );
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
|
||||
if ( ! pClient->connected ) {
|
||||
fprintf (stderr, "log client create: timed out synchronizing with circuit connect to \"%s\" after %.1f seconds\n",
|
||||
pClient->name, LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT );
|
||||
}
|
||||
|
||||
return (void *) pClient;
|
||||
}
|
||||
|
||||
@@ -516,9 +537,6 @@ logClientId epicsShareAPI logClientCreate (
|
||||
void epicsShareAPI logClientShow (logClientId id, unsigned level)
|
||||
{
|
||||
logClient *pClient = (logClient *) id;
|
||||
if ( ! pClient ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pClient->connected ) {
|
||||
printf ("log client: connected to log server at \"%s\"\n", pClient->name);
|
||||
@@ -532,46 +550,5 @@ void epicsShareAPI logClientShow (logClientId id, unsigned level)
|
||||
pClient->sock==INVALID_SOCKET?"INVALID":"OK",
|
||||
pClient->connectCount);
|
||||
}
|
||||
|
||||
if (logClientPrefix) {
|
||||
printf ("log client: prefix is \"%s\"\n", logClientPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* logClientSendMessage (); deprecated
|
||||
*/
|
||||
void logClientSendMessage ( logClientId id, const char * message )
|
||||
{
|
||||
if ( !iocLogDisable ) {
|
||||
logClientSend (id, message);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* iocLogPrefix()
|
||||
*/
|
||||
void epicsShareAPI iocLogPrefix(const char * prefix)
|
||||
{
|
||||
|
||||
/* If we have already established a log prefix, don't let the user change
|
||||
* it. The iocLogPrefix command is expected to be run from the IOC startup
|
||||
* script during initialization; the prefix can't be changed once it has
|
||||
* been set.
|
||||
*/
|
||||
|
||||
if (logClientPrefix) {
|
||||
printf ("iocLogPrefix: The prefix was already set to \"%s\" "
|
||||
"and can't be changed.\n", logClientPrefix);
|
||||
return;
|
||||
}
|
||||
|
||||
if (prefix) {
|
||||
unsigned prefixLen = strlen(prefix);
|
||||
if (prefixLen > 0) {
|
||||
char * localCopy = malloc(prefixLen+1);
|
||||
strcpy(localCopy, prefix);
|
||||
logClientPrefix = localCopy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ epicsShareFunc logClientId epicsShareAPI logClientCreate (
|
||||
epicsShareFunc void epicsShareAPI logClientSend (logClientId id, const char *message);
|
||||
epicsShareFunc void epicsShareAPI logClientShow (logClientId id, unsigned level);
|
||||
epicsShareFunc void epicsShareAPI logClientFlush (logClientId id);
|
||||
epicsShareFunc void epicsShareAPI iocLogPrefix(const char* prefix);
|
||||
|
||||
/* deprecated interface; retained for backward compatibility */
|
||||
/* note: implementations are in iocLog.c, not logClient.c */
|
||||
|
||||
@@ -558,186 +558,6 @@ 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
|
||||
*/
|
||||
@@ -749,10 +569,6 @@ 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 )
|
||||
@@ -872,7 +688,6 @@ 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