Merge branch '7.0' into PSI-7.0
This commit is contained in:
22
.github/codeql/config.yml
vendored
Normal file
22
.github/codeql/config.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
name: "CodeQL Config"
|
||||
|
||||
# Queries and the suites they belong to are documented at
|
||||
# https://codeql.github.com/codeql-query-help/cpp/
|
||||
|
||||
queries:
|
||||
- uses: security-and-quality
|
||||
# Choose the above from 3 query suites:
|
||||
# default
|
||||
# The default set of queries
|
||||
# security-extended
|
||||
# `default` suite plus lower severity and precision queries
|
||||
# security-and-quality
|
||||
# `security-extended`, plus maintainability and reliability queries
|
||||
|
||||
query-filters:
|
||||
-
|
||||
exclude:
|
||||
id: cpp/use-of-goto
|
||||
-
|
||||
exclude:
|
||||
problem.severity: recommendation
|
36
.github/workflows/ci-scripts-build.yml
vendored
36
.github/workflows/ci-scripts-build.yml
vendored
@ -15,7 +15,6 @@ on:
|
||||
- 'startup/*'
|
||||
- '.appveyor/*'
|
||||
- '.tools/*'
|
||||
- '.lgtm.yml'
|
||||
- '.gitattributes'
|
||||
- '**/*.html'
|
||||
- '**/*.md'
|
||||
@ -25,7 +24,6 @@ on:
|
||||
- 'startup/*'
|
||||
- '.appveyor/*'
|
||||
- '.tools/*'
|
||||
- '.lgtm.yml'
|
||||
- '.gitattributes'
|
||||
- '**/*.html'
|
||||
- '**/*.md'
|
||||
@ -79,81 +77,81 @@ jobs:
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "windows-x64-mingw"
|
||||
name: "Ub-20 gcc-9 + MinGW"
|
||||
name: "Ub-20 gcc + MinGW"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
cross: "windows-x64-mingw"
|
||||
name: "Ub-20 gcc-9 + MinGW, static"
|
||||
name: "Ub-20 gcc + MinGW, static"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
extra: "CMD_CXXFLAGS=-std=c++11"
|
||||
name: "Ub-20 gcc-9 C++11, static"
|
||||
name: "Ub-20 gcc C++11, static"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
extra: "CMD_CFLAGS=-funsigned-char CMD_CXXFLAGS=-funsigned-char"
|
||||
name: "Ub-20 gcc-9 unsigned char"
|
||||
name: "Ub-20 gcc unsigned char"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: clang
|
||||
configuration: default
|
||||
name: "Ub-20 clang-10"
|
||||
name: "Ub-20 clang"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: clang
|
||||
configuration: default
|
||||
extra: "CMD_CXXFLAGS=-std=c++11"
|
||||
name: "Ub-20 clang-10 C++11"
|
||||
name: "Ub-20 clang C++11"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "RTEMS-pc686-qemu@5"
|
||||
name: "Ub-20 gcc-9 + RT-5.1 pc686"
|
||||
name: "Ub-20 gcc + RT-5.1 pc686"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "RTEMS-beatnik@5"
|
||||
test: NO
|
||||
name: "Ub-20 gcc-9 + RT-5.1 beatnik"
|
||||
name: "Ub-20 gcc + RT-5.1 beatnik"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "RTEMS-xilinx_zynq_a9_qemu@5"
|
||||
test: NO
|
||||
name: "Ub-20 gcc-9 + RT-5.1 xilinx_zynq_a9_qemu"
|
||||
name: "Ub-20 gcc + RT-5.1 xilinx_zynq_a9_qemu"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
cross: "RTEMS-uC5282@5"
|
||||
test: NO
|
||||
name: "Ub-20 gcc-9 + RT-5.1 uC5282"
|
||||
name: "Ub-20 gcc + RT-5.1 uC5282"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
name: "Ub-20 gcc-9 + RT-4.10"
|
||||
name: "Ub-20 gcc + RT-4.10"
|
||||
cross: "RTEMS-pc386-qemu@4.10"
|
||||
test: NO
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
name: "Ub-20 gcc-9 + RT-4.9"
|
||||
name: "Ub-20 gcc + RT-4.9"
|
||||
cross: "RTEMS-pc386-qemu@4.9"
|
||||
|
||||
- os: macos-latest
|
||||
cmp: clang
|
||||
configuration: default
|
||||
name: "MacOS clang-12"
|
||||
name: "MacOS clang"
|
||||
|
||||
- os: windows-2019
|
||||
cmp: vs2019
|
||||
@ -198,7 +196,7 @@ jobs:
|
||||
cross: linux-arm@arm-linux-gnueabihf
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Automatic core dumper analysis
|
||||
@ -216,7 +214,7 @@ jobs:
|
||||
run: python .ci/cue.py -T 60M test
|
||||
- name: Upload tapfiles Artifact
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tapfiles ${{ matrix.name }}
|
||||
path: '**/O.*/*.tap'
|
||||
@ -283,7 +281,7 @@ jobs:
|
||||
# people would rather just break all existing scripts...
|
||||
[ -e /usr/bin/python ] || ln -sf python3 /usr/bin/python
|
||||
python --version
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Automatic core dumper analysis
|
||||
@ -300,7 +298,7 @@ jobs:
|
||||
run: python .ci/cue.py -T 20M test
|
||||
- name: Upload tapfiles Artifact
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tapfiles ${{ matrix.name }}
|
||||
path: '**/O.*/*.tap'
|
||||
|
64
.github/workflows/codeql.yml
vendored
Normal file
64
.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: 7.0
|
||||
tags: 'R7.0.*'
|
||||
pull_request:
|
||||
branches: 7.0
|
||||
paths-ignore:
|
||||
- '.appveyor/*'
|
||||
- '.tools/*'
|
||||
- 'documentation/*'
|
||||
- 'startup/*'
|
||||
- '**/*.md'
|
||||
- '**/*.html'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
# - windows-latest
|
||||
# Supported by CodeQL which would check the Windows
|
||||
# port, but needs more work here to set it up
|
||||
|
||||
permissions:
|
||||
# Required for all workflows:
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ cpp ]
|
||||
|
||||
steps:
|
||||
- name: Checkout Repositories
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: false
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install --yes libreadline-dev
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/config.yml
|
||||
|
||||
- name: Build C/C++
|
||||
run: |
|
||||
echo '*** Building with these versions >>>'
|
||||
g++ --version
|
||||
make --version
|
||||
perl --version
|
||||
echo '<<<'
|
||||
make -sj2 || echo '*** Ignoring build failure for CodeQL ***'
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,6 +3,7 @@
|
||||
/lib/
|
||||
/db/
|
||||
/dbd/
|
||||
/doc/
|
||||
/html/
|
||||
/include/
|
||||
/templates/
|
||||
|
50
.lgtm.yml
50
.lgtm.yml
@ -1,50 +0,0 @@
|
||||
# Configuration for lgtm.com
|
||||
#
|
||||
|
||||
path_classifiers:
|
||||
test:
|
||||
- exclude: /
|
||||
- test
|
||||
- "modules/*/test*"
|
||||
library:
|
||||
- modules/libcom/src/yacc
|
||||
- modules/libcom/src/flex
|
||||
template:
|
||||
- src/template
|
||||
- modules/ca/src/template
|
||||
- modules/database/src/template
|
||||
|
||||
extraction:
|
||||
cpp:
|
||||
prepare:
|
||||
packages:
|
||||
- "libreadline-dev"
|
||||
index:
|
||||
build_command:
|
||||
- "g++ --version"
|
||||
- "make --version"
|
||||
- "perl --version"
|
||||
- "make -sj2 || echo '*** Build failed, ignored for lgtm ***'"
|
||||
|
||||
python:
|
||||
index:
|
||||
include:
|
||||
- src/tools
|
||||
|
||||
# Interpreted languages to be excluded
|
||||
javascript:
|
||||
index:
|
||||
exclude:
|
||||
- "*"
|
||||
|
||||
# Compiled languages to be excluded
|
||||
java:
|
||||
index:
|
||||
build_command: "echo No Java code in this project"
|
||||
csharp:
|
||||
index:
|
||||
build_command: "echo No C# code in this project"
|
||||
go:
|
||||
index:
|
||||
build_command: "echo No Go code in this project"
|
||||
|
36
.readthedocs.yaml
Normal file
36
.readthedocs.yaml
Normal file
@ -0,0 +1,36 @@
|
||||
# .readthedocs.yml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.9"
|
||||
apt_packages:
|
||||
- graphviz
|
||||
- rsync
|
||||
jobs:
|
||||
pre_build:
|
||||
- make inc
|
||||
- make -C documentation rtd
|
||||
|
||||
# Build documentation in the documentation/O.Common directory with Sphinx
|
||||
sphinx:
|
||||
configuration: documentation/O.Common/rtd-src/conf.py
|
||||
|
||||
# Build documentation with MkDocs
|
||||
#mkdocs:
|
||||
# configuration: mkdocs.yml
|
||||
|
||||
# Optionally build your docs in additional formats such as PDF and ePub
|
||||
#formats: []
|
||||
|
||||
submodules:
|
||||
exclude: all
|
||||
|
||||
python:
|
||||
install:
|
||||
- requirements: documentation/requirements.txt
|
@ -45,10 +45,13 @@ FIND_PM = $(wildcard $(EPICS_BASE)/lib/perl/$(1))
|
||||
#---------------------------------------------------------------
|
||||
# EPICS Base build tools and tool flags
|
||||
|
||||
PODTOMD_pl = $(TOOLS)/podToMD.pl
|
||||
PODTOMD = $(PERL) $(PODTOMD_pl)
|
||||
PODTOHTML_pl = $(TOOLS)/podToHtml.pl
|
||||
PODTOHTML_dep = $(PODTOHTML_pl) $(call FIND_PM,EPICS/PodHtml.pm)
|
||||
PODTOHTML = $(PERL) $(PODTOHTML_pl)
|
||||
CONVERTRELEASE = $(PERL) $(call FIND_TOOL,convertRelease.pl)
|
||||
FILTERMAKEFLAGS = $(PERL) $(call FIND_TOOL,filterMakeflags.pl)
|
||||
FULLPATHNAME = $(PERL) $(TOOLS)/fullPathName.pl
|
||||
GENVERSIONHEADER = $(PERL) $(TOOLS)/genVersionHeader.pl $(QUIET_FLAG) $(QUESTION_FLAG)
|
||||
|
||||
@ -65,6 +68,24 @@ INSTALL_LIBRARY = $(INSTALL)
|
||||
MKMF = $(PERL) $(TOOLS)/mkmf.pl
|
||||
REPLACEVAR = $(PERL) $(TOOLS)/replaceVAR.pl
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# How to portably check the flags to make
|
||||
# GNUmake versions before 4.0 gave different values
|
||||
makeflags := $(shell $(FILTERMAKEFLAGS) $(MAKEFLAGS))
|
||||
define checkflags
|
||||
make-$1 := $(findstring $1,$(makeflags))
|
||||
endef
|
||||
# This is extensible to most single letter flags:
|
||||
$(foreach flag,s q, $(eval $(call checkflags,$(flag))))
|
||||
|
||||
# Silent builds - suppress messages during 'make -s'
|
||||
NOP = :
|
||||
ECHO = @$(if $(make-s),$(NOP),echo)
|
||||
QUIET_FLAG := $(if $(make-s),-q,)
|
||||
|
||||
# Convert 'make -q' flag into '-i' for genVersionHeader.pl
|
||||
QUESTION_FLAG := $(if $(make-q),-i,)
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# tools for cleaning out unwanted files
|
||||
CVSCLEAN = $(call FIND_TOOL,cvsclean.pl)
|
||||
|
@ -81,23 +81,6 @@ FINAL_LOCATION = $(INSTALL_ABSOLUTE)
|
||||
# IOC's view of install path
|
||||
IOCS_APPL_TOP = $(INSTALL_ABSOLUTE)
|
||||
|
||||
#-------------------------------------------------------
|
||||
# How to portably check the flags to make
|
||||
makeflags := $(firstword $(filter-out -,$(filter-out --%,$(MAKEFLAGS))))
|
||||
define checkflags
|
||||
make-$1 := $(findstring $1,$(makeflags))
|
||||
endef
|
||||
# This is extensible to most single letter flags:
|
||||
$(foreach flag,s q, $(eval $(call checkflags,$(flag))))
|
||||
|
||||
# Silent builds - suppress messages during 'make -s'
|
||||
NOP = :
|
||||
ECHO = @$(if $(make-s),$(NOP),echo)
|
||||
QUIET_FLAG := $(if $(make-s),-q,)
|
||||
|
||||
# Convert 'make -q' flag into '-i' for genVersionHeader.pl
|
||||
QUESTION_FLAG := $(if $(make-q),-i,)
|
||||
|
||||
#-------------------------------------------------------
|
||||
ifdef T_A
|
||||
|
||||
@ -486,4 +469,9 @@ COMMON_INC += $(filter $(COMMON_DIR)/%, \
|
||||
$(foreach dir, $(ALL_SRC_DIRS), \
|
||||
$(addsuffix /$(file), $(dir)))) $(COMMON_DIR)/$(file))))
|
||||
|
||||
COMMON_DOCS += $(filter $(COMMON_DIR)/%, \
|
||||
$(foreach file, $(DOCS), \
|
||||
$(firstword $(wildcard $(file) \
|
||||
$(foreach dir, $(ALL_SRC_DIRS), \
|
||||
$(addsuffix /$(file), $(dir)))) $(COMMON_DIR)/$(file))))
|
||||
endif
|
||||
|
@ -12,6 +12,7 @@ DBDTORECTYPEH_pl = $(EPICS_BASE_HOST_BIN)/dbdToRecordtypeH.pl
|
||||
DBDTORECTYPEH_dep = $(DBDTORECTYPEH_pl) $(call FIND_PM,DBD/Rec*.pm)
|
||||
DBDTOMENUH_pl = $(EPICS_BASE_HOST_BIN)/dbdToMenuH.pl
|
||||
DBDTOMENUH_dep = $(DBDTOMENUH_pl) $(call FIND_PM,DBD/Menu.pm)
|
||||
DBDTOMD_pl = $(EPICS_BASE_HOST_BIN)/dbdToMD.pl
|
||||
DBDTOHTML_pl = $(EPICS_BASE_HOST_BIN)/dbdToHtml.pl
|
||||
DBDTOHTML_dep = $(DBDTOHTML_pl) $(call FIND_PM,EPICS/Pod*Html.pm)
|
||||
REGRECDEVDRV_pl = $(EPICS_BASE_HOST_BIN)/registerRecordDeviceDriver.pl
|
||||
@ -21,6 +22,7 @@ REGRECDEVDRV_dep = $(REGRECDEVDRV_pl)
|
||||
DBEXPAND = $(PERL) $(DBDEXPAND_pl)
|
||||
DBTORECORDTYPEH = $(PERL) $(DBDTORECTYPEH_pl)
|
||||
DBTOMENUH = $(PERL) $(DBDTOMENUH_pl)
|
||||
DBDTOMD = $(PERL) $(DBDTOMD_pl)
|
||||
DBDTOHTML = $(PERL) $(DBDTOHTML_pl)
|
||||
REGISTERRECORDDEVICEDRIVER = $(PERL) $(REGRECDEVDRV_pl)
|
||||
|
||||
|
@ -197,7 +197,7 @@ endif
|
||||
# build dependancies, clean rule
|
||||
|
||||
inc: $(COMMON_INC) $(INSTALL_INC) $(COMMON_DBDS) $(COMMON_DBDCATS) \
|
||||
$(INSTALL_DBDS) $(INSTALL_DBD_INSTALLS)
|
||||
$(INSTALL_DBDS) $(INSTALL_DBD_INSTALLS) $(COMMON_DOCS)
|
||||
|
||||
build: $(COMMON_DBS) $(INSTALL_DBS) \
|
||||
$(DBDDEPENDS_FILES) $(TARGETS) \
|
||||
@ -427,6 +427,26 @@ $(foreach file, $(DBD_INSTALLS), $(eval $(call DBD_INSTALLS_template, $(file))))
|
||||
|
||||
.PRECIOUS: $(COMMON_DBDS) $(COMMON_DIR)/%.dbd
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Markdown files
|
||||
|
||||
$(COMMON_DIR)/%.md: %.dbd.pod $(DBDTOMD_pl)
|
||||
@$(RM) $(notdir $@)
|
||||
$(DBDTOMD) $(DBDFLAGS) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%.md: %.pod $(PODTOMD_pl)
|
||||
@$(RM) $(notdir $@)
|
||||
$(PODTOMD) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
$(COMMON_DIR)/%.md: ../%.pl $(PODTOMD_pl)
|
||||
@$(RM) $(notdir $@)
|
||||
$(PODTOMD) -o $(notdir $@) $<
|
||||
@$(MV) $(notdir $@) $@
|
||||
|
||||
.PRECIOUS: $(COMMON_DIR)/%.md
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# HTML files
|
||||
|
||||
|
@ -22,7 +22,8 @@ vpath %.cpp $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.rc $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.h $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.hpp $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.html $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.html $(USR_VPATH) $(ALL_SRC_DIRS) $(COMMON_DIR)
|
||||
vpath %.md $(USR_VPATH) $(ALL_SRC_DIRS) $(COMMON_DIR)
|
||||
vpath %.skel.static $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.y $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
vpath %.l $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
@ -128,7 +129,7 @@ endif
|
||||
#---------------------------------------------------------------
|
||||
# Read dependency files
|
||||
|
||||
ifneq (inc,$(strip $(MAKECMDGOALS)))
|
||||
ifneq ($(filter-out inc,$(strip $(MAKECMDGOALS))),)
|
||||
ifneq (,$(strip $(HDEPENDS_FILES)))
|
||||
$(filter-out $(wildcard *$(DEP)), $(HDEPENDS_FILES)): | $(COMMON_INC)
|
||||
-include $(HDEPENDS_FILES)
|
||||
@ -182,12 +183,12 @@ build: $(OBJSNAME) $(LIBTARGETS) $(PRODTARGETS) $(TESTPRODTARGETS) \
|
||||
$(TARGETS) $(TESTSCRIPTS) $(INSTALL_LIB_INSTALLS)
|
||||
|
||||
inc: $(COMMON_INC) $(INSTALL_INC) $(INSTALL_CONFIGS) $(INSTALLS_CFG) \
|
||||
$(INSTALL_HTMLS) $(INSTALLS_PERL_MODULES) $(INSTALL_SCRIPTS)
|
||||
$(INSTALL_HTMLS) $(INSTALLS_PERL_MODULES) $(INSTALL_SCRIPTS) \
|
||||
$(INSTALL_DOCS)
|
||||
|
||||
buildInstall: \
|
||||
$(INSTALL_PROD) $(INSTALL_MUNCHS) \
|
||||
$(INSTALL_TCLLIBS) $(INSTALL_TCLINDEX) \
|
||||
$(INSTALL_DOCS) \
|
||||
$(INSTALL_OBJS) \
|
||||
$(INSTALL_TEMPLATE) \
|
||||
$(INSTALL_BIN_INSTALLS)
|
||||
@ -575,6 +576,10 @@ $(INSTALL_INCLUDE)/compiler/$(CMPLR_CLASS)/%: %
|
||||
$(ECHO) "Installing compiler dependent include file $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_DOC)/%: $(COMMON_DIR)/%
|
||||
$(ECHO) "Installing generated doc $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D)
|
||||
|
||||
$(INSTALL_DOC)/%: %
|
||||
$(ECHO) "Installing doc $@"
|
||||
@$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(INSTALL_DOC)
|
||||
|
@ -65,7 +65,7 @@ CXXFLAGS = $($(BUILD_CLASS)_CXXFLAGS) $(POSIX_CXXFLAGS) $(OPT_CXXFLAGS)\
|
||||
$(USR_CXXFLAGS) $(CMD_CXXFLAGS) $(ARCH_DEP_CXXFLAGS) $(CODE_CXXFLAGS)\
|
||||
$(STATIC_CXXFLAGS) $(OP_SYS_CXXFLAGS) $(LIBRARY_SRC_CFLAGS)
|
||||
|
||||
LDFLAGS = $(OPT_LDFLAGS) $(TARGET_LDFLAGS) $(USR_LDFLAGS) $(CMD_LDFLAGS)\
|
||||
LDFLAGS += $(OPT_LDFLAGS) $(TARGET_LDFLAGS) $(USR_LDFLAGS) $(CMD_LDFLAGS)\
|
||||
$(POSIX_LDFLAGS) $(ARCH_DEP_LDFLAGS) $(DEBUG_LDFLAGS) $(OP_SYS_LDFLAGS)\
|
||||
$($(BUILD_CLASS)_LDFLAGS) $(RUNTIME_LDFLAGS) $(CODE_LDFLAGS)
|
||||
|
||||
@ -102,15 +102,47 @@ OS_CLASS = RTEMS
|
||||
# Operating system compile & link flags
|
||||
OP_SYS_CFLAGS += -D__LINUX_ERRNO_EXTENSIONS__
|
||||
|
||||
OP_SYS_CFLAGS_NET_yes = -DRTEMS_LEGACY_STACK
|
||||
OP_SYS_CFLAGS += $(OP_SYS_CFLAGS_NET_$(RTEMS_HAS_NETWORKING))
|
||||
|
||||
ifeq ($(RTEMS_HAS_POSIX_API),yes)
|
||||
POSIX_CPPFLAGS = -D_GNU_SOURCE -D_DEFAULT_SOURCE
|
||||
# Has RTEMS been built with the internal legacy stack?
|
||||
ifeq ($(RTEMS_LEGACY_NETWORKING_INTERNAL),yes)
|
||||
RTEMS_HAS_NETWORKING = yes
|
||||
RTEMS_NETWORKING = legacy_internal
|
||||
endif
|
||||
|
||||
OP_SYS_LDLIBS_posix_NET_yes = -ltftpfs -lnfs -lz -ltelnetd
|
||||
OP_SYS_LDLIBS_posix_NET_no = -ltftpfs -lbsd -lz
|
||||
# Has RTEMS been built with the legacy stack as a separate package?
|
||||
ifeq ($(RTEMS_LEGACY_NETWORKING),yes)
|
||||
RTEMS_HAS_NETWORKING = yes
|
||||
RTEMS_NETWORKING = legacy
|
||||
endif
|
||||
|
||||
# Has RTEMS been built with the libbsd stack as a separate package?
|
||||
ifeq ($(RTEMS_BSD_NETWORKING),yes)
|
||||
RTEMS_HAS_NETWORKING = yes
|
||||
RTEMS_NETWORKING = bsd
|
||||
endif
|
||||
|
||||
RTEMS_LEGACY_NET_LIB_no=
|
||||
|
||||
# Legacy network with RTEMS 5 and earlier
|
||||
RTEMS_NET_LIB_legacy_internal=-lnfs
|
||||
OP_SYS_CFLAGS_NET_legacy_internal = -DRTEMS_LEGACY_STACK
|
||||
|
||||
# Legacy network with RTEMS 6 is a separate package and library
|
||||
RTEMS_NET_LIB_legacy=-lnfs -lnetworking -lnfs
|
||||
OP_SYS_CFLAGS_NET_legacy = -DRTEMS_LEGACY_STACK
|
||||
|
||||
# LibBSD network with RTEMS 5 and 6 is a separate package and library
|
||||
RTEMS_NET_LIB_bsd=-lbsd
|
||||
OP_SYS_CFLAGS_NET_bsd = -DRTEMS_LIBBSD_STACK
|
||||
|
||||
# Set the networking flags
|
||||
OP_SYS_CFLAGS += $(OP_SYS_CFLAGS_NET_$(RTEMS_NETWORKING))
|
||||
|
||||
POSIX_CPPFLAGS_posix = -D_GNU_SOURCE -D_DEFAULT_SOURCE
|
||||
POSIX_CPPFLAGS = $(POSIX_CPPFLAGS_$(OS_API))
|
||||
|
||||
OP_SYS_LDLIBS_posix_NET_yes = -ltftpfs -lz -ltelnetd
|
||||
OP_SYS_LDLIBS_posix_NET_yes += $(RTEMS_NET_LIB_$(RTEMS_NETWORKING))
|
||||
OP_SYS_LDLIBS_posix_NET_no = -ltftpfs -lz
|
||||
OP_SYS_LDLIBS_score_NET_yes = -lnfs
|
||||
OP_SYS_LDLIBS_score_NET_no = -lnfs
|
||||
OP_SYS_LDLIBS += -lrtemsCom -lCom
|
||||
|
@ -1,7 +1,6 @@
|
||||
#
|
||||
# Author: Matt Rippa
|
||||
#
|
||||
RTEMS_BSP = mvme2307
|
||||
RTEMS_TARGET_CPU = powerpc
|
||||
ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL
|
||||
ARCH_DEP_CFLAGS += -DHAVE_PPCBUG
|
||||
@ -23,3 +22,9 @@ define MUNCH_CMD
|
||||
endef
|
||||
|
||||
include $(CONFIG)/os/CONFIG.Common.RTEMS
|
||||
|
||||
ifeq ($(shell test $(RTEMS_VERSION) -ge 5; echo $$?),0)
|
||||
RTEMS_BSP = mvme2700
|
||||
else
|
||||
RTEMS_BSP = mvme2307
|
||||
endif
|
||||
|
@ -25,7 +25,7 @@ include $(CONFIG)/os/CONFIG.Common.RTEMS
|
||||
OP_SYS_LDFLAGS += -Wl,-Ttext,0x100000
|
||||
|
||||
# This check must appear after the above include
|
||||
ifeq ($(RTEMS_VERSION),5)
|
||||
ifeq ($(shell test $(RTEMS_VERSION) -ge 5; echo $$?),0)
|
||||
$(info *** This target is not compatible with the configured RTEMS version.)
|
||||
$(info *** Build the RTEMS-pc686 (-qemu) target for RTEMS 5.x)
|
||||
$(error Can't continue)
|
||||
|
@ -32,7 +32,7 @@ OP_SYS_LDFLAGS += -Wl,-Ttext,0x100000
|
||||
|
||||
|
||||
# This check must appear after the above include
|
||||
ifneq ($(firstword $(subst ., ,$(RTEMS_VERSION))),5)
|
||||
ifeq ($(shell test $(RTEMS_VERSION) -lt 5; echo $$?),0)
|
||||
$(info *** This target is not compatible with the configured RTEMS version.)
|
||||
$(info *** Build the RTEMS-pc386 (-qemu) target for RTEMS 4.x)
|
||||
$(error Can't continue)
|
||||
|
@ -2,13 +2,23 @@
|
||||
# Definitions for freebsd-x86_64 host - freebsd-x86_64 target builds
|
||||
# Sites may override these definitions in CONFIG_SITE.freebsd-x86_64.freebsd-x86_64
|
||||
#-------------------------------------------------------
|
||||
GNU_DIR=/usr/local
|
||||
GNU_DIR=/usr
|
||||
|
||||
# Include common gnu compiler definitions
|
||||
include $(CONFIG)/CONFIG.gnuCommon
|
||||
|
||||
GNU_BIN = $(GNU_DIR)/bin
|
||||
GNU_LIB = $(GNU_DIR)/lib
|
||||
|
||||
CMPLR_CLASS = clang
|
||||
|
||||
CC = $(GNU_BIN)/$(CMPLR_PREFIX)cc$(CMPLR_SUFFIX)
|
||||
CCC = $(GNU_BIN)/$(CMPLR_PREFIX)c++$(CMPLR_SUFFIX)
|
||||
CPP = $(CC) -x c -E
|
||||
|
||||
GNU_LDLIBS_YES =
|
||||
|
||||
STATIC_LDFLAGS_YES= -Wl,-Bstatic
|
||||
STATIC_LDFLAGS_NO=
|
||||
STATIC_LDLIBS_YES= -Wl,-Bdynamic
|
||||
STATIC_LDLIBS_NO=
|
||||
|
||||
|
@ -30,9 +30,26 @@ MSVC_VER = _MSC_VER
|
||||
#ifdef __rtems__
|
||||
#include <rtems/score/cpuopts.h>
|
||||
# if __RTEMS_MAJOR__>=5
|
||||
OS_API = posix
|
||||
OS_API = posix
|
||||
# else
|
||||
OS_API = score
|
||||
OS_API = score
|
||||
# endif
|
||||
# if defined(RTEMS_NETWORKING)
|
||||
/* legacy stack circa RTEMS <= 5 and networking internal to RTEMS */
|
||||
RTEMS_LEGACY_NETWORKING_INTERNAL = yes
|
||||
# else
|
||||
# if !defined(__has_include)
|
||||
/* assume old GCC implies RTEMS < 5 with mis-configured BSP */
|
||||
# error rebuild BSP with --enable-network
|
||||
# elif __has_include(<machine/rtems-net-legacy.h>)
|
||||
/* legacy stack circa RTEMS > 5 */
|
||||
RTEMS_LEGACY_NETWORKING = yes
|
||||
# elif __has_include(<machine/rtems-bsd-version.h>)
|
||||
/* libbsd stack */
|
||||
RTEMS_BSD_NETWORKING = yes
|
||||
# else
|
||||
# error Cannot determine RTEMS network configuration
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -51,4 +68,3 @@ COMMANDLINE_LIBRARY ?= $(strip $(if $(wildcard $(if $(GNU_DIR),$(GNU_DIR)/includ
|
||||
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE>2
|
||||
OP_SYS_CPPFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
|
||||
#endif
|
||||
|
||||
|
3
documentation/.gitignore
vendored
3
documentation/.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
*.db
|
||||
epics-base.tag
|
||||
html/
|
@ -759,10 +759,10 @@ WARN_LOGFILE =
|
||||
# spaces.
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = ../mainpage.dox \
|
||||
../RELEASE_NOTES.md \
|
||||
INPUT = ../RELEASE_NOTES.md \
|
||||
../README.md \
|
||||
@TOP@/include
|
||||
@TOP@/include \
|
||||
@TOP@/doc
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
@ -1833,7 +1833,7 @@ MAN_LINKS = NO
|
||||
# captures the structure of the code including all documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
GENERATE_XML = NO
|
||||
GENERATE_XML = YES
|
||||
|
||||
# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
|
||||
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||
@ -1841,7 +1841,7 @@ GENERATE_XML = NO
|
||||
# The default directory is: xml.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_OUTPUT = xml
|
||||
XML_OUTPUT = @RTD_SRC@/xml
|
||||
|
||||
# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
|
||||
# listings (including syntax highlighting and cross-referencing information) to
|
||||
@ -1946,7 +1946,7 @@ ENABLE_PREPROCESSING = YES
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
MACRO_EXPANSION = NO
|
||||
MACRO_EXPANSION = YES
|
||||
|
||||
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
|
||||
# the macro expansion is limited to the macros specified with the PREDEFINED and
|
||||
@ -1986,7 +1986,17 @@ INCLUDE_FILE_PATTERNS =
|
||||
# recursively expanded use the := operator instead of the = operator.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
PREDEFINED = __cplusplus
|
||||
PREDEFINED = __cplusplus \
|
||||
LIBCOM_API \
|
||||
DBCORE_API \
|
||||
LIBCA_API \
|
||||
DBRECSTD_API \
|
||||
EPICS_ALWAYS_INLINE \
|
||||
epicsShareExtern \
|
||||
epicsShareClass \
|
||||
epicsShareFunc \
|
||||
epicsShareAPI \
|
||||
epicsStdCall
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||
# tag can be used to specify a list of macro names that should be expanded. The
|
||||
|
4
documentation/HEADER_h.md
Normal file
4
documentation/HEADER_h.md
Normal file
@ -0,0 +1,4 @@
|
||||
# @HEADER@.h
|
||||
|
||||
```{doxygenfile} @HEADER@.h
|
||||
```
|
@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>Known Problems in EPICS 7.0.3.1</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1 style="text-align: center">EPICS 7.0.3.1: Known Problems</h1>
|
||||
|
||||
<p>Any patch files linked below should be applied at the root of the
|
||||
base-7.0.3.1 tree. Download them, then use the GNU Patch program as
|
||||
follows:</p>
|
||||
|
||||
<blockquote><pre>% <b>cd <i>/path/to/</i>base-7.0.3.1</b>
|
||||
% <b>patch -p1 < <i>/path/to/</i>file.patch</b></pre></blockquote>
|
||||
|
||||
<p>The following problems were known by the developers at the time of this
|
||||
release:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<!-- Items added after release should be formatted thusly:
|
||||
<li>YYYY-MM-DD: Description of problem.
|
||||
<a href="fix.patch">This patch</a> fixes the problem.
|
||||
...</li>
|
||||
-->
|
||||
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -7,25 +7,168 @@ EXPAND_ME += EPICS_REVISION
|
||||
EXPAND_ME += EPICS_MODIFICATION
|
||||
EXPAND_ME += EPICS_PATCH_LEVEL
|
||||
EXPAND_ME += OS_CLASS CMPLR_CLASS
|
||||
EXPAND_ME += RTD_SRC
|
||||
|
||||
HTMLS += ComponentReference.html
|
||||
DOXYGEN ?= doxygen
|
||||
|
||||
TARGETS += doxygen
|
||||
libcom_HEADERS += adjustment
|
||||
libcom_HEADERS += alarm
|
||||
libcom_HEADERS += alarmString
|
||||
libcom_HEADERS += asTrapWrite
|
||||
libcom_HEADERS += bucketLib
|
||||
libcom_HEADERS += cantProceed
|
||||
libcom_HEADERS += compilerDependencies
|
||||
libcom_HEADERS += cvtFast
|
||||
libcom_HEADERS += dbmf
|
||||
libcom_HEADERS += devLibVME
|
||||
libcom_HEADERS += devLibVMEImpl
|
||||
libcom_HEADERS += ellLib
|
||||
libcom_HEADERS += envDefs
|
||||
libcom_HEADERS += epicsAlgorithm
|
||||
libcom_HEADERS += epicsAssert
|
||||
libcom_HEADERS += epicsAtomic
|
||||
libcom_HEADERS += epicsEvent
|
||||
libcom_HEADERS += epicsExit
|
||||
libcom_HEADERS += epicsExport
|
||||
libcom_HEADERS += epicsGeneralTime
|
||||
libcom_HEADERS += epicsGuard
|
||||
libcom_HEADERS += epicsMessageQueue
|
||||
libcom_HEADERS += epicsMutex
|
||||
libcom_HEADERS += epicsReadline
|
||||
libcom_HEADERS += epicsRingBytes
|
||||
libcom_HEADERS += epicsRingPointer
|
||||
libcom_HEADERS += epicsSignal
|
||||
libcom_HEADERS += epicsSpin
|
||||
libcom_HEADERS += epicsStackTrace
|
||||
libcom_HEADERS += epicsStdio
|
||||
libcom_HEADERS += epicsStdlib
|
||||
libcom_HEADERS += epicsString
|
||||
libcom_HEADERS += epicsTempFile
|
||||
libcom_HEADERS += epicsThread
|
||||
libcom_HEADERS += epicsTime
|
||||
libcom_HEADERS += epicsTypes
|
||||
libcom_HEADERS += epicsUnitTest
|
||||
libcom_HEADERS += errlog
|
||||
libcom_HEADERS += freeList
|
||||
libcom_HEADERS += iocsh
|
||||
libcom_HEADERS += ipAddrToAsciiAsynchronous
|
||||
libcom_HEADERS += logClient
|
||||
libcom_HEADERS += macLib
|
||||
libcom_HEADERS += osiPoolStatus
|
||||
libcom_HEADERS += osiProcess
|
||||
libcom_HEADERS += osiSock
|
||||
libcom_HEADERS += postfix
|
||||
libcom_HEADERS += shareLib
|
||||
libcom_HEADERS += testMain
|
||||
libcom_HEADERS += yajl_alloc
|
||||
libcom_HEADERS += yajl_common
|
||||
libcom_HEADERS += yajl_gen
|
||||
libcom_HEADERS += yajl_parse
|
||||
|
||||
DOXYGEN = doxygen
|
||||
ME = documentation/O.$(T_A)/html
|
||||
GH_FILES = $(ME)/ $(ME)/.nojekyll $(ME)/*.* $(ME)/*/*.*
|
||||
database_HEADERS += chfPlugin
|
||||
database_HEADERS += dbChannel
|
||||
database_HEADERS += dbCommon
|
||||
database_HEADERS += dbDefs
|
||||
database_HEADERS += dbExtractArray
|
||||
database_HEADERS += dbLink
|
||||
database_HEADERS += dbServer
|
||||
database_HEADERS += dbState
|
||||
database_HEADERS += dbStaticLib
|
||||
database_HEADERS += dbUnitTest
|
||||
database_HEADERS += devLib
|
||||
database_HEADERS += devSup
|
||||
database_HEADERS += drvSup
|
||||
database_HEADERS += initHooks
|
||||
|
||||
record_HEADERS += aaiRecord
|
||||
record_HEADERS += aaoRecord
|
||||
record_HEADERS += aiRecord
|
||||
record_HEADERS += aoRecord
|
||||
record_HEADERS += aSubRecord
|
||||
record_HEADERS += biRecord
|
||||
record_HEADERS += boRecord
|
||||
record_HEADERS += calcRecord
|
||||
record_HEADERS += calcoutRecord
|
||||
record_HEADERS += compressRecord
|
||||
record_HEADERS += dfanoutRecord
|
||||
record_HEADERS += eventRecord
|
||||
record_HEADERS += fanoutRecord
|
||||
record_HEADERS += histogramRecord
|
||||
record_HEADERS += int64inRecord
|
||||
record_HEADERS += int64outRecord
|
||||
record_HEADERS += longinRecord
|
||||
record_HEADERS += longoutRecord
|
||||
record_HEADERS += lsiRecord
|
||||
record_HEADERS += lsoRecord
|
||||
record_HEADERS += mbbiRecord
|
||||
record_HEADERS += mbbiDirectRecord
|
||||
record_HEADERS += mbboRecord
|
||||
record_HEADERS += mbboDirectRecord
|
||||
record_HEADERS += permissiveRecord
|
||||
record_HEADERS += printfRecord
|
||||
record_HEADERS += selRecord
|
||||
record_HEADERS += seqRecord
|
||||
record_HEADERS += stateRecord
|
||||
record_HEADERS += stringinRecord
|
||||
record_HEADERS += stringoutRecord
|
||||
record_HEADERS += subRecord
|
||||
record_HEADERS += subArrayRecord
|
||||
record_HEADERS += waveformRecord
|
||||
|
||||
menu_HEADERS += menuAlarmSevr
|
||||
menu_HEADERS += menuAlarmStat
|
||||
menu_HEADERS += menuConvert
|
||||
menu_HEADERS += menuFtype
|
||||
menu_HEADERS += menuIvoa
|
||||
menu_HEADERS += menuOmsl
|
||||
menu_HEADERS += menuPini
|
||||
menu_HEADERS += menuPost
|
||||
menu_HEADERS += menuPriority
|
||||
menu_HEADERS += menuScan
|
||||
menu_HEADERS += menuSimm
|
||||
menu_HEADERS += menuYesNo
|
||||
|
||||
HEADER_TYPES = libcom database record menu
|
||||
|
||||
HEADER_MD_FILES = $(foreach t, $(HEADER_TYPES), \
|
||||
$(addsuffix _h.md, $($t_HEADERS)))
|
||||
API_RST_FILES = $(addsuffix -api.rst, $(HEADER_TYPES))
|
||||
|
||||
RTD_SRC = $(COMMON_DIR)/rtd-src
|
||||
|
||||
DOCS += README.md
|
||||
DOCS += RELEASE_NOTES.md
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
doxygen: Doxyfile ../mainpage.dox $(INSTALL_HTMLS)
|
||||
$(HEADER_MD_FILES): %_h.md: ../HEADER_h.md
|
||||
$(EXPAND_TOOL) -t $(INSTALL_LOCATION) -DHEADER=$* $< $@
|
||||
|
||||
$(API_RST_FILES): %-api.rst: ../%-API.rst
|
||||
@$(RM) $@
|
||||
@$(ECHO) Creating $@
|
||||
@$(CP) $< $@
|
||||
@$(foreach h, $($*_HEADERS), \
|
||||
echo " $h_h.rst" >> $@;)
|
||||
|
||||
ifndef T_A
|
||||
doxygen rtd sphinx: inc
|
||||
$(MAKE) -C O.$(EPICS_HOST_ARCH) $@
|
||||
else
|
||||
|
||||
doxygen: Doxyfile
|
||||
@$(MKDIR) $(RTD_SRC)
|
||||
$(DOXYGEN)
|
||||
rsync -av $(TOP)/html/ html/
|
||||
|
||||
.PHONY: doxygen
|
||||
rtd: doxygen $(API_RST_FILES) $(HEADER_MD_FILES)
|
||||
rsync -av $(INSTALL_DOC)/ $(RTD_SRC)/
|
||||
rsync -av $(HEADER_MD_FILES) $(RTD_SRC)/
|
||||
rsync -av $(API_RST_FILES) $(RTD_SRC)/
|
||||
rsync -av ../index.rst ../conf.py $(RTD_SRC)/
|
||||
|
||||
commit: doxygen
|
||||
$(TOUCH) html/.nojekyll
|
||||
(cd $(TOP) && $(CURDIR)/../commit-gh.sh $(GH_FILES))
|
||||
sphinx: rtd
|
||||
cd $(COMMON_DIR); $(PYTHON) -m sphinx rtd-src readthedocs
|
||||
rsync -av $(COMMON_DIR)/readthedocs $(INSTALL_HTML)/
|
||||
endif
|
||||
|
||||
.PHONY: commit
|
||||
.PHONY: doxygen rtd sphinx
|
||||
|
@ -1,27 +1,7 @@
|
||||
# Installation Instructions {#install}
|
||||
# Installation instructions
|
||||
|
||||
## EPICS Base Release 7.0.x
|
||||
|
||||
-----
|
||||
|
||||
### Table of Contents
|
||||
|
||||
- [What is EPICS base?](#what-is-epics-base?)
|
||||
- [What is new in this release?](#what-is-new-in-this-release?)
|
||||
- [Copyright](#copyright)
|
||||
- [Supported platforms](#supported-platforms)
|
||||
- [Supported compilers](#supported-compilers)
|
||||
- [Software requirements](#software-requirements)
|
||||
- [Host system storage requirements](#host-system-storage-requirements)
|
||||
- [Documentation](#documentation)
|
||||
- [Directory Structure](#directory-structure)
|
||||
- [Site-specific build configuration](#site-specific-build-configuration)
|
||||
- [Building EPICS base](#building-epics-base)
|
||||
- [Example application and extension](#example-application-and-extension)
|
||||
- [Multiple host platforms](#multiple-host-platforms)
|
||||
|
||||
-----
|
||||
|
||||
### What is EPICS base?
|
||||
|
||||
The Experimental Physics and Industrial Control Systems (EPICS) is an
|
||||
@ -36,8 +16,8 @@ interfaces) of various types.
|
||||
|
||||
### What is new in this release?
|
||||
|
||||
Please check the `documentation/RELEASE_NOTES.md` file for
|
||||
description of changes and release migration details.
|
||||
Please check the [release notes](RELEASE_NOTES.md)
|
||||
for description of changes and release migration details.
|
||||
|
||||
### Copyright
|
||||
|
||||
@ -80,8 +60,7 @@ executable must be found through your normal search path.
|
||||
|
||||
#### Unzip and tar (Winzip on WIN32 systems)
|
||||
|
||||
You must have tools available to unzip and untar the EPICS base
|
||||
distribution file.
|
||||
You may need tools to unzip and untar the EPICS base distribution file.
|
||||
|
||||
#### Target systems
|
||||
|
||||
@ -91,7 +70,7 @@ running as processes on the host platform.
|
||||
|
||||
#### vxWorks
|
||||
|
||||
You must have vxWorks 6.8 or later installed if any of your target
|
||||
You must have vxWorks 6.8 or 6.9 installed if any of your target
|
||||
systems are vxWorks systems; the C++ compiler from older versions cannot
|
||||
compile recently developed code. The vxWorks installation provides the
|
||||
cross-compiler and header files needed to build for these targets. The
|
||||
@ -120,16 +99,10 @@ readline is available and will then use it. RTEMS targets may be
|
||||
configured to use `LIBTECLA` if available, and on vxWorks the OS's
|
||||
ledLib line-editing library is normally used.
|
||||
|
||||
### Host system storage requirements
|
||||
|
||||
The compressed tar file is approximately 3 MB in size. The
|
||||
distribution source tree takes up approximately 21 MB. A 64-bit host
|
||||
architecture may need around 610 MB to compile, while cross-compiled
|
||||
targets are somewhat smaller.
|
||||
|
||||
### Documentation
|
||||
|
||||
EPICS documentation is available through the [EPICS website](https://epics.anl.gov/) at Argonne.
|
||||
EPICS documentation is available from the
|
||||
[EPICS Documentation Website](https://docs.epics-controls.org/).
|
||||
|
||||
Release specific documentation can also be found in the
|
||||
`base/documentation` directory of the distribution.
|
||||
@ -143,8 +116,10 @@ Release specific documentation can also be found in the
|
||||
base/configure Build rules and OS-independent config files
|
||||
base/configure/os OS-dependent build config files
|
||||
base/documentation Distribution documentation
|
||||
base/src Source code in various subdirectories
|
||||
base/src Source code for templates and build tools
|
||||
base/modules Source code for distribution submodules
|
||||
base/startup Scripts for setting up path and environment
|
||||
base/test Unit tests for build tools
|
||||
```
|
||||
|
||||
#### Directories created by the build
|
||||
@ -158,7 +133,8 @@ configuration variable if that has been set.
|
||||
cfg Installed build configuration files
|
||||
db Installed database files
|
||||
dbd Installed database definition files
|
||||
html Installed html documentation
|
||||
doc Installed Markdown documentation
|
||||
html Installed HTML documentation
|
||||
include Installed header files
|
||||
include/os Installed OS-specific header files in subdirs
|
||||
include/compiler Installed compiler-specific header files
|
||||
@ -169,12 +145,11 @@ configuration variable if that has been set.
|
||||
|
||||
#### `base/documentation` Directory
|
||||
|
||||
This contains documents on how to setup, build, and install EPICS.
|
||||
This contains EPICS reference documentation.
|
||||
|
||||
```
|
||||
README.md This file
|
||||
RELEASE_NOTES.md Notes on release changes
|
||||
KnownProblems.html List of known problems and workarounds
|
||||
```
|
||||
|
||||
#### `base/startup` Directory
|
||||
@ -272,8 +247,7 @@ need C and C++ compilers in your search path. When building base you
|
||||
must have `echo` in your search path. For Unix host builds you will
|
||||
also need `cp`, `rm`, `mv`, and `mkdir` in your search path. Some Unix
|
||||
systems may also need `ar` and `ranlib`, and the C/C++ compilers may
|
||||
require `as` and `ld` in your path. On Solaris systems you need
|
||||
`uname` in your path.
|
||||
require `as` and `ld` in your path.
|
||||
|
||||
* **`LD_LIBRARY_PATH`**
|
||||
EPICS shared libraries and executables normally contain the full path
|
||||
@ -290,7 +264,6 @@ Shared libraries are now built by default on all Unix type hosts.
|
||||
|
||||
To configure EPICS, you may want to modify some values set in the
|
||||
following files:
|
||||
>>>>>>> mirror/3.15
|
||||
|
||||
```
|
||||
configure/CONFIG_SITE Build settings. Specify target archs.
|
||||
|
@ -1,4 +1,4 @@
|
||||
# EPICS 7.0 Release Notes {#releasenotes}
|
||||
# EPICS 7.0 Release Notes
|
||||
|
||||
These release notes describe changes that have been made since the previous
|
||||
release of this series of EPICS Base. **Note that changes which were merged up
|
||||
@ -27,13 +27,6 @@ should also be read to understand what has changed since earlier releases:
|
||||
Updating property fields now only post DBE_PROPERTY events if the
|
||||
field actually changed.
|
||||
|
||||
### Allow to load the same alias multiple times
|
||||
|
||||
Aliases can now be defined multiple times as long as they still refer to the
|
||||
same record, unless the shell variable dbRecordsOnceOnly is set.
|
||||
This allows to load database files multiple times, even if they contain
|
||||
alias definitions.
|
||||
|
||||
### Allow users to delete previously created records from the database
|
||||
|
||||
From this release, record instances and aliases that have already been loaded
|
||||
@ -50,8 +43,6 @@ For example this will remove the record named "unwanted":
|
||||
record("#", "unwanted") { }
|
||||
```
|
||||
|
||||
-----
|
||||
|
||||
## EPICS Release 7.0.8.1
|
||||
|
||||
### Limit to `_FORTIFY_SOURCE=2`
|
||||
@ -154,62 +145,6 @@ record("*", "myrec") {} # allowed
|
||||
record(ai, "myrec") {} # error
|
||||
```
|
||||
|
||||
### PROC field changed to ASL0
|
||||
|
||||
The PROC field has been changed from access security level ASL1 to ASL0.
|
||||
This allows users to trigger processing a record without having the rights
|
||||
to reconfigure the records.
|
||||
|
||||
### bi "Raw Soft Channel" use MASK
|
||||
|
||||
If MASK is non-zero, The raw device support will now apply MASK to the
|
||||
value read into RVAL.
|
||||
eg. allows extraction of a bit from an input integer.
|
||||
|
||||
```
|
||||
record(longin, "integer") {
|
||||
field(VAL, "0xff")
|
||||
}
|
||||
record(bi, "bit1") {
|
||||
field(DESC, "extract bit 1")
|
||||
field(DTYP, "Raw Soft Channel")
|
||||
field(INP , "integer")
|
||||
field(MASK, "0x2")
|
||||
field(ZNAM, "Clear")
|
||||
field(ONAM, "Set")
|
||||
}
|
||||
```
|
||||
|
||||
### ANSI escapes in stderr
|
||||
|
||||
ANSI escape charactor sequences may now be printed to the stderr stream.
|
||||
These escapes will appear in logs captured from that stream.
|
||||
Tools which parse and/or render these logs may need to be adjusted to
|
||||
either strip out the escapes, or to translate them into markup.
|
||||
(see [ansi2html](https://pypi.org/project/ansi2html/) for example)
|
||||
|
||||
### Allow explicit append with `dbRecordsOnceOnly!=0`
|
||||
|
||||
Previously setting `dbRecordsOnceOnly!=0` prevented any further changes to a record via a .db file. eg.
|
||||
|
||||
```
|
||||
record(ai, "myrec") {}
|
||||
```
|
||||
|
||||
`dbRecordsOnceOnly!=0` previously disallowed appending fields with either form:
|
||||
|
||||
```
|
||||
record("*", "myrec") {} # error
|
||||
record(ai, "myrec") {} # error
|
||||
```
|
||||
|
||||
Beginning with this release, `dbRecordsOnceOnly!=0` allows appending when explicitly intended (when record type is `"*"`).
|
||||
|
||||
```
|
||||
record("*", "myrec") {} # allowed
|
||||
record(ai, "myrec") {} # error
|
||||
```
|
||||
|
||||
### Add `$EPICS_CLI_TIMEOUT`
|
||||
|
||||
Add support for CA tools timeout from environment variable `$EPICS_CLI_TIMEOUT`
|
||||
@ -785,33 +720,6 @@ make INSTALL_LOCATION=/tmp/build FINAL_LOCATION=/usr/lib/epics
|
||||
`FINAL_LOCATION` is now correctly used in systemd and sysv init scripts
|
||||
`caRepeater.service`, `S99caRepeater`, and `S99logServer`.
|
||||
|
||||
### epicsEnvShow accepts glob pattern
|
||||
|
||||
The optional argument to epicsEnvShow can now be a glob pattern.
|
||||
|
||||
### New function `epicsStrnGlobMatch()`
|
||||
|
||||
The function `epicsStrnGlobMatch(char* str, size_t len, char* pattern)`
|
||||
works exactly the same as `epicsStrGlobMatch()` but takes an additional
|
||||
length arguments which limits the number of characters of `str` to match.
|
||||
|
||||
### Glob pattern allowed in `var` command
|
||||
|
||||
When used with one argument, the `var` command can be used with a glob pattern
|
||||
for printing matching variables.
|
||||
|
||||
### Fix for input links marked "special"
|
||||
|
||||
The calcout record (and a number of synApps record types) marks its input
|
||||
link fields with the attribute `special(SPC_MOD)` and provides code in
|
||||
the record's `special()` routine to reinitialize the related value field
|
||||
whenever the input link field is set to a numeric constant. Unfortunately the
|
||||
changes to the link handling code broke this behaviour (reported as Launchpad
|
||||
[bug #1824277](https://bugs.launchpad.net/epics-base/+bug/1824277))
|
||||
back in the Base 3.16.1 release. This issue has been fixed in Base, although
|
||||
external record types may require some fixing to ensure they are correctly
|
||||
checking for and initializing the link in their `special()` routine.
|
||||
|
||||
### IOCsh sets `${PWD}`
|
||||
|
||||
IOC shell will now ensure `${PWD}` is set on startup,
|
||||
@ -901,33 +809,6 @@ that the variables referenced by output pointers are initialized.
|
||||
```
|
||||
|
||||
|
||||
### Timeouts for Unit Test Programs
|
||||
|
||||
The unit test programs that are run by the `make runtests` or `make tapfiles`
|
||||
commands get executed by a `.t` wrapper script which is normally generated by
|
||||
the EPICS `makeTestfile.pl` program. Those generated wrapper scripts now
|
||||
impose a time-limit on the test program they execute, and will kill it if it
|
||||
runs for longer than 500 seconds (8 minutes 20) without exiting. That
|
||||
time-limit can be changed for any such test by modifying the Makefile which
|
||||
creates and runs the `.t` wrapper script.
|
||||
|
||||
Setting the environment variable `EPICS_UNITTEST_TIMEOUT` to the desired
|
||||
number of seconds while the Makefile is generating the test script changes the
|
||||
timeout in that script. For example:
|
||||
|
||||
```
|
||||
TESTSCRIPTS_HOST += hourLongTest.t
|
||||
hourLongTest.t: export EPICS_UNITTEST_TIMEOUT=3600
|
||||
```
|
||||
|
||||
When selecting such a timeout remember that different Continuous Integration
|
||||
systems such as GitHub Actions and Appveyor run on processors with different
|
||||
speeds, so allow enough head-room for slower systems to complete the test.
|
||||
|
||||
Test programs written directly in Perl as a `.plt` script should implement a
|
||||
similar timeout for themselves. The "netget" test in Base does this in a way
|
||||
that works on Windows as well as Unix-like hosts.
|
||||
|
||||
### Timeouts for Unit Test Programs
|
||||
|
||||
The unit test programs that are run by the `make runtests` or `make tapfiles`
|
||||
|
@ -1,45 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e -x
|
||||
# Usage: commit-gh <sub-directory-prefix> <files...>
|
||||
#
|
||||
# Creates a commit containing only the files in the sub-directory provided as an argument
|
||||
#
|
||||
# Does not disturb the working copy or index
|
||||
|
||||
prefix="$1"
|
||||
shift
|
||||
|
||||
# Commit to this branch
|
||||
BRANCH=refs/heads/gh-pages
|
||||
|
||||
# Use the main branch description as the gh-pages commit message
|
||||
MSG=`git describe --tags --always`
|
||||
|
||||
# Scratch space
|
||||
TDIR=`mktemp -d -p $PWD`
|
||||
|
||||
# Automatic cleanup of scratch space
|
||||
trap 'rm -rf $TDIR' INT TERM QUIT EXIT
|
||||
|
||||
export GIT_INDEX_FILE="$TDIR/index"
|
||||
|
||||
# Add listed files to a new (empty) index
|
||||
git update-index --add "$@"
|
||||
|
||||
# Write the index into the repo, get tree hash
|
||||
TREE=`git write-tree --prefix="$prefix"`
|
||||
|
||||
echo "TREE $TREE"
|
||||
git cat-file -p $TREE
|
||||
|
||||
# Create a commit with our new tree
|
||||
# Reference current branch head as parent (if any)
|
||||
CMT=`git commit-tree -m "$MSG" $TREE`
|
||||
|
||||
echo "COMMIT $CMT"
|
||||
git cat-file -p $CMT
|
||||
|
||||
# Update the branch with the new commit tree hash
|
||||
git update-ref $BRANCH $CMT
|
||||
|
||||
echo "Done"
|
130
documentation/conf.py
Normal file
130
documentation/conf.py
Normal file
@ -0,0 +1,130 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# http://www.sphinx-doc.org/en/master/config
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath("."))
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = "EPICS Base Documentation"
|
||||
copyright = "EPICS Controls"
|
||||
author = "The EPICS Collaboration"
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
|
||||
extensions = [
|
||||
"hoverxref.extension",
|
||||
"breathe",
|
||||
"sphinx.ext.mathjax",
|
||||
"sphinx.ext.ifconfig",
|
||||
"sphinx.ext.graphviz",
|
||||
"sphinx_copybutton",
|
||||
"sphinx.ext.intersphinx",
|
||||
'myst_parser',
|
||||
]
|
||||
|
||||
# Setup the breathe extension
|
||||
breathe_projects = {"epics-base": "xml"}
|
||||
|
||||
breathe_default_project = "epics-base"
|
||||
|
||||
# Tell sphinx what the primary language being documented is.
|
||||
primary_domain = "cpp"
|
||||
|
||||
# Tell sphinx what the pygments highlight language should be.
|
||||
highlight_language = "cpp"
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
# templates_path = ()
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "O.*", "venv"]
|
||||
|
||||
# Intersphinx links to subprojects
|
||||
intersphinx_mapping = {
|
||||
"epics": ("https://docs.epics-controls.org/en/latest/", None),
|
||||
}
|
||||
intersphinx_disabled_reftypes = ["*"]
|
||||
hoverxref_role_types = {
|
||||
"hoverxref": "tooltip",
|
||||
"ref": "modal",
|
||||
"confval": "tooltip",
|
||||
"mod": "modal",
|
||||
"class": "modal",
|
||||
"obj": "tooltip",
|
||||
}
|
||||
|
||||
hoverxref_intersphinx_types = {
|
||||
"readthedocs": "modal",
|
||||
"sphinx": "tooltip",
|
||||
}
|
||||
|
||||
hoverxref_domains = [
|
||||
"py",
|
||||
]
|
||||
|
||||
# Enabled Markdown extensions.
|
||||
# See here for what they do:
|
||||
# https://myst-parser.readthedocs.io/en/latest/syntax/optional.html
|
||||
myst_enable_extensions = [
|
||||
"amsmath",
|
||||
"colon_fence",
|
||||
"deflist",
|
||||
"dollarmath",
|
||||
"fieldlist",
|
||||
"html_image",
|
||||
"replacements",
|
||||
"smartquotes",
|
||||
"strikethrough",
|
||||
"tasklist",
|
||||
]
|
||||
|
||||
# Allows auto-generated header anchors:
|
||||
# https://myst-parser.readthedocs.io/en/latest/syntax/optional.html#auto-generated-header-anchors
|
||||
myst_heading_anchors = 4
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
# html_static_path = ['_static']
|
||||
|
||||
# html_css_files = [
|
||||
# 'css/custom.css',
|
||||
# ]
|
||||
|
||||
master_doc = "index"
|
||||
|
||||
# html_theme_options = {
|
||||
# 'logo_only': True,
|
||||
# }
|
||||
# html_logo = "images/EPICS_white_logo_v02.png"
|
||||
|
||||
# html_extra_path = ['../html']
|
||||
|
||||
# Breathe directives
|
7
documentation/database-API.rst
Normal file
7
documentation/database-API.rst
Normal file
@ -0,0 +1,7 @@
|
||||
IOC Database C/C++ APIs
|
||||
=======================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: IOC Header Files
|
||||
|
30
documentation/index.rst
Normal file
30
documentation/index.rst
Normal file
@ -0,0 +1,30 @@
|
||||
EPICS Base Documentation
|
||||
========================
|
||||
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
EPICS Documentation Index <https://docs.epics-controls.org/en/latest/>
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: General Information
|
||||
|
||||
README
|
||||
RELEASE_NOTES
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: IOC Component Reference
|
||||
|
||||
ComponentReference
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: C/C++ Headers
|
||||
|
||||
libcom-api
|
||||
database-api
|
||||
record-api
|
||||
menu-api
|
7
documentation/libcom-API.rst
Normal file
7
documentation/libcom-API.rst
Normal file
@ -0,0 +1,7 @@
|
||||
Common Library C/C++ APIs
|
||||
=========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: LibCom Header Files
|
||||
|
@ -1,15 +0,0 @@
|
||||
/**
|
||||
@mainpage EPICS Base
|
||||
|
||||
Documentation index
|
||||
|
||||
@li @ref releasenotes
|
||||
@li @ref install
|
||||
@li <a href="ComponentReference.html">EPICS Component Reference Manual</a>
|
||||
@li <a href="filters.html">Field Modifiers and Channel Filters</a>
|
||||
@li <a href="links.html">Extensible IOC Database Links</a>
|
||||
@li <a href="CAref.html">Channel Access Reference Manual</a>
|
||||
@li <a href="msi.html">msi: Macro Substitution and Include Tool</a>
|
||||
@li <a href="CA.html">Perl 5 Interface to Channel Access</a>
|
||||
|
||||
*/
|
7
documentation/menu-API.rst
Normal file
7
documentation/menu-API.rst
Normal file
@ -0,0 +1,7 @@
|
||||
C/C++ Headers from Menus
|
||||
========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Generated Menu Header Files
|
||||
|
7
documentation/record-API.rst
Normal file
7
documentation/record-API.rst
Normal file
@ -0,0 +1,7 @@
|
||||
C/C++ Headers from Record Types
|
||||
===============================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: Generated Record Header Files
|
||||
|
6
documentation/requirements.txt
Normal file
6
documentation/requirements.txt
Normal file
@ -0,0 +1,6 @@
|
||||
sphinx==7.2.6
|
||||
myst-parser==2.0.0
|
||||
breathe==4.35.0
|
||||
sphinx_copybutton==0.5.2
|
||||
sphinx-hoverxref==1.3.0
|
||||
sphinx-rtd-theme==2.0.0
|
@ -38,7 +38,7 @@ ifeq ($(wildcard $(PERL_h)),)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (inc,$(strip $(MAKECMDGOALS)))
|
||||
ifneq ($(filter-out inc,$(strip $(MAKECMDGOALS))),)
|
||||
ifeq ($(T_A),$(EPICS_HOST_ARCH)) # No cross-builds (wrong Perl!)
|
||||
ifeq ($(strip $(XSUBPP)),)
|
||||
$(warning Perl's xsubpp program was not found.)
|
||||
|
@ -16,7 +16,7 @@ USR_CPPFLAGS += -DUSE_TYPED_RSET -DUSE_TYPED_DSET
|
||||
# Shared library ABI version.
|
||||
SHRLIB_VERSION = $(EPICS_DATABASE_MAJOR_VERSION).$(EPICS_DATABASE_MINOR_VERSION).$(EPICS_DATABASE_MAINTENANCE_VERSION)
|
||||
|
||||
API_HEADER = dbCoreAPI.h
|
||||
# dbCoreAPI.h generated earlier during libcom/
|
||||
dbCore_API = dbCore
|
||||
|
||||
LIBRARY_IOC += dbCore
|
||||
|
@ -20,7 +20,7 @@ BPT_DBD += bptTypeJdegF.dbd
|
||||
BPT_DBD += bptTypeKdegC.dbd
|
||||
BPT_DBD += bptTypeKdegF.dbd
|
||||
|
||||
ifneq (inc,$(strip $(MAKECMDGOALS)))
|
||||
ifneq ($(filter-out inc,$(strip $(MAKECMDGOALS))),)
|
||||
DBD += $(BPT_DBD)
|
||||
endif
|
||||
|
||||
@ -28,5 +28,5 @@ PROD_HOST += makeBpt
|
||||
|
||||
makeBpt_SRCS = makeBpt
|
||||
|
||||
DOCS += menuConvert.md
|
||||
HTMLS += menuConvert.html
|
||||
|
||||
|
@ -62,6 +62,12 @@ DBDINC += menuScan
|
||||
DBDINC += dbCommon
|
||||
|
||||
dbMenusPod = $(notdir $(wildcard ../db/menu*.dbd.pod))
|
||||
|
||||
DOCS += $(patsubst %.dbd.pod,%.md,$(dbMenusPod))
|
||||
DOCS += dbCommonRecord.md
|
||||
DOCS += dbCommonInput.md
|
||||
DOCS += dbCommonOutput.md
|
||||
|
||||
HTMLS += $(patsubst %.dbd.pod,%.html,$(dbMenusPod))
|
||||
HTMLS += dbCommonRecord.html
|
||||
HTMLS += dbCommonInput.html
|
||||
|
@ -62,8 +62,28 @@ DBCORE_API void post_event(int event);
|
||||
DBCORE_API void scanAdd(struct dbCommon *);
|
||||
DBCORE_API void scanDelete(struct dbCommon *);
|
||||
DBCORE_API double scanPeriod(int scan);
|
||||
DBCORE_API int scanOnce(struct dbCommon *);
|
||||
DBCORE_API int scanOnceCallback(struct dbCommon *, once_complete cb, void *usr);
|
||||
/** Shorthand for scanOnceCallback(prec, NULL, NULL)
|
||||
*/
|
||||
DBCORE_API int scanOnce(struct dbCommon *prec);
|
||||
/** @brief scanOnce Request immediate record processing from another thread.
|
||||
*
|
||||
* Queue a request for record processing from the dedicated "Once" thread.
|
||||
* Request may fail if Once queue overflows. See scanOnceSetQueueSize()
|
||||
*
|
||||
* @param prec Record to process
|
||||
* @param cb Function called after target record dbProcess()
|
||||
* Does not wait for async record completion.
|
||||
* @param usr Argumentfor cb
|
||||
* @return Zero on success. Non-zero if the request could not be queued.
|
||||
*/
|
||||
DBCORE_API int scanOnceCallback(struct dbCommon *prec, once_complete cb, void *usr);
|
||||
/** @brief Set Once queue size
|
||||
*
|
||||
* Must be called prior to iocInit()
|
||||
*
|
||||
* @param size New size. May be smaller
|
||||
* @return Zero on success
|
||||
*/
|
||||
DBCORE_API int scanOnceSetQueueSize(int size);
|
||||
DBCORE_API int scanOnceQueueStatus(const int reset, scanOnceQueueStats *result);
|
||||
DBCORE_API void scanOnceQueueShow(const int reset);
|
||||
@ -77,9 +97,39 @@ DBCORE_API int scanpel(const char *event_name);
|
||||
/*print io_event list*/
|
||||
DBCORE_API int scanpiol(void);
|
||||
|
||||
/** @brief Initialize "I/O Intr" source
|
||||
* @param ppios Pointer to scan list to be initialized
|
||||
*
|
||||
* Afterwards this IOSCANPVT may be assigned during a get_ioint_info() callback.
|
||||
* See typed_dset::get_ioint_info()
|
||||
*
|
||||
* @note There is currently no way to free this allocation.
|
||||
*/
|
||||
DBCORE_API void scanIoInit(IOSCANPVT *ppios);
|
||||
/** @brief Request processing of all associated records from callback threads
|
||||
* @param pios The scan list
|
||||
* @pre pios must be initialized by scanIoInit()
|
||||
* @return
|
||||
*/
|
||||
DBCORE_API unsigned int scanIoRequest(IOSCANPVT pios);
|
||||
/** @brief Process all records on the scan list for the specificed priority.
|
||||
*
|
||||
* Also executes the callback set by scanIoSetComplete()
|
||||
*
|
||||
* @param pios The scan list
|
||||
* @param prio one of priorityLow through priorityHigh (defined in callback.h).
|
||||
* A value between 0 and NUM_CALLBACK_PRIORITIES-1 .
|
||||
* @return Zero if the scan list was empty or 1<<prio
|
||||
* @since 3.16.0.1
|
||||
*/
|
||||
DBCORE_API unsigned int scanIoImmediate(IOSCANPVT pios, int prio);
|
||||
/** @brief Set scan list completion callback
|
||||
*
|
||||
* Replace the callback which will be invoked after record processing begins.
|
||||
* Asynchronous record processing may be ongoing.
|
||||
*
|
||||
* @since 3.15.0.2
|
||||
*/
|
||||
DBCORE_API void scanIoSetComplete(IOSCANPVT, io_scan_complete, void *usr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -17,7 +17,8 @@ C<MAYBE> or C<NO WAY> would not be accepted as choices for the field.
|
||||
Also, the choices C<yes>, C<No>, and C<Yes> are not valid choices since they
|
||||
don't match the case of C<NO> or C<YES>.
|
||||
The integer values C<0> and C<1> may often be used instead however, they are
|
||||
used as an index into the choices so C<0> becomes C<NO> and C<1> becomes <YES>.
|
||||
used as an index into the choices so C<0> becomes C<NO> and C<1> becomes
|
||||
C<YES>.
|
||||
|
||||
=menu menuYesNo
|
||||
|
||||
|
@ -190,6 +190,7 @@ unsigned short recGblResetAlarms(void *precord)
|
||||
|
||||
if(strcmp(pdbc->namsg, pdbc->amsg)!=0) {
|
||||
strcpy(pdbc->amsg, pdbc->namsg);
|
||||
pdbc->namsg[0] = '\0';
|
||||
stat_mask = DBE_ALARM;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ SRC_DIRS += $(IOCDIR)/dbtemplate
|
||||
PROD_CMD += msi
|
||||
|
||||
msi_SRCS = msi.cpp
|
||||
HTMLS += msi.html
|
||||
DOCS += msi.md
|
||||
|
||||
INC += dbLoadTemplate.h
|
||||
INC += dbtoolsIocRegister.h
|
||||
|
@ -1,445 +0,0 @@
|
||||
<!DOCTYPE html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>msi: Macro Substitution and Include Tool</h1>
|
||||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
<p>msi is a general purpose macro substitution/include tool. It accepts as input
|
||||
an ascii template file. It looks for lines containing two reserved command
|
||||
names: <tt>include</tt> and <tt>substitute</tt>. It also looks for and performs
|
||||
substitutions on macros of the form $(var) and ${var}. It uses the macLib
|
||||
routines from EPICS Base to perform the substitutions, so it also accepts the
|
||||
default value and value definition syntax that macLib implements.</p>
|
||||
|
||||
<p>msi also allows substitutions to be specified via a separate substitution
|
||||
file. This substitution file allows the same format as the substitution files
|
||||
accepted by the EPICS IOC's dbLoadTemplate command.</p>
|
||||
|
||||
<h2>Command Syntax:</h2>
|
||||
|
||||
<pre>msi -V -g -D -o<i>outfile</i> -I<i>dir</i> -M<i>subs</i> -S<i>subfile</i> <i>template</i></pre>
|
||||
|
||||
<p>All parameters are optional. The -o, -I, -M, and -S switches may be
|
||||
separated from their associated value string by spaces if desired. Output will
|
||||
be written to stdout unless the -o option is given.</p>
|
||||
|
||||
<p>Switches have the following meanings:</p>
|
||||
|
||||
<dl>
|
||||
<dt><tt>-V</tt></dt>
|
||||
<dd>Verbose warnings; if this parameter is specified then any undefined or
|
||||
recursive macros discovered in the template will be considered an error and
|
||||
will be marked in the output file. An error message will be shown, and when
|
||||
msi terminates it will do so with an exit status of 2.</dd>
|
||||
|
||||
<dt><tt>-g</tt></dt>
|
||||
<dd>When this flag is given all macros defined in a substitution file will
|
||||
have global scope and thus their values will persist until a new value is
|
||||
given for this macro. This flag is provided for backwards compatibility as
|
||||
this was the behavior of previous versions of msi, but it does not follow
|
||||
common scoping rules and is discouraged.</dd>
|
||||
|
||||
<dt><tt>-D</tt></dt>
|
||||
<dd>Output dependency information suitable for including by a Makefile to
|
||||
stdout instead of performing the macro substitutions. The <tt>-o</tt> option
|
||||
must be given to specify the target name for the dependency rules. Other
|
||||
options should be given exactly as will be used in the macro substitution
|
||||
process.</dd>
|
||||
|
||||
<dt><tt>-o</tt> <i>file</i></dt>
|
||||
<dd>Output will be written to the specifed file rather than to the standard
|
||||
output.</dd>
|
||||
|
||||
<dt><tt>-I</tt> <i>dir</i></dt>
|
||||
<dd>This parameter, which may be repeated or contain a colon-separated (or
|
||||
semi-colon separated on Windows) list of directory paths, specifies a search
|
||||
path for include commands. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>msi -I /home/mrk/examples:. -I.. template</pre>
|
||||
</blockquote>
|
||||
|
||||
specifies that all named files should be searched for in the following
|
||||
locations in the order given:
|
||||
|
||||
<ol>
|
||||
<li><tt>/home/mrk/examples</tt></li>
|
||||
<li><tt>.</tt> (the current directory)</li>
|
||||
<li><tt>..</tt> (the parent of the current directory)</li>
|
||||
</ol>
|
||||
</dd>
|
||||
|
||||
<dt><tt>-M</tt> <i>substitutions</i></dt>
|
||||
<dd>This parameter specifies macro values for the template instance.
|
||||
Multiple macro values can be specified in one substitution parameter, or in
|
||||
multiple <tt>-M</tt> parameters. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>msi -M "a=aval,b=bval" -Mc=cval template</pre>
|
||||
</blockquote>
|
||||
|
||||
specifies that in the template file each occurrence of:
|
||||
|
||||
<dl>
|
||||
<dd><tt>$(a)</tt> or <tt>${a}</tt> is replaced by <tt>aval</tt></dd>
|
||||
<dd><tt>$(b)</tt> or <tt>${b}</tt> is replaced by <tt>bval</tt></dd>
|
||||
<dd><tt>$(c)</tt> or <tt>${c}</tt> is replaced by <tt>cval</tt></dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><tt>-S</tt> <i>subfile</i></dt>
|
||||
<dd>The substitution file. See below for format.</dd>
|
||||
|
||||
<dt><i>template</i></dt>
|
||||
<dd> The input file. If no file is specified then input is taken from
|
||||
stdin, i.e. msi can be used as a filter. See below for a description of
|
||||
commands that can be embedded in the template file.</dd>
|
||||
</dl>
|
||||
|
||||
<p>It is not possible to display usage by just typing <tt>msi</tt> since
|
||||
executing the command with no arguments is a valid command. To show usage
|
||||
specify an illegal switch, e.g.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>msi -help</pre>
|
||||
</blockquote>
|
||||
|
||||
<h2>Exit Status</h2>
|
||||
|
||||
<dl>
|
||||
<dt>0<dd>Success.
|
||||
<dt>1<dd>Can't open/create file, or other I/O error.
|
||||
<dt>2<dd>Undefined macros encountered with the <tt>-V</tt> option specified.
|
||||
</dl>
|
||||
|
||||
<h2>Template File Format</h2>
|
||||
|
||||
<p>This file contains the text to be read and written to the output after macro
|
||||
substitution is performed. If no file is given then input is read from stdin.
|
||||
Variable instances to be substituted by macro values are expressed in the
|
||||
template using the syntax <tt>$(</tt><i>name</i><tt>)</tt> or
|
||||
<tt>${</tt><i>name</i><tt>}</tt>. The template can also provide default values
|
||||
to be used when a macro has not been given a value, using the syntax
|
||||
<tt>$(</tt><i>name</i><tt>=</tt><i>default</i><tt>)</tt> or
|
||||
<tt>${</tt><i>name</i><tt>=</tt><i>default</i><tt>}</tt>.</p>
|
||||
|
||||
<p>For example, using the command</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>msi -M name=Marty template</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>where the file template contains</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>My name is $(name)
|
||||
My age is $(age=none of your business)</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>results in this output:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>My name is Marty
|
||||
My age is none of your business</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>Macro variables and their default values can be expressed in terms of other
|
||||
macros if necessary, to almost any level of complexity. Recursive definitions
|
||||
will generate warning messages on stderr and result in undefined output.</p>
|
||||
|
||||
<p>The template file is read and processed one line at a time, where the
|
||||
maximum length of a line before and/or after macro expansion is 1023 characters
|
||||
— longer input or output lines will cause msi to fail. Within the context
|
||||
of a single line, macro expansion does not occur when the variable instance
|
||||
appears inside a single-quoted string, or where the dollar sign <tt>$</tt> is
|
||||
preceded by a back-slash character <tt>\</tt>, but as with the standard Unix
|
||||
shells, variables inside double quoted strings are expanded properly.</p>
|
||||
|
||||
<p>However neither back-slash characters nor quotes of either variety are
|
||||
removed when generating the output file, so depending on what is being output
|
||||
the single quote behaviour may not be useful and may even be a hinderance. It
|
||||
cannot be disabled in the current version of msi.</p>
|
||||
|
||||
<h3>Template file commands</h3>
|
||||
|
||||
<p>In addition to the regular text and variable instances described above, the
|
||||
template file may also contain commands which allow the insertion of other
|
||||
template files and the ability to set macro values inside the template file
|
||||
itself. These commands are:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>include "file"
|
||||
substitute "var=value,var=value,..."</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>Lines containing commands must be in one of these forms:</p>
|
||||
|
||||
<ul>
|
||||
<li><tt>include "</tt><i>filename</i><tt>"</tt></li>
|
||||
<li><tt>substitute "</tt><i>name1=value1, name2=value2, ...</i><tt>"</tt></li>
|
||||
</ul>
|
||||
|
||||
<p>White space is allowed before and after the command verb, and after the
|
||||
quoted string. If embedded quotes are needed, the backslash character
|
||||
<tt>\</tt> can be used as an escape character. For example</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>substitute "a=\"val\""</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>specifies that (unless <tt>a</tt> is subsequently redefined) wherever a
|
||||
<tt>$(a)</tt> macro appears in the template below this point, the text
|
||||
<tt>"val"</tt> (including the double quote characters) will appear in the
|
||||
output instead.</p>
|
||||
|
||||
<p>If a line does match either syntax above it is just passed to macLib for
|
||||
processing without any notification. Thus the input line:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>include "myfile" #include file</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>would just be passed to macLib, i.e. it would <em>not</em> be considered an
|
||||
include command.</p>
|
||||
|
||||
<p>As an example of these commands, let the Unix command be:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>msi template</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>and file includeFile contain:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>first name is ${first}
|
||||
family name is ${family}</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>and template is</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>substitute "first=Marty,family=Kraimer"
|
||||
include "includeFile"
|
||||
substitute "first=Irma,family=Kraimer"
|
||||
include "includeFile"</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>then the following is written to the output.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>first name is Marty
|
||||
family name is Kraimer
|
||||
first name is Irma
|
||||
family name is Kraimer</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>Note that the IOC's <tt>dbLoadTemplate</tt> command does not support the
|
||||
<tt>substitute</tt> syntax in template files, although the <tt>include</tt>
|
||||
syntax is supported.</p>
|
||||
|
||||
<h2>Substitution File Format</h2>
|
||||
|
||||
<p>The optional substitution file has three formats: regular, pattern, and
|
||||
dbTemplate format. We will discuss each separately.</p>
|
||||
|
||||
<h3>Regular format</h3>
|
||||
|
||||
<blockquote>
|
||||
<pre>global {gbl_var1=gbl_val1, gbl_var2=gbl_val2, ...}
|
||||
{var1=set1_val1, var2=set1_val2, ...}
|
||||
{var2=set2_val2, var1=set2_val1, ...}
|
||||
global {gbl_var1=gbl_val3, gbl_var2=gbl_val4, ...}
|
||||
{var1=set3_val1, var2=set3_val2, ...}
|
||||
{var2=set4_val2, var1=set4_val1, ...}</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>The template file is output with macro substitutions performed once for each
|
||||
set of braces containing macro replacement values.</p>
|
||||
|
||||
<h3>Pattern format</h3>
|
||||
|
||||
<blockquote>
|
||||
<pre>global {gbl_var1=gbl_val1, gbl_var2=gbl_val2, ...}
|
||||
pattern {var1, var2, ...}
|
||||
{set1_val1, set1_val2, ...}
|
||||
{set2_val1, set2_val2, ...}
|
||||
pattern {var2, var1, ...}
|
||||
global {gbl_var1=gbl_val3, gbl_var2=gbl_val4, ...}
|
||||
{set3_val2, set3_val1, ...}
|
||||
{set4_val2, set4_val2, ...}</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>This produces the same result as the regular format example above.</p>
|
||||
|
||||
<h3>dbLoadTemplate Format</h3>
|
||||
|
||||
<p>This format is an extension of the format accepted by the EPICS IOC command
|
||||
<tt>dbLoadTemplate</tt>, and allows templates to be expanded on the host rather
|
||||
by using dbLoadTemplate at IOC boot time.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>global {gbl_var1=gbl_val1, gbl_var2=gbl_val2, ...}
|
||||
file templatefile {
|
||||
<i>pattern format or regular format</i>
|
||||
}
|
||||
file "${WHERE}/template2" {
|
||||
<i>pattern format or regular format</i>
|
||||
}</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>For the dbTemplate format, the template filename does not have to be given
|
||||
on the command line, and is usually specified in the substitutions file
|
||||
instead. If a template filename is given on the command line it will override
|
||||
the filenames listed in the substitutions files.</p>
|
||||
|
||||
<h3>Syntax for all formats</h3>
|
||||
|
||||
<p>A comment line may appear anywhere in a substitution file, and will be
|
||||
ignored. A comment line is any line beginning with the character <tt>#</tt>,
|
||||
which must be the very first character on the line.</p>
|
||||
|
||||
<p>Global definitions may supplement or override the macro values supplied on
|
||||
the command-line using the <tt>-M</tt> switch, and set default values that will
|
||||
survive for the remainder of the file unless another global definition of the
|
||||
same macro changes it.</p>
|
||||
|
||||
<p>For definitions within braces given in any of the file formats, a separator
|
||||
must be given between items. A separator is either a comma, or one or more of
|
||||
the standard white space characters (space, formfeed, newline, carriage return,
|
||||
tab or vertical tab).</p>
|
||||
|
||||
<p>Each item within braces can be an alphanumeric token, or a double-quoted
|
||||
string. A back-slash character <tt>\</tt> can be used to escape a quote
|
||||
character needed inside a quoted string. These three sets of substitutions are
|
||||
all equivalent:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>{a=aa b=bb c="\"cc\""}
|
||||
{b="bb",a=aa,c="\"cc\""}
|
||||
{
|
||||
c="\"cc\""
|
||||
b=bb
|
||||
a="aa"
|
||||
}</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>Within a substitutions file, the file name may appear inside double quotation
|
||||
marks; these are required if the name contains certain characters or environment
|
||||
variable macros of the form ${ENV_VAR} or $(ENV_VAR), which will be expanded
|
||||
before the file is opened.</p>
|
||||
|
||||
<h3>Regular substitution example</h3>
|
||||
|
||||
<p>Let the command be:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>msi -S substitute template</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>The file <tt>template</tt> contains</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>first name is ${first}
|
||||
family name is ${family}</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> and the file <tt>substitute</tt> is</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>global {family=Kraimer}
|
||||
{first=Marty}
|
||||
{first=Irma}</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>The following is the output produced:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>first name is Marty
|
||||
family name is Kraimer
|
||||
first name is Irma
|
||||
family name is Kraimer</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Pattern substitution example</h3>
|
||||
|
||||
<p>Let the command be:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>msi -S pattern template</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>The file <tt>pattern</tt> contains</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>pattern {first,last}
|
||||
{Marty,Kraimer}
|
||||
{Irma,Kraimer}</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>and <tt>template</tt> is the same as the previous example:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>first name is ${first}
|
||||
family name is ${family}</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>This is the output:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>first name is Marty
|
||||
family name is Kraimer
|
||||
first name is Irma
|
||||
family name is Kraimer</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>dbTemplate example</h3>
|
||||
Let the command be
|
||||
|
||||
<blockquote>
|
||||
<pre>msi -S xxx.substitutions</pre>
|
||||
</blockquote>
|
||||
|
||||
<tt>xxx.substitutions</tt> is
|
||||
|
||||
<blockquote>
|
||||
<pre>file template {
|
||||
pattern {first,last}
|
||||
{Marty,Kraimer}
|
||||
{Irma,Kraimer}
|
||||
pattern {last,first}
|
||||
{Smith,Bill}
|
||||
{Smith,Mary}
|
||||
}
|
||||
file template {
|
||||
{first=Marty,last=Kraimer}
|
||||
{first=Irma,last=Kraimer}
|
||||
}</pre>
|
||||
</blockquote>
|
||||
<tt>template</tt> is the same as in the previous example..
|
||||
|
||||
<p>The following is written to the output</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>first name is Marty
|
||||
family name is Kraimer
|
||||
first name is Irma
|
||||
family name is Kraimer
|
||||
first name is Bill
|
||||
last name is Smith
|
||||
first name is Mary
|
||||
last name is Smith
|
||||
first name is Marty
|
||||
family name is Kraimer
|
||||
first name is Irma
|
||||
family name is Kraimer</pre>
|
||||
</blockquote>
|
||||
|
||||
</body>
|
||||
</html>
|
384
modules/database/src/ioc/dbtemplate/msi.md
Normal file
384
modules/database/src/ioc/dbtemplate/msi.md
Normal file
@ -0,0 +1,384 @@
|
||||
# msi: Macro Substitution and Include Tool
|
||||
|
||||
(msitool)=
|
||||
## Introduction
|
||||
|
||||
msi is a general purpose macro substitution/include tool.
|
||||
It accepts as input an ascii template file. It looks for lines containing two reserved
|
||||
command names: `include` and `substitute`. It also looks for and performs
|
||||
substitutions on macros of the form `$(var)` and `${var}`. It uses the
|
||||
macLib routines from EPICS Base to perform the substitutions, so it also
|
||||
accepts the default value and value definition syntax that macLib
|
||||
implements.
|
||||
|
||||
msi also allows substitutions to be specified via a separate
|
||||
substitution file. This substitution file allows the same format as the
|
||||
substitution files accepted by the EPICS IOC's dbLoadTemplate command.
|
||||
|
||||
|
||||
## Command Syntax
|
||||
|
||||
`msi -V -g -o outfile -I dir -M subs -S subfile template`
|
||||
|
||||
All parameters are optional. The -o, -I, -M, and -S switches may be
|
||||
separated from their associated value string by spaces if desired.
|
||||
Output will be written to stdout unless the -o option is given.
|
||||
|
||||
Switches have the following meanings:
|
||||
|
||||
- **-V**
|
||||
|
||||
Verbose warnings; if this parameter is specified then any undefined
|
||||
macro discovered in the template file which does not have an
|
||||
associated default value is considered an error. An error message is
|
||||
generated, and when msi terminates it will do so with an exit status
|
||||
of 2.
|
||||
- **-g**
|
||||
|
||||
When this flag is given all macros defined in a substitution file
|
||||
will have global scope and thus their values will persist until a
|
||||
new value is given for this macro. This flag is provided for
|
||||
backwards compatibility as this was the behavior of previous
|
||||
versions of msi, but it does not follow common scoping rules and is
|
||||
discouraged.
|
||||
- **-o _file_**
|
||||
|
||||
Output will be written to the specifed file rather than to the
|
||||
standard output.
|
||||
- **-I _dir_**
|
||||
|
||||
This parameter, which may be repeated or contain a colon-separated
|
||||
(or semi-colon separated on Windows) list of directory paths,
|
||||
specifies a search path for include commands. For example:
|
||||
|
||||
msi -I /home/mrk/examples:. -I.. template
|
||||
|
||||
specifies that all named files should be searched for in the following locations,
|
||||
in the order given:
|
||||
|
||||
1. /home/mrk/examples
|
||||
2. . (the current directory)
|
||||
3. .. (the parent of the current directory)
|
||||
|
||||
- **-M _substitutions_**
|
||||
|
||||
This parameter specifies macro values for the template instance.
|
||||
Multiple macro values can be specified in one substitution
|
||||
parameter, or in multiple -M parameters. For example:
|
||||
|
||||
msi -M "a=aval,b=bval" -Mc=cval template
|
||||
|
||||
specifies that in the template file each occurrence of:
|
||||
|
||||
- `$(a)` or `${a}` is replaced by _aval_
|
||||
- `$(b)` or `${b}` is replaced by _bval_
|
||||
- `$(c)` or `${c}` is replaced by _cval_
|
||||
|
||||
- **-S _subfile_**
|
||||
|
||||
The substitution file. See below for format.
|
||||
- **_template_**
|
||||
|
||||
The input file. If no file is specified then input is taken from
|
||||
stdin, i.e. msi can be used as a filter. See below for a description
|
||||
of commands that can be embedded in the template file.
|
||||
|
||||
It is not possible to display usage by just typing msi since executing
|
||||
the command with no arguments is a valid command. To show usage specify
|
||||
an illegal switch, e.g.
|
||||
|
||||
msi -help
|
||||
|
||||
|
||||
## Exit Status
|
||||
|
||||
- **0**
|
||||
Success.
|
||||
- **1**
|
||||
Can't open/create file, or other I/O error.
|
||||
- **2**
|
||||
Undefined macros encountered with the -V option specified.
|
||||
|
||||
|
||||
## Template File Format
|
||||
|
||||
This file contains the text to be read and written to the output after
|
||||
macro substitution is performed. If no file is given then input is read
|
||||
from stdin. Variable instances to be substituted by macro values are
|
||||
expressed in the template using the syntax \$(_name_) or \${_name_}. The
|
||||
template can also provide default values to be used when a macro has not
|
||||
been given a value, using the syntax \$(_name_=_default_) or \${_name_=_default_}.
|
||||
|
||||
For example, using the command
|
||||
|
||||
msi -M name=Marty template
|
||||
|
||||
where the file template contains
|
||||
|
||||
My name is $(name)
|
||||
My age is $(age=none of your business)
|
||||
|
||||
results in this output:
|
||||
|
||||
My name is Marty
|
||||
My age is none of your business
|
||||
|
||||
Macro variables and their default values can be expressed in terms of
|
||||
other macros if necessary, to almost any level of complexity. Recursive
|
||||
definitions will generate warning messages on stderr and result in
|
||||
undefined output.
|
||||
|
||||
The template file is read and processed one line at a time, where the
|
||||
maximum length of a line before and/or after macro expansion is 1023
|
||||
characters; longer input or output lines will cause msi to fail. Within
|
||||
the context of a single line, macro expansion does not occur when the
|
||||
variable instance appears inside a single-quoted string, or where the
|
||||
dollar sign $ is preceded by a back-slash character \, but as with the
|
||||
standard Unix shells, variables inside double quoted strings are
|
||||
expanded properly.
|
||||
|
||||
However neither back-slash characters nor quotes of either variety are
|
||||
removed when generating the output file, so depending on what is being
|
||||
output the single quote behaviour may not be useful and may even be a
|
||||
hinderance. It cannot be disabled in the current version of msi.
|
||||
|
||||
|
||||
### Template file commands
|
||||
|
||||
In addition to the regular text and variable instances described above,
|
||||
the template file may also contain commands which allow the insertion of
|
||||
other template files and the ability to set macro values inside the
|
||||
template file itself. These commands are:
|
||||
|
||||
include "file"
|
||||
substitute "var=value,var=value,..."
|
||||
|
||||
Lines containing commands must be in one of these forms:
|
||||
|
||||
- include "_filename_"
|
||||
|
||||
- substitute "_name1=value1, name2=value2, ..._"
|
||||
|
||||
White space is allowed before and after the command verb, and after the
|
||||
quoted string. If embedded quotes are needed, the backslash character \
|
||||
can be used as an escape character. For example
|
||||
|
||||
substitute "a=\"val\""
|
||||
|
||||
specifies that (unless a is subsequently redefined) wherever a $(a)
|
||||
macro appears in the template below this point, the text
|
||||
"val" (including the double quote characters) will appear in the output
|
||||
instead.
|
||||
|
||||
If a line does match either syntax above it is just passed to macLib for
|
||||
processing without any notification. Thus the input line:
|
||||
|
||||
include "myfile" #include file
|
||||
|
||||
would just be passed to macLib, i.e. it would _not_ be considered an
|
||||
include command.
|
||||
|
||||
As an example of these commands, let the Unix command be:
|
||||
|
||||
msi template
|
||||
|
||||
and file includeFile contain:
|
||||
|
||||
first name is ${first}
|
||||
family name is ${family}
|
||||
|
||||
and template is
|
||||
|
||||
substitute "first=Marty,family=Kraimer"
|
||||
include "includeFile"
|
||||
substitute "first=Irma,family=Kraimer"
|
||||
include "includeFile"
|
||||
|
||||
then the following is written to the output.
|
||||
|
||||
first name is Marty
|
||||
family name is Kraimer
|
||||
first name is Irma
|
||||
family name is Kraimer
|
||||
|
||||
Note that the IOC's dbLoadTemplate command does not support the
|
||||
substitute syntax in template files, although the include syntax is
|
||||
supported.
|
||||
|
||||
|
||||
## Substitution File Format
|
||||
|
||||
The optional substitution file has three formats: regular, pattern, and
|
||||
dbTemplate format. We will discuss each separately.
|
||||
|
||||
|
||||
### Regular format
|
||||
|
||||
global {gbl_var1=gbl_val1, gbl_var2=gbl_val2, ...}
|
||||
{var1=set1_val1, var2=set1_val2, ...}
|
||||
{var2=set2_val2, var1=set2_val1, ...}
|
||||
global {gbl_var1=gbl_val3, gbl_var2=gbl_val4, ...}
|
||||
{var1=set3_val1, var2=set3_val2, ...}
|
||||
{var2=set4_val2, var1=set4_val1, ...}
|
||||
|
||||
The template file is output with macro substitutions performed once for
|
||||
each set of braces containing macro replacement values.
|
||||
|
||||
|
||||
### Pattern format
|
||||
|
||||
global {gbl_var1=gbl_val1, gbl_var2=gbl_val2, ...}
|
||||
pattern {var1, var2, ...}
|
||||
{set1_val1, set1_val2, ...}
|
||||
{set2_val1, set2_val2, ...}
|
||||
pattern {var2, var1, ...}
|
||||
global {gbl_var1=gbl_val3, gbl_var2=gbl_val4, ...}
|
||||
{set3_val2, set3_val1, ...}
|
||||
{set4_val2, set4_val2, ...}
|
||||
|
||||
This produces the same result as the regular format example above.
|
||||
|
||||
|
||||
### dbLoadTemplate Format
|
||||
|
||||
This format is an extension of the format accepted by the EPICS IOC
|
||||
command dbLoadTemplate, and allows templates to be expanded on the host
|
||||
rather by using dbLoadTemplate at IOC boot time.
|
||||
|
||||
global {gbl_var1=gbl_val1, gbl_var2=gbl_val2, ...}
|
||||
file templatefile {
|
||||
/pattern format or regular format/
|
||||
}
|
||||
file "${WHERE}/template2" {
|
||||
/pattern format or regular format/
|
||||
}
|
||||
|
||||
For the dbTemplate format, the template filename does not have to be
|
||||
given on the command line, and is usually specified in the substitutions
|
||||
file instead. If a template filename is given on the command line it
|
||||
will override the filenames listed in the substitutions files.
|
||||
|
||||
|
||||
### Syntax for all formats
|
||||
|
||||
A comment line may appear anywhere in a substitution file, and will be
|
||||
ignored. A comment line is any line beginning with the character #,
|
||||
which must be the very first character on the line.
|
||||
|
||||
Global definitions may supplement or override the macro values supplied
|
||||
on the command-line using the -M switch, and set default values that
|
||||
will survive for the remainder of the file unless another global
|
||||
definition of the same macro changes it.
|
||||
|
||||
For definitions within braces given in any of the file formats, a
|
||||
separator must be given between items. A separator is either a comma, or
|
||||
one or more of the standard white space characters (space, formfeed,
|
||||
newline, carriage return, tab or vertical tab).
|
||||
|
||||
Each item within braces can be an alphanumeric token, or a double-quoted
|
||||
string. A back-slash character \ can be used to escape a quote character
|
||||
needed inside a quoted string. These three sets of substitutions are all
|
||||
equivalent:
|
||||
|
||||
{a=aa b=bb c="\"cc\""}
|
||||
{b="bb",a=aa,c="\"cc\""}
|
||||
{
|
||||
c="\"cc\""
|
||||
b=bb
|
||||
a="aa"
|
||||
}
|
||||
|
||||
Within a substitutions file, the file name may appear inside double
|
||||
quotation marks; these are required if the name contains certain
|
||||
characters or environment variable macros of the form `${ENV_VAR}` or
|
||||
`$(ENV_VAR)`, which will be expanded before the file is opened.
|
||||
|
||||
|
||||
### Regular substitution example
|
||||
|
||||
Let the command be:
|
||||
|
||||
msi -S substitute template
|
||||
|
||||
The file template contains
|
||||
|
||||
first name is ${first}
|
||||
family name is ${family}
|
||||
|
||||
and the file `substitute` is
|
||||
|
||||
global {family=Kraimer}
|
||||
{first=Marty}
|
||||
{first=Irma}
|
||||
|
||||
The following is the output produced:
|
||||
|
||||
first name is Marty
|
||||
family name is Kraimer
|
||||
first name is Irma
|
||||
family name is Kraimer
|
||||
|
||||
|
||||
### Pattern substitution example
|
||||
|
||||
Let the command be:
|
||||
|
||||
msi -S pattern template
|
||||
|
||||
The file pattern contains
|
||||
|
||||
pattern {first,last}
|
||||
{Marty,Kraimer}
|
||||
{Irma,Kraimer}
|
||||
|
||||
and template is the same as the previous example:
|
||||
|
||||
first name is ${first}
|
||||
family name is ${family}
|
||||
|
||||
This is the output:
|
||||
|
||||
first name is Marty
|
||||
family name is Kraimer
|
||||
first name is Irma
|
||||
family name is Kraimer
|
||||
|
||||
|
||||
### dbTemplate example
|
||||
|
||||
Let the command be
|
||||
|
||||
msi -S xxx.substitutions
|
||||
|
||||
`xxx.substitutions` is
|
||||
|
||||
file template {
|
||||
pattern {first,last}
|
||||
{Marty,Kraimer}
|
||||
{Irma,Kraimer}
|
||||
pattern {last,first}
|
||||
{Smith,Bill}
|
||||
{Smith,Mary}
|
||||
}
|
||||
file template {
|
||||
{first=Marty,last=Kraimer}
|
||||
{first=Irma,last=Kraimer}
|
||||
}
|
||||
|
||||
`template` is the same as in the previous example.
|
||||
|
||||
The following is written to the output
|
||||
|
||||
first name is Marty
|
||||
family name is Kraimer
|
||||
first name is Irma
|
||||
family name is Kraimer
|
||||
first name is Bill
|
||||
last name is Smith
|
||||
first name is Mary
|
||||
last name is Smith
|
||||
first name is Marty
|
||||
family name is Kraimer
|
||||
first name is Irma
|
||||
family name is Kraimer
|
||||
|
96
modules/database/src/std/ComponentReference.md
Normal file
96
modules/database/src/std/ComponentReference.md
Normal file
@ -0,0 +1,96 @@
|
||||
# IOC Component Reference
|
||||
|
||||
This document provides reference information about the record types,
|
||||
menus, link types and channel filters included with EPICS Base.
|
||||
|
||||
## Introduction and IOC Concepts
|
||||
|
||||
- [Introduction to EPICS](https://docs.epics-controls.org/en/latest/getting-started/EPICS_Intro.html)
|
||||
- [Process Database Concepts](https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html)
|
||||
|
||||
## Record Type Definitions
|
||||
|
||||
These sections describe common aspects of the record types:
|
||||
|
||||
```{toctree}
|
||||
:titlesonly:
|
||||
|
||||
dbCommonRecord
|
||||
dbCommonInput
|
||||
dbCommonOutput
|
||||
```
|
||||
|
||||
These are the record types supplied with EPICS Base:
|
||||
|
||||
```{toctree}
|
||||
:titlesonly:
|
||||
|
||||
aaiRecord
|
||||
aaoRecord
|
||||
aiRecord
|
||||
aoRecord
|
||||
aSubRecord
|
||||
biRecord
|
||||
boRecord
|
||||
calcoutRecord
|
||||
calcRecord
|
||||
compressRecord
|
||||
dfanoutRecord
|
||||
eventRecord
|
||||
fanoutRecord
|
||||
histogramRecord
|
||||
int64inRecord
|
||||
int64outRecord
|
||||
longinRecord
|
||||
longoutRecord
|
||||
lsiRecord
|
||||
lsoRecord
|
||||
mbbiDirectRecord
|
||||
mbbiRecord
|
||||
mbboDirectRecord
|
||||
mbboRecord
|
||||
permissiveRecord
|
||||
printfRecord
|
||||
selRecord
|
||||
seqRecord
|
||||
stateRecord
|
||||
stringinRecord
|
||||
stringoutRecord
|
||||
subArrayRecord
|
||||
subRecord
|
||||
waveformRecord
|
||||
```
|
||||
|
||||
## Menu Definitions
|
||||
|
||||
Menu field choices are documented with the record type that defines them, or
|
||||
here for the global menus that are used by multiple record types:
|
||||
|
||||
```{toctree}
|
||||
:titlesonly:
|
||||
|
||||
menuAlarmSevr
|
||||
menuAlarmStat
|
||||
menuConvert
|
||||
menuFtype
|
||||
menuIvoa
|
||||
menuOmsl
|
||||
menuPini
|
||||
menuPost
|
||||
menuPriority
|
||||
menuScan
|
||||
menuSimm
|
||||
menuYesNo
|
||||
```
|
||||
|
||||
## Other Components
|
||||
|
||||
EPICS Base also comes with extensible sets of server Channel Filters and IOC
|
||||
Database Link types, which are documented here:
|
||||
|
||||
```{toctree}
|
||||
:titlesonly:
|
||||
|
||||
filters
|
||||
links
|
||||
```
|
@ -163,8 +163,8 @@ Database Link types, which are documented here:
|
||||
|
||||
Corrections to these documents can be submitted as patch files to the EPICS
|
||||
core developers, or as GitHub pull requests to the 7.0 branch of Base.
|
||||
These document sources can be found under `modules/database/src` tree, mostly
|
||||
in the `std/rec` and `ioc/db` directories in files with extension `.dbd.pod`.
|
||||
These document sources can be found under C<modules/database/src> tree, mostly
|
||||
in the C<std/rec> and C<ioc/db> directories in files with extension C<.dbd.pod>.
|
||||
The documentation source format is a combination of the EPICS DBD file format
|
||||
with an extended version of Perl's POD (plain old documentation); run `perldoc
|
||||
pod` for details of POD.
|
||||
with an extended version of Perl's POD (plain old documentation); run
|
||||
C<perldoc pod> for details of POD.
|
@ -30,6 +30,9 @@ include $(STDDIR)/filters/Makefile
|
||||
include $(STDDIR)/link/Makefile
|
||||
include $(STDDIR)/softIoc/Makefile
|
||||
|
||||
DOCS += ComponentReference.md
|
||||
HTMLS += ComponentReference.html
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
include $(STDDIR)/rec/RULES
|
||||
|
@ -18,5 +18,5 @@ dbRecStd_SRCS += sync.c
|
||||
dbRecStd_SRCS += decimate.c
|
||||
dbRecStd_SRCS += utag.c
|
||||
|
||||
DOCS += filters.md
|
||||
HTMLS += filters.html
|
||||
|
||||
|
@ -16,4 +16,5 @@ dbRecStd_SRCS += lnkCalc.c
|
||||
dbRecStd_SRCS += lnkState.c
|
||||
dbRecStd_SRCS += lnkDebug.c
|
||||
|
||||
DOCS += links.md
|
||||
HTMLS += links.html
|
||||
|
@ -54,8 +54,13 @@ stdRecords_DBD = $(patsubst %,%.dbd,$(stdRecords))
|
||||
|
||||
dbRecStd_SRCS += $(patsubst %,%.c,$(stdRecords))
|
||||
|
||||
DOCS += $(patsubst %.dbd.pod,%.md,$(notdir $(wildcard ../rec/*Record.dbd.pod)))
|
||||
HTMLS += $(patsubst %.dbd.pod,%.html,$(notdir $(wildcard ../rec/*Record.dbd.pod)))
|
||||
|
||||
vpath %.png $(SRC_DIRS)
|
||||
|
||||
DOCS += image/compress-1.png
|
||||
DOCS += image/compress-2.png
|
||||
|
||||
HTMLS += image/compress-1.png
|
||||
HTMLS += image/compress-2.png
|
||||
|
@ -34,6 +34,7 @@ PERL_SCRIPTS += dbdToRecordtypeH.pl
|
||||
PERL_SCRIPTS += dbdExpand.pl
|
||||
PERL_SCRIPTS += dbExpand.pl
|
||||
PERL_SCRIPTS += dbdToHtml.pl
|
||||
PERL_SCRIPTS += dbdToMD.pl
|
||||
PERL_SCRIPTS += registerRecordDeviceDriver.pl
|
||||
|
||||
HTMLS += dbdToHtml.html
|
||||
|
307
modules/database/src/tools/dbdToMD.pl
Normal file
307
modules/database/src/tools/dbdToMD.pl
Normal file
@ -0,0 +1,307 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# SPDX-License-Identifier: EPICS
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
use strict;
|
||||
|
||||
|
||||
use FindBin qw($Bin);
|
||||
use lib ("$Bin/../../lib/perl");
|
||||
|
||||
use DBD;
|
||||
use DBD::Parser;
|
||||
use EPICS::Getopts;
|
||||
use EPICS::macLib;
|
||||
use EPICS::PodMD;
|
||||
use EPICS::Readfile;
|
||||
|
||||
use Pod::Usage;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
dbdToMD.pl - Convert DBD file with POD to Markdown
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<dbdToMD.pl> [B<-h>] [B<-D>] [B<-I> dir] [B<-o> file] file.dbd.pod
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Generates MArkdown documentation from a B<.dbd.pod> file.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
B<dbdToMD.pl> understands the following options:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<-h>
|
||||
|
||||
Help, display usage information.
|
||||
|
||||
=item B<-H>
|
||||
|
||||
Conversion help, display information about converting reference documentation
|
||||
from the EPICS Wiki into a B<.dbd.pod> file for use with this tool.
|
||||
|
||||
=item B<-I>
|
||||
|
||||
Path to look for include files.
|
||||
|
||||
=item B<-o> file
|
||||
|
||||
Name of the output file to be created.
|
||||
|
||||
=back
|
||||
|
||||
If no output filename is set, the file created will be named after the input
|
||||
file, removing any directory components in the path and replacing any
|
||||
B<.dbd.pod> file extension with B<.md>.
|
||||
|
||||
=cut
|
||||
|
||||
our ($opt_h, $opt_H, @opt_I, $opt_o);
|
||||
|
||||
my $tool = 'dbdToMD.pl';
|
||||
|
||||
getopts('hHI@o:') or
|
||||
pod2usage(2);
|
||||
pod2usage(-verbose => 2) if $opt_H;
|
||||
pod2usage(1) if $opt_h;
|
||||
pod2usage("$tool: No input file given.\n") if @ARGV != 1;
|
||||
|
||||
my $dbd = DBD->new();
|
||||
|
||||
my $infile = shift @ARGV;
|
||||
$infile =~ m/\.dbd.pod$/ or
|
||||
pod2usage("$tool: Input file '$infile' must have '.dbd.pod' extension.\n");
|
||||
|
||||
ParseDBD($dbd, Readfile($infile, 0, \@opt_I));
|
||||
|
||||
if (!$opt_o) {
|
||||
($opt_o = $infile) =~ s/\.dbd\.pod$/.md/;
|
||||
$opt_o =~ s/^.*\///;
|
||||
$opt_o =~ s/dbCommonRecord/dbCommon/;
|
||||
}
|
||||
|
||||
(my $title = $opt_o) =~ s/\.md$//;
|
||||
|
||||
open my $out, '>', $opt_o or
|
||||
die "Can't create $opt_o: $!\n";
|
||||
|
||||
$SIG{__DIE__} = sub {
|
||||
die @_ if $^S; # Ignore eval deaths
|
||||
close $out;
|
||||
unlink $opt_o;
|
||||
};
|
||||
|
||||
sub make_fragment {
|
||||
my $fragment = $_[1];
|
||||
$fragment =~ s/\W+/-/g;
|
||||
$fragment = lc($fragment);
|
||||
$_[1] = $fragment;
|
||||
}
|
||||
|
||||
my $podRst = EPICS::PodMD->new(
|
||||
perldoc_url_prefix => '',
|
||||
perldoc_fragment_format => make_fragment,
|
||||
markdown_fragment_format => make_fragment,
|
||||
);
|
||||
|
||||
# Parse the Pod text from the root DBD object
|
||||
my $pod = join "\n",
|
||||
map {
|
||||
# Handle a 'recordtype' Pod directive
|
||||
if (m/^ =recordtype \s+ (\w+) /x) {
|
||||
my $rn = $1;
|
||||
my $rtyp = $dbd->recordtype($rn);
|
||||
die "Unknown recordtype '$rn' in $infile POD directive\n"
|
||||
unless $rtyp;
|
||||
rtypeToMD($rtyp, $dbd);
|
||||
}
|
||||
# Handle a 'menu' Pod directive
|
||||
elsif (m/^ =menu \s+ (\w+) /x) {
|
||||
my $mn = $1;
|
||||
my $menu = $dbd->menu($mn);
|
||||
die "Unknown menu '$mn' in $infile POD directive\n"
|
||||
unless $menu;
|
||||
menuToMD($menu);
|
||||
}
|
||||
elsif (m/^ =title \s+ (.*)/x) {
|
||||
$title = $1;
|
||||
"=head1 $title";
|
||||
}
|
||||
else {
|
||||
$_;
|
||||
}
|
||||
} $dbd->pod;
|
||||
|
||||
$podRst->output_fh($out);
|
||||
$podRst->parse_string_document($pod);
|
||||
close $out;
|
||||
|
||||
sub menuToMD {
|
||||
my ($menu) = @_;
|
||||
my $index = 0;
|
||||
return "| Index | Identifier | Choice String |",
|
||||
"| ----- | ---------- | ------------- |",
|
||||
map({choiceTableRow($_, $index++)} $menu->choices);
|
||||
}
|
||||
|
||||
sub choiceTableRow {
|
||||
my ($ch, $index) = @_;
|
||||
my ($id, $name) = @{$ch};
|
||||
return "| $index | $id | $name |";
|
||||
}
|
||||
|
||||
sub rtypeToMD {
|
||||
my ($rtyp, $dbd) = @_;
|
||||
return map {
|
||||
# Handle a 'fields' Pod directive
|
||||
if (m/^ =fields \s+ (\w+ (?:\s* , \s* \w+ )* )/x) {
|
||||
my @names = split /\s*,\s*/, $1;
|
||||
# Look up the named fields
|
||||
my @fields = map {
|
||||
my $field = $rtyp->field($_);
|
||||
die "Unknown field name '$_' in $infile POD\n"
|
||||
unless $field;
|
||||
$field;
|
||||
} @names;
|
||||
# Generate Pod for the table
|
||||
"| Field | Summary | Type | DCT | Default | Read | Write | CA PP |",
|
||||
"| ----- | ------- | ---- | --- | ------- | ---- | ----- | ----- |",
|
||||
map({fieldTableRow($_, $dbd)} @fields);
|
||||
}
|
||||
# Handle a 'menu' Pod directive
|
||||
elsif (m/^ =menu \s+ (\w+) /x) {
|
||||
my $mn = $1;
|
||||
my $menu = $dbd->menu($mn);
|
||||
die "Unknown menu '$mn' in $infile POD directive\n"
|
||||
unless $menu;
|
||||
menuToMD($menu);
|
||||
}
|
||||
else {
|
||||
# Raw text line
|
||||
$_;
|
||||
}
|
||||
} $rtyp->pod;
|
||||
}
|
||||
|
||||
sub fieldTableRow {
|
||||
my ($fld, $dbd) = @_;
|
||||
my @md;
|
||||
push @md, $fld->name, $fld->attribute('prompt');
|
||||
|
||||
my $type = $fld->public_type;
|
||||
if ($type eq 'STRING') {
|
||||
$type .= ' [' . $fld->attribute('size') . ']';
|
||||
} elsif ($type eq 'MENU') {
|
||||
my $mn = $fld->attribute('menu');
|
||||
my $menu = $dbd->menu($mn);
|
||||
my $mnl = lc($mn);
|
||||
my $url = $menu ? "/menu-$mnl" : "${mn}.md";
|
||||
#just pass a L directive for the parser
|
||||
$type .= " L<$mn|$url>";
|
||||
}
|
||||
push @md, $type;
|
||||
|
||||
push @md, $fld->attribute('promptgroup') ? 'Yes' : 'No';
|
||||
push @md, $fld->attribute('initial') || ' ';
|
||||
push @md, $fld->readable;
|
||||
push @md, $fld->writable;
|
||||
push @md, $fld->attribute('pp') eq 'TRUE' ? 'Yes' : 'No';
|
||||
return '| ' . join(' | ', @md) . ' |';
|
||||
}
|
||||
|
||||
# Native type presented to dbAccess users
|
||||
sub DBD::Recfield::public_type {
|
||||
my $fld = shift;
|
||||
m/^ =type \s+ (.+) /x && return $1 for $fld->comments;
|
||||
my $type = $fld->dbf_type;
|
||||
$type =~ s/^DBF_//;
|
||||
return $type;
|
||||
}
|
||||
|
||||
# Check if this field is readable
|
||||
sub DBD::Recfield::readable {
|
||||
my $fld = shift;
|
||||
m/^ =read \s+ (?i) (Yes|No) /x && return $1 for $fld->comments;
|
||||
return 'Probably'
|
||||
if $fld->attribute('special') eq "SPC_DBADDR";
|
||||
return $fld->dbf_type eq 'DBF_NOACCESS' ? 'No' : 'Yes';
|
||||
}
|
||||
|
||||
# Check if this field is writable
|
||||
sub DBD::Recfield::writable {
|
||||
my $fld = shift;
|
||||
m/^ =write \s+ (?i) (Yes|No) /x && return $1 for $fld->comments;
|
||||
my $special = $fld->attribute('special');
|
||||
return 'No'
|
||||
if $special eq "SPC_NOMOD";
|
||||
return 'Maybe'
|
||||
if $special eq "SPC_DBADDR";
|
||||
return $fld->dbf_type eq "DBF_NOACCESS" ? 'No' : 'Yes';
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head1 Converting Wiki Record Reference to POD
|
||||
|
||||
If you open the src/std/rec/aiRecord.dbd.pod file in your favourite plain text
|
||||
editor you'll see what input was required to generate the aiRecord.html file.
|
||||
The text markup language we're using is a standard called POD (Plain Old
|
||||
Documentation) which is used by Perl developers, but you don't need to know Perl
|
||||
at all to be able to use it.
|
||||
|
||||
When we add POD markup to a record type, we rename its *Record.dbd file to
|
||||
.dbd.pod in the src/std/rec directory; no other changes are needed for the build
|
||||
system to find it by its new name. The POD content is effectively just a new
|
||||
kind of comment that appears in .dbd.pod files, which the formatter knows how to
|
||||
convert into Markdown. The build also generates a plain *Record.dbd file from this
|
||||
same input file by stripping out all of the POD markup.
|
||||
|
||||
Documentation for Perl's POD markup standard can be found online at
|
||||
L<https://perldoc.perl.org/perlpod.html> or you may be able to type 'perldoc
|
||||
perlpod' into a Linux command-line to see the same text. We added a few POD
|
||||
keywords of our own to handle the table generation, and I'll cover those briefly
|
||||
below.
|
||||
|
||||
POD text can appear almost anywhere in a dbd.pod file. It always starts with a
|
||||
line "=[keyword] [additional text...]" where [keyword] is "title", "head1"
|
||||
through "head4" etc.. The POD text ends with a line "=cut". There must be a
|
||||
blank line above every POD line, and in many cases below it as well.
|
||||
|
||||
The POD keywords we have added are "title", "recordtype", "menu", "fields",
|
||||
"type", "read" and "write". The last 3 are less common but are used in some of
|
||||
the other record types such as the waveform and aSub records.
|
||||
|
||||
The most interesting of our new keywords is "fields", which takes a list of
|
||||
record field names on the same line after the keyword and generates an Markdown
|
||||
Table describing those fields based on the field description found in the DBD
|
||||
parts. In the ai documentation the first such table covers the DTYP and INP
|
||||
fields.
|
||||
|
||||
Note that the "=fields" line must appear inside the DBD's declaration of the
|
||||
record type, i.e. after the line
|
||||
|
||||
recordtype(ai) {
|
||||
|
||||
The "type", "read" and "write" POD keywords are used inside an individual record
|
||||
field declaration and provide information for the "Type", "Read" and "Write"
|
||||
columns of the field's table output for fields where this information is
|
||||
normally supplied by the record support code. Usage examples for these keywords
|
||||
can be found in the aai and aSub record types.
|
||||
|
||||
If you look at the L<aoRecord.dbd.pod> file you'll see that the POD there starts
|
||||
by documenting a record-specific menu definition. The "menu" keyword generates a
|
||||
table that lists all the choices found in the named menu. Any MENU fields in the
|
||||
field tables that refer to a locally-defined menu will generate a link to a
|
||||
document section which must be titled "Menu [menuName]".
|
||||
|
||||
=cut
|
@ -21,7 +21,9 @@ dbRecStdTest_LIBS += dbRecStd dbCore ca Com
|
||||
PROD_LIBS = dbRecStdTest dbRecStd dbCore ca Com
|
||||
|
||||
TARGETS += $(COMMON_DIR)/recTestIoc.dbd
|
||||
ifneq (inc,$(strip $(MAKECMDGOALS)))
|
||||
DBDDEPENDS_FILES += recTestIoc.dbd$(DEP)
|
||||
endif
|
||||
recTestIoc_DBD = base.dbd
|
||||
recTestIoc_DBD += bptTypeKdegC.dbd
|
||||
recTestIoc_DBD += bptTypeKdegF.dbd
|
||||
@ -174,7 +176,9 @@ TESTS += regressTest
|
||||
TARGETS += $(COMMON_DIR)/simmTest.dbd
|
||||
TARGETS += $(COMMON_DIR)/simmTest.db
|
||||
DBDDEPENDS_FILES += simmTest.dbd$(DEP)
|
||||
ifneq (inc,$(strip $(MAKECMDGOALS)))
|
||||
DBDDEPENDS_FILES += simmTest.db$(DEP)
|
||||
endif
|
||||
simmTest_DBD += base.dbd
|
||||
TESTPROD_HOST += simmTest
|
||||
simmTest_SRCS += simmTest.c
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2002 The University of Saskatchewan
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* RTEMS configuration for EPICS
|
||||
@ -128,16 +128,17 @@ extern void *POSIX_Init(void *argument);
|
||||
&rtems_shell_SYSCTL_Command
|
||||
#else // LEGACY_STACK:
|
||||
#define CONFIGURE_SHELL_USER_COMMANDS \
|
||||
&bsp_interrupt_shell_command, \
|
||||
&rtems_shell_PING_Command, \
|
||||
&rtems_shell_ROUTE_Command, \
|
||||
&rtems_shell_IFCONFIG_Command
|
||||
#endif
|
||||
&bsp_interrupt_shell_command
|
||||
#endif // not LEGACY_STACK
|
||||
|
||||
#define CONFIGURE_SHELL_COMMAND_CPUUSE
|
||||
#define CONFIGURE_SHELL_COMMAND_PERIODUSE
|
||||
#define CONFIGURE_SHELL_COMMAND_STACKUSE
|
||||
#define CONFIGURE_SHELL_COMMAND_PROFREPORT
|
||||
#define CONFIGURE_SHELL_COMMAND_TOP
|
||||
#define CONFIGURE_SHELL_COMMAND_RTEMS
|
||||
|
||||
#define CONFIGURE_SHELL_COMMANDS_ALL_NETWORKING
|
||||
|
||||
#define CONFIGURE_SHELL_COMMAND_CP
|
||||
#define CONFIGURE_SHELL_COMMAND_PWD
|
||||
@ -155,14 +156,15 @@ extern void *POSIX_Init(void *argument);
|
||||
#define CONFIGURE_SHELL_COMMAND_SHUTDOWN
|
||||
|
||||
#include <rtems/shellconfig.h>
|
||||
|
||||
#define RTEMS_BSD_CONFIG_BSP_CONFIG
|
||||
#define RTEMS_BSD_CONFIG_SERVICE_TELNETD
|
||||
#define RTEMS_BSD_CONFIG_TELNETD_STACK_SIZE (16 * 1024)
|
||||
#define RTEMS_BSD_CONFIG_SERVICE_FTPD
|
||||
#define RTEMS_BSD_CONFIG_FIREWALL_PF
|
||||
#else
|
||||
#else // __RTEMS_MAJOR__ > 4
|
||||
#include <rtems/shellconfig.h>
|
||||
#endif // not LEGACY_STACK
|
||||
#endif // __RTEMS_MAJOR__ > 4
|
||||
|
||||
#if __RTEMS_MAJOR__ < 5 // still needed in Version 4?
|
||||
#define CONFIGURE_MAXIMUM_TASKS rtems_resource_unlimited(30)
|
||||
|
@ -102,9 +102,9 @@ char bootp_server_name_init[128] = "1001.1001@10.0.5.1:/epics";
|
||||
char bootp_boot_file_name_init[128] = "/epics/myExample/bin/RTEMS-beatnik/myExample.boot";
|
||||
char bootp_cmdline_init[128] = "/epics/myExample/iocBoot/iocmyExample/st.cmd";
|
||||
|
||||
struct in_addr rtems_bsdnet_bootp_server_address;
|
||||
/* TODO check rtems_bsdnet_bootp_cmdline */
|
||||
#ifndef RTEMS_LEGACY_STACK
|
||||
struct in_addr rtems_bsdnet_bootp_server_address;
|
||||
char *rtems_bsdnet_bootp_server_name = bootp_server_name_init;
|
||||
char *rtems_bsdnet_bootp_boot_file_name = bootp_boot_file_name_init;
|
||||
char *rtems_bsdnet_bootp_cmdline = bootp_cmdline_init;
|
||||
|
@ -54,6 +54,8 @@ include $(LIBCOM)/yajl/Makefile
|
||||
# Generate library API header file
|
||||
API_HEADER = libComAPI.h
|
||||
Com_API = libCom
|
||||
# Generate early to allow a sneak peak at dbChannel.h
|
||||
API_HEADER += dbCoreAPI.h
|
||||
|
||||
# Library to build:
|
||||
LIBRARY=Com
|
||||
|
@ -19,4 +19,8 @@ INC += asTrapWrite.h
|
||||
Com_SRCS += asLib.c
|
||||
Com_SRCS += asTrapWrite.c
|
||||
|
||||
# Allow early access to dbChannel.h
|
||||
asTrapWrite_CPPFLAGS = -I$(LIBCOM)/../../database/src/ioc/db
|
||||
|
||||
|
||||
CLEANS += asLib.c asLib_lex.c
|
||||
|
@ -22,6 +22,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dbChannel;
|
||||
|
||||
/* 0 - Use (unverified) client provided host name string.
|
||||
* 1 - Use actual client IP address. HAG() are resolved to IPs at ACF load time.
|
||||
*/
|
||||
@ -121,7 +123,7 @@ LIBCOM_API int epicsStdCall asDumpHash(void);
|
||||
LIBCOM_API int epicsStdCall asDumpHashFP(FILE *fp);
|
||||
|
||||
LIBCOM_API void * epicsStdCall asTrapWriteBeforeWithData(
|
||||
const char *userid, const char *hostid, void *addr,
|
||||
const char *userid, const char *hostid, struct dbChannel *addr,
|
||||
int dbrType, int no_elements, void *data);
|
||||
|
||||
LIBCOM_API void epicsStdCall asTrapWriteAfterWrite(void *pvt);
|
||||
|
@ -22,10 +22,10 @@
|
||||
|
||||
#include "ellLib.h"
|
||||
#include "freeList.h"
|
||||
#include "epicsStdio.h"
|
||||
#include "cantProceed.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "ellLib.h"
|
||||
#include <dbChannel.h>
|
||||
|
||||
#include "asLib.h"
|
||||
#include "asTrapWrite.h"
|
||||
@ -112,11 +112,12 @@ void epicsStdCall asTrapWriteUnregisterListener(asTrapWriteId id)
|
||||
}
|
||||
|
||||
void * epicsStdCall asTrapWriteBeforeWithData(
|
||||
const char *userid, const char *hostid, void *addr,
|
||||
const char *userid, const char *hostid, dbChannel *chan,
|
||||
int dbrType, int no_elements, void *data)
|
||||
{
|
||||
writeMessage *pwriteMessage;
|
||||
listener *plistener;
|
||||
void *pfieldsave;
|
||||
|
||||
if (pasTrapWritePvt == 0 ||
|
||||
ellCount(&pasTrapWritePvt->listenerList) <= 0) return 0;
|
||||
@ -125,13 +126,14 @@ void * epicsStdCall asTrapWriteBeforeWithData(
|
||||
pasTrapWritePvt->freeListWriteMessage);
|
||||
pwriteMessage->message.userid = userid;
|
||||
pwriteMessage->message.hostid = hostid;
|
||||
pwriteMessage->message.serverSpecific = addr;
|
||||
pwriteMessage->message.serverSpecific = chan;
|
||||
pwriteMessage->message.dbrType = dbrType;
|
||||
pwriteMessage->message.no_elements = no_elements;
|
||||
pwriteMessage->message.data = data;
|
||||
ellInit(&pwriteMessage->listenerPvtList);
|
||||
|
||||
epicsMutexMustLock(pasTrapWritePvt->lock);
|
||||
pfieldsave = chan->addr.pfield;
|
||||
ellAdd(&pasTrapWritePvt->writeMessageList, &pwriteMessage->node);
|
||||
plistener = (listener *)ellFirst(&pasTrapWritePvt->listenerList);
|
||||
while (plistener) {
|
||||
@ -141,6 +143,7 @@ void * epicsStdCall asTrapWriteBeforeWithData(
|
||||
plistenerPvt->plistener = plistener;
|
||||
pwriteMessage->message.userPvt = 0;
|
||||
plistener->func(&pwriteMessage->message, 0);
|
||||
chan->addr.pfield = pfieldsave;
|
||||
plistenerPvt->userPvt = pwriteMessage->message.userPvt;
|
||||
ellAdd(&pwriteMessage->listenerPvtList, &plistenerPvt->node);
|
||||
plistener = (listener *)ellNext(&plistener->node);
|
||||
@ -153,11 +156,15 @@ void epicsStdCall asTrapWriteAfterWrite(void *pvt)
|
||||
{
|
||||
writeMessage *pwriteMessage = (writeMessage *)pvt;
|
||||
listenerPvt *plistenerPvt;
|
||||
dbChannel *chan;
|
||||
void *pfieldsave;
|
||||
|
||||
if (pwriteMessage == 0 ||
|
||||
pasTrapWritePvt == 0) return;
|
||||
|
||||
epicsMutexMustLock(pasTrapWritePvt->lock);
|
||||
chan = pwriteMessage->message.serverSpecific;
|
||||
pfieldsave = chan->addr.pfield;
|
||||
plistenerPvt = (listenerPvt *)ellFirst(&pwriteMessage->listenerPvtList);
|
||||
while (plistenerPvt) {
|
||||
listenerPvt *pnext = (listenerPvt *)ellNext(&plistenerPvt->node);
|
||||
@ -165,6 +172,7 @@ void epicsStdCall asTrapWriteAfterWrite(void *pvt)
|
||||
|
||||
pwriteMessage->message.userPvt = plistenerPvt->userPvt;
|
||||
plistener->func(&pwriteMessage->message, 1);
|
||||
chan->addr.pfield = pfieldsave;
|
||||
ellDelete(&pwriteMessage->listenerPvtList, &plistenerPvt->node);
|
||||
freeListFree(pasTrapWritePvt->freeListListenerPvt, plistenerPvt);
|
||||
plistenerPvt = pnext;
|
||||
|
@ -26,6 +26,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dbChannel;
|
||||
|
||||
/**
|
||||
* \brief The message passed to registered listeners.
|
||||
*/
|
||||
@ -39,7 +41,7 @@ typedef struct asTrapWriteMessage {
|
||||
* the value the server provides to asTrapWriteWithData(), which
|
||||
* for RSRV is the dbChannel pointer for the target field.
|
||||
*/
|
||||
void *serverSpecific;
|
||||
struct dbChannel *serverSpecific;
|
||||
/** \brief A field for use by the \ref asTrapWriteListener.
|
||||
*
|
||||
* When the listener is called before the write, this has the
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -78,10 +79,8 @@ void epicsThread :: printLastChanceExceptionMessage (
|
||||
"with type \"%s\" in thread \"%s\" at %s\n",
|
||||
pExceptionContext, pExceptionTypeName, name, date );
|
||||
errlogFlush ();
|
||||
// This behavior matches the C++ implementation when an exception
|
||||
// isn't handled by the thread code. Users can install their own
|
||||
// application-specific unexpected handler if preferred.
|
||||
std::unexpected ();
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
extern "C" void epicsThreadCallEntryPoint ( void * pPvt )
|
||||
|
52
modules/libcom/src/osi/os/RTEMS-posix/osdThreadExtra.c
Executable file
52
modules/libcom/src/osi/os/RTEMS-posix/osdThreadExtra.c
Executable file
@ -0,0 +1,52 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* SPDX-License-Identifier: EPICS
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* Author: Marty Kraimer Date: 18JAN2000 */
|
||||
/* Author: Chris Johns Date: 21JUL2023 */
|
||||
|
||||
/* This is part of the posix implementation of epicsThread */
|
||||
|
||||
#include "epicsStdio.h"
|
||||
#include "ellLib.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsThread.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
void epicsThreadShowInfo(epicsThreadOSD *pthreadInfo, unsigned int level)
|
||||
{
|
||||
if(!pthreadInfo) {
|
||||
fprintf(epicsGetStdout()," NAME EPICS ID "
|
||||
"PTHREAD ID OSIPRI OSSPRI STATE\n");
|
||||
} else {
|
||||
struct sched_param param;
|
||||
int policy;
|
||||
int priority = 0;
|
||||
|
||||
if(pthreadInfo->tid) {
|
||||
int status;
|
||||
status = pthread_getschedparam(pthreadInfo->tid,&policy,¶m);
|
||||
if(!status) priority = param.sched_priority;
|
||||
}
|
||||
fprintf(epicsGetStdout(),"%16.16s %14p %12lu %3d%8d %8.8s\n",
|
||||
pthreadInfo->name,(void *)
|
||||
pthreadInfo,(unsigned long)pthreadInfo->tid,
|
||||
pthreadInfo->osiPriority,priority,
|
||||
pthreadInfo->isSuspended?"SUSPEND":"OK");
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_hook(epicsThreadId pthreadInfo)
|
||||
{
|
||||
pthread_setname_np(pthreadInfo->tid, pthreadInfo->name);
|
||||
}
|
||||
|
||||
EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault = thread_hook;
|
||||
EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain = thread_hook;
|
@ -139,8 +139,12 @@ bswap32(epicsUInt32 value)
|
||||
/* hton* is optimized or a builtin for most compilers
|
||||
* so use it if possible
|
||||
*/
|
||||
#ifndef bswap16
|
||||
#define bswap16(v) htons(v)
|
||||
#endif
|
||||
#ifndef bswap32
|
||||
#define bswap32(v) htonl(v)
|
||||
#endif
|
||||
|
||||
# define be_ioread16(A) bswap16(nat_ioread16(A))
|
||||
# define be_ioread32(A) bswap32(nat_ioread32(A))
|
||||
|
@ -615,6 +615,10 @@ epicsThreadCreateOpt(const char * name,
|
||||
start_routine, pthreadInfo);
|
||||
if (status==EPERM) {
|
||||
/* Try again without SCHED_FIFO*/
|
||||
if (pthreadInfo->joinable) {
|
||||
int cnt = epicsAtomicDecrIntT(&pthreadInfo->refcnt);
|
||||
assert(cnt==1);
|
||||
}
|
||||
free_threadInfo(pthreadInfo);
|
||||
|
||||
pthreadInfo = init_threadInfo(name, opts->priority, stackSize,
|
||||
@ -630,12 +634,15 @@ epicsThreadCreateOpt(const char * name,
|
||||
if (status) {
|
||||
if (pthreadInfo->joinable) {
|
||||
/* release extra ref which would have been for epicsThreadMustJoin() */
|
||||
epicsAtomicDecrIntT(&pthreadInfo->refcnt);
|
||||
int cnt = epicsAtomicDecrIntT(&pthreadInfo->refcnt);
|
||||
assert(cnt==1);
|
||||
}
|
||||
|
||||
free_threadInfo(pthreadInfo);
|
||||
return 0;
|
||||
}
|
||||
/* New thread starting and is now responsible for one free_threadInfo().
|
||||
* If joinable, then caller responsible for arranging one epicsThreadMustJoin()
|
||||
*/
|
||||
|
||||
status = pthread_sigmask(SIG_SETMASK, &oldSig, NULL);
|
||||
checkStatusOnce(status, "pthread_sigmask");
|
||||
@ -680,34 +687,54 @@ static epicsThreadOSD *createImplicit(void)
|
||||
|
||||
void epicsThreadMustJoin(epicsThreadId id)
|
||||
{
|
||||
void *ret = NULL;
|
||||
int status;
|
||||
int prev;
|
||||
epicsThreadId self;
|
||||
|
||||
if(!id) {
|
||||
if(!id)
|
||||
return;
|
||||
} else if(epicsAtomicCmpAndSwapIntT(&id->joinable, 1, 0)!=1) {
|
||||
if(epicsThreadGetIdSelf()==id) {
|
||||
errlogPrintf("Warning: %s thread self-join of unjoinable\n", id->name);
|
||||
|
||||
prev = epicsAtomicCmpAndSwapIntT(&id->joinable, 1, 0);
|
||||
self = epicsThreadGetIdSelf();
|
||||
|
||||
if(prev==0) {
|
||||
/* join of unjoinable */
|
||||
if(self==id) {
|
||||
errlogPrintf(ERL_WARNING ": %s thread self-join of unjoinable\n", id->name);
|
||||
return;
|
||||
|
||||
} else {
|
||||
/* try to error nicely, however in all likelihood de-ref of
|
||||
* 'id' has already caused SIGSEGV as we are racing thread exit,
|
||||
* which free's 'id'.
|
||||
*/
|
||||
cantProceed("Error: %s thread not joinable.\n", id->name);
|
||||
cantProceed(ERL_ERROR ": %s can't join unjoinable %s\n", self->name, id->name);
|
||||
}
|
||||
return;
|
||||
|
||||
} else if(prev!=1) { /* also not 0, the only other allowed value. */
|
||||
cantProceed(ERL_ERROR ": %s joins corrupt thread handle\n", self->name);
|
||||
}
|
||||
|
||||
status = pthread_join(id->tid, &ret);
|
||||
if(status == EDEADLK) {
|
||||
/* Thread can't join itself (directly or indirectly)
|
||||
* so we detach instead.
|
||||
/* from this point, we are responsible to either detach or join (or leak memory) */
|
||||
|
||||
if(self!=id) {
|
||||
status = pthread_join(id->tid, NULL);
|
||||
checkStatusOnce(status, "pthread_join");
|
||||
/* on error, continue and attempt to detach */
|
||||
|
||||
} else {
|
||||
/* Thread self pthread_join() isn't portable.
|
||||
* We choose to allow, and treat as detach.
|
||||
*/
|
||||
status = EDEADLK;
|
||||
}
|
||||
|
||||
if(status) {
|
||||
status = pthread_detach(id->tid);
|
||||
checkStatusOnce(status, "pthread_detach");
|
||||
} else checkStatusOnce(status, "pthread_join");
|
||||
free_threadInfo(id);
|
||||
}
|
||||
|
||||
free_threadInfo(id); /* release joinable reference */
|
||||
}
|
||||
|
||||
LIBCOM_API void epicsStdCall epicsThreadSuspendSelf(void)
|
||||
|
61
src/tools/EPICS/PodMD.pm
Normal file
61
src/tools/EPICS/PodMD.pm
Normal file
@ -0,0 +1,61 @@
|
||||
# SPDX-License-Identifier: EPICS
|
||||
|
||||
package EPICS::PodMD;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'Pod::Markdown';
|
||||
|
||||
# Translate L<link text|filename/Section name>
|
||||
# into <a href="filename.md#Section-name">link text</a>#
|
||||
# This is for Sphinx processing on Readthedocs. Sphinx converts
|
||||
# links to .md into .html automatically in the processing.
|
||||
|
||||
sub format_perldoc_url {
|
||||
my ($self, $name, $section) = @_;
|
||||
|
||||
my $url_prefix = $self->perldoc_url_prefix;
|
||||
if (
|
||||
defined($name)
|
||||
&& $self->is_local_module($name)
|
||||
&& defined($self->local_module_url_prefix)
|
||||
) {
|
||||
$url_prefix = $self->local_module_url_prefix;
|
||||
}
|
||||
|
||||
my $url = '';
|
||||
|
||||
# If the link is to another module (external link).
|
||||
if (defined($name)) {
|
||||
$name .= ".md" unless $name =~ m/\.md$/;
|
||||
$url = $url_prefix .
|
||||
($self->escape_url ? URI::Escape::uri_escape($name) : $name);
|
||||
}
|
||||
|
||||
# See https://rt.cpan.org/Ticket/Display.html?id=57776
|
||||
# for a discussion on the need to mangle the section.
|
||||
if ($section){
|
||||
|
||||
my $method = $url
|
||||
# If we already have a prefix on the url it's external.
|
||||
? $self->perldoc_fragment_format
|
||||
# Else an internal link points to this markdown doc.
|
||||
: $self->markdown_fragment_format;
|
||||
|
||||
$method = 'format_fragment_' . $method
|
||||
unless ref($method);
|
||||
|
||||
{
|
||||
# Set topic to enable code refs to be simple.
|
||||
local $_ = $section;
|
||||
$section = $self->$method($section);
|
||||
}
|
||||
|
||||
$url .= '#' . $section;
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
1;
|
@ -43,6 +43,8 @@ sub HostArch {
|
||||
return "cygwin-x86" if m/^i[3-6]86-cygwin/;
|
||||
return 'solaris-sparc' if m/^sun4-solaris/;
|
||||
return 'solaris-x86' if m/^i86pc-solaris/;
|
||||
return 'freebsd-x86_64' if m/^x86_64-freebsd/;
|
||||
return 'freebsd-x86_64' if m/^amd64-freebsd/;
|
||||
|
||||
my ($kernel, $hostname, $release, $version, $cpu) = uname;
|
||||
if (m/^darwin/) {
|
||||
|
@ -17,7 +17,10 @@ PERL_MODULES += EPICS/Release.pm
|
||||
PERL_MODULES += EPICS/Readfile.pm
|
||||
PERL_MODULES += EPICS/Getopts.pm
|
||||
PERL_MODULES += EPICS/PodHtml.pm
|
||||
PERL_MODULES += EPICS/PodMD.pm
|
||||
PERL_MODULES += EPICS/PodXHtml.pm
|
||||
PERL_MODULES += Pod/Markdown.pm
|
||||
PERL_MODULES += URI/Escape.pm
|
||||
|
||||
# This goes into lib/perl, not bin/<host>
|
||||
PERL_MODULES += EpicsHostArch.pl
|
||||
@ -29,6 +32,7 @@ PERL_SCRIPTS += depclean.pl
|
||||
PERL_SCRIPTS += dos2unix.pl
|
||||
PERL_SCRIPTS += epicsProve.pl
|
||||
PERL_SCRIPTS += expandVars.pl
|
||||
PERL_SCRIPTS += filterMakeflags.pl
|
||||
PERL_SCRIPTS += fullPathName.pl
|
||||
PERL_SCRIPTS += installEpics.pl
|
||||
PERL_SCRIPTS += makeAPIheader.pl
|
||||
@ -36,6 +40,7 @@ PERL_SCRIPTS += makeMakefile.pl
|
||||
PERL_SCRIPTS += makeTestfile.pl
|
||||
PERL_SCRIPTS += mkmf.pl
|
||||
PERL_SCRIPTS += munch.pl
|
||||
PERL_SCRIPTS += podToMD.pl
|
||||
PERL_SCRIPTS += podToHtml.pl
|
||||
PERL_SCRIPTS += podRemove.pl
|
||||
PERL_SCRIPTS += replaceVAR.pl
|
||||
@ -54,6 +59,11 @@ HTMLS += fullPathName.html
|
||||
HTMLS += makeAPIheader.html
|
||||
HTMLS += munch.html
|
||||
HTMLS += podToHtml.html
|
||||
HTMLS += podToMD.html
|
||||
HTMLS += podRemove.html
|
||||
|
||||
# The above Perl program documentation (modelled after Man pages)
|
||||
# doesn't work well in Doxygen's "Related Pages" area, the titles
|
||||
# for all doc's are "NAME", so don't convert these to Markdown.
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
1698
src/tools/Pod/Markdown.pm
Normal file
1698
src/tools/Pod/Markdown.pm
Normal file
File diff suppressed because it is too large
Load Diff
249
src/tools/URI/Escape.pm
Normal file
249
src/tools/URI/Escape.pm
Normal file
@ -0,0 +1,249 @@
|
||||
package URI::Escape;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
URI::Escape - Percent-encode and percent-decode unsafe characters
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use URI::Escape;
|
||||
$safe = uri_escape("10% is enough\n");
|
||||
$verysafe = uri_escape("foo", "\0-\377");
|
||||
$str = uri_unescape($safe);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides functions to percent-encode and percent-decode URI strings as
|
||||
defined by RFC 3986. Percent-encoding URI's is informally called "URI escaping".
|
||||
This is the terminology used by this module, which predates the formalization of the
|
||||
terms by the RFC by several years.
|
||||
|
||||
A URI consists of a restricted set of characters. The restricted set
|
||||
of characters consists of digits, letters, and a few graphic symbols
|
||||
chosen from those common to most of the character encodings and input
|
||||
facilities available to Internet users. They are made up of the
|
||||
"unreserved" and "reserved" character sets as defined in RFC 3986.
|
||||
|
||||
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||
reserved = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
||||
"!" / "$" / "&" / "'" / "(" / ")"
|
||||
/ "*" / "+" / "," / ";" / "="
|
||||
|
||||
In addition, any byte (octet) can be represented in a URI by an escape
|
||||
sequence: a triplet consisting of the character "%" followed by two
|
||||
hexadecimal digits. A byte can also be represented directly by a
|
||||
character, using the US-ASCII character for that octet.
|
||||
|
||||
Some of the characters are I<reserved> for use as delimiters or as
|
||||
part of certain URI components. These must be escaped if they are to
|
||||
be treated as ordinary data. Read RFC 3986 for further details.
|
||||
|
||||
The functions provided (and exported by default) from this module are:
|
||||
|
||||
=over 4
|
||||
|
||||
=item uri_escape( $string )
|
||||
|
||||
=item uri_escape( $string, $unsafe )
|
||||
|
||||
Replaces each unsafe character in the $string with the corresponding
|
||||
escape sequence and returns the result. The $string argument should
|
||||
be a string of bytes. The uri_escape() function will croak if given a
|
||||
characters with code above 255. Use uri_escape_utf8() if you know you
|
||||
have such chars or/and want chars in the 128 .. 255 range treated as
|
||||
UTF-8.
|
||||
|
||||
The uri_escape() function takes an optional second argument that
|
||||
overrides the set of characters that are to be escaped. The set is
|
||||
specified as a string that can be used in a regular expression
|
||||
character class (between [ ]). E.g.:
|
||||
|
||||
"\x00-\x1f\x7f-\xff" # all control and hi-bit characters
|
||||
"a-z" # all lower case characters
|
||||
"^A-Za-z" # everything not a letter
|
||||
|
||||
The default set of characters to be escaped is all those which are
|
||||
I<not> part of the C<unreserved> character class shown above as well
|
||||
as the reserved characters. I.e. the default is:
|
||||
|
||||
"^A-Za-z0-9\-\._~"
|
||||
|
||||
The second argument can also be specified as a regular expression object:
|
||||
|
||||
qr/[^A-Za-z]/
|
||||
|
||||
Any strings matched by this regular expression will have all of their
|
||||
characters escaped.
|
||||
|
||||
=item uri_escape_utf8( $string )
|
||||
|
||||
=item uri_escape_utf8( $string, $unsafe )
|
||||
|
||||
Works like uri_escape(), but will encode chars as UTF-8 before
|
||||
escaping them. This makes this function able to deal with characters
|
||||
with code above 255 in $string. Note that chars in the 128 .. 255
|
||||
range will be escaped differently by this function compared to what
|
||||
uri_escape() would. For chars in the 0 .. 127 range there is no
|
||||
difference.
|
||||
|
||||
Equivalent to:
|
||||
|
||||
utf8::encode($string);
|
||||
my $uri = uri_escape($string);
|
||||
|
||||
Note: JavaScript has a function called escape() that produces the
|
||||
sequence "%uXXXX" for chars in the 256 .. 65535 range. This function
|
||||
has really nothing to do with URI escaping but some folks got confused
|
||||
since it "does the right thing" in the 0 .. 255 range. Because of
|
||||
this you sometimes see "URIs" with these kind of escapes. The
|
||||
JavaScript encodeURIComponent() function is similar to uri_escape_utf8().
|
||||
|
||||
=item uri_unescape($string,...)
|
||||
|
||||
Returns a string with each %XX sequence replaced with the actual byte
|
||||
(octet).
|
||||
|
||||
This does the same as:
|
||||
|
||||
$string =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
|
||||
|
||||
but does not modify the string in-place as this RE would. Using the
|
||||
uri_unescape() function instead of the RE might make the code look
|
||||
cleaner and is a few characters less to type.
|
||||
|
||||
In a simple benchmark test I did,
|
||||
calling the function (instead of the inline RE above) if a few chars
|
||||
were unescaped was something like 40% slower, and something like 700% slower if none were. If
|
||||
you are going to unescape a lot of times it might be a good idea to
|
||||
inline the RE.
|
||||
|
||||
If the uri_unescape() function is passed multiple strings, then each
|
||||
one is returned unescaped.
|
||||
|
||||
=back
|
||||
|
||||
The module can also export the C<%escapes> hash, which contains the
|
||||
mapping from all 256 bytes to the corresponding escape codes. Lookup
|
||||
in this hash is faster than evaluating C<sprintf("%%%02X", ord($byte))>
|
||||
each time.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<URI>
|
||||
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 1995-2004 Gisle Aas.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself.
|
||||
|
||||
SPDX-License-Identifier: Artistic-2.0
|
||||
=cut
|
||||
|
||||
use Exporter 5.57 'import';
|
||||
our %escapes;
|
||||
our @EXPORT = qw(uri_escape uri_unescape uri_escape_utf8);
|
||||
our @EXPORT_OK = qw(%escapes);
|
||||
our $VERSION = '5.28';
|
||||
|
||||
use Carp ();
|
||||
|
||||
# Build a char->hex map
|
||||
for (0..255) {
|
||||
$escapes{chr($_)} = sprintf("%%%02X", $_);
|
||||
}
|
||||
|
||||
my %subst; # compiled patterns
|
||||
|
||||
my %Unsafe = (
|
||||
RFC2732 => qr/[^A-Za-z0-9\-_.!~*'()]/,
|
||||
RFC3986 => qr/[^A-Za-z0-9\-\._~]/,
|
||||
);
|
||||
|
||||
sub uri_escape {
|
||||
my($text, $patn) = @_;
|
||||
return undef unless defined $text;
|
||||
my $re;
|
||||
if (defined $patn){
|
||||
if (ref $patn eq 'Regexp') {
|
||||
$text =~ s{($patn)}{
|
||||
join('', map +($escapes{$_} || _fail_hi($_)), split //, "$1")
|
||||
}ge;
|
||||
return $text;
|
||||
}
|
||||
$re = $subst{$patn};
|
||||
if (!defined $re) {
|
||||
$re = $patn;
|
||||
# we need to escape the [] characters, except for those used in
|
||||
# posix classes. if they are prefixed by a backslash, allow them
|
||||
# through unmodified.
|
||||
$re =~ s{(\[:\w+:\])|(\\)?([\[\]]|\\\z)}{
|
||||
defined $1 ? $1 : defined $2 ? "$2$3" : "\\$3"
|
||||
}ge;
|
||||
eval {
|
||||
# disable the warnings here, since they will trigger later
|
||||
# when used, and we only want them to appear once per call,
|
||||
# but every time the same pattern is used.
|
||||
no warnings 'regexp';
|
||||
$re = $subst{$patn} = qr{[$re]};
|
||||
1;
|
||||
} or Carp::croak("uri_escape: $@");
|
||||
}
|
||||
}
|
||||
else {
|
||||
$re = $Unsafe{RFC3986};
|
||||
}
|
||||
$text =~ s/($re)/$escapes{$1} || _fail_hi($1)/ge;
|
||||
$text;
|
||||
}
|
||||
|
||||
sub _fail_hi {
|
||||
my $chr = shift;
|
||||
Carp::croak(sprintf "Can't escape \\x{%04X}, try uri_escape_utf8() instead", ord($chr));
|
||||
}
|
||||
|
||||
sub uri_escape_utf8 {
|
||||
my $text = shift;
|
||||
return undef unless defined $text;
|
||||
utf8::encode($text);
|
||||
return uri_escape($text, @_);
|
||||
}
|
||||
|
||||
sub uri_unescape {
|
||||
# Note from RFC1630: "Sequences which start with a percent sign
|
||||
# but are not followed by two hexadecimal characters are reserved
|
||||
# for future extension"
|
||||
my $str = shift;
|
||||
if (@_ && wantarray) {
|
||||
# not executed for the common case of a single argument
|
||||
my @str = ($str, @_); # need to copy
|
||||
for (@str) {
|
||||
s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
|
||||
}
|
||||
return @str;
|
||||
}
|
||||
$str =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg if defined $str;
|
||||
$str;
|
||||
}
|
||||
|
||||
# XXX FIXME escape_char is buggy as it assigns meaning to the string's storage format.
|
||||
sub escape_char {
|
||||
# Old versions of utf8::is_utf8() didn't properly handle magical vars (e.g. $1).
|
||||
# The following forces a fetch to occur beforehand.
|
||||
my $dummy = substr($_[0], 0, 0);
|
||||
|
||||
if (utf8::is_utf8($_[0])) {
|
||||
my $s = shift;
|
||||
utf8::encode($s);
|
||||
unshift(@_, $s);
|
||||
}
|
||||
|
||||
return join '', @URI::Escape::escapes{split //, $_[0]};
|
||||
}
|
||||
|
||||
1;
|
15
src/tools/filterMakeflags.pl
Normal file
15
src/tools/filterMakeflags.pl
Normal file
@ -0,0 +1,15 @@
|
||||
#!/bin/env perl
|
||||
#
|
||||
# Filter all versions of GNU Make's MAKEFLAGS variable to return
|
||||
# only the single-letter flags. The content differed slightly
|
||||
# between 3.81, 3.82 and 4.0; Apple still ship 3.81.
|
||||
|
||||
use strict;
|
||||
|
||||
my @flags;
|
||||
foreach (@ARGV) {
|
||||
last if m/^--$/ or m/\w+=/;
|
||||
next if m/^--/ or m/^-$/;
|
||||
push @flags, $_;
|
||||
};
|
||||
print join(' ', @flags);
|
103
src/tools/podToMD.pl
Normal file
103
src/tools/podToMD.pl
Normal file
@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env perl
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# SPDX-License-Identifier: EPICS
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# To find the EPICS::Getopts module used below we need to add our lib/perl to
|
||||
# the lib search path. If the script is running from the src/tools directory
|
||||
# before everything has been installed though, the search path must include
|
||||
# our source directory (i.e. $Bin), so we add both here.
|
||||
use FindBin qw($Bin);
|
||||
use lib ("$Bin/../../lib/perl", $Bin);
|
||||
|
||||
use EPICS::Getopts;
|
||||
|
||||
use EPICS::PodMD;
|
||||
|
||||
use Pod::Usage;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
podToMD.pl - Convert EPICS .pod files to .md
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<podToMD.pl> [B<-h>] [B<-o> file.md] file.pod
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Converts files from Perl's POD format into Markdown format.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
B<podToMD.pl> understands the following options:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<-h>
|
||||
|
||||
Help, display this document as text.
|
||||
|
||||
=item B<-o> file.md
|
||||
|
||||
Name of the Markdown output file to be created.
|
||||
|
||||
=back
|
||||
|
||||
If no output filename is set, the file created will be named after the input
|
||||
file, removing any directory components in the path and replacing any file
|
||||
extension with .md.
|
||||
|
||||
=cut
|
||||
|
||||
our ($opt_o, $opt_h);
|
||||
|
||||
sub HELP_MESSAGE {
|
||||
pod2usage(-exitval => 2, -verbose => $opt_h);
|
||||
}
|
||||
|
||||
HELP_MESSAGE() if !getopts('ho:') || $opt_h || @ARGV != 1;
|
||||
|
||||
my $infile = shift @ARGV;
|
||||
|
||||
my @inpath = split /\//, $infile;
|
||||
my $file = pop @inpath;
|
||||
|
||||
if (!$opt_o) {
|
||||
($opt_o = $file) =~ s/\. \w+ $/.md/x;
|
||||
}
|
||||
|
||||
open my $out, '>', $opt_o or
|
||||
die "Can't create $opt_o: $!\n";
|
||||
|
||||
$SIG{__DIE__} = sub {
|
||||
die @_ if $^S; # Ignore eval deaths
|
||||
close $out;
|
||||
unlink $opt_o;
|
||||
};
|
||||
|
||||
my $podMD = EPICS::PodMD->new();
|
||||
|
||||
$podMD->perldoc_url_prefix('');
|
||||
# $podMD->perldoc_url_postfix('.md');
|
||||
$podMD->output_string(\my $md);
|
||||
$podMD->parse_file($infile);
|
||||
|
||||
print $out $md;
|
||||
close $out;
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 2013 UChicago Argonne LLC, as Operator of Argonne National
|
||||
Laboratory.
|
||||
|
||||
This software is distributed under the terms of the EPICS Open License.
|
||||
|
||||
=cut
|
0
startup/win32.bat
Executable file → Normal file
0
startup/win32.bat
Executable file → Normal file
Reference in New Issue
Block a user