Compare commits
202 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f142e03f5 | ||
|
|
bb7b754730 | ||
|
|
a9ff175cf0 | ||
|
|
458c0af4e9 | ||
|
|
eacee1b548 | ||
|
|
6754404d0f | ||
|
|
6734918e6e | ||
|
|
1c566e2110 | ||
|
|
7f878d3074 | ||
|
|
12ab69402a | ||
|
|
0926f7db0f | ||
|
|
08eaea64d2 | ||
|
|
bee00658ae | ||
|
|
e881cb15c4 | ||
|
|
4a0f488657 | ||
|
|
2340c6e6c1 | ||
|
|
5593103c11 | ||
| 5a8b6e4111 | |||
|
|
c4348dc6e0 | ||
|
|
9d0597fc15 | ||
|
|
93208af61c | ||
|
|
9c23247c04 | ||
|
|
552b2d1766 | ||
|
|
1755a46bfe | ||
|
|
36d0fbd7be | ||
|
|
30e1431fb4 | ||
|
|
3f209efa3c | ||
|
|
2c1c35268e | ||
|
|
745c3f552e | ||
|
|
27918cb7a1 | ||
|
|
8723d4d9cb | ||
|
|
410921b5ef | ||
|
|
d3e96c4c2b | ||
|
|
43bd5ee1c2 | ||
|
|
34a0b387b0 | ||
|
|
78d685688c | ||
|
|
cf3173b6f4 | ||
|
|
c95cbe4a0f | ||
|
|
1e471832e9 | ||
|
|
40d9a21c0c | ||
|
|
dd9f38d711 | ||
|
|
7050bded31 | ||
|
|
c19605232a | ||
|
|
4e81eaa7e8 | ||
|
|
99852c6504 | ||
|
|
a9e3fa74aa | ||
|
|
d997690aa5 | ||
|
|
326ef00bc9 | ||
|
|
a043599e18 | ||
|
|
02be10069e | ||
|
|
4f14e9e674 | ||
|
|
ff4317d05a | ||
|
|
63919e199c | ||
|
|
f775e0b8f6 | ||
|
|
518bab9675 | ||
|
|
a8036d7f34 | ||
|
|
436ce4526b | ||
|
|
b49f06916e | ||
|
|
9ba0081a82 | ||
|
|
c60056d4d6 | ||
|
|
68c056f2f8 | ||
|
|
48a6d2f781 | ||
|
|
79bb9e000b | ||
|
|
c404eb3f83 | ||
|
|
7beb32e209 | ||
|
|
a365de2419 | ||
|
|
035ffdf045 | ||
|
|
5f0d52cd5c | ||
|
|
2035fc641a | ||
|
|
d25c9a74ad | ||
|
|
e20151439b | ||
|
|
4e055610b7 | ||
|
|
db027d4a7f | ||
|
|
17ee7dd6c7 | ||
|
|
dc99d63df8 | ||
|
|
53897d4a82 | ||
|
|
d24a297304 | ||
|
|
761edcae15 | ||
|
|
b890d584bc | ||
|
|
db2f7d8b92 | ||
|
|
d83e3b5de1 | ||
|
|
cbac1c54f5 | ||
|
|
2cfbf5c1c9 | ||
|
|
d108a1ff11 | ||
|
|
0a65707383 | ||
| 9048e998fb | |||
|
|
7632c355ee | ||
|
|
4730e14cc7 | ||
|
|
c969f05f51 | ||
|
|
8fd36d8eef | ||
|
|
3947b9a061 | ||
|
|
cf56a0e08e | ||
| 6b5abf76c8 | |||
| 3b3261c877 | |||
| 30d8febb0b | |||
| 4ad98d5b4f | |||
| 14b9ac3277 | |||
| 275c4c7cf4 | |||
| 5d808b7c02 | |||
| afdf34b791 | |||
| ea05bab26a | |||
| edb8f1a5df | |||
| 8f5be5f0ad | |||
| bc34526bcb | |||
| 0ee36388cb | |||
| c51c83b1d5 | |||
| d0ef45acc3 | |||
| 7ab56a68d1 | |||
| 39c8d5619a | |||
| e0dfb6cff8 | |||
| 3627c38a57 | |||
| 17a8dbc2d7 | |||
| b1f445925d | |||
|
|
297f04bddc | ||
|
|
a7bf59079f | ||
|
|
baced535e3 | ||
|
|
be7c6a0a0a | ||
|
|
14476391c0 | ||
|
|
223b292c33 | ||
|
|
68121ec907 | ||
|
|
228ad79b7a | ||
|
|
bbc0a56d2b | ||
|
|
9726b9efc9 | ||
|
|
f44f4ac7ad | ||
|
|
f1e83b22f2 | ||
|
|
cdc627a15c | ||
|
|
8a90688880 | ||
|
|
bbdd9392fe | ||
|
|
fe35e6e703 | ||
|
|
3e891a12ff | ||
|
|
f8a6735691 | ||
|
|
dc579b78db | ||
|
|
22ee229aca | ||
|
|
1ae3bd6c70 | ||
|
|
cbba08b1ef | ||
|
|
53044571fb | ||
|
|
f8df3473ab | ||
|
|
e8bee54531 | ||
|
|
0cae0db98b | ||
|
|
df6981ceae | ||
|
|
11984633dc | ||
|
|
051ba20fe1 | ||
|
|
d6cf29e942 | ||
|
|
bdd41cca13 | ||
|
|
e40970bd5e | ||
|
|
9e3d5d52ab | ||
|
|
2c389a90d1 | ||
|
|
8d98387245 | ||
|
|
b36e5262c7 | ||
|
|
79d7ac9315 | ||
|
|
03c4fe8a8d | ||
|
|
ad3728d00d | ||
|
|
c465354c67 | ||
|
|
5f5cc85e28 | ||
|
|
7cc246afc1 | ||
|
|
75b89b40bf | ||
|
|
b34d3c83fc | ||
|
|
c1152f94fd | ||
|
|
8c9e42d15e | ||
|
|
0c800d4428 | ||
|
|
0fca5fc8a9 | ||
|
|
fe177e40fd | ||
|
|
fa4af8b27d | ||
|
|
980711589a | ||
|
|
b2ef47573c | ||
|
|
b0d78921fd | ||
|
|
c00f638f7e | ||
|
|
975e9ec553 | ||
|
|
de2de5e2fd | ||
|
|
a8e0de043c | ||
|
|
549d6f67e3 | ||
|
|
55f4e55383 | ||
|
|
e2256d0663 | ||
|
|
88e0ced03e | ||
|
|
baaf50c6d2 | ||
|
|
97b8df6912 | ||
|
|
98a358437f | ||
|
|
00ac15cec5 | ||
|
|
456e774d85 | ||
|
|
91c5b2fee2 | ||
|
|
ae604b2a55 | ||
|
|
d381a936b5 | ||
| d1491e0860 | |||
| 7709239636 | |||
| a9731b90f6 | |||
| 4368697f58 | |||
| 12cfd418d6 | |||
| e5a48f152a | |||
| 0a1fb25e6b | |||
| 473790124b | |||
| 0353ede517 | |||
| 73b86d4921 | |||
| dec4fc30d9 | |||
| e68e38ad95 | |||
| 3176651c71 | |||
| a42197f0d6 | |||
| f8035d8d5e | |||
| e4dcd3cefd | |||
| c4c13d8ce0 | |||
| 19c50d4c3d | |||
| 8cc20393f1 | |||
| cc616371b1 |
@@ -1,5 +1,5 @@
|
||||
# .appveyor.yml for use with EPICS Base ci-scripts
|
||||
# (see: https://github.com/epics-base/ci-scripts)
|
||||
# Appveyor configuration file for EPICS Base 7 builds
|
||||
# (see also https://github.com/epics-base/ci-scripts)
|
||||
|
||||
# Version format
|
||||
version: base-{branch}-{build}
|
||||
@@ -29,9 +29,10 @@ clone_depth: 5
|
||||
skip_commits:
|
||||
files:
|
||||
- 'documentation/*'
|
||||
- 'startup/*'
|
||||
- '.github/*'
|
||||
- '**/*.html'
|
||||
- '**/*.md'
|
||||
- '.travis.yml'
|
||||
|
||||
#---------------------------------#
|
||||
# build matrix configuration #
|
||||
@@ -77,14 +78,17 @@ matrix:
|
||||
CMP: vs2012
|
||||
- platform: x64
|
||||
CMP: vs2010
|
||||
- platform: x64
|
||||
CMP: vs2008
|
||||
# Exclude more jobs to reduce build time
|
||||
# Skip 32-bit for "middle-aged" compilers
|
||||
- platform: x86
|
||||
CMP: vs2017
|
||||
- platform: x86
|
||||
CMP: vs2015
|
||||
# MinGW debug builds use the same libraries, unlike VS
|
||||
- configuration: dynamic-debug
|
||||
CMP: gcc
|
||||
- configuration: static-debug
|
||||
CMP: gcc
|
||||
|
||||
#---------------------------------#
|
||||
# building & testing #
|
||||
@@ -92,18 +96,23 @@ matrix:
|
||||
|
||||
install:
|
||||
- cmd: git submodule update --init --recursive
|
||||
- cmd: pip install git+https://github.com/mdavidsaver/ci-core-dumper#egg=ci-core-dumper
|
||||
- cmd: python .ci/cue.py prepare
|
||||
|
||||
build_script:
|
||||
- cmd: python .ci/cue.py build
|
||||
|
||||
test_script:
|
||||
- cmd: python -m ci_core_dumper install
|
||||
- cmd: python .ci/cue.py test
|
||||
|
||||
on_finish:
|
||||
- ps: Get-ChildItem *.tap -Recurse -Force | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
||||
- cmd: python .ci/cue.py build test-results -s
|
||||
|
||||
on_failure:
|
||||
- cmd: python -m ci_core_dumper report
|
||||
|
||||
#---------------------------------#
|
||||
# debugging #
|
||||
#---------------------------------#
|
||||
|
||||
150
.appveyor/epics-base-7.yml
Normal file
150
.appveyor/epics-base-7.yml
Normal file
@@ -0,0 +1,150 @@
|
||||
# Appveyor configuration file for EPICS Base 7 builds
|
||||
# (see also https://github.com/epics-base/ci-scripts)
|
||||
|
||||
# branches to build
|
||||
branches:
|
||||
# whitelist
|
||||
only:
|
||||
- 7.0
|
||||
- /R7\.0\.\d+.*/
|
||||
|
||||
# Version format
|
||||
version: base-{branch}-{build}
|
||||
|
||||
#---------------------------------#
|
||||
# build cache #
|
||||
#---------------------------------#
|
||||
# The AppVeyor cache allowance is way too small (1GB per account across all projects, branches and jobs)
|
||||
# to be used for the dependency builds.
|
||||
|
||||
cache:
|
||||
- C:\Users\appveyor\.tools
|
||||
|
||||
#---------------------------------#
|
||||
# repository cloning #
|
||||
#---------------------------------#
|
||||
|
||||
# Called at very beginning, before repo cloning
|
||||
init:
|
||||
# Set autocrlf to make batch files work
|
||||
- git config --global core.autocrlf true
|
||||
|
||||
# Set clone depth (do not fetch complete history)
|
||||
clone_depth: 5
|
||||
|
||||
# Skipping commits affecting only specific files
|
||||
skip_commits:
|
||||
files:
|
||||
- 'documentation/*'
|
||||
- 'startup/*'
|
||||
- '.github/*'
|
||||
- '**/*.html'
|
||||
- '**/*.md'
|
||||
|
||||
#---------------------------------#
|
||||
# build matrix configuration #
|
||||
#---------------------------------#
|
||||
|
||||
image: Visual Studio 2015
|
||||
|
||||
# Build Configurations: dll/static, regular/debug
|
||||
configuration:
|
||||
- dynamic
|
||||
- static
|
||||
- dynamic-debug
|
||||
- static-debug
|
||||
|
||||
# Environment variables: compiler toolchain, base version, setup file, ...
|
||||
environment:
|
||||
# common / default variables for all jobs
|
||||
SETUP_PATH: .ci-local:.ci
|
||||
BASE: SELF
|
||||
EPICS_TEST_IMPRECISE_TIMING: YES
|
||||
|
||||
matrix:
|
||||
- CMP: vs2019
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
- CMP: vs2017
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
- CMP: vs2015
|
||||
- CMP: vs2013
|
||||
- CMP: vs2012
|
||||
- CMP: vs2010
|
||||
- CMP: gcc
|
||||
|
||||
# Platform: processor architecture
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
# Matrix configuration: exclude sets of jobs
|
||||
matrix:
|
||||
exclude:
|
||||
# VS2012 and older installs don't have the 64 bit compiler
|
||||
- platform: x64
|
||||
CMP: vs2012
|
||||
- platform: x64
|
||||
CMP: vs2010
|
||||
# Exclude more jobs to reduce build time
|
||||
# Skip 32-bit for "middle-aged" compilers
|
||||
- platform: x86
|
||||
CMP: vs2017
|
||||
- platform: x86
|
||||
CMP: vs2015
|
||||
# MinGW debug builds use the same libraries, unlike VS
|
||||
- configuration: dynamic-debug
|
||||
CMP: gcc
|
||||
- configuration: static-debug
|
||||
CMP: gcc
|
||||
|
||||
#---------------------------------#
|
||||
# building & testing #
|
||||
#---------------------------------#
|
||||
|
||||
install:
|
||||
- cmd: git submodule update --init --recursive
|
||||
- cmd: pip install git+https://github.com/mdavidsaver/ci-core-dumper#egg=ci-core-dumper
|
||||
- cmd: python .ci/cue.py prepare
|
||||
|
||||
build_script:
|
||||
- cmd: python .ci/cue.py build
|
||||
|
||||
test_script:
|
||||
- cmd: python -m ci_core_dumper install
|
||||
- cmd: python .ci/cue.py test
|
||||
|
||||
on_finish:
|
||||
- ps: Get-ChildItem *.tap -Recurse -Force | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
||||
- cmd: python .ci/cue.py build test-results -s
|
||||
|
||||
on_failure:
|
||||
- cmd: python -m ci_core_dumper report
|
||||
|
||||
#---------------------------------#
|
||||
# debugging #
|
||||
#---------------------------------#
|
||||
|
||||
## if you want to connect by remote desktop to a failed build, uncomment these lines
|
||||
## note that you will need to connect within the usual build timeout limit (60 minutes)
|
||||
## so you may want to adjust the build matrix above to just build the one of interest
|
||||
|
||||
# print the connection info
|
||||
#init:
|
||||
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
|
||||
# block a failed build (until the watchdog barks)
|
||||
#on_failure:
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
|
||||
#---------------------------------#
|
||||
# notifications #
|
||||
#---------------------------------#
|
||||
|
||||
notifications:
|
||||
|
||||
- provider: Email
|
||||
to:
|
||||
- core-talk@aps.anl.gov
|
||||
on_build_success: false
|
||||
|
||||
- provider: GitHubPullRequest
|
||||
2
.ci
2
.ci
Submodule .ci updated: 87942a7c29...3db08b5977
152
.github/workflows/ci-scripts-build.yml
vendored
Normal file
152
.github/workflows/ci-scripts-build.yml
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
# .github/workflows/ci-scripts-build.yml for use with EPICS Base ci-scripts
|
||||
# (see: https://github.com/epics-base/ci-scripts)
|
||||
|
||||
# This is YAML - indentation levels are crucial
|
||||
|
||||
# Workflow name, shared by all branches
|
||||
|
||||
name: Base
|
||||
|
||||
# Trigger on pushes and PRs to any branch
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'documentation/*'
|
||||
- 'startup/*'
|
||||
- '.appveyor/*'
|
||||
- '**/*.html'
|
||||
- '**/*.md'
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
SETUP_PATH: .ci-local:.ci
|
||||
BASE: SELF
|
||||
EPICS_TEST_IMPRECISE_TIMING: YES
|
||||
|
||||
jobs:
|
||||
build-base:
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
# Set environment variables from matrix parameters
|
||||
env:
|
||||
CMP: ${{ matrix.cmp }}
|
||||
BCFG: ${{ matrix.configuration }}
|
||||
WINE: ${{ matrix.wine }}
|
||||
RTEMS: ${{ matrix.rtems }}
|
||||
EXTRA: ${{ matrix.extra }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Job names also name artifacts, character limitations apply
|
||||
include:
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
wine: "64"
|
||||
name: "Ub-20 gcc-9 + MinGW"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
wine: "64"
|
||||
name: "Ub-20 gcc-9 + MinGW, static"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
extra: "CMD_CXXFLAGS=-std=c++11"
|
||||
name: "Ub-20 gcc-9 C++11, static"
|
||||
|
||||
- os: ubuntu-16.04
|
||||
cmp: clang
|
||||
configuration: default
|
||||
name: "Ub-16 clang-9"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: clang
|
||||
configuration: default
|
||||
extra: "CMD_CXXFLAGS=-std=c++11"
|
||||
name: "Ub-20 clang-10 C++11"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
rtems: "4.10"
|
||||
name: "Ub-20 gcc-9 + RT-4.10"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
rtems: "4.9"
|
||||
name: "Ub-20 gcc-9 + RT-4.9"
|
||||
|
||||
- os: ubuntu-16.04
|
||||
cmp: gcc-4.8
|
||||
utoolchain: "4.8"
|
||||
configuration: default
|
||||
name: "Ub-16 gcc-4.8"
|
||||
|
||||
- os: ubuntu-16.04
|
||||
cmp: gcc-4.9
|
||||
utoolchain: "4.9"
|
||||
configuration: default
|
||||
name: "Ub-16 gcc-4.9"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc-8
|
||||
utoolchain: "8"
|
||||
configuration: default
|
||||
name: "Ub-20 gcc-8"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: clang
|
||||
configuration: default
|
||||
name: "Ub-20 clang-10"
|
||||
|
||||
- os: macos-latest
|
||||
cmp: clang
|
||||
configuration: default
|
||||
name: "MacOS clang-12"
|
||||
|
||||
- os: windows-2019
|
||||
cmp: vs2019
|
||||
configuration: default
|
||||
name: "Win2019 MSC-19"
|
||||
|
||||
- os: windows-2019
|
||||
cmp: vs2019
|
||||
configuration: static
|
||||
name: "Win2019 MSC-19, static"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Automatic core dumper analysis
|
||||
uses: mdavidsaver/ci-core-dumper@master
|
||||
- name: "apt-get install"
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install qemu-system-x86 g++-mingw-w64-x86-64 gdb
|
||||
if: runner.os == 'Linux'
|
||||
- name: "apt-get install ${{ matrix.cmp }}"
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install software-properties-common
|
||||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install g++-${{ matrix.utoolchain }}
|
||||
if: matrix.utoolchain
|
||||
- name: Prepare and compile dependencies
|
||||
run: python .ci/cue.py prepare
|
||||
- name: Build main module
|
||||
run: python .ci/cue.py build
|
||||
- name: Run main module tests
|
||||
run: python .ci/cue.py test
|
||||
- name: Upload tapfiles Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: tapfiles ${{ matrix.name }}
|
||||
path: '**/O.*/*.tap'
|
||||
- name: Collect and show test results
|
||||
run: python .ci/cue.py test-results
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -11,6 +11,8 @@
|
||||
/modules/Makefile.local
|
||||
O.*/
|
||||
/QtC-*
|
||||
/.vscode/
|
||||
*.orig
|
||||
*.log
|
||||
.*.swp
|
||||
.DS_Store
|
||||
|
||||
102
.tools/adjustver.py
Executable file
102
.tools/adjustver.py
Executable file
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import logging
|
||||
import sys
|
||||
import re
|
||||
from io import StringIO
|
||||
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
def main(args):
|
||||
logging.basicConfig(level=args.level)
|
||||
|
||||
if args.dev is True:
|
||||
actions=[
|
||||
('DEVELOPMENT_FLAG', '1'),
|
||||
('DEV_SNAPSHOT', '-DEV'),
|
||||
]
|
||||
|
||||
elif args.dev is False:
|
||||
actions=[
|
||||
('DEVELOPMENT_FLAG', '0'),
|
||||
('DEV_SNAPSHOT', ''),
|
||||
]
|
||||
|
||||
elif args.version:
|
||||
M=re.match(r'R?(\d+).(\d+).(\d+)(?:.(\d+))?(-.*)?', args.version)
|
||||
actions=[
|
||||
('SITE_VERSION', None),
|
||||
('SHORT_VERSION', None),
|
||||
|
||||
('MINOR_VERSION', M[2]),
|
||||
('REVISION', M[2]),
|
||||
|
||||
('MODIFICATION', M[3]),
|
||||
('MAINTENANCE_VERSION', M[3]),
|
||||
|
||||
('PATCH_LEVEL', M[4] or '0'),
|
||||
|
||||
('DEVELOPMENT_FLAG', '1' if (M[5] or '').upper().endswith('-DEV') else '0'),
|
||||
('DEV_SNAPSHOT', M[5] or ''),
|
||||
|
||||
('MAJOR_VERSION', M[1]),
|
||||
('VERSION', M[1]), # plain _VERSION must be last to resolve ambiguity
|
||||
]
|
||||
|
||||
elif args.dry_run:
|
||||
_log.debug('Print existing')
|
||||
for fname in args.conf:
|
||||
print('# ', fname)
|
||||
with open(fname, 'r') as F:
|
||||
sys.stdout.write(F.read())
|
||||
return
|
||||
|
||||
else:
|
||||
print('One of --version, --release, --dev, or --dry-run is required')
|
||||
sys.exit(1)
|
||||
|
||||
for name, val in actions:
|
||||
_log.debug('Pattern "%s" -> "%s"', name, val)
|
||||
|
||||
for fname in args.conf:
|
||||
OUT=StringIO()
|
||||
|
||||
with open(fname, 'r') as F:
|
||||
for line in F:
|
||||
_log.debug('Line: %s', repr(line))
|
||||
for name, val in actions:
|
||||
M = re.match(r'(\s*[A-Z_]+' + name + r'\s*=[\t ]*)(\S*)(\s*)', line)
|
||||
if M and val is None:
|
||||
_log.debug('Ignore')
|
||||
OUT.write(line)
|
||||
break
|
||||
elif M:
|
||||
_log.debug(' Match %s -> %s', M.re.pattern, M.groups())
|
||||
OUT.write(M[1]+val+M[3])
|
||||
break
|
||||
else:
|
||||
_log.debug('No match')
|
||||
OUT.write(line)
|
||||
|
||||
if args.dry_run:
|
||||
print('# ', fname)
|
||||
print(OUT.getvalue())
|
||||
else:
|
||||
with open(fname, 'w') as F:
|
||||
F.write(OUT.getvalue())
|
||||
|
||||
def getargs():
|
||||
from argparse import ArgumentParser
|
||||
P = ArgumentParser()
|
||||
P.add_argument('-n','--dry-run', action='store_true', default=False)
|
||||
P.add_argument('-d','--debug', dest='level', action='store_const',
|
||||
const=logging.DEBUG, default=logging.INFO)
|
||||
P.add_argument('-V', '--version', help='A version in R1.2.3-xyz or 1.2.3 form')
|
||||
P.add_argument('-D', '--dev', action='store_true', default=None)
|
||||
P.add_argument('-R', '--release', dest='dev', action='store_false')
|
||||
P.add_argument('conf', nargs='+',
|
||||
help='A configure/CONFIG_*_VERSION file name')
|
||||
return P
|
||||
|
||||
if __name__=='__main__':
|
||||
main(getargs().parse_args())
|
||||
91
.travis.yml
91
.travis.yml
@@ -1,91 +0,0 @@
|
||||
# .travis.yml for use with EPICS Base ci-scripts
|
||||
# (see: https://github.com/epics-base/ci-scripts)
|
||||
|
||||
language: cpp
|
||||
compiler: gcc
|
||||
dist: xenial
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache
|
||||
|
||||
env:
|
||||
global:
|
||||
- SETUP_PATH=.ci-local:.ci
|
||||
- BASE=SELF
|
||||
- EPICS_TEST_IMPRECISE_TIMING=YES
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
# for all EPICS builds
|
||||
- libreadline6-dev
|
||||
- libncurses5-dev
|
||||
- perl
|
||||
# for clang compiler
|
||||
- clang
|
||||
# for mingw builds (32bit and 64bit)
|
||||
- g++-mingw-w64-i686
|
||||
- g++-mingw-w64-x86-64
|
||||
# for RTEMS cross builds
|
||||
- qemu-system-x86
|
||||
homebrew:
|
||||
packages:
|
||||
# for all EPICS builds
|
||||
- bash
|
||||
update: true
|
||||
|
||||
install:
|
||||
- ./.ci-local/travis-fixup.sh
|
||||
- python .ci/cue.py prepare
|
||||
|
||||
script:
|
||||
- python .ci/cue.py build
|
||||
- python .ci/cue.py test
|
||||
- python .ci/cue.py test-results
|
||||
|
||||
# Define build jobs
|
||||
|
||||
jobs:
|
||||
include:
|
||||
|
||||
# Different configurations of default gcc and clang
|
||||
- dist: bionic
|
||||
|
||||
- dist: xenial
|
||||
|
||||
- dist: bionic
|
||||
env: BCFG=static EXTRA="CMD_CXXFLAGS=-std=c++11"
|
||||
|
||||
- dist: trusty
|
||||
env: EXTRA="CMD_CXXFLAGS=-std=c++11"
|
||||
|
||||
- dist: bionic
|
||||
compiler: clang
|
||||
|
||||
- compiler: clang
|
||||
|
||||
- dist: trusty
|
||||
compiler: clang
|
||||
env: BCFG=static
|
||||
|
||||
# Cross-compilations to Windows using MinGW and WINE
|
||||
|
||||
- env: WINE=32 TEST=NO BCFG=static
|
||||
|
||||
- env: WINE=32 TEST=NO
|
||||
|
||||
# Cross-compilation to RTEMS
|
||||
|
||||
- env: RTEMS=4.10
|
||||
|
||||
- env: RTEMS=4.9
|
||||
|
||||
# MacOS build
|
||||
|
||||
- os: osx
|
||||
env:
|
||||
- EXTRA="CMD_CFLAGS=-mmacosx-version-min=10.7"
|
||||
- EXTRA1="CMD_CXXFLAGS=-mmacosx-version-min=10.7 -std=c++11 -stdlib=libc++"
|
||||
- EXTRA2="CMD_LDXFLAGS=-mmacosx-version-min=10.7 -std=c++11 -stdlib=libc++"
|
||||
compiler: clang
|
||||
@@ -31,7 +31,7 @@ PROF_CFLAGS_YES = -p
|
||||
GPROF_CFLAGS_YES = -pg
|
||||
CODE_CFLAGS = $(PROF_CFLAGS_$(PROFILE)) $(GPROF_CFLAGS_$(GPROF))
|
||||
CODE_CFLAGS += $(ASAN_FLAGS_$(ENABLE_ASAN))
|
||||
WARN_CFLAGS_YES = -Wall
|
||||
WARN_CFLAGS_YES = -Wall -Werror-implicit-function-declaration
|
||||
WARN_CFLAGS_NO = -w
|
||||
OPT_CFLAGS_YES = -O3
|
||||
OPT_CFLAGS_NO = -g
|
||||
|
||||
@@ -64,10 +64,15 @@ DEPCLEAN = $(call FIND_TOOL,depclean.pl)
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Tools for testing
|
||||
TAPTOJUNIT = $(PERL) $(TOOLS)/tap-to-junit-xml.pl
|
||||
PROVE = $(PERL) $(TOOLS)/epicsProve.pl
|
||||
PROVE.tap = $(PROVE) --ext .tap --exec "$(CAT)"
|
||||
TAPS_FAILED_LOG = .taps-failed.log
|
||||
TESTS_FAILED_LOG = .tests-failed.log
|
||||
TESTS_FAILED_PATH = $(abspath $(TOP)/$(TESTS_FAILED_LOG))
|
||||
|
||||
TEST_FAILURE_FILENAME = .tests-failed.log
|
||||
TEST_FAILURE_FILE = $(TOP)/$(TEST_FAILURE_FILENAME)
|
||||
PROVE_FAILURE = echo $(abspath .)>> $(TEST_FAILURE_FILE)
|
||||
TAPTOJUNIT = $(PERL) $(TOOLS)/tap-to-junit-xml.pl
|
||||
PROVE = $(PERL) $(TOOLS)/epicsProve.pl --failures --color
|
||||
PROVE.tap = $(PROVE) --ext .tap --exec "$(CAT)"
|
||||
TESTFAILURES = $(PERL) $(TOOLS)/testFailures.pl
|
||||
SHOWTESTFAILURES = $(TESTFAILURES) $(TESTS_FAILED_PATH) $(TAPS_FAILED_LOG)
|
||||
|
||||
PROVE_FAILURE = echo $(abspath .)>> $(TESTS_FAILED_PATH)
|
||||
TAPFILE_FAILURE = echo $@>> $(TAPS_FAILED_LOG)
|
||||
|
||||
@@ -48,11 +48,11 @@ EPICS_VERSION = 7
|
||||
EPICS_REVISION = 0
|
||||
|
||||
# EPICS_MODIFICATION must be a number >=0 and <256
|
||||
EPICS_MODIFICATION = 4
|
||||
EPICS_MODIFICATION = 5
|
||||
|
||||
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
|
||||
# Not included in the official EPICS version number if zero
|
||||
EPICS_PATCH_LEVEL = 1
|
||||
EPICS_PATCH_LEVEL = 0
|
||||
|
||||
# Immediately after an official release the EPICS_PATCH_LEVEL is incremented
|
||||
# and the -DEV suffix is added (similar to the Maven -SNAPSHOT versions)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
EPICS_CA_MAJOR_VERSION = 4
|
||||
EPICS_CA_MINOR_VERSION = 13
|
||||
EPICS_CA_MAINTENANCE_VERSION = 7
|
||||
EPICS_CA_MAINTENANCE_VERSION = 8
|
||||
|
||||
# Development flag, set to zero for release versions
|
||||
|
||||
|
||||
@@ -80,12 +80,12 @@ IOCS_APPL_TOP = $(shell $(FULLPATHNAME) $(INSTALL_LOCATION))
|
||||
#-------------------------------------------------------
|
||||
# Silencing the build - suppress messages during 'make -s'
|
||||
NOP = :
|
||||
ECHO = @$(if $(findstring s,$(MFLAGS)),$(NOP),echo)
|
||||
QUIET_FLAG := $(if $(findstring s,$(MFLAGS)),-q,)
|
||||
ECHO = @$(if $(filter -s,$(MFLAGS)),$(NOP),echo)
|
||||
QUIET_FLAG := $(if $(filter -s,$(MFLAGS)),-q,)
|
||||
|
||||
#-------------------------------------------------------
|
||||
# Convert 'make -q' flag into '-i' for genVersionHeader.pl
|
||||
QUESTION_FLAG := $(if $(findstring q,$(MFLAGS)),-i,)
|
||||
QUESTION_FLAG := $(if $(filter -q,$(MFLAGS)),-i,)
|
||||
|
||||
#-------------------------------------------------------
|
||||
ifdef T_A
|
||||
|
||||
@@ -24,3 +24,5 @@ MSI3_15 = $(EPICS_DATABASE_HOST_BIN)/msi$(HOSTEXE)
|
||||
|
||||
# Libraries needed to link a basic IOC
|
||||
EPICS_BASE_IOC_LIBS = dbRecStd dbCore ca Com
|
||||
|
||||
HAS_registerAllRecordDeviceDrivers=YES
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Version number for the database APIs and shared library
|
||||
|
||||
EPICS_DATABASE_MAJOR_VERSION = 3
|
||||
EPICS_DATABASE_MINOR_VERSION = 18
|
||||
EPICS_DATABASE_MAINTENANCE_VERSION = 1
|
||||
EPICS_DATABASE_MINOR_VERSION = 19
|
||||
EPICS_DATABASE_MAINTENANCE_VERSION = 0
|
||||
|
||||
# Development flag, set to zero for release versions
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Version number for the libcom APIs and shared library
|
||||
|
||||
EPICS_LIBCOM_MAJOR_VERSION = 3
|
||||
EPICS_LIBCOM_MINOR_VERSION = 18
|
||||
EPICS_LIBCOM_MAINTENANCE_VERSION = 1
|
||||
EPICS_LIBCOM_MINOR_VERSION = 19
|
||||
EPICS_LIBCOM_MAINTENANCE_VERSION = 0
|
||||
|
||||
# Development flag, set to zero for release versions
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
# darwin-x86 (Intel based Apple running OSX)
|
||||
# freebsd-x86 (GNU compiler used for host builds)
|
||||
# freebsd-x86_64 (GNU compiler used for host builds)
|
||||
# linux-aarch64 (GNU compiler used for host builds)
|
||||
# linux-arm (GNU compiler used for host builds)
|
||||
# linux-ppc (GNU compiler used for host builds)
|
||||
# linux-ppc64 (GNU compiler used for host builds)
|
||||
@@ -51,7 +52,6 @@
|
||||
# windows-x64-debug (MS Visual C++ compiler with debug option for host builds)
|
||||
|
||||
|
||||
# EPICS_HOST_ARCH is a required environment variable
|
||||
# Do not set EPICS_HOST_ARCH in this file.
|
||||
# Use base/startup files to set EPICS_HOST_ARCH or
|
||||
# provide EPICS_HOST_ARCH on the GNU make command line.
|
||||
|
||||
@@ -32,12 +32,12 @@ vpath %.l $(USR_VPATH) $(ALL_SRC_DIRS)
|
||||
include $(CONFIG)/CONFIG_ADDONS
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Set PROD, TESTPROD, OBJS, and LIBRARY
|
||||
|
||||
SCRIPTS_HOST += $(PERL_SCRIPTS)
|
||||
# PERL_SCRIPTS are installed into existing $(INSTALL_BIN) for Host systems
|
||||
|
||||
ifeq ($(findstring Host,$(VALID_BUILDS)),Host)
|
||||
# Host targets can compile and run programs
|
||||
ifneq (,$(findstring Host,$(VALID_BUILDS)))
|
||||
LIBRARY += $(LIBRARY_HOST)
|
||||
LOADABLE_LIBRARY += $(LOADABLE_LIBRARY_HOST)
|
||||
OBJS += $(OBJS_HOST)
|
||||
@@ -49,7 +49,21 @@ TESTSCRIPTS += $(TESTSCRIPTS_HOST)
|
||||
TESTPROD += $(TESTPROD_HOST)
|
||||
endif
|
||||
|
||||
ifeq ($(findstring Ioc,$(VALID_BUILDS)),Ioc)
|
||||
# Command targets have a command line and support main()
|
||||
ifneq (,$(findstring Command,$(VALID_BUILDS)))
|
||||
LIBRARY += $(LIBRARY_CMD)
|
||||
LOADABLE_LIBRARY += $(LOADABLE_LIBRARY_CMD)
|
||||
OBJS += $(OBJS_CMD)
|
||||
PROD += $(PROD_CMD)
|
||||
SCRIPTS += $(SCRIPTS_CMD)
|
||||
TARGETS += $(TARGETS_CMD)
|
||||
TESTLIBRARY += $(TESTLIBRARY_CMD)
|
||||
TESTSCRIPTS += $(TESTSCRIPTS_CMD)
|
||||
TESTPROD += $(TESTPROD_CMD)
|
||||
endif
|
||||
|
||||
# Ioc targets can run IOCs
|
||||
ifneq (,$(findstring Ioc,$(VALID_BUILDS)))
|
||||
LIBRARY += $(LIBRARY_IOC)
|
||||
LOADABLE_LIBRARY += $(LOADABLE_LIBRARY_IOC)
|
||||
OBJS += $(OBJS_IOC)
|
||||
@@ -358,7 +372,8 @@ runtests: run-tap-tests
|
||||
run-tap-tests: $(TESTSCRIPTS.t)
|
||||
ifneq ($(TESTSCRIPTS.t),)
|
||||
ifdef RUNTESTS_ENABLED
|
||||
$(PROVE) --failures --color $^ || $(PROVE_FAILURE)
|
||||
$(ECHO) "$(PROVE) $^"
|
||||
@$(PROVE) $^ || $(PROVE_FAILURE)
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -369,7 +384,8 @@ test-results: tap-results
|
||||
tap-results: $(TAPFILES)
|
||||
ifneq ($(strip $(TAPFILES)),)
|
||||
ifdef RUNTESTS_ENABLED
|
||||
$(PROVE.tap) --failures --color $^ || $(PROVE_FAILURE)
|
||||
$(ECHO) "$(PROVE.tap) $^"
|
||||
@$(PROVE.tap) $^ || $(PROVE_FAILURE)
|
||||
endif
|
||||
|
||||
CURRENT_TAPFILES := $(wildcard $(TAPFILES))
|
||||
@@ -377,8 +393,8 @@ CURRENT_JUNITFILES := $(wildcard $(JUNITFILES))
|
||||
endif
|
||||
|
||||
clean-tests:
|
||||
ifneq ($(CURRENT_TAPFILES),)
|
||||
$(RM) $(CURRENT_TAPFILES)
|
||||
ifneq ($(CURRENT_TAPFILES)$(TAPS_FAILED_LOG),)
|
||||
$(RM) $(CURRENT_TAPFILES) $(TAPS_FAILED_LOG)
|
||||
endif
|
||||
ifneq ($(CURRENT_JUNITFILES),)
|
||||
$(RM) $(CURRENT_JUNITFILES)
|
||||
@@ -387,7 +403,8 @@ endif
|
||||
# A .tap file is the output from running the associated test script
|
||||
$(TAPFILES.t): %.tap: %.t
|
||||
ifdef RUNTESTS_ENABLED
|
||||
$(PERL) $< -tap > $@
|
||||
$(ECHO) "$(PERL) $< -tap > $@"
|
||||
@$(PERL) $< -tap > $@ || $(TAPFILE_FAILURE)
|
||||
endif
|
||||
|
||||
$(JUNITFILES.t): %-results.xml: %.tap
|
||||
|
||||
@@ -86,8 +86,10 @@ expand_clean:
|
||||
ASSEMBLE_TOOL ?= $(PERL) $(TOOLS)/assembleSnippets.pl
|
||||
|
||||
define COMMON_ASSEMBLY_template
|
||||
ifneq '$$($1_PATTERN)' ''
|
||||
$1_SNIPPETS += $$(foreach dir, .. $$(SRC_DIRS), \
|
||||
$$(wildcard $$(dir)/$$($1_PATTERN)))
|
||||
endif
|
||||
$(COMMON_DIR)/$1: $$($1_SNIPPETS)
|
||||
$(ECHO) "Assembling common file $$@ from snippets"
|
||||
@$(RM) $1
|
||||
@@ -98,8 +100,10 @@ $(foreach asy, $(COMMON_ASSEMBLIES), \
|
||||
$(eval $(call COMMON_ASSEMBLY_template,$(strip $(asy)))))
|
||||
|
||||
define ASSEMBLY_template
|
||||
ifneq '$$($1_PATTERN)' ''
|
||||
$1_SNIPPETS += $$(foreach dir, .. $$(SRC_DIRS), \
|
||||
$$(wildcard $$(dir)/$$($1_PATTERN)))
|
||||
endif
|
||||
$1: $$($1_SNIPPETS)
|
||||
$(ECHO) "Assembling file $$@ from snippets"
|
||||
@$(RM) $$@
|
||||
|
||||
@@ -47,14 +47,9 @@ realclean:
|
||||
|
||||
.PHONY: RELEASE.host realclean
|
||||
|
||||
# Append all our live submodule failure files
|
||||
FAILURE_FILES = $(addsuffix /$(TEST_FAILURE_FILENAME), $(LIVE_SUBMODULES))
|
||||
|
||||
define combine_failure_files
|
||||
@$(TOUCH) $(FAILURE_FILES)
|
||||
@$(CAT) $(FAILURE_FILES) >> $(TEST_FAILURE_FILE)
|
||||
endef
|
||||
runtests: | $(addsuffix $(DIVIDER)runtests, $(LIVE_SUBMODULES))
|
||||
$(if $(FAILURE_FILES), $(combine_failure_files))
|
||||
test-results: | $(addsuffix $(DIVIDER)test-results, $(LIVE_SUBMODULES))
|
||||
$(if $(FAILURE_FILES), $(combine_failure_files))
|
||||
# Testing: Combine test failure logs from the live submodules
|
||||
TESTS_FAILED_LOGS = $(wildcard $(addsuffix /$(TESTS_FAILED_LOG), \
|
||||
$(LIVE_SUBMODULES)))
|
||||
runtests test-results: % : | $(addsuffix $(DIVIDER)%, $(LIVE_SUBMODULES))
|
||||
$(if $(TESTS_FAILED_LOGS), \
|
||||
@$(CAT) $(TESTS_FAILED_LOGS)>> $(TESTS_FAILED_PATH))
|
||||
|
||||
@@ -33,7 +33,7 @@ UNINSTALL_DIRS += $(INSTALL_INCLUDE) $(INSTALL_TEMPLATES) $(DIRECTORY_TARGETS)
|
||||
ifneq ($(INSTALL_LOCATION),$(TOP))
|
||||
UNINSTALL_DIRS += $(INSTALL_CONFIG)
|
||||
endif
|
||||
uninstallDirs:
|
||||
uninstallDirs: | clean
|
||||
$(RMDIR) $(UNINSTALL_DIRS)
|
||||
|
||||
# Remove the bin and lib directories if they have no sub-directories
|
||||
@@ -41,17 +41,18 @@ uninstallDirs:
|
||||
EMPTY_INSTALL_DIRS = \
|
||||
$(if $(wildcard $(INSTALL_LOCATION_BIN)/*),,$(INSTALL_LOCATION_BIN)) \
|
||||
$(if $(wildcard $(INSTALL_LOCATION_LIB)/*),,$(INSTALL_LOCATION_LIB))
|
||||
uninstall: archuninstall uninstallDirs
|
||||
uninstall: archuninstall uninstallDirs | clean
|
||||
$(RMDIR) $(EMPTY_INSTALL_DIRS)
|
||||
|
||||
archuninstall: $(addprefix uninstall$(DIVIDER),$(BUILD_ARCHS))
|
||||
|
||||
uninstall$(DIVIDER)%:
|
||||
uninstall$(DIVIDER)%: | clean
|
||||
$(RMDIR) $(addsuffix /$(subst uninstall$(DIVIDER),,$@), \
|
||||
$(INSTALL_LOCATION_BIN) $(INSTALL_LOCATION_LIB))
|
||||
|
||||
# Only run this at the top of the parent
|
||||
runtests test-results:
|
||||
@$(PERL) $(TOOLS)/testFailures.pl $(TEST_FAILURE_FILE)
|
||||
@$(SHOWTESTFAILURES)
|
||||
|
||||
else
|
||||
#
|
||||
@@ -63,10 +64,10 @@ else
|
||||
|
||||
endif # DISABLE_TOP_RULES
|
||||
|
||||
# Clean out old results
|
||||
before-runtests before-test-results: rm-failure-file
|
||||
rm-failure-file:
|
||||
@$(RM) $(TEST_FAILURE_FILE)
|
||||
@$(TOUCH) $(TEST_FAILURE_FILE)
|
||||
$(RM) $(TESTS_FAILED_PATH)
|
||||
|
||||
help:
|
||||
@echo "Usage: gnumake [options] [target] ..."
|
||||
|
||||
@@ -76,7 +76,7 @@ CPPFLAGS += $($(BUILD_CLASS)_CPPFLAGS) $(POSIX_CPPFLAGS) $(OPT_CPPFLAGS)\
|
||||
$(USR_CPPFLAGS) $(CMD_CPPFLAGS) $(ARCH_DEP_CPPFLAGS) $(OP_SYS_CPPFLAGS)\
|
||||
$(OP_SYS_INCLUDE_CPPFLAGS) $(CODE_CPPFLAGS)
|
||||
|
||||
ECHO = @$(if $(findstring s,$(MFLAGS)),$(NOP),echo)
|
||||
ECHO = @$(if $(filter -s,$(MFLAGS)),$(NOP),echo)
|
||||
|
||||
#--------------------------------------------------
|
||||
# Although RTEMS uses gcc, it wants to use gcc its own way
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Unix valid build types
|
||||
VALID_BUILDS = Host Ioc
|
||||
VALID_BUILDS = Host Ioc Command
|
||||
|
||||
#-------------------------------------------------------
|
||||
# Unix prefix and suffix definitions
|
||||
|
||||
14
configure/os/CONFIG.Common.darwin-aarch64
Normal file
14
configure/os/CONFIG.Common.darwin-aarch64
Normal file
@@ -0,0 +1,14 @@
|
||||
# CONFIG.Common.darwin-aarch64
|
||||
#
|
||||
# This file is maintained by the build community.
|
||||
#
|
||||
# Definitions for darwin-aarch64 target builds
|
||||
# Sites may override these definitions in CONFIG_SITE.Common.darwin-aarch64
|
||||
#-------------------------------------------------------
|
||||
|
||||
#
|
||||
# To build universal binaries, configure ARCH_CLASS
|
||||
# in the file CONFIG_SITE.Common.darwin-aarch64
|
||||
|
||||
# Include definitions common to all Darwin targets
|
||||
include $(CONFIG)/os/CONFIG.darwinCommon.darwinCommon
|
||||
@@ -12,7 +12,7 @@ include $(CONFIG)/os/CONFIG.Common.linux-x86
|
||||
ARCH_DEP_CFLAGS = -march=i386
|
||||
|
||||
ifeq ($(BUILD_CLASS),CROSS)
|
||||
VALID_BUILDS = Ioc
|
||||
VALID_BUILDS = Ioc Command
|
||||
endif
|
||||
|
||||
# If your crosscompiler name has a GNU target prefix like <gnutarget>-gcc,
|
||||
|
||||
@@ -10,7 +10,7 @@ include $(CONFIG)/os/CONFIG.Common.linux-x86
|
||||
ARCH_DEP_CFLAGS = -march=i486
|
||||
|
||||
ifeq ($(BUILD_CLASS),CROSS)
|
||||
VALID_BUILDS = Ioc
|
||||
VALID_BUILDS = Ioc Command
|
||||
endif
|
||||
|
||||
# If your crosscompiler name has a GNU target prefix like <gnutarget>-gcc,
|
||||
|
||||
@@ -11,7 +11,7 @@ include $(CONFIG)/os/CONFIG.Common.linux-x86
|
||||
ARCH_DEP_CFLAGS = -march=i586
|
||||
|
||||
ifeq ($(BUILD_CLASS),CROSS)
|
||||
VALID_BUILDS = Ioc
|
||||
VALID_BUILDS = Ioc Command
|
||||
endif
|
||||
|
||||
# If your crosscompiler name has a GNU target prefix like <gnutarget>-gcc,
|
||||
|
||||
@@ -11,7 +11,7 @@ include $(CONFIG)/os/CONFIG.Common.linux-x86
|
||||
ARCH_DEP_CFLAGS = -march=i686
|
||||
|
||||
ifeq ($(BUILD_CLASS),CROSS)
|
||||
VALID_BUILDS = Ioc
|
||||
VALID_BUILDS = Ioc Command
|
||||
endif
|
||||
|
||||
# If your crosscompiler name has a GNU target prefix like <gnutarget>-gcc,
|
||||
|
||||
@@ -10,7 +10,7 @@ include $(CONFIG)/os/CONFIG.Common.linux-x86
|
||||
ARCH_DEP_CFLAGS += -march=athlon-mp -mfpmath=sse
|
||||
|
||||
ifeq ($(BUILD_CLASS),CROSS)
|
||||
VALID_BUILDS = Ioc
|
||||
VALID_BUILDS = Ioc Command
|
||||
endif
|
||||
|
||||
# If your crosscompiler name has a GNU target prefix like <gnutarget>-gcc,
|
||||
|
||||
@@ -15,7 +15,7 @@ include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
ARCH_CLASS = microblaze
|
||||
|
||||
ifeq ($(BUILD_CLASS),CROSS)
|
||||
VALID_BUILDS = Ioc
|
||||
VALID_BUILDS = Ioc Command
|
||||
GNU_TARGET = microblazeel-unknown-linux-gnu
|
||||
CMPLR_PREFIX = $(addsuffix -,$(GNU_TARGET))
|
||||
endif
|
||||
|
||||
@@ -13,7 +13,7 @@ include $(CONFIG)/os/CONFIG.Common.linuxCommon
|
||||
ARCH_CLASS = xscale
|
||||
|
||||
ifeq ($(BUILD_CLASS),CROSS)
|
||||
VALID_BUILDS = Ioc
|
||||
VALID_BUILDS = Ioc Command
|
||||
GNU_TARGET = xscale_be
|
||||
CMPLR_PREFIX = $(GNU_TARGET:%=%-)
|
||||
|
||||
|
||||
8
configure/os/CONFIG.darwin-aarch64.Common
Normal file
8
configure/os/CONFIG.darwin-aarch64.Common
Normal file
@@ -0,0 +1,8 @@
|
||||
# CONFIG.darwin-aarch64.Common
|
||||
#
|
||||
# Definitions for darwin-aarch64 host builds
|
||||
# Sites may override these definitions in CONFIG_SITE.darwin-aarch64.Common
|
||||
#-------------------------------------------------------
|
||||
|
||||
#Include definitions common to unix hosts
|
||||
include $(CONFIG)/os/CONFIG.UnixCommon.Common
|
||||
8
configure/os/CONFIG.linux-aarch64.Common
Normal file
8
configure/os/CONFIG.linux-aarch64.Common
Normal file
@@ -0,0 +1,8 @@
|
||||
# CONFIG.linux-aarch64.Common
|
||||
#
|
||||
# Definitions for linux-aarch64 host builds
|
||||
# Sites may override these definitions in CONFIG_SITE.linux-aarch64.Common
|
||||
#-------------------------------------------------------
|
||||
|
||||
#Include definitions common to unix hosts
|
||||
include $(CONFIG)/os/CONFIG.UnixCommon.Common
|
||||
8
configure/os/CONFIG.linux-aarch64.linux-aarch64
Normal file
8
configure/os/CONFIG.linux-aarch64.linux-aarch64
Normal file
@@ -0,0 +1,8 @@
|
||||
# CONFIG.linux-aarch64.linux-aarch64
|
||||
#
|
||||
# Definitions for native linux-aarch64 builds
|
||||
# Override these definitions in CONFIG_SITE.linux-aarch64.linux-aarch64
|
||||
#-------------------------------------------------------
|
||||
|
||||
# Include common gnu compiler definitions
|
||||
include $(CONFIG)/CONFIG.gnuCommon
|
||||
@@ -4,7 +4,7 @@
|
||||
# Override these settings in CONFIG_SITE.linux-x86.linux-arm
|
||||
#-------------------------------------------------------
|
||||
|
||||
VALID_BUILDS = Ioc
|
||||
VALID_BUILDS = Ioc Command
|
||||
GNU_TARGET = arm-linux
|
||||
|
||||
# prefix of compiler tools
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Sites may override these in CONFIG_SITE.linux-x86_64.linux-aarch64
|
||||
#-------------------------------------------------------
|
||||
|
||||
VALID_BUILDS = Ioc
|
||||
VALID_BUILDS = Ioc Command
|
||||
GNU_TARGET = aarch64-linux
|
||||
|
||||
# prefix of compiler tools
|
||||
|
||||
@@ -26,6 +26,3 @@ endif
|
||||
|
||||
# Needed to find dlls for base installed build tools (antelope,eflex,...)
|
||||
PATH := $(EPICS_BASE_BIN):$(PATH)
|
||||
|
||||
# Silence the tr1 namespace deprecation warnings
|
||||
USR_CXXFLAGS_WIN32 += -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
# Win32 valid build types and include directory suffixes
|
||||
|
||||
VALID_BUILDS = Host Ioc
|
||||
VALID_BUILDS = Host Ioc Command
|
||||
|
||||
CMPLR_CLASS = msvc
|
||||
|
||||
@@ -107,6 +107,9 @@ CODE_CPPFLAGS += -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
|
||||
WARN_CXXFLAGS_YES = -W3 -w44355 -w44344 -w44251
|
||||
WARN_CXXFLAGS_NO = -W1
|
||||
|
||||
# Silence tr1 namespace deprecation warnings
|
||||
WARN_CXXFLAGS += -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING
|
||||
|
||||
#
|
||||
# -Ox maximum optimizations
|
||||
# -GL whole program optimization
|
||||
|
||||
@@ -16,3 +16,9 @@ COMMANDLINE_LIBRARY = READLINE_NCURSESW
|
||||
|
||||
# No other libraries needed
|
||||
#COMMANDLINE_LIBRARY = READLINE
|
||||
|
||||
|
||||
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
|
||||
# overridden in this file for native builds, e.g. variables such as
|
||||
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
|
||||
# They must be set in CONFIG_SITE.cygwin-x86.cygwin-x86 instead.
|
||||
|
||||
@@ -11,10 +11,8 @@
|
||||
#LDLIBS_READLINE = -lreadline -lcurses
|
||||
|
||||
|
||||
# It makes sense to include debugging symbols even in optimized builds
|
||||
# in case you want to attach gdb to the process or examine a core-dump.
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES += -g
|
||||
OPT_CXXFLAGS_YES += -g
|
||||
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
|
||||
# overridden in this file for native builds, e.g. variables such as
|
||||
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
|
||||
# They must be set in CONFIG_SITE.cygwin-x86_64.cygwin-x86_64 instead.
|
||||
|
||||
|
||||
9
configure/os/CONFIG_SITE.Common.darwin-aarch64
Normal file
9
configure/os/CONFIG_SITE.Common.darwin-aarch64
Normal file
@@ -0,0 +1,9 @@
|
||||
# CONFIG_SITE.Common.darwin-aarch64
|
||||
#
|
||||
# Site override definitions for darwin-aarch64 target builds
|
||||
#-------------------------------------------------------
|
||||
|
||||
#
|
||||
# arm64 devices: Apple Silicon M1
|
||||
|
||||
ARCH_CLASS = arm64
|
||||
@@ -30,3 +30,9 @@
|
||||
# Needs -lcurses (older versions)
|
||||
#COMMANDLINE_LIBRARY = READLINE_CURSES
|
||||
|
||||
|
||||
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
|
||||
# overridden in this file for native builds, e.g. variables such as
|
||||
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
|
||||
# They must be set in CONFIG_SITE.linux-aarch64.linux-aarch64 instead.
|
||||
|
||||
|
||||
@@ -33,3 +33,12 @@ COMMANDLINE_LIBRARY = $(strip $(if $(wildcard \
|
||||
|
||||
# Readline is broken or you don't want use it:
|
||||
#COMMANDLINE_LIBRARY = EPICS
|
||||
|
||||
|
||||
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
|
||||
# overridden in this file for native builds, e.g. variables such as
|
||||
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
|
||||
# They must be set in CONFIG_SITE.linux-arm.linux-arm instead.
|
||||
|
||||
# Permit access to 64-bit file-systems
|
||||
OP_SYS_CFLAGS += -D_FILE_OFFSET_BITS=64
|
||||
|
||||
@@ -34,22 +34,17 @@ COMMANDLINE_LIBRARY = $(strip $(if $(wildcard \
|
||||
#COMMANDLINE_LIBRARY = EPICS
|
||||
|
||||
|
||||
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
|
||||
# overridden in this file for native builds, e.g. variables such as
|
||||
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
|
||||
# They must be set in CONFIG_SITE.linux-x86.linux-x86 instead.
|
||||
|
||||
# Permit access to 64-bit file-systems
|
||||
OP_SYS_CFLAGS += -D_FILE_OFFSET_BITS=64
|
||||
|
||||
|
||||
# Uncomment the followings lines to build with CLANG instead of GCC.
|
||||
#
|
||||
#GNU = NO
|
||||
#CMPLR_CLASS = clang
|
||||
#CC = clang
|
||||
#CCC = clang++
|
||||
|
||||
|
||||
# Tune GNU compiler output for a specific 32-bit cpu-type
|
||||
# (e.g. generic, native, i386, i686, pentium2/3/4, prescott, k6, athlon etc.)
|
||||
GNU_TUNE_CFLAGS = -mtune=generic
|
||||
|
||||
|
||||
# Developers using a suitable compiler may enable its address sanitizer:
|
||||
#ENABLE_ASAN = YES
|
||||
|
||||
@@ -34,18 +34,14 @@ COMMANDLINE_LIBRARY = $(strip $(if $(wildcard \
|
||||
#COMMANDLINE_LIBRARY = EPICS
|
||||
|
||||
|
||||
# Uncomment the followings lines to build with CLANG instead of GCC.
|
||||
#
|
||||
#GNU = NO
|
||||
#CMPLR_CLASS = clang
|
||||
#CC = clang
|
||||
#CCC = clang++
|
||||
|
||||
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
|
||||
# overridden in this file for native builds, e.g. variables such as
|
||||
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
|
||||
# They must be set in CONFIG_SITE.linux-x86_64.linux-x86_64 instead.
|
||||
|
||||
# Tune GNU compiler output for a specific 64-bit cpu-type
|
||||
# (e.g. generic, native, core2, nocona, k8, opteron, athlon64, barcelona etc.)
|
||||
GNU_TUNE_CFLAGS = -mtune=generic
|
||||
|
||||
|
||||
# Developers using a suitable compiler may enable its address sanitizer:
|
||||
#ENABLE_ASAN = YES
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
#
|
||||
# Site-specific settings for all linux targets
|
||||
|
||||
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
|
||||
# overridden in this file for native builds, e.g. variables such as
|
||||
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
|
||||
# They must be set in the host+target specific file instead:
|
||||
# CONFIG_SITE.<linux-arch>.<linux-arch>
|
||||
|
||||
# It makes sense to include debugging symbols even in optimized builds
|
||||
# in case you want to attach gdb to the process or examine a core-dump.
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES += -g
|
||||
OPT_CXXFLAGS_YES += -g
|
||||
|
||||
@@ -6,3 +6,11 @@
|
||||
# GNU_DIR used when COMMANDLINE_LIBRARY is READLINE
|
||||
#GNU_DIR=C:/cygwin
|
||||
|
||||
|
||||
# It makes sense to include debugging symbols even in optimized builds
|
||||
# in case you want to attach gdb to the process or examine a core-dump.
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES += -g
|
||||
OPT_CXXFLAGS_YES += -g
|
||||
|
||||
|
||||
12
configure/os/CONFIG_SITE.linux-aarch64.linux-aarch64
Normal file
12
configure/os/CONFIG_SITE.linux-aarch64.linux-aarch64
Normal file
@@ -0,0 +1,12 @@
|
||||
# CONFIG_SITE.linux-aarch64.linux-aarch64
|
||||
#
|
||||
# Site specific definitions for native linux-aarch64 builds
|
||||
#-------------------------------------------------------
|
||||
|
||||
# It makes sense to include debugging symbols even in optimized builds
|
||||
# in case you want to attach gdb to the process or examine a core-dump.
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES += -g
|
||||
OPT_CXXFLAGS_YES += -g
|
||||
|
||||
@@ -3,3 +3,17 @@
|
||||
# Site specific definitions for linux-x86 host - linux-x86 target builds
|
||||
#-------------------------------------------------------
|
||||
|
||||
# It makes sense to include debugging symbols even in optimized builds
|
||||
# in case you want to attach gdb to the process or examine a core-dump.
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES += -g
|
||||
OPT_CXXFLAGS_YES += -g
|
||||
|
||||
# Uncomment the followings lines to build with CLANG instead of GCC.
|
||||
#
|
||||
#GNU = NO
|
||||
#CMPLR_CLASS = clang
|
||||
#CC = clang
|
||||
#CCC = clang++
|
||||
|
||||
|
||||
@@ -3,4 +3,17 @@
|
||||
# Site specific definitions for linux-x86_64 host - linux-x86_64 target builds
|
||||
#-------------------------------------------------------
|
||||
|
||||
# It makes sense to include debugging symbols even in optimized builds
|
||||
# in case you want to attach gdb to the process or examine a core-dump.
|
||||
# This does cost disk space, but not memory as debug symbols are not
|
||||
# loaded into RAM when the binary is loaded.
|
||||
OPT_CFLAGS_YES += -g
|
||||
OPT_CXXFLAGS_YES += -g
|
||||
|
||||
# Uncomment the followings lines to build with CLANG instead of GCC.
|
||||
#
|
||||
#GNU = NO
|
||||
#CMPLR_CLASS = clang
|
||||
#CC = clang
|
||||
#CCC = clang++
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Installation Instructions {#install}
|
||||
|
||||
## EPICS Base Release 7.0.3.1
|
||||
## EPICS Base Release 7.0.5
|
||||
|
||||
-----
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
- [Supported platforms](#0_0_4)
|
||||
- [Supported compilers](#0_0_5)
|
||||
- [Software requirements](#0_0_6)
|
||||
- [Host system storage requirements](#0_0_7)
|
||||
- [Documentation](#0_0_8)
|
||||
- [Directory Structure](#0_0_10)
|
||||
- [Build related components](#0_0_11)
|
||||
@@ -39,7 +38,7 @@ interfaces) of various types.
|
||||
Please check the `RELEASE_NOTES` file in the distribution for
|
||||
description of changes and release migration details.
|
||||
|
||||
### <span id="0_0_3">Copyright</span>
|
||||
### <span id="0_0_3">Copyright Licenses</span>
|
||||
|
||||
Please review the LICENSE file included in the distribution for legal
|
||||
terms of usage.
|
||||
@@ -68,10 +67,10 @@ path to do EPICS builds; check the definitions of CC and CCC in
|
||||
|
||||
**GNU make**
|
||||
You must use GNU make, gnumake, for any EPICS builds. Set your path so
|
||||
that a gnumake version 3.81 or later is available.
|
||||
that a gnumake version 4.1 or later is available.
|
||||
|
||||
**Perl**
|
||||
You must have Perl version 5.8.1 or later installed. The EPICS
|
||||
You must have Perl version 5.10 or later installed. The EPICS
|
||||
configuration files do not specify the perl full pathname, so the perl
|
||||
executable must be found through your normal search path.
|
||||
|
||||
@@ -114,13 +113,6 @@ installed on linux-x86. Command-line editing and history will then be
|
||||
those supplied by the os. On vxWorks the ledLib command-line input
|
||||
library is used instead.
|
||||
|
||||
### <span id="0_0_7">Host system storage requirements</span>
|
||||
|
||||
The compressed tar file is approximately 1.6 MB in size. The
|
||||
distribution source tree takes up approximately 12 MB. Each host
|
||||
target will need around 40 MB for build files, and each cross-compiled
|
||||
target around 20 MB.
|
||||
|
||||
### <span id="0_0_8">Documentation</span>
|
||||
|
||||
EPICS documentation is available through the [EPICS
|
||||
@@ -237,22 +229,18 @@ Files in the base/startup directory have been provided to help set
|
||||
required path and other environment variables.
|
||||
|
||||
* `EPICS_HOST_ARCH`
|
||||
Before you can build or use EPICS R3.15, the environment variable
|
||||
Before you can build or use this EPICS base, the environment variable
|
||||
`EPICS_HOST_ARCH` must be defined. A perl script EpicsHostArch.pl in
|
||||
the base/startup directory has been provided to help set
|
||||
`EPICS_HOST_ARCH.` You should have `EPICS_HOST_ARCH` set to your
|
||||
host operating system followed by a dash and then your host
|
||||
architecture, e.g. solaris-sparc. If you are not using the OS
|
||||
architecture, e.g. linux-x86_64. If you are not using the OS
|
||||
vendor's c/c++ compiler for host builds, you will need another dash
|
||||
followed by the alternate compiler name (e.g. "-gnu" for GNU c/c++
|
||||
compilers on a solaris host or "-mingw" for MinGW c/c++ compilers on
|
||||
a WIN32 host). See `configure/CONFIG_SITE` for a list of supported
|
||||
Windows). See `configure/CONFIG_SITE` for a list of supported
|
||||
`EPICS_HOST_ARCH` values.
|
||||
|
||||
* `PERLLIB`
|
||||
On WIN32, some versions of Perl require that the environment
|
||||
variable PERLLIB be set to <perl directory location>.
|
||||
|
||||
* `PATH`
|
||||
As already mentioned, you must have the perl executable and you may
|
||||
need C and C++ compilers in your search path. For building base you
|
||||
@@ -263,7 +251,7 @@ ranlib in your path, and the C compiler may require as and ld in
|
||||
your path. On solaris systems you need uname in your path.
|
||||
|
||||
* `LD_LIBRARY_PATH`
|
||||
R3.15 shared libraries and executables normally contain the full
|
||||
EPICS shared libraries and executables normally contain the full
|
||||
path to any libraries they require. However, if you move the EPICS
|
||||
files or directories from their build-time location then in order
|
||||
for the shared libraries to be found at runtime `LD_LIBRARY_PATH`
|
||||
@@ -336,10 +324,10 @@ A perl tool, makeBaseApp.pl is included in the distribution file. This
|
||||
script will create a sample application that can be built and then
|
||||
executed to try out this release of base.
|
||||
|
||||
Instructions for building and executing the 3.15 example application
|
||||
Instructions for building and executing the EPICS example application
|
||||
can be found in the section "Example Application" of Chapter 2,
|
||||
"Getting Started", in the "IOC Application Developer's Guide" for this
|
||||
release. The "Example IOC Application" section briefly explains how to
|
||||
"Getting Started", in the "EPICS Application Developer's Guide".
|
||||
The "Example IOC Application" section briefly explains how to
|
||||
create and build an example application in a user created <top>
|
||||
directory. It also explains how to run the example application on a
|
||||
vxWorks ioc or as a process on the host system. By running the example
|
||||
|
||||
@@ -11,11 +11,292 @@ release.
|
||||
The PVA submodules each have their own individual sets of release notes which
|
||||
should also be read to understand what has changed since earlier releases.
|
||||
|
||||
**This version of EPICS has not been released yet.**
|
||||
## EPICS Release 7.0.5
|
||||
|
||||
## Changes made on the 7.0 branch since 7.0.4.1
|
||||
### Fix aai's Device Support Initialization
|
||||
|
||||
<!-- Insert new items immediately below here ... -->
|
||||
Krisztian Loki [reported](https://github.com/epics-base/epics-base/issues/97)
|
||||
segfaults occurring when a Soft Channel aai record INP field was a DB link to
|
||||
an array field of a compress record. This was caused by the aai record's
|
||||
pass-0 device support initialization clashing with the semantics of the new
|
||||
link support API.
|
||||
|
||||
The aai record
|
||||
[has been modified](https://github.com/epics-base/epics-base/pull/114) to
|
||||
allow the Soft Channel device support to request a pass-1 initialization
|
||||
callback. See the Device Support section of the Array Analogue Input Record
|
||||
Reference pages in this release for the API changes, which are fully backwards
|
||||
compatible for existing aai device support.
|
||||
|
||||
### Prevent default DTYPs from changing
|
||||
|
||||
[Kay Kasemir reported](https://bugs.launchpad.net/epics-base/+bug/1908305) that
|
||||
it is possible to change the Base record type's default DTYP if a `device()`
|
||||
entry is seen before the `recordtype()` definition to which it refers. The
|
||||
default DTYP is the first device loaded, which is normally the `Soft Channel`
|
||||
support from Base. A warning was being displayed by dbdExpand when a `device()`
|
||||
entry was see first, but that was easily missed.
|
||||
|
||||
The DBD file parser in dbdExpand.pl has now been modified to make this an error,
|
||||
although the registerRecordDeviceDriver.pl script will still accept `device()`
|
||||
entries without having their `recordtype()` loaded since this is necessary to
|
||||
compile device supports as loadable modules.
|
||||
|
||||
|
||||
### Priority inversion safe Posix mutexes
|
||||
|
||||
On Posix systems, epicsMutex now support priority inheritance if available.
|
||||
The IOC needs to run with SCHED_FIFO engaged to use these.
|
||||
Support for Posix implementations before POSIX.1-2001 (`_XOPEN_SOURCE < 500`,
|
||||
glibc version < 2.3.3) has been dropped.
|
||||
|
||||
The IOC shell's `epicsMutexShowAll` command prints "PI is enabled" if both
|
||||
libc and kernel support is present.
|
||||
|
||||
### Fix for Periodic Scan threads hanging on Windows
|
||||
|
||||
Since 7.0.3.1 a Windows IOC could not run for more than 49.7 days; at that
|
||||
time the periodic scan threads would stop processing. This issue should now
|
||||
have been fixed and the Monotonic time functions on Windows should return
|
||||
values which count at nanosecond resolution. However we have not waited 49.7
|
||||
days to test the final software, so there is a small chance that it's still
|
||||
broken.
|
||||
|
||||
This fixes [lauchpad bug #1896295](https://bugs.launchpad.net/bugs/1896295).
|
||||
|
||||
### Support for Apple M1 (arm64) Processors
|
||||
|
||||
Thanks to Jeong Han Lee this release comes with build support for Apple's new
|
||||
M1 CPUs running macOS, using the target name `darwin-aarch64`.
|
||||
|
||||
It should also be possible to build universal binaries containing code for
|
||||
both the Intel and arm64 processors under either target name: In the
|
||||
appropriate `configure/os/CONFIG_SITE.Common.darwin-*` file add the other
|
||||
architecture class name to the `ARCH_CLASS` variable (after a space).
|
||||
|
||||
### New String Comparison Routine `epicsStrSimilarity()`
|
||||
|
||||
The new `epicsStrSimilarity()` routine in epicsString.h uses a modified
|
||||
Levenshtein distance to compare two strings, with a character case difference
|
||||
being half the weight of a full substitution. The double return value falls in
|
||||
the range 0.0 (identical) through 1.0 (no characters matching), or -1.0 for
|
||||
error. This is used to provide a new "Did you mean ..." suggestion when a .db
|
||||
file provides an invalid choice string for a `DBF_MENU` or `DBF_DEVICE` field.
|
||||
|
||||
### Build System: New `VALID_BUILDS` type "Command"
|
||||
|
||||
Target architectures that support command-line programs that run the `main()`
|
||||
routine can now be marked as such in their `VALID_BUILDS` definition. This
|
||||
enables a new set of Makefile target variables `PROD_CMD` (similar to
|
||||
`PROD_HOST`), `LIBRARY_CMD` (like `LIBRARY_HOST`, etc.), `LOADABLE_LIBRARY_CMD`,
|
||||
`OBJS_CMD`, `SCRIPTS_CMD`, `TARGETS_CMD`, `TESTLIBRARY_CMD`, `TESTSCRIPTS_CMD`
|
||||
and `TESTPROD_CMD`. The CA client tools and programs such as `caRepeater` are now built for all such targets (previously they were built for all targets except where the OS was VxWorks, RTEMS and iOS).
|
||||
|
||||
If you have created your own site-specific target architectures you may need to
|
||||
update the `VALID_BUILDS` variable if it gets set in your locally added
|
||||
`configure/os/CONFIG.Common.<arch>` files. This is usually only needed for
|
||||
cross-compiled targets though since `CONFIG.Common.UnixCommon` sets it.
|
||||
|
||||
The other `VALID_BUILDS` types are "Host" for target architectures that can
|
||||
compile and run their own programs (`PROD_HOST` etc.), and "Ioc" for targets
|
||||
that can run IOCs (`PROD_IOC` etc.).
|
||||
|
||||
### Support for JSON5
|
||||
|
||||
The YAJL parser and generator routines in libcom and in the IOC's dbStatic
|
||||
parser now support the JSON5 standard. This adds various features to JSON
|
||||
without altering the API for the code other than adding a new option to the
|
||||
YAJL parser which can be used to disable JSON5 support if desired. The new
|
||||
features include:
|
||||
|
||||
- The ability to handle numeric values `Infinity`, `-Infinity` and `NaN`.
|
||||
- String values and map keys may be enclosed in single quotes `'`, inside which
|
||||
the double-quote character `"` doesn't have to be escaped with a back-slash
|
||||
`\`, although a single-quote character `'` (or apostrophy) must be escaped
|
||||
inside a single-quoted string.
|
||||
- Numbers may start with a plus sign, `+`.
|
||||
- Integers may be expressed in hexadecimal with a leading `0x` or `0X`.
|
||||
- Floating-point numbers may start or end with their decimal point `.`
|
||||
(after the sign or before the exponent respectively if present).
|
||||
- Map keys that match the regex `[A-Za-z_][A-Za-z_0-9]*` don't have to be
|
||||
enclosed in quotes at all. The dbStatic parser adds `.+-` to the characters
|
||||
allowed but will add quotes around such keys before passing them to YAJL.
|
||||
- Arrays and maps allow a comma before the closing bracket/brace character.
|
||||
- The YAJL parser will elide a backslash followed by a newline characters from
|
||||
a string value. The dbStatic parser doesn't allow that however.
|
||||
|
||||
Code that must also compile against the older API can use the new C macro
|
||||
`HAS_JSON5` to detect the new version. This macro is defined on including
|
||||
either the `yajl_parse.h` or `yajl_gen.h` headers, which also provide the
|
||||
new configuration options to turn on JSON5 support.
|
||||
|
||||
All APIs in the IOC that previously accepted JSON will now accept JSON5.
|
||||
This includes JSON field modifiers (channel filters), JSON link addresses,
|
||||
constant input link array values and database info-tag values. JSON values
|
||||
that get parsed by the dbLoadRecords() routine are still more liberal than
|
||||
the other uses as the ability to use unquoted strings that was called
|
||||
"relaxed JSON" is still supported, whereas the JSON5 standard and the YAJL
|
||||
parser only allow unquoted strings to be used for keys in a JSON map.
|
||||
|
||||
This also fixes [lauchpad bug #1714455](https://bugs.launchpad.net/bugs/1714455).
|
||||
|
||||
|
||||
### Character Escape Changes
|
||||
|
||||
- The libCom routines `epicsStrnRawFromEscaped()` and `dbTranslateEscape()`
|
||||
declared in epicsString.h no longer accept octal escaped characters such as
|
||||
`\123` or `\41`.
|
||||
- The routine `epicsStrnEscapedFromRaw()` now generates hex
|
||||
excaped characters for unprintable characters such as `\x1f`.
|
||||
- Hex escape character sequences `\xXX` must now contain exactly 2 hex digits.
|
||||
- An escape sequence `\0` now generates a zero byte in the raw string, but the
|
||||
other digits `1-9` should not appear after a back-slash.
|
||||
|
||||
These changes are to more closely follow the JSON5 standard, which doesn't
|
||||
support octal character escapes or the `\a` (Bel, `\x07`) escape sequence.
|
||||
|
||||
### Filters in database input links
|
||||
|
||||
Input database links can now use channel filters, it is not necessary to
|
||||
make them CA links for the filters to work.
|
||||
|
||||
### ai Soft Channel support
|
||||
|
||||
The Soft Channel device support for ai records now returns failure when
|
||||
fetching the INP link fails.
|
||||
|
||||
### Support for zero-length arrays
|
||||
|
||||
Several modifications have been made to properly support zero-length
|
||||
array values inside the IOC and over Channel Access. Some of these changes
|
||||
may affect external code that interfaces with the IOC, either directly or
|
||||
over the CA client API so we recommend thorough testing of any external
|
||||
code that handles array fields when upgrading to this release.
|
||||
|
||||
Since these changes affect the Channel Access client-side API they will
|
||||
require rebuilding any CA Gateways against this version or Base to
|
||||
properly handle zero-length arrays. The `caget`, `caput` and `camonitor`
|
||||
client programs are known to work with empty arrays as long as they were
|
||||
built with this or a later version of EPICS.
|
||||
|
||||
#### Change to the db_access.h `dbr_size_n(TYPE, COUNT)` macro
|
||||
|
||||
When called with COUNT=0 this macro no longer returns the number of bytes
|
||||
required for a scalar (1 element) but for an empty array (0 elements).
|
||||
Make sure code that uses this doesn't call it with COUNT=0 when it really
|
||||
means COUNT=1.
|
||||
|
||||
Note that the db_access.h header file is included by cadef.h so the change
|
||||
can impact Channel Access client programs that use this macro.
|
||||
|
||||
#### Channel Access support for zero-length arrays
|
||||
|
||||
The `ca_array_put()` and `ca_array_put_callback()` routines now accept an
|
||||
element count of zero, and will write a zero-length array to the PV if
|
||||
possible. No error will be raised if the target is a scalar field though,
|
||||
and the field's value will not be changed.
|
||||
|
||||
The `ca_array_get_callback()` and `ca_create_subscription()` routines
|
||||
still accept a count of zero to mean fetch as many elements as the PV
|
||||
currently holds.
|
||||
|
||||
Client programs should be prepared for the `count` fields of any
|
||||
`struct event_handler_args` or `struct exception_handler_args` passed to
|
||||
their callback routines to be zero.
|
||||
|
||||
#### Array records
|
||||
|
||||
The soft device support for the array records aai, waveform, and subArray
|
||||
as well as the aSub record type now correctly report reading 0 elements
|
||||
when getting an empty array from an input link.
|
||||
|
||||
#### Array support for dbpf
|
||||
|
||||
The dbpf command now accepts array values, including empty arrays, when
|
||||
provided as a JSON string. This must be enclosed in quotes so the iocsh
|
||||
argument parser sees the JSON as a single argument:
|
||||
|
||||
```
|
||||
epics> dbpf wf10:i32 '[1, 2, 3, 4, 5]'
|
||||
DBF_LONG[5]: 1 = 0x1 2 = 0x2 3 = 0x3 4 = 0x4 5 = 0x5
|
||||
```
|
||||
|
||||
#### Reading empty arrays as scalar values
|
||||
|
||||
Record links that get a scalar value from an array that is currently
|
||||
empty will cause the record that has the link field to be set to an
|
||||
`INVALID/LINK` alarm status.
|
||||
The record code must call `dbGetLink()` with `pnRequest=NULL` for it to
|
||||
be recognized as a request for a scalar value though.
|
||||
|
||||
This changes the semantics of passing `pnRequest=NULL` to `dbGetLink()`,
|
||||
which now behaves differently than passing it a pointer to a long integer
|
||||
containing the value 1, which was previously equivalent.
|
||||
The latter can successfully fetch a zero-element array without triggering
|
||||
a LINK alarm.
|
||||
|
||||
#### Writing empty arrays to scalar fields
|
||||
|
||||
Record links that put a zero-element array into a scalar field will now set
|
||||
the target record to `INVALID/LINK` alarm without changing the field's value.
|
||||
Previously the field was set to 0 in this case (with no alarm).
|
||||
The target field must be marked as `special(SPC_DBADDR)` to be recognized
|
||||
as an array field, and its record support must define a `put_array_info()`
|
||||
routine.
|
||||
|
||||
### Timestamp before processing output links
|
||||
|
||||
The record processing code for records with output links has been modified to
|
||||
update the timestamp via recGblGetTimeStamp() _before_ processing the output
|
||||
links. This ensures that other records which get processed via an output link
|
||||
can use TSEL links to fetch the timestamp corresponding to the data processed
|
||||
by the output link.
|
||||
|
||||
This change could result in a slightly earlier timestamp for records whose
|
||||
output link is handled by a device driver, but only if the device driver does
|
||||
not handle its own timestamping via TSE -2 and instead uses TSE 0 or TSE -1 to
|
||||
get current time or best time, and the time spent in the device driver is
|
||||
greater than your timestamp provider resolution. For these situations it is
|
||||
recommended to set TSE to -2 and set the timestamp in the driver code.
|
||||
|
||||
### Add registerAllRecordDeviceDrivers()
|
||||
|
||||
A new iocsh command `registerAllRecordDeviceDrivers` is provided and also
|
||||
defined as a function in iocshRegisterCommon.h. This uses dynamic symbol
|
||||
lookup with `epicsFindSymbol()` to perform the same function as a generated
|
||||
`*_registerRecordDeviceDriver()` function. This allows for an alternative
|
||||
approach to dynamic loading of support modules without code generation.
|
||||
|
||||
This feature is not intended for use by IOCs constructed using the standard
|
||||
EPICS application build process and booted from a startup script in an iocBoot
|
||||
subdirectory, although it might work in some of those cases — the
|
||||
generated registerRecordDeviceDriver.cpp file is normally required to link
|
||||
everything referred to in the DBD file into the IOC's executable. It also
|
||||
won't work with some static build configurations, or if the symbol table has
|
||||
been stripped from the executable.
|
||||
|
||||
### Using a `{const:"string"}` to initialize an array of `DBF_CHAR`
|
||||
|
||||
It is now possible to use a JSON Const link with a string value to initialize
|
||||
an aai or waveform record that has `FTVL` set to `CHAR` through the INP link.
|
||||
The string length is not limited to 40 characters. This should also work for
|
||||
aSub record inputs similarly configured as long strings.
|
||||
|
||||
```
|
||||
record(waveform, "wf") {
|
||||
field(NELM, 100)
|
||||
field(FTVL, CHAR)
|
||||
field(INP, {const:"This is a waveform and more than 40 characters"})
|
||||
}
|
||||
```
|
||||
|
||||
### RELEASE files may use `undefine`
|
||||
|
||||
GNUmake added the directive `undefine` in version 3.82 to allow variables to
|
||||
be undefined. Support for this has been added to the EPICS Release file parser,
|
||||
so `undefine` can now be used in configure/RELEASE files to unset variables.
|
||||
|
||||
-----
|
||||
|
||||
## EPICS Release 7.0.4.1
|
||||
|
||||
@@ -64,6 +345,8 @@ Bad character ' ' in record name "bad practice"
|
||||
if a record name begins with a minus, plus, left square bracket,
|
||||
or left curly bracket.
|
||||
|
||||
-----
|
||||
|
||||
## EPICS Release 7.0.4
|
||||
|
||||
### Bug fixes
|
||||
@@ -248,6 +531,8 @@ devLsiEtherIP = {
|
||||
};
|
||||
```
|
||||
|
||||
-----
|
||||
|
||||
## EPICS Release 7.0.3.1
|
||||
|
||||
**IMPORTANT NOTE:** *Some record types in this release will not be compatible
|
||||
@@ -441,6 +726,8 @@ necessary, all RTEMS targets should now link although the IOC won't be able to
|
||||
be used with the VME I/O on those systems (that we don't have VMEbus I/O
|
||||
support for in libCom).
|
||||
|
||||
-----
|
||||
|
||||
## EPICS Release 7.0.3
|
||||
|
||||
### `epicsTimeGetCurrent()` optimization
|
||||
@@ -461,6 +748,8 @@ This may result in slightly fewer, but larger frames being sent.
|
||||
Report NOBT as "precision" through the dbAccess API. This is not accessible
|
||||
through CA, but is planned to be used through QSRV.
|
||||
|
||||
-----
|
||||
|
||||
## EPICS Release 7.0.2.2
|
||||
|
||||
### Build System changes
|
||||
@@ -495,6 +784,8 @@ substantial than bug fixes.
|
||||
|
||||
Turns out this is ~10x slower to query than `CLOCK_MONOTONIC`.
|
||||
|
||||
-----
|
||||
|
||||
## EPICS Release 7.0.2.1
|
||||
|
||||
### Linking shared libraries on macOS
|
||||
@@ -546,6 +837,8 @@ rewrite of the link address parser code in dbStaticLib. This release fixes that
|
||||
issue, although in some cases the output may be slightly different than it used
|
||||
to be.
|
||||
|
||||
-----
|
||||
|
||||
## EPICS Release 7.0.2
|
||||
|
||||
### Launchpad Bugs
|
||||
@@ -563,6 +856,8 @@ modules. The layout of the source files has not changed at all however, so the
|
||||
source code for libcom, ca and the database are still found separately under
|
||||
the module subdirectory.
|
||||
|
||||
-----
|
||||
|
||||
## EPICS Release 7.0.1.1
|
||||
|
||||
### Changed SIML failure behavior
|
||||
@@ -621,7 +916,11 @@ than is currently available, but as developers we generally much prefer to
|
||||
write code than documentation. Send questions to the tech-talk mailing list
|
||||
and we'll be happy to try and answer them!
|
||||
|
||||
## Changes between 3.16.1 and 3.16.2
|
||||
-----
|
||||
|
||||
## Changes made between 3.16.1 and 3.16.2
|
||||
|
||||
### Launchpad Bugs
|
||||
|
||||
The list of tracked bugs fixed in this release can be found on the
|
||||
[Launchpad Milestone page for EPICS Base 3.16.2](https://launchpad.net/epics-base/+milestone/3.16.2).
|
||||
@@ -828,6 +1127,8 @@ array is made even larger; the previous array buffer was not being released
|
||||
correctly. See Launchpad
|
||||
[bug #1706703](https://bugs.launchpad.net/epics-base/+bug/1706703).
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.16.0.1 and 3.16.1
|
||||
|
||||
### IOC Database Support for 64-bit integers
|
||||
@@ -1264,6 +1565,7 @@ and then replace `(RECSUPFUN)` with `RECSUPFUN_CAST` when initializing the
|
||||
rset. Further changes might also be needed, e.g. to adapt `const`-ness of
|
||||
method parameters.
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.15.3 and 3.16.0.1
|
||||
|
||||
@@ -1372,6 +1674,8 @@ header and removed the need for dbScan.c to reach into the internals of its
|
||||
`CALLBACK` objects.
|
||||
|
||||
|
||||
-----
|
||||
|
||||
# Changes incorporated from the 3.15 branch
|
||||
|
||||
|
||||
@@ -1383,6 +1687,7 @@ The names of the generated junit xml test output files have been changed
|
||||
from `<testname>.xml` to `<testname>-results.xml`, to allow better
|
||||
distinction from other xml files. (I.e., for easy wildcard matching.)
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.15.7 and 3.15.8
|
||||
|
||||
@@ -1488,6 +1793,7 @@ don't provide it any more.
|
||||
If multiple IOCs were started at the same time, by systemd say, they could race
|
||||
to obtain the Channel Access TCP port number 5064. This issue has been fixed.
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.15.6 and 3.15.7
|
||||
|
||||
@@ -1631,6 +1937,8 @@ into the htmls directory. Thanks to Tony Pietryla.
|
||||
|
||||
This displays the version numbers of EPICS Base and the CA protocol.
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.15.5 and 3.15.6
|
||||
|
||||
### Unsetting environment variables
|
||||
@@ -1856,6 +2164,8 @@ choice string cannot be parsed, the associated periodic scan thread will no
|
||||
longer be started by the IOC and a warning message will be displayed at iocInit
|
||||
time. The `scanppl` command will also flag the faulty menuScan value.
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.15.4 and 3.15.5
|
||||
|
||||
### dbStatic Library Speedup and Cleanup
|
||||
@@ -1987,6 +2297,8 @@ will be installed into the target bin directory, from where it can be copied
|
||||
into the appropriate systemd location and modified as necessary. Installation
|
||||
instructions are included as comments in the file.
|
||||
|
||||
-----
|
||||
|
||||
## Changes made between 3.15.3 and 3.15.4
|
||||
|
||||
### New string input device support "getenv"
|
||||
@@ -2092,6 +2404,8 @@ variable to a non-zero value before loading the file, like this:
|
||||
This was [Launchpad bug
|
||||
541119](https://bugs.launchpad.net/bugs/541119).
|
||||
|
||||
-----
|
||||
|
||||
## Changes from the 3.14 branch between 3.15.3 and 3.15.4
|
||||
|
||||
### NTP Time Provider adjusts to OS tick rate changes
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
# Record Reference Documentation {#recordrefmanual}
|
||||
|
||||
The following documentation for the record types and menus include with Base was
|
||||
The documentation below for the record types and menus included with Base was
|
||||
converted from the old EPICS Wiki pages and updated. This list only includes the
|
||||
record types supplied with Base.
|
||||
record types supplied with Base. The first two links below are to an external
|
||||
website where these original reference chapters are now being published.
|
||||
|
||||
* [Introduction to EPICS](https://docs.epics-controls.org/en/latest/guides/EPICS_Intro.html)
|
||||
* [Process Database Concepts](https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html)
|
||||
* [Fields Common to All Record Types](dbCommonRecord.html)
|
||||
* [Fields Common to Input Record Types](dbCommonInput.html)
|
||||
* [Fields Common to Output Record Types](dbCommonOutput.html)
|
||||
@@ -35,7 +38,7 @@ record types supplied with Base.
|
||||
* [Multi-Bit Binary Output Direct Record (mbboDirect)](mbboDirectRecord.html)
|
||||
* [Multi-Bit Binary Output Record (mbbo)](mbboRecord.html)
|
||||
* [Permissive Record (permissive)](permissiveRecord.html)
|
||||
* [Printf Record (prinf)](printfRecord.html)
|
||||
* [Printf Record (printf)](printfRecord.html)
|
||||
* [Select Record (sel)](selRecord.html)
|
||||
* [Sequence Record (seq)](seqRecord.html)
|
||||
* [State Record (state)](stateRecord.html)
|
||||
@@ -53,6 +56,9 @@ record types supplied with Base.
|
||||
* [Field Type Menu](menuFtype.html)
|
||||
* [Invalid Value Output Action Menu](menuIvoa.html)
|
||||
* [Output Mode Select Menu](menuOmsl.html)
|
||||
* [Process at iocInit Menu](menuPini.html)
|
||||
* [Post Monitors Menu](menuPost.html)
|
||||
* [Priority Menu](menuPriority.html)
|
||||
* [Scan Menu](menuScan.html)
|
||||
* [Simulation Mode Menu](menuSimm.html)
|
||||
* [Yes/No Menu](menuYesNo.html)
|
||||
|
||||
@@ -147,17 +147,17 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
|
||||
<td>Tag the module in Git, using these tag conventions:
|
||||
<ul>
|
||||
<li>
|
||||
<tt>R7.0.4.1-pre<i>n</i></tt>
|
||||
<tt>R7.0.5-pre<i>n</i></tt>
|
||||
— pre-release tag
|
||||
</li>
|
||||
<li>
|
||||
<tt>R7.0.4.1-rc<i>n</i></tt>
|
||||
<tt>R7.0.5-rc<i>n</i></tt>
|
||||
— release candidate tag
|
||||
</li>
|
||||
</ul>
|
||||
<blockquote><tt>
|
||||
cd base-7.0<br />
|
||||
git tag -m 'ANJ: Tagged for 7.0.4.1-rc1' R7.0.4.1-rc1
|
||||
git tag -m 'ANJ: Tagged for 7.0.5-rc1' R7.0.5-rc1
|
||||
</tt></blockquote>
|
||||
Note that submodules must <em>not</em> be tagged with the version used
|
||||
for the top-level, they each have their own separate version numbers
|
||||
@@ -171,11 +171,11 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
|
||||
files and directories that are only used for continuous integration:
|
||||
<blockquote><tt>
|
||||
cd base-7.0<br />
|
||||
./.tools/make-tar.sh R7.0.4.1-rc1 base-7.0.4.1-rc1.tar.gz base-7.0.4.1-rc1/
|
||||
./.tools/make-tar.sh R7.0.5-rc1 base-7.0.5-rc1.tar.gz base-7.0.5-rc1/
|
||||
</tt></blockquote>
|
||||
Create a GPG signature file of the tarfile as follows:
|
||||
<blockquote><tt>
|
||||
gpg --armor --sign --detach-sig base-7.0.4.1-rc1.tar.gz
|
||||
gpg --armor --sign --detach-sig base-7.0.5-rc1.tar.gz
|
||||
</tt></blockquote>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -298,7 +298,7 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
|
||||
|
||||
<li>Tag the module:
|
||||
<blockquote><tt>
|
||||
git tag -m 'ANJ: Tag for EPICS 7.0.4.1' <module-version>
|
||||
git tag -m 'ANJ: Tag for EPICS 7.0.5' <module-version>
|
||||
</tt></blockquote>
|
||||
</li>
|
||||
|
||||
@@ -355,7 +355,7 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
|
||||
<td>Tag the epics-base module in Git:
|
||||
<blockquote><tt>
|
||||
cd base-7.0<br />
|
||||
git tag -m 'ANJ: Tagged for release' R7.0.4.1
|
||||
git tag -m 'ANJ: Tagged for release' R7.0.5
|
||||
</tt></blockquote>
|
||||
<p>Don't push these commits or the new tag to the Launchpad repository
|
||||
yet.</p>
|
||||
@@ -387,12 +387,12 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
|
||||
files and directories that are only used for continuous integration:
|
||||
<blockquote><tt>
|
||||
cd base-7.0<br />
|
||||
./.tools/make-tar.sh R7.0.4.1 ../base-7.0.4.1.tar.gz base-7.0.4.1/
|
||||
./.tools/make-tar.sh R7.0.5 ../base-7.0.5.tar.gz base-7.0.5/
|
||||
</tt></blockquote>
|
||||
Create a GPG signature file of the tarfile as follows:
|
||||
<blockquote><tt>
|
||||
cd ..<br />
|
||||
gpg --armor --sign --detach-sig base-7.0.4.1.tar.gz
|
||||
gpg --armor --sign --detach-sig base-7.0.5.tar.gz
|
||||
</tt></blockquote>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -457,7 +457,7 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
|
||||
<td>Upload the tar file and its <tt>.asc</tt> signature file to the
|
||||
epics-controls web-server.
|
||||
<blockquote><tt>
|
||||
scp base-7.0.4.1.tar.gz base-7.0.4.1.tar.gz.asc epics-controls:download/base<br />
|
||||
scp base-7.0.5.tar.gz base-7.0.5.tar.gz.asc epics-controls:download/base<br />
|
||||
</tt></blockquote>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -95,10 +95,7 @@ PROD_LIBS = ca Com
|
||||
# needed when its an object library build
|
||||
PROD_SYS_LIBS_WIN32 = ws2_32 advapi32 user32
|
||||
|
||||
PROD_DEFAULT += caRepeater catime acctst caConnTest casw caEventRate
|
||||
PROD_vxWorks = -nil-
|
||||
PROD_RTEMS = -nil-
|
||||
PROD_iOS = -nil-
|
||||
PROD_CMD += caRepeater catime acctst caConnTest casw caEventRate
|
||||
|
||||
OBJS_vxWorks = catime acctst caConnTest casw caEventRate acctstRegister
|
||||
|
||||
|
||||
@@ -153,13 +153,13 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
|
||||
this->localPort = htons ( tmpAddr.ia.sin_port );
|
||||
}
|
||||
|
||||
std::auto_ptr < CallbackGuard > pCBGuard;
|
||||
ca::auto_ptr < CallbackGuard > pCBGuard;
|
||||
if ( ! enablePreemptiveCallback ) {
|
||||
pCBGuard.reset ( new CallbackGuard ( this->cbMutex ) );
|
||||
}
|
||||
|
||||
// multiple steps ensure exception safety
|
||||
this->pCallbackGuard = pCBGuard;
|
||||
this->pCallbackGuard = PTRMOVE(pCBGuard);
|
||||
}
|
||||
|
||||
ca_client_context::~ca_client_context ()
|
||||
|
||||
@@ -517,7 +517,7 @@ struct dbr_ctrl_double{
|
||||
};
|
||||
|
||||
#define dbr_size_n(TYPE,COUNT)\
|
||||
((unsigned)((COUNT)<=0?dbr_size[TYPE]:dbr_size[TYPE]+((COUNT)-1)*dbr_value_size[TYPE]))
|
||||
((unsigned)((COUNT)<0?dbr_size[TYPE]:dbr_size[TYPE]+((COUNT)-1)*dbr_value_size[TYPE]))
|
||||
|
||||
/* size for each type - array indexed by the DBR_ type code */
|
||||
LIBCA_API extern const unsigned short dbr_size[];
|
||||
|
||||
@@ -329,7 +329,7 @@ void nciu::write (
|
||||
if ( ! this->accessRightState.writePermit() ) {
|
||||
throw cacChannel::noWriteAccess();
|
||||
}
|
||||
if ( countIn > this->count || countIn == 0 ) {
|
||||
if ( countIn > this->count) {
|
||||
throw cacChannel::outOfBounds();
|
||||
}
|
||||
if ( type == DBR_STRING ) {
|
||||
@@ -350,7 +350,7 @@ cacChannel::ioStatus nciu::write (
|
||||
if ( ! this->accessRightState.writePermit() ) {
|
||||
throw cacChannel::noWriteAccess();
|
||||
}
|
||||
if ( countIn > this->count || countIn == 0 ) {
|
||||
if ( countIn > this->count) {
|
||||
throw cacChannel::outOfBounds();
|
||||
}
|
||||
if ( type == DBR_STRING ) {
|
||||
|
||||
@@ -38,6 +38,17 @@
|
||||
#include "cadef.h"
|
||||
#include "syncGroup.h"
|
||||
|
||||
namespace ca {
|
||||
#if __cplusplus>=201103L
|
||||
template<typename T>
|
||||
using auto_ptr = std::unique_ptr<T>;
|
||||
#define PTRMOVE(AUTO) std::move(AUTO)
|
||||
#else
|
||||
using std::auto_ptr;
|
||||
#define PTRMOVE(AUTO) (AUTO)
|
||||
#endif
|
||||
}
|
||||
|
||||
struct oldChannelNotify : private cacChannelNotify {
|
||||
public:
|
||||
oldChannelNotify (
|
||||
@@ -393,8 +404,8 @@ private:
|
||||
epicsEvent ioDone;
|
||||
epicsEvent callbackThreadActivityComplete;
|
||||
epicsThreadId createdByThread;
|
||||
std::auto_ptr < CallbackGuard > pCallbackGuard;
|
||||
std::auto_ptr < cacContext > pServiceContext;
|
||||
ca::auto_ptr < CallbackGuard > pCallbackGuard;
|
||||
ca::auto_ptr < cacContext > pServiceContext;
|
||||
caExceptionHandler * ca_exception_func;
|
||||
void * ca_exception_arg;
|
||||
caPrintfFunc * pVPrintfFunc;
|
||||
|
||||
@@ -40,6 +40,17 @@
|
||||
#include "repeaterSubscribeTimer.h"
|
||||
#include "SearchDest.h"
|
||||
|
||||
namespace ca {
|
||||
#if __cplusplus>=201103L
|
||||
template<typename T>
|
||||
using auto_ptr = std::unique_ptr<T>;
|
||||
#define PTRMOVE(AUTO) std::move(AUTO)
|
||||
#else
|
||||
using std::auto_ptr;
|
||||
#define PTRMOVE(AUTO) (AUTO)
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" void cacRecvThreadUDP ( void *pParam );
|
||||
|
||||
LIBCA_API void epicsStdCall caStartRepeaterIfNotInstalled (
|
||||
@@ -161,7 +172,7 @@ private:
|
||||
epicsMutex & cacMutex;
|
||||
const unsigned nTimers;
|
||||
struct SearchArray {
|
||||
typedef std::auto_ptr <searchTimer> value_type;
|
||||
typedef ca::auto_ptr <searchTimer> value_type;
|
||||
value_type *arr;
|
||||
SearchArray(size_t n) : arr(new value_type[n]) {}
|
||||
~SearchArray() { delete[] arr; }
|
||||
|
||||
@@ -13,10 +13,7 @@ TOP = ../../../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PROD_DEFAULT += caget camonitor cainfo caput
|
||||
PROD_vxWorks = -nil-
|
||||
PROD_RTEMS = -nil-
|
||||
PROD_iOS = -nil-
|
||||
PROD_CMD = caget camonitor cainfo caput
|
||||
|
||||
PROD_SRCS = tool_lib.c
|
||||
|
||||
|
||||
@@ -946,13 +946,18 @@ long dbGet(DBADDR *paddr, short dbrType,
|
||||
if (offset == 0 && (!nRequest || no_elements == 1)) {
|
||||
if (nRequest)
|
||||
*nRequest = 1;
|
||||
else if (no_elements < 1) {
|
||||
status = S_db_onlyOne;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!pfl || pfl->type == dbfl_type_rec) {
|
||||
status = dbFastGetConvertRoutine[field_type][dbrType]
|
||||
(paddr->pfield, pbuf, paddr);
|
||||
} else {
|
||||
DBADDR localAddr = *paddr; /* Structure copy */
|
||||
|
||||
if (pfl->no_elements < 1) {
|
||||
if (no_elements < 1) {
|
||||
status = S_db_badField;
|
||||
goto done;
|
||||
}
|
||||
@@ -996,6 +1001,11 @@ long dbGet(DBADDR *paddr, short dbrType,
|
||||
} else {
|
||||
DBADDR localAddr = *paddr; /* Structure copy */
|
||||
|
||||
if (pfl->no_elements < 1) {
|
||||
status = S_db_badField;
|
||||
goto done;
|
||||
}
|
||||
|
||||
localAddr.field_type = pfl->field_type;
|
||||
localAddr.field_size = pfl->field_size;
|
||||
localAddr.no_elements = pfl->no_elements;
|
||||
@@ -1037,7 +1047,7 @@ static long dbPutFieldLink(DBADDR *paddr,
|
||||
short dbrType, const void *pbuffer, long nRequest)
|
||||
{
|
||||
dbLinkInfo link_info;
|
||||
DBADDR *pdbaddr = NULL;
|
||||
dbChannel *chan = NULL;
|
||||
dbCommon *precord = paddr->precord;
|
||||
dbCommon *lockrecs[2];
|
||||
dbLocker locker;
|
||||
@@ -1075,16 +1085,11 @@ static long dbPutFieldLink(DBADDR *paddr,
|
||||
|
||||
if (link_info.ltype == PV_LINK &&
|
||||
(link_info.modifiers & (pvlOptCA | pvlOptCP | pvlOptCPP)) == 0) {
|
||||
DBADDR tempaddr;
|
||||
|
||||
if (dbNameToAddr(link_info.target, &tempaddr)==0) {
|
||||
/* This will become a DB link. */
|
||||
pdbaddr = malloc(sizeof(*pdbaddr));
|
||||
if (!pdbaddr) {
|
||||
status = S_db_noMemory;
|
||||
goto cleanup;
|
||||
}
|
||||
*pdbaddr = tempaddr; /* struct copy */
|
||||
chan = dbChannelCreate(link_info.target);
|
||||
if (chan && dbChannelOpen(chan) != 0) {
|
||||
errlogPrintf("ERROR: dbPutFieldLink %s.%s=%s: dbChannelOpen() failed\n",
|
||||
precord->name, pfldDes->name, link_info.target);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1093,7 +1098,7 @@ static long dbPutFieldLink(DBADDR *paddr,
|
||||
|
||||
memset(&locker, 0, sizeof(locker));
|
||||
lockrecs[0] = precord;
|
||||
lockrecs[1] = pdbaddr ? pdbaddr->precord : NULL;
|
||||
lockrecs[1] = chan ? dbChannelRecord(chan) : NULL;
|
||||
dbLockerPrepare(&locker, lockrecs, 2);
|
||||
|
||||
dbScanLockMany(&locker);
|
||||
@@ -1181,7 +1186,8 @@ static long dbPutFieldLink(DBADDR *paddr,
|
||||
case PV_LINK:
|
||||
case CONSTANT:
|
||||
case JSON_LINK:
|
||||
dbAddLink(&locker, plink, pfldDes->field_type, pdbaddr);
|
||||
dbAddLink(&locker, plink, pfldDes->field_type, chan);
|
||||
chan = NULL; /* don't clean it up */
|
||||
break;
|
||||
|
||||
case DB_LINK:
|
||||
@@ -1211,6 +1217,8 @@ unlock:
|
||||
dbScanUnlockMany(&locker);
|
||||
dbLockerFinalize(&locker);
|
||||
cleanup:
|
||||
if (chan)
|
||||
dbChannelDelete(chan);
|
||||
free(link_info.target);
|
||||
return status;
|
||||
}
|
||||
@@ -1330,25 +1338,21 @@ long dbPut(DBADDR *paddr, short dbrType,
|
||||
status = prset->get_array_info(paddr, &dummy, &offset);
|
||||
/* paddr->pfield may be modified */
|
||||
if (status) goto done;
|
||||
} else
|
||||
offset = 0;
|
||||
|
||||
if (no_elements <= 1) {
|
||||
status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer,
|
||||
paddr->pfield, paddr);
|
||||
nRequest = 1;
|
||||
} else {
|
||||
if (no_elements < nRequest)
|
||||
nRequest = no_elements;
|
||||
status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer,
|
||||
nRequest, no_elements, offset);
|
||||
}
|
||||
|
||||
/* update array info */
|
||||
if (!status &&
|
||||
paddr->pfldDes->special == SPC_DBADDR &&
|
||||
prset && prset->put_array_info) {
|
||||
status = prset->put_array_info(paddr, nRequest);
|
||||
/* update array info */
|
||||
if (!status && prset->put_array_info)
|
||||
status = prset->put_array_info(paddr, nRequest);
|
||||
} else {
|
||||
if (nRequest < 1) {
|
||||
recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM);
|
||||
} else {
|
||||
status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer,
|
||||
paddr->pfield, paddr);
|
||||
nRequest = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Always do special processing if needed */
|
||||
|
||||
@@ -173,9 +173,8 @@ struct dbr_alDouble {DBRalDouble};
|
||||
#define dbr_alLong_size sizeof(struct dbr_alLong)
|
||||
#define dbr_alDouble_size sizeof(struct dbr_alDouble)
|
||||
|
||||
#ifndef INCerrMdefh
|
||||
#include "errMdef.h"
|
||||
#endif
|
||||
|
||||
#define S_db_notFound (M_dbAccess| 1) /*Process Variable Not Found*/
|
||||
#define S_db_badDbrtype (M_dbAccess| 3) /*Illegal Database Request Type*/
|
||||
#define S_db_noMod (M_dbAccess| 5) /*Attempt to modify noMod field*/
|
||||
|
||||
@@ -48,6 +48,17 @@
|
||||
#include "db_convert.h"
|
||||
#include "resourceLib.h"
|
||||
|
||||
namespace ca {
|
||||
#if __cplusplus>=201103L
|
||||
template<typename T>
|
||||
using auto_ptr = std::unique_ptr<T>;
|
||||
#define PTRMOVE(AUTO) std::move(AUTO)
|
||||
#else
|
||||
using std::auto_ptr;
|
||||
#define PTRMOVE(AUTO) (AUTO)
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" int putNotifyPut ( processNotify *ppn, notifyPutType notifyPutType );
|
||||
extern "C" void putNotifyCompletion ( processNotify *ppn );
|
||||
|
||||
@@ -194,7 +205,7 @@ private:
|
||||
epicsMutex & mutex;
|
||||
epicsMutex & cbMutex;
|
||||
cacContextNotify & notify;
|
||||
std::auto_ptr < cacContext > pNetContext;
|
||||
ca::auto_ptr < cacContext > pNetContext;
|
||||
char * pStateNotifyCache;
|
||||
bool isolated;
|
||||
|
||||
|
||||
@@ -411,9 +411,15 @@ long dbCaGetLink(struct link *plink, short dbrType, void *pdest,
|
||||
goto done;
|
||||
}
|
||||
newType = dbDBRoldToDBFnew[pca->dbrType];
|
||||
if (!nelements || *nelements == 1) {
|
||||
if (!nelements) {
|
||||
long (*fConvert)(const void *from, void *to, struct dbAddr *paddr);
|
||||
|
||||
if (pca->usedelements < 1) {
|
||||
pca->sevr = INVALID_ALARM;
|
||||
pca->stat = LINK_ALARM;
|
||||
status = -1;
|
||||
goto done;
|
||||
}
|
||||
fConvert = dbFastGetConvertRoutine[newType][dbrType];
|
||||
assert(pca->pgetNative);
|
||||
status = fConvert(pca->pgetNative, pdest, 0);
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#define EPICS_PRIVATE_API
|
||||
|
||||
#include "cantProceed.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "epicsString.h"
|
||||
@@ -68,6 +70,7 @@ void dbChannelInit (void)
|
||||
freeListInitPvt(&dbChannelFreeList, sizeof(dbChannel), 128);
|
||||
freeListInitPvt(&chFilterFreeList, sizeof(chFilter), 64);
|
||||
freeListInitPvt(&dbchStringFreeList, sizeof(epicsOldString), 128);
|
||||
db_init_event_freelists();
|
||||
}
|
||||
|
||||
static void chf_value(parseContext *parser, parse_result *presult)
|
||||
|
||||
@@ -169,6 +169,9 @@ static long dbConstLoadScalar(struct link *plink, short dbrType, void *pbuffer)
|
||||
return dbPutConvertJSON(pstr, dbrType, pbuffer, &nReq);
|
||||
}
|
||||
|
||||
if(dbrType>=NELEMENTS(convert))
|
||||
return S_db_badDbrtype;
|
||||
|
||||
return convert[dbrType](pstr, pbuffer, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ dbContext::dbContext ( epicsMutex & cbMutexIn,
|
||||
epicsMutex & mutexIn, cacContextNotify & notifyIn ) :
|
||||
readNotifyCache ( mutexIn ), ctx ( 0 ),
|
||||
stateNotifyCacheSize ( 0 ), mutex ( mutexIn ), cbMutex ( cbMutexIn ),
|
||||
notify ( notifyIn ), pNetContext ( 0 ), pStateNotifyCache ( 0 ),
|
||||
notify ( notifyIn ), pStateNotifyCache ( 0 ),
|
||||
isolated(dbServiceIsolate)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "dbConvertFast.h"
|
||||
#include "dbConvert.h"
|
||||
#include "db_field_log.h"
|
||||
#include "db_access_routines.h"
|
||||
#include "dbFldTypes.h"
|
||||
#include "dbLink.h"
|
||||
#include "dbLockPvt.h"
|
||||
@@ -74,7 +75,7 @@
|
||||
#include "recSup.h"
|
||||
#include "special.h"
|
||||
#include "dbDbLink.h"
|
||||
|
||||
#include "dbChannel.h"
|
||||
|
||||
/***************************** Database Links *****************************/
|
||||
|
||||
@@ -83,45 +84,51 @@ static lset dbDb_lset;
|
||||
|
||||
static long processTarget(dbCommon *psrc, dbCommon *pdst);
|
||||
|
||||
#define linkChannel(plink) ((dbChannel *) (plink)->value.pv_link.pvt)
|
||||
|
||||
long dbDbInitLink(struct link *plink, short dbfType)
|
||||
{
|
||||
DBADDR dbaddr;
|
||||
long status;
|
||||
DBADDR *pdbAddr;
|
||||
dbChannel *chan;
|
||||
dbCommon *precord;
|
||||
|
||||
status = dbNameToAddr(plink->value.pv_link.pvname, &dbaddr);
|
||||
chan = dbChannelCreate(plink->value.pv_link.pvname);
|
||||
if (!chan)
|
||||
return S_db_notFound;
|
||||
status = dbChannelOpen(chan);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
precord = dbChannelRecord(chan);
|
||||
|
||||
plink->lset = &dbDb_lset;
|
||||
plink->type = DB_LINK;
|
||||
pdbAddr = dbCalloc(1, sizeof(struct dbAddr));
|
||||
*pdbAddr = dbaddr; /* structure copy */
|
||||
plink->value.pv_link.pvt = pdbAddr;
|
||||
ellAdd(&dbaddr.precord->bklnk, &plink->value.pv_link.backlinknode);
|
||||
plink->value.pv_link.pvt = chan;
|
||||
ellAdd(&precord->bklnk, &plink->value.pv_link.backlinknode);
|
||||
/* merging into the same lockset is deferred to the caller.
|
||||
* cf. initPVLinks()
|
||||
*/
|
||||
dbLockSetMerge(NULL, plink->precord, dbaddr.precord);
|
||||
assert(plink->precord->lset->plockSet == dbaddr.precord->lset->plockSet);
|
||||
dbLockSetMerge(NULL, plink->precord, precord);
|
||||
assert(plink->precord->lset->plockSet == precord->lset->plockSet);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dbDbAddLink(struct dbLocker *locker, struct link *plink, short dbfType,
|
||||
DBADDR *ptarget)
|
||||
dbChannel *chan)
|
||||
{
|
||||
plink->lset = &dbDb_lset;
|
||||
plink->type = DB_LINK;
|
||||
plink->value.pv_link.pvt = ptarget;
|
||||
ellAdd(&ptarget->precord->bklnk, &plink->value.pv_link.backlinknode);
|
||||
plink->value.pv_link.pvt = chan;
|
||||
ellAdd(&dbChannelRecord(chan)->bklnk, &plink->value.pv_link.backlinknode);
|
||||
|
||||
/* target record is already locked in dbPutFieldLink() */
|
||||
dbLockSetMerge(locker, plink->precord, ptarget->precord);
|
||||
dbLockSetMerge(locker, plink->precord, dbChannelRecord(chan));
|
||||
}
|
||||
|
||||
static void dbDbRemoveLink(struct dbLocker *locker, struct link *plink)
|
||||
{
|
||||
DBADDR *pdbAddr = (DBADDR *) plink->value.pv_link.pvt;
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
dbCommon *precord = dbChannelRecord(chan);
|
||||
|
||||
plink->type = PV_LINK;
|
||||
|
||||
@@ -131,10 +138,10 @@ static void dbDbRemoveLink(struct dbLocker *locker, struct link *plink)
|
||||
plink->value.pv_link.getCvt = 0;
|
||||
plink->value.pv_link.pvlMask = 0;
|
||||
plink->value.pv_link.lastGetdbrType = 0;
|
||||
ellDelete(&pdbAddr->precord->bklnk, &plink->value.pv_link.backlinknode);
|
||||
dbLockSetSplit(locker, plink->precord, pdbAddr->precord);
|
||||
ellDelete(&precord->bklnk, &plink->value.pv_link.backlinknode);
|
||||
dbLockSetSplit(locker, plink->precord, precord);
|
||||
}
|
||||
free(pdbAddr);
|
||||
dbChannelDelete(chan);
|
||||
}
|
||||
|
||||
static int dbDbIsConnected(const struct link *plink)
|
||||
@@ -144,16 +151,14 @@ static int dbDbIsConnected(const struct link *plink)
|
||||
|
||||
static int dbDbGetDBFtype(const struct link *plink)
|
||||
{
|
||||
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
|
||||
|
||||
return paddr->field_type;
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
return dbChannelFinalFieldType(chan);
|
||||
}
|
||||
|
||||
static long dbDbGetElements(const struct link *plink, long *nelements)
|
||||
{
|
||||
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
|
||||
|
||||
*nelements = paddr->no_elements;
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
*nelements = dbChannelFinalElements(chan);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -161,47 +166,75 @@ static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
long *pnRequest)
|
||||
{
|
||||
struct pv_link *ppv_link = &plink->value.pv_link;
|
||||
DBADDR *paddr = ppv_link->pvt;
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
DBADDR *paddr = &chan->addr;
|
||||
dbCommon *precord = plink->precord;
|
||||
db_field_log *pfl = NULL;
|
||||
long status;
|
||||
|
||||
/* scan passive records if link is process passive */
|
||||
if (ppv_link->pvlMask & pvlOptPP) {
|
||||
status = dbScanPassive(precord, paddr->precord);
|
||||
status = dbScanPassive(precord, dbChannelRecord(chan));
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType) {
|
||||
status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr);
|
||||
} else {
|
||||
unsigned short dbfType = paddr->field_type;
|
||||
if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType)
|
||||
{
|
||||
/* shortcut: scalar with known conversion, no filter */
|
||||
status = ppv_link->getCvt(dbChannelField(chan), pbuffer, paddr);
|
||||
}
|
||||
else if (dbChannelFinalElements(chan) == 1 && (!pnRequest || *pnRequest == 1)
|
||||
&& dbChannelSpecial(chan) != SPC_DBADDR
|
||||
&& dbChannelSpecial(chan) != SPC_ATTRIBUTE
|
||||
&& ellCount(&chan->filters) == 0)
|
||||
{
|
||||
/* simple scalar: set up shortcut */
|
||||
unsigned short dbfType = dbChannelFinalFieldType(chan);
|
||||
|
||||
if (dbrType < 0 || dbrType > DBR_ENUM || dbfType > DBF_DEVICE)
|
||||
return S_db_badDbrtype;
|
||||
|
||||
if (paddr->no_elements == 1 && (!pnRequest || *pnRequest == 1)
|
||||
&& paddr->special != SPC_DBADDR
|
||||
&& paddr->special != SPC_ATTRIBUTE) {
|
||||
ppv_link->getCvt = dbFastGetConvertRoutine[dbfType][dbrType];
|
||||
status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr);
|
||||
} else {
|
||||
ppv_link->getCvt = NULL;
|
||||
status = dbGet(paddr, dbrType, pbuffer, NULL, pnRequest, NULL);
|
||||
}
|
||||
ppv_link->getCvt = dbFastGetConvertRoutine[dbfType][dbrType];
|
||||
ppv_link->lastGetdbrType = dbrType;
|
||||
status = ppv_link->getCvt(dbChannelField(chan), pbuffer, paddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* filter, array, or special */
|
||||
ppv_link->getCvt = NULL;
|
||||
|
||||
if (ellCount(&chan->filters)) {
|
||||
/* If filters are involved in a read, create field log and run filters */
|
||||
pfl = db_create_read_log(chan);
|
||||
if (!pfl)
|
||||
return S_db_noMemory;
|
||||
|
||||
pfl = dbChannelRunPreChain(chan, pfl);
|
||||
pfl = dbChannelRunPostChain(chan, pfl);
|
||||
}
|
||||
|
||||
status = dbChannelGet(chan, dbrType, pbuffer, NULL, pnRequest, pfl);
|
||||
|
||||
if (pfl)
|
||||
db_delete_field_log(pfl);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!status && precord != paddr->precord)
|
||||
if (!status && precord != dbChannelRecord(chan))
|
||||
recGblInheritSevr(plink->value.pv_link.pvlMask & pvlOptMsMode,
|
||||
plink->precord, paddr->precord->stat, paddr->precord->sevr);
|
||||
plink->precord,
|
||||
dbChannelRecord(chan)->stat, dbChannelRecord(chan)->sevr);
|
||||
return status;
|
||||
}
|
||||
|
||||
static long dbDbGetControlLimits(const struct link *plink, double *low,
|
||||
double *high)
|
||||
{
|
||||
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
DBADDR *paddr = &chan->addr;
|
||||
struct buffer {
|
||||
DBRctrlDouble
|
||||
double value;
|
||||
@@ -222,7 +255,8 @@ static long dbDbGetControlLimits(const struct link *plink, double *low,
|
||||
static long dbDbGetGraphicLimits(const struct link *plink, double *low,
|
||||
double *high)
|
||||
{
|
||||
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
DBADDR *paddr = &chan->addr;
|
||||
struct buffer {
|
||||
DBRgrDouble
|
||||
double value;
|
||||
@@ -243,7 +277,8 @@ static long dbDbGetGraphicLimits(const struct link *plink, double *low,
|
||||
static long dbDbGetAlarmLimits(const struct link *plink, double *lolo,
|
||||
double *low, double *high, double *hihi)
|
||||
{
|
||||
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
DBADDR *paddr = &chan->addr;
|
||||
struct buffer {
|
||||
DBRalDouble
|
||||
double value;
|
||||
@@ -265,7 +300,8 @@ static long dbDbGetAlarmLimits(const struct link *plink, double *lolo,
|
||||
|
||||
static long dbDbGetPrecision(const struct link *plink, short *precision)
|
||||
{
|
||||
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
DBADDR *paddr = &chan->addr;
|
||||
struct buffer {
|
||||
DBRprecision
|
||||
double value;
|
||||
@@ -284,7 +320,8 @@ static long dbDbGetPrecision(const struct link *plink, short *precision)
|
||||
|
||||
static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize)
|
||||
{
|
||||
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
DBADDR *paddr = &chan->addr;
|
||||
struct buffer {
|
||||
DBRunits
|
||||
double value;
|
||||
@@ -304,20 +341,20 @@ static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize)
|
||||
static long dbDbGetAlarm(const struct link *plink, epicsEnum16 *status,
|
||||
epicsEnum16 *severity)
|
||||
{
|
||||
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
|
||||
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
dbCommon *precord = dbChannelRecord(chan);
|
||||
if (status)
|
||||
*status = paddr->precord->stat;
|
||||
*status = precord->stat;
|
||||
if (severity)
|
||||
*severity = paddr->precord->sevr;
|
||||
*severity = precord->sevr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long dbDbGetTimeStamp(const struct link *plink, epicsTimeStamp *pstamp)
|
||||
{
|
||||
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
|
||||
|
||||
*pstamp = paddr->precord->time;
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
dbCommon *precord = dbChannelRecord(chan);
|
||||
*pstamp = precord->time;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -325,9 +362,10 @@ static long dbDbPutValue(struct link *plink, short dbrType,
|
||||
const void *pbuffer, long nRequest)
|
||||
{
|
||||
struct pv_link *ppv_link = &plink->value.pv_link;
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
struct dbCommon *psrce = plink->precord;
|
||||
DBADDR *paddr = (DBADDR *) ppv_link->pvt;
|
||||
dbCommon *pdest = paddr->precord;
|
||||
DBADDR *paddr = &chan->addr;
|
||||
dbCommon *pdest = dbChannelRecord(chan);
|
||||
long status = dbPut(paddr, dbrType, pbuffer, nRequest);
|
||||
|
||||
recGblInheritSevr(ppv_link->pvlMask & pvlOptMsMode, pdest, psrce->nsta,
|
||||
@@ -335,7 +373,7 @@ static long dbDbPutValue(struct link *plink, short dbrType,
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (paddr->pfield == (void *) &pdest->proc ||
|
||||
if (dbChannelField(chan) == (void *) &pdest->proc ||
|
||||
(ppv_link->pvlMask & pvlOptPP && pdest->scan == 0)) {
|
||||
status = processTarget(psrce, pdest);
|
||||
}
|
||||
@@ -346,9 +384,8 @@ static long dbDbPutValue(struct link *plink, short dbrType,
|
||||
static void dbDbScanFwdLink(struct link *plink)
|
||||
{
|
||||
dbCommon *precord = plink->precord;
|
||||
dbAddr *paddr = (dbAddr *) plink->value.pv_link.pvt;
|
||||
|
||||
dbScanPassive(precord, paddr->precord);
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
dbScanPassive(precord, dbChannelRecord(chan));
|
||||
}
|
||||
|
||||
static long doLocked(struct link *plink, dbLinkUserCallback rtn, void *priv)
|
||||
|
||||
@@ -27,7 +27,7 @@ struct dbLocker;
|
||||
|
||||
epicsShareFunc long dbDbInitLink(struct link *plink, short dbfType);
|
||||
epicsShareFunc void dbDbAddLink(struct dbLocker *locker, struct link *plink,
|
||||
short dbfType, DBADDR *ptarget);
|
||||
short dbfType, dbChannel *ptarget);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -252,18 +252,15 @@ int dbel ( const char *pname, unsigned level )
|
||||
}
|
||||
|
||||
/*
|
||||
* DB_INIT_EVENTS()
|
||||
* DB_INIT_EVENT_FREELISTS()
|
||||
*
|
||||
*
|
||||
* Initialize the event facility for this task. Must be called at least once
|
||||
* by each task which uses the db event facility
|
||||
* Initialize the free lists used by the event facility.
|
||||
* Safe to be called multiple times.
|
||||
*
|
||||
* returns: ptr to event user block or NULL if memory can't be allocated
|
||||
*/
|
||||
dbEventCtx db_init_events (void)
|
||||
void db_init_event_freelists (void)
|
||||
{
|
||||
struct event_user * evUser;
|
||||
|
||||
if (!dbevEventUserFreeList) {
|
||||
freeListInitPvt(&dbevEventUserFreeList,
|
||||
sizeof(struct event_user),8);
|
||||
@@ -280,6 +277,22 @@ dbEventCtx db_init_events (void)
|
||||
freeListInitPvt(&dbevFieldLogFreeList,
|
||||
sizeof(struct db_field_log),2048);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* DB_INIT_EVENTS()
|
||||
*
|
||||
*
|
||||
* Initialize the event facility for this task. Must be called at least once
|
||||
* by each task which uses the db event facility
|
||||
*
|
||||
* returns: ptr to event user block or NULL if memory can't be allocated
|
||||
*/
|
||||
dbEventCtx db_init_events (void)
|
||||
{
|
||||
struct event_user * evUser;
|
||||
|
||||
db_init_event_freelists();
|
||||
|
||||
evUser = (struct event_user *)
|
||||
freeListCalloc(dbevEventUserFreeList);
|
||||
@@ -1048,7 +1061,11 @@ static void event_task (void *pParm)
|
||||
epicsEventDestroy(evUser->pflush_sem);
|
||||
epicsMutexDestroy(evUser->lock);
|
||||
|
||||
freeListFree(dbevEventUserFreeList, evUser);
|
||||
if (dbevEventUserFreeList)
|
||||
freeListFree(dbevEventUserFreeList, evUser);
|
||||
else
|
||||
fprintf(stderr, "%s exiting but dbevEventUserFreeList already NULL\n",
|
||||
__FUNCTION__);
|
||||
|
||||
taskwdRemove(epicsThreadGetIdSelf());
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ epicsShareFunc void db_event_change_priority ( dbEventCtx ctx, unsigned epicsPri
|
||||
|
||||
#ifdef EPICS_PRIVATE_API
|
||||
epicsShareFunc void db_cleanup_events(void);
|
||||
epicsShareFunc void db_init_event_freelists (void);
|
||||
#endif
|
||||
|
||||
typedef void EVENTFUNC (void *user_arg, struct dbChannel *chan,
|
||||
|
||||
@@ -144,7 +144,7 @@ void dbInitLink(struct link *plink, short dbfType)
|
||||
}
|
||||
|
||||
void dbAddLink(struct dbLocker *locker, struct link *plink, short dbfType,
|
||||
DBADDR *ptarget)
|
||||
dbChannel *ptarget)
|
||||
{
|
||||
struct dbCommon *precord = plink->precord;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "epicsTypes.h"
|
||||
#include "epicsTime.h"
|
||||
#include "dbAddr.h"
|
||||
#include "dbChannel.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -369,7 +370,7 @@ epicsShareFunc const char * dbLinkFieldName(const struct link *plink);
|
||||
|
||||
epicsShareFunc void dbInitLink(struct link *plink, short dbfType);
|
||||
epicsShareFunc void dbAddLink(struct dbLocker *locker, struct link *plink,
|
||||
short dbfType, DBADDR *ptarget);
|
||||
short dbfType, dbChannel *ptarget);
|
||||
|
||||
epicsShareFunc void dbLinkOpen(struct link *plink);
|
||||
epicsShareFunc void dbRemoveLink(struct dbLocker *locker, struct link *plink);
|
||||
|
||||
@@ -743,14 +743,14 @@ void dbLockSetSplit(dbLocker *locker, dbCommon *pfirst, dbCommon *psecond)
|
||||
for(i=0; i<rtype->no_links; i++) {
|
||||
dbFldDes *pdesc = rtype->papFldDes[rtype->link_ind[i]];
|
||||
DBLINK *plink = (DBLINK*)((char*)prec + pdesc->offset);
|
||||
DBADDR *ptarget;
|
||||
dbChannel *chan;
|
||||
lockRecord *lr;
|
||||
|
||||
if(plink->type!=DB_LINK)
|
||||
continue;
|
||||
|
||||
ptarget = plink->value.pv_link.pvt;
|
||||
lr = ptarget->precord->lset;
|
||||
chan = plink->value.pv_link.pvt;
|
||||
lr = dbChannelRecord(chan)->lset;
|
||||
assert(lr);
|
||||
|
||||
if(lr->precord==pfirst) {
|
||||
|
||||
@@ -1076,13 +1076,10 @@ static void addToList(struct dbCommon *precord, scan_list *psl)
|
||||
pse->pscan_list = psl;
|
||||
ptemp = (scan_element *)ellLast(&psl->list);
|
||||
while (ptemp) {
|
||||
if (ptemp->precord->phas <= precord->phas) {
|
||||
ellInsert(&psl->list, &ptemp->node, &pse->node);
|
||||
break;
|
||||
}
|
||||
if (ptemp->precord->phas <= precord->phas) break;
|
||||
ptemp = (scan_element *)ellPrevious(&ptemp->node);
|
||||
}
|
||||
if (ptemp == NULL) ellAdd(&psl->list, (void *)pse);
|
||||
ellInsert(&psl->list, (ptemp ? &ptemp->node : NULL), &pse->node);
|
||||
psl->modified = TRUE;
|
||||
epicsMutexUnlock(psl->lock);
|
||||
}
|
||||
@@ -1108,7 +1105,7 @@ static void deleteFromList(struct dbCommon *precord, scan_list *psl)
|
||||
return;
|
||||
}
|
||||
pse->pscan_list = NULL;
|
||||
ellDelete(&psl->list, (void *)pse);
|
||||
ellDelete(&psl->list, &pse->node);
|
||||
psl->modified = TRUE;
|
||||
epicsMutexUnlock(psl->lock);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "recGbl.h"
|
||||
#include "recSup.h"
|
||||
#include "special.h"
|
||||
#include "dbConvertJSON.h"
|
||||
|
||||
#define MAXLINE 80
|
||||
#define MAXMESS 128
|
||||
@@ -364,8 +365,9 @@ long dbpf(const char *pname,const char *pvalue)
|
||||
{
|
||||
DBADDR addr;
|
||||
long status;
|
||||
short dbrType;
|
||||
size_t n = 1;
|
||||
short dbrType = DBR_STRING;
|
||||
long n = 1;
|
||||
char *array = NULL;
|
||||
|
||||
if (!pname || !*pname || !pvalue) {
|
||||
printf("Usage: dbpf \"pv name\", \"value\"\n");
|
||||
@@ -380,16 +382,25 @@ long dbpf(const char *pname,const char *pvalue)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (addr.no_elements > 1 &&
|
||||
(addr.dbr_field_type == DBR_CHAR || addr.dbr_field_type == DBR_UCHAR)) {
|
||||
if (addr.no_elements > 1) {
|
||||
dbrType = addr.dbr_field_type;
|
||||
n = strlen(pvalue) + 1;
|
||||
if (addr.dbr_field_type == DBR_CHAR || addr.dbr_field_type == DBR_UCHAR) {
|
||||
n = (long)strlen(pvalue) + 1;
|
||||
} else {
|
||||
n = addr.no_elements;
|
||||
array = calloc(n, dbValueSize(dbrType));
|
||||
if (!array) {
|
||||
printf("Out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
status = dbPutConvertJSON(pvalue, dbrType, array, &n);
|
||||
if (status)
|
||||
return status;
|
||||
pvalue = array;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dbrType = DBR_STRING;
|
||||
}
|
||||
|
||||
status = dbPutField(&addr, dbrType, pvalue, (long) n);
|
||||
status = dbPutField(&addr, dbrType, pvalue, n);
|
||||
free(array);
|
||||
dbgf(pname);
|
||||
return status;
|
||||
}
|
||||
@@ -943,13 +954,13 @@ static void printBuffer(
|
||||
}
|
||||
|
||||
/* Now print values */
|
||||
if (no_elements == 0)
|
||||
return;
|
||||
|
||||
if (no_elements == 1)
|
||||
sprintf(pmsg, "DBF_%s: ", dbr[dbr_type]);
|
||||
else
|
||||
else {
|
||||
sprintf(pmsg, "DBF_%s[%ld]: ", dbr[dbr_type], no_elements);
|
||||
if (no_elements == 0)
|
||||
strcat(pmsg, "(empty)");
|
||||
}
|
||||
dbpr_msgOut(pMsgBuff, tab_size);
|
||||
|
||||
if (status != 0) {
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "initHooks.h"
|
||||
#include "iocInit.h"
|
||||
#include "errSymTbl.h"
|
||||
#include "iocshRegisterCommon.h"
|
||||
|
||||
static dbEventCtx testEvtCtx;
|
||||
static epicsMutexId testEvtLock;
|
||||
@@ -98,6 +99,7 @@ void testdbCleanup(void)
|
||||
db_cleanup_events();
|
||||
initHookFree();
|
||||
registryFree();
|
||||
clearRegistrarOnce();
|
||||
pdbbase = NULL;
|
||||
dbmfFreeChunks();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
=head1 Menu menuIvoa
|
||||
|
||||
This menu specifies the possibile actions to take when the INVALID alarm is
|
||||
This menu specifies the possible actions to take when the INVALID alarm is
|
||||
triggered. See individual record types for more information.
|
||||
|
||||
=menu menuIvoa
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
menu(menuPini) {
|
||||
choice(menuPiniNO,"NO")
|
||||
choice(menuPiniYES,"YES")
|
||||
choice(menuPiniRUN,"RUN")
|
||||
choice(menuPiniRUNNING,"RUNNING")
|
||||
choice(menuPiniPAUSE,"PAUSE")
|
||||
choice(menuPiniPAUSED,"PAUSED")
|
||||
}
|
||||
66
modules/database/src/ioc/db/menuPini.dbd.pod
Normal file
66
modules/database/src/ioc/db/menuPini.dbd.pod
Normal file
@@ -0,0 +1,66 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=head1 Menu menuPini
|
||||
|
||||
This menu defines the choices for the C<PINI> field, which controls whether
|
||||
and when each record should be processed during initialization or pausing
|
||||
of the IOC. Choices other than C<NO> cause record processing at the
|
||||
following initHook transitions:
|
||||
|
||||
=over 4
|
||||
|
||||
=item YES
|
||||
|
||||
C<initHookAfterScanInit> E<mdash> All records and links have been
|
||||
initialized but the scan threads and CA server are not running yet, nor
|
||||
have CA links been connected up. The initHook C<initHookAfterInitialProcess>
|
||||
immediately follows this procssing.
|
||||
|
||||
=item RUN
|
||||
|
||||
C<initHookAtIocRun> E<mdash> The C<iocRun()> routine has just been called,
|
||||
although not necessarily for the first time.
|
||||
|
||||
=item RUNNING
|
||||
|
||||
C<initHookAfterIocRunning> E<mdash> All remaining initializations have
|
||||
taken place, C<interruptAccept> is enabled, the scan threads and CA server
|
||||
are running and the IOC is processing records. CA links might not have
|
||||
finished connecting though, and sequence programs won't usually have been
|
||||
started yet.
|
||||
|
||||
=item PAUSE
|
||||
|
||||
C<initHookAtIocPause> E<mdash> The C<iocPause()> routine has just been
|
||||
called and the IOC is about to suspend operations.
|
||||
|
||||
=item PAUSED
|
||||
|
||||
C<initHookAfterIocPaused> E<mdash> The CA server, CA link operations and
|
||||
the scan threads have been paused and C<interruptAccept> disabled.
|
||||
|
||||
=back
|
||||
|
||||
Note that the order in which records that have the same C<PINI> value get
|
||||
processed can be controlled by setting their C<PHAS> field, which is honored
|
||||
for C<PINI> processing as well as for regular scanning.
|
||||
|
||||
=menu menuPini
|
||||
|
||||
=cut
|
||||
|
||||
menu(menuPini) {
|
||||
choice(menuPiniNO,"NO")
|
||||
choice(menuPiniYES,"YES")
|
||||
choice(menuPiniRUN,"RUN")
|
||||
choice(menuPiniRUNNING,"RUNNING")
|
||||
choice(menuPiniPAUSE,"PAUSE")
|
||||
choice(menuPiniPAUSED,"PAUSED")
|
||||
}
|
||||
@@ -5,6 +5,16 @@
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=head1 Menu menuPost
|
||||
|
||||
This menu is used by the long string record types to specify whether they
|
||||
should generate a monitor event only when their string value changes, or
|
||||
every time it gets written to even if the value is the same.
|
||||
|
||||
=menu menuPost
|
||||
|
||||
=cut
|
||||
|
||||
menu(menuPost) {
|
||||
choice(menuPost_OnChange, "On Change")
|
||||
choice(menuPost_Always, "Always")
|
||||
@@ -7,6 +7,20 @@
|
||||
# EPICS Base is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=head1 Menu menuPriority
|
||||
|
||||
This menu is used for the C<PRIO> field of all record types. It controls
|
||||
the relative priority of records scheduled with C<SCAN=Event> or
|
||||
C<SCAN=I/O Intr>, and also of records that use asynchronous completion.
|
||||
|
||||
=menu menuPriority
|
||||
|
||||
The number of priorities is set in various other places in the code too,
|
||||
so adding new entries to this menu will probably break the IOC build.
|
||||
|
||||
=cut
|
||||
|
||||
menu(menuPriority) {
|
||||
choice(menuPriorityLOW,"LOW")
|
||||
choice(menuPriorityMEDIUM,"MEDIUM")
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
newline "\n"
|
||||
backslash "\\"
|
||||
singlequote "'"
|
||||
doublequote "\""
|
||||
comment "#"
|
||||
whitespace [ \t\r\n]
|
||||
@@ -18,17 +19,30 @@ stringchar [^"\n\\]
|
||||
bareword [a-zA-Z0-9_\-+:.\[\]<>;]
|
||||
|
||||
punctuation [:,\[\]{}]
|
||||
normalchar [^"\\\0-\x1f]
|
||||
normalchar [^"'\\\0-\x1f]
|
||||
barechar [a-zA-Z0-9_\-+.]
|
||||
escapedchar ({backslash}["\\/bfnrt])
|
||||
escapedchar ({backslash}[^ux1-9])
|
||||
hexdigit [0-9a-fA-F]
|
||||
latinchar ({backslash}"x"{hexdigit}{2})
|
||||
unicodechar ({backslash}"u"{hexdigit}{4})
|
||||
jsonchar ({normalchar}|{escapedchar}|{unicodechar})
|
||||
jsondqstr ({doublequote}{jsonchar}*{doublequote})
|
||||
int ("-"?([0-9]|[1-9][0-9]+))
|
||||
jsondqchar ({normalchar}|{singlequote}|{escapedchar}|{latinchar}|{unicodechar})
|
||||
jsondqstr ({doublequote}{jsondqchar}*{doublequote})
|
||||
jsonsqchar ({normalchar}|{doublequote}|{escapedchar}|{latinchar}|{unicodechar})
|
||||
jsonsqstr ({singlequote}{jsonsqchar}*{singlequote})
|
||||
jsonstr ({jsondqstr}|{jsonsqstr})
|
||||
|
||||
sign ([+-]?)
|
||||
int ({sign}([0-9]|[1-9][0-9]+))
|
||||
frac ("."[0-9]+)
|
||||
exp ([eE][+-]?[0-9]+)
|
||||
number ({int}{frac}?{exp}?)
|
||||
exp ([eE]{sign}[0-9]+)
|
||||
jsonnum ({int}{frac}?{exp}?)
|
||||
intexp ({int}"."{exp}?)
|
||||
fracexp ({sign}{frac}{exp}?)
|
||||
specialnum ("NaN"|{sign}"Infinity")
|
||||
|
||||
zerox ("0x"|"0X")
|
||||
hexint ({sign}{zerox}{hexdigit}+)
|
||||
number ({jsonnum}|{intexp}|{fracexp}|{specialnum}|{hexint})
|
||||
|
||||
%{
|
||||
#undef YY_INPUT
|
||||
@@ -97,7 +111,7 @@ static int yyreset(void)
|
||||
|
||||
<JSON>{punctuation} return yytext[0];
|
||||
|
||||
<JSON>{jsondqstr} {
|
||||
<JSON>{jsonstr} {
|
||||
yylval.Str = dbmfStrdup((char *) yytext);
|
||||
return jsonSTRING;
|
||||
}
|
||||
|
||||
@@ -1172,19 +1172,22 @@ static void dbRecordField(char *name,char *value)
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
if (*value == '"') {
|
||||
|
||||
if (*value == '"' || *value == '\'') {
|
||||
/* jsonSTRING values still have their quotes */
|
||||
value++;
|
||||
value[strlen(value) - 1] = 0;
|
||||
dbTranslateEscape(value, value); /* in-place; safe & legal */
|
||||
}
|
||||
dbTranslateEscape(value, value); /* in-place; safe & legal */
|
||||
|
||||
status = dbPutString(pdbentry,value);
|
||||
if (status) {
|
||||
char msg[128];
|
||||
|
||||
errSymLookup(status, msg, sizeof(msg));
|
||||
epicsPrintf("Can't set \"%s.%s\" to \"%s\" %s\n",
|
||||
dbGetRecordName(pdbentry), name, value, msg);
|
||||
epicsPrintf("Can't set \"%s.%s\" to \"%s\" %s : %s\n",
|
||||
dbGetRecordName(pdbentry), name, value, pdbentry->message ? pdbentry->message : "", msg);
|
||||
dbPutStringSuggest(pdbentry, value);
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
@@ -1203,12 +1206,14 @@ static void dbRecordInfo(char *name, char *value)
|
||||
if (duplicate) return;
|
||||
ptempListNode = (tempListNode *)ellFirst(&tempList);
|
||||
pdbentry = ptempListNode->item;
|
||||
if (*value == '"') {
|
||||
|
||||
if (*value == '"' || *value == '\'') {
|
||||
/* jsonSTRING values still have their quotes */
|
||||
value++;
|
||||
value[strlen(value) - 1] = 0;
|
||||
dbTranslateEscape(value, value); /* in-place; safe & legal */
|
||||
}
|
||||
dbTranslateEscape(value, value); /* yuck: in-place, but safe */
|
||||
|
||||
status = dbPutInfo(pdbentry,name,value);
|
||||
if (status) {
|
||||
epicsPrintf("Can't set \"%s\" info \"%s\" to \"%s\"\n",
|
||||
|
||||
@@ -81,8 +81,6 @@ maplinkType pamaplinkType[LINK_NTYPES] = {
|
||||
};
|
||||
|
||||
/*forward references for private routines*/
|
||||
static void dbMsgPrint(DBENTRY *pdbentry, const char *fmt, ...)
|
||||
EPICS_PRINTF_STYLE(2,3);
|
||||
static long dbAddOnePath (DBBASE *pdbbase, const char *path, unsigned length);
|
||||
|
||||
/* internal routines*/
|
||||
@@ -199,7 +197,6 @@ void dbMsgNCpy(DBENTRY *pdbentry, const char *msg, size_t len)
|
||||
pdbentry->message[len] = '\0';
|
||||
}
|
||||
|
||||
static
|
||||
void dbMsgPrint(DBENTRY *pdbentry, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
@@ -2331,8 +2328,7 @@ long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
|
||||
}
|
||||
|
||||
/* Link may be an array constant */
|
||||
if (pstr[0] == '[' && pstr[len-1] == ']' &&
|
||||
(strchr(pstr, ',') || strchr(pstr, '"'))) {
|
||||
if (pstr[0] == '[' && pstr[len-1] == ']') {
|
||||
pinfo->ltype = CONSTANT;
|
||||
return 0;
|
||||
}
|
||||
@@ -2636,6 +2632,52 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
|
||||
return(status);
|
||||
}
|
||||
|
||||
void dbPutStringSuggest(DBENTRY *pdbentry, const char *pstring)
|
||||
{
|
||||
dbFldDes *pflddes = pdbentry->pflddes;
|
||||
|
||||
switch (pflddes->field_type) {
|
||||
case DBF_MENU:
|
||||
case DBF_DEVICE: {
|
||||
int i, nchoices = 0;
|
||||
char** choices = NULL;
|
||||
const char *best = NULL;
|
||||
double maxdist = 0.0; /* don't offer suggestions which have no similarity */
|
||||
|
||||
if(pflddes->field_type==DBF_MENU) {
|
||||
dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt;
|
||||
if(!pdbMenu)
|
||||
return;
|
||||
|
||||
choices = pdbMenu->papChoiceValue;
|
||||
nchoices = pdbMenu->nChoice;
|
||||
|
||||
} else {
|
||||
dbDeviceMenu *pdbDeviceMenu = dbGetDeviceMenu(pdbentry);
|
||||
if(!pdbDeviceMenu)
|
||||
return;
|
||||
|
||||
choices = pdbDeviceMenu->papChoice;
|
||||
nchoices = pdbDeviceMenu->nChoice;
|
||||
}
|
||||
|
||||
for(i=0; i<nchoices; i++) {
|
||||
double dist = epicsStrSimilarity(pstring, choices[i]);
|
||||
if(dist>maxdist) {
|
||||
best = choices[i];
|
||||
maxdist = dist;
|
||||
}
|
||||
}
|
||||
if(best) {
|
||||
epicsPrintf(" Did you mean \"%s\"?\n", best);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char * dbVerify(DBENTRY *pdbentry, const char *pstring)
|
||||
{
|
||||
dbFldDes *pflddes = pdbentry->pflddes;
|
||||
|
||||
@@ -36,6 +36,10 @@ char *dbRecordName(DBENTRY *pdbentry);
|
||||
char *dbGetStringNum(DBENTRY *pdbentry);
|
||||
long dbPutStringNum(DBENTRY *pdbentry,const char *pstring);
|
||||
|
||||
void dbMsgPrint(DBENTRY *pdbentry, const char *fmt, ...) EPICS_PRINTF_STYLE(2,3);
|
||||
|
||||
void dbPutStringSuggest(DBENTRY *pdbentry, const char *pstring);
|
||||
|
||||
struct jlink;
|
||||
|
||||
typedef struct dbLinkInfo {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "dbCommonPvt.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "dbStaticPvt.h"
|
||||
#include "dbAccess.h"
|
||||
#include "devSup.h"
|
||||
#include "special.h"
|
||||
|
||||
@@ -479,8 +480,17 @@ long dbPutStringNum(DBENTRY *pdbentry, const char *pstring)
|
||||
epicsEnum16 value;
|
||||
long status = epicsParseUInt16(pstring, &value, 0, NULL);
|
||||
|
||||
if (status)
|
||||
if (status) {
|
||||
status = S_db_badChoice;
|
||||
if(pflddes->field_type==DBF_MENU) {
|
||||
dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt;
|
||||
dbMsgPrint(pdbentry, "using menu %s", pdbMenu->name);
|
||||
|
||||
} else if(pflddes->field_type==DBF_DEVICE) {
|
||||
dbMsgPrint(pdbentry, "no such device support for '%s' record type", pdbentry->precordType->name);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
index = dbGetNMenuChoices(pdbentry);
|
||||
if (value > index && index > 0 && value < USHRT_MAX)
|
||||
|
||||
@@ -32,8 +32,8 @@ static int yyAbort = 0;
|
||||
|
||||
%token jsonNULL jsonTRUE jsonFALSE
|
||||
%token <Str> jsonNUMBER jsonSTRING jsonBARE
|
||||
%type <Str> json_value json_object json_array
|
||||
%type <Str> json_members json_pair json_elements json_string
|
||||
%type <Str> json_value json_string json_object json_array
|
||||
%type <Str> json_members json_pair json_key json_elements
|
||||
|
||||
%%
|
||||
|
||||
@@ -299,13 +299,24 @@ json_members: json_pair
|
||||
if (dbStaticDebug>2) printf("json %s\n", $$);
|
||||
};
|
||||
|
||||
json_pair: json_string ':' json_value
|
||||
json_pair: json_key ':' json_value
|
||||
{
|
||||
$$ = dbmfStrcat3($1, ":", $3);
|
||||
dbmfFree($1); dbmfFree($3);
|
||||
if (dbStaticDebug>2) printf("json %s\n", $$);
|
||||
};
|
||||
|
||||
json_key: jsonSTRING
|
||||
| jsonBARE
|
||||
{
|
||||
/* A key containing any of these characters must be quoted for YAJL */
|
||||
if (strcspn($1, "+-.") < strlen($1)) {
|
||||
$$ = dbmfStrcat3("\"", $1, "\"");
|
||||
dbmfFree($1);
|
||||
}
|
||||
if (dbStaticDebug>2) printf("json %s\n", $$);
|
||||
};
|
||||
|
||||
json_string: jsonSTRING
|
||||
| jsonBARE
|
||||
{
|
||||
|
||||
@@ -25,5 +25,6 @@ dbCore_SRCS += iocInit.c
|
||||
dbCore_SRCS += miscIocRegister.c
|
||||
dbCore_SRCS += dlload.c
|
||||
dbCore_SRCS += iocshRegisterCommon.c
|
||||
dbCore_SRCS += registerAllRecordDeviceDrivers.cpp
|
||||
|
||||
miscIocRegister_CFLAGS_iOS = -DSYSTEM_UNAVAILABLE
|
||||
|
||||
@@ -26,6 +26,16 @@
|
||||
#define quote(v) #v
|
||||
#define str(v) quote(v)
|
||||
|
||||
/* registerAllRecordDeviceDrivers */
|
||||
static const iocshArg rrddArg0 = {"pdbbase", iocshArgPdbbase};
|
||||
static const iocshArg *rrddArgs[] = {&rrddArg0};
|
||||
static const iocshFuncDef rrddFuncDef =
|
||||
{"registerAllRecordDeviceDrivers", 1, rrddArgs};
|
||||
static void rrddCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
iocshSetError(registerAllRecordDeviceDrivers(*iocshPpdbbase));
|
||||
}
|
||||
|
||||
void iocshRegisterCommon(void)
|
||||
{
|
||||
const char *targetArch = envGetConfigParamPtr(&EPICS_BUILD_TARGET_ARCH);
|
||||
@@ -53,4 +63,5 @@ void iocshRegisterCommon(void)
|
||||
asIocRegister();
|
||||
miscIocRegister();
|
||||
libComRegister();
|
||||
iocshRegister(&rrddFuncDef, rrddCallFunc);
|
||||
}
|
||||
|
||||
@@ -19,9 +19,25 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dbBase;
|
||||
|
||||
/* register many useful commands */
|
||||
epicsShareFunc void iocshRegisterCommon(void);
|
||||
|
||||
#define HAS_registerAllRecordDeviceDrivers
|
||||
|
||||
epicsShareFunc
|
||||
long
|
||||
registerAllRecordDeviceDrivers(struct dbBase *pdbbase);
|
||||
|
||||
epicsShareFunc
|
||||
void runRegistrarOnce(void (*reg_func)(void));
|
||||
|
||||
#ifdef EPICS_PRIVATE_API
|
||||
epicsShareFunc
|
||||
void clearRegistrarOnce(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
255
modules/database/src/ioc/misc/registerAllRecordDeviceDrivers.cpp
Normal file
255
modules/database/src/ioc/misc/registerAllRecordDeviceDrivers.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2020 Michael Davidsaver
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define EPICS_PRIVATE_API
|
||||
|
||||
#include <iocsh.h>
|
||||
|
||||
#include <epicsStdio.h>
|
||||
#include <epicsFindSymbol.h>
|
||||
#define epicsExportSharedSymbols
|
||||
#include <registryRecordType.h>
|
||||
#include <registryDeviceSupport.h>
|
||||
#include <registryDriverSupport.h>
|
||||
#include <iocshRegisterCommon.h>
|
||||
#include <registryCommon.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbBase.h>
|
||||
#include <dbStaticLib.h>
|
||||
|
||||
namespace {
|
||||
|
||||
struct compareLoc {
|
||||
bool operator()(const recordTypeLocation& lhs, const recordTypeLocation& rhs) const
|
||||
{
|
||||
if(lhs.prset<rhs.prset)
|
||||
return true;
|
||||
else if(lhs.prset>rhs.prset)
|
||||
return false;
|
||||
return lhs.sizeOffset<rhs.sizeOffset;
|
||||
}
|
||||
};
|
||||
|
||||
// storage which will be referenced by pdbbase. Must never be free'd
|
||||
std::set<std::string> names;
|
||||
std::set<recordTypeLocation, compareLoc> reclocs;
|
||||
|
||||
template<typename T, typename Y>
|
||||
const T& intern(std::set<T,Y>& coll, const T& val)
|
||||
{
|
||||
return *coll.insert(val).first;
|
||||
}
|
||||
|
||||
std::set<void*> registrarsRun;
|
||||
|
||||
// gcc circa 4.4 doesn't like iocshVarDef[2] as mapped_type
|
||||
struct varDef {
|
||||
iocshVarDef def[2];
|
||||
};
|
||||
typedef std::map<std::string, varDef> vardefs_t;
|
||||
vardefs_t vardefs;
|
||||
|
||||
template<typename T>
|
||||
T lookupAs(const char* a, const char* b =0, const char* c =0, const char* d =0)
|
||||
{
|
||||
std::string name(a);
|
||||
if(b)
|
||||
name += b;
|
||||
if(c)
|
||||
name += c;
|
||||
if(d)
|
||||
name += d;
|
||||
|
||||
T ret = (T)epicsFindSymbol(name.c_str());
|
||||
if(!ret) {
|
||||
fprintf(stderr, "Unable to find symbol '%s' : %s\n", name.c_str(), epicsLoadError());
|
||||
// all pvar_* are pointers to the exported object
|
||||
} else if(ret && !*ret) {
|
||||
fprintf(stderr, "symbol '%s' holds NULL\n", name.c_str());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void runRegistrarOnce(void (*reg_func)(void))
|
||||
{
|
||||
if(registrarsRun.find((void*)reg_func)!=registrarsRun.end())
|
||||
return;
|
||||
|
||||
registrarsRun.insert((void*)reg_func);
|
||||
|
||||
reg_func();
|
||||
}
|
||||
|
||||
void clearRegistrarOnce()
|
||||
{
|
||||
registrarsRun.clear();
|
||||
}
|
||||
|
||||
long
|
||||
registerAllRecordDeviceDrivers(DBBASE *pdbbase)
|
||||
{
|
||||
DBENTRY entry;
|
||||
|
||||
if(!pdbbase) {
|
||||
fprintf(stderr, "Must call dbLoadRecords() before registerAllRecordDeviceDrivers(pdbbase)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
dbInitEntry(pdbbase, &entry);
|
||||
try {
|
||||
// for each recordType
|
||||
for(long status=dbFirstRecordType(&entry); !status; status=dbNextRecordType(&entry)) {
|
||||
dbRecordType *rtype = entry.precordType;
|
||||
|
||||
if(!registryRecordTypeFind(rtype->name)) {
|
||||
|
||||
rset** prset = lookupAs<rset**>("pvar_rset_", rtype->name, "RSET");
|
||||
computeSizeOffset* sizeOffset = lookupAs<computeSizeOffset*>("pvar_func_", rtype->name, "RecordSizeOffset");
|
||||
|
||||
if(!prset || !*prset || !sizeOffset || !*sizeOffset) {
|
||||
fprintf(stderr, "Unable to find support for record type '%s' : %s\n",
|
||||
rtype->name, epicsLoadError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
recordTypeLocation sup;
|
||||
sup.prset = *prset;
|
||||
sup.sizeOffset = *sizeOffset;
|
||||
|
||||
const char *cname = intern<std::string>(names, rtype->name).c_str();
|
||||
const recordTypeLocation* csup = &intern<recordTypeLocation>(reclocs, sup);
|
||||
registerRecordTypes(pdbbase, 1, &cname, csup);
|
||||
}
|
||||
|
||||
// for each device support for this recordType
|
||||
for(ELLNODE *cur = ellFirst(&rtype->devList); cur; cur = ellNext(cur)) {
|
||||
devSup& devsup = *CONTAINER(cur, devSup, node);
|
||||
|
||||
if(registryDeviceSupportFind(devsup.name))
|
||||
continue;
|
||||
|
||||
dset** ptr = lookupAs<dset**>("pvar_dset_", devsup.name);
|
||||
|
||||
if(!ptr || !*ptr) {
|
||||
fprintf(stderr, "Unable to find dset for record type '%s' support '%s' : %s\n",
|
||||
rtype->name, devsup.name, epicsLoadError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *cname = intern<std::string>(names, devsup.name).c_str();
|
||||
registerDevices(pdbbase, 1, &cname, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
// for each driver
|
||||
for(ELLNODE *cur = ellFirst(&pdbbase->drvList); cur; cur = ellNext(cur)) {
|
||||
drvSup& drv = *CONTAINER(cur, drvSup, node);
|
||||
|
||||
if(registryDriverSupportFind(drv.name))
|
||||
continue;
|
||||
|
||||
drvet** ptr = lookupAs<drvet**>("pvar_drvet_", drv.name);
|
||||
|
||||
if(!ptr || !*ptr) {
|
||||
fprintf(stderr, "Unable to find drvet '%s' : %s\n", drv.name, epicsLoadError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *cname = intern<std::string>(names, drv.name).c_str();
|
||||
registerDrivers(pdbbase, 1, &cname, ptr);
|
||||
}
|
||||
|
||||
// for each link support
|
||||
for(ELLNODE *cur = ellFirst(&pdbbase->linkList); cur; cur = ellNext(cur)) {
|
||||
linkSup& lnk = *CONTAINER(cur, linkSup, node);
|
||||
|
||||
jlif** ptr = lookupAs<jlif**>("pvar_jlif_", lnk.jlif_name);
|
||||
|
||||
if(!ptr || !*ptr) {
|
||||
fprintf(stderr, "Unable to find link support '%s' : %s\n", lnk.jlif_name, epicsLoadError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
registerJLinks(pdbbase, 1, ptr);
|
||||
}
|
||||
|
||||
// for each function()
|
||||
for(ELLNODE *cur = ellFirst(&pdbbase->functionList); cur; cur = ellNext(cur)) {
|
||||
dbText& reg = *CONTAINER(cur, dbText, node);
|
||||
|
||||
typedef void(*registrar)(void);
|
||||
registrar* ptr = lookupAs<registrar*>("pvar_func_register_func_", reg.text);
|
||||
|
||||
if(!ptr || !*ptr) {
|
||||
fprintf(stderr, "Unable to find function '%s' : %s\n", reg.text, epicsLoadError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
runRegistrarOnce(*ptr);
|
||||
}
|
||||
|
||||
// for each registrar()
|
||||
for(ELLNODE *cur = ellFirst(&pdbbase->registrarList); cur; cur = ellNext(cur)) {
|
||||
dbText& reg = *CONTAINER(cur, dbText, node);
|
||||
|
||||
typedef void(*registrar)(void);
|
||||
registrar* ptr = lookupAs<registrar*>("pvar_func_", reg.text);
|
||||
|
||||
if(!ptr || !*ptr) {
|
||||
fprintf(stderr, "Unable to find registrar '%s' : %s\n", reg.text, epicsLoadError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
runRegistrarOnce(*ptr);
|
||||
}
|
||||
|
||||
// for each iocsh variable
|
||||
for(ELLNODE *cur = ellFirst(&pdbbase->variableList); cur; cur = ellNext(cur)) {
|
||||
dbVariableDef& var = *CONTAINER(cur, dbVariableDef, node);
|
||||
|
||||
if(iocshFindVariable(var.name))
|
||||
continue;
|
||||
|
||||
void** ptr = lookupAs<void**>("pvar_", var.type, "_", var.name);
|
||||
|
||||
if(!ptr || !*ptr) {
|
||||
fprintf(stderr, "Unable to find variable '%s' : %s\n", var.name, epicsLoadError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
vardefs_t::mapped_type& vdef = vardefs[var.name];
|
||||
vdef.def[0].name = intern<std::string>(names, var.name).c_str();
|
||||
vdef.def[0].pval = *ptr;
|
||||
if(strcmp(var.type, "double")==0) {
|
||||
vdef.def[0].type = iocshArgDouble;
|
||||
} else if(strcmp(var.type, "int")==0) {
|
||||
vdef.def[0].type = iocshArgInt;
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported type %s of variable '%s' : %s\n", var.type, var.name, epicsLoadError());
|
||||
return 1;
|
||||
}
|
||||
vdef.def[1].name = 0;
|
||||
iocshRegisterVariable(vdef.def);
|
||||
}
|
||||
|
||||
dbFinishEntry(&entry);
|
||||
return 0;
|
||||
|
||||
} catch(std::exception& e) {
|
||||
dbFinishEntry(&entry);
|
||||
fprintf(stderr, "Error: %s\n", e.what());
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@@ -47,23 +47,20 @@ static long init_record(dbCommon *pcommon)
|
||||
aaiRecord *prec = (aaiRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
|
||||
/* This is pass 0, link hasn't been initialized yet */
|
||||
dbInitLink(plink, DBF_INLINK);
|
||||
/* Ask record to call us in pass 1 instead */
|
||||
if (prec->pact != AAI_DEVINIT_PASS1) {
|
||||
return AAI_DEVINIT_PASS1;
|
||||
}
|
||||
|
||||
if (dbLinkIsConstant(plink)) {
|
||||
long nRequest = prec->nelm;
|
||||
long status;
|
||||
|
||||
/* Allocate a buffer, record support hasn't done that yet */
|
||||
if (!prec->bptr) {
|
||||
prec->bptr = callocMustSucceed(nRequest, dbValueSize(prec->ftvl),
|
||||
"devAaiSoft: buffer calloc failed");
|
||||
}
|
||||
|
||||
status = dbLoadLinkArray(plink, prec->ftvl, prec->bptr, &nRequest);
|
||||
if (!status && nRequest > 0) {
|
||||
if (!status) {
|
||||
prec->nord = nRequest;
|
||||
prec->udf = FALSE;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -75,7 +72,7 @@ static long readLocked(struct link *pinp, void *dummy)
|
||||
long nRequest = prec->nelm;
|
||||
long status = dbGetLink(pinp, prec->ftvl, prec->bptr, 0, &nRequest);
|
||||
|
||||
if (!status && nRequest > 0) {
|
||||
if (!status) {
|
||||
prec->nord = nRequest;
|
||||
prec->udf = FALSE;
|
||||
|
||||
@@ -90,8 +87,12 @@ static long read_aai(aaiRecord *prec)
|
||||
{
|
||||
epicsUInt32 nord = prec->nord;
|
||||
struct link *pinp = prec->simm == menuYesNoYES ? &prec->siol : &prec->inp;
|
||||
long status = dbLinkDoLocked(pinp, readLocked, NULL);
|
||||
long status;
|
||||
|
||||
if (dbLinkIsConstant(pinp))
|
||||
return 0;
|
||||
|
||||
status = dbLinkDoLocked(pinp, readLocked, NULL);
|
||||
if (status == S_db_noLSET)
|
||||
status = readLocked(pinp, NULL);
|
||||
|
||||
|
||||
@@ -86,9 +86,10 @@ static long read_ai(aiRecord *prec)
|
||||
|
||||
prec->udf = FALSE;
|
||||
prec->dpvt = &devAiSoft; /* Any non-zero value */
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
prec->dpvt = NULL;
|
||||
|
||||
return 2;
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ static long init_record(dbCommon *pcommon)
|
||||
|
||||
status = dbLoadLinkArray(&prec->inp, prec->ftvl, prec->bptr, &nRequest);
|
||||
|
||||
if (!status && nRequest > 0)
|
||||
if (!status)
|
||||
subset(prec, nRequest);
|
||||
|
||||
return status;
|
||||
@@ -116,7 +116,7 @@ static long read_sa(subArrayRecord *prec)
|
||||
status = readLocked(&prec->inp, &rt);
|
||||
}
|
||||
|
||||
if (!status && rt.nRequest > 0) {
|
||||
if (!status) {
|
||||
subset(prec, rt.nRequest);
|
||||
|
||||
if (nord != prec->nord)
|
||||
|
||||
@@ -42,7 +42,7 @@ static long init_record(dbCommon *pcommon)
|
||||
long nelm = prec->nelm;
|
||||
long status = dbLoadLinkArray(&prec->inp, prec->ftvl, prec->bptr, &nelm);
|
||||
|
||||
if (!status && nelm > 0) {
|
||||
if (!status) {
|
||||
prec->nord = nelm;
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
@@ -78,11 +78,14 @@ static long read_wf(waveformRecord *prec)
|
||||
rt.ptime = (dbLinkIsConstant(&prec->tsel) &&
|
||||
prec->tse == epicsTimeEventDeviceTime) ? &prec->time : NULL;
|
||||
|
||||
if (dbLinkIsConstant(&prec->inp))
|
||||
return 0;
|
||||
|
||||
status = dbLinkDoLocked(&prec->inp, readLocked, &rt);
|
||||
if (status == S_db_noLSET)
|
||||
status = readLocked(&prec->inp, &rt);
|
||||
|
||||
if (!status && rt.nRequest > 0) {
|
||||
if (!status) {
|
||||
prec->nord = rt.nRequest;
|
||||
prec->udf = FALSE;
|
||||
if (nord != prec->nord)
|
||||
|
||||
@@ -489,8 +489,17 @@ static long lnkConst_loadArray(struct link *plink, short dbrType, void *pbuffer,
|
||||
case sc40:
|
||||
if (clink->jlink.debug)
|
||||
printf(" sc40 '%s'\n", clink->value.scalar_string);
|
||||
status = dbFastPutConvertRoutine[DBF_STRING][dbrType]
|
||||
(clink->value.scalar_string, pbuffer, NULL);
|
||||
if (dbrType != DBF_CHAR) {
|
||||
status = dbFastPutConvertRoutine[DBF_STRING][dbrType]
|
||||
(clink->value.scalar_string, pbuffer, NULL);
|
||||
}
|
||||
else {
|
||||
/* Long string conversion */
|
||||
strncpy(pbuffer, clink->value.scalar_string, *pnReq);
|
||||
((char *)pbuffer)[*pnReq] = 0;
|
||||
nElems = strlen(pbuffer) + 1;
|
||||
status = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ai64:
|
||||
|
||||
@@ -227,6 +227,7 @@ static long process(struct dbCommon *pcommon)
|
||||
return 0;
|
||||
|
||||
prec->pact = TRUE;
|
||||
recGblGetTimeStamp(prec);
|
||||
|
||||
/* Push the output link values */
|
||||
if (!status) {
|
||||
@@ -237,7 +238,6 @@ static long process(struct dbCommon *pcommon)
|
||||
(&prec->neva)[i]);
|
||||
}
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
monitor(prec);
|
||||
recGblFwdLink(prec);
|
||||
prec->pact = FALSE;
|
||||
@@ -278,10 +278,9 @@ static long fetch_values(aSubRecord *prec)
|
||||
long nRequest = (&prec->noa)[i];
|
||||
status = dbGetLink(&(&prec->inpa)[i], (&prec->fta)[i], (&prec->a)[i], 0,
|
||||
&nRequest);
|
||||
if (nRequest > 0)
|
||||
(&prec->nea)[i] = nRequest;
|
||||
if (status)
|
||||
return status;
|
||||
(&prec->nea)[i] = nRequest;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ The VAL field is set to the value returned by the user subroutine.
|
||||
The value is treated as an error status value where zero mean success.
|
||||
The output links OUTA ... OUTU will only be used to forward the associated
|
||||
output value fields when the subroutine has returned a zero status.
|
||||
If the return status was non-zero, the record will be put into C<SOFT_ALARM>
|
||||
If the return status was less than zero, the record will be put into C<SOFT_ALARM>
|
||||
state with severity given by the BRSV field.
|
||||
|
||||
The INAM field may be used to name a subroutine that will be called once at
|
||||
@@ -1363,7 +1363,7 @@ be sent through the OUTA ... OUTU links during record processing.
|
||||
The previous values of the output fields.
|
||||
These are used to determine when to post events if EFLG is set to C<ON CHANGE>.
|
||||
|
||||
=fields VALA, VALB, VALC, VALD, VALE, VALF, VALG, VALH, VALI, VALJ, VALK, VALL, VALM, VALN, VALO, VALP, VALQ, VALR, VALS, VALT, VALU
|
||||
=fields OVLA, OVLB, OVLC, OVLD, OVLE, OVLF, OVLG, OVLH, OVLI, OVLJ, OVLK, OVLL, OVLM, OVLN, OVLO, OVLP, OVLQ, OVLR, OVLS, OVLT, OVLU
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
@@ -112,16 +112,18 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
prec->ftvl = DBF_UCHAR;
|
||||
prec->nord = (prec->nelm == 1);
|
||||
|
||||
/* we must call pdset->init_record in pass 0
|
||||
because it may set prec->bptr which must
|
||||
not change after links are established before pass 1
|
||||
*/
|
||||
|
||||
/* call pdset->init_record() in pass 0 so it can do its own
|
||||
* memory allocation and set prec->bptr, which must be set by
|
||||
* the end of pass 0.
|
||||
*/
|
||||
if (pdset->common.init_record) {
|
||||
long status = pdset->common.init_record(pcommon);
|
||||
|
||||
/* init_record may set the bptr to point to the data */
|
||||
if (status)
|
||||
if (status == AAI_DEVINIT_PASS1) {
|
||||
/* requesting pass 1 callback, remember to do that */
|
||||
prec->pact = AAI_DEVINIT_PASS1;
|
||||
}
|
||||
else if (status)
|
||||
return status;
|
||||
}
|
||||
if (!prec->bptr) {
|
||||
@@ -132,6 +134,14 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (prec->pact == AAI_DEVINIT_PASS1) {
|
||||
/* device support asked for an init_record() callback in pass 1 */
|
||||
long status = pdset->common.init_record(pcommon);
|
||||
if (status)
|
||||
return status;
|
||||
prec->pact = FALSE;
|
||||
}
|
||||
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
/* must have read_aai function defined */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user