diff --git a/.gitignore b/.gitignore index ae1ac6fce91f08a9586b8b72b04ae78690ca23d7..397aa14418101e04e2e3dc245143c8a8888f352a 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ dkms.conf .#* \#* .cvsignore +.vscode \ No newline at end of file diff --git a/App/tools/driver.makefile b/App/tools/driver.makefile index b209b13bdf3b54693a3d3c68516e27b8bd3ebb88..c3412f8474f5a2de105684b99c100f5d5d29c1b4 100644 --- a/App/tools/driver.makefile +++ b/App/tools/driver.makefile @@ -71,6 +71,8 @@ USERMAKEFILE:=$(lastword $(filter-out $(lastword ${MAKEFILE_LIST}), ${MAKEFILE_L EPICS_LOCATION = ##---## In E3, we extract BASE_VERSION from EPICS_LOCATION E3_EPICS_VERSION:=$(patsubst base-%,%,$(notdir $(EPICS_LOCATION))) +E3_SITEMODS_PATH = +E3_SITEAPPS_PATH = BUILD_EPICS_VERSIONS = $(E3_EPICS_VERSION) ##---## @@ -104,6 +106,7 @@ REGISTRYFILE = ${PRJ}_registerRecordDeviceDriver.cpp EXPORTFILE = ${PRJ}_exportAddress.c SUBFUNCFILE = ${PRJ}_subRecordFunctions.dbd DEPFILE = ${PRJ}.dep +METAFILE = ${PRJ}_meta.yaml # Clear potential environment variables. TEMPLATES= @@ -159,6 +162,9 @@ MODULE= PROJECT= PRJDIR:=$(subst -,_,$(subst .,_,$(notdir $(patsubst %Lib,%,$(patsubst %/snl,%,$(patsubst %/src,%,${PWD})))))) PRJ = $(strip $(or ${MODULE},${PROJECT},${PRJDIR})) + +# To keep consistent between conda/nfs, we will force all modules to be lowercase. +PRJ := $(shell echo $(PRJ) | tr '[:upper:]' '[:lower:]') export PRJ OS_CLASS_LIST = $(BUILDCLASSES) @@ -168,6 +174,15 @@ export ARCH_FILTER export EXCLUDE_ARCHS export MAKE_FIRST +# Since we force modules to be in lowercase, we need to use the correct variables here +# e.g. MCoreUtils_E3_GIT_URL vs mcoreutils_E3_GIT_URL +${PRJ}_E3_GIT_URL := $(${PROJECT}_E3_GIT_URL) +export ${PRJ}_E3_GIT_URL +${PRJ}_E3_GIT_DESC := $(${PROJECT}_E3_GIT_DESC) +export ${PRJ}_E3_GIT_DESC +${PRJ}_E3_GIT_STATUS := $(${PROJECT}_E3_GIT_STATUS) +export ${PRJ}_E3_GIT_STATUS + # Some shell commands: RMDIR = rm -rf LN = ln -s @@ -222,7 +237,6 @@ debug:: # @echo "INSTALLED_EPICS_VERSIONS = ${INSTALLED_EPICS_VERSIONS}" @echo "BUILD_EPICS_VERSIONS = ${BUILD_EPICS_VERSIONS}" # @echo "MISSING_EPICS_VERSIONS = ${MISSING_EPICS_VERSIONS}" -# @echo "EPICS_VERSIONS_3.13 = ${EPICS_VERSIONS_3.13}" # @echo "EPICS_VERSIONS_3.14 = ${EPICS_VERSIONS_3.14}" @echo "EPICS_VERSIONS_3.15 = ${EPICS_VERSIONS_3.15}" @echo "BUILDCLASSES = ${BUILDCLASSES}" @@ -297,15 +311,6 @@ else # EPICSVERSION EPICS_BASE=${EPICS_LOCATION} #/base-${EPICSVERSION} -ifneq ($(filter 3.13.%,$(EPICSVERSION)),) - -EPICS_BASETYPE=3.13 -CONFIG=${EPICS_BASE}/config -export BUILD_TYPE=Vx - -else # 3.14+ - -EPICS_BASETYPE=3.14 CONFIG=${EPICS_BASE}/configure # There is no 64 bit support before 3.14.12 @@ -318,7 +323,6 @@ USR_LDFLAGS_$(EPICS_HOST_ARCH) += -m32 endif endif -endif # 3.14+ ${CONFIG}/CONFIG: @echo "ERROR: EPICS release ${EPICSVERSION} not installed on this host." @@ -355,12 +359,10 @@ ifndef T_A AUTOSRCS := $(filter-out ~%,$(wildcard *.c *.cc *.cpp *.st *.stt *.gt)) SRCS = $(if ${SOURCES},$(filter-out -none-,${SOURCES}),${AUTOSRCS}) -#SRCS += ${SOURCES_${EPICS_BASETYPE}} # added later by VAR_EXTENSIONS #SRCS += ${SOURCES_${EPICSVERSION}} export SRCS DBD_SRCS = $(if ${DBDS},$(filter-out -none-,${DBDS}),$(wildcard menu*.dbd *Record.dbd) $(strip $(filter-out %Include.dbd dbCommon.dbd %Record.dbd,$(wildcard *.dbd)) ${BPTS})) -DBD_SRCS += ${DBDS_${EPICS_BASETYPE}} DBD_SRCS += ${DBDS_${EPICSVERSION}} export DBD_SRCS @@ -378,17 +380,17 @@ BPTS = $(patsubst %.data,%.dbd,$(wildcard bpt*.data)) export BPTS HDRS = ${HEADERS} $(addprefix ${COMMON_DIR}/,$(addsuffix Record.h,${RECORDS})) -HDRS += ${HEADERS_${EPICS_BASETYPE}} HDRS += ${HEADERS_${EPICSVERSION}} export HDRS +HDR_SUBDIRS = $(KEEP_HEADER_SUBDIRS) +export HDR_SUBDIRS + TEMPLS = $(if ${TEMPLATES},$(filter-out -none-,${TEMPLATES}),$(wildcard *.template *.db *.subs)) -TEMPLS += ${TEMPLATES_${EPICS_BASETYPE}} TEMPLS += ${TEMPLATES_${EPICSVERSION}} export TEMPLS SCR = $(if ${SCRIPTS},$(filter-out -none-,${SCRIPTS}),$(wildcard *.cmd *.iocsh)) -SCR += ${SCRIPTS_${EPICS_BASETYPE}} SCR += ${SCRIPTS_${EPICSVERSION}} export SCR @@ -397,12 +399,9 @@ DOCUDIR = . export DOCU # Loop over all target architectures for third run. -# Go to O.${T_A} subdirectory because RULES.Vx only work there: # Filter architectures to build using EXCLUDE_ARCHS and ARCH_FILTER. -ifneq (${EPICS_BASETYPE},3.13) CROSS_COMPILER_TARGET_ARCHS := ${EPICS_HOST_ARCH} ${CROSS_COMPILER_TARGET_ARCHS} -endif # !3.13 CROSS_COMPILER_TARGET_ARCHS := $(filter-out $(addprefix %,${EXCLUDE_ARCHS}),$(filter-out $(addsuffix %,${EXCLUDE_ARCHS}),$(if ${ARCH_FILTER},$(filter ${ARCH_FILTER},${CROSS_COMPILER_TARGET_ARCHS}),${CROSS_COMPILER_TARGET_ARCHS}))) # Create build dirs (and links) if necessary. @@ -415,13 +414,7 @@ endef $(foreach a,${CROSS_COMPILER_TARGET_ARCHS},$(foreach l,$(LINK_$a),$(eval $(call MAKELINKDIRS,$l,$a)))) SRCS_Linux = ${SOURCES_Linux} -SRCS_Linux += ${SOURCES_${EPICS_BASETYPE}_Linux} -SRCS_Linux += ${SOURCES_Linux_${EPICS_BASETYPE}} export SRCS_Linux -SRCS_vxWorks = ${SOURCES_vxWorks} -SRCS_vxWorks += ${SOURCES_${EPICS_BASETYPE}_vxWorks} -SRCS_vxWorks += ${SOURCES_vxWorks_${EPICS_BASETYPE}} -export SRCS_vxWorks install build debug:: $(MAKE_FIRST) @echo "MAKING EPICS VERSION ${EPICSVERSION}" @@ -432,7 +425,6 @@ uninstall:: debug:: @echo "EPICS_BASE = ${EPICS_BASE}" @echo "EPICSVERSION = ${EPICSVERSION}" - @echo "EPICS_BASETYPE = ${EPICS_BASETYPE}" @echo "CROSS_COMPILER_TARGET_ARCHS = ${CROSS_COMPILER_TARGET_ARCHS}" @echo "EXCLUDE_ARCHS = ${EXCLUDE_ARCHS}" @echo "LIBVERSION = ${LIBVERSION}" @@ -495,9 +487,9 @@ install build debug:: O.${EPICSVERSION}_Common O.${EPICSVERSION}_${T_A} endif -# Add sources for specific epics types (3.13 or 3.14) or architectures. +# Add sources for specific epics types or architectures. ARCH_PARTS = ${T_A} $(subst -, ,${T_A}) ${OS_CLASS} -VAR_EXTENSIONS = ${EPICS_BASETYPE} ${EPICSVERSION} ${ARCH_PARTS} ${ARCH_PARTS:%=${EPICS_BASETYPE}_%} ${ARCH_PARTS:%=${EPICSVERSION}_%} +VAR_EXTENSIONS = ${EPICSVERSION} ${ARCH_PARTS} ${ARCH_PARTS:%=${EPICSVERSION}_%} export VAR_EXTENSIONS REQ = ${REQUIRED} $(foreach x, ${VAR_EXTENSIONS}, ${REQUIRED_$x}) @@ -512,21 +504,27 @@ export BINS export CFG +# These variables are written into a .yaml file in the installed module directory to keep track of +# metadata for which module was compiled. + +${PRJ}_GIT_DESC := $(shell git describe --tags 2> /dev/null || git rev-parse HEAD) +export ${PRJ}_GIT_DESC +# The formatting here is just to make sure this is properly parseable .yaml data +${PRJ}_GIT_STATUS := [ $(shell git status --porcelain | grep -v "\.Makefile" | sed 's/^/\\\"/' | sed 's/$$/\\\", /')] +export ${PRJ}_GIT_STATUS + else # in O.* ## RUN 4 # In O.* directory. -# Add macros like USR_CFLAGS_vxWorks. +# Add macros like USR_CFLAGS_Linux. EXTENDED_VARS=INCLUDES CFLAGS CXXFLAGS CPPFLAGS CODE_CXXFLAGS LDFLAGS $(foreach v,${EXTENDED_VARS},$(foreach x,${VAR_EXTENSIONS},$(eval $v+=$${$v_$x}) $(eval USR_$v+=$${USR_$v_$x}))) CFLAGS += ${EXTRA_CFLAGS} -COMMON_DIR_3.14 = ../O.${EPICSVERSION}_Common -COMMON_DIR_3.13 = . -COMMON_DIR = ${COMMON_DIR_${EPICS_BASETYPE}} +COMMON_DIR = ../O.${EPICSVERSION}_Common # Remove include directory for this module from search path. -# 3.13 and 3.14 use different variables INSTALL_INCLUDES = EPICS_INCLUDES = @@ -545,11 +543,18 @@ EPICS_INCLUDES = # endef # $(eval $(foreach m,$(filter-out $(PRJ),$(notdir $(wildcard ${EPICS_MODULES}/*))),$(call ADD_FOREIGN_INCLUDES,$m))) -define ADD_OTHER_MODULE_INCLUDES -$(eval $(1)_VERSION := $(patsubst ${EPICS_MODULES}/$(1)/%/include,%,$(firstword $(shell ls -dvr ${EPICS_MODULES}/$(1)/+([0-9]).+([0-9]).+([0-9])/include 2>/dev/null)))) -INSTALL_INCLUDES += $$(patsubst %,-I${EPICS_MODULES}/$(1)/%/include,$$($(1)_VERSION)) +define ADD_SITEMODS_INCLUDES +$(eval $(1)_VERSION := $(patsubst ${E3_SITEMODS_PATH}/$(1)/%/include,%,$(firstword $(shell ls -dvr ${E3_SITEMODS_PATH}/$(1)/+([0-9]).+([0-9]).+([0-9])/include 2>/dev/null)))) +INSTALL_INCLUDES += $$(patsubst %,-I${E3_SITEMODS_PATH}/$(1)/%/include,$$($(1)_VERSION)) endef -$(eval $(foreach m,$(filter-out $(PRJ),$(notdir $(wildcard ${EPICS_MODULES}/*))),$(call ADD_OTHER_MODULE_INCLUDES,$m))) +$(eval $(foreach m,$(filter-out $(PRJ),$(notdir $(wildcard ${E3_SITEMODS_PATH}/*))),$(call ADD_SITEMODS_INCLUDES,$m))) + +define ADD_SITEAPPS_INCLUDES +$(eval $(1)_VERSION := $(patsubst ${E3_SITEAPPS_PATH}/$(1)/%/include,%,$(firstword $(shell ls -dvr ${E3_SITEAPPS_PATH}/$(1)/+([0-9]).+([0-9]).+([0-9])/include 2>/dev/null)))) +INSTALL_INCLUDES += $$(patsubst %,-I${E3_SITEAPPS_PATH}/$(1)/%/include,$$($(1)_VERSION)) +endef +$(eval $(foreach m,$(filter-out $(PRJ),$(notdir $(wildcard ${E3_SITEAPPS_PATH}/*))),$(call ADD_SITEAPPS_INCLUDES,$m))) + ifneq ($(wildcard ${MAKEHOME}/getPrerequisites.tcl),) @@ -564,16 +569,9 @@ $(eval $(1)_VERSION := $(or $(patsubst ${EPICS_MODULES}/$(1)/%/,%,$(firstword $( endef $(eval $(foreach m,${REQ},$(call ADD_MANUAL_DEPENDENCIES,$m))) -# EPICS 3.13 uses :: in some rules where 3.14 uses : -ifeq (${EPICS_BASETYPE},3.13) -INSTALLRULE=install:: -BUILDRULE=build:: -BASERULES=${EPICS_BASE}/config/RULES.Vx -else # 3.14 INSTALLRULE=install: BUILDRULE=build: BASERULES=${EPICS_BASE}/configure/RULES -endif # 3.14 INSTALL_REV = ${MODULE_LOCATION} INSTALL_BIN = ${INSTALL_REV}/bin/$(T_A) @@ -608,45 +606,12 @@ INSTALL_SCR = ${INSTALL_REV} # chmod 444 $@ # $(SETLINKS) ${INSTALL_TEMPL} .db $(basename $(notdir $^)) -# Different settings required to build library in EPICS 3.13 and 3.14. -ifeq (${EPICS_BASETYPE},3.13) # only 3.13 from here - -# Convert sources to object code, skip .a and .o here. -LIBOBJS += $(patsubst %,%.o,$(notdir $(basename $(filter-out %.o %.a,${SRCS})))) -# Add all .a and .o with absolute path. -LIBOBJS += $(filter /%.o /%.a,${SRCS}) -# Add all .a and .o with relative path, but go one directory up. -LIBOBJS += $(patsubst %,../%,$(filter-out /%,$(filter %.o %.a,${SRCS}))) -LIBOBJS += ${LIBRARIES:%=${INSTALL_LIB}/%Lib} -LIBOBJS += $(foreach l,${USR_LIBOBJS}, $(addprefix ../,$(filter-out /%,$l)) $(filter /%,$l)) - -LIBNAME = $(if $(strip ${LIBOBJS}),${PRJ}Lib,) # Must be the un-munched name. -MODULELIB = ${LIBNAME:%=%.munch} -PROD = ${MODULELIB} - -# Add munched library for C++ code (does not work for Tornado 1). -#ifneq ($(filter %.cc %.cpp %.C,${SRCS}),) -#ifeq ($(filter T1-%,${T_A}),) -#PROD = ${MODULELIB}.munch -#endif # T1- T_A -#endif # .cc or .cpp found - -else # Only 3.14 from here. - LIBRARY_OBJS = $(strip ${LIBOBJS} $(foreach l,${USR_LIBOBJS},$(addprefix ../,$(filter-out /%,$l))$(filter /%,$l))) -ifeq (${OS_CLASS},vxWorks) -# Only install the munched library. -INSTALL_PROD= -MODULELIB = $(if ${LIBRARY_OBJS},${PRJ}Lib.munch,) -else MODULELIB = $(if ${LIBRARY_OBJS},${LIB_PREFIX}${PRJ}${SHRLIB_SUFFIX},) -endif -# vxWorks -PROD_vxWorks=${MODULELIB} -LIBOBJS += $(addsuffix $(OBJ),$(notdir $(basename $(filter-out %.$(OBJ) %(LIB_SUFFIX),$(sort ${SRCS}))))) -LIBOBJS += $(filter /%.$(OBJ) /%(LIB_SUFFIX),${SRCS}) +LIBOBJS += $(addsuffix $(OBJ),$(notdir $(basename $(filter-out %.$(OBJ) %$(LIB_SUFFIX),$(sort ${SRCS}))))) +LIBOBJS += $(filter /%.$(OBJ) /%$(LIB_SUFFIX),${SRCS}) LIBOBJS += ${LIBRARIES:%=${INSTALL_LIB}/%Lib} LIBS = -L ${EPICS_BASE_LIB} ${BASELIBS:%=-l%} LINK.cpp += ${LIBS} @@ -655,18 +620,10 @@ PRODUCT_OBJS = ${LIBRARY_OBJS} # Linux LOADABLE_LIBRARY=$(if ${LIBRARY_OBJS},${PRJ},) -# Hack needed needed for 3.14.8 host arch when no Makefile exists (but only for example GNUmakefile). -ifeq (${EPICSVERSION}-${T_A},3.14.8-${EPICS_HOST_ARCH}) -ifeq ($(wildcard ../Makefile),) -LOADABLE_BUILD_LIBRARY = ${LOADABLE_LIBRARY} -endif -endif - # Handle registry stuff automagically if we have a dbd file. # See ${REGISTRYFILE} and ${EXPORTFILE} rules below. LIBOBJS += $(if $(MODULEDBD), $(addsuffix $(OBJ),$(basename ${REGISTRYFILE} ${EXPORTFILE}))) -endif # Both, 3.13 and 3.14 from here. # For backward compatibility: # Provide a global symbol for every version with the same @@ -681,9 +638,6 @@ PATCH=$(word 3,${MAJOR_MINOR_PATCH}) ifneq (${MINOR},) ALLMINORS := $(shell for ((i=0;i<=${MINOR};i++));do echo $$i;done) PREREQUISITES = $(shell ${MAKEHOME}/getPrerequisites.tcl ${INSTALL_INCLUDE} | grep -vw ${PRJ}) -ifeq (${OS_CLASS}, vxWorks) -PROVIDES = ${ALLMINORS:%=--defsym __${PRJ}Lib_${MAJOR}.%=0} -endif # vxWorks ifeq (${OS_CLASS}, Linux) PROVIDES = ${ALLMINORS:%=-Wl,--defsym,${PRJ}Lib_${MAJOR}.%=0} endif # Linux @@ -714,15 +668,6 @@ SRC_INCLUDES = $(addprefix -I, $(wildcard $(foreach d,$(call uniq, $(filter-out # Different macro name for 3.14.8. GENERIC_SRC_INCLUDES = $(SRC_INCLUDES) -ifeq (${EPICS_BASETYPE},3.13) -# Only 3.13 from here. - -# Different macro name for 3.13 -USR_INCLUDES += $(SRC_INCLUDES) $(INSTALL_INCLUDES) - -else -# Only 3.14 from here. - # Create dbd file for snl code. DBDFILES += $(patsubst %.st,%_snl.dbd,$(notdir $(filter %.st,${SRCS}))) DBDFILES += $(patsubst %.stt,%_snl.dbd,$(notdir $(filter %.stt,${SRCS}))) @@ -745,12 +690,10 @@ DBDFILES += $(patsubst %.gt,%.dbd,$(notdir $(filter %.gt,${SRCS}))) # snc location in 3.14: From latest version of module seq or fall back to globally installed snc. #SNC=$(lastword $(dir ${EPICS_BASE})seq/bin/$(EPICS_HOST_ARCH)/snc $(shell ls -dv ${EPICS_MODULES}/seq/$(or $(seq_VERSION),+([0-9]).+([0-9]).+([0-9]))/bin/${EPICS_HOST_ARCH}/snc 2>/dev/null)) -SNCALL=$(shell ls -dv $(EPICS_MODULES)/sequencer/$(sequencer_VERSION)/bin/$(EPICS_HOST_ARCH) 2> /dev/null) +SNCALL=$(shell ls -dv $(E3_SITEMODS_PATH)/sequencer/$(sequencer_VERSION)/bin/$(EPICS_HOST_ARCH) 2> /dev/null) SNC=$(lastword $(SNCALL))/snc -endif # 3.14 - ifneq ($(strip ${DBDFILES}),) MODULEDBD=${PRJ}.dbd endif @@ -770,12 +713,10 @@ debug:: @echo "BPTS = ${BPTS}" @echo "HDRS = ${HDRS}" @echo "SOURCES = ${SOURCES}" - @echo "SOURCES_${EPICS_BASETYPE} = ${SOURCES_${EPICS_BASETYPE}}" @echo "SOURCES_${OS_CLASS} = ${SOURCES_${OS_CLASS}}" @echo "SRCS = ${SRCS}" @echo "LIBOBJS = ${LIBOBJS}" @echo "DBDS = ${DBDS}" - @echo "DBDS_${EPICS_BASETYPE} = ${DBDS_${EPICS_BASETYPE}}" @echo "DBDS_${OS_CLASS} = ${DBDS_${OS_CLASS}}" @echo "DBD_SRCS = ${DBD_SRCS}" @echo "DBDFILES = ${DBDFILES}" @@ -821,7 +762,7 @@ vpath %.hh $(addprefix ../,$(sort $(dir $(filter-out /%,${HDRS}) ${SRCS}))) $(so vpath %.hxx $(addprefix ../,$(sort $(dir $(filter-out /%,${HDRS}) ${SRCS}))) $(sort $(dir $(filter /%,${HDRS}))) -PRODUCTS = ${MODULELIB} ${MODULEDBD} ${DEPFILE} +PRODUCTS = ${MODULELIB} ${MODULEDBD} ${DEPFILE} ${METAFILE} MODULEINFOS: @echo ${PRJ} > MODULENAME @echo $(realpath ${EPICS_MODULES}) > INSTBASE @@ -838,6 +779,7 @@ ${MODULEDBD}: ${DBDFILES} # Install everything. INSTALL_LIBS = ${MODULELIB:%=${INSTALL_LIB}/%} INSTALL_DEPS = ${DEPFILE:%=${INSTALL_LIB}/%} +INSTALL_META = ${METAFILE:%=${INSTALL_REV}/%} INSTALL_DBDS = ${MODULEDBD:%=${INSTALL_DBD}/%} INSTALL_HDRS = $(addprefix ${INSTALL_INCLUDE}/,$(notdir ${HDRS})) INSTALL_DBS = $(addprefix ${INSTALL_DB}/,$(notdir ${TEMPLS})) @@ -849,6 +791,7 @@ debug:: @echo "INSTALL_LIB = $(INSTALL_LIB)" @echo "INSTALL_LIBS = $(INSTALL_LIBS)" @echo "INSTALL_DEPS = $(INSTALL_DEPS)" + @echo "INSTALL_META = $(INSTALL_META)" @echo "INSTALL_DBD = $(INSTALL_DBD)" @echo "INSTALL_DBDS = $(INSTALL_DBDS)" @echo "INSTALL_INCLUDE = $(INSTALL_INCLUDE)" @@ -861,8 +804,18 @@ debug:: @echo "INSTALL_CFGS = $(INSTALL_CFGS)" @echo "INSTALL_BIN = $(INSTALL_BIN)" @echo "INSTALL_BINS = $(INSTALL_BINS)" + @echo "HDR_SUBDIRS = $(HDR_SUBDIRS)" -INSTALLS += ${INSTALL_CFGS} ${INSTALL_SCRS} ${INSTALL_HDRS} ${INSTALL_DBDS} ${INSTALL_DBS} ${INSTALL_LIBS} ${INSTALL_BINS} ${INSTALL_DEPS} +define install_subdirs +$1_HDRS = $$(filter $1/%,$$(HDRS)) +INSTALL_HDRS += $$(addprefix $$(INSTALL_INCLUDE)/,$$($1_HDRS:$1/%=%)) +vpath %h ../$1 +debug:: + @echo "$1_HDRS = $$($1_HDRS)" +endef +$(foreach d,$(HDR_SUBDIRS),$(eval $(call install_subdirs,$d))) + +INSTALLS += ${INSTALL_CFGS} ${INSTALL_SCRS} ${INSTALL_HDRS} ${INSTALL_DBDS} ${INSTALL_DBS} ${INSTALL_LIBS} ${INSTALL_BINS} ${INSTALL_DEPS} ${INSTALL_META} ${INSTALLRULE} ${INSTALLS} @@ -878,28 +831,13 @@ ${INSTALL_DEPS}: $(notdir ${INSTALL_DEPS}) @echo "Installing module dependency file $@" $(INSTALL) -d -m444 $< $(@D) -# Fix templates for older EPICS versions: -# Remove 'alias' for EPICS <= 3.14.10 -# and 'info' and macro defaults for EPICS 3.13. -# Make use of differences in defined variables. -ifeq ($(DEP),.d) -# 3.14.10+ +${INSTALL_META}: $(notdir ${INSTALL_META}) + @echo "Installing metadata file $@" + $(INSTALL) -d -m444 $< $(@D) + ${INSTALL_DBS}: $(notdir ${INSTALL_DBS}) @echo "Installing module template files $^ to $(@D)" $(INSTALL) -d -m444 $^ $(@D) -else ifeq (${EPICS_BASETYPE},3.13) -# 3.13 -${INSTALL_DBS}: $(notdir ${INSTALL_DBS}) - @echo "Installing module template files $^ to $(@D)" - mkdir -p -m 775 $(@D) - for i in $^; do sed -r 's/\$$\{([^={]*)=[^}]*\}/$${\1}/g;s/\$$\(([^=(]*)=[^)]*\)/$$(\1)/g;s/(^|\))[ \t]*(alias|info)[ \t]*\(/#&/g' $$i > $(@D)/$$(basename $$i); done -else -# 3.14.9- -${INSTALL_DBS}: $(notdir ${INSTALL_DBS}) - @echo "Installing module template files $^ to $(@D)" - mkdir -p -m 775 $(@D) - for i in $^; do sed -r 's/(^|\))[ \t]*alias[ \t]*/#&/g' $$i > $(@D)/$$(basename $$i); done -endif ${INSTALL_SCRS}: $(notdir ${SCR}) @echo "Installing scripts $^ to $(@D)" @@ -914,7 +852,6 @@ ${INSTALL_BINS}: $(addprefix ../,$(filter-out /%,${BINS})) $(filter /%,${BINS}) $(INSTALL) -d -m555 $^ $(@D) # Create SNL code from st/stt file. -# (RULES.Vx only allows ../%.st, 3.14 has no .st rules at all.) # Important to have %.o: %.st and %.o: %.stt rule before %.o: %.c rule! # Preprocess in any case because docu and implemented EPICS rules mismatch here. @@ -924,7 +861,7 @@ CPPSNCFLAGS1 += -I $(dir $(SNC))../../include SNCFLAGS += -r -# 1) ESS uses 3.15.5 as the minimal EPICS BASE, so we don't need to check 3.13, +# 1) ESS uses 7.0.3.1 as the minimal EPICS BASE, so we don't need to check 3.13, # 2) We also need -c option in $(COMPILE.c) in order to compile generated source file properly # 3) SNC (2.1.21) should use -o, because without them, snc returns $(*F).i.c instead of $(*F).c # With the EPICS standard building rule, -o and mv are used. @@ -1010,7 +947,6 @@ ${REGISTRYFILE}: ${MODULEDBD} # 3.14.12 complains if this rule is not overwritten ./%Include.dbd: -# For 3.13 code used with 3.14+: # Add missing epicsExportAddress() calls for registry. define makexportfile @@ -1042,11 +978,7 @@ END {for (name in func_missing) if (!func_found[name]) { \ endef CORELIB = ${CORELIB_${OS_CLASS}} -CORELIB_vxWorks = $(firstword $(wildcard ${EPICS_BASE}/bin/${T_A}/softIoc.munch ${EPICS_BASE}/bin/${T_A}/iocCoreLibrary.munch)) -ifeq (${OS_CLASS},vxWorks) -SHARED_LIBRARIES=NO -endif LSUFFIX_YES=$(SHRLIB_SUFFIX) LSUFFIX_NO=$(LIB_SUFFIX) LSUFFIX=$(LSUFFIX_$(SHARED_LIBRARIES)) @@ -1055,13 +987,21 @@ ${EXPORTFILE}: $(filter-out $(basename ${EXPORTFILE})$(OBJ),${LIBOBJS}) $(RM) $@ $(NM) $^ ${BASELIBS:%=${EPICS_BASE}/lib/${T_A}/${LIB_PREFIX}%$(LSUFFIX)} ${CORELIB} | awk '$(makexportfile)' > $@ + +${METAFILE}: + @echo "wrapper_url: '$(${PRJ}_E3_GIT_URL)'" > $@ + @echo "wrapper_git_desc: '$(${PRJ}_E3_GIT_DESC)'" >> $@ + @echo "wrapper_diffs: $(${PRJ}_E3_GIT_STATUS)" >> $@ + @echo "module_git_desc: '$(${PRJ}_GIT_DESC)'" >> $@ + @echo "module_diffs: $(${PRJ}_GIT_STATUS)" >> $@ + # Create dependency file for recursive requires. ${DEPFILE}: ${LIBOBJS} $(USERMAKEFILE) @echo "Collecting dependencies" $(RM) $@ @echo "# Generated file. Do not edit." > $@ # Check dependencies on other module headers. - cat *.d 2>/dev/null | sed 's/ /\n/g' | sed -n 's%$(EPICS_MODULES)/*\([^/]*\)/\([0-9]*\.[0-9]*\.[0-9]*\)/.*%\1 \2%p;s%$(EPICS_MODULES)/*\([^/]*\)/\([^/]*\)/.*%\1 \2%p'| grep -v "include" | sort -u >> $@ + cat *.d 2>/dev/null | sed 's/ /\n/g' | sed -n 's%$(E3_SITEMODS_PATH)/*\([^/]*\)/\([0-9]*\.[0-9]*\.[0-9]*\)/.*%\1 \2%p;s%$(E3_SITEMODS_PATH)/*\([^/]*\)/\([^/]*\)/.*%\1 \2%p;s%$(E3_SITEAPPS_PATH)/*\([^/]*\)/\([0-9]*\.[0-9]*\.[0-9]*\)/.*%\1 \2%p;s%$(E3_SITEAPPS_PATH)/*\([^/]*\)/\([^/]*\)/.*%\1 \2%p;s%$(EPICS_MODULES)/*\([^/]*\)/\([0-9]*\.[0-9]*\.[0-9]*\)/.*%\1 \2%p;s%$(EPICS_MODULES)/*\([^/]*\)/\([^/]*\)/.*%\1 \2%p'| grep -v "include" | sort -u >> $@ ifneq ($(strip ${REQ}),) # Manully added dependencies: ${REQ} @$(foreach m,${REQ},echo "$m $(or ${$m_VERSION},$(and $(wildcard ${EPICS_MODULES}/$m),$(error REQUIRED module $m has no numbered version. Set $m_VERSION)),$(warning REQUIRED module $m not found for ${T_A}.))" >> $@;) @@ -1110,4 +1050,8 @@ endif # EPICSVERSION defined ## ## Monday, September 9 15:25:53 CEST 2019 : Revert E3_SITEMODS_PATH from E3_SITELIBS_PATH in the snc path ## -## Tuesday, June 30 2020 : Combine NFS E3 driver.makefile with conda version \ No newline at end of file +## Tuesday, June 30 2020 : Combine NFS E3 driver.makefile with conda version +## +## Friday, July 3 2020 : Force all module names to be lowercase, to allow consistency between conda/nfs startup scripts. +## +## $(DATE) : Removed the V3-specific code. Added metadata file. \ No newline at end of file diff --git a/require.c b/require.c index ee28028c29c2092f48c79662a7bd1666be63cddf..3d9d7af849749e102d3a729d18a9386faea5a3fe 100644 --- a/require.c +++ b/require.c @@ -29,22 +29,6 @@ #include <osiFileName.h> #include <epicsVersion.h> - - -#ifdef BASE_VERSION -#define EPICS_3_13 - -#define epicsGetStdout() stdout -extern int dbLoadDatabase(const char *filename, const char *path, const char *substitutions); -int dbLoadRecords(const char *filename, const char *substitutions) -{ - /* This implementation uses EPICS_DB_INCLUDE_PATH */ - return dbLoadDatabase(filename, NULL, substitutions); -} -extern volatile int interruptAccept; - -#else /* 3.14+ */ - #include <iocsh.h> #include <dbAccess.h> /* This prototype is missing in older EPICS versions */ @@ -54,220 +38,235 @@ epicsShareFunc int epicsShareAPI iocshCmd(const char *cmd); #include <osiFileName.h> #include <epicsExport.h> -#endif - #include "require.h" int requireDebug; #if defined(vxWorks) - #ifndef OS_CLASS - #define OS_CLASS "vxWorks" - #endif - - #include <symLib.h> - #include <sysSymTbl.h> - #include <loadLib.h> - #include <shellLib.h> - #include <ioLib.h> - #include <fioLib.h> - #include <envLib.h> - #include <epicsAssert.h> - #include "strdup.h" - #include "asprintf.h" - - #define HMODULE MODULE_ID - #define PREFIX - #define INFIX "Lib" - #define EXT ".munch" - - #define getAddress(module, name) __extension__ \ - ({SYM_TYPE t; char* a = NULL; symFindByName(sysSymTbl, (name), &a, &t); a;}) +#ifndef OS_CLASS +#define OS_CLASS "vxWorks" +#endif + +#include <symLib.h> +#include <sysSymTbl.h> +#include <loadLib.h> +#include <shellLib.h> +#include <ioLib.h> +#include <fioLib.h> +#include <envLib.h> +#include <epicsAssert.h> +#include "strdup.h" +#include "asprintf.h" + +#define HMODULE MODULE_ID +#define PREFIX +#define INFIX "Lib" +#define EXT ".munch" + +#define getAddress(module, name) __extension__({SYM_TYPE t; char* a = NULL; symFindByName(sysSymTbl, (name), &a, &t); a; }) #ifndef _WRS_VXWORKS_MAJOR - /* vxWorks 5 has no snprintf() */ - struct outStr_s { - char *str; - int free; - }; - - static STATUS outRoutine(char *buffer, int nchars, int outarg) { - struct outStr_s *poutStr = (struct outStr_s *) outarg; - int free = poutStr->free; - - if (free < 1) { /*let fioFormatV continue to count length*/ - return OK; - } else if (free > 1) { - if (nchars >= free) nchars = free-1; - strncpy(poutStr->str, buffer, nchars); - poutStr->str += nchars; - poutStr->free -= nchars; - } - /*make sure final string is null terminated*/ - *poutStr->str = 0; +/* vxWorks 5 has no snprintf() */ +struct outStr_s +{ + char *str; + int free; +}; + +static STATUS outRoutine(char *buffer, int nchars, int outarg) +{ + struct outStr_s *poutStr = (struct outStr_s *)outarg; + int free = poutStr->free; + + if (free < 1) + { /*let fioFormatV continue to count length*/ return OK; } - - static int snprintf(char *str, size_t size, const char *format, ...) + else if (free > 1) { - struct outStr_s outStr; - int nchars; - va_list ap; - - outStr.str = str; - outStr.free = size; - va_start(ap, format); - nchars = fioFormatV(format, ap, outRoutine, (int)&outStr); - va_end(ap); - return nchars; + if (nchars >= free) + nchars = free - 1; + strncpy(poutStr->str, buffer, nchars); + poutStr->str += nchars; + poutStr->free -= nchars; } + /*make sure final string is null terminated*/ + *poutStr->str = 0; + return OK; +} + +static int snprintf(char *str, size_t size, const char *format, ...) +{ + struct outStr_s outStr; + int nchars; + va_list ap; + + outStr.str = str; + outStr.free = size; + va_start(ap, format); + nchars = fioFormatV(format, ap, outRoutine, (int)&outStr); + va_end(ap); + return nchars; +} #endif - /* vxWorks has no realpath() -- at least make directory absolute */ - static char* realpath(const char* path, char* buf) +/* vxWorks has no realpath() -- at least make directory absolute */ +static char *realpath(const char *path, char *buf) +{ + size_t len = 0; + if (!buf) + buf = malloc(PATH_MAX + 1); + if (!buf) + return NULL; + if (path[0] != OSI_PATH_SEPARATOR[0]) { - size_t len = 0; - if (!buf) buf = malloc(PATH_MAX+1); - if (!buf) return NULL; - if (path[0] != OSI_PATH_SEPARATOR[0]) - { - getcwd(buf, PATH_MAX); - len = strlen(buf); - if (len && buf[len-1] != OSI_PATH_SEPARATOR[0]) - buf[len++] = OSI_PATH_SEPARATOR[0]; - } - strcpy(buf+len, path); - return buf; + getcwd(buf, PATH_MAX); + len = strlen(buf); + if (len && buf[len - 1] != OSI_PATH_SEPARATOR[0]) + buf[len++] = OSI_PATH_SEPARATOR[0]; } + strcpy(buf + len, path); + return buf; +} #elif defined(__unix) - #ifndef OS_CLASS - #ifdef __linux - #define OS_CLASS "Linux" - #endif - - #ifdef SOLARIS - #define OS_CLASS "solaris" - #endif - - #ifdef __rtems__ - #define OS_CLASS "RTEMS" - #endif - - #ifdef CYGWIN32 - #define OS_CLASS "cygwin32" - #endif - - #ifdef freebsd - #define OS_CLASS "freebsd" - #endif - - #ifdef darwin - #define OS_CLASS "Darwin" - #endif - - #ifdef _AIX32 - #define OS_CLASS "AIX" - #endif - #endif - - #include <dlfcn.h> - #define HMODULE void * - - #define getAddress(module, name) dlsym(module, name) - - #ifdef CYGWIN32 - #define PREFIX - #define INFIX - #define EXT ".dll" - #else - #define PREFIX "lib" - #define INFIX - #define EXT ".so" - #endif - -#elif defined (_WIN32) - - #ifndef OS_CLASS - #define OS_CLASS "WIN32" - #endif - - #include <windows.h> - #include <Psapi.h> - #pragma comment(lib, "kernel32.lib") - #pragma comment(lib, "psapi.lib") - #include "asprintf.h" - #define snprintf _snprintf - #define setenv(name,value,overwrite) _putenv_s(name,value) - #define PATH_MAX MAX_PATH - - #define PREFIX - #define INFIX - #define EXT ".dll" - - #define getAddress(module, name) GetProcAddress(module, name) - - static char* realpath(const char* path, char* buffer) +#ifndef OS_CLASS +#ifdef __linux +#define OS_CLASS "Linux" +#endif + +#ifdef SOLARIS +#define OS_CLASS "solaris" +#endif + +#ifdef __rtems__ +#define OS_CLASS "RTEMS" +#endif + +#ifdef CYGWIN32 +#define OS_CLASS "cygwin32" +#endif + +#ifdef freebsd +#define OS_CLASS "freebsd" +#endif + +#ifdef darwin +#define OS_CLASS "Darwin" +#endif + +#ifdef _AIX32 +#define OS_CLASS "AIX" +#endif +#endif + +#include <dlfcn.h> +#define HMODULE void * + +#define getAddress(module, name) dlsym(module, name) + +#ifdef CYGWIN32 +#define PREFIX +#define INFIX +#define EXT ".dll" +#else +#define PREFIX "lib" +#define INFIX +#define EXT ".so" +#endif + +#elif defined(_WIN32) + +#ifndef OS_CLASS +#define OS_CLASS "WIN32" +#endif + +#include <windows.h> +#include <Psapi.h> +#pragma comment(lib, "kernel32.lib") +#pragma comment(lib, "psapi.lib") +#include "asprintf.h" +#define snprintf _snprintf +#define setenv(name, value, overwrite) _putenv_s(name, value) +#define PATH_MAX MAX_PATH + +#define PREFIX +#define INFIX +#define EXT ".dll" + +#define getAddress(module, name) GetProcAddress(module, name) + +static char *realpath(const char *path, char *buffer) +{ + int len = MAX_PATH; + if (buffer == NULL) { - int len = MAX_PATH; + len = GetFullPathName(path, 0, NULL, NULL); + if (len == 0) + return NULL; + buffer = malloc(len); if (buffer == NULL) - { - len = GetFullPathName(path, 0, NULL, NULL); - if (len == 0) return NULL; - buffer = malloc(len); - if (buffer == NULL) return NULL; - } - GetFullPathName(path, len, buffer, NULL); - return buffer; + return NULL; } - + GetFullPathName(path, len, buffer, NULL); + return buffer; +} + #else - #warning unknown OS - #define PREFIX - #define INFIX - #define EXT - #define getAddress(module, name) NULL +#warning unknown OS +#define PREFIX +#define INFIX +#define EXT +#define getAddress(module, name) NULL #endif /* for readdir: Windows or Posix */ #if defined(_WIN32) - #define DIR_HANDLE HANDLE - #define DIR_ENTRY WIN32_FIND_DATA - #define IF_OPEN_DIR(f) if(snprintf(f+modulediroffs, sizeof(f)-modulediroffs, "\\*.*"), (dir=FindFirstFile(filename, &direntry)) != INVALID_HANDLE_VALUE || (FindClose(dir), 0)) - #define START_DIR_LOOP do - #define END_DIR_LOOP while(FindNextFile(dir,&direntry)); FindClose(dir); - #define SKIP_NON_DIR(e) if (!(e.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || (e.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) continue; - #define FILENAME(e) e.cFileName +#define DIR_HANDLE HANDLE +#define DIR_ENTRY WIN32_FIND_DATA +#define IF_OPEN_DIR(f) if (snprintf(f + modulediroffs, sizeof(f) - modulediroffs, "\\*.*"), (dir = FindFirstFile(filename, &direntry)) != INVALID_HANDLE_VALUE || (FindClose(dir), 0)) +#define START_DIR_LOOP do +#define END_DIR_LOOP \ + while (FindNextFile(dir, &direntry)) \ + ; \ + FindClose(dir); +#define SKIP_NON_DIR(e) \ + if (!(e.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || (e.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) \ + continue; +#define FILENAME(e) e.cFileName #else - #include <dirent.h> - #define DIR_HANDLE DIR* - #define IF_OPEN_DIR(f) if ((dir = opendir(f))) - #define DIR_ENTRY struct dirent* - #define START_DIR_LOOP while ((errno = 0, direntry = readdir(dir)) != NULL) - #define END_DIR_LOOP if (!direntry && errno) fprintf(stderr, "error reading directory %s: %s\n", filename, strerror(errno)); if (dir) closedir(dir); - #ifdef _DIRENT_HAVE_D_TYPE - #define SKIP_NON_DIR(e) if (e->d_type != DT_DIR && e->d_type != DT_UNKNOWN) continue; - #else - #define SKIP_NON_DIR(e) - #endif - #define FILENAME(e) e->d_name - +#include <dirent.h> +#define DIR_HANDLE DIR * +#define IF_OPEN_DIR(f) if ((dir = opendir(f))) +#define DIR_ENTRY struct dirent * +#define START_DIR_LOOP while ((errno = 0, direntry = readdir(dir)) != NULL) +#define END_DIR_LOOP \ + if (!direntry && errno) \ + fprintf(stderr, "error reading directory %s: %s\n", filename, strerror(errno)); \ + if (dir) \ + closedir(dir); +#ifdef _DIRENT_HAVE_D_TYPE +#define SKIP_NON_DIR(e) \ + if (e->d_type != DT_DIR && e->d_type != DT_UNKNOWN) \ + continue; +#else +#define SKIP_NON_DIR(e) #endif +#define FILENAME(e) e->d_name - +#endif #define LIBDIR "lib" OSI_PATH_SEPARATOR #define TEMPLATEDIR "db" - /* +/* #define TOSTR(s) TOSTR2(s) #define TOSTR2(s) #s const char epicsRelease[] = TOSTR(EPICS_VERSION)"."TOSTR(EPICS_REVISION)"."TOSTR(EPICS_MODIFICATION); -const char epicsBasetype[] = TOSTR(EPICS_VERSION)"."TOSTR(EPICS_REVISION); #ifndef T_A #error T_A not defined: Compile with USR_CFLAGS += -DT_A='"${T_A}"' @@ -285,57 +284,54 @@ const char osClass[] = OS_CLASS; Find a loadable library by name and load it. */ - char epicsRelease[80]; -char epicsBasetype[80]; char *targetArch; void set_require_env() { - char* epics_version_major = getenv("EPICS_VERSION_MAJOR"); - char* epics_version_middle = getenv("EPICS_VERSION_MIDDLE"); - char* epics_version_minor = getenv("EPICS_VERSION_MINOR"); - - sprintf(epicsRelease, "%s.%s.%s", epics_version_major, epics_version_middle, epics_version_minor); - sprintf(epicsBasetype, "%s.%s", epics_version_major, epics_version_middle); - targetArch = getenv("EPICS_HOST_ARCH"); - return; + char *epics_version_major = getenv("EPICS_VERSION_MAJOR"); + char *epics_version_middle = getenv("EPICS_VERSION_MIDDLE"); + char *epics_version_minor = getenv("EPICS_VERSION_MINOR"); + + sprintf(epicsRelease, "%s.%s.%s", epics_version_major, epics_version_middle, epics_version_minor); + targetArch = getenv("EPICS_HOST_ARCH"); + return; } -static HMODULE loadlib(const char* libname) +static HMODULE loadlib(const char *libname) { HMODULE libhandle = NULL; if (libname == NULL) { - fprintf (stderr, "missing library name\n"); + fprintf(stderr, "missing library name\n"); return NULL; } -#if defined (__unix) - if ((libhandle = dlopen(libname, RTLD_NOW|RTLD_GLOBAL)) == NULL) +#if defined(__unix) + if ((libhandle = dlopen(libname, RTLD_NOW | RTLD_GLOBAL)) == NULL) { - fprintf (stderr, "Loading %s library failed: %s\n", - libname, dlerror()); + fprintf(stderr, "Loading %s library failed: %s\n", + libname, dlerror()); } -#elif defined (_WIN32) +#elif defined(_WIN32) if ((libhandle = LoadLibrary(libname)) == NULL) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, + FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, NULL ); - fprintf (stderr, "Loading %s library failed: %s\n", - libname, lpMsgBuf); + (LPTSTR)&lpMsgBuf, + 0, NULL); + fprintf(stderr, "Loading %s library failed: %s\n", + libname, lpMsgBuf); LocalFree(lpMsgBuf); } -#elif defined (vxWorks) +#elif defined(vxWorks) { int fd, loaderror; fd = open(libname, O_RDONLY, 0); @@ -345,46 +341,47 @@ static HMODULE loadlib(const char* libname) errno = 0; libhandle = loadModule(fd, LOAD_GLOBAL_SYMBOLS); #ifndef _WRS_VXWORKS_MAJOR -/* vxWorks 5 */ + /* vxWorks 5 */ if (errno == S_symLib_SYMBOL_NOT_FOUND) { libhandle = NULL; } #endif loaderror = errno; - close (fd); + close(fd); } if (libhandle == NULL) { fprintf(stderr, "Loading %s library failed: %s\n", - libname, strerror(loaderror)); + libname, strerror(loaderror)); } } #else - fprintf (stderr, "cannot load libraries on this OS.\n"); -#endif + fprintf(stderr, "cannot load libraries on this OS.\n"); +#endif return libhandle; } typedef struct moduleitem { - struct moduleitem* next; + struct moduleitem *next; char content[0]; } moduleitem; -static moduleitem* loadedModules = NULL; +static moduleitem *loadedModules = NULL; static unsigned long moduleCount = 0; static unsigned long moduleListBufferSize = 1; static unsigned long maxModuleNameLength = 0; -int putenvprintf(const char* format, ...) +int putenvprintf(const char *format, ...) { va_list ap; char *var; char *val; int status = 0; - if (!format) return -1; + if (!format) + return -1; va_start(ap, format); if (vasprintf(&var, format, ap) < 0) { @@ -397,7 +394,7 @@ int putenvprintf(const char* format, ...) printf("require: putenv(\"%s\")\n", var); val = strchr(var, '='); - if (!val) + if (!val) { fprintf(stderr, "putenvprintf: string contains no =: %s\n", var); status = -1; @@ -423,11 +420,12 @@ int putenvprintf(const char* format, ...) return status; } -void pathAdd(const char* varname, const char* dirname) +void pathAdd(const char *varname, const char *dirname) { - char* old_path; + char *old_path; - if (!varname || !dirname) { + if (!varname || !dirname) + { fprintf(stderr, "usage: pathAdd \"ENVIRONMENT_VARIABLE\",\"directory\"\n"); fprintf(stderr, " Adds or moves the directory to the front of the ENVIRONMENT_VARIABLE\n"); fprintf(stderr, " but after a leading \".\".\n"); @@ -441,7 +439,7 @@ void pathAdd(const char* varname, const char* dirname) else { size_t len = strlen(dirname); - char* p; + char *p; /* skip over "." at the beginning */ if (old_path[0] == '.' && old_path[1] == OSI_PATH_LIST_SEPARATOR[0]) @@ -451,11 +449,12 @@ void pathAdd(const char* varname, const char* dirname) p = old_path; while ((p = strstr(p, dirname)) != NULL) { - if ((p == old_path || *(p-1) == OSI_PATH_LIST_SEPARATOR[0]) && + if ((p == old_path || *(p - 1) == OSI_PATH_LIST_SEPARATOR[0]) && (p[len] == 0 || p[len] == OSI_PATH_LIST_SEPARATOR[0])) { - if (p == old_path) break; /* already at front, nothing to do */ - memmove(old_path+len+1, old_path, p-old_path-1); + if (p == old_path) + break; /* already at front, nothing to do */ + memmove(old_path + len + 1, old_path, p - old_path - 1); strcpy(old_path, dirname); old_path[len] = OSI_PATH_LIST_SEPARATOR[0]; if (requireDebug) @@ -467,13 +466,13 @@ void pathAdd(const char* varname, const char* dirname) if (p == NULL) /* add new directory to the front (after "." )*/ putenvprintf("%s=." OSI_PATH_LIST_SEPARATOR "%s" OSI_PATH_LIST_SEPARATOR "%s", - varname, dirname, old_path); + varname, dirname, old_path); } } -static int setupDbPath(const char* module, const char* dbdir) +static int setupDbPath(const char *module, const char *dbdir) { - char* absdir = realpath(dbdir, NULL); /* so we can change directory later safely */ + char *absdir = realpath(dbdir, NULL); /* so we can change directory later safely */ if (absdir == NULL) { if (requireDebug) @@ -499,9 +498,9 @@ static int setupDbPath(const char* module, const char* dbdir) return 0; } -static int getRecordHandle(const char* namepart, short type, long minsize, DBADDR* paddr) +static int getRecordHandle(const char *namepart, short type, long minsize, DBADDR *paddr) { - /* + /* #define PVNAME_STRINGSZ 61 defined in EPICS_BASE/include/dbDefs.h */ @@ -509,43 +508,43 @@ static int getRecordHandle(const char* namepart, short type, long minsize, DBADD long dummy = 0L; long offset = 0L; - sprintf(recordname, "%.*s%s", (int)(PVNAME_STRINGSZ-strlen(namepart)-1), getenv("REQUIRE_IOC"), namepart); - + sprintf(recordname, "%.*s%s", (int)(PVNAME_STRINGSZ - strlen(namepart) - 1), getenv("REQUIRE_IOC"), namepart); + if (dbNameToAddr(recordname, paddr) != 0) - { + { fprintf(stderr, - "require:getRecordHandle : record %s not found\n", - recordname); + "require:getRecordHandle : record %s not found\n", + recordname); return -1; - } + } if (paddr->field_type != type) - { + { fprintf(stderr, - "require:getRecordHandle : record %s has wrong type %s instead of %s\n", - recordname, - pamapdbfType[paddr->field_type].strvalue, - pamapdbfType[type].strvalue); + "require:getRecordHandle : record %s has wrong type %s instead of %s\n", + recordname, + pamapdbfType[paddr->field_type].strvalue, + pamapdbfType[type].strvalue); return -1; - } + } if (paddr->no_elements < minsize) - { + { fprintf(stderr, - "require:getRecordHandle : record %s has not enough elements: %lu instead of %lu\n", - recordname, - paddr->no_elements, - minsize); + "require:getRecordHandle : record %s has not enough elements: %lu instead of %lu\n", + recordname, + paddr->no_elements, + minsize); return -1; - } + } if (paddr->pfield == NULL) - { + { fprintf(stderr, "require:getRecordHandle : record %s has not yet allocated memory\n", - recordname); + recordname); return -1; - } + } /* update array information */ dbGetRset(paddr)->get_array_info(paddr, &dummy, &offset); - + return 0; } @@ -564,99 +563,95 @@ static void fillModuleListRecord(initHookState state) moduleitem *m; int i = 0; long c = 0; - + if (requireDebug) printf("require: fillModuleListRecord\n"); - have_modules = (getRecordHandle(":MODULES", DBF_STRING, moduleCount, &modules) == 0); + have_modules = (getRecordHandle(":MODULES", DBF_STRING, moduleCount, &modules) == 0); have_versions = (getRecordHandle(":VERSIONS", DBF_STRING, moduleCount, &versions) == 0); - + moduleListBufferSize += moduleCount * maxModuleNameLength; - have_modver = (getRecordHandle(":MOD_VER", DBF_CHAR, moduleListBufferSize, &modver) == 0); + have_modver = (getRecordHandle(":MOD_VER", DBF_CHAR, moduleListBufferSize, &modver) == 0); - for (m = loadedModules, i = 0; m; m=m->next, i++) + for (m = loadedModules, i = 0; m; m = m->next, i++) { - size_t lm = strlen(m->content)+1; + size_t lm = strlen(m->content) + 1; if (have_modules) { if (requireDebug) printf("require: %s[%d] = \"%.*s\"\n", - modules.precord->name, i, - MAX_STRING_SIZE-1, m->content); - sprintf((char*)(modules.pfield) + i * MAX_STRING_SIZE, "%.*s", - MAX_STRING_SIZE-1, m->content); + modules.precord->name, i, + MAX_STRING_SIZE - 1, m->content); + sprintf((char *)(modules.pfield) + i * MAX_STRING_SIZE, "%.*s", + MAX_STRING_SIZE - 1, m->content); } if (have_versions) { if (requireDebug) printf("require: %s[%d] = \"%.*s\"\n", - versions.precord->name, i, - MAX_STRING_SIZE-1, m->content+lm); - sprintf((char*)(versions.pfield) + i * MAX_STRING_SIZE, "%.*s", - MAX_STRING_SIZE-1, m->content+lm); + versions.precord->name, i, + MAX_STRING_SIZE - 1, m->content + lm); + sprintf((char *)(versions.pfield) + i * MAX_STRING_SIZE, "%.*s", + MAX_STRING_SIZE - 1, m->content + lm); } if (have_modver) { if (requireDebug) printf("require: %s+=\"%-*s%s\"\n", - modver.precord->name, - (int)maxModuleNameLength, m->content, m->content+lm); - c += sprintf((char*)(modver.pfield) + c, "%-*s%s\n", - (int)maxModuleNameLength, m->content, m->content+lm); + modver.precord->name, + (int)maxModuleNameLength, m->content, m->content + lm); + c += sprintf((char *)(modver.pfield) + c, "%-*s%s\n", + (int)maxModuleNameLength, m->content, m->content + lm); } } - if (have_modules) dbGetRset(&modules)->put_array_info(&modules, i); - if (have_versions) dbGetRset(&versions)->put_array_info(&versions, i); - if (have_modver) dbGetRset(&modver)->put_array_info(&modver, c+1); + if (have_modules) + dbGetRset(&modules)->put_array_info(&modules, i); + if (have_versions) + dbGetRset(&versions)->put_array_info(&versions, i); + if (have_modver) + dbGetRset(&modver)->put_array_info(&modver, c + 1); } } -void registerModule(const char* module, const char* version, const char* location) +void registerModule(const char *module, const char *version, const char *location) { moduleitem *m, **pm; size_t lm = strlen(module) + 1; size_t lv = (version ? strlen(version) : 0) + 1; size_t ll = 1; - char* abslocation = NULL; - char* argstring = NULL; - int addSlash=0; + char *abslocation = NULL; + char *argstring = NULL; + int addSlash = 0; const char *mylocation; static int firstTime = 1; if (requireDebug) printf("require: registerModule(%s,%s,%s)\n", module, version, location); - + if (firstTime) { -#ifdef EPICS_3_13 - int (*initHookRegister)() = NULL; - SYM_TYPE type; - symFindByName(sysSymTbl, "initHookRegister", (char**)&initHookRegister, &type); - if (initHookRegister) -#endif - { - initHookRegister(fillModuleListRecord); - if (requireDebug) - printf("require: initHookRegister\n"); - } + initHookRegister(fillModuleListRecord); + if (requireDebug) + printf("require: initHookRegister\n"); firstTime = 0; } - - if (!version) version=""; - + + if (!version) + version = ""; + if (location) { abslocation = realpath(location, NULL); - if (!abslocation) abslocation = (char*)location; + if (!abslocation) + abslocation = (char *)location; ll = strlen(abslocation) + 1; /* linux realpath removes trailing slash */ - if (abslocation[ll-1-strlen(OSI_PATH_SEPARATOR)] != OSI_PATH_SEPARATOR[0]) + if (abslocation[ll - 1 - strlen(OSI_PATH_SEPARATOR)] != OSI_PATH_SEPARATOR[0]) { addSlash = strlen(OSI_PATH_SEPARATOR); } - } - m = (moduleitem*) malloc(sizeof(moduleitem) + lm + lv + ll + addSlash); + m = (moduleitem *)malloc(sizeof(moduleitem) + lm + lv + ll + addSlash); if (m == NULL) { fprintf(stderr, "require: out of memory\n"); @@ -665,15 +660,19 @@ void registerModule(const char* module, const char* version, const char* locatio m->next = NULL; - strcpy (m->content, module); - strcpy (m->content+lm, version); - strcpy (m->content+lm+lv, abslocation ? abslocation : ""); + strcpy(m->content, module); + strcpy(m->content + lm, version); + strcpy(m->content + lm + lv, abslocation ? abslocation : ""); - if (addSlash) strcpy (m->content+lm+lv+ll-1, OSI_PATH_SEPARATOR); - if (abslocation != location) free(abslocation); - for (pm = &loadedModules; *pm != NULL; pm = &(*pm)->next); + if (addSlash) + strcpy(m->content + lm + lv + ll - 1, OSI_PATH_SEPARATOR); + if (abslocation != location) + free(abslocation); + for (pm = &loadedModules; *pm != NULL; pm = &(*pm)->next) + ; *pm = m; - if (lm > maxModuleNameLength) maxModuleNameLength = lm; + if (lm > maxModuleNameLength) + maxModuleNameLength = lm; moduleListBufferSize += lv; moduleCount++; @@ -681,17 +680,20 @@ void registerModule(const char* module, const char* version, const char* locatio putenvprintf("%s_VERSION=%s", module, version); if (location) { - putenvprintf("%s_DIR=%s", module, m->content+lm+lv); - pathAdd("SCRIPT_PATH", m->content+lm+lv); + putenvprintf("%s_DIR=%s", module, m->content + lm + lv); + pathAdd("SCRIPT_PATH", m->content + lm + lv); } - + /* only do registration register stuff at init */ - if (interruptAccept) return; - + if (interruptAccept) + return; + /* create a record with the version string */ mylocation = getenv("require_DIR"); - if (mylocation == NULL) return; - if (asprintf(&abslocation, "%s" OSI_PATH_SEPARATOR "db" OSI_PATH_SEPARATOR "moduleversion.template", mylocation) < 0) return; + if (mylocation == NULL) + return; + if (asprintf(&abslocation, "%s" OSI_PATH_SEPARATOR "db" OSI_PATH_SEPARATOR "moduleversion.template", mylocation) < 0) + return; /* Require DB has the following four PVs: - $(REQUIRE_IOC):$(MODULE)_VER @@ -703,35 +705,40 @@ void registerModule(const char* module, const char* version, const char* locatio So, the whole PV and record name in moduleversion.template has 59 + 1. */ if (asprintf(&argstring, "REQUIRE_IOC=%.30s, MODULE=%.24s, VERSION=%.39s, MODULE_COUNT=%lu, BUFFER_SIZE=%lu", - getenv("REQUIRE_IOC"), module, version, moduleCount, - moduleListBufferSize+maxModuleNameLength*moduleCount) < 0) return; + getenv("REQUIRE_IOC"), module, version, moduleCount, + moduleListBufferSize + maxModuleNameLength * moduleCount) < 0) + return; printf("Loading module info records for %s\n", module); dbLoadRecords(abslocation, argstring); free(argstring); free(abslocation); } -#if defined (vxWorks) -static BOOL findLibRelease ( - char *name, /* symbol name */ - int val, /* value of symbol */ - SYM_TYPE type, /* symbol type */ - int arg, /* user-supplied arg */ - UINT16 group /* group number */ -) { +#if defined(vxWorks) +static BOOL findLibRelease( + char *name, /* symbol name */ + int val, /* value of symbol */ + SYM_TYPE type, /* symbol type */ + int arg, /* user-supplied arg */ + UINT16 group /* group number */ +) +{ /* find symbols with a name like "_<module>LibRelease" */ - char* module; + char *module; size_t lm; - if (name[0] != '_') return TRUE; + if (name[0] != '_') + return TRUE; lm = strlen(name); - if (lm <= 10) /* strlen("LibRelease") */ return TRUE; + if (lm <= 10) /* strlen("LibRelease") */ + return TRUE; lm -= 10; - if (strcmp(name+lm, "LibRelease") != 0) return TRUE; - module = strdup(name+1); /* remove '_' */ - module[lm-1]=0; /* remove "libRelase" */ + if (strcmp(name + lm, "LibRelease") != 0) + return TRUE; + module = strdup(name + 1); /* remove '_' */ + module[lm - 1] = 0; /* remove "libRelase" */ if (getLibVersion(module) == NULL) - registerModule(module, (char*)val, NULL); + registerModule(module, (char *)val, NULL); free(module); return TRUE; } @@ -742,40 +749,52 @@ void registerExternalModules() symEach(sysSymTbl, (FUNCPTR)findLibRelease, 0); } -#elif defined (__linux) +#elif defined(__linux) /* This is the Linux link.h, not the EPICS link.h ! */ #include <link.h> -static int findLibRelease ( +static int findLibRelease( struct dl_phdr_info *info, /* shared library info */ size_t size, /* size of info structure */ void *data /* user-supplied arg */ -) { +) +{ void *handle; - char* location = NULL; - char* p; - char* version; - char* symname; - char name[PATH_MAX + 11]; /* get space for library path + "LibRelease" */ - - (void)data; /* unused */ - if (size < sizeof(struct dl_phdr_info)) return 0; /* wrong version of struct dl_phdr_info */ + char *location = NULL; + char *p; + char *version; + char *symname; + char name[PATH_MAX + 11]; /* get space for library path + "LibRelease" */ + + (void)data; /* unused */ + if (size < sizeof(struct dl_phdr_info)) + return 0; /* wrong version of struct dl_phdr_info */ /* find a symbol with a name like "_<module>LibRelease" where <module> is from the library name "<location>/lib<module>.so" */ - if (info->dlpi_name == NULL || info->dlpi_name[0] == 0) return 0; /* no library name */ - strcpy(name, info->dlpi_name); /* get a modifiable copy of the library name */ - handle = dlopen(info->dlpi_name, RTLD_LAZY); /* re-open already loaded library */ - p = strrchr(name, '/'); /* find file name part in "<location>/lib<module>.so" */ - if (p) {location = name; *++p=0;} else p=name; /* terminate "<location>/" (if exists) */ - *(symname = p+2) = '_'; /* replace "lib" with "_" */ - p = strchr(symname, '.'); /* find ".so" extension */ - if (p == NULL) p = symname + strlen(symname); /* no file extension ? */ - strcpy(p, "LibRelease"); /* append "LibRelease" to module name */ - version = dlsym(handle, symname); /* find symbol "_<module>LibRelease" */ + if (info->dlpi_name == NULL || info->dlpi_name[0] == 0) + return 0; /* no library name */ + strcpy(name, info->dlpi_name); /* get a modifiable copy of the library name */ + handle = dlopen(info->dlpi_name, RTLD_LAZY); /* re-open already loaded library */ + p = strrchr(name, '/'); /* find file name part in "<location>/lib<module>.so" */ + if (p) + { + location = name; + *++p = 0; + } + else + p = name; /* terminate "<location>/" (if exists) */ + *(symname = p + 2) = '_'; /* replace "lib" with "_" */ + p = strchr(symname, '.'); /* find ".so" extension */ + if (p == NULL) + p = symname + strlen(symname); /* no file extension ? */ + strcpy(p, "LibRelease"); /* append "LibRelease" to module name */ + version = dlsym(handle, symname); /* find symbol "_<module>LibRelease" */ if (version) { - *p=0; symname++; /* get "<module>" from "_<module>LibRelease" */ - if ((p = strstr(name, "/" LIBDIR)) != NULL) p[1]=0; /* cut "<location>" before LIBDIR */ + *p = 0; + symname++; /* get "<module>" from "_<module>LibRelease" */ + if ((p = strstr(name, "/" LIBDIR)) != NULL) + p[1] = 0; /* cut "<location>" before LIBDIR */ if (getLibVersion(symname) == NULL) registerModule(symname, version, location); } @@ -789,42 +808,52 @@ static void registerExternalModules() dl_iterate_phdr(findLibRelease, NULL); } -#elif defined (_WIN32) +#elif defined(_WIN32) static void registerExternalModules() { HMODULE hMods[100]; HANDLE hProcess = GetCurrentProcess(); DWORD cbNeeded; - char* location = NULL; - char* p; - char* version; - char* symname; + char *location = NULL; + char *p; + char *version; + char *symname; unsigned int i; - char name [MAX_PATH+11]; /* get space for library path + "LibRelease" */ - + char name[MAX_PATH + 11]; /* get space for library path + "LibRelease" */ + /* iterate over all loaded libraries */ - if (!EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) return; + if (!EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) + return; for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { /* Get the full path to the module's file. */ - if (!GetModuleFileName(hMods[i], name, MAX_PATH)) continue; /* no library name */ - name[sizeof(name)-1] = 0; /* WinXP may not terminate the string */ - p = strrchr(name, '\\'); /* find file name part in "<location>/<module>.dll" */ - if (p) { location = name; } else p=name; /* find end of "<location>\\" (if exists) */ + if (!GetModuleFileName(hMods[i], name, MAX_PATH)) + continue; /* no library name */ + name[sizeof(name) - 1] = 0; /* WinXP may not terminate the string */ + p = strrchr(name, '\\'); /* find file name part in "<location>/<module>.dll" */ + if (p) + { + location = name; + } + else + p = name; /* find end of "<location>\\" (if exists) */ symname = p; - p = strchr(symname, '.'); /* find ".dll" */ - if (p == NULL) p = symname + strlen(symname); /* no file extension ? */ - memmove(symname+2, symname, p - symname); /* make room for 0 and '_' */ - *symname++ = 0; /* terminate "<location>/" */ - *symname = '_'; /* prefix module name with '_' */ - strcpy((p+=2), "LibRelease"); /* append "LibRelease" to module name */ - - version = (char*)GetProcAddress(hMods[i], symname); /* find symbol "_<module>LibRelease" */ + p = strchr(symname, '.'); /* find ".dll" */ + if (p == NULL) + p = symname + strlen(symname); /* no file extension ? */ + memmove(symname + 2, symname, p - symname); /* make room for 0 and '_' */ + *symname++ = 0; /* terminate "<location>/" */ + *symname = '_'; /* prefix module name with '_' */ + strcpy((p += 2), "LibRelease"); /* append "LibRelease" to module name */ + + version = (char *)GetProcAddress(hMods[i], symname); /* find symbol "_<module>LibRelease" */ if (version) { - *p=0; symname++; /* get "<module>" from "_<module>LibRelease" */ - if ((p = strstr(name, "\\" LIBDIR)) != NULL) p[1]=0; /* cut "<location>" before LIBDIR */ + *p = 0; + symname++; /* get "<module>" from "_<module>LibRelease" */ + if ((p = strstr(name, "\\" LIBDIR)) != NULL) + p[1] = 0; /* cut "<location>" before LIBDIR */ if (getLibVersion(symname) == NULL) registerModule(symname, version, location); } @@ -838,58 +867,59 @@ static void registerExternalModules() } #endif -size_t foreachLoadedLib(size_t (*func)(const char* name, const char* version, const char* path, void* arg), void* arg) +size_t foreachLoadedLib(size_t (*func)(const char *name, const char *version, const char *path, void *arg), void *arg) { - moduleitem* m; + moduleitem *m; int result; - for (m = loadedModules; m; m=m->next) + for (m = loadedModules; m; m = m->next) { - const char* name = m->content; - const char* version = name + strlen(name)+1; - const char* path = version + strlen(version)+1; + const char *name = m->content; + const char *version = name + strlen(name) + 1; + const char *path = version + strlen(version) + 1; result = func(name, version, path, arg); - if (result) return result; + if (result) + return result; } return 0; } -const char* getLibVersion(const char* libname) +const char *getLibVersion(const char *libname) { - moduleitem* m; + moduleitem *m; - for (m = loadedModules; m; m=m->next) + for (m = loadedModules; m; m = m->next) { if (strcmp(m->content, libname) == 0) { - return m->content+strlen(m->content)+1; + return m->content + strlen(m->content) + 1; } } return NULL; } -const char* getLibLocation(const char* libname) +const char *getLibLocation(const char *libname) { - moduleitem* m; + moduleitem *m; char *v; - for (m = loadedModules; m; m=m->next) + for (m = loadedModules; m; m = m->next) { if (strcmp(m->content, libname) == 0) { - v = m->content+strlen(m->content)+1; - return v+strlen(v)+1; + v = m->content + strlen(m->content) + 1; + return v + strlen(v) + 1; } } return NULL; } -int libversionShow(const char* outfile) +int libversionShow(const char *outfile) { - moduleitem* m; + moduleitem *m; size_t lm, lv; - - FILE* out = epicsGetStdout(); + + FILE *out = epicsGetStdout(); if (outfile) { @@ -897,22 +927,22 @@ int libversionShow(const char* outfile) if (out == NULL) { fprintf(stderr, "can't open %s: %s\n", - outfile, strerror(errno)); + outfile, strerror(errno)); return -1; } } - for (m = loadedModules; m; m=m->next) + for (m = loadedModules; m; m = m->next) { - lm = strlen(m->content)+1; - lv = strlen(m->content+lm)+1; + lm = strlen(m->content) + 1; + lv = strlen(m->content + lm) + 1; fprintf(out, "%-*s%-20s %s\n", - (int)maxModuleNameLength, m->content, - m->content+lm, m->content+lm+lv); + (int)maxModuleNameLength, m->content, + m->content + lm, m->content + lm + lv); } if (fflush(out) < 0 && outfile) { fprintf(stderr, "can't write to %s: %s\n", - outfile, strerror(errno)); + outfile, strerror(errno)); return -1; } if (outfile) @@ -926,18 +956,18 @@ int libversionShow(const char* outfile) #define TESTVERS 2 #define HIGHER 3 -static int compareVersions(const char* found, const char* request) +static int compareVersions(const char *found, const char *request) { - int found_major, found_minor=0, found_patch=0, found_parts = 0; + int found_major, found_minor = 0, found_patch = 0, found_parts = 0; int req_major, req_minor, req_patch, req_parts; - const char* found_extra; - const char* req_extra; + const char *found_extra; + const char *req_extra; int n; - + if (requireDebug) printf("require: compareVersions(found=%s, request=%s)\n", found, request); - - if (found == NULL || found[0] == 0) /* no version found: any requested? */ + + if (found == NULL || found[0] == 0) /* no version found: any requested? */ { if (request == NULL || request[0] == 0) { @@ -955,7 +985,7 @@ static int compareVersions(const char* found, const char* request) n = 0; found_parts = sscanf(found, "%d%n.%d%n.%d%n", &found_major, &n, &found_minor, &n, &found_patch, &n); found_extra = found + n; - if (request == NULL || request[0] == 0) /* no particular version request: match anything */ + if (request == NULL || request[0] == 0) /* no particular version request: match anything */ { if (found_parts == 0 || found_extra[0] != 0) { @@ -1024,7 +1054,7 @@ static int compareVersions(const char* found, const char* request) printf("require: compareVersions: MISMATCH minor number too low\n"); return MISMATCH; } - if (found_minor > req_minor) /* minor larger than required */ + if (found_minor > req_minor) /* minor larger than required */ { if (req_extra[0] == '+') { @@ -1065,7 +1095,7 @@ static int compareVersions(const char* found, const char* request) } if (requireDebug) printf("require: compareVersions: HIGHER patch level\n"); - return HIGHER; + return HIGHER; } /* require (module) @@ -1080,40 +1110,35 @@ it calls epicsExit to abort the application. */ /* wrapper to abort statup script */ -static int require_priv(const char* module, const char* version, const char* args, const char* versionstr); +static int require_priv(const char *module, const char *version, const char *args, const char *versionstr); -int require(const char* module, const char* version, const char* args) +int require(const char *module, const char *version, const char *args) { int status; - char* versionstr; + char *versionstr; static int firstTime = 1; - if (firstTime) { firstTime = 0; - - set_require_env(); - - putenvprintf("T_A=%s", targetArch); - putenvprintf("EPICS_HOST_ARCH=%s", targetArch); - putenvprintf("EPICS_RELEASE=%s", epicsRelease); - putenvprintf("EPICS_BASETYPE=%s", epicsBasetype); - putenvprintf("OS_CLASS=%s", osClass); - + + set_require_env(); + + putenvprintf("T_A=%s", targetArch); + putenvprintf("EPICS_HOST_ARCH=%s", targetArch); + putenvprintf("EPICS_RELEASE=%s", epicsRelease); + putenvprintf("OS_CLASS=%s", osClass); } if (module == NULL) { printf("Usage: require \"<module>\" [, \"<version>\" | \"ifexists\"] [, \"<args>\"]\n"); printf("Loads " PREFIX "<module>" INFIX EXT " and <libname>.dbd\n"); -#ifndef EPICS_3_13 printf("And calls <module>_registerRecordDeviceDriver\n"); -#endif printf("If available, runs startup script snippet (only before iocInit)\n"); return -1; } - + /* either order for version and args, either may be empty or NULL */ if (version && strchr(version, '=')) { @@ -1124,7 +1149,8 @@ int require(const char* module, const char* version, const char* args) printf("require: swap version and args\n"); } - if (version && version[0] == 0) version = NULL; + if (version && version[0] == 0) + version = NULL; if (version && strcmp(version, "none") == 0) { @@ -1136,15 +1162,17 @@ int require(const char* module, const char* version, const char* args) if (version) { /* needed for old style only: */ - if (asprintf(&versionstr, "-%s", version) < 0) return errno; - if (isdigit((unsigned char)version[0]) && version[strlen(version)-1] == '+') + if (asprintf(&versionstr, "-%s", version) < 0) + return errno; + if (isdigit((unsigned char)version[0]) && version[strlen(version) - 1] == '+') { /* user may give a minimal version (e.g. "1.2.4+") load highest matching version (here "1.2") and check later */ - char* p = strrchr(versionstr, '.'); - if (p == NULL) p = versionstr; + char *p = strrchr(versionstr, '.'); + if (p == NULL) + p = versionstr; *p = 0; } } @@ -1155,30 +1183,35 @@ int require(const char* module, const char* version, const char* args) status = require_priv(module, version, args, versionstr); - if (version) free(versionstr); + if (version) + free(versionstr); - if (status == 0) return 0; - if (status != -1) perror("require"); - if (interruptAccept) return status; + if (status == 0) + return 0; + if (status != -1) + perror("require"); + if (interruptAccept) + return status; /* require failed in startup script before iocInit */ fprintf(stderr, "Aborting startup script\n"); - #ifdef vxWorks +#ifdef vxWorks shellScriptAbort(); - #else +#else epicsExit(1); - #endif +#endif return status; } -static off_t fileSize(const char* filename) +static off_t fileSize(const char *filename) { struct stat filestat; if (stat( #ifdef vxWorks - (char*) /* vxWorks has buggy stat prototype */ + (char *)/* vxWorks has buggy stat prototype */ #endif - filename, &filestat) != 0) + filename, + &filestat) != 0) { if (requireDebug) printf("require: %s does not exist\n", filename); @@ -1186,96 +1219,101 @@ static off_t fileSize(const char* filename) } switch (filestat.st_mode & S_IFMT) { - case S_IFREG: - if (requireDebug) - printf("require: file %s exists, size %lld bytes\n", - filename, (unsigned long long)filestat.st_size); - return filestat.st_size; - case S_IFDIR: - if (requireDebug) - printf("require: directory %s exists\n", - filename); - return 0; - #ifdef S_IFBLK - case S_IFBLK: - if (requireDebug) - printf("require: %s is a block device\n", - filename); - return -1; - #endif - #ifdef S_IFCHR - case S_IFCHR: - if (requireDebug) - printf("require: %s is a character device\n", - filename); - return -1; - #endif - #ifdef S_IFIFO - case S_IFIFO: - if (requireDebug) - printf("require: %s is a FIFO/pipe\n", - filename); - return -1; - #endif - #ifdef S_IFSOCK - case S_IFSOCK: - if (requireDebug) - printf("require: %s is a socket\n", - filename); - return -1; - #endif - default: - if (requireDebug) - printf("require: %s is an unknown type of special file\n", - filename); - return -1; + case S_IFREG: + if (requireDebug) + printf("require: file %s exists, size %lld bytes\n", + filename, (unsigned long long)filestat.st_size); + return filestat.st_size; + case S_IFDIR: + if (requireDebug) + printf("require: directory %s exists\n", + filename); + return 0; +#ifdef S_IFBLK + case S_IFBLK: + if (requireDebug) + printf("require: %s is a block device\n", + filename); + return -1; +#endif +#ifdef S_IFCHR + case S_IFCHR: + if (requireDebug) + printf("require: %s is a character device\n", + filename); + return -1; +#endif +#ifdef S_IFIFO + case S_IFIFO: + if (requireDebug) + printf("require: %s is a FIFO/pipe\n", + filename); + return -1; +#endif +#ifdef S_IFSOCK + case S_IFSOCK: + if (requireDebug) + printf("require: %s is a socket\n", + filename); + return -1; +#endif + default: + if (requireDebug) + printf("require: %s is an unknown type of special file\n", + filename); + return -1; } } -#define fileExists(filename) (fileSize(filename)>=0) -#define fileNotEmpty(filename) (fileSize(filename)>0) +#define fileExists(filename) (fileSize(filename) >= 0) +#define fileNotEmpty(filename) (fileSize(filename) > 0) -static int handleDependencies(const char* module, char* depfilename) +static int handleDependencies(const char *module, char *depfilename) { - FILE* depfile; + FILE *depfile; char buffer[40]; - char *end; /* end of string */ - char *rmodule; /* required module */ + char *end; /* end of string */ + char *rmodule; /* required module */ char *rversion; /* required version */ if (requireDebug) printf("require: parsing dependency file %s\n", depfilename); depfile = fopen(depfilename, "r"); - while (fgets(buffer, sizeof(buffer)-1, depfile)) + while (fgets(buffer, sizeof(buffer) - 1, depfile)) { rmodule = buffer; /* ignore leading spaces */ - while (isspace((unsigned char)*rmodule)) rmodule++; + while (isspace((unsigned char)*rmodule)) + rmodule++; /* ignore empty lines and comment lines */ - if (*rmodule == 0 || *rmodule == '#') continue; + if (*rmodule == 0 || *rmodule == '#') + continue; /* rmodule at start of module name */ rversion = rmodule; /* find end of module name */ - while (*rversion && !isspace((unsigned char)*rversion)) rversion++; + while (*rversion && !isspace((unsigned char)*rversion)) + rversion++; /* terminate module name */ *rversion++ = 0; /* ignore spaces */ - while (isspace((unsigned char)*rversion)) rversion++; + while (isspace((unsigned char)*rversion)) + rversion++; /* rversion at start of version */ - + if (*rversion) { end = rversion; /* find end of version */ - while (*end && !isspace((unsigned char)*end)) end++; + while (*end && !isspace((unsigned char)*end)) + end++; /* add + to numerial versions if not yet there */ - /* + /* ESS would like to use the MATCH version only, not HIGHER. In order to touch the PSI code mininaly, disable add + from VERSION from Dep file. At the same time, ESS use the X.X.X instead of X.X. Wednesday, May 2 00:12:18 CEST 2018, jhlee */ - /* + /* if (*(end-1) != '+' && strspn(rversion, "0123456789.") == (size_t)(end-rversion)) *end++ = '+'; */ /* terminate version */ @@ -1292,503 +1330,456 @@ static int handleDependencies(const char* module, char* depfilename) return 0; } -static int -require_priv(const char* module, - const char* version, - const char* args, - const char* versionstr /* "-<version>" or "" (for old style only */ - ) +static int +require_priv(const char *module, + const char *version, + const char *args, + const char *versionstr /* "-<version>" or "" (for old style only */ +) { - int status; - const char* loaded = NULL; - const char* found = NULL; - HMODULE libhandle; - int ifexists = 0; - const char* driverpath; - const char* dirname; - const char *end; - - int releasediroffs; - int libdiroffs; - int extoffs; - char* founddir = NULL; - char* symbolname; - char filename[PATH_MAX]; - - int someVersionFound = 0; - int someArchFound = 0; - - static char* globalTemplates = NULL; - - if (requireDebug) - printf("require: module=\"%s\" version=\"%s\" args=\"%s\"\n", module, version, args); + int status; + const char *loaded = NULL; + const char *found = NULL; + HMODULE libhandle; + int ifexists = 0; + const char *driverpath; + const char *dirname; + const char *end; + + int releasediroffs; + int libdiroffs; + int extoffs; + char *founddir = NULL; + char *symbolname; + char filename[PATH_MAX]; + + int someVersionFound = 0; + int someArchFound = 0; + + static char *globalTemplates = NULL; + + if (requireDebug) + printf("require: module=\"%s\" version=\"%s\" args=\"%s\"\n", module, version, args); #if defined __GNUC__ && __GNUC__ < 3 -#define TRY_FILE(offs, args...) \ - (snprintf(filename + offs, sizeof(filename) - offs, args) && fileExists(filename)) +#define TRY_FILE(offs, args...) \ + (snprintf(filename + offs, sizeof(filename) - offs, args) && fileExists(filename)) -#define TRY_NONEMPTY_FILE(offs, args...) \ - (snprintf(filename + offs, sizeof(filename) - offs, args) && fileNotEmpty(filename)) +#define TRY_NONEMPTY_FILE(offs, args...) \ + (snprintf(filename + offs, sizeof(filename) - offs, args) && fileNotEmpty(filename)) #else -#define TRY_FILE(offs, ...) \ - (snprintf(filename + offs, sizeof(filename) - offs, __VA_ARGS__) && fileExists(filename)) +#define TRY_FILE(offs, ...) \ + (snprintf(filename + offs, sizeof(filename) - offs, __VA_ARGS__) && fileExists(filename)) -#define TRY_NONEMPTY_FILE(offs, ...) \ - (snprintf(filename + offs, sizeof(filename) - offs, __VA_ARGS__) && fileNotEmpty(filename)) +#define TRY_NONEMPTY_FILE(offs, ...) \ + (snprintf(filename + offs, sizeof(filename) - offs, __VA_ARGS__) && fileNotEmpty(filename)) #endif -#if defined (_WIN32) - /* enable %n in printf */ - _set_printf_count_output(1); +#if defined(_WIN32) + /* enable %n in printf */ + _set_printf_count_output(1); #endif - driverpath = getenv("EPICS_DRIVER_PATH"); - if (!globalTemplates) + driverpath = getenv("EPICS_DRIVER_PATH"); + if (!globalTemplates) { - char *t = getenv("TEMPLATES"); - if (t) globalTemplates = strdup(t); + char *t = getenv("TEMPLATES"); + if (t) + globalTemplates = strdup(t); } - - if (driverpath == NULL) driverpath = "."; - if (requireDebug) - printf("require: searchpath=%s\n", driverpath); - if (version && strcmp(version,"ifexists") == 0) + if (driverpath == NULL) + driverpath = "."; + if (requireDebug) + printf("require: searchpath=%s\n", driverpath); + + if (version && strcmp(version, "ifexists") == 0) { - ifexists = 1; - version = NULL; - versionstr = ""; + ifexists = 1; + version = NULL; + versionstr = ""; } - /* check already loaded verion */ - loaded = getLibVersion(module); - if (loaded) + /* check already loaded verion */ + loaded = getLibVersion(module); + if (loaded) { - /* Library already loaded. Check Version. */ - switch (compareVersions(loaded, version)) + /* Library already loaded. Check Version. */ + switch (compareVersions(loaded, version)) { - case TESTVERS: - if (version) - printf("Warning: Module %s test version %s already loaded where %s was requested\n", - module, loaded, version); - case EXACT: - case MATCH: - printf ("Module %s version %s already loaded\n", module, loaded); - break; - default: - printf("Conflict between requested %s version %s and already loaded version %s.\n", - module, version, loaded); - return -1; + case TESTVERS: + if (version) + printf("Warning: Module %s test version %s already loaded where %s was requested\n", + module, loaded, version); + case EXACT: + case MATCH: + printf("Module %s version %s already loaded\n", module, loaded); + break; + default: + printf("Conflict between requested %s version %s and already loaded version %s.\n", + module, version, loaded); + return -1; } - dirname = getLibLocation(module); - if (dirname[0] == 0) return 0; - if (requireDebug) - printf("require: library found in %s\n", dirname); - snprintf(filename, sizeof(filename), "%s%n", dirname, &releasediroffs); - putenvprintf("MODULE=%s", module); - pathAdd("SCRIPT_PATH", dirname); + dirname = getLibLocation(module); + if (dirname[0] == 0) + return 0; + if (requireDebug) + printf("require: library found in %s\n", dirname); + snprintf(filename, sizeof(filename), "%s%n", dirname, &releasediroffs); + putenvprintf("MODULE=%s", module); + pathAdd("SCRIPT_PATH", dirname); } - else + else { - if (requireDebug) - printf("require: no %s version loaded yet\n", module); + if (requireDebug) + printf("require: no %s version loaded yet\n", module); - /* Search for module in driverpath */ - for (dirname = driverpath; dirname != NULL; dirname = end) + /* Search for module in driverpath */ + for (dirname = driverpath; dirname != NULL; dirname = end) { - /* get one directory from driverpath */ - int dirlen; - int modulediroffs; - DIR_HANDLE dir; - DIR_ENTRY direntry; - - end = strchr(dirname, OSI_PATH_LIST_SEPARATOR[0]); - if (end && end[1] == OSI_PATH_SEPARATOR[0] && end[2] == OSI_PATH_SEPARATOR[0]) /* "http://..." and friends */ - end = strchr(end+2, OSI_PATH_LIST_SEPARATOR[0]); - if (end) dirlen = (int)(end++ - dirname); - else dirlen = (int)strlen(dirname); - if (dirlen == 0) continue; /* ignore empty driverpath elements */ - - if (requireDebug) - printf("require: trying %.*s\n", dirlen, dirname); - - snprintf(filename, sizeof(filename), "%.*s" OSI_PATH_SEPARATOR "%s" OSI_PATH_SEPARATOR "%n", - dirlen, dirname, module, &modulediroffs); - dirlen++; - /* filename = "<dirname>/[dirlen]<module>/[modulediroffs]" */ - - /* Does the module directory exist? */ - IF_OPEN_DIR(filename) - { - if (requireDebug) - printf("require: found directory %s\n", filename); - - /* Now look for versions. */ - START_DIR_LOOP - { - char* currentFilename = FILENAME(direntry); - - SKIP_NON_DIR(direntry) - if (currentFilename[0] == '.') continue; /* ignore hidden directories */ - - someVersionFound = 1; - - /* Look for highest matching version. */ - if (requireDebug) - printf("require: checking version %s against required %s\n", - currentFilename, version); - - switch ((status = compareVersions(currentFilename, version))) - { - case TESTVERS: /* test version found */ - case EXACT: /* exact match found */ - case MATCH: /* all given numbers match. */ - { - someArchFound = 1; - - if (requireDebug) - printf("require: %s %s may match %s\n", - module, currentFilename, version); - - /* Check if it has our EPICS version and architecture. */ - /* Even if it has no library, at least it has a dep file in the lib dir */ - - - /* Step 1 : library file location */ - /* filename = "<dirname>/[dirlen]<module>/[modulediroffs]" */ - if (!TRY_FILE(modulediroffs, "%s" OSI_PATH_SEPARATOR LIBDIR "%s" OSI_PATH_SEPARATOR, - currentFilename, targetArch)) - /* filename = "<dirname>/[dirlen]<module>/[modulediroffs]<version>/lib/<targetArch>/" */ - { - if (requireDebug) - printf("require: %s %s has no support for %s %s\n", - module, currentFilename, epicsRelease, targetArch); - continue; - } - - if (status == EXACT) - { - if (requireDebug) - printf("require: %s %s matches %s exactly\n", - module, currentFilename, version); - /* We are done. */ - end = NULL; - break; - } - - /* Is it higher than the one we found before? */ - if (found && requireDebug) - printf("require: %s %s support for %s %s found, compare against previously found %s\n", - module, currentFilename, epicsRelease, targetArch, found); - if (!found || compareVersions(currentFilename, found) == HIGHER) - { - if (requireDebug) - printf("require: %s %s looks promising\n", module, currentFilename); - break; - } - if (requireDebug) - printf("require: version %s is lower than %s \n", currentFilename, found); - continue; - } - default: - { - if (requireDebug) - printf("require: %s %s does not match %s\n", - module, currentFilename, version); - continue; - } - } - /* we have found something (EXACT or MATCH) */ - free(founddir); - /* filename = "<dirname>/[dirlen]<module>/[modulediroffs]..." */ - if (asprintf(&founddir, "%.*s%s", modulediroffs, filename, currentFilename) < 0) - return errno; - /* founddir = "<dirname>/[dirlen]<module>/[modulediroffs]<version>" */ - found = founddir + modulediroffs; /* version part in the path */ - if (status == EXACT) break; - } - END_DIR_LOOP - } - else + /* get one directory from driverpath */ + int dirlen; + int modulediroffs; + DIR_HANDLE dir; + DIR_ENTRY direntry; + + end = strchr(dirname, OSI_PATH_LIST_SEPARATOR[0]); + if (end && end[1] == OSI_PATH_SEPARATOR[0] && end[2] == OSI_PATH_SEPARATOR[0]) /* "http://..." and friends */ + end = strchr(end + 2, OSI_PATH_LIST_SEPARATOR[0]); + if (end) + dirlen = (int)(end++ - dirname); + else + dirlen = (int)strlen(dirname); + if (dirlen == 0) + continue; /* ignore empty driverpath elements */ + + if (requireDebug) + printf("require: trying %.*s\n", dirlen, dirname); + + snprintf(filename, sizeof(filename), "%.*s" OSI_PATH_SEPARATOR "%s" OSI_PATH_SEPARATOR "%n", + dirlen, dirname, module, &modulediroffs); + dirlen++; + /* filename = "<dirname>/[dirlen]<module>/[modulediroffs]" */ + + /* Does the module directory exist? */ + IF_OPEN_DIR(filename) { - /* filename = "<dirname>/[dirlen]<module>/" */ - if (requireDebug) - printf("require: no %s directory\n", filename); + if (requireDebug) + printf("require: found directory %s\n", filename); - /* try local/old style module only if no new style candidate has been found */ - if (!found) + /* Now look for versions. */ + START_DIR_LOOP { - /* look for dep file */ - releasediroffs = libdiroffs = dirlen; - if (TRY_FILE(dirlen, "%s%s.dep", module, versionstr)) + char *currentFilename = FILENAME(direntry); + + SKIP_NON_DIR(direntry) + if (currentFilename[0] == '.') + continue; /* ignore hidden directories */ + + someVersionFound = 1; + + /* Look for highest matching version. */ + if (requireDebug) + printf("require: checking version %s against required %s\n", + currentFilename, version); + + switch ((status = compareVersions(currentFilename, version))) + { + case TESTVERS: /* test version found */ + case EXACT: /* exact match found */ + case MATCH: /* all given numbers match. */ + { + someArchFound = 1; + + if (requireDebug) + printf("require: %s %s may match %s\n", + module, currentFilename, version); + + /* Check if it has our EPICS version and architecture. */ + /* Even if it has no library, at least it has a dep file in the lib dir */ + + /* Step 1 : library file location */ + /* filename = "<dirname>/[dirlen]<module>/[modulediroffs]" */ + if (!TRY_FILE(modulediroffs, "%s" OSI_PATH_SEPARATOR LIBDIR "%s" OSI_PATH_SEPARATOR, + currentFilename, targetArch)) + /* filename = "<dirname>/[dirlen]<module>/[modulediroffs]<version>/lib/<targetArch>/" */ + { + if (requireDebug) + printf("require: %s %s has no support for %s %s\n", + module, currentFilename, epicsRelease, targetArch); + continue; + } + + if (status == EXACT) + { + if (requireDebug) + printf("require: %s %s matches %s exactly\n", + module, currentFilename, version); + /* We are done. */ + end = NULL; + break; + } + + /* Is it higher than the one we found before? */ + if (found && requireDebug) + printf("require: %s %s support for %s %s found, compare against previously found %s\n", + module, currentFilename, epicsRelease, targetArch, found); + if (!found || compareVersions(currentFilename, found) == HIGHER) + { + if (requireDebug) + printf("require: %s %s looks promising\n", module, currentFilename); + break; + } + if (requireDebug) + printf("require: version %s is lower than %s \n", currentFilename, found); + continue; + } + default: + { + if (requireDebug) + printf("require: %s %s does not match %s\n", + module, currentFilename, version); + continue; + } + } + /* we have found something (EXACT or MATCH) */ + free(founddir); + /* filename = "<dirname>/[dirlen]<module>/[modulediroffs]..." */ + if (asprintf(&founddir, "%.*s%s", modulediroffs, filename, currentFilename) < 0) + return errno; + /* founddir = "<dirname>/[dirlen]<module>/[modulediroffs]<version>" */ + found = founddir + modulediroffs; /* version part in the path */ + if (status == EXACT) + break; + } + END_DIR_LOOP + } + else + { + /* filename = "<dirname>/[dirlen]<module>/" */ + if (requireDebug) + printf("require: no %s directory\n", filename); + + /* try local/old style module only if no new style candidate has been found */ + if (!found) + { + /* look for dep file */ + releasediroffs = libdiroffs = dirlen; + if (TRY_FILE(dirlen, "%s%s.dep", module, versionstr)) /* filename = "<dirname>/[dirlen][releasediroffs][libdiroffs]<module>(-<version>)?.dep" */ { - if (requireDebug) - printf("require: found old style %s\n", filename); - printf ("Module %s%s found in %.*s\n", module, - versionstr, dirlen, filename); - goto checkdep; + if (requireDebug) + printf("require: found old style %s\n", filename); + printf("Module %s%s found in %.*s\n", module, + versionstr, dirlen, filename); + goto checkdep; } - /* look for library file */ - if (TRY_FILE(dirlen, PREFIX "%s" INFIX "%s%n" EXT, module, versionstr, &extoffs) - /* filename = "<dirname>/[dirlen][releasediroffs][libdiroffs]PREFIX<module>INFIX(-<version>)?[extoffs]EXT" */ + /* look for library file */ + if (TRY_FILE(dirlen, PREFIX "%s" INFIX "%s%n" EXT, module, versionstr, &extoffs) + /* filename = "<dirname>/[dirlen][releasediroffs][libdiroffs]PREFIX<module>INFIX(-<version>)?[extoffs]EXT" */ #ifdef vxWorks - /* try without extension */ - || (filename[dirlen + extoffs] = 0, fileExists(filename)) + /* try without extension */ + || (filename[dirlen + extoffs] = 0, fileExists(filename)) #endif - ) + ) { - if (requireDebug) - printf("require: found old style %s\n", filename); - printf ("Module %s%s found in %.*s\n", module, - versionstr, dirlen, filename); - goto loadlib; + if (requireDebug) + printf("require: found old style %s\n", filename); + printf("Module %s%s found in %.*s\n", module, + versionstr, dirlen, filename); + goto loadlib; } } } - /* filename = "<dirname>/[dirlen]..." */ - if (!found && requireDebug) - printf("require: no matching version in %.*s\n", dirlen, filename); + /* filename = "<dirname>/[dirlen]..." */ + if (!found && requireDebug) + printf("require: no matching version in %.*s\n", dirlen, filename); } - if (!found) + if (!found) { - if (someArchFound) - fprintf(stderr, "Module %s%s%s not available for %s\n(but maybe for other EPICS versions or architectures)\n", - module, version ? " version " : "", version ? version : "", targetArch); - else - if (someVersionFound) - fprintf(stderr, "Module %s%s%s not available (but other versions are available)\n", - module, version ? " version " : "", version ? version : ""); + if (someArchFound) + fprintf(stderr, "Module %s%s%s not available for %s\n(but maybe for other EPICS versions or architectures)\n", + module, version ? " version " : "", version ? version : "", targetArch); + else if (someVersionFound) + fprintf(stderr, "Module %s%s%s not available (but other versions are available)\n", + module, version ? " version " : "", version ? version : ""); else - fprintf(stderr, "Module %s%s%s not available\n", - module, version ? " version " : "", version ? version : ""); - return ifexists ? 0 : -1; + fprintf(stderr, "Module %s%s%s not available\n", + module, version ? " version " : "", version ? version : ""); + return ifexists ? 0 : -1; } - versionstr = ""; - - /* founddir = "<dirname>/[dirlen]<module>/<version>" */ - printf ("Module %s version %s found in %s" OSI_PATH_SEPARATOR "\n", module, found, founddir); - + versionstr = ""; + /* founddir = "<dirname>/[dirlen]<module>/<version>" */ + printf("Module %s version %s found in %s" OSI_PATH_SEPARATOR "\n", module, found, founddir); - /* Step 2 : Looking for Dep file */ - if (requireDebug) - printf("require: looking for dependency file\n"); + /* Step 2 : Looking for Dep file */ + if (requireDebug) + printf("require: looking for dependency file\n"); - if (!TRY_FILE(0, "%s" OSI_PATH_SEPARATOR "%n" LIBDIR "%s" OSI_PATH_SEPARATOR "%n%s.dep", - founddir, &releasediroffs, targetArch, &libdiroffs, module)) + if (!TRY_FILE(0, "%s" OSI_PATH_SEPARATOR "%n" LIBDIR "%s" OSI_PATH_SEPARATOR "%n%s.dep", + founddir, &releasediroffs, targetArch, &libdiroffs, module)) /* filename = "<dirname>/[dirlen]<module>/<version>/R<epicsRelease>/[releasediroffs]/lib/<targetArch>/[libdiroffs]/module.dep" */ { - fprintf(stderr, "Dependency file %s not found\n", filename); + fprintf(stderr, "Dependency file %s not found\n", filename); } - else + else { - checkdep: - /* filename = "<dirname>/[dirlen]<module>/<version>/R<epicsRelease>/[releasediroffs]/lib/<targetArch>/[libdiroffs]/module.dep" */ - /* or (old) "<dirname>/[dirlen]][releasediroffs][libdiroffs]<module>(-<version>)?.dep" */ - if (handleDependencies(module, filename) == -1) - return -1; + checkdep: + /* filename = "<dirname>/[dirlen]<module>/<version>/R<epicsRelease>/[releasediroffs]/lib/<targetArch>/[libdiroffs]/module.dep" */ + /* or (old) "<dirname>/[dirlen]][releasediroffs][libdiroffs]<module>(-<version>)?.dep" */ + if (handleDependencies(module, filename) == -1) + return -1; } - if (requireDebug) - printf("require: looking for library file\n"); + if (requireDebug) + printf("require: looking for library file\n"); - if (!(TRY_FILE(libdiroffs, PREFIX "%s" INFIX "%s%n" EXT, module, versionstr, &extoffs) + if (!(TRY_FILE(libdiroffs, PREFIX "%s" INFIX "%s%n" EXT, module, versionstr, &extoffs) #ifdef vxWorks - /* try without extension */ - || (filename[libdiroffs + extoffs] = 0, fileExists(filename)) + /* try without extension */ + || (filename[libdiroffs + extoffs] = 0, fileExists(filename)) #endif - )) + )) /* filename = "<dirname>/[dirlen]<module>/<version>/R<epicsRelease>/[releasediroffs]/lib/<targetArch>/[libdiroffs]/PREFIX<module>INFIX[extoffs](EXT)?" */ /* or (old) "<dirname>/[dirlen][releasediroffs][libdiroffs]PREFIX<module>INFIX(-<version>)?[extoffs](EXT)?" */ { - printf("Module %s has no library\n", module); + printf("Module %s has no library\n", module); } - else + else { - loadlib: - /* filename = "<dirname>/[dirlen]<module>/<version>/R<epicsRelease>/[releasediroffs]/lib/<targetArch>/[libdiroffs]/PREFIX<module>INFIX[extoffs]EXT" */ - /* or (old) "<dirname>/[dirlen][releasediroffs][libdiroffs]PREFIX<module>INFIX(-<version>)?[extoffs]EXT" */ - printf("Loading library %s\n", filename); - if ((libhandle = loadlib(filename)) == NULL) - return -1; - - /* now check what version we really got (with compiled-in version number) */ - if (asprintf (&symbolname, "_%sLibRelease", module) < 0) - return errno; - - found = (const char*) getAddress(libhandle, symbolname); - free(symbolname); - printf("Loaded %s version %s\n", module, found); - - /* check what we got */ - if (requireDebug) - printf("require: compare requested version %s with loaded version %s\n", version, found); - if (compareVersions(found, version) == MISMATCH) + loadlib: + /* filename = "<dirname>/[dirlen]<module>/<version>/R<epicsRelease>/[releasediroffs]/lib/<targetArch>/[libdiroffs]/PREFIX<module>INFIX[extoffs]EXT" */ + /* or (old) "<dirname>/[dirlen][releasediroffs][libdiroffs]PREFIX<module>INFIX(-<version>)?[extoffs]EXT" */ + printf("Loading library %s\n", filename); + if ((libhandle = loadlib(filename)) == NULL) + return -1; + + /* now check what version we really got (with compiled-in version number) */ + if (asprintf(&symbolname, "_%sLibRelease", module) < 0) + return errno; + + found = (const char *)getAddress(libhandle, symbolname); + free(symbolname); + printf("Loaded %s version %s\n", module, found); + + /* check what we got */ + if (requireDebug) + printf("require: compare requested version %s with loaded version %s\n", version, found); + if (compareVersions(found, version) == MISMATCH) { - fprintf(stderr, "Requested %s version %s not available, found only %s.\n", - module, version, found); - return -1; + fprintf(stderr, "Requested %s version %s not available, found only %s.\n", + module, version, found); + return -1; } - /* load dbd file */ - if (TRY_NONEMPTY_FILE(releasediroffs, "dbd" OSI_PATH_SEPARATOR "%s%s.dbd", module, versionstr) || - TRY_NONEMPTY_FILE(releasediroffs, "%s%s.dbd", module, versionstr) || - TRY_NONEMPTY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "dbd" OSI_PATH_SEPARATOR "%s%s.dbd", module, versionstr) || - TRY_NONEMPTY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "%s%s.dbd", module, versionstr) || - TRY_NONEMPTY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR ".." OSI_PATH_SEPARATOR "dbd" OSI_PATH_SEPARATOR "%s.dbd", module)) /* org EPICSbase */ + /* load dbd file */ + if (TRY_NONEMPTY_FILE(releasediroffs, "dbd" OSI_PATH_SEPARATOR "%s%s.dbd", module, versionstr) || + TRY_NONEMPTY_FILE(releasediroffs, "%s%s.dbd", module, versionstr) || + TRY_NONEMPTY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "dbd" OSI_PATH_SEPARATOR "%s%s.dbd", module, versionstr) || + TRY_NONEMPTY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "%s%s.dbd", module, versionstr) || + TRY_NONEMPTY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR ".." OSI_PATH_SEPARATOR "dbd" OSI_PATH_SEPARATOR "%s.dbd", module)) /* org EPICSbase */ { - printf("Loading dbd file %s\n", filename); - if (dbLoadDatabase(filename, NULL, NULL) != 0) + printf("Loading dbd file %s\n", filename); + if (dbLoadDatabase(filename, NULL, NULL) != 0) { - fprintf (stderr, "Error loading %s\n", filename); - return -1; + fprintf(stderr, "Error loading %s\n", filename); + return -1; } -#ifndef EPICS_3_13 - /* when dbd is loaded call register function */ - if (asprintf(&symbolname, "%s_registerRecordDeviceDriver", module) < 0) - return errno; + /* when dbd is loaded call register function */ + if (asprintf(&symbolname, "%s_registerRecordDeviceDriver", module) < 0) + return errno; - printf ("Calling function %s\n", symbolname); + printf("Calling function %s\n", symbolname); #ifdef vxWorks - { - FUNCPTR f = (FUNCPTR) getAddress(NULL, symbolname); - if (f) - f(pdbbase); - else - fprintf (stderr, "require: can't find %s function\n", symbolname); - } -#else /* !vxWorks */ - iocshCmd(symbolname); + { + FUNCPTR f = (FUNCPTR)getAddress(NULL, symbolname); + if (f) + f(pdbbase); + else + fprintf(stderr, "require: can't find %s function\n", symbolname); + } +#else /* !vxWorks */ + iocshCmd(symbolname); #endif /* !vxWorks */ - free(symbolname); -#endif /* !EPICS_3_13 */ + free(symbolname); } - else + else { - /* no dbd file, but that might be OK */ - printf("%s has no dbd file\n", module); + /* no dbd file, but that might be OK */ + printf("%s has no dbd file\n", module); } } - /* register module with path */ - filename[releasediroffs] = 0; - registerModule(module, found, filename); + /* register module with path */ + filename[releasediroffs] = 0; + registerModule(module, found, filename); } - status = 0; + status = 0; - if (requireDebug) - printf("require: looking for template directory\n"); - /* filename = "<dirname>/[dirlen]<module>/<version>/R<epicsRelease>/[releasediroffs]..." */ - if (!((TRY_FILE(releasediroffs, TEMPLATEDIR) || - TRY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR TEMPLATEDIR)) && setupDbPath(module, filename) == 0)) + if (requireDebug) + printf("require: looking for template directory\n"); + /* filename = "<dirname>/[dirlen]<module>/<version>/R<epicsRelease>/[releasediroffs]..." */ + if (!((TRY_FILE(releasediroffs, TEMPLATEDIR) || + TRY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR TEMPLATEDIR)) && + setupDbPath(module, filename) == 0)) { - /* if no template directory found, restore TEMPLATES to initial value */ - char *t; - t = getenv("TEMPLATES"); - if (globalTemplates && (!t || strcmp(globalTemplates, t) != 0)) - putenvprintf("TEMPLATES=%s", globalTemplates); + /* if no template directory found, restore TEMPLATES to initial value */ + char *t; + t = getenv("TEMPLATES"); + if (globalTemplates && (!t || strcmp(globalTemplates, t) != 0)) + putenvprintf("TEMPLATES=%s", globalTemplates); } - if (loaded && args == NULL) return 0; /* no need to execute startup script twice if not with new arguments */ - + if (loaded && args == NULL) + return 0; /* no need to execute startup script twice if not with new arguments */ - /* - * Even if it creates nothing, if they cannot find start up script, - * I would like to do silent the calling the startup scripts. - * E3 doesn't need this automatic execute them. - * - * Tuesday, October 17 13:51:23 CEST 2017, jhlee - */ - - // load startup script - // if (requireDebug) - // printf("require: looking for startup script\n"); - // filename = "<dirname>/[dirlen]<module>/<version>/R<epicsRelease>/[releasediroffs]db" - - - /* if (TRY_FILE(releasediroffs, "%s-%s.cmd", targetArch, epicsRelease) || */ - /* TRY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "%s-%s.cmd", targetArch, epicsRelease) || */ - /* TRY_FILE(releasediroffs, "%s-%s.cmd", targetArch, epicsBasetype) || */ - /* TRY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "%s-%s.cmd", targetArch, epicsBasetype) || */ - /* TRY_FILE(releasediroffs, "%s-%s.cmd", osClass, epicsRelease) || */ - /* TRY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "%s-%s.cmd", osClass, epicsRelease) || */ - /* TRY_FILE(releasediroffs, "%s-%s.cmd", osClass, epicsBasetype) || */ - /* TRY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "%s-%s.cmd", osClass, epicsBasetype) || */ - /* TRY_FILE(releasediroffs, "startup-%s.cmd", epicsRelease) || */ - /* TRY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "startup-%s.cmd", epicsRelease) || */ - /* TRY_FILE(releasediroffs, "startup-%s.cmd", epicsBasetype) || */ - /* TRY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "startup-%s.cmd", epicsBasetype) || */ - /* TRY_FILE(releasediroffs, "%s.cmd", targetArch) || */ - /* TRY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "%s.cmd", targetArch) || */ - /* TRY_FILE(releasediroffs, "%s.cmd", osClass) || */ - /* TRY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "%s.cmd", osClass) || */ - /* TRY_FILE(releasediroffs, "startup.cmd") || */ - /* TRY_FILE(releasediroffs, ".." OSI_PATH_SEPARATOR "startup.cmd") */ - /* ) */ - /* { */ - /* if (args) */ - /* printf("Executing %s with \"%s\"\n", filename, args); */ - /* else if (interruptAccept) */ - /* { */ - /* printf("Not executing %s after iocInit\n", filename); */ - /* return 0; */ - /* } */ - /* else */ - /* printf("Executing %s\n", filename); */ - /* if (runScript(filename, args) != 0) */ - /* fprintf (stderr, "Error executing %s\n", filename); */ - /* else */ - /* printf("Done with %s\n", filename); */ - /* } */ - - return status; + return status; } -#ifndef EPICS_3_13 static const iocshFuncDef requireDef = { - "require", 3, (const iocshArg *[]) { - &(iocshArg) { "module", iocshArgString }, - &(iocshArg) { "[version]", iocshArgString }, - &(iocshArg) { "[substitutions]", iocshArgString }, -}}; - -static void requireFunc (const iocshArgBuf *args) + "require", 3, (const iocshArg *[]){ + &(iocshArg){"module", iocshArgString}, + &(iocshArg){"[version]", iocshArgString}, + &(iocshArg){"[substitutions]", iocshArgString}, + }}; + +static void requireFunc(const iocshArgBuf *args) { require(args[0].sval, args[1].sval, args[2].sval); } static const iocshFuncDef libversionShowDef = { - "libversionShow", 1, (const iocshArg *[]) { - &(iocshArg) { "outputfile", iocshArgString }, -}}; + "libversionShow", 1, (const iocshArg *[]){ + &(iocshArg){"outputfile", iocshArgString}, + }}; -static void libversionShowFunc (const iocshArgBuf *args) +static void libversionShowFunc(const iocshArgBuf *args) { libversionShow(args[0].sval); } static const iocshFuncDef ldDef = { - "ld", 1, (const iocshArg *[]) { - &(iocshArg) { "library", iocshArgString }, -}}; + "ld", 1, (const iocshArg *[]){ + &(iocshArg){"library", iocshArgString}, + }}; -static void ldFunc (const iocshArgBuf *args) +static void ldFunc(const iocshArgBuf *args) { loadlib(args[0].sval); } static const iocshFuncDef pathAddDef = { - "pathAdd", 2, (const iocshArg *[]) { - &(iocshArg) { "ENV_VARIABLE", iocshArgString }, - &(iocshArg) { "directory", iocshArgString }, -}}; + "pathAdd", 2, (const iocshArg *[]){ + &(iocshArg){"ENV_VARIABLE", iocshArgString}, + &(iocshArg){"directory", iocshArgString}, + }}; -static void pathAddFunc (const iocshArgBuf *args) +static void pathAddFunc(const iocshArgBuf *args) { pathAdd(args[0].sval, args[1].sval); } @@ -1796,16 +1787,16 @@ static void pathAddFunc (const iocshArgBuf *args) static void requireRegister(void) { static int firstTime = 1; - if (firstTime) { + if (firstTime) + { firstTime = 0; - iocshRegister (&requireDef, requireFunc); - iocshRegister (&libversionShowDef, libversionShowFunc); - iocshRegister (&ldDef, ldFunc); - iocshRegister (&pathAddDef, pathAddFunc); + iocshRegister(&requireDef, requireFunc); + iocshRegister(&libversionShowDef, libversionShowFunc); + iocshRegister(&ldDef, ldFunc); + iocshRegister(&pathAddDef, pathAddFunc); registerExternalModules(); } } epicsExportRegistrar(requireRegister); epicsExportAddress(int, requireDebug); -#endif diff --git a/tools/iocsh.bash b/tools/iocsh.bash index 8ff7554079a15f31fb951b010ceff8a59581e0aa..09b1ab0d8c73549fc3e3ab98c990bac7307f90df 100755 --- a/tools/iocsh.bash +++ b/tools/iocsh.bash @@ -55,6 +55,16 @@ declare -r TMP_PATH="/tmp/systemd-private-e3-iocsh-$(whoami)" . ${SC_TOP}/iocsh_functions +# To get the absolute path where iocsh.bash is executed +IOCSH_TOP=${PWD} + +# Load any environment variables +if [ -f "$IOCSH_TOP/env.sh" ]; then + echo "Loading environment variables from $IOCSH_TOP/env.sh" + source "$IOCSH_TOP/env.sh" +fi + + BASECODE="$(basecode_generator)" check_mandatory_env_settings @@ -76,9 +86,6 @@ REQUIRE_IOC=$(require_ioc "${iocsh_bash_id}") mkdir -p ${TMP_PATH} IOC_STARTUP=$(mktemp -p ${TMP_PATH} -q --suffix=_iocsh_${SC_VERSION}) || die 1 "${SC_SCRIPTNAME} CANNOT create the startup file, please check the disk space"; -# -# To get the absolute path where iocsh.bash is executed -IOCSH_TOP=${PWD} # EPICS_DRIVER_PATH defined in iocsh and startup.script_common # Remember, driver is equal to module, so EPICS_DRIVER_PATH is the module directory diff --git a/tools/iocsh_functions b/tools/iocsh_functions index 19e89950fd5305e5f827704a3f073bbefe3ee7ce..7863b2bfd2e3635380fe533d033e6cfb6ea9533c 100644 --- a/tools/iocsh_functions +++ b/tools/iocsh_functions @@ -397,7 +397,7 @@ function loadFiles loadFiles $(cat ${file#@}) ;; ( *=* ) - echo -n $file | awk -F '=' '{printf "epicsEnvSet %s '\''%s'\''\n", $1, $2}' + echo -n $file | awk -F '=' '{printf "epicsEnvSet %s '\''%s'\''\n" $1 $2}' ;; ( -c ) shift @@ -428,7 +428,8 @@ function loadFiles ;; ( -l ) shift - printf "epicsEnvSet EPICS_DRIVER_PATH %s:${EPICS_DRIVER_PATH}\n", $1 + printf "epicsEnvSet EPICS_DRIVER_PATH %s:${EPICS_DRIVER_PATH}\n" $1 + EPICS_DRIVER_PATH="$1:$EPICS_DRIVER_PATH" ;; ( -dg ) shift @@ -481,7 +482,7 @@ function loadFiles if [[ ${BASECODE} -ge 03150002 ]]; then echo "iocshLoad '$file','$subst'" else - echo -n $subst | awk -F '=' -v 'RS=,' '{printf "epicsEnvSet %s '\''%s'\''\n", $1, $2}' + echo -n $subst | awk -F '=' -v 'RS=,' '{printf "epicsEnvSet %s '\''%s'\''\n" $1 $2}' echo "< '$file'" fi