Newer
Older
# Copyright (c) 2004 - 2017 Paul Scherrer Institute
# Copyright (c) 2017 - 2021 European Spallation Source ERIC
#
# The program is free software: you can redistribute
# it and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 2 of the
# License, or any newer version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see https://www.gnu.org/licenses/gpl-2.0.txt
#
#
# PSI original iocsh author : Dirk Zimoch
# ESS author : Jeong Han Lee
# ESS maintainer : Simon Rose
# Usage :
# e3_version="$(read_file_get_string "${file_name}" "E3_VERSION:=")";
function read_file_get_string {
local FILENAME=$1
local PREFIX=$2
}
# Base Code is defined with 8 digits numbers
# Two digits are enough to cover all others (I think)
# First Two : 00 (EPICS VERSION)
# Second Two : 00 (EPICS_REVISION)
# Third Two : 00 (EPICS_MODIFICATION)
function basecode_generator() { #@ Generator BASECODE
local epics_ver_maj epics_ver_mid epics_ver_min epics_ver_patch
epics_ver_maj="$(read_file_get_string "${EPICS_BASE}/configure/CONFIG_BASE_VERSION" "EPICS_VERSION = ")"
epics_ver_mid="$(read_file_get_string "${EPICS_BASE}/configure/CONFIG_BASE_VERSION" "EPICS_REVISION = ")"
epics_ver_min="$(read_file_get_string "${EPICS_BASE}/configure/CONFIG_BASE_VERSION" "EPICS_MODIFICATION = ")"
epics_ver_patch="$(read_file_get_string "${EPICS_BASE}/configure/CONFIG_BASE_VERSION" "EPICS_PATCH_LEVEL = ")"
if [[ ${#epics_ver_maj} -lt 2 ]]; then
epics_ver_maj="00${epics_ver_maj}"
epics_ver_maj="${epics_ver_maj: -2}"
fi
if [[ ${#epics_ver_mid} -lt 2 ]]; then
epics_ver_mid="00${epics_ver_mid}"
epics_ver_mid="${epics_ver_mid: -2}"
fi
if [[ ${#epics_ver_min} -lt 2 ]]; then
epics_ver_min="00${epics_ver_min}"
epics_ver_min="${epics_ver_min: -2}"
fi
if [[ ${#epics_ver_patch} -lt 2 ]]; then
epics_ver_patch="00${epics_ver_patch}"
epics_ver_patch="${epics_ver_patch: -2}"
fi
base_code=${epics_ver_maj}${epics_ver_mid}${epics_ver_min}${epics_ver_patch}
printf "%s : %s%s\n" "European Spallation Source ERIC" "$SC_SCRIPTNAME" ${SC_VERSION:+" ($SC_VERSION)"} >&2
declare -a var_list=()
var_list+=(EPICS_CA_REPEATER_PORT)
var_list+=(EPICS_CA_SERVER_PORT)
var_list+=(EPICS_TIMEZONE)
var_list+=(EPICS_TS_NTP_INET)
var_list+=(EPICS_AR_PORT)
var_list+=(EPICS_VERSION_MAJOR)
var_list+=(EPICS_VERSION_MIDDLE)
var_list+=(EPICS_VERSION_MINOR)
var_list+=(EPICS_VERSION_PATCH)
var_list+=(EPICS_VERSION_FULL)
for var in "${var_list[@]}"; do
printf "# %s=\"%s\"\n" "$var" "${!var}"
done
printf "#\n"
declare -a var_list=()
var_list+=(HOSTDISPLAY)
var_list+=(WINDOWID)
var_list+=(PWD)
var_list+=(USER)
var_list+=(LOGNAME)
var_list+=(EPICS_HOST_ARCH)
var_list+=(EPICS_BASE)
# REQUIRE
var_list+=(E3_REQUIRE_NAME)
var_list+=(E3_REQUIRE_VERSION)
var_list+=(E3_REQUIRE_LOCATION)
var_list+=(E3_REQUIRE_BIN)
var_list+=(E3_REQUIRE_DB)
var_list+=(E3_REQUIRE_DBD)
var_list+=(E3_REQUIRE_INC)
var_list+=(E3_REQUIRE_LIB)
# EPICS and others
var_list+=(EPICS_DRIVER_PATH)
var_list+=(EPICS_CA_AUTO_ADDR_LIST)
var_list+=(EPICS_CA_ADDR_LIST)
var_list+=(EPICS_PVA_AUTO_ADDR_LIST)
var_list+=(PATH)
printf "#\n"
printf "# Start at \"%s\"\n" "$(date +%Y-W%V-%b%d-%H%M-%S-%Z)"
printf "#\n"
printf "# Version information:\n"
printf "# %s : %s%s\n" "European Spallation Source ERIC" "$SC_SCRIPTNAME" ${SC_VERSION:+" ($SC_VERSION)"}
printf "#\n"
printf "# --->--> snip -->--> \n"
printf "# Please Use Version and other environment variables\n"
printf "# in order to report or debug this shell\n"
printf "#\n"
for var in "${var_list[@]}"; do
printf "# %s=\"%s\"\n" "$var" "${!var}"
done
printf "# --->--> snip -->--> \n"
printf "#\n"
# Ctrl+c : OK
# exit : OK
# kill softioc process : OK
# kill main process : Enter twice in terminal,
# close softIoc, but STARTUP file is remained.
local startup_file=$1
rm -f "${startup_file}"
# only clean terminal when stdout is opened on a terminal
# avoid "stty: standard input: Inappropriate ioctl for device" otherwise
[[ -t 1 ]] && stty sane
exit
function die() { #@ Print error message and exit with error code
#@ USAGE: die [errno [message]]
error=${1:-1}
## exits with 1 if error number not given
shift
[ -n "$*" ] &&
printf "%s%s: %s\n" "$SC_SCRIPTNAME" ${SC_VERSION:+" ($SC_VERSION)"} "$*" >&2
exit "$error"
local iocsh_ps1=""
local pid="$1"
# Keep only short hostname (without domain)
local host=${HOSTNAME%%.*}
iocsh_ps1+=${host:0:15}
iocsh_ps1+="-"
iocsh_ps1+=$pid
iocsh_ps1+=" > "
# Please look at the limitation in require.c in registerModule()
# /*
# Require DB has the following four PVs:
# - $(REQUIRE_IOC):$(MODULE)_VER
# - $(REQUIRE_IOC):MOD_VER
# - $(REQUIRE_IOC):VERSIONS
# - $(REQUIRE_IOC):MODULES
# We reserved 30 chars for :$(MODULE)_VER, so MODULE has the maximum 24 chars.
# And we've reserved for 30 chars for $(REQUIRE_IOC).
# So, the whole PV and record name in moduleversion.template has 59 + 1.
# e3-ioc-hash-hostname-pid fails when host has icslab-ser03 and IOCUSER-VIRTUALBOX
# so better to keep simple in case when hostname is long.
# And it has the limitation of PV length
# #define PVNAME_STRINGSZ 61 in EPICS_BASE/include/dbDefs.h
local require_ioc=""
# Test if IOCNAME is defined
if [ -z "${IOCNAME}" ]; then
local pid="$1"
# Keep only short hostname (without domain)
local hostname=${HOSTNAME%%.*}
# Record name should not have . character, because it is used inside record
require_ioc="REQMOD" # char 6 ( 6)
require_ioc+=":" # char 1 ( 7)
require_ioc+=${hostname:0:15} # char 15 (22)
require_ioc+="-" # char 1 (23)
require_ioc+=${pid} # char 7 (30), max pid in 64 bit 4194304 (7),
else
require_ioc=${IOCNAME:0:30}
fi
echo "${require_ioc}"
local libPrefix=lib
local libPostfix=.so
local libName=${libPrefix}${E3_REQUIRE_NAME}${libPostfix}
local require_lib=${E3_REQUIRE_LIB}/${EPICS_HOST_ARCH}/${libName}
local require_dbd=${E3_REQUIRE_DBD}/${E3_REQUIRE_NAME}.dbd
printf "# \n"
printf "# Load %s module, which has the version %s\n" "${E3_REQUIRE_NAME}" "${E3_REQUIRE_VERSION}"
printf "# \n"
printf "dlload %s\n" "${require_lib}"
printf "dbLoadDatabase %s\n" "${require_dbd}"
printf "%s_registerRecordDeviceDriver\n\n" "${E3_REQUIRE_NAME%-*}"
printf "# \n"
}
function check_mandatory_env_settings() {
declare -a var_list=()
var_list+=(EPICS_HOST_ARCH)
var_list+=(EPICS_BASE)
var_list+=(E3_REQUIRE_NAME)
var_list+=(E3_REQUIRE_BIN)
var_list+=(E3_REQUIRE_LIB)
var_list+=(E3_REQUIRE_DB)
var_list+=(E3_REQUIRE_DBD)
var_list+=(E3_REQUIRE_VERSION)
for var in "${var_list[@]}"; do
if [[ -z "${!var}" ]]; then
die 1 " $var is not defined!. Please source ${E3_REQUIRE_BIN}/setE3Env.bash "
fi
done

Anders Lindh Olsson
committed
if [[ -z "$IOCNAME" ]]; then
echo "Warning: environment variable IOCNAME is not set." >&2
else
echo "IOCNAME is set to $IOCNAME"
while [ "$#" -gt 0 ]; do
file=$1
case $file in
-rt | -RT | -realtime | --realtime)
REALTIME="RT"
__LOADER__="chrt --fifo 1 "
;;
@*)
loadFiles "$(cat "${file#@}")"
;;
*=*)
echo -n "$file" | awk -F '=' '{printf "epicsEnvSet %s '\''%s'\''\n" $1 $2}'
;;
-c)
shift
case $1 in
seq*)
esac
echo "$1"
;;
-s)
shift
if [ "$init" != NO ]; then
echo "iocInit"
init=NO
fi
echo "seq $1"
;;
-r)
shift
echo "require $1"
;;
-l)
shift
add_path="$1/$(basename "${EPICS_BASE}")/require-${E3_REQUIRE_VERSION}"
printf "epicsEnvSet EPICS_DRIVER_PATH %s:${EPICS_DRIVER_PATH}\n" "$add_path"
EPICS_DRIVER_PATH="$add_path:$EPICS_DRIVER_PATH"
;;
-dg)
if [[ -n "${2%--dgarg=*}" ]]; then
__LOADER__="gdb --eval-command run --args "
else
shift
if [[ -z "${1#*=}" ]]; then
else
__LOADER__="gdb ${1#*=} "
fi
if [[ -n "${2%--dvarg=*}" ]]; then
__LOADER__="valgrind --leak-check=full "
else
shift
if [[ -z "${1#*=}" ]]; then
else
__LOADER__="valgrind ${1#*=} "
fi
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
;;
-n)
__LOADER__="nice --10 "
shift
;;
-*)
printf "Unknown option %s\n\n" "$1" >&2
help
;;
*.so)
echo "dlload \"$file\""
;;
*)
subst=""
while [ "$#" -gt 1 ]; do
case $2 in
*=*)
subst="$subst,$2"
shift
;;
*)
break
;;
esac
done
subst=${subst#,}
case $file in
*.db | *.template)
echo "dbLoadRecords '$file','$subst'"
*.dbd)
# some dbd files must be loaded before main to take effect
echo "dbLoadDatabase '$file','$DBD','$subst'"
# Search for any instance of iocInit at the start of the line.
# If found, do not add the iocInit to the startup script. Any
# and the script will add an active iocInit.
if grep -q "^\s*iocInit\b" "$file"; then
local file=$1
local file_path=""
local file_top=""
local file_name=""
if [ -f "$file" ]; then
file_path="$(readlink -e "$file")"
file_top="${file_path%/*}"
file_name=${file##*/}
printf "# Set E3_CMD_TOP for the absolute path where %s exists\n" "$file_name"
printf "epicsEnvSet E3_CMD_TOP \"%s\"\n" "$file_top"
printf "#\n"
{
printf "\n"
printf "USAGE: iocsh.bash [startup files]\n"
printf "\n"
printf "Start the ESS iocsh.bash and load startup scripts.\n\n"
printf "Options:\n\n"
printf " -?, -h, --help Show this page and exit.\n"
printf " -v, --version Show version and exit.\n"
printf " -rt Execute in realtime mode.\n"
printf " (Also -RT, -realtime, --realtime)\n"
printf " -c 'cmd args' Ioc shell command.\n"
printf " -s 'prog m=v' Sequencer program (and arguments), run with 'seq'.\n"
printf " This forces an 'iocInit' before running the program.\n"
printf " -i Do not add iocInit. This option does not override\n"
printf " a valid iocInit in the startup script.\n"
printf " -r module[,ver] Module (optionally with version) loaded via 'require'.\n"
printf " -l 'cell path' Run Ioc with a cell path.\n"
printf " -dg [--dgarg='gdb-options'] Run with debugger gdb with user selected options or default option.\n"
printf " -dv [--dvarg='valgrind-options'] Run with valgrind with user selected options or default option.\n"
printf " -n Run with 'nice --10' (requires sudo).\n"
printf " @file More arguments are read from file.\n\n"
printf "Supported filetypes:\n\n"
printf " *.db, *.dbt, *.template loaded via 'dbLoadRecords'\n"
printf " *.subs, *.subst loaded via 'dbLoadTemplate'\n"
printf " *.dbd loaded via 'dbLoadDatabase'\n"
printf " *.so loaded via 'dlload'\n"
printf "\n"
printf "All other files are executed as startup scripts by the EPICS shell.\n"
printf "After a file you can specify substitutions like m1=v1 m2=v1 for that file.\n\n"
printf "Examples:\n"
printf " iocsh.bash st.cmd\n"
printf " iocsh.bash my_database.template P=XY M=3\n"
printf " iocsh.bash -r my_module,version -c 'initModule()'\n"
printf " iocsh.bash -c 'var requireDebug 1' st.cmd\n"
printf " iocsh.bash -i st.cmd\n"
printf " iocsh.bash -dv --dvarg='--vgdb=full'\n"
printf " iocsh.bash -dv st.cmd\n\n"