Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1c8303870 | ||
|
|
a3ef984f4f | ||
|
|
ca86a63180 | ||
|
|
07b79693af | ||
|
|
4ef9e18ac6 | ||
|
|
320cc3c60b | ||
|
|
45d0d76a7f | ||
|
|
b2b42d5f8c | ||
|
|
90b1f2f6da | ||
|
|
2e775ef2fb | ||
|
|
f17d2bbca1 | ||
|
|
79b02254c4 | ||
|
|
19245ce805 | ||
|
|
0fa927afa7 | ||
|
|
d9b3f98e35 | ||
|
|
81e7968230 | ||
|
|
06f3b96992 | ||
| 1038182a16 | |||
| 60091bfe56 | |||
| f4de6dd9b1 | |||
|
|
3d93a80cce | ||
|
|
94eff54fa9 | ||
|
|
e9dde4d2f8 | ||
|
|
0a5e22e5b0 | ||
|
|
3a5cfba4e1 | ||
|
|
07b75e4543 | ||
|
|
e4f150b34f | ||
|
|
ca2ae0d0e7 | ||
|
|
828506720c | ||
|
|
ad712b63f9 | ||
|
|
4c3d5a788d | ||
|
|
df89135455 | ||
|
|
95d452870c | ||
|
|
8a82ff9fe4 | ||
|
|
dd24b2ad75 | ||
|
|
17fa7a7724 | ||
|
|
d01ba94ed7 | ||
|
|
c7c7585950 | ||
|
|
f869936cfd | ||
|
|
0ad253c6f0 | ||
|
|
52d04d5044 | ||
|
|
bff2dc9cd2 | ||
|
|
b903df5d0d | ||
|
|
416d910577 | ||
|
|
37b7a0708f |
94
.appveyor.yml
Normal file
94
.appveyor.yml
Normal file
@@ -0,0 +1,94 @@
|
||||
# .appveyor.yml for use with EPICS Base ci-scripts
|
||||
# (see: https://github.com/epics-base/ci-scripts)
|
||||
|
||||
cache:
|
||||
- C:\Users\appveyor\.tools
|
||||
|
||||
#---------------------------------#
|
||||
# additional packages #
|
||||
#---------------------------------#
|
||||
|
||||
install:
|
||||
# for the sequencer
|
||||
- cinst re2c
|
||||
- cmd: git submodule update --init --recursive
|
||||
|
||||
#---------------------------------#
|
||||
# repository cloning #
|
||||
#---------------------------------#
|
||||
|
||||
init:
|
||||
# Set autocrlf to make batch files work
|
||||
- git config --global core.autocrlf true
|
||||
|
||||
clone_depth: 50
|
||||
|
||||
# Skipping commits affecting only specific files
|
||||
skip_commits:
|
||||
files:
|
||||
- 'documentation/*'
|
||||
- '**/*.md'
|
||||
|
||||
# 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
|
||||
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
CMP: vs2019
|
||||
BASE: 7.0
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
CMP: gcc
|
||||
BASE: 7.0
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
CMP: vs2017
|
||||
BASE: 7.0
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
CMP: vs2019
|
||||
BASE: 3.15
|
||||
|
||||
# Platform: processor architecture
|
||||
platform:
|
||||
- x64
|
||||
|
||||
#---------------------------------#
|
||||
# building & testing #
|
||||
#---------------------------------#
|
||||
|
||||
build_script:
|
||||
- cmd: python .ci/cue.py prepare
|
||||
- cmd: python .ci/cue.py build
|
||||
|
||||
test_script:
|
||||
- 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
|
||||
|
||||
#---------------------------------#
|
||||
# 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
|
||||
|
||||
#on_failure:
|
||||
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
|
||||
#---------------------------------#
|
||||
# notifications #
|
||||
#---------------------------------#
|
||||
|
||||
notifications:
|
||||
- provider: GitHubPullRequest
|
||||
1
.ci
Submodule
1
.ci
Submodule
Submodule .ci added at ad8dd4a136
6
.ci-local/defaults.set
Normal file
6
.ci-local/defaults.set
Normal file
@@ -0,0 +1,6 @@
|
||||
# EPICS Base
|
||||
BASE_DIRNAME=base
|
||||
BASE_REPONAME=epics-base
|
||||
BASE_REPOOWNER=epics-base
|
||||
BASE_VARNAME=EPICS_BASE
|
||||
BASE_RECURSIVE=NO
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e -x
|
||||
|
||||
make -j2
|
||||
|
||||
if [ "$TEST" != "NO" ]
|
||||
then
|
||||
make -j2 tapfiles
|
||||
make -j2 -s test-results
|
||||
fi
|
||||
@@ -1,83 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e -x
|
||||
|
||||
cat << EOF > configure/RELEASE.local
|
||||
EPICS_BASE=$HOME/.source/epics-base
|
||||
EOF
|
||||
|
||||
install -d "$HOME/.source"
|
||||
cd "$HOME/.source"
|
||||
|
||||
git clone --quiet --depth 5 --branch "$BRBASE" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base
|
||||
(cd epics-base && git log -n1 )
|
||||
|
||||
EPICS_HOST_ARCH=`sh epics-base/startup/EpicsHostArch`
|
||||
|
||||
# requires wine and g++-mingw-w64-i686
|
||||
if [ "$WINE" = "32" ]
|
||||
then
|
||||
echo "Cross mingw32"
|
||||
sed -i -e '/CMPLR_PREFIX/d' epics-base/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw
|
||||
cat << EOF >> epics-base/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw
|
||||
CMPLR_PREFIX=i686-w64-mingw32-
|
||||
EOF
|
||||
cat << EOF >> epics-base/configure/CONFIG_SITE
|
||||
CROSS_COMPILER_TARGET_ARCHS+=win32-x86-mingw
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ "$STATIC" = "YES" ]
|
||||
then
|
||||
echo "Build static libraries/executables"
|
||||
cat << EOF >> epics-base/configure/CONFIG_SITE
|
||||
SHARED_LIBRARIES=NO
|
||||
STATIC_BUILD=YES
|
||||
EOF
|
||||
fi
|
||||
|
||||
case "$CMPLR" in
|
||||
clang)
|
||||
echo "Host compiler is clang"
|
||||
cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.$EPICS_HOST_ARCH
|
||||
GNU = NO
|
||||
CMPLR_CLASS = clang
|
||||
CC = clang
|
||||
CCC = clang++
|
||||
EOF
|
||||
|
||||
# hack
|
||||
sed -i -e 's/CMPLR_CLASS = gcc/CMPLR_CLASS = clang/' epics-base/configure/CONFIG.gnuCommon
|
||||
|
||||
clang --version
|
||||
;;
|
||||
*)
|
||||
echo "Host compiler is default"
|
||||
gcc --version
|
||||
;;
|
||||
esac
|
||||
|
||||
cat <<EOF >> epics-base/configure/CONFIG_SITE
|
||||
USR_CPPFLAGS += $USR_CPPFLAGS
|
||||
USR_CFLAGS += $USR_CFLAGS
|
||||
USR_CXXFLAGS += $USR_CXXFLAGS
|
||||
EOF
|
||||
|
||||
# set RTEMS to eg. "4.9" or "4.10"
|
||||
# requires qemu, bison, flex, texinfo, install-info
|
||||
if [ -n "$RTEMS" ]
|
||||
then
|
||||
echo "Cross RTEMS${RTEMS} for pc386"
|
||||
curl -L "https://github.com/mdavidsaver/rsb/releases/download/20171203-${RTEMS}/i386-rtems${RTEMS}-trusty-20171203-${RTEMS}.tar.bz2" \
|
||||
| tar -C / -xmj
|
||||
|
||||
sed -i -e '/^RTEMS_VERSION/d' -e '/^RTEMS_BASE/d' epics-base/configure/os/CONFIG_SITE.Common.RTEMS
|
||||
cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.RTEMS
|
||||
RTEMS_VERSION=$RTEMS
|
||||
RTEMS_BASE=$HOME/.rtems
|
||||
EOF
|
||||
cat << EOF >> epics-base/configure/CONFIG_SITE
|
||||
CROSS_COMPILER_TARGET_ARCHS += RTEMS-pc386-qemu
|
||||
EOF
|
||||
fi
|
||||
|
||||
make -j2 -C epics-base $EXTRA
|
||||
153
.github/workflows/ci-scripts-build.yml
vendored
Normal file
153
.github/workflows/ci-scripts-build.yml
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
# .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
|
||||
|
||||
# Set the 'name:' properties to values that work for you (pvxs)
|
||||
|
||||
name: pvData
|
||||
|
||||
# Trigger on pushes and PRs to any branch
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- .appveyor.yml
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
SETUP_PATH: .ci-local:.ci
|
||||
EPICS_TEST_IMPRECISE_TIMING: YES
|
||||
|
||||
jobs:
|
||||
build-base:
|
||||
name: ${{ matrix.base }}/${{ matrix.os }}/${{ matrix.cmp }}/${{ matrix.configuration }}/${{ matrix.wine }}${{ matrix.rtems }}/${{ matrix.extra }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
# Set environment variables from matrix parameters
|
||||
env:
|
||||
BASE: ${{ matrix.base }}
|
||||
CMP: ${{ matrix.cmp }}
|
||||
BCFG: ${{ matrix.configuration }}
|
||||
WINE: ${{ matrix.wine }}
|
||||
RTEMS: ${{ matrix.rtems }}
|
||||
EXTRA: ${{ matrix.extra }}
|
||||
TEST: ${{ matrix.test }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
wine: "64"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
base: "7.0"
|
||||
wine: "64"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
base: "3.15"
|
||||
wine: "64"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: static
|
||||
base: "7.0"
|
||||
extra: "CMD_CXXFLAGS=-std=c++11"
|
||||
|
||||
- os: ubuntu-16.04
|
||||
cmp: clang
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: clang
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
extra: "CMD_CXXFLAGS=-std=c++11"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
rtems: "4.10"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
rtems: "4.9"
|
||||
|
||||
- os: ubuntu-16.04
|
||||
cmp: gcc-4.8
|
||||
utoolchain: true
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
|
||||
- os: ubuntu-16.04
|
||||
cmp: gcc-4.9
|
||||
utoolchain: true
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: gcc-8
|
||||
utoolchain: true
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
|
||||
- os: ubuntu-20.04
|
||||
cmp: clang
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
|
||||
- os: macos-latest
|
||||
cmp: clang
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
|
||||
- os: windows-2019
|
||||
cmp: vs2019
|
||||
configuration: default
|
||||
base: "7.0"
|
||||
|
||||
- os: windows-2019
|
||||
cmp: vs2019
|
||||
configuration: static
|
||||
base: "7.0"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Cache Dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache
|
||||
key: ${{ matrix.base }}/${{ matrix.os }}/${{ matrix.cmp }}/${{ matrix.configuration }}/${{ matrix.wine }}${{ matrix.rtems }}/${{ matrix.extra }}
|
||||
- name: Automatic core dump 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 -y install software-properties-common
|
||||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install ${{ matrix.cmp }}
|
||||
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: Collect and show test results
|
||||
run: python .ci/cue.py test-results
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule ".ci"]
|
||||
path = .ci
|
||||
url = https://github.com/epics-base/ci-scripts
|
||||
17
.readthedocs.yml
Normal file
17
.readthedocs.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
# .readthedocs.yml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Build documentation in the documentation/ directory with Sphinx
|
||||
sphinx:
|
||||
configuration: documentation/conf.py
|
||||
|
||||
# Build documentation with MkDocs
|
||||
#mkdocs:
|
||||
# configuration: mkdocs.yml
|
||||
|
||||
# Optionally build your docs in additional formats such as PDF and ePub
|
||||
formats: all
|
||||
30
.travis.yml
30
.travis.yml
@@ -1,30 +0,0 @@
|
||||
sudo: false
|
||||
dist: trusty
|
||||
language: c++
|
||||
compiler:
|
||||
- gcc
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libreadline6-dev
|
||||
- libncurses5-dev
|
||||
- perl
|
||||
- clang
|
||||
- g++-mingw-w64-i686
|
||||
- qemu-system-x86
|
||||
install:
|
||||
- ./.ci/travis-prepare.sh
|
||||
script:
|
||||
- ./.ci/travis-build.sh
|
||||
env:
|
||||
- BRBASE=7.0 CMPLR=gcc
|
||||
- BRBASE=7.0 CMPLR=clang
|
||||
- BRBASE=7.0 USR_CXXFLAGS=-std=c++11
|
||||
- BRBASE=7.0 CMPLR=clang USR_CXXFLAGS=-std=c++11
|
||||
- BRBASE=7.0 WINE=32 TEST=NO STATIC=YES
|
||||
- BRBASE=7.0 WINE=32 TEST=NO STATIC=NO
|
||||
- BRBASE=7.0 RTEMS=4.10 TEST=NO
|
||||
- BRBASE=7.0 RTEMS=4.9 TEST=NO
|
||||
- BRBASE=3.16
|
||||
- BRBASE=3.15
|
||||
- BRBASE=3.14
|
||||
316
Doxyfile
316
Doxyfile
@@ -1,4 +1,4 @@
|
||||
# Doxyfile 1.8.6
|
||||
# Doxyfile 1.8.8
|
||||
|
||||
# This file describes the settings to be used by the documentation system
|
||||
# doxygen (www.doxygen.org) for a project.
|
||||
@@ -32,33 +32,33 @@ DOXYFILE_ENCODING = UTF-8
|
||||
# title of most generated pages and in a few other places.
|
||||
# The default value is: My Project.
|
||||
|
||||
PROJECT_NAME = pvDataCPP
|
||||
PROJECT_NAME = "PVData C++"
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_NUMBER = 8.0.4
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
# quick idea about the purpose of the project. Keep the description short.
|
||||
|
||||
PROJECT_BRIEF =
|
||||
PROJECT_BRIEF =
|
||||
|
||||
# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
|
||||
# the documentation. The maximum height of the logo should not exceed 55 pixels
|
||||
# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
|
||||
# to the output directory.
|
||||
|
||||
PROJECT_LOGO =
|
||||
PROJECT_LOGO =
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
||||
# into which the generated documentation will be written. If a relative path is
|
||||
# entered, it will be relative to the location where doxygen was started. If
|
||||
# left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY =
|
||||
OUTPUT_DIRECTORY = .
|
||||
|
||||
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
|
||||
# directories (in 2 levels) under the output directory of each output format and
|
||||
@@ -70,6 +70,14 @@ OUTPUT_DIRECTORY =
|
||||
|
||||
CREATE_SUBDIRS = NO
|
||||
|
||||
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
|
||||
# characters to appear in the names of generated files. If set to NO, non-ASCII
|
||||
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
|
||||
# U+3044.
|
||||
# The default value is: NO.
|
||||
|
||||
ALLOW_UNICODE_NAMES = NO
|
||||
|
||||
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
||||
# documentation generated by doxygen is written. Doxygen will use this
|
||||
# information to generate all constant output in the proper language.
|
||||
@@ -110,7 +118,17 @@ REPEAT_BRIEF = YES
|
||||
# the entity):The $name class, The $name widget, The $name file, is, provides,
|
||||
# specifies, contains, represents, a, an and the.
|
||||
|
||||
ABBREVIATE_BRIEF =
|
||||
ABBREVIATE_BRIEF = "The $name class" \
|
||||
"The $name widget" \
|
||||
"The $name file" \
|
||||
is \
|
||||
provides \
|
||||
specifies \
|
||||
contains \
|
||||
represents \
|
||||
a \
|
||||
an \
|
||||
the
|
||||
|
||||
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
|
||||
# doxygen will generate a detailed section even if there is only a brief
|
||||
@@ -125,7 +143,7 @@ ALWAYS_DETAILED_SEC = NO
|
||||
# operators of the base classes will not be shown.
|
||||
# The default value is: NO.
|
||||
|
||||
INLINE_INHERITED_MEMB = YES
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
|
||||
# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
|
||||
# before files name in the file list and in the header files. If set to NO the
|
||||
@@ -144,7 +162,7 @@ FULL_PATH_NAMES = YES
|
||||
# will be relative from the directory where doxygen is started.
|
||||
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
|
||||
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_PATH = src
|
||||
|
||||
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
|
||||
# path mentioned in the documentation of a class, which tells the reader which
|
||||
@@ -153,7 +171,7 @@ STRIP_FROM_PATH =
|
||||
# specify the list of include paths that are normally passed to the compiler
|
||||
# using the -I flag.
|
||||
|
||||
STRIP_FROM_INC_PATH =
|
||||
STRIP_FROM_INC_PATH = src
|
||||
|
||||
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
|
||||
# less readable) file names. This can be useful is your file systems doesn't
|
||||
@@ -220,13 +238,13 @@ TAB_SIZE = 4
|
||||
# "Side Effects:". You can put \n's in the value part of an alias to insert
|
||||
# newlines.
|
||||
|
||||
ALIASES =
|
||||
ALIASES =
|
||||
|
||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
||||
# will allow you to use the command class in the itcl::class meaning.
|
||||
|
||||
TCL_SUBST =
|
||||
TCL_SUBST =
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C. For
|
||||
@@ -261,16 +279,19 @@ OPTIMIZE_OUTPUT_VHDL = NO
|
||||
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
||||
# using this tag. The format is ext=language, where ext is a file extension, and
|
||||
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
|
||||
# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
|
||||
# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
|
||||
# (default is Fortran), use: inc=Fortran f=C.
|
||||
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
|
||||
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
|
||||
# Fortran. In the later case the parser tries to guess whether the code is fixed
|
||||
# or free formatted code, this is the default for Fortran type files), VHDL. For
|
||||
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
|
||||
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
|
||||
#
|
||||
# Note For files without extension you can use no_extension as a placeholder.
|
||||
#
|
||||
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
|
||||
# the files are not read by doxygen.
|
||||
|
||||
EXTENSION_MAPPING =
|
||||
EXTENSION_MAPPING =
|
||||
|
||||
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
|
||||
# according to the Markdown format, which allows for more readable
|
||||
@@ -298,7 +319,7 @@ AUTOLINK_SUPPORT = YES
|
||||
# diagrams that involve STL classes more complete and accurate.
|
||||
# The default value is: NO.
|
||||
|
||||
BUILTIN_STL_SUPPORT = YES
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
|
||||
# If you use Microsoft's C++/CLI language, you should set this option to YES to
|
||||
# enable parsing support.
|
||||
@@ -398,7 +419,7 @@ LOOKUP_CACHE_SIZE = 0
|
||||
# normally produced when WARNINGS is set to YES.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_ALL = NO
|
||||
|
||||
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
|
||||
# be included in the documentation.
|
||||
@@ -487,7 +508,7 @@ INTERNAL_DOCS = NO
|
||||
# and Mac users are advised to set this option to NO.
|
||||
# The default value is: system dependent.
|
||||
|
||||
CASE_SENSE_NAMES = YES
|
||||
CASE_SENSE_NAMES = NO
|
||||
|
||||
# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
|
||||
# their full class and namespace scopes in the documentation. If set to YES the
|
||||
@@ -606,7 +627,7 @@ GENERATE_DEPRECATEDLIST= YES
|
||||
# sections, marked by \if <section_label> ... \endif and \cond <section_label>
|
||||
# ... \endcond blocks.
|
||||
|
||||
ENABLED_SECTIONS =
|
||||
ENABLED_SECTIONS =
|
||||
|
||||
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
|
||||
# initial value of a variable or macro / define can have for it to appear in the
|
||||
@@ -648,7 +669,7 @@ SHOW_NAMESPACES = YES
|
||||
# by doxygen. Whatever the program writes to standard output is used as the file
|
||||
# version. For an example see the documentation.
|
||||
|
||||
FILE_VERSION_FILTER =
|
||||
FILE_VERSION_FILTER =
|
||||
|
||||
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
|
||||
# by doxygen. The layout file controls the global structure of the generated
|
||||
@@ -661,7 +682,7 @@ FILE_VERSION_FILTER =
|
||||
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
|
||||
# tag is left empty.
|
||||
|
||||
LAYOUT_FILE =
|
||||
LAYOUT_FILE =
|
||||
|
||||
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
|
||||
# the reference definitions. This must be a list of .bib files. The .bib
|
||||
@@ -669,10 +690,9 @@ LAYOUT_FILE =
|
||||
# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
|
||||
# For LaTeX the style of the bibliography can be controlled using
|
||||
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
|
||||
# search path. Do not use file names with spaces, bibtex cannot handle them. See
|
||||
# also \cite for info how to create references.
|
||||
# search path. See also \cite for info how to create references.
|
||||
|
||||
CITE_BIB_FILES =
|
||||
CITE_BIB_FILES =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to warning and progress messages
|
||||
@@ -699,7 +719,7 @@ WARNINGS = YES
|
||||
# will automatically be disabled.
|
||||
# The default value is: YES.
|
||||
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
|
||||
# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
|
||||
# potential errors in the documentation, such as not documenting some parameters
|
||||
@@ -731,7 +751,7 @@ WARN_FORMAT = "$file:$line: $text"
|
||||
# messages should be written. If left blank the output is written to standard
|
||||
# error (stderr).
|
||||
|
||||
WARN_LOGFILE =
|
||||
WARN_LOGFILE =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the input files
|
||||
@@ -743,7 +763,12 @@ WARN_LOGFILE =
|
||||
# spaces.
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = include
|
||||
INPUT = src/pv \
|
||||
documentation/mainpage.dox \
|
||||
src/copy/pv \
|
||||
src/misc/pv \
|
||||
src/json/pv \
|
||||
documentation/release_notes.dox
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
@@ -763,13 +788,13 @@ INPUT_ENCODING = UTF-8
|
||||
# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
|
||||
# *.qsf, *.as and *.js.
|
||||
|
||||
FILE_PATTERNS =
|
||||
FILE_PATTERNS =
|
||||
|
||||
# The RECURSIVE tag can be used to specify whether or not subdirectories should
|
||||
# be searched for input files as well.
|
||||
# The default value is: NO.
|
||||
|
||||
RECURSIVE = YES
|
||||
RECURSIVE = NO
|
||||
|
||||
# The EXCLUDE tag can be used to specify files and/or directories that should be
|
||||
# excluded from the INPUT source files. This way you can easily exclude a
|
||||
@@ -778,7 +803,7 @@ RECURSIVE = YES
|
||||
# Note that relative paths are relative to the directory from which doxygen is
|
||||
# run.
|
||||
|
||||
EXCLUDE =
|
||||
EXCLUDE =
|
||||
|
||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||
# directories that are symbolic links (a Unix file system feature) are excluded
|
||||
@@ -794,7 +819,7 @@ EXCLUDE_SYMLINKS = NO
|
||||
# Note that the wildcards are matched against the file with absolute path, so to
|
||||
# exclude all test directories for example use the pattern */test/*
|
||||
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_PATTERNS =
|
||||
|
||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||
@@ -805,20 +830,20 @@ EXCLUDE_PATTERNS =
|
||||
# Note that the wildcards are matched against the file with absolute path, so to
|
||||
# exclude all test directories use the pattern */test/*
|
||||
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXCLUDE_SYMBOLS =
|
||||
|
||||
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
|
||||
# that contain example code fragments that are included (see the \include
|
||||
# command).
|
||||
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATH = examples
|
||||
|
||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
|
||||
# *.h) to filter out the source-files in the directories. If left blank all
|
||||
# files are included.
|
||||
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_PATTERNS = *.cpp
|
||||
|
||||
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
|
||||
# searched for input files to be used with the \include or \dontinclude commands
|
||||
@@ -831,7 +856,7 @@ EXAMPLE_RECURSIVE = NO
|
||||
# that contain images that are to be included in the documentation (see the
|
||||
# \image command).
|
||||
|
||||
IMAGE_PATH =
|
||||
IMAGE_PATH =
|
||||
|
||||
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||
@@ -848,7 +873,7 @@ IMAGE_PATH =
|
||||
# code is scanned, but not when the output code is generated. If lines are added
|
||||
# or removed, the anchors will not be placed correctly.
|
||||
|
||||
INPUT_FILTER =
|
||||
INPUT_FILTER =
|
||||
|
||||
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
|
||||
# basis. Doxygen will compare the file name with each pattern and apply the
|
||||
@@ -857,7 +882,7 @@ INPUT_FILTER =
|
||||
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
|
||||
# patterns match the file name, INPUT_FILTER is applied.
|
||||
|
||||
FILTER_PATTERNS =
|
||||
FILTER_PATTERNS =
|
||||
|
||||
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
|
||||
# INPUT_FILTER ) will also be used to filter the input files that are used for
|
||||
@@ -872,14 +897,14 @@ FILTER_SOURCE_FILES = NO
|
||||
# *.ext= (so without naming a filter).
|
||||
# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
|
||||
|
||||
FILTER_SOURCE_PATTERNS =
|
||||
FILTER_SOURCE_PATTERNS =
|
||||
|
||||
# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
|
||||
# is part of the input, its contents will be placed on the main page
|
||||
# (index.html). This can be useful if you have a project on for instance GitHub
|
||||
# and want to reuse the introduction page also for the doxygen output.
|
||||
|
||||
USE_MDFILE_AS_MAINPAGE =
|
||||
USE_MDFILE_AS_MAINPAGE =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to source browsing
|
||||
@@ -911,13 +936,13 @@ STRIP_CODE_COMMENTS = YES
|
||||
# function all documented functions referencing it will be listed.
|
||||
# The default value is: NO.
|
||||
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCED_BY_RELATION = NO
|
||||
|
||||
# If the REFERENCES_RELATION tag is set to YES then for each documented function
|
||||
# all documented entities called/used by that function will be listed.
|
||||
# The default value is: NO.
|
||||
|
||||
REFERENCES_RELATION = YES
|
||||
REFERENCES_RELATION = NO
|
||||
|
||||
# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
|
||||
# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
|
||||
@@ -967,6 +992,25 @@ USE_HTAGS = NO
|
||||
|
||||
VERBATIM_HEADERS = YES
|
||||
|
||||
# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the
|
||||
# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
|
||||
# cost of reduced performance. This can be particularly helpful with template
|
||||
# rich C++ code for which doxygen's built-in parser lacks the necessary type
|
||||
# information.
|
||||
# Note: The availability of this option depends on whether or not doxygen was
|
||||
# compiled with the --with-libclang option.
|
||||
# The default value is: NO.
|
||||
|
||||
CLANG_ASSISTED_PARSING = YES
|
||||
|
||||
# If clang assisted parsing is enabled you can provide the compiler with command
|
||||
# line options that you would normally use when invoking the compiler. Note that
|
||||
# the include paths will already be set by doxygen for the files and directories
|
||||
# specified with INPUT and INCLUDE_PATH.
|
||||
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
|
||||
|
||||
CLANG_OPTIONS =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -976,7 +1020,7 @@ VERBATIM_HEADERS = YES
|
||||
# classes, structs, unions or interfaces.
|
||||
# The default value is: YES.
|
||||
|
||||
ALPHABETICAL_INDEX = NO
|
||||
ALPHABETICAL_INDEX = YES
|
||||
|
||||
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
|
||||
# which the alphabetical index list will be split.
|
||||
@@ -991,7 +1035,7 @@ COLS_IN_ALPHA_INDEX = 5
|
||||
# while generating the index headers.
|
||||
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||
|
||||
IGNORE_PREFIX =
|
||||
IGNORE_PREFIX =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the HTML output
|
||||
@@ -1008,7 +1052,7 @@ GENERATE_HTML = YES
|
||||
# The default directory is: html.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_OUTPUT = documentation/html
|
||||
HTML_OUTPUT = html/doxygen
|
||||
|
||||
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
||||
# generated HTML page (for example: .htm, .php, .asp).
|
||||
@@ -1035,7 +1079,7 @@ HTML_FILE_EXTENSION = .html
|
||||
# of the possible markers and block names see the documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_HEADER =
|
||||
HTML_HEADER =
|
||||
|
||||
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
|
||||
# generated HTML page. If the tag is left blank doxygen will generate a standard
|
||||
@@ -1045,7 +1089,7 @@ HTML_HEADER =
|
||||
# that doxygen normally uses.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_FOOTER =
|
||||
HTML_FOOTER =
|
||||
|
||||
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
|
||||
# sheet that is used by each HTML page. It can be used to fine-tune the look of
|
||||
@@ -1057,18 +1101,20 @@ HTML_FOOTER =
|
||||
# obsolete.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_STYLESHEET =
|
||||
HTML_STYLESHEET =
|
||||
|
||||
# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
|
||||
# defined cascading style sheet that is included after the standard style sheets
|
||||
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
|
||||
# cascading style sheets that are included after the standard style sheets
|
||||
# created by doxygen. Using this option one can overrule certain style aspects.
|
||||
# This is preferred over using HTML_STYLESHEET since it does not replace the
|
||||
# standard style sheet and is therefor more robust against future updates.
|
||||
# Doxygen will copy the style sheet file to the output directory. For an example
|
||||
# see the documentation.
|
||||
# Doxygen will copy the style sheet files to the output directory.
|
||||
# Note: The order of the extra stylesheet files is of importance (e.g. the last
|
||||
# stylesheet in the list overrules the setting of the previous ones in the
|
||||
# list). For an example see the documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_EXTRA_STYLESHEET =
|
||||
HTML_EXTRA_STYLESHEET =
|
||||
|
||||
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||
# other source files which should be copied to the HTML output directory. Note
|
||||
@@ -1078,7 +1124,7 @@ HTML_EXTRA_STYLESHEET =
|
||||
# files will be copied as-is; there are no commands or markers available.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_EXTRA_FILES = documentation/pvDataCPP.html
|
||||
HTML_EXTRA_FILES =
|
||||
|
||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
||||
# will adjust the colors in the stylesheet and background images according to
|
||||
@@ -1206,7 +1252,7 @@ GENERATE_HTMLHELP = NO
|
||||
# written to the html output directory.
|
||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||
|
||||
CHM_FILE =
|
||||
CHM_FILE =
|
||||
|
||||
# The HHC_LOCATION tag can be used to specify the location (absolute path
|
||||
# including file name) of the HTML help compiler ( hhc.exe). If non-empty
|
||||
@@ -1214,7 +1260,7 @@ CHM_FILE =
|
||||
# The file has to be specified with full path.
|
||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||
|
||||
HHC_LOCATION =
|
||||
HHC_LOCATION =
|
||||
|
||||
# The GENERATE_CHI flag controls if a separate .chi index file is generated (
|
||||
# YES) or that it should be included in the master .chm file ( NO).
|
||||
@@ -1227,10 +1273,11 @@ GENERATE_CHI = NO
|
||||
# and project file content.
|
||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||
|
||||
CHM_INDEX_ENCODING =
|
||||
CHM_INDEX_ENCODING =
|
||||
|
||||
# The BINARY_TOC flag controls whether a binary table of contents is generated (
|
||||
# YES) or a normal table of contents ( NO) in the .chm file.
|
||||
# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it
|
||||
# enables the Previous and Next buttons.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||
|
||||
@@ -1257,7 +1304,7 @@ GENERATE_QHP = NO
|
||||
# the HTML output folder.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QCH_FILE =
|
||||
QCH_FILE =
|
||||
|
||||
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
|
||||
# Project output. For more information please see Qt Help Project / Namespace
|
||||
@@ -1282,7 +1329,7 @@ QHP_VIRTUAL_FOLDER = doc
|
||||
# filters).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_CUST_FILTER_NAME =
|
||||
QHP_CUST_FILTER_NAME =
|
||||
|
||||
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
|
||||
# custom filter to add. For more information please see Qt Help Project / Custom
|
||||
@@ -1290,21 +1337,21 @@ QHP_CUST_FILTER_NAME =
|
||||
# filters).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
|
||||
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
|
||||
# project's filter section matches. Qt Help Project / Filter Attributes (see:
|
||||
# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
|
||||
# The QHG_LOCATION tag can be used to specify the location of Qt's
|
||||
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
|
||||
# generated .qhp file.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHG_LOCATION =
|
||||
QHG_LOCATION =
|
||||
|
||||
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
|
||||
# generated, together with the HTML files, they form an Eclipse help plugin. To
|
||||
@@ -1437,7 +1484,7 @@ MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
MATHJAX_EXTENSIONS =
|
||||
MATHJAX_EXTENSIONS =
|
||||
|
||||
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
|
||||
# of code that will be used on startup of the MathJax code. See the MathJax site
|
||||
@@ -1445,7 +1492,7 @@ MATHJAX_EXTENSIONS =
|
||||
# example see the documentation.
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
MATHJAX_CODEFILE =
|
||||
MATHJAX_CODEFILE =
|
||||
|
||||
# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
|
||||
# the HTML output. The underlying search engine uses javascript and DHTML and
|
||||
@@ -1466,15 +1513,15 @@ MATHJAX_CODEFILE =
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
SEARCHENGINE = NO
|
||||
SEARCHENGINE = YES
|
||||
|
||||
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
||||
# implemented using a web server instead of a web client using Javascript. There
|
||||
# are two flavours of web server based searching depending on the
|
||||
# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
|
||||
# searching and an index file used by the script. When EXTERNAL_SEARCH is
|
||||
# enabled the indexing and searching needs to be provided by external tools. See
|
||||
# the section "External Indexing and Searching" for details.
|
||||
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
|
||||
# setting. When disabled, doxygen will generate a PHP script for searching and
|
||||
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
|
||||
# and searching needs to be provided by external tools. See the section
|
||||
# "External Indexing and Searching" for details.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||
|
||||
@@ -1505,7 +1552,7 @@ EXTERNAL_SEARCH = NO
|
||||
# Searching" for details.
|
||||
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||
|
||||
SEARCHENGINE_URL =
|
||||
SEARCHENGINE_URL =
|
||||
|
||||
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
|
||||
# search data is written to a file for indexing by an external tool. With the
|
||||
@@ -1521,7 +1568,7 @@ SEARCHDATA_FILE = searchdata.xml
|
||||
# projects and redirect the results back to the right project.
|
||||
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||
|
||||
EXTERNAL_SEARCH_ID =
|
||||
EXTERNAL_SEARCH_ID =
|
||||
|
||||
# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
|
||||
# projects other than the one defined by this configuration file, but that are
|
||||
@@ -1531,7 +1578,7 @@ EXTERNAL_SEARCH_ID =
|
||||
# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
|
||||
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||
|
||||
EXTRA_SEARCH_MAPPINGS =
|
||||
EXTRA_SEARCH_MAPPINGS =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the LaTeX output
|
||||
@@ -1583,7 +1630,7 @@ COMPACT_LATEX = NO
|
||||
# The default value is: a4.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
PAPER_TYPE = a4wide
|
||||
PAPER_TYPE = a4
|
||||
|
||||
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
|
||||
# that should be included in the LaTeX output. To get the times font for
|
||||
@@ -1592,7 +1639,7 @@ PAPER_TYPE = a4wide
|
||||
# If left blank no extra packages will be included.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
EXTRA_PACKAGES =
|
||||
EXTRA_PACKAGES =
|
||||
|
||||
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
|
||||
# generated LaTeX document. The header should contain everything until the first
|
||||
@@ -1602,22 +1649,24 @@ EXTRA_PACKAGES =
|
||||
#
|
||||
# Note: Only use a user-defined header if you know what you are doing! The
|
||||
# following commands have a special meaning inside the header: $title,
|
||||
# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
|
||||
# replace them by respectively the title of the page, the current date and time,
|
||||
# only the current date, the version number of doxygen, the project name (see
|
||||
# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
|
||||
# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
|
||||
# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string,
|
||||
# for the replacement values of the other commands the user is refered to
|
||||
# HTML_HEADER.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_HEADER =
|
||||
LATEX_HEADER =
|
||||
|
||||
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
|
||||
# generated LaTeX document. The footer should contain everything after the last
|
||||
# chapter. If it is left blank doxygen will generate a standard footer.
|
||||
# chapter. If it is left blank doxygen will generate a standard footer. See
|
||||
# LATEX_HEADER for more information on how to generate a default footer and what
|
||||
# special commands can be used inside the footer.
|
||||
#
|
||||
# Note: Only use a user-defined footer if you know what you are doing!
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_FOOTER =
|
||||
LATEX_FOOTER =
|
||||
|
||||
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||
# other source files which should be copied to the LATEX_OUTPUT output
|
||||
@@ -1625,7 +1674,7 @@ LATEX_FOOTER =
|
||||
# markers available.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_EXTRA_FILES =
|
||||
LATEX_EXTRA_FILES =
|
||||
|
||||
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
|
||||
# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
|
||||
@@ -1634,15 +1683,15 @@ LATEX_EXTRA_FILES =
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
PDF_HYPERLINKS = NO
|
||||
PDF_HYPERLINKS = YES
|
||||
|
||||
# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
|
||||
# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
|
||||
# the PDF file directly from the LaTeX files. Set this option to YES to get a
|
||||
# higher quality PDF documentation.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
USE_PDFLATEX = NO
|
||||
USE_PDFLATEX = YES
|
||||
|
||||
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
|
||||
# command to the generated LaTeX files. This will instruct LaTeX to keep running
|
||||
@@ -1725,14 +1774,14 @@ RTF_HYPERLINKS = NO
|
||||
# default style sheet that doxygen normally uses.
|
||||
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_STYLESHEET_FILE =
|
||||
|
||||
# Set optional variables used in the generation of an RTF document. Syntax is
|
||||
# similar to doxygen's config file. A template extensions file can be generated
|
||||
# using doxygen -e rtf extensionFile.
|
||||
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||
|
||||
RTF_EXTENSIONS_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the man page output
|
||||
@@ -1762,6 +1811,13 @@ MAN_OUTPUT = man
|
||||
|
||||
MAN_EXTENSION = .3
|
||||
|
||||
# The MAN_SUBDIR tag determines the name of the directory created within
|
||||
# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
|
||||
# MAN_EXTENSION with the initial . removed.
|
||||
# This tag requires that the tag GENERATE_MAN is set to YES.
|
||||
|
||||
MAN_SUBDIR =
|
||||
|
||||
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
|
||||
# will generate one additional man file for each entity documented in the real
|
||||
# man page(s). These additional files only source the real man page, but without
|
||||
@@ -1789,18 +1845,6 @@ GENERATE_XML = NO
|
||||
|
||||
XML_OUTPUT = xml
|
||||
|
||||
# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
|
||||
# validating XML parser to check the syntax of the XML files.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_SCHEMA =
|
||||
|
||||
# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
|
||||
# validating XML parser to check the syntax of the XML files.
|
||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||
|
||||
XML_DTD =
|
||||
|
||||
# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
|
||||
# listings (including syntax highlighting and cross-referencing information) to
|
||||
# the XML output. Note that enabling this will significantly increase the size
|
||||
@@ -1828,6 +1872,15 @@ GENERATE_DOCBOOK = NO
|
||||
|
||||
DOCBOOK_OUTPUT = docbook
|
||||
|
||||
# If the DOCBOOK_PROGRAMLISTING tag is set to YES doxygen will include the
|
||||
# program listings (including syntax highlighting and cross-referencing
|
||||
# information) to the DOCBOOK output. Note that enabling this will significantly
|
||||
# increase the size of the DOCBOOK output.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
|
||||
|
||||
DOCBOOK_PROGRAMLISTING = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -1876,7 +1929,7 @@ PERLMOD_PRETTY = YES
|
||||
# overwrite each other's variables.
|
||||
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
|
||||
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
@@ -1895,7 +1948,7 @@ ENABLE_PREPROCESSING = YES
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
MACRO_EXPANSION = NO
|
||||
MACRO_EXPANSION = YES
|
||||
|
||||
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
|
||||
# the macro expansion is limited to the macros specified with the PREDEFINED and
|
||||
@@ -1917,7 +1970,7 @@ SEARCH_INCLUDES = YES
|
||||
# preprocessor.
|
||||
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
|
||||
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_PATH = src/misc src ../../include/
|
||||
|
||||
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
|
||||
# patterns (like *.h and *.hpp) to filter out the header-files in the
|
||||
@@ -1925,7 +1978,7 @@ INCLUDE_PATH =
|
||||
# used.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
|
||||
# The PREDEFINED tag can be used to specify one or more macro names that are
|
||||
# defined before the preprocessor is started (similar to the -D option of e.g.
|
||||
@@ -1935,7 +1988,7 @@ INCLUDE_FILE_PATTERNS =
|
||||
# recursively expanded use the := operator instead of the = operator.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
PREDEFINED =
|
||||
PREDEFINED =
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||
# tag can be used to specify a list of macro names that should be expanded. The
|
||||
@@ -1947,14 +2000,14 @@ PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
|
||||
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
|
||||
# remove all refrences to function-like macros that are alone on a line, have an
|
||||
# all uppercase name, and do not end with a semicolon. Such function macros are
|
||||
# typically used for boiler-plate code, and will confuse the parser if not
|
||||
# remove all references to function-like macros that are alone on a line, have
|
||||
# an all uppercase name, and do not end with a semicolon. Such function macros
|
||||
# are typically used for boiler-plate code, and will confuse the parser if not
|
||||
# removed.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
SKIP_FUNCTION_MACROS = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to external references
|
||||
@@ -1969,17 +2022,17 @@ SKIP_FUNCTION_MACROS = YES
|
||||
# where loc1 and loc2 can be relative or absolute paths or URLs. See the
|
||||
# section "Linking to external documentation" for more information about the use
|
||||
# of tag files.
|
||||
# Note: Each tag file must have an unique name (where the name does NOT include
|
||||
# Note: Each tag file must have a unique name (where the name does NOT include
|
||||
# the path). If a tag file is not located in the directory in which doxygen is
|
||||
# run, you must also specify the path to the tagfile here.
|
||||
|
||||
TAGFILES =
|
||||
TAGFILES = "libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen"
|
||||
|
||||
# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
|
||||
# tag file that is based on the input files it reads. See section "Linking to
|
||||
# external documentation" for more information about the usage of tag files.
|
||||
|
||||
GENERATE_TAGFILE =
|
||||
GENERATE_TAGFILE = pvdata.tag
|
||||
|
||||
# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
|
||||
# class index. If set to NO only the inherited external classes will be listed.
|
||||
@@ -1992,14 +2045,14 @@ ALLEXTERNALS = NO
|
||||
# listed.
|
||||
# The default value is: YES.
|
||||
|
||||
EXTERNAL_GROUPS = YES
|
||||
EXTERNAL_GROUPS = NO
|
||||
|
||||
# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
|
||||
# the related pages index. If set to NO, only the current project's pages will
|
||||
# be listed.
|
||||
# The default value is: YES.
|
||||
|
||||
EXTERNAL_PAGES = YES
|
||||
EXTERNAL_PAGES = NO
|
||||
|
||||
# The PERL_PATH should be the absolute path and name of the perl script
|
||||
# interpreter (i.e. the result of 'which perl').
|
||||
@@ -2027,14 +2080,14 @@ CLASS_DIAGRAMS = YES
|
||||
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
||||
# default search path.
|
||||
|
||||
MSCGEN_PATH =
|
||||
MSCGEN_PATH =
|
||||
|
||||
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
||||
# then run dia to produce the diagram and insert it in the documentation. The
|
||||
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
||||
# If left empty dia is assumed to be found in the default search path.
|
||||
|
||||
DIA_PATH =
|
||||
DIA_PATH =
|
||||
|
||||
# If set to YES, the inheritance and collaboration graphs will hide inheritance
|
||||
# and usage relations if the target is undocumented or is not a class.
|
||||
@@ -2047,9 +2100,9 @@ HIDE_UNDOC_RELATIONS = YES
|
||||
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
|
||||
# Bell Labs. The other options in this section have no effect if this option is
|
||||
# set to NO
|
||||
# The default value is: NO.
|
||||
# The default value is: YES.
|
||||
|
||||
HAVE_DOT = NO
|
||||
HAVE_DOT = YES
|
||||
|
||||
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
|
||||
# to run in parallel. When set to 0 doxygen will base this on the number of
|
||||
@@ -2061,7 +2114,7 @@ HAVE_DOT = NO
|
||||
|
||||
DOT_NUM_THREADS = 0
|
||||
|
||||
# When you want a differently looking font n the dot files that doxygen
|
||||
# When you want a differently looking font in the dot files that doxygen
|
||||
# generates you can specify the font name using DOT_FONTNAME. You need to make
|
||||
# sure dot is able to find the font, which can be done by putting it in a
|
||||
# standard location or by setting the DOTFONTPATH environment variable or by
|
||||
@@ -2083,7 +2136,7 @@ DOT_FONTSIZE = 10
|
||||
# the path where dot can find it using this tag.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_FONTPATH =
|
||||
DOT_FONTPATH =
|
||||
|
||||
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
|
||||
# each documented class showing the direct and indirect inheritance relations.
|
||||
@@ -2199,7 +2252,9 @@ DIRECTORY_GRAPH = YES
|
||||
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
|
||||
# to make the SVG files visible in IE 9+ (other browsers do not have this
|
||||
# requirement).
|
||||
# Possible values are: png, jpg, gif and svg.
|
||||
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
|
||||
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
|
||||
# gif:cairo:gd, gif:gd, gif:gd:gd and svg.
|
||||
# The default value is: png.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
@@ -2221,26 +2276,35 @@ INTERACTIVE_SVG = NO
|
||||
# found. If left blank, it is assumed the dot tool can be found in the path.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_PATH =
|
||||
DOT_PATH =
|
||||
|
||||
# The DOTFILE_DIRS tag can be used to specify one or more directories that
|
||||
# contain dot files that are included in the documentation (see the \dotfile
|
||||
# command).
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOTFILE_DIRS =
|
||||
DOTFILE_DIRS =
|
||||
|
||||
# The MSCFILE_DIRS tag can be used to specify one or more directories that
|
||||
# contain msc files that are included in the documentation (see the \mscfile
|
||||
# command).
|
||||
|
||||
MSCFILE_DIRS =
|
||||
MSCFILE_DIRS =
|
||||
|
||||
# The DIAFILE_DIRS tag can be used to specify one or more directories that
|
||||
# contain dia files that are included in the documentation (see the \diafile
|
||||
# command).
|
||||
|
||||
DIAFILE_DIRS =
|
||||
DIAFILE_DIRS =
|
||||
|
||||
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
|
||||
# path where java can find the plantuml.jar file. If left blank, it is assumed
|
||||
# PlantUML is not used or called during a preprocessing step. Doxygen will
|
||||
# generate a warning when it encounters a \startuml command in this case and
|
||||
# will not generate output for the diagram.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
PLANTUML_JAR_PATH =
|
||||
|
||||
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
|
||||
# that will be shown in the graph. If the number of nodes in a graph becomes
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
# Version number for the PV Data API and shared library
|
||||
|
||||
EPICS_PVD_MAJOR_VERSION = 8
|
||||
EPICS_PVD_MINOR_VERSION = 0
|
||||
EPICS_PVD_MAINTENANCE_VERSION = 0
|
||||
EPICS_PVD_MAINTENANCE_VERSION = 4
|
||||
|
||||
# Development flag, set to zero for release versions
|
||||
|
||||
EPICS_PVD_DEVELOPMENT_FLAG = 0
|
||||
|
||||
# Immediately after a release the MAINTENANCE_VERSION
|
||||
# will be incremented and the DEVELOPMENT_FLAG set to 1
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = "PVData C++"
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 8.0.0
|
||||
PROJECT_NUMBER = 8.0.4
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
7
documentation/_static/css/custom.css
Normal file
7
documentation/_static/css/custom.css
Normal file
@@ -0,0 +1,7 @@
|
||||
.wy-side-nav-search {
|
||||
background-color: #18334B;
|
||||
}
|
||||
|
||||
.wy-side-nav-search input[type="text"] {
|
||||
border-color: #18334b;
|
||||
}
|
||||
78
documentation/conf.py
Normal file
78
documentation/conf.py
Normal file
@@ -0,0 +1,78 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# http://www.sphinx-doc.org/en/master/config
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
# import os
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'EPICS Documentation'
|
||||
copyright = '2019, EPICS Controls.'
|
||||
author = 'EPICS'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.intersphinx',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
# Intersphinx links to subprojects
|
||||
intersphinx_mapping = {
|
||||
'how-tos': ('https://docs.epics-controls.org/projects/how-tos/en/latest', None),
|
||||
}
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
html_css_files = [
|
||||
'css/custom.css',
|
||||
]
|
||||
|
||||
master_doc = 'index'
|
||||
|
||||
html_theme_options = {
|
||||
'logo_only': True,
|
||||
}
|
||||
html_logo = "images/EPICS_white_logo_v02.png"
|
||||
|
||||
html_extra_path = ['../html']
|
||||
|
||||
|
||||
# -- Run Doxygen ------------------------------------------------------------
|
||||
|
||||
import subprocess
|
||||
subprocess.call('cd ..; mkdir -p html/doxygen; doxygen', shell=True)
|
||||
BIN
documentation/images/EPICS_white_logo_v02.png
Normal file
BIN
documentation/images/EPICS_white_logo_v02.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
16
documentation/index.rst
Normal file
16
documentation/index.rst
Normal file
@@ -0,0 +1,16 @@
|
||||
pvData (C++) Library
|
||||
====================
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
EPICS Website <https://epics-controls.org>
|
||||
EPICS Documentation Home <https://docs.epics-controls.org>
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: pvDataCPP
|
||||
|
||||
Reference Manual and API Documentation <https://docs.epics-controls.org/projects/pvdata-cpp/en/latest/doxygen>
|
||||
Source Code Repository on GitHub <https://github.com/epics-base/pvDataCPP>
|
||||
@@ -2,16 +2,47 @@
|
||||
|
||||
@page release_notes Release Notes
|
||||
|
||||
Release 8.1.0 (Feb 2021)
|
||||
========================
|
||||
|
||||
- Incompatible changes
|
||||
- Remove ByteBuffer::align()
|
||||
- Compatible changes
|
||||
- Deprecate SerializableControl::alignBuffer() and DeserializableControl::alignData()
|
||||
- shared_vector_convert<>() fix convert of empty, untyped, array
|
||||
|
||||
Release 8.0.3 (July 2020)
|
||||
=========================
|
||||
|
||||
- Incompatible changes
|
||||
- Removed THROW_BASE_EXCEPTION_CAUSE() macro which has long ignored its cause.
|
||||
Any external users should switch to the functionally identical THROW_BASE_EXCEPTION_CAUSE()
|
||||
- Various printing of functions now conditionally escape strings
|
||||
including quote '\"' and similar charactors.
|
||||
|
||||
Release 8.0.2 (May 2020)
|
||||
========================
|
||||
|
||||
- Changes to documentation and unittests.
|
||||
No functional changes to library.
|
||||
|
||||
Release 8.0.1 (Nov 2019)
|
||||
==========================
|
||||
|
||||
- Incompatible changes
|
||||
- Requires Base >= 3.15
|
||||
- Bug fixes
|
||||
|
||||
Release 8.0.0 (July 2019)
|
||||
=========================
|
||||
|
||||
- Deprecations
|
||||
- ByteBuffer::getArray()
|
||||
- ByteBuffer::getArray()
|
||||
- Removals
|
||||
- pv/localStaticLock.h
|
||||
- pv/pvCopy.h (see epics::pvData::PVRequestMapper)
|
||||
- pv/localStaticLock.h
|
||||
- pv/pvCopy.h (see epics::pvData::PVRequestMapper)
|
||||
- Additions
|
||||
- Add {Structure,Union}::getFieldT
|
||||
- Add {Structure,Union}::getFieldT
|
||||
|
||||
Release 7.1.3 (Apr 2019)
|
||||
========================
|
||||
@@ -28,60 +59,60 @@ Release 7.1.1 (Mar 2019)
|
||||
========================
|
||||
|
||||
- Fixes
|
||||
- Init order issue with StandardField::getStandardField()
|
||||
- Build fix for Visual Studio 2013+
|
||||
- Init order issue with StandardField::getStandardField()
|
||||
- Build fix for Visual Studio 2013+
|
||||
|
||||
Release 7.1.0 (Nov 2018)
|
||||
========================
|
||||
|
||||
- Deprecations
|
||||
- BoundedString, BoundedScalarArray, and FixedScalarArray will be removed unless they are fixed.
|
||||
See https://github.com/epics-base/pvDataCPP/issues/52 for discussion.
|
||||
- pv/localStaticLock.h
|
||||
- pv/pvCopy.h (see epics::pvData::PVRequestMapper)
|
||||
- BoundedString, BoundedScalarArray, and FixedScalarArray will be removed unless they are fixed.
|
||||
See https://github.com/epics-base/pvDataCPP/issues/52 for discussion.
|
||||
- pv/localStaticLock.h
|
||||
- pv/pvCopy.h (see epics::pvData::PVRequestMapper)
|
||||
- Removals
|
||||
- Remove previously deprecated executor.h, queue.h and timerFunction.h
|
||||
- Remove *HashFunction functors to "hash" Field sub-classes which were never fully implemented.
|
||||
- Remove previously deprecated executor.h, queue.h and timerFunction.h
|
||||
- Remove *HashFunction functors to "hash" Field sub-classes which were never fully implemented.
|
||||
- Fixes
|
||||
- Make thread safe getFieldCreate() and getPVDataCreate()
|
||||
- Workaround for MSVC pickyness that iterators be non-NULL, even when not de-referenced.
|
||||
- Fix alignment fault during (de)serialization on RTEMS/vxWorks.
|
||||
- Fix epics::pvData::shared_vector::swap() for void specialization.
|
||||
- Changes in several epics::pvData::Field sub-classes to return const ref. instead of a copy.
|
||||
- Make thread safe getFieldCreate() and getPVDataCreate()
|
||||
- Workaround for MSVC pickyness that iterators be non-NULL, even when not de-referenced.
|
||||
- Fix alignment fault during (de)serialization on RTEMS/vxWorks.
|
||||
- Fix epics::pvData::shared_vector::swap() for void specialization.
|
||||
- Changes in several epics::pvData::Field sub-classes to return const ref. instead of a copy.
|
||||
- Additions
|
||||
- epics::pvData::shared_vector add c++11 move and construct for initializer list.
|
||||
- Add epics::pvData::AnyScalar::clear()
|
||||
- Add ctor epics::pvData::AnyScalar(ScalarType, const void*) to allow construction from an untyped buffer.
|
||||
- Add epics::pvData::Timer::close()
|
||||
- Allow epics::pvData::castUnsafe() from const char* without first allocating a std::string.
|
||||
- De-duplication of epics::pvData::Field instances is performed using a global hash table.
|
||||
Identical definitions will share a single instance. Allows O(0) comparision.
|
||||
- Add epics::pvData::PVRequestMapper to facilitate (partial) copying between PVStructure instances
|
||||
modified by a pvRequest.
|
||||
- Add shorthand notations epics::pvData::FieldBuilder::begin() and epics::pvData::Field::build()
|
||||
- epics::pvData::shared_vector add c++11 move and construct for initializer list.
|
||||
- Add epics::pvData::AnyScalar::clear()
|
||||
- Add ctor epics::pvData::AnyScalar(ScalarType, const void*) to allow construction from an untyped buffer.
|
||||
- Add epics::pvData::Timer::close()
|
||||
- Allow epics::pvData::castUnsafe() from const char* without first allocating a std::string.
|
||||
- De-duplication of epics::pvData::Field instances is performed using a global hash table.
|
||||
Identical definitions will share a single instance. Allows O(0) comparision.
|
||||
- Add epics::pvData::PVRequestMapper to facilitate (partial) copying between PVStructure instances
|
||||
modified by a pvRequest.
|
||||
- Add shorthand notations epics::pvData::FieldBuilder::begin() and epics::pvData::Field::build()
|
||||
|
||||
Release 7.0.0 (Dec 2017)
|
||||
========================
|
||||
|
||||
- Removals
|
||||
- Remove requester.h, monitor.h, and destroyable.h.. Migrated to the pvAccessCPP module.
|
||||
- Previously deprecated monitorPlugin.h is removed.
|
||||
- Remove pv/messageQueue.h and epics::pvData::MessageQueue
|
||||
- Remove requester.h, monitor.h, and destroyable.h.. Migrated to the pvAccessCPP module.
|
||||
- Previously deprecated monitorPlugin.h is removed.
|
||||
- Remove pv/messageQueue.h and epics::pvData::MessageQueue
|
||||
- Deprecate the following utility classes, to be removed in 8.0.
|
||||
- epics::pvData::Queue
|
||||
- epics::pvData::Executor
|
||||
- epics::pvData::TimeFunction
|
||||
- epics::pvData::Queue
|
||||
- epics::pvData::Executor
|
||||
- epics::pvData::TimeFunction
|
||||
- Additions
|
||||
- Add pv/pvdVersion.h which is included by pv/pvIntrospect.h
|
||||
- Add epics::pvData::createRequest() function. Alternative to epics::pvData::CreateRequest class which throws on error.
|
||||
- epics::pvData::FieldBuilder allow Structure defintion to be changed/appended
|
||||
- Add epics::pvData::ValueBuilder like FieldBuilder also sets initial values.
|
||||
- Can also be constructed using an existing PVStructure to allow "editing".
|
||||
- Add debugPtr.h wrapper with reference tracking to assist in troubleshooting shared_ptr related ref. loops.
|
||||
- Add @ref pvjson utilities
|
||||
- Add reftrack @ref pvd_reftrack
|
||||
- Add header typemap.h to facilitate boilerplate switch() over ScalarType
|
||||
- Add epics::auto_ptr typedef in help writing code supporting both c++98 and c++11 w/o copious deprecation warnings.
|
||||
- Add pv/pvdVersion.h which is included by pv/pvIntrospect.h
|
||||
- Add epics::pvData::createRequest() function. Alternative to epics::pvData::CreateRequest class which throws on error.
|
||||
- epics::pvData::FieldBuilder allow Structure defintion to be changed/appended
|
||||
- Add epics::pvData::ValueBuilder like FieldBuilder also sets initial values.
|
||||
- Can also be constructed using an existing PVStructure to allow "editing".
|
||||
- Add debugPtr.h wrapper with reference tracking to assist in troubleshooting shared_ptr related ref. loops.
|
||||
- Add @ref pvjson utilities
|
||||
- Add reftrack @ref pvd_reftrack
|
||||
- Add header typemap.h to facilitate boilerplate switch() over ScalarType
|
||||
- Add epics::auto_ptr typedef in help writing code supporting both c++98 and c++11 w/o copious deprecation warnings.
|
||||
|
||||
|
||||
Release 6.0.1
|
||||
|
||||
@@ -30,7 +30,7 @@ static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
struct CreateRequestImpl {
|
||||
|
||||
struct Node
|
||||
struct Node
|
||||
{
|
||||
string name;
|
||||
vector<Node> nodes;
|
||||
@@ -55,7 +55,7 @@ struct CreateRequestImpl {
|
||||
|
||||
|
||||
CreateRequestImpl() {}
|
||||
|
||||
|
||||
|
||||
void removeBlanks(string& str)
|
||||
{
|
||||
@@ -129,7 +129,7 @@ struct CreateRequestImpl {
|
||||
if(pos==string::npos) break;
|
||||
numValues++;
|
||||
index = pos +1;
|
||||
}
|
||||
}
|
||||
vector<string> valueList(numValues,"");
|
||||
index=0;
|
||||
for(size_t i=0; i<numValues; i++) {
|
||||
@@ -483,4 +483,3 @@ PVStructure::shared_pointer createRequest(std::string const & request)
|
||||
|
||||
|
||||
}} // namespace
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ bool compare(const Structure& a, const Structure& b)
|
||||
if(&a==&b)
|
||||
return true;
|
||||
if (a.getID()!=b.getID())
|
||||
return false;
|
||||
return false;
|
||||
size_t nflds=a.getNumberFields();
|
||||
if (b.getNumberFields()!=nflds)
|
||||
return false;
|
||||
@@ -111,7 +111,7 @@ bool compare(const Union& a, const Union& b)
|
||||
if(&a==&b)
|
||||
return true;
|
||||
if (a.getID()!=b.getID())
|
||||
return false;
|
||||
return false;
|
||||
size_t nflds=a.getNumberFields();
|
||||
if (b.getNumberFields()!=nflds)
|
||||
return false;
|
||||
@@ -268,7 +268,7 @@ bool compareField(const PVUnion* left, const PVUnion* right)
|
||||
|
||||
if(*ls!=*right->getUnion())
|
||||
return false;
|
||||
|
||||
|
||||
if (ls->isVariant())
|
||||
{
|
||||
const PVField::const_shared_pointer& lval = left->get();
|
||||
|
||||
@@ -24,7 +24,7 @@ using std::tr1::static_pointer_cast;
|
||||
using std::size_t;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
|
||||
static std::vector<string> split(string commaSeparatedList) {
|
||||
@@ -60,7 +60,7 @@ void Convert::getString(string *buf,PVField const *pvField,int /*indentLevel*/)
|
||||
size_t Convert::fromString(PVStructurePtr const &pvStructure, StringArray const & from, size_t fromStartIndex)
|
||||
{
|
||||
size_t processed = 0;
|
||||
|
||||
|
||||
PVFieldPtrArray const & fieldsData = pvStructure->getPVFields();
|
||||
if (fieldsData.size() != 0) {
|
||||
size_t length = pvStructure->getStructure()->getNumberFields();
|
||||
@@ -93,7 +93,7 @@ size_t Convert::fromString(PVStructurePtr const &pvStructure, StringArray const
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,11 @@ Field::Field(Type type)
|
||||
|
||||
Field::~Field() {
|
||||
REFTRACE_DECREMENT(num_instances);
|
||||
FieldCreatePtr create(getFieldCreate());
|
||||
}
|
||||
|
||||
void Field::cacheCleanup()
|
||||
{
|
||||
const FieldCreatePtr& create(getFieldCreate());
|
||||
|
||||
Lock G(create->mutex);
|
||||
|
||||
@@ -109,7 +113,7 @@ std::tr1::shared_ptr<PVField> Field::build() const
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const Field& f)
|
||||
{
|
||||
return f.dump(o);
|
||||
return f.dump(o);
|
||||
};
|
||||
|
||||
Scalar::Scalar(ScalarType scalarType)
|
||||
@@ -119,7 +123,10 @@ Scalar::Scalar(ScalarType scalarType)
|
||||
THROW_EXCEPTION2(std::invalid_argument, "Can't construct Scalar from invalid ScalarType");
|
||||
}
|
||||
|
||||
Scalar::~Scalar(){}
|
||||
Scalar::~Scalar()
|
||||
{
|
||||
cacheCleanup();
|
||||
}
|
||||
|
||||
std::ostream& Scalar::dump(std::ostream& o) const
|
||||
{
|
||||
@@ -129,18 +136,18 @@ std::ostream& Scalar::dump(std::ostream& o) const
|
||||
string Scalar::getID() const
|
||||
{
|
||||
static const string idScalarLUT[] = {
|
||||
"boolean", // pvBoolean
|
||||
"byte", // pvByte
|
||||
"short", // pvShort
|
||||
"int", // pvInt
|
||||
"long", // pvLong
|
||||
"ubyte", // pvUByte
|
||||
"ushort", // pvUShort
|
||||
"uint", // pvUInt
|
||||
"ulong", // pvULong
|
||||
"float", // pvFloat
|
||||
"double", // pvDouble
|
||||
"string" // pvString
|
||||
"boolean", // pvBoolean
|
||||
"byte", // pvByte
|
||||
"short", // pvShort
|
||||
"int", // pvInt
|
||||
"long", // pvLong
|
||||
"ubyte", // pvUByte
|
||||
"ushort", // pvUShort
|
||||
"uint", // pvUInt
|
||||
"ulong", // pvULong
|
||||
"float", // pvFloat
|
||||
"double", // pvDouble
|
||||
"string" // pvString
|
||||
};
|
||||
return idScalarLUT[scalarType];
|
||||
}
|
||||
@@ -209,20 +216,21 @@ BoundedString::BoundedString(std::size_t maxStringLength) :
|
||||
THROW_EXCEPTION2(std::invalid_argument, "maxLength == 0");
|
||||
}
|
||||
|
||||
BoundedString::~BoundedString() {}
|
||||
BoundedString::~BoundedString()
|
||||
{
|
||||
cacheCleanup();
|
||||
}
|
||||
|
||||
|
||||
static string emptyStringtring;
|
||||
|
||||
static void serializeStructureField(const Structure* structure, ByteBuffer* buffer, SerializableControl* control)
|
||||
{
|
||||
// to optimize default (non-empty) IDs optimization
|
||||
// empty IDs are not allowed
|
||||
string id = structure->getID();
|
||||
if (id == Structure::DEFAULT_ID) // TODO slow comparison
|
||||
SerializeHelper::serializeString(emptyStringtring, buffer, control);
|
||||
else
|
||||
SerializeHelper::serializeString(id, buffer, control);
|
||||
// to optimize default (non-empty) IDs optimization
|
||||
// empty IDs are not allowed
|
||||
string id = structure->getID();
|
||||
if (id == Structure::DEFAULT_ID) // TODO slow comparison
|
||||
SerializeHelper::serializeString(string(), buffer, control);
|
||||
else
|
||||
SerializeHelper::serializeString(id, buffer, control);
|
||||
|
||||
FieldConstPtrArray const & fields = structure->getFields();
|
||||
StringArray const & fieldNames = structure->getFieldNames();
|
||||
@@ -250,18 +258,18 @@ static StructureConstPtr deserializeStructureField(const FieldCreate* fieldCreat
|
||||
if (id.empty())
|
||||
return fieldCreate->createStructure(fieldNames, fields);
|
||||
else
|
||||
return fieldCreate->createStructure(id, fieldNames, fields);
|
||||
return fieldCreate->createStructure(id, fieldNames, fields);
|
||||
}
|
||||
|
||||
static void serializeUnionField(const Union* punion, ByteBuffer* buffer, SerializableControl* control)
|
||||
{
|
||||
// to optimize default (non-empty) IDs optimization
|
||||
// empty IDs are not allowed
|
||||
string id = punion->getID();
|
||||
if (id == Union::DEFAULT_ID) // TODO slow comparison
|
||||
SerializeHelper::serializeString(emptyStringtring, buffer, control);
|
||||
else
|
||||
SerializeHelper::serializeString(id, buffer, control);
|
||||
// to optimize default (non-empty) IDs optimization
|
||||
// empty IDs are not allowed
|
||||
string id = punion->getID();
|
||||
if (id == Union::DEFAULT_ID) // TODO slow comparison
|
||||
SerializeHelper::serializeString(string(), buffer, control);
|
||||
else
|
||||
SerializeHelper::serializeString(id, buffer, control);
|
||||
|
||||
FieldConstPtrArray const & fields = punion->getFields();
|
||||
StringArray const & fieldNames = punion->getFieldNames();
|
||||
@@ -289,7 +297,7 @@ static UnionConstPtr deserializeUnionField(const FieldCreate* fieldCreate, ByteB
|
||||
if (id.empty())
|
||||
return fieldCreate->createUnion(fieldNames, fields);
|
||||
else
|
||||
return fieldCreate->createUnion(id, fieldNames, fields);
|
||||
return fieldCreate->createUnion(id, fieldNames, fields);
|
||||
}
|
||||
|
||||
Array::Array(Type type)
|
||||
@@ -307,23 +315,26 @@ ScalarArray::ScalarArray(ScalarType elementType)
|
||||
throw std::invalid_argument("Can't construct ScalarArray from invalid ScalarType");
|
||||
}
|
||||
|
||||
ScalarArray::~ScalarArray() {}
|
||||
ScalarArray::~ScalarArray()
|
||||
{
|
||||
cacheCleanup();
|
||||
}
|
||||
|
||||
const string ScalarArray::getIDScalarArrayLUT() const
|
||||
{
|
||||
static const string idScalarArrayLUT[] = {
|
||||
"boolean[]", // pvBoolean
|
||||
"byte[]", // pvByte
|
||||
"short[]", // pvShort
|
||||
"int[]", // pvInt
|
||||
"long[]", // pvLong
|
||||
"ubyte[]", // pvUByte
|
||||
"ushort[]", // pvUShort
|
||||
"uint[]", // pvUInt
|
||||
"ulong[]", // pvULong
|
||||
"float[]", // pvFloat
|
||||
"double[]", // pvDouble
|
||||
"string[]" // pvString
|
||||
"boolean[]", // pvBoolean
|
||||
"byte[]", // pvByte
|
||||
"short[]", // pvShort
|
||||
"int[]", // pvInt
|
||||
"long[]", // pvLong
|
||||
"ubyte[]", // pvUByte
|
||||
"ushort[]", // pvUShort
|
||||
"uint[]", // pvUInt
|
||||
"ulong[]", // pvULong
|
||||
"float[]", // pvFloat
|
||||
"double[]", // pvDouble
|
||||
"string[]" // pvString
|
||||
};
|
||||
return idScalarArrayLUT[elementType];
|
||||
}
|
||||
@@ -353,7 +364,10 @@ std::tr1::shared_ptr<PVScalarArray> ScalarArray::build() const
|
||||
}
|
||||
|
||||
|
||||
BoundedScalarArray::~BoundedScalarArray() {}
|
||||
BoundedScalarArray::~BoundedScalarArray()
|
||||
{
|
||||
cacheCleanup();
|
||||
}
|
||||
|
||||
BoundedScalarArray::BoundedScalarArray(ScalarType elementType, size_t size)
|
||||
: ScalarArray(elementType),
|
||||
@@ -375,7 +389,10 @@ void BoundedScalarArray::serialize(ByteBuffer *buffer, SerializableControl *cont
|
||||
}
|
||||
|
||||
|
||||
FixedScalarArray::~FixedScalarArray() {}
|
||||
FixedScalarArray::~FixedScalarArray()
|
||||
{
|
||||
cacheCleanup();
|
||||
}
|
||||
|
||||
FixedScalarArray::FixedScalarArray(ScalarType elementType, size_t size)
|
||||
: ScalarArray(elementType),
|
||||
@@ -403,11 +420,14 @@ StructureArray::StructureArray(StructureConstPtr const & structure)
|
||||
{
|
||||
}
|
||||
|
||||
StructureArray::~StructureArray() {}
|
||||
StructureArray::~StructureArray()
|
||||
{
|
||||
cacheCleanup();
|
||||
}
|
||||
|
||||
string StructureArray::getID() const
|
||||
{
|
||||
return pstructure->getID() + "[]";
|
||||
return pstructure->getID() + "[]";
|
||||
}
|
||||
|
||||
std::ostream& StructureArray::dump(std::ostream& o) const
|
||||
@@ -440,11 +460,14 @@ UnionArray::UnionArray(UnionConstPtr const & _punion)
|
||||
{
|
||||
}
|
||||
|
||||
UnionArray::~UnionArray() {}
|
||||
UnionArray::~UnionArray()
|
||||
{
|
||||
cacheCleanup();
|
||||
}
|
||||
|
||||
string UnionArray::getID() const
|
||||
{
|
||||
return punion->getID() + "[]";
|
||||
return punion->getID() + "[]";
|
||||
}
|
||||
|
||||
std::ostream& UnionArray::dump(std::ostream& o) const
|
||||
@@ -524,12 +547,15 @@ Structure::Structure (
|
||||
}
|
||||
}
|
||||
|
||||
Structure::~Structure() { }
|
||||
Structure::~Structure()
|
||||
{
|
||||
cacheCleanup();
|
||||
}
|
||||
|
||||
|
||||
string Structure::getID() const
|
||||
{
|
||||
return id;
|
||||
return id;
|
||||
}
|
||||
|
||||
FieldConstPtr Structure::getField(string const & fieldName) const {
|
||||
@@ -702,7 +728,10 @@ Union::Union (
|
||||
}
|
||||
}
|
||||
|
||||
Union::~Union() { }
|
||||
Union::~Union()
|
||||
{
|
||||
cacheCleanup();
|
||||
}
|
||||
|
||||
int32 Union::guess(Type t, ScalarType s) const
|
||||
{
|
||||
@@ -742,7 +771,7 @@ int32 Union::guess(Type t, ScalarType s) const
|
||||
|
||||
string Union::getID() const
|
||||
{
|
||||
return id;
|
||||
return id;
|
||||
}
|
||||
|
||||
FieldConstPtr Union::getField(string const & fieldName) const {
|
||||
@@ -937,7 +966,7 @@ FieldBuilder::FieldBuilder(const FieldBuilderPtr & _parentBuilder,
|
||||
{}
|
||||
|
||||
FieldBuilder::FieldBuilder(FieldBuilderPtr const & _parentBuilder,
|
||||
string const & _nestedName,
|
||||
string const & _nestedName,
|
||||
Type _nestedClassToBuild, bool _nestedArray)
|
||||
:fieldCreate(_parentBuilder->fieldCreate)
|
||||
,idSet(false)
|
||||
@@ -950,10 +979,10 @@ FieldBuilder::FieldBuilder(FieldBuilderPtr const & _parentBuilder,
|
||||
|
||||
void FieldBuilder::reset()
|
||||
{
|
||||
id.erase();
|
||||
id.erase();
|
||||
idSet = false;
|
||||
fieldNames.clear();
|
||||
fields.clear();
|
||||
fieldNames.clear();
|
||||
fields.clear();
|
||||
}
|
||||
|
||||
FieldBuilderPtr FieldBuilder::begin()
|
||||
@@ -972,7 +1001,7 @@ FieldBuilderPtr FieldBuilder::begin(StructureConstPtr S)
|
||||
FieldBuilderPtr FieldBuilder::setId(string const & id)
|
||||
{
|
||||
this->id = id;
|
||||
idSet = true;
|
||||
idSet = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
@@ -994,7 +1023,7 @@ FieldBuilderPtr FieldBuilder::add(string const & name, FieldConstPtr const & fie
|
||||
} else if(*cur!=*field) {
|
||||
THROW_EXCEPTION2(std::runtime_error, "duplicate field name w/ different type : "+name);
|
||||
} // else exact duplicate is silently ignored
|
||||
return shared_from_this();
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
FieldBuilderPtr FieldBuilder::addArray(string const & name, ScalarType scalarType)
|
||||
@@ -1036,7 +1065,7 @@ FieldBuilderPtr FieldBuilder::addArray(string const & name, FieldConstPtr const
|
||||
msg << element->getType();
|
||||
THROW_EXCEPTION2(std::invalid_argument, msg.str());
|
||||
}
|
||||
|
||||
|
||||
return add(name, fld);
|
||||
}
|
||||
|
||||
@@ -1071,7 +1100,7 @@ StructureConstPtr FieldBuilder::createStructure()
|
||||
{
|
||||
if (parentBuilder.get())
|
||||
THROW_EXCEPTION2(std::runtime_error, "createStructure() called in nested FieldBuilder");
|
||||
|
||||
|
||||
StructureConstPtr field(static_pointer_cast<const Structure>(createFieldInternal(structure)));
|
||||
reset();
|
||||
return field;
|
||||
@@ -1081,7 +1110,7 @@ UnionConstPtr FieldBuilder::createUnion()
|
||||
{
|
||||
if (parentBuilder.get())
|
||||
THROW_EXCEPTION2(std::runtime_error, "createUnion() called in nested FieldBuilder");
|
||||
|
||||
|
||||
UnionConstPtr field(static_pointer_cast<const Union>(createFieldInternal(union_)));
|
||||
reset();
|
||||
return field;
|
||||
@@ -1149,7 +1178,7 @@ FieldBuilderPtr FieldBuilder::endNested()
|
||||
{
|
||||
if (!parentBuilder)
|
||||
THROW_EXCEPTION2(std::runtime_error, "FieldBuilder::endNested() can only be called to create nested fields");
|
||||
|
||||
|
||||
FieldConstPtr nestedField = createFieldInternal(nestedClassToBuild);
|
||||
|
||||
if(createNested) {
|
||||
@@ -1217,7 +1246,7 @@ ScalarArrayConstPtr FieldCreate::createScalarArray(ScalarType elementType) const
|
||||
strm << elementType;
|
||||
THROW_EXCEPTION2(std::invalid_argument, strm.str());
|
||||
}
|
||||
|
||||
|
||||
return scalarArrays[elementType];
|
||||
}
|
||||
|
||||
@@ -1419,7 +1448,7 @@ static int decodeScalar(int8 code)
|
||||
pvUInt, // unsigned 32-bits
|
||||
pvULong // unsigned 64-bits
|
||||
};
|
||||
|
||||
|
||||
static const int floatLUT[] =
|
||||
{
|
||||
-1, // reserved
|
||||
@@ -1626,4 +1655,3 @@ namespace std{
|
||||
return o << "nullptr";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ PVArray::PVArray(FieldConstPtr const & field)
|
||||
{
|
||||
capacityMutable = false;
|
||||
PVField::setImmutable();
|
||||
}
|
||||
}
|
||||
|
||||
bool PVArray::isCapacityMutable() const
|
||||
{
|
||||
@@ -49,7 +49,7 @@ PVArray::PVArray(FieldConstPtr const & field)
|
||||
|
||||
std::ostream& operator<<(format::array_at_internal const& manip, const PVArray& array)
|
||||
{
|
||||
return array.dumpValue(manip.stream, manip.index);
|
||||
return array.dumpValue(manip.stream, manip.index);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -144,8 +144,7 @@ PVString::PVString(ScalarConstPtr const & scalar)
|
||||
|
||||
std::ostream& PVString::dumpValue(std::ostream& o) const
|
||||
{
|
||||
// we escape, but do not quote, for scalar string
|
||||
o<<escape(get());
|
||||
o<<maybeQuote(get());
|
||||
return o;
|
||||
}
|
||||
|
||||
@@ -160,17 +159,17 @@ void PVString::serialize(ByteBuffer *pbuffer,
|
||||
void PVString::serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher, size_t offset, size_t count) const
|
||||
{
|
||||
// check bounds
|
||||
// check bounds
|
||||
const size_t length = storage.value.length();
|
||||
/*if (offset < 0) offset = 0;
|
||||
else*/ if (offset > length) offset = length;
|
||||
//if (count < 0) count = length;
|
||||
/*if (offset < 0) offset = 0;
|
||||
else*/ if (offset > length) offset = length;
|
||||
//if (count < 0) count = length;
|
||||
|
||||
const size_t maxCount = length - offset;
|
||||
if (count > maxCount)
|
||||
count = maxCount;
|
||||
|
||||
// write
|
||||
const size_t maxCount = length - offset;
|
||||
if (count > maxCount)
|
||||
count = maxCount;
|
||||
|
||||
// write
|
||||
SerializeHelper::serializeSubstring(storage.value, offset, count, pbuffer, pflusher);
|
||||
}
|
||||
|
||||
@@ -191,7 +190,7 @@ template<typename T>
|
||||
PVValueArray<T>::PVValueArray(ScalarArrayConstPtr const & scalarArray)
|
||||
:base_t(scalarArray)
|
||||
,value()
|
||||
|
||||
|
||||
{}
|
||||
|
||||
PVValueArray<PVStructurePtr>::PVValueArray(StructureArrayConstPtr const & structureArray)
|
||||
@@ -233,7 +232,7 @@ std::ostream& PVValueArray<T>::dumpValue(std::ostream& o) const
|
||||
template<>
|
||||
std::ostream& PVValueArray<std::string>::dumpValue(std::ostream& o, size_t index) const
|
||||
{
|
||||
return o << '"' << escape(this->view().at(index)) << '"';
|
||||
return o << maybeQuote(this->view().at(index));
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -244,9 +243,9 @@ std::ostream& PVValueArray<std::string>::dumpValue(std::ostream& o) const
|
||||
end(v.end());
|
||||
o << '[';
|
||||
if(it!=end) {
|
||||
o << '"' << escape(*it++) << '"';
|
||||
o << maybeQuote(*it++);
|
||||
for(; it!=end; ++it)
|
||||
o << ", \"" << escape(*it) << '"';
|
||||
o << ", " << maybeQuote(*it);
|
||||
|
||||
}
|
||||
return o << ']';
|
||||
@@ -627,7 +626,7 @@ PVScalarArrayPtr PVDataCreate::createPVScalarArray(
|
||||
return PVScalarArrayPtr(new PVStringArray(scalarArray));
|
||||
}
|
||||
throw std::logic_error("PVDataCreate::createPVScalarArray should never get here");
|
||||
|
||||
|
||||
}
|
||||
|
||||
PVScalarArrayPtr PVDataCreate::createPVScalarArray(
|
||||
@@ -780,4 +779,3 @@ namespace std{
|
||||
return o << "nullptr";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ size_t PVField::getNumberFields() const
|
||||
|
||||
void PVField::setImmutable() {immutable = true;}
|
||||
|
||||
void PVField::postPut()
|
||||
void PVField::postPut()
|
||||
{
|
||||
if(postHandler) postHandler->postPut();
|
||||
}
|
||||
@@ -91,7 +91,7 @@ bool PVField::equals(PVField &pv)
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const PVField& f)
|
||||
{
|
||||
return f.dumpValue(o);
|
||||
return f.dumpValue(o);
|
||||
};
|
||||
|
||||
string PVField::getFullName() const
|
||||
|
||||
@@ -38,7 +38,7 @@ PVStructure::PVStructure(StructureConstPtr const & structurePtr)
|
||||
pvFields.push_back(pvDataCreate->createPVField(fields[i]));
|
||||
}
|
||||
for(size_t i=0; i<numberFields; i++) {
|
||||
pvFields[i]->setParentAndName(this,fieldNames[i]);
|
||||
pvFields[i]->setParentAndName(this,fieldNames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ PVFieldPtr PVStructure::getSubFieldImpl(const char *name, bool throws) const
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field: " << fullName << " ("
|
||||
<< std::string(fullName, sep) << " not found)";
|
||||
throw std::runtime_error(ss.str());
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
else
|
||||
return PVFieldPtr();
|
||||
@@ -184,7 +184,7 @@ PVFieldPtr PVStructure::getSubFieldImpl(const char *name, bool throws) const
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field: " << fullName
|
||||
<< " (" << std::string(fullName, sep)
|
||||
<< " is not a structure)";
|
||||
<< " is not a structure)";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
else
|
||||
@@ -307,22 +307,22 @@ std::ostream& PVStructure::dumpValue(std::ostream& o) const
|
||||
o << format::indent() << getStructure()->getID() << ' ' << getFieldName();
|
||||
o << std::endl;
|
||||
{
|
||||
format::indent_scope s(o);
|
||||
format::indent_scope s(o);
|
||||
|
||||
PVFieldPtrArray const & fieldsData = getPVFields();
|
||||
if (fieldsData.size() != 0) {
|
||||
size_t length = getStructure()->getNumberFields();
|
||||
for(size_t i=0; i<length; i++) {
|
||||
PVFieldPtr fieldField = fieldsData[i];
|
||||
Type type = fieldField->getField()->getType();
|
||||
if (type == scalar || type == scalarArray)
|
||||
o << format::indent() << fieldField->getField()->getID() << ' ' << fieldField->getFieldName() << ' ' << *(fieldField.get()) << std::endl;
|
||||
else
|
||||
o << *(fieldField.get());
|
||||
}
|
||||
}
|
||||
PVFieldPtrArray const & fieldsData = getPVFields();
|
||||
if (fieldsData.size() != 0) {
|
||||
size_t length = getStructure()->getNumberFields();
|
||||
for(size_t i=0; i<length; i++) {
|
||||
PVFieldPtr fieldField = fieldsData[i];
|
||||
Type type = fieldField->getField()->getType();
|
||||
if (type == scalar || type == scalarArray)
|
||||
o << format::indent() << fieldField->getField()->getID() << ' ' << fieldField->getFieldName() << ' ' << *(fieldField.get()) << std::endl;
|
||||
else
|
||||
o << *(fieldField.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
return o;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -218,10 +218,10 @@ std::ostream& PVStructureArray::dumpValue(std::ostream& o) const
|
||||
size_t length = getLength();
|
||||
if (length > 0)
|
||||
{
|
||||
format::indent_scope s(o);
|
||||
format::indent_scope s(o);
|
||||
|
||||
for (size_t i = 0; i < length; i++)
|
||||
dumpValue(o, i);
|
||||
dumpValue(o, i);
|
||||
}
|
||||
|
||||
return o;
|
||||
|
||||
@@ -23,7 +23,7 @@ using std::size_t;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
|
||||
#define PVUNION_UNDEFINED_INDEX -1
|
||||
const int32 PVUnion::UNDEFINED_INDEX = PVUNION_UNDEFINED_INDEX;
|
||||
|
||||
@@ -75,13 +75,13 @@ PVFieldPtr PVUnion::select(int32 index)
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
PVFieldPtr PVUnion::select(string const & fieldName)
|
||||
{
|
||||
int32 index = variant ? -1 : static_cast<int32>(unionPtr->getFieldIndex(fieldName));
|
||||
if (index == -1)
|
||||
if (index == -1)
|
||||
throw std::invalid_argument("no such fieldName");
|
||||
return select(index);
|
||||
return select(index);
|
||||
}
|
||||
|
||||
void PVUnion::set(int32 index, PVFieldPtr const & value)
|
||||
@@ -94,14 +94,14 @@ void PVUnion::set(int32 index, PVFieldPtr const & value)
|
||||
{
|
||||
// for undefined index we accept only null values
|
||||
if (value)
|
||||
throw std::invalid_argument("non-null value for index == UNDEFINED_INDEX");
|
||||
throw std::invalid_argument("non-null value for index == UNDEFINED_INDEX");
|
||||
}
|
||||
else if (index < 0 || size_t(index) >= unionPtr->getFields().size())
|
||||
throw std::invalid_argument("index out of bounds");
|
||||
else if (!value)
|
||||
throw std::invalid_argument("Can't set defined index w/ NULL");
|
||||
else if (value->getField() != unionPtr->getField(index))
|
||||
throw std::invalid_argument("selected field and its introspection data do not match");
|
||||
throw std::invalid_argument("selected field and its introspection data do not match");
|
||||
}
|
||||
|
||||
selector = index;
|
||||
@@ -136,7 +136,7 @@ void PVUnion::serialize(ByteBuffer *pbuffer, SerializableControl *pflusher) cons
|
||||
// write selector value
|
||||
SerializeHelper::writeSize(selector, pbuffer, pflusher);
|
||||
// write value, no value for UNDEFINED_INDEX
|
||||
if (selector != UNDEFINED_INDEX)
|
||||
if (selector != UNDEFINED_INDEX)
|
||||
value->serialize(pbuffer, pflusher);
|
||||
}
|
||||
}
|
||||
@@ -180,20 +180,20 @@ std::ostream& PVUnion::dumpValue(std::ostream& o) const
|
||||
{
|
||||
o << format::indent() << getUnion()->getID() << ' ' << getFieldName() << std::endl;
|
||||
{
|
||||
format::indent_scope s(o);
|
||||
format::indent_scope s(o);
|
||||
const PVField::const_shared_pointer& fieldField = get();
|
||||
if (fieldField.get() == NULL)
|
||||
o << format::indent() << "(none)" << std::endl;
|
||||
else
|
||||
{
|
||||
Type type = fieldField->getField()->getType();
|
||||
if (type == scalar || type == scalarArray)
|
||||
o << format::indent() << fieldField->getField()->getID() << ' ' << fieldField->getFieldName() << ' ' << *(fieldField.get()) << std::endl;
|
||||
else
|
||||
o << *(fieldField.get());
|
||||
}
|
||||
if (fieldField.get() == NULL)
|
||||
o << format::indent() << "(none)" << std::endl;
|
||||
else
|
||||
{
|
||||
Type type = fieldField->getField()->getType();
|
||||
if (type == scalar || type == scalarArray)
|
||||
o << format::indent() << fieldField->getField()->getID() << ' ' << fieldField->getFieldName() << ' ' << *(fieldField.get()) << std::endl;
|
||||
else
|
||||
o << *(fieldField.get());
|
||||
}
|
||||
}
|
||||
return o;
|
||||
return o;
|
||||
}
|
||||
|
||||
void PVUnion::copy(const PVUnion& from)
|
||||
|
||||
@@ -217,10 +217,10 @@ std::ostream& PVUnionArray::dumpValue(std::ostream& o) const
|
||||
size_t length = getLength();
|
||||
if (length > 0)
|
||||
{
|
||||
format::indent_scope s(o);
|
||||
format::indent_scope s(o);
|
||||
|
||||
for (size_t i = 0; i < length; i++)
|
||||
dumpValue(o, i);
|
||||
dumpValue(o, i);
|
||||
}
|
||||
|
||||
return o;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static
|
||||
StructureConstPtr buildValueAlarm(ScalarType vtype)
|
||||
@@ -123,8 +123,8 @@ StructureConstPtr StandardField::createProperties(string id,FieldConstPtr field,
|
||||
while(gotValueAlarm) {
|
||||
if(type==epics::pvData::scalar || type==epics::pvData::scalarArray) {
|
||||
ScalarType scalarType = (type==epics::pvData::scalar) ?
|
||||
static_pointer_cast<const Scalar>(field)->getScalarType() :
|
||||
static_pointer_cast<const ScalarArray>(field)->getElementType();
|
||||
static_pointer_cast<const Scalar>(field)->getScalarType() :
|
||||
static_pointer_cast<const ScalarArray>(field)->getElementType();
|
||||
switch(scalarType) {
|
||||
case pvBoolean: valueAlarm = booleanAlarmField; break;
|
||||
case pvByte: valueAlarm = byteAlarmField; break;
|
||||
@@ -157,7 +157,7 @@ StructureConstPtr StandardField::createProperties(string id,FieldConstPtr field,
|
||||
if(first->getType()==epics::pvData::scalar
|
||||
&& second->getType()==epics::pvData::scalarArray) {
|
||||
ScalarConstPtr scalarFirst = static_pointer_cast<const Scalar>(first);
|
||||
ScalarArrayConstPtr scalarArraySecond =
|
||||
ScalarArrayConstPtr scalarArraySecond =
|
||||
static_pointer_cast<const ScalarArray>(second);
|
||||
if(scalarFirst->getScalarType()==pvInt
|
||||
&& scalarArraySecond->getElementType()==pvString) {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
StandardPVField::StandardPVField()
|
||||
: standardField(getStandardField()),
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace ScalarTypeFunc {
|
||||
if(type>=pvBoolean && type<=pvDouble) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static const char* names[] = {
|
||||
"boolean",
|
||||
"byte", "short", "int", "long",
|
||||
|
||||
@@ -19,9 +19,7 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/bitSet.h>
|
||||
#include <pv/pvData.h>
|
||||
#if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1)
|
||||
# include <pv/json.h>
|
||||
#endif
|
||||
#include <pv/json.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
@@ -173,7 +171,7 @@ bool printEnumT(std::ostream& strm, const PVStructure& top, bool fromtop)
|
||||
if(I>=ch.size()) {
|
||||
strm<<" <undefined>";
|
||||
} else {
|
||||
strm<<' '<<escape(ch[I]);
|
||||
strm<<' '<<maybeQuote(ch[I]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -182,7 +180,7 @@ void csvEscape(std::string& S)
|
||||
{
|
||||
// concise, not particularly efficient...
|
||||
std::string temp(escape(S).style(escape::CSV).str());
|
||||
if(S.find_first_of(" ,\\")!=S.npos) {// only quote if necessary (stupid Excel)
|
||||
if(S.find_first_of("\" ,\\")!=S.npos) {// only quote if necessary (stupid Excel)
|
||||
std::string temp2;
|
||||
temp2.reserve(temp.size()+2);
|
||||
temp2.push_back('\"');
|
||||
@@ -190,7 +188,7 @@ void csvEscape(std::string& S)
|
||||
temp2.push_back('\"');
|
||||
temp2.swap(temp);
|
||||
}
|
||||
S = temp;
|
||||
S.swap(temp);
|
||||
}
|
||||
|
||||
bool printTable(std::ostream& strm, const PVStructure& top)
|
||||
@@ -404,15 +402,11 @@ void printRaw(std::ostream& strm, const PVStructure::Formatter& format, const PV
|
||||
std::ostream& operator<<(std::ostream& strm, const PVStructure::Formatter& format)
|
||||
{
|
||||
if(format.xfmt==PVStructure::Formatter::JSON) {
|
||||
#if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1)
|
||||
JSONPrintOptions opts;
|
||||
opts.multiLine = false;
|
||||
printJSON(strm, format.xtop, format.xshow ? *format.xshow : BitSet().set(0), opts);
|
||||
strm<<'\n';
|
||||
return strm;
|
||||
#else
|
||||
// fall through to Raw
|
||||
#endif
|
||||
|
||||
} else if(format.xfmt==PVStructure::Formatter::NT) {
|
||||
std::string id(format.xtop.getStructure()->getID()),
|
||||
@@ -520,4 +514,38 @@ std::ostream& operator<<(std::ostream& strm, const escape& Q)
|
||||
return strm;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& strm, const maybeQuote& q)
|
||||
{
|
||||
bool esc = false;
|
||||
for(size_t i=0, N=q.s.size(); i<N && !esc; i++) {
|
||||
switch(q.s[i]) {
|
||||
case '\a':
|
||||
case '\b':
|
||||
case '\f':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
case ' ':
|
||||
case '\v':
|
||||
case '\\':
|
||||
case '\'':
|
||||
case '\"':
|
||||
esc = true;
|
||||
break;
|
||||
default:
|
||||
if(!isprint(q.s[i])) {
|
||||
esc = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(esc) {
|
||||
strm<<'"'<<escape(q.s)<<'"';
|
||||
} else {
|
||||
strm<<q.s;
|
||||
}
|
||||
return strm;
|
||||
}
|
||||
|
||||
}} //epics::pvData
|
||||
|
||||
@@ -17,7 +17,7 @@ using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
template<typename T>
|
||||
void copy(
|
||||
@@ -272,4 +272,3 @@ void copy(
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/valueBuilder.h>
|
||||
|
||||
#if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1)
|
||||
|
||||
#include "pv/json.h"
|
||||
|
||||
namespace pvd = epics::pvData;
|
||||
@@ -280,5 +278,3 @@ parseJSON(std::istream& strm)
|
||||
}
|
||||
|
||||
}} // namespace epics::pvData
|
||||
|
||||
#endif // EPICS_VERSION_INT
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvdVersion.h>
|
||||
|
||||
#if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1)
|
||||
|
||||
#include "pv/json.h"
|
||||
|
||||
namespace {
|
||||
@@ -118,5 +116,3 @@ bool yajl_parse_helper(std::istream& src,
|
||||
}
|
||||
|
||||
}} // namespace epics::pvData
|
||||
|
||||
#endif // EPICS_VERSION_INT
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/valueBuilder.h>
|
||||
#include <pv/bitSet.h>
|
||||
|
||||
#if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1)
|
||||
|
||||
#include "pv/json.h"
|
||||
|
||||
namespace pvd = epics::pvData;
|
||||
@@ -347,6 +344,3 @@ void parseJSON(std::istream& strm,
|
||||
}
|
||||
|
||||
}} // namespace epics::pvData
|
||||
|
||||
#endif // EPICS_VERSION_INT
|
||||
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/valueBuilder.h>
|
||||
#include <pv/bitSet.h>
|
||||
|
||||
#if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1)
|
||||
|
||||
#include "pv/json.h"
|
||||
|
||||
namespace pvd = epics::pvData;
|
||||
@@ -232,5 +229,3 @@ void printJSON(std::ostream& strm,
|
||||
}
|
||||
|
||||
}} // namespace epics::pvData
|
||||
|
||||
#endif // EPICS_VERSION_INT
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include <pv/pvdVersion.h>
|
||||
#include <pv/pvData.h>
|
||||
|
||||
#if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1)
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define pvjson_epicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
@@ -147,8 +145,4 @@ typedef size_t size_arg;
|
||||
|
||||
}} // namespace epics::pvData
|
||||
|
||||
#else
|
||||
# error JSON parser requires EPICS Base >= 3.15.0.1
|
||||
#endif // EPICS_VERSION_INT
|
||||
|
||||
#endif // PV_JSON_H
|
||||
|
||||
@@ -42,12 +42,12 @@
|
||||
#define CHECK_POST() assert(words.empty() || words.back()!=0)
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
|
||||
BitSet::shared_pointer BitSet::create(uint32 nbits)
|
||||
{
|
||||
return BitSet::shared_pointer(new BitSet(nbits));
|
||||
}
|
||||
|
||||
|
||||
BitSet::BitSet() {}
|
||||
|
||||
BitSet::BitSet(uint32 nbits)
|
||||
@@ -327,7 +327,7 @@ namespace epics { namespace pvData {
|
||||
SerializeHelper::writeSize(len, buffer, flusher);
|
||||
flusher->ensureBuffer(len);
|
||||
|
||||
n = len / 8;
|
||||
n = len / 8;
|
||||
for (uint32 i = 0; i < n; i++)
|
||||
buffer->putLong(words[i]);
|
||||
|
||||
@@ -338,7 +338,7 @@ namespace epics { namespace pvData {
|
||||
|
||||
void BitSet::deserialize(ByteBuffer* buffer, DeserializableControl* control) {
|
||||
|
||||
uint32 bytes = static_cast<uint32>(SerializeHelper::readSize(buffer, control)); // in bytes
|
||||
uint32 bytes = static_cast<uint32>(SerializeHelper::readSize(buffer, control)); // in bytes
|
||||
|
||||
size_t wordsInUse = (bytes + 7) / BYTES_PER_WORD;
|
||||
words.resize(wordsInUse);
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
|
||||
Event::~Event() {
|
||||
|
||||
@@ -25,406 +25,6 @@ using std::string;
|
||||
#define NEED_LONGLONG
|
||||
#endif
|
||||
|
||||
#ifndef EPICS_VERSION_INT
|
||||
#define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P))
|
||||
#define EPICS_VERSION_INT VERSION_INT(EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL)
|
||||
#endif
|
||||
|
||||
#if EPICS_VERSION_INT < VERSION_INT(3,15,0,1)
|
||||
/* These integer conversion primitives added to epicsStdlib.c in 3.15.0.1 */
|
||||
|
||||
#define S_stdlib_noConversion 1 /* No digits to convert */
|
||||
#define S_stdlib_extraneous 2 /* Extraneous characters */
|
||||
#define S_stdlib_underflow 3 /* Too small to represent */
|
||||
#define S_stdlib_overflow 4 /* Too large to represent */
|
||||
#define S_stdlib_badBase 5 /* Number base not supported */
|
||||
|
||||
static int
|
||||
epicsParseLong(const char *str, long *to, int base, char **units)
|
||||
{
|
||||
int c;
|
||||
char *endp;
|
||||
long value;
|
||||
|
||||
while ((c = *str) && isspace(c))
|
||||
++str;
|
||||
|
||||
errno = 0;
|
||||
value = strtol(str, &endp, base);
|
||||
|
||||
if (endp == str)
|
||||
return S_stdlib_noConversion;
|
||||
if (errno == EINVAL) /* Not universally supported */
|
||||
return S_stdlib_badBase;
|
||||
if (errno == ERANGE)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
while ((c = *endp) && isspace(c))
|
||||
++endp;
|
||||
if (c && !units)
|
||||
return S_stdlib_extraneous;
|
||||
|
||||
*to = value;
|
||||
if (units)
|
||||
*units = endp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseULong(const char *str, unsigned long *to, int base, char **units)
|
||||
{
|
||||
int c;
|
||||
char *endp;
|
||||
unsigned long value;
|
||||
|
||||
while ((c = *str) && isspace(c))
|
||||
++str;
|
||||
|
||||
errno = 0;
|
||||
value = strtoul(str, &endp, base);
|
||||
|
||||
if (endp == str)
|
||||
return S_stdlib_noConversion;
|
||||
if (errno == EINVAL) /* Not universally supported */
|
||||
return S_stdlib_badBase;
|
||||
if (errno == ERANGE)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
while ((c = *endp) && isspace(c))
|
||||
++endp;
|
||||
if (c && !units)
|
||||
return S_stdlib_extraneous;
|
||||
|
||||
*to = value;
|
||||
if (units)
|
||||
*units = endp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseDouble(const char *str, double *to, char **units)
|
||||
{
|
||||
int c;
|
||||
char *endp;
|
||||
double value;
|
||||
|
||||
while ((c = *str) && isspace(c))
|
||||
++str;
|
||||
|
||||
errno = 0;
|
||||
value = epicsStrtod(str, &endp);
|
||||
|
||||
if (endp == str)
|
||||
return S_stdlib_noConversion;
|
||||
if (errno == ERANGE)
|
||||
return (value == 0) ? S_stdlib_underflow : S_stdlib_overflow;
|
||||
|
||||
while ((c = *endp) && isspace(c))
|
||||
++endp;
|
||||
if (c && !units)
|
||||
return S_stdlib_extraneous;
|
||||
|
||||
*to = value;
|
||||
if (units)
|
||||
*units = endp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* These call the primitives */
|
||||
|
||||
static int
|
||||
epicsParseInt8(const char *str, epicsInt8 *to, int base, char **units)
|
||||
{
|
||||
long value;
|
||||
int status = epicsParseLong(str, &value, base, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (value < -0x80 || value > 0x7f)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
*to = (epicsInt8)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseUInt8(const char *str, epicsUInt8 *to, int base, char **units)
|
||||
{
|
||||
unsigned long value;
|
||||
int status = epicsParseULong(str, &value, base, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (value > 0xff && value <= ~0xffUL)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
*to = (epicsUInt8)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseInt16(const char *str, epicsInt16 *to, int base, char **units)
|
||||
{
|
||||
long value;
|
||||
int status = epicsParseLong(str, &value, base, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (value < -0x8000 || value > 0x7fff)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
*to = (epicsInt16)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseUInt16(const char *str, epicsUInt16 *to, int base, char **units)
|
||||
{
|
||||
unsigned long value;
|
||||
int status = epicsParseULong(str, &value, base, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (value > 0xffff && value <= ~0xffffUL)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
*to = (epicsUInt16)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseInt32(const char *str, epicsInt32 *to, int base, char **units)
|
||||
{
|
||||
long value;
|
||||
int status = epicsParseLong(str, &value, base, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
#if (LONG_MAX > 0x7fffffff)
|
||||
if (value < -0x80000000L || value > 0x7fffffffL)
|
||||
return S_stdlib_overflow;
|
||||
#endif
|
||||
|
||||
*to = (epicsInt32)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseUInt32(const char *str, epicsUInt32 *to, int base, char **units)
|
||||
{
|
||||
unsigned long value;
|
||||
int status = epicsParseULong(str, &value, base, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
#if (ULONG_MAX > 0xffffffff)
|
||||
if (value > 0xffffffffUL && value <= ~0xffffffffUL)
|
||||
return S_stdlib_overflow;
|
||||
#endif
|
||||
|
||||
*to = (epicsUInt32)value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
epicsParseFloat(const char *str, float *to, char **units)
|
||||
{
|
||||
double value, abs;
|
||||
int status = epicsParseDouble(str, &value, units);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
abs = fabs(value);
|
||||
if (value > 0 && abs <= FLT_MIN)
|
||||
return S_stdlib_underflow;
|
||||
if (finite(value) && abs >= FLT_MAX)
|
||||
return S_stdlib_overflow;
|
||||
|
||||
*to = (float)value;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Sometimes we have to provide our own copy of strtoll()
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||
// On Windows with MSVC, Base-3.15 provides strtoll()
|
||||
# define NEED_OLL_FUNCS (EPICS_VERSION_INT < VERSION_INT(3,15,0,1))
|
||||
#elif defined(vxWorks)
|
||||
// On VxWorks, Base-3.15 provides strtoll()
|
||||
# define NEED_OLL_FUNCS (EPICS_VERSION_INT < VERSION_INT(3,15,0,1))
|
||||
#else
|
||||
// Other architectures all provide strtoll()
|
||||
# define NEED_OLL_FUNCS 0
|
||||
#endif
|
||||
|
||||
#if defined(NEED_LONGLONG) && NEED_OLL_FUNCS
|
||||
static
|
||||
long long strtoll(const char *ptr, char ** endp, int base)
|
||||
{
|
||||
size_t inlen = strlen(ptr);
|
||||
long long result;
|
||||
unsigned char offset=0;
|
||||
|
||||
assert(base==0);
|
||||
|
||||
if(ptr[0]=='-')
|
||||
offset=1;
|
||||
|
||||
try {
|
||||
std::istringstream strm(ptr);
|
||||
|
||||
assert(strm.rdbuf()->in_avail()>=0
|
||||
&& inlen==(size_t)strm.rdbuf()->in_avail());
|
||||
|
||||
if(ptr[offset]=='0') {
|
||||
if(ptr[offset+1]=='x')
|
||||
strm >> std::hex;
|
||||
else
|
||||
strm >> std::oct;
|
||||
}
|
||||
|
||||
strm >> result;
|
||||
if(strm.fail())
|
||||
goto noconvert;
|
||||
|
||||
assert(strm.rdbuf()->in_avail()>=0
|
||||
&& inlen>=(size_t)strm.rdbuf()->in_avail());
|
||||
|
||||
size_t consumed = inlen - strm.rdbuf()->in_avail();
|
||||
*endp = (char*)ptr + consumed;
|
||||
|
||||
return result;
|
||||
|
||||
} catch(...) {
|
||||
goto noconvert;
|
||||
}
|
||||
|
||||
return result;
|
||||
noconvert:
|
||||
*endp = (char*)ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(vxWorks)
|
||||
/* The VxWorks version of std::istringstream >> uint64_t is buggy,
|
||||
* provide our own implementation
|
||||
*/
|
||||
static
|
||||
unsigned long long strtoull(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s = nptr;
|
||||
unsigned long long acc;
|
||||
int c;
|
||||
unsigned long long cutoff;
|
||||
int neg = 0, any, cutlim;
|
||||
|
||||
do
|
||||
c = *s++;
|
||||
while (isspace(c));
|
||||
if (c == '-')
|
||||
{
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
}
|
||||
else if (c == '+')
|
||||
c = *s++;
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X'))
|
||||
{
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
cutoff = (unsigned long long) UINT64_MAX / (unsigned long long) base;
|
||||
cutlim = (unsigned long long) UINT64_MAX % (unsigned long long) base;
|
||||
|
||||
for (acc = 0, any = 0;; c = *s++)
|
||||
{
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else
|
||||
{
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0)
|
||||
{
|
||||
acc = UINT64_MAX;
|
||||
errno = ERANGE;
|
||||
}
|
||||
else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = any ? (char *) s - 1 : (char *) nptr;
|
||||
return (acc);
|
||||
}
|
||||
#else
|
||||
static
|
||||
unsigned long long strtoull(const char *ptr, char ** endp, int base)
|
||||
{
|
||||
size_t inlen = strlen(ptr);
|
||||
unsigned long long result;
|
||||
|
||||
assert(base==0);
|
||||
|
||||
try {
|
||||
std::istringstream strm(ptr);
|
||||
|
||||
assert(strm.rdbuf()->in_avail()>=0
|
||||
&& inlen==(size_t)strm.rdbuf()->in_avail());
|
||||
|
||||
if(ptr[0]=='0') {
|
||||
if(ptr[1]=='x')
|
||||
strm >> std::hex;
|
||||
else
|
||||
strm >> std::oct;
|
||||
}
|
||||
|
||||
strm >> result;
|
||||
if(strm.fail())
|
||||
goto noconvert;
|
||||
|
||||
assert(strm.rdbuf()->in_avail()>=0
|
||||
&& inlen>=(size_t)strm.rdbuf()->in_avail());
|
||||
|
||||
size_t consumed = inlen - strm.rdbuf()->in_avail();
|
||||
*endp = (char*)ptr + consumed;
|
||||
|
||||
return result;
|
||||
|
||||
} catch(...) {
|
||||
goto noconvert;
|
||||
}
|
||||
|
||||
return result;
|
||||
noconvert:
|
||||
*endp = (char*)ptr;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* do we need long long? */
|
||||
#ifdef NEED_LONGLONG
|
||||
static int
|
||||
|
||||
@@ -494,23 +494,6 @@ public:
|
||||
{
|
||||
return sizeof(T)>1 && _reverseEndianess;
|
||||
}
|
||||
/**
|
||||
* Adjust position to the next multiple of 'size.
|
||||
* @param size The alignment requirement, must be a power of 2. (unchecked)
|
||||
* @param fill value to use for padding bytes (default '\0').
|
||||
*
|
||||
* @note This alignment is absolute, not necessarily with respect to _buffer.
|
||||
*/
|
||||
inline void align(std::size_t size, char fill='\0')
|
||||
{
|
||||
const std::size_t k = size - 1, bufidx = (std::size_t)_position;
|
||||
if(bufidx&k) {
|
||||
std::size_t npad = size-(bufidx&k);
|
||||
assert(npad<=getRemaining());
|
||||
std::fill(_position, _position+npad, fill);
|
||||
_position += npad;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Put a boolean value into the byte buffer.
|
||||
*
|
||||
|
||||
@@ -207,7 +207,7 @@ public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
explicit BaseException(const std::string msg) : std::logic_error(msg) {}
|
||||
explicit BaseException(const std::string& msg) : std::logic_error(msg) {}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@@ -229,7 +229,6 @@ private:
|
||||
#endif
|
||||
|
||||
#define THROW_BASE_EXCEPTION(msg) THROW_EXCEPTION2(::epics::pvData::BaseException, msg)
|
||||
#define THROW_BASE_EXCEPTION_CAUSE(msg, cause) THROW_EXCEPTION2(::epics::pvData::BaseException, msg)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,27 +46,10 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <epicsVersion.h>
|
||||
#include <epicsAtomic.h>
|
||||
|
||||
#ifndef VERSION_INT
|
||||
# define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P))
|
||||
#endif
|
||||
|
||||
#ifndef EPICS_VERSION_INT
|
||||
# define EPICS_VERSION_INT VERSION_INT(EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL)
|
||||
#endif
|
||||
|
||||
#if EPICS_VERSION_INT>=VERSION_INT(3,15,1,0)
|
||||
# include <epicsAtomic.h>
|
||||
# define REFTRACK_USE_ATOMIC
|
||||
#endif
|
||||
|
||||
#ifdef REFTRACK_USE_ATOMIC
|
||||
# define REFTRACE_INCREMENT(counter) ::epics::atomic::increment(counter)
|
||||
# define REFTRACE_DECREMENT(counter) ::epics::atomic::decrement(counter)
|
||||
#else
|
||||
# define REFTRACE_INCREMENT(counter) do{}while(0)
|
||||
# define REFTRACE_DECREMENT(counter) do{}while(0)
|
||||
#endif
|
||||
#define REFTRACE_INCREMENT(counter) ::epics::atomic::increment(counter)
|
||||
#define REFTRACE_DECREMENT(counter) ::epics::atomic::decrement(counter)
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
|
||||
@@ -16,6 +16,14 @@
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
#if defined(PVD_INTERNAL)
|
||||
# define PVD_DEPRECATED(msg)
|
||||
#elif __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 5
|
||||
# define PVD_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||
#else
|
||||
# define PVD_DEPRECATED(msg) EPICS_DEPRECATED
|
||||
#endif
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class SerializableControl;
|
||||
@@ -47,11 +55,7 @@ namespace epics { namespace pvData {
|
||||
* @param size The number of bytes.
|
||||
*/
|
||||
virtual void ensureBuffer(std::size_t size) =0;
|
||||
/**
|
||||
* Add pad bytes to buffer.
|
||||
* @param alignment alignment required.
|
||||
*/
|
||||
virtual void alignBuffer(std::size_t alignment) =0;
|
||||
virtual void alignBuffer(std::size_t alignment) PVD_DEPRECATED("Deprecated for lack of use") {}
|
||||
/**
|
||||
* Method for serializing primitive array data.
|
||||
* Hook for supplying custom serialization implementation.
|
||||
@@ -98,14 +102,8 @@ namespace epics { namespace pvData {
|
||||
* @param size The number of bytes.
|
||||
*/
|
||||
virtual void ensureData(std::size_t size) =0;
|
||||
/**
|
||||
* Align buffer.
|
||||
* Note that this takes care only current buffer alignment.
|
||||
* If streaming protocol is used,
|
||||
* care must be taken that entire stream is aligned.
|
||||
* @param alignment size in bytes, must be power of two.
|
||||
*/
|
||||
virtual void alignData(std::size_t alignment) =0;
|
||||
// Deprecated for lack of use
|
||||
virtual void alignData(std::size_t alignment) PVD_DEPRECATED("Deprecated for lack of use") {};
|
||||
/**
|
||||
* Method for deserializing array data.
|
||||
* Hook for supplying custom deserialization implementation.
|
||||
@@ -150,7 +148,7 @@ namespace epics { namespace pvData {
|
||||
*/
|
||||
virtual void serialize(ByteBuffer *buffer,
|
||||
SerializableControl *flusher) const = 0;
|
||||
/**
|
||||
/**
|
||||
* Deserialize buffer.
|
||||
* @param buffer serialization buffer.
|
||||
* @param flusher deserialization control.
|
||||
@@ -213,7 +211,7 @@ namespace epics { namespace pvData {
|
||||
*/
|
||||
virtual void serialize(ByteBuffer *buffer,
|
||||
SerializableControl *flusher,BitSet *bitSet) const = 0;
|
||||
/**
|
||||
/**
|
||||
* Deserialize buffer.
|
||||
* @param buffer serialization buffer.
|
||||
* @param flusher deserialization control.
|
||||
|
||||
@@ -544,11 +544,11 @@ private:
|
||||
/* Hack alert.
|
||||
* For reasons of simplicity and efficiency, we want to use raw pointers for iteration.
|
||||
* However, shared_ptr::get() isn't defined when !m_sdata, although practically it gives NULL.
|
||||
* Unfortunately, many of the MSVC (<= VS 2010) STL methods assert() that iterators are never NULL.
|
||||
* Unfortunately, many of the MSVC (<= VS 2013) STL methods assert() that iterators are never NULL.
|
||||
* So we fudge here by abusing 'this' so that our iterators are always !NULL.
|
||||
*/
|
||||
inline E* base_ptr() const {
|
||||
#if defined(_MSC_VER) && _MSC_VER<=1600
|
||||
#if defined(_MSC_VER) && _MSC_VER<=1800
|
||||
return this->m_count ? this->m_sdata.get() : (E*)(this-1);
|
||||
#else
|
||||
return this->m_sdata.get();
|
||||
@@ -837,9 +837,13 @@ namespace detail {
|
||||
typedef typename meta::strip_const<TO>::type to_t;
|
||||
ScalarType stype = src.original_type(),
|
||||
dtype = (ScalarType)ScalarTypeID<TO>::value;
|
||||
if(stype==dtype) {
|
||||
if(src.empty()) {
|
||||
return shared_vector<TO>();
|
||||
|
||||
} else if(stype==dtype) {
|
||||
// no convert needed
|
||||
return shared_vector<TO>(src, detail::_shared_vector_cast_tag());
|
||||
|
||||
} else {
|
||||
// alloc and convert
|
||||
shared_vector<to_t> ret(src.size()/ScalarTypeFunc::elementSize(stype));
|
||||
|
||||
@@ -28,10 +28,10 @@ namespace epics { namespace pvData {
|
||||
class epicsShareClass Status : public epics::pvData::Serializable {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Status);
|
||||
/**
|
||||
* Status type enum.
|
||||
*/
|
||||
enum StatusType {
|
||||
/**
|
||||
* Status type enum.
|
||||
*/
|
||||
enum StatusType {
|
||||
/** Operation completed successfully. */
|
||||
STATUSTYPE_OK,
|
||||
/** Operation completed successfully, but there is a warning message. */
|
||||
@@ -40,11 +40,11 @@ namespace epics { namespace pvData {
|
||||
STATUSTYPE_ERROR,
|
||||
/** Operation failed due to an unexpected error. */
|
||||
STATUSTYPE_FATAL
|
||||
};
|
||||
|
||||
static const char* StatusTypeName[];
|
||||
|
||||
static Status Ok;
|
||||
};
|
||||
|
||||
static const char* StatusTypeName[];
|
||||
|
||||
static Status Ok;
|
||||
|
||||
static inline Status warn(const std::string& m) { return Status(STATUSTYPE_WARNING, m); }
|
||||
static inline Status error(const std::string& m) { return Status(STATUSTYPE_ERROR, m); }
|
||||
@@ -54,10 +54,10 @@ namespace epics { namespace pvData {
|
||||
* Creates OK status; STATUSTYPE_OK, empty message and stackDump.
|
||||
*/
|
||||
Status() :m_statusType(STATUSTYPE_OK) {}
|
||||
|
||||
/**
|
||||
* Create non-OK status.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create non-OK status.
|
||||
*/
|
||||
Status(StatusType type, std::string const & message);
|
||||
|
||||
/**
|
||||
|
||||
@@ -237,6 +237,14 @@ public:
|
||||
std::ostream& operator<<(std::ostream& strm, const escape& Q);
|
||||
};
|
||||
|
||||
struct maybeQuote {
|
||||
const std::string& s;
|
||||
maybeQuote(const std::string& s) :s(s) {}
|
||||
};
|
||||
|
||||
epicsShareExtern
|
||||
std::ostream& operator<<(std::ostream& strm, const maybeQuote& q);
|
||||
|
||||
}} // end namespace
|
||||
|
||||
#endif // PVTYPECAST_H
|
||||
|
||||
@@ -25,15 +25,6 @@
|
||||
|
||||
namespace {
|
||||
|
||||
#ifndef REFTRACK_USE_ATOMIC
|
||||
static inline
|
||||
size_t readref(const size_t *ref)
|
||||
{
|
||||
volatile const size_t *vref = ref;
|
||||
return *vref;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef epicsGuard<epicsMutex> Guard;
|
||||
typedef epicsGuardRelease<epicsMutex> UnGuard;
|
||||
|
||||
@@ -88,11 +79,7 @@ size_t readRefCounter(const char *name)
|
||||
refgbl_t::counters_t::iterator it(refgbl->counters.find(name));
|
||||
if(it==refgbl->counters.end())
|
||||
return 0;
|
||||
#ifdef REFTRACK_USE_ATOMIC
|
||||
return atomic::get(*it->second);
|
||||
#else
|
||||
return readref(it->second);
|
||||
#endif
|
||||
}
|
||||
|
||||
const RefSnapshot::Count&
|
||||
@@ -119,11 +106,7 @@ void RefSnapshot::update()
|
||||
end=counters.end();
|
||||
it!=end; ++it)
|
||||
{
|
||||
#ifdef REFTRACK_USE_ATOMIC
|
||||
size_t cnt = atomic::get(*it->second);
|
||||
#else
|
||||
size_t cnt = readref(it->second);
|
||||
#endif
|
||||
|
||||
counts[it->first] = Count(cnt, 0);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace epics {
|
||||
}
|
||||
|
||||
void SerializeHelper::writeSize(std::size_t s, ByteBuffer* buffer) {
|
||||
if(s==(std::size_t)-1) // null // TODO remove
|
||||
if(s==(std::size_t)-1) // null not a size, but used in PVUnion::serialize()
|
||||
buffer->putByte(-1);
|
||||
else if(s<254)
|
||||
buffer->putByte(static_cast<int8>(s));
|
||||
@@ -103,7 +103,7 @@ namespace epics {
|
||||
DeserializableControl* control) {
|
||||
|
||||
std::size_t size = SerializeHelper::readSize(buffer, control);
|
||||
if(size!=(size_t)-1) // TODO null strings check, to be removed in the future
|
||||
if(size!=(size_t)-1) // TODO null strings check, to be removed in the future
|
||||
{
|
||||
if (buffer->getRemaining()>=size)
|
||||
{
|
||||
@@ -174,14 +174,6 @@ struct ToString : public epics::pvData::SerializableControl
|
||||
assert(bufwrap.getRemaining()>0);
|
||||
}
|
||||
|
||||
virtual void alignBuffer(std::size_t alignment)
|
||||
{
|
||||
if(bufwrap.getRemaining()<alignment)
|
||||
flushSerializeBuffer();
|
||||
assert(bufwrap.getRemaining()>=alignment);
|
||||
bufwrap.align(alignment);
|
||||
}
|
||||
|
||||
virtual bool directSerialize(
|
||||
ByteBuffer *existingBuffer,
|
||||
const char* toSerialize,
|
||||
@@ -232,16 +224,6 @@ struct FromString : public epics::pvData::DeserializableControl
|
||||
throw std::logic_error("Incomplete buffer");
|
||||
}
|
||||
|
||||
virtual void alignData(std::size_t alignment)
|
||||
{
|
||||
size_t pos = buf.getPosition(), k = alignment-1;
|
||||
if(pos&k) {
|
||||
std::size_t npad = alignment-(pos&k);
|
||||
ensureData(npad);
|
||||
buf.align(alignment);
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool directDeserialize(
|
||||
ByteBuffer *existingBuffer,
|
||||
char* deserializeTo,
|
||||
|
||||
@@ -32,7 +32,7 @@ Status::Status(StatusType type, string const & message, string const & stackDump
|
||||
if (type == STATUSTYPE_OK)
|
||||
throw std::invalid_argument("type == STATUSTYPE_OK");
|
||||
}
|
||||
|
||||
|
||||
void Status::maximize(const Status& o)
|
||||
{
|
||||
if(m_statusType < o.m_statusType) {
|
||||
@@ -44,40 +44,40 @@ void Status::maximize(const Status& o)
|
||||
|
||||
void Status::serialize(ByteBuffer *buffer, SerializableControl *flusher) const
|
||||
{
|
||||
flusher->ensureBuffer(1);
|
||||
if (m_statusType == STATUSTYPE_OK)
|
||||
{
|
||||
// special code for okStatus (optimization)
|
||||
buffer->putByte((int8)-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer->putByte((int8)m_statusType);
|
||||
SerializeHelper::serializeString(m_message, buffer, flusher);
|
||||
SerializeHelper::serializeString(m_stackDump, buffer, flusher);
|
||||
}
|
||||
flusher->ensureBuffer(1);
|
||||
if (m_statusType == STATUSTYPE_OK)
|
||||
{
|
||||
// special code for okStatus (optimization)
|
||||
buffer->putByte((int8)-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer->putByte((int8)m_statusType);
|
||||
SerializeHelper::serializeString(m_message, buffer, flusher);
|
||||
SerializeHelper::serializeString(m_stackDump, buffer, flusher);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Status::deserialize(ByteBuffer *buffer, DeserializableControl *flusher)
|
||||
{
|
||||
flusher->ensureData(1);
|
||||
int8 typeCode = buffer->getByte();
|
||||
if (typeCode == (int8)-1)
|
||||
{
|
||||
// in most of the cases status will be OK, we statistically optimize
|
||||
if (m_statusType != STATUSTYPE_OK)
|
||||
{
|
||||
m_statusType = STATUSTYPE_OK;
|
||||
flusher->ensureData(1);
|
||||
int8 typeCode = buffer->getByte();
|
||||
if (typeCode == (int8)-1)
|
||||
{
|
||||
// in most of the cases status will be OK, we statistically optimize
|
||||
if (m_statusType != STATUSTYPE_OK)
|
||||
{
|
||||
m_statusType = STATUSTYPE_OK;
|
||||
m_message.clear();
|
||||
m_stackDump.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_statusType = (StatusType)typeCode;
|
||||
m_message = SerializeHelper::deserializeString(buffer, flusher);
|
||||
m_stackDump = SerializeHelper::deserializeString(buffer, flusher);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_statusType = (StatusType)typeCode;
|
||||
m_message = SerializeHelper::deserializeString(buffer, flusher);
|
||||
m_stackDump = SerializeHelper::deserializeString(buffer, flusher);
|
||||
}
|
||||
}
|
||||
|
||||
void Status::dump(std::ostream& o) const
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
TimerCallback::TimerCallback()
|
||||
: period(0.0),
|
||||
@@ -61,6 +61,10 @@ bool Timer::cancel(TimerCallbackPtr const &timerCallback)
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(!timerCallback->onList) return false;
|
||||
if(!alive) {
|
||||
timerCallback->onList = false;
|
||||
return true;
|
||||
}
|
||||
for(queue_t::iterator it(queue.begin()), end(queue.end()); it != end; ++it)
|
||||
{
|
||||
TimerCallbackPtr& cur = *it;
|
||||
@@ -111,7 +115,7 @@ void Timer::run()
|
||||
work->callback();
|
||||
}
|
||||
|
||||
if(work->period > 0.0) {
|
||||
if(work->period > 0.0 && alive) {
|
||||
work->timeToRun += work->period;
|
||||
addElement(work);
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@ static void castVTyped(size_t count, void *draw, const void *sraw)
|
||||
{
|
||||
TO *dest=(TO*)draw;
|
||||
const FROM *src=(FROM*)sraw;
|
||||
|
||||
|
||||
//std::transform(src, src+count, dest, castUnsafe<TO,FROM>);
|
||||
|
||||
|
||||
try {
|
||||
for(size_t i=0; i<count; i++) {
|
||||
dest[i] = castUnsafe<TO,FROM>(src[i]);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
AlarmSeverity AlarmSeverityFunc::getSeverity(int value)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
string PVAlarm::noAlarmFound("No alarm structure found");
|
||||
string PVAlarm::notAttached("Not attached to an alarm structure");
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvControl.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
string PVDisplay::noDisplayFound("No display structure found");
|
||||
string PVDisplay::notAttached("Not attached to an display structure");
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
string PVEnumerated::notFound("No enumerated structure found");
|
||||
string PVEnumerated::notAttached("Not attached to an enumerated structure");
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::string;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
string PVTimeStamp::noTimeStamp("No timeStamp structure found");
|
||||
string PVTimeStamp::notAttached("Not attached to a timeStamp structure");
|
||||
@@ -93,5 +93,5 @@ bool PVTimeStamp::set(TimeStamp const & timeStamp)
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/timeStamp.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
const int32 milliSecPerSec = 1000;
|
||||
const int32 microSecPerSec = 1000000;
|
||||
|
||||
@@ -948,11 +948,11 @@ public:
|
||||
typedef PVUnion & reference;
|
||||
typedef const PVUnion & const_reference;
|
||||
|
||||
/**
|
||||
* Undefined index.
|
||||
* Default value upon PVUnion construction. Can be set by the user.
|
||||
* Corresponds to @c null value.
|
||||
*/
|
||||
/**
|
||||
* Undefined index.
|
||||
* Default value upon PVUnion construction. Can be set by the user.
|
||||
* Corresponds to @c null value.
|
||||
*/
|
||||
static const int32 UNDEFINED_INDEX;
|
||||
|
||||
/**
|
||||
@@ -1081,9 +1081,9 @@ private:
|
||||
friend class PVDataCreate;
|
||||
UnionConstPtr unionPtr; // same as PVField::getField()
|
||||
|
||||
int32 selector;
|
||||
PVFieldPtr value;
|
||||
bool variant;
|
||||
int32 selector;
|
||||
PVFieldPtr value;
|
||||
bool variant;
|
||||
EPICS_NOT_COPYABLE(PVUnion)
|
||||
};
|
||||
|
||||
|
||||
@@ -24,14 +24,6 @@
|
||||
#include <pv/pvdVersion.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
#if defined(PVD_INTERNAL)
|
||||
# define PVD_DEPRECATED(msg)
|
||||
#elif __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 5
|
||||
# define PVD_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||
#else
|
||||
# define PVD_DEPRECATED(msg) EPICS_DEPRECATED
|
||||
#endif
|
||||
#define PVD_DEPRECATED_52 PVD_DEPRECATED("See https://github.com/epics-base/pvDataCPP/issues/52")
|
||||
|
||||
/* C++11 keywords
|
||||
@@ -371,6 +363,7 @@ protected:
|
||||
* @param type The field type.
|
||||
*/
|
||||
Field(Type type);
|
||||
void cacheCleanup();
|
||||
private:
|
||||
const Type m_fieldType;
|
||||
unsigned int m_hash;
|
||||
@@ -1078,12 +1071,12 @@ public:
|
||||
//! Create a new instance of in-line @c Field builder pre-initialized with and existing Structure
|
||||
static FieldBuilderPtr begin(StructureConstPtr S);
|
||||
|
||||
/**
|
||||
* Set ID of an object to be created.
|
||||
* @param id id to be set.
|
||||
/**
|
||||
* Set ID of an object to be created.
|
||||
* @param id id to be set.
|
||||
* @return this instance of a @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr setId(std::string const & id);
|
||||
*/
|
||||
FieldBuilderPtr setId(std::string const & id);
|
||||
|
||||
/**
|
||||
* Add a @c Scalar.
|
||||
@@ -1213,20 +1206,20 @@ private:
|
||||
FieldBuilder(const FieldBuilderPtr & _parentBuilder, const std::string& name, const Union*);
|
||||
FieldBuilder(const FieldBuilderPtr & _parentBuilder, const std::string& name, const UnionArray*);
|
||||
FieldBuilder(FieldBuilderPtr const & parentBuilder,
|
||||
std::string const & nestedName,
|
||||
Type nestedClassToBuild, bool nestedArray);
|
||||
std::string const & nestedName,
|
||||
Type nestedClassToBuild, bool nestedArray);
|
||||
|
||||
const Field *findField(const std::string& name, Type ftype);
|
||||
|
||||
void reset();
|
||||
FieldConstPtr createFieldInternal(Type type);
|
||||
|
||||
void reset();
|
||||
FieldConstPtr createFieldInternal(Type type);
|
||||
|
||||
friend class FieldCreate;
|
||||
|
||||
const FieldCreatePtr fieldCreate;
|
||||
|
||||
std::string id;
|
||||
bool idSet;
|
||||
std::string id;
|
||||
bool idSet;
|
||||
|
||||
StringArray fieldNames;
|
||||
FieldConstPtrArray fields;
|
||||
@@ -1250,11 +1243,11 @@ class epicsShareClass FieldCreate {
|
||||
friend struct detail::field_factory;
|
||||
public:
|
||||
static const FieldCreatePtr &getFieldCreate();
|
||||
/**
|
||||
* Create a new instance of in-line @c Field builder.
|
||||
* @return a new instance of a @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr createFieldBuilder() const;
|
||||
/**
|
||||
* Create a new instance of in-line @c Field builder.
|
||||
* @return a new instance of a @c FieldBuilder.
|
||||
*/
|
||||
FieldBuilderPtr createFieldBuilder() const;
|
||||
/**
|
||||
* Create a new instance of in-line @c Field builder pre-initialized with and existing Structure
|
||||
* @return a new instance of a @c FieldBuilder.
|
||||
@@ -1322,7 +1315,7 @@ public:
|
||||
* @return a @c Structure interface for the newly created object.
|
||||
*/
|
||||
StructureConstPtr createStructure (
|
||||
std::string const & id,
|
||||
std::string const & id,
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
/**
|
||||
@@ -1358,7 +1351,7 @@ public:
|
||||
* @return a @c Union interface for the newly created object.
|
||||
*/
|
||||
UnionConstPtr createUnion (
|
||||
std::string const & id,
|
||||
std::string const & id,
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & fields) const;
|
||||
/**
|
||||
|
||||
@@ -72,7 +72,7 @@ static bool checkBitSetPVField(
|
||||
|
||||
bool BitSetUtil::compress(BitSetPtr const &bitSet,PVStructurePtr const &pvStructure)
|
||||
{
|
||||
return checkBitSetPVField(pvStructure,bitSet,0);
|
||||
return checkBitSetPVField(pvStructure,bitSet,0);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -12,6 +12,8 @@ include $(PVDATA_TEST)/pv/Makefile
|
||||
include $(PVDATA_TEST)/property/Makefile
|
||||
include $(PVDATA_TEST)/copy/Makefile
|
||||
|
||||
PROD_SRCS_RTEMS += rtemsTestData.c
|
||||
|
||||
# pvDataAllTests runs all the test programs in a known working order.
|
||||
testHarness_SRCS += pvDataAllTests.c
|
||||
|
||||
@@ -30,6 +32,11 @@ TESTSPEC_RTEMS = pvdTestHarness.$(MUNCH_SUFFIX); pvDataAllTests
|
||||
# Build test scripts for hosts
|
||||
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
|
||||
|
||||
ifneq ($(filter $(T_A),$(CROSS_COMPILER_RUNTEST_ARCHS)),)
|
||||
TESTPROD = $(TESTPROD_HOST)
|
||||
TESTSCRIPTS += $(TESTS:%=%.t)
|
||||
endif
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
|
||||
|
||||
@@ -203,8 +203,8 @@ static void testCreateRequestInternal() {
|
||||
|
||||
request = string("record[process=true,xxx=yyy]")
|
||||
+ "putField(power.value)"
|
||||
+ "getField(alarm,timeStamp,power{value,alarm},"
|
||||
+ "current{value,alarm},voltage{value,alarm})";
|
||||
+ "getField(alarm,timeStamp,power{value,alarm},"
|
||||
+ "current{value,alarm},voltage{value,alarm})";
|
||||
|
||||
pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) { cout<< createRequest->getMessage() << endl;}
|
||||
@@ -241,10 +241,10 @@ static void testCreateRequestInternal() {
|
||||
testPass("request %s",request.c_str());
|
||||
|
||||
request = string("record[process=true,xxx=yyy]")
|
||||
+ "putField(power.value)"
|
||||
+ "getField(alarm,timeStamp,power{value,alarm},"
|
||||
+ "current{value,alarm},voltage{value,alarm},"
|
||||
+ "ps0{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}},"
|
||||
+ "putField(power.value)"
|
||||
+ "getField(alarm,timeStamp,power{value,alarm},"
|
||||
+ "current{value,alarm},voltage{value,alarm},"
|
||||
+ "ps0{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}},"
|
||||
+ "ps1{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}}"
|
||||
+ ")";
|
||||
|
||||
@@ -730,5 +730,3 @@ MAIN(testCreateRequest)
|
||||
testMaskErr();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,16 +31,6 @@ void Unroller::unroll<0>(double /*d*/) {
|
||||
THROW_BASE_EXCEPTION("the root cause");
|
||||
}
|
||||
|
||||
void internalTestBaseException(int /*unused*/ = 0)
|
||||
{
|
||||
try {
|
||||
// NOTE: 5, 4, 3, 2, 1 calls will be optimized and not shown
|
||||
Unroller().unroll<5>(42.0);
|
||||
} catch (BaseException& be3) {
|
||||
THROW_BASE_EXCEPTION_CAUSE("exception 1", be3);
|
||||
}
|
||||
}
|
||||
|
||||
void testBaseExceptionTest() {
|
||||
printf("testBaseException... ");
|
||||
|
||||
@@ -50,16 +40,6 @@ void testBaseExceptionTest() {
|
||||
printf("\n\n%s\n\n", be.what());
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
internalTestBaseException();
|
||||
} catch (BaseException& be2) {
|
||||
THROW_BASE_EXCEPTION_CAUSE("exception 2", be2);
|
||||
}
|
||||
} catch (BaseException& be) {
|
||||
printf("\n\n%s\n\n", be.what());
|
||||
}
|
||||
|
||||
testPass("testBaseException");
|
||||
}
|
||||
|
||||
@@ -88,4 +68,3 @@ MAIN(testBaseException)
|
||||
testBaseExceptionTest();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ static void testOperators()
|
||||
b2.set(256);
|
||||
b1 ^= b2;
|
||||
testOk1((b1.cardinality() == 2 && b1.get(1) == true && b1.get(256) == true));
|
||||
|
||||
|
||||
|
||||
testDiag("assign");
|
||||
testOk1(b1 != b2);
|
||||
|
||||
@@ -217,38 +217,6 @@ void testUnaligned()
|
||||
{
|
||||
testDiag("test correctness of unaligned access");
|
||||
|
||||
ByteBuffer buf(32, EPICS_ENDIAN_BIG);
|
||||
|
||||
// malloc() should give us a buffer aligned to at least native integer size
|
||||
buf.align(sizeof(int));
|
||||
testOk1(buf.getPosition()==0);
|
||||
|
||||
buf.clear();
|
||||
buf.put<uint8>(0x42);
|
||||
buf.put<uint16>(0x1020);
|
||||
buf.align(2, '\x41');
|
||||
testOk1(buf.getPosition()==4);
|
||||
|
||||
testOk1(memcmp(buf.getBuffer(), "\x42\x10\x20\x41", 4)==0);
|
||||
|
||||
buf.clear();
|
||||
buf.put<uint8>(0x42);
|
||||
buf.put<uint32>(0x12345678);
|
||||
buf.align(4, '\x41');
|
||||
testOk1(buf.getPosition()==8);
|
||||
|
||||
testOk1(memcmp(buf.getBuffer(), "\x42\x12\x34\x56\x78\x41\x41\x41", 8)==0);
|
||||
|
||||
buf.clear();
|
||||
buf.put<uint8>(0x42);
|
||||
uint64 val = 0x12345678;
|
||||
val<<=32;
|
||||
val |= 0x90abcdef;
|
||||
buf.put<uint64>(val);
|
||||
buf.align(8, '\x41');
|
||||
testOk1(buf.getPosition()==16);
|
||||
|
||||
testOk1(memcmp(buf.getBuffer(), "\x42\x12\x34\x56\x78\x90\xab\xcd\xef\x41\x41\x41", 8)==0);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -305,7 +273,7 @@ void testArrayBE()
|
||||
|
||||
MAIN(testByteBuffer)
|
||||
{
|
||||
testPlan(104);
|
||||
testPlan(97);
|
||||
testDiag("Tests byteBuffer");
|
||||
testBasicOperations();
|
||||
testInverseEndianness(EPICS_ENDIAN_BIG, expect_be);
|
||||
|
||||
@@ -12,4 +12,3 @@ printf("EPICS_BYTE_ORDER: %s\n", (EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE) ? "li
|
||||
printf("EPICS_FLOAT_WORD_ORDER: %s\n", (EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE) ? "little" : "big");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,4 +47,3 @@ MAIN(testEvent)
|
||||
testBasicEvent();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ void test()
|
||||
testOk1(userOverrunBitSet->get(secondsOffset));
|
||||
testOk1(userOverrunBitSet->get(nanosecondsOffset));
|
||||
testOk1(userOverrunBitSet->get(userTagOffset));
|
||||
|
||||
|
||||
BitSetUtil::compress(userChangeBitSet,pvStructure);
|
||||
BitSetUtil::compress(userOverrunBitSet,pvStructure);
|
||||
testOk1(userChangeBitSet->cardinality()==4);
|
||||
@@ -138,4 +138,3 @@ MAIN(testOverrunBitSet)
|
||||
test();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -67,10 +67,6 @@ public:
|
||||
virtual void ensureBuffer(std::size_t /*size*/) {
|
||||
}
|
||||
|
||||
virtual void alignBuffer(std::size_t alignment) {
|
||||
buffer->align(alignment);
|
||||
}
|
||||
|
||||
virtual bool directSerialize(ByteBuffer* /*existingBuffer*/, const char* /*toSerialize*/,
|
||||
std::size_t /*elementCount*/, std::size_t /*elementSize*/)
|
||||
{
|
||||
@@ -95,10 +91,6 @@ public:
|
||||
virtual void ensureData(size_t /*size*/) {
|
||||
}
|
||||
|
||||
virtual void alignData(size_t alignment) {
|
||||
buffer->align(alignment);
|
||||
}
|
||||
|
||||
virtual bool directDeserialize(ByteBuffer* /*existingBuffer*/, char* /*deserializeTo*/,
|
||||
std::size_t /*elementCount*/, std::size_t /*elementSize*/)
|
||||
{
|
||||
@@ -146,48 +138,48 @@ void testEquals() {
|
||||
PVDataCreatePtr factory = getPVDataCreate();
|
||||
testOk1(factory.get()!=NULL);
|
||||
|
||||
// be sure all is covered
|
||||
for (int i = pvBoolean; i < pvString; i++)
|
||||
{
|
||||
ScalarType scalarType = static_cast<ScalarType>(i);
|
||||
// be sure all is covered
|
||||
for (int i = pvBoolean; i < pvString; i++)
|
||||
{
|
||||
ScalarType scalarType = static_cast<ScalarType>(i);
|
||||
|
||||
PVScalarPtr scalar1 = factory->createPVScalar(scalarType);
|
||||
PVScalarPtr scalar2 = factory->createPVScalar(scalarType);
|
||||
testOk1((*scalar1)==(*scalar2));
|
||||
PVScalarPtr scalar1 = factory->createPVScalar(scalarType);
|
||||
PVScalarPtr scalar2 = factory->createPVScalar(scalarType);
|
||||
testOk1((*scalar1)==(*scalar2));
|
||||
|
||||
PVScalarArrayPtr array1 = factory->createPVScalarArray(scalarType);
|
||||
PVScalarArrayPtr array2 = factory->createPVScalarArray(scalarType);
|
||||
testOk1((*array1)==(*array2));
|
||||
}
|
||||
PVScalarArrayPtr array1 = factory->createPVScalarArray(scalarType);
|
||||
PVScalarArrayPtr array2 = factory->createPVScalarArray(scalarType);
|
||||
testOk1((*array1)==(*array2));
|
||||
}
|
||||
|
||||
// and a structure
|
||||
// and a structure
|
||||
PVStructurePtr structure1 = factory->createPVStructure(getStandardField()->timeStamp());
|
||||
PVStructurePtr structure2 = factory->createPVStructure(getStandardField()->timeStamp());
|
||||
testOk1((*structure1)==(*structure2));
|
||||
testOk1((*structure1)==(*structure2));
|
||||
|
||||
// and a structure array
|
||||
PVStructureArrayPtr structureArray1 = factory->createPVStructureArray(getFieldCreate()->createStructureArray(structure1->getStructure()));
|
||||
PVStructureArrayPtr structureArray2 = factory->createPVStructureArray(getFieldCreate()->createStructureArray(structure2->getStructure()));
|
||||
testOk1((*structureArray1)==(*structureArray2));
|
||||
|
||||
// variant union
|
||||
PVUnionPtr variantUnion1 = factory->createPVVariantUnion();
|
||||
PVUnionPtr variantUnion2 = factory->createPVVariantUnion();
|
||||
testOk1((*variantUnion1)==(*variantUnion2));
|
||||
|
||||
variantUnion1->set(structure1);
|
||||
variantUnion2->set(structure1);
|
||||
testOk1((*variantUnion1)==(*variantUnion2));
|
||||
testOk1((*structureArray1)==(*structureArray2));
|
||||
|
||||
variantUnion2->set(structureArray1);
|
||||
testOk1((*variantUnion1)!=(*variantUnion2));
|
||||
|
||||
// variant union array
|
||||
PVUnionArrayPtr variantUnionArray1 = factory->createPVVariantUnionArray();
|
||||
PVUnionArrayPtr variantUnionArray2 = factory->createPVVariantUnionArray();
|
||||
testOk1((*variantUnionArray1)==(*variantUnionArray2));
|
||||
// variant union
|
||||
PVUnionPtr variantUnion1 = factory->createPVVariantUnion();
|
||||
PVUnionPtr variantUnion2 = factory->createPVVariantUnion();
|
||||
testOk1((*variantUnion1)==(*variantUnion2));
|
||||
|
||||
// union
|
||||
variantUnion1->set(structure1);
|
||||
variantUnion2->set(structure1);
|
||||
testOk1((*variantUnion1)==(*variantUnion2));
|
||||
|
||||
variantUnion2->set(structureArray1);
|
||||
testOk1((*variantUnion1)!=(*variantUnion2));
|
||||
|
||||
// variant union array
|
||||
PVUnionArrayPtr variantUnionArray1 = factory->createPVVariantUnionArray();
|
||||
PVUnionArrayPtr variantUnionArray2 = factory->createPVVariantUnionArray();
|
||||
testOk1((*variantUnionArray1)==(*variantUnionArray2));
|
||||
|
||||
// union
|
||||
UnionConstPtr punion = getFieldCreate()->createFieldBuilder()->
|
||||
add("double", pvDouble)->
|
||||
add("double2", pvDouble)->
|
||||
@@ -198,30 +190,30 @@ void testEquals() {
|
||||
endNested()->
|
||||
addArray("intArray", pvInt)->
|
||||
createUnion();
|
||||
PVUnionPtr union1 = factory->createPVUnion(punion);
|
||||
PVUnionPtr union2 = factory->createPVUnion(punion);
|
||||
testOk1((*union1)==(*union2));
|
||||
|
||||
union1->select<PVDouble>("double")->put(1.2);
|
||||
union2->select<PVDouble>("double")->put(1.2);
|
||||
testOk1((*union1)==(*union2));
|
||||
|
||||
union2->select<PVDouble>("double")->put(2.2);
|
||||
testOk1((*union1)!=(*union2));
|
||||
PVUnionPtr union1 = factory->createPVUnion(punion);
|
||||
PVUnionPtr union2 = factory->createPVUnion(punion);
|
||||
testOk1((*union1)==(*union2));
|
||||
|
||||
union2->select<PVDouble>("double2")->put(1.2);
|
||||
testOk1((*union1)!=(*union2));
|
||||
union1->select<PVDouble>("double")->put(1.2);
|
||||
union2->select<PVDouble>("double")->put(1.2);
|
||||
testOk1((*union1)==(*union2));
|
||||
|
||||
union2->select("nested");
|
||||
testOk1((*union1)!=(*union2));
|
||||
union2->select<PVDouble>("double")->put(2.2);
|
||||
testOk1((*union1)!=(*union2));
|
||||
|
||||
testOk1((*union1)!=(*variantUnion2));
|
||||
|
||||
PVUnionArrayPtr unionArray1 = factory->createPVUnionArray(getFieldCreate()->createUnionArray(punion));
|
||||
PVUnionArrayPtr unionArray2 = factory->createPVUnionArray(getFieldCreate()->createUnionArray(punion));
|
||||
testOk1((*unionArray1)==(*unionArray2));
|
||||
union2->select<PVDouble>("double2")->put(1.2);
|
||||
testOk1((*union1)!=(*union2));
|
||||
|
||||
testOk1((*variantUnionArray1)!=(*unionArray2));
|
||||
union2->select("nested");
|
||||
testOk1((*union1)!=(*union2));
|
||||
|
||||
testOk1((*union1)!=(*variantUnion2));
|
||||
|
||||
PVUnionArrayPtr unionArray1 = factory->createPVUnionArray(getFieldCreate()->createUnionArray(punion));
|
||||
PVUnionArrayPtr unionArray2 = factory->createPVUnionArray(getFieldCreate()->createUnionArray(punion));
|
||||
testOk1((*unionArray1)==(*unionArray2));
|
||||
|
||||
testOk1((*variantUnionArray1)!=(*unionArray2));
|
||||
}
|
||||
|
||||
template<typename PVT>
|
||||
@@ -264,7 +256,7 @@ void testScalar() {
|
||||
|
||||
testDiag("type %s", ScalarTypeFunc::name(pvBoolean));
|
||||
PVBooleanPtr pvBoolean =
|
||||
std::tr1::static_pointer_cast<PVBoolean>(factory->createPVScalar(epics::pvData::pvBoolean));
|
||||
std::tr1::static_pointer_cast<PVBoolean>(factory->createPVScalar(epics::pvData::pvBoolean));
|
||||
pvBoolean->put(false);
|
||||
serializationTest(pvBoolean);
|
||||
pvBoolean->put(true);
|
||||
@@ -284,7 +276,7 @@ void testScalar() {
|
||||
|
||||
testDiag("type %s", ScalarTypeFunc::name(pvString));
|
||||
PVStringPtr pvString =
|
||||
std::tr1::static_pointer_cast<PVString>(factory->createPVScalar(epics::pvData::pvString));
|
||||
std::tr1::static_pointer_cast<PVString>(factory->createPVScalar(epics::pvData::pvString));
|
||||
pvString->put("");
|
||||
serializationTest(pvString);
|
||||
pvString->put("s");
|
||||
@@ -382,7 +374,7 @@ void testStructure() {
|
||||
testOk1(factory.get()!=NULL);
|
||||
|
||||
testDiag("\tSimple structure serialization");
|
||||
PVStructurePtr pvStructure = factory->createPVStructure(getStandardField()->timeStamp());
|
||||
PVStructurePtr pvStructure = factory->createPVStructure(getStandardField()->timeStamp());
|
||||
pvStructure->getSubField<PVLong>("secondsPastEpoch")->put(123);
|
||||
pvStructure->getSubField<PVInt>("nanoseconds")->put(456);
|
||||
pvStructure->getSubField<PVInt>("userTag")->put(789);
|
||||
@@ -390,11 +382,11 @@ void testStructure() {
|
||||
serializationTest(pvStructure);
|
||||
|
||||
testDiag("\tComplex structure serialization");
|
||||
pvStructure = factory->createPVStructure(
|
||||
getStandardField()->structureArray(
|
||||
getStandardField()->timeStamp(), "alarm,control,display,timeStamp")
|
||||
);
|
||||
// TODO fill with data
|
||||
pvStructure = factory->createPVStructure(
|
||||
getStandardField()->structureArray(
|
||||
getStandardField()->timeStamp(), "alarm,control,display,timeStamp")
|
||||
);
|
||||
// TODO fill with data
|
||||
serializationTest(pvStructure);
|
||||
}
|
||||
|
||||
@@ -439,17 +431,17 @@ void testUnion() {
|
||||
|
||||
PVUnionArrayPtr variantArray = factory->createPVVariantUnionArray();
|
||||
testOk1(variantArray.get()!=NULL);
|
||||
|
||||
|
||||
variantArray->setLength(6);
|
||||
PVUnionArray::svector data;
|
||||
|
||||
PVUnionPtr u = factory->createPVVariantUnion();
|
||||
data.push_back(u);
|
||||
|
||||
|
||||
u = factory->createPVVariantUnion();
|
||||
u->set(factory->createPVStructure(getStandardField()->timeStamp()));
|
||||
data.push_back(u);
|
||||
|
||||
|
||||
u = factory->createPVVariantUnion();
|
||||
u->set(factory->createPVStructure(getStandardField()->control()));
|
||||
data.push_back(u);
|
||||
@@ -458,18 +450,18 @@ void testUnion() {
|
||||
|
||||
variantArray->replace(freeze(data));
|
||||
serializationTest(variantArray);
|
||||
|
||||
|
||||
testDiag("\tVariant union test");
|
||||
|
||||
|
||||
UnionConstPtr punion = getFieldCreate()->createFieldBuilder()->
|
||||
add("doubleValue", pvDouble)->
|
||||
add("intValue", pvInt)->
|
||||
createUnion();
|
||||
|
||||
u = factory->createPVUnion(punion);
|
||||
testOk1(NULL!=u.get());
|
||||
|
||||
// null union test
|
||||
u = factory->createPVUnion(punion);
|
||||
testOk1(NULL!=u.get());
|
||||
|
||||
// null union test
|
||||
testOk1(NULL==u->get().get());
|
||||
testOk1(PVUnion::UNDEFINED_INDEX == u->getSelectedIndex());
|
||||
testOk1("" == u->getSelectedFieldName());
|
||||
@@ -480,13 +472,13 @@ void testUnion() {
|
||||
testOk1(0 == u->getSelectedIndex());
|
||||
testOk1("doubleValue" == u->getSelectedFieldName());
|
||||
serializationTest(u);
|
||||
|
||||
|
||||
u->select<PVInt>("intValue")->put(543);
|
||||
testOk1(543 == u->get<PVInt>()->get());
|
||||
testOk1(1 == u->getSelectedIndex());
|
||||
testOk1("intValue" == u->getSelectedFieldName());
|
||||
serializationTest(u);
|
||||
|
||||
|
||||
u->select<PVInt>(1)->put(5432);
|
||||
testOk1(5432 == u->get<PVInt>()->get());
|
||||
serializationTest(u);
|
||||
@@ -496,12 +488,12 @@ void testUnion() {
|
||||
testOk1(PVUnion::UNDEFINED_INDEX == u->getSelectedIndex());
|
||||
testOk1("" == u->getSelectedFieldName());
|
||||
serializationTest(u);
|
||||
|
||||
|
||||
u->set("doubleValue", doubleValue);
|
||||
testOk1(doubleValue.get() == u->get().get());
|
||||
testOk1(0 == u->getSelectedIndex());
|
||||
serializationTest(u);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
u->set(1, doubleValue);
|
||||
@@ -523,7 +515,7 @@ void testUnion() {
|
||||
// expected
|
||||
testPass("PVUnion.select(int32) index out of bounds test");
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
u->select(-2);
|
||||
@@ -545,22 +537,22 @@ void testUnion() {
|
||||
// expected
|
||||
testPass("PVUnion.set(int32, PVFieldPtr const&) index out of bounds test");
|
||||
}
|
||||
|
||||
|
||||
testDiag("\tUnion array test");
|
||||
|
||||
PVUnionArrayPtr unionArray = factory->createPVUnionArray(getFieldCreate()->createUnionArray(punion));
|
||||
testOk1(unionArray.get()!=NULL);
|
||||
|
||||
|
||||
unionArray->setLength(6);
|
||||
data.clear();
|
||||
|
||||
u = factory->createPVUnion(punion);
|
||||
data.push_back(u);
|
||||
|
||||
|
||||
u = factory->createPVUnion(punion);
|
||||
u->select<PVDouble>(0)->put(12);
|
||||
data.push_back(u);
|
||||
|
||||
|
||||
u = factory->createPVUnion(punion);
|
||||
u->select<PVInt>(1)->put(421);
|
||||
data.push_back(u);
|
||||
@@ -569,7 +561,7 @@ void testUnion() {
|
||||
|
||||
unionArray->replace(freeze(data));
|
||||
serializationTest(unionArray);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void testStructureArray() {
|
||||
@@ -633,38 +625,38 @@ void serializationFieldTest(FieldConstPtr const & field)
|
||||
{
|
||||
testShow()<<CURRENT_FUNCTION<<"\n"<<field;
|
||||
|
||||
buffer->clear();
|
||||
buffer->clear();
|
||||
|
||||
// serialize
|
||||
field->serialize(buffer, flusher);
|
||||
// serialize
|
||||
field->serialize(buffer, flusher);
|
||||
|
||||
// deserialize
|
||||
buffer->flip();
|
||||
// deserialize
|
||||
buffer->flip();
|
||||
|
||||
FieldConstPtr deserializedField = getFieldCreate()->deserialize(buffer, control);
|
||||
FieldConstPtr deserializedField = getFieldCreate()->deserialize(buffer, control);
|
||||
|
||||
testShow()<<" after "<<(void*)field.get()<<" == "<<(void*)deserializedField.get();
|
||||
testOk1(*field == *deserializedField);
|
||||
testOk1(*field == *deserializedField);
|
||||
}
|
||||
|
||||
void testIntrospectionSerialization()
|
||||
{
|
||||
testDiag("Testing introspection serialization...");
|
||||
testDiag("Testing introspection serialization...");
|
||||
|
||||
FieldCreatePtr factory = getFieldCreate();
|
||||
testOk1(factory.get()!=NULL);
|
||||
FieldCreatePtr factory = getFieldCreate();
|
||||
testOk1(factory.get()!=NULL);
|
||||
|
||||
// be sure all is covered
|
||||
for (int i = pvBoolean; i < pvString; i++)
|
||||
{
|
||||
ScalarType scalarType = static_cast<ScalarType>(i);
|
||||
// be sure all is covered
|
||||
for (int i = pvBoolean; i < pvString; i++)
|
||||
{
|
||||
ScalarType scalarType = static_cast<ScalarType>(i);
|
||||
|
||||
ScalarConstPtr scalar = factory->createScalar(scalarType);
|
||||
serializationFieldTest(scalar);
|
||||
ScalarConstPtr scalar = factory->createScalar(scalarType);
|
||||
serializationFieldTest(scalar);
|
||||
|
||||
ScalarArrayConstPtr array = factory->createScalarArray(scalarType);
|
||||
serializationFieldTest(array);
|
||||
}
|
||||
ScalarArrayConstPtr array = factory->createScalarArray(scalarType);
|
||||
serializationFieldTest(array);
|
||||
}
|
||||
|
||||
// and a structure
|
||||
StructureConstPtr structure = getStandardField()->timeStamp();
|
||||
@@ -677,11 +669,11 @@ void testIntrospectionSerialization()
|
||||
// variant union
|
||||
UnionConstPtr variant = factory->createVariantUnion();
|
||||
serializationFieldTest(variant);
|
||||
|
||||
|
||||
// variant array union
|
||||
UnionArrayConstPtr variantArray = factory->createVariantUnionArray();
|
||||
serializationFieldTest(variantArray);
|
||||
|
||||
|
||||
// union
|
||||
UnionConstPtr punion = factory->createFieldBuilder()->
|
||||
add("double", pvDouble)->
|
||||
@@ -693,7 +685,7 @@ void testIntrospectionSerialization()
|
||||
addArray("intArray", pvInt)->
|
||||
createUnion();
|
||||
serializationFieldTest(punion);
|
||||
|
||||
|
||||
// union array
|
||||
UnionArrayConstPtr punionArray = factory->createUnionArray(punion);
|
||||
serializationFieldTest(punionArray);
|
||||
@@ -748,7 +740,7 @@ void testBoundedString() {
|
||||
try {
|
||||
pvStr->put("tooLargeString");
|
||||
testFail("too large string accepted");
|
||||
} catch (std::overflow_error oe) {
|
||||
} catch (std::overflow_error& oe) {
|
||||
// OK
|
||||
}
|
||||
|
||||
@@ -877,7 +869,7 @@ MAIN(testSerialization) {
|
||||
testStructure();
|
||||
testStructureId();
|
||||
testStructureArray();
|
||||
|
||||
|
||||
testUnion();
|
||||
|
||||
testArraySizeType();
|
||||
@@ -894,4 +886,3 @@ MAIN(testSerialization) {
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -474,6 +474,9 @@ void testVectorConvert()
|
||||
testOk1(ints.unique());
|
||||
testOk1(strings.size()==ints.size());
|
||||
testOk1(strings.at(0)=="42");
|
||||
|
||||
testDiag("convert empty array");
|
||||
testOk1(pvd::shared_vector_convert<double>(pvd::shared_vector<pvd::int32>()).empty());
|
||||
}
|
||||
|
||||
void testWeak()
|
||||
@@ -522,7 +525,7 @@ void testICE()
|
||||
testOk1(B.size()==6);
|
||||
testOk1(A.data()!=check);
|
||||
testOk1(B.data()==check);
|
||||
|
||||
|
||||
D = B; // create second const reference
|
||||
|
||||
// clears D, but reference to B
|
||||
@@ -695,7 +698,7 @@ void testCXX11Init()
|
||||
|
||||
MAIN(testSharedVector)
|
||||
{
|
||||
testPlan(191);
|
||||
testPlan(192);
|
||||
testDiag("Tests for shared_vector");
|
||||
|
||||
testDiag("sizeof(shared_vector<pvd::int32>)=%lu",
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include <pv/pvdVersion.h>
|
||||
|
||||
#if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1)
|
||||
|
||||
#include <pv/json.h>
|
||||
#include <pv/bitSet.h>
|
||||
#include <pv/valueBuilder.h>
|
||||
@@ -290,15 +288,3 @@ MAIN(testjson)
|
||||
}
|
||||
return testDone();
|
||||
}
|
||||
|
||||
#else // EPICS_VERSION_INT
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
|
||||
MAIN(testjson)
|
||||
{
|
||||
testPlan(1);
|
||||
testSkip(1, "JSON parser requires Base >=3.15.0.1");
|
||||
return testDone();
|
||||
}
|
||||
#endif //EPICS_VERSION_INT
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/standardField.h>
|
||||
|
||||
#if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1)
|
||||
# define USE_JSON
|
||||
#endif
|
||||
|
||||
namespace pvd = epics::pvData;
|
||||
|
||||
typedef std::vector<std::string> lines_t;
|
||||
@@ -138,12 +134,12 @@ void showNTScalarNumeric()
|
||||
{
|
||||
testDiag("%s", CURRENT_FUNCTION);
|
||||
pvd::PVStructurePtr input(pvd::getPVDataCreate()->createPVStructure(scalarNumeric));
|
||||
input->getSubFieldT<pvd::PVScalar>("value")->putFrom(-42);
|
||||
input->getSubFieldT<pvd::PVScalar>("value")->putFrom(pvd::int32(-42));
|
||||
|
||||
testDiff("<undefined> -42 \n", print(input->stream()));
|
||||
|
||||
input->getSubFieldT<pvd::PVScalar>("alarm.severity")->putFrom(1);
|
||||
input->getSubFieldT<pvd::PVScalar>("alarm.status")->putFrom(1);
|
||||
input->getSubFieldT<pvd::PVScalar>("alarm.severity")->putFrom(pvd::int32(1));
|
||||
input->getSubFieldT<pvd::PVScalar>("alarm.status")->putFrom(pvd::int32(1));
|
||||
input->getSubFieldT<pvd::PVString>("alarm.message")->put("FOO");
|
||||
|
||||
testDiff("<undefined> -42 MINOR DEVICE FOO \n", print(input->stream()));
|
||||
@@ -166,8 +162,8 @@ void showNTScalarString()
|
||||
|
||||
testDiff("<undefined> bar \n", print(input->stream()));
|
||||
|
||||
input->getSubFieldT<pvd::PVScalar>("alarm.severity")->putFrom(1);
|
||||
input->getSubFieldT<pvd::PVScalar>("alarm.status")->putFrom(1);
|
||||
input->getSubFieldT<pvd::PVScalar>("alarm.severity")->putFrom(pvd::int32(1));
|
||||
input->getSubFieldT<pvd::PVScalar>("alarm.status")->putFrom(pvd::int32(1));
|
||||
input->getSubFieldT<pvd::PVString>("alarm.message")->put("FOO");
|
||||
|
||||
testDiff("<undefined> bar MINOR DEVICE FOO \n", print(input->stream()));
|
||||
@@ -201,12 +197,12 @@ void showNTEnum()
|
||||
|
||||
input->getSubFieldT<pvd::PVInt>("value.index")->put(1);
|
||||
|
||||
testDiff("<undefined> (1) a two\n", print(input->stream()), "two");
|
||||
testDiff("<undefined> (1) \"a two\"\n", print(input->stream()), "two");
|
||||
|
||||
testDiff("epics:nt/NTEnum:1.0 \n"
|
||||
" enum_t value (1) a two\n"
|
||||
" enum_t value (1) \"a two\"\n"
|
||||
" int index 1\n"
|
||||
" string[] choices [\"one\", \"a two\"]\n"
|
||||
" string[] choices [one, \"a two\"]\n"
|
||||
" alarm_t alarm \n"
|
||||
" int severity 0\n"
|
||||
" int status 0\n"
|
||||
@@ -303,7 +299,7 @@ void testRaw()
|
||||
|
||||
testDiff("omg \n"
|
||||
" string scalar \n" // bit 1
|
||||
" string[] scalarArray [\"hello\", \"world\\x7F\"]\n"
|
||||
" string[] scalarArray [hello, \"world\\x7F\"]\n"
|
||||
" structure below\n"
|
||||
" int A 0\n" // bit 4
|
||||
" union select\n"
|
||||
@@ -323,7 +319,7 @@ void testRaw()
|
||||
|
||||
testDiff("omg \n"
|
||||
"\033[1m string scalar \n"
|
||||
"\033[0m\033[1m string[] scalarArray [\"hello\", \"world\\x7F\"]\n"
|
||||
"\033[0m\033[1m string[] scalarArray [hello, \"world\\x7F\"]\n"
|
||||
"\033[0m structure below\n"
|
||||
"\033[1m int A 0\n"
|
||||
"\033[0m union select\n"
|
||||
@@ -351,13 +347,20 @@ void testEscape()
|
||||
testEqual("hello\"\"world", std::string(SB()<<pvd::escape("hello\"world").style(pvd::escape::CSV)));
|
||||
|
||||
testEqual("hello\"\"world", pvd::escape("hello\"world").style(pvd::escape::CSV).str());
|
||||
|
||||
testEqual("hello_world", std::string(SB()<<pvd::maybeQuote("hello_world")));
|
||||
testEqual("\"hello_world\\\"\"", std::string(SB()<<pvd::maybeQuote("hello_world\"")));
|
||||
testEqual("\"hello world\"", std::string(SB()<<pvd::maybeQuote("hello world")));
|
||||
testEqual("\"hello\\nworld\"", std::string(SB()<<pvd::maybeQuote("hello\nworld")));
|
||||
testEqual("\"hello\\\"world\"", std::string(SB()<<pvd::maybeQuote("hello\"world")));
|
||||
testEqual("\"hello\\x7Fworld\"", std::string(SB()<<pvd::maybeQuote("hello\x7Fworld")));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MAIN(testprinter)
|
||||
{
|
||||
testPlan(20);
|
||||
testPlan(26);
|
||||
showNTScalarNumeric();
|
||||
showNTScalarString();
|
||||
showNTEnum();
|
||||
|
||||
@@ -64,7 +64,7 @@ static void testAlarm()
|
||||
{
|
||||
testDiag("testAlarm\n");
|
||||
Alarm alarm;
|
||||
PVAlarm pvAlarm;
|
||||
PVAlarm pvAlarm;
|
||||
bool result;
|
||||
PVFieldPtr pvField = doubleRecord->getSubField<PVStructure>(string("alarm"));
|
||||
if(pvField.get()==NULL) {
|
||||
@@ -93,7 +93,7 @@ static void testTimeStamp()
|
||||
{
|
||||
testDiag("testTimeStamp\n");
|
||||
TimeStamp timeStamp;
|
||||
PVTimeStamp pvTimeStamp;
|
||||
PVTimeStamp pvTimeStamp;
|
||||
bool result;
|
||||
PVFieldPtr pvField = doubleRecord->getSubField<PVStructure>(string("timeStamp"));
|
||||
if(pvField.get()==NULL) {
|
||||
@@ -132,7 +132,7 @@ static void testControl()
|
||||
{
|
||||
testDiag("testControl\n");
|
||||
Control control;
|
||||
PVControl pvControl;
|
||||
PVControl pvControl;
|
||||
bool result;
|
||||
PVFieldPtr pvField = doubleRecord->getSubField<PVStructure>(string("control"));
|
||||
if(pvField.get()==NULL) {
|
||||
@@ -159,7 +159,7 @@ static void testDisplay()
|
||||
{
|
||||
testDiag("testDisplay\n");
|
||||
Display display;
|
||||
PVDisplay pvDisplay;
|
||||
PVDisplay pvDisplay;
|
||||
bool result;
|
||||
PVFieldPtr pvField = doubleRecord->getSubField<PVStructure>(string("display"));
|
||||
if(pvField.get()==NULL) {
|
||||
@@ -191,7 +191,7 @@ static void testDisplay()
|
||||
static void testEnumerated()
|
||||
{
|
||||
testDiag("testEnumerated\n");
|
||||
PVEnumerated pvEnumerated;
|
||||
PVEnumerated pvEnumerated;
|
||||
bool result;
|
||||
PVFieldPtr pvField = enumeratedRecord->getSubField<PVStructure>(string("value"));
|
||||
if(pvField.get()==NULL) {
|
||||
@@ -232,4 +232,3 @@ MAIN(testProperty)
|
||||
printRecords();
|
||||
return testDone();;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ static StandardPVFieldPtr standardPVField;
|
||||
static void test()
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
|
||||
testDiag("\ntestBitSetUtil\n");
|
||||
StringArray fieldNames;
|
||||
PVFieldPtrArray pvFields;
|
||||
@@ -127,4 +127,3 @@ MAIN(testBitSetUtil)
|
||||
test();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ void test_factory()
|
||||
testOk1(fb.get() != 0);
|
||||
|
||||
FieldBuilderPtr fb2 = fieldCreate->createFieldBuilder();
|
||||
testOk1(fb.get() != fb2.get());
|
||||
testOk1(fb.get() != fb2.get());
|
||||
}
|
||||
|
||||
void test_structure()
|
||||
@@ -34,7 +34,7 @@ void test_structure()
|
||||
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
FieldBuilderPtr fb = fieldCreate->createFieldBuilder();
|
||||
|
||||
|
||||
// test with simple (non-nested) structure
|
||||
std::string ID = "testStructureID";
|
||||
StructureConstPtr s = fb->setId(ID)->
|
||||
@@ -44,7 +44,7 @@ void test_structure()
|
||||
testOk1(s.get() != 0);
|
||||
testOk1(ID == s->getID());
|
||||
testOk1(2 == s->getFields().size());
|
||||
|
||||
|
||||
FieldConstPtr f0 = s->getField(0);
|
||||
testOk1(scalar == f0->getType());
|
||||
testOk1("double" == s->getFieldName(0));
|
||||
@@ -54,13 +54,13 @@ void test_structure()
|
||||
testOk1(scalarArray == f1->getType());
|
||||
testOk1("intArray" == s->getFieldName(1));
|
||||
testOk(pvInt == std::tr1::static_pointer_cast<const ScalarArray>(f1)->getElementType(), "f1 element type == int");
|
||||
|
||||
|
||||
// test reuse with empty structure
|
||||
StructureConstPtr emptyStructure = fb->createStructure();
|
||||
testOk1(emptyStructure.get() != 0);
|
||||
testOk1(Structure::DEFAULT_ID == emptyStructure->getID());
|
||||
testOk1(0 == emptyStructure->getFields().size());
|
||||
|
||||
|
||||
// test add/addArray with Field
|
||||
StructureConstPtr s2 = fb->add("s", s)->
|
||||
addArray("sArray", s)->
|
||||
@@ -137,7 +137,7 @@ void test_nestedStructure()
|
||||
testDiag("Test test_nestedStructure()");
|
||||
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
|
||||
std::string NESTED_ID = "nestedID";
|
||||
StructureConstPtr s = fieldCreate->createFieldBuilder()->
|
||||
add("double", pvDouble)->
|
||||
@@ -163,21 +163,21 @@ void test_nestedStructure()
|
||||
|
||||
{
|
||||
StructureConstPtr s2 = std::tr1::static_pointer_cast<const Structure>(f1);
|
||||
|
||||
|
||||
testOk1(s2.get() != 0);
|
||||
testOk1(NESTED_ID == s2->getID());
|
||||
testOk1(2 == s2->getFields().size());
|
||||
|
||||
|
||||
FieldConstPtr f20 = s2->getField(0);
|
||||
testOk1(scalar == f20->getType());
|
||||
testOk1("short" == s2->getFieldName(0));
|
||||
testOk(pvShort == std::tr1::static_pointer_cast<const Scalar>(f20)->getScalarType(), "f20 scalar type == short");
|
||||
|
||||
|
||||
FieldConstPtr f21 = s2->getField(1);
|
||||
testOk1(scalar == f21->getType());
|
||||
testOk1("long" == s2->getFieldName(1));
|
||||
testOk(pvLong == std::tr1::static_pointer_cast<const Scalar>(f21)->getScalarType(), "f21 element type == long");
|
||||
|
||||
|
||||
}
|
||||
|
||||
FieldConstPtr f2 = s->getField(2);
|
||||
@@ -185,15 +185,15 @@ void test_nestedStructure()
|
||||
testOk1("intArray" == s->getFieldName(2));
|
||||
testOk(pvInt == std::tr1::static_pointer_cast<const ScalarArray>(f2)->getElementType(), "f2 element type == int");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void test_nestedStructureArray()
|
||||
{
|
||||
testDiag("Test test_nestedStructureArray()");
|
||||
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
|
||||
|
||||
std::string NESTED_ID = "nestedID";
|
||||
StructureConstPtr s = fieldCreate->createFieldBuilder()->
|
||||
add("double", pvDouble)->
|
||||
@@ -219,21 +219,21 @@ void test_nestedStructureArray()
|
||||
|
||||
{
|
||||
StructureConstPtr s2 = std::tr1::static_pointer_cast<const StructureArray>(f1)->getStructure();
|
||||
|
||||
|
||||
testOk1(s2.get() != 0);
|
||||
testOk1(NESTED_ID == s2->getID());
|
||||
testOk1(2 == s2->getFields().size());
|
||||
|
||||
|
||||
FieldConstPtr f20 = s2->getField(0);
|
||||
testOk1(scalar == f20->getType());
|
||||
testOk1("short" == s2->getFieldName(0));
|
||||
testOk(pvShort == std::tr1::static_pointer_cast<const Scalar>(f20)->getScalarType(), "f20 scalar type == short");
|
||||
|
||||
|
||||
FieldConstPtr f21 = s2->getField(1);
|
||||
testOk1(scalar == f21->getType());
|
||||
testOk1("long" == s2->getFieldName(1));
|
||||
testOk(pvLong == std::tr1::static_pointer_cast<const Scalar>(f21)->getScalarType(), "f21 element type == long");
|
||||
|
||||
|
||||
}
|
||||
|
||||
FieldConstPtr f2 = s->getField(2);
|
||||
|
||||
@@ -32,7 +32,7 @@ static void testScalarCommon(ScalarType stype,
|
||||
ScalarConstPtr pscalar = fieldCreate->createScalar(stype);
|
||||
Type type = pscalar->getType();
|
||||
testOk1(type==scalar);
|
||||
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << type;
|
||||
testOk1(oss.str().compare("scalar")==0);
|
||||
@@ -307,17 +307,17 @@ static void testUnion()
|
||||
|
||||
testOk1(union1arr->getUnion()==union1);
|
||||
testOk1(union1arr->getID()=="union[]");
|
||||
|
||||
|
||||
UnionConstPtr variantUnion1 = fieldCreate->createVariantUnion();
|
||||
|
||||
testOk1(variantUnion1->getNumberFields()==0);
|
||||
testOk1(variantUnion1->getID() == Union::ANY_ID);
|
||||
|
||||
|
||||
UnionArrayConstPtr variantUnion1arr = fieldCreate->createVariantUnionArray();
|
||||
|
||||
testOk1(variantUnion1arr->getUnion()==variantUnion1);
|
||||
testOk1(variantUnion1arr->getID()=="any[]");
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void testBoundedString()
|
||||
|
||||
@@ -72,7 +72,7 @@ MAIN(testOperators)
|
||||
|
||||
pvStructure = standardPVField->scalarArray(pvDouble,"alarm,timeStamp");
|
||||
std::cout << *pvStructure << std::endl;
|
||||
|
||||
|
||||
PVDoubleArray::svector values(3);
|
||||
values[0] = 1.1; values[1] = 2.2; values[2] = 3.3;
|
||||
PVDoubleArrayPtr darray = pvStructure->getSubField<PVDoubleArray>("value");
|
||||
@@ -95,4 +95,3 @@ MAIN(testOperators)
|
||||
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,34 @@ static string alarmTimeStamp("alarm,timeStamp");
|
||||
static string alarmTimeStampValueAlarm("alarm,timeStamp,valueAlarm");
|
||||
static string allProperties("alarm,timeStamp,display,control,valueAlarm");
|
||||
|
||||
static void testSizes()
|
||||
{
|
||||
#define SHOW(T) testDiag("sizeof(" #T ")==%zu", sizeof(T))
|
||||
SHOW(std::string);
|
||||
SHOW(std::vector<int>);
|
||||
SHOW(shared_vector<int>);
|
||||
SHOW(std::tr1::shared_ptr<PVField>);
|
||||
SHOW(Field);
|
||||
SHOW(Structure);
|
||||
SHOW(StructureArray);
|
||||
SHOW(Union);
|
||||
SHOW(UnionArray);
|
||||
SHOW(Scalar);
|
||||
SHOW(ScalarArray);
|
||||
SHOW(PVField);
|
||||
SHOW(PVStructure);
|
||||
SHOW(PVStructureArray);
|
||||
SHOW(PVUnion);
|
||||
SHOW(PVUnionArray);
|
||||
SHOW(PVScalar);
|
||||
SHOW(PVScalarArray);
|
||||
SHOW(PVInt);
|
||||
SHOW(PVIntArray);
|
||||
SHOW(PVString);
|
||||
SHOW(PVStringArray);
|
||||
#undef SHOW
|
||||
}
|
||||
|
||||
static void testCreatePVStructure()
|
||||
{
|
||||
PVStructurePtr pv0 = standardPVField->scalar(
|
||||
@@ -53,7 +81,7 @@ static void testCreatePVStructure()
|
||||
pvFields.push_back(pv1);
|
||||
PVStructurePtr pvParent = pvDataCreate->createPVStructure(
|
||||
fieldNames,pvFields);
|
||||
|
||||
|
||||
std::cout << "testCreatePVStructure PASSED" << std::endl;
|
||||
}
|
||||
|
||||
@@ -316,7 +344,7 @@ static void testPVScalar()
|
||||
testPVScalarWithProperties(string("float"),pvFloat);
|
||||
testPVScalarWithProperties(string("double"),pvDouble);
|
||||
testPVScalarWithProperties(string("string"),pvString);
|
||||
|
||||
|
||||
std::cout << "testPVScalar PASSED" << std::endl;
|
||||
}
|
||||
|
||||
@@ -358,7 +386,7 @@ static void testScalarArray()
|
||||
}
|
||||
|
||||
static void testRequest()
|
||||
{
|
||||
{
|
||||
StringArray nullNames;
|
||||
FieldConstPtrArray nullFields;
|
||||
StringArray optionNames(1);
|
||||
@@ -747,6 +775,7 @@ MAIN(testPVData)
|
||||
standardField = getStandardField();
|
||||
standardPVField = getStandardPVField();
|
||||
convert = getConvert();
|
||||
testSizes();
|
||||
testCreatePVStructure();
|
||||
testCreatePVStructureWithInvalidName();
|
||||
testPVScalar();
|
||||
@@ -762,4 +791,3 @@ MAIN(testPVData)
|
||||
}
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -113,9 +113,9 @@ static void testCompress()
|
||||
static void testRemove()
|
||||
{
|
||||
testDiag("Test structure array remove");
|
||||
|
||||
|
||||
PVStructureArray::svector contents(10);
|
||||
|
||||
|
||||
for(size_t i=0; i<contents.size(); i++)
|
||||
contents[i] = standardField->alarm()->build();
|
||||
|
||||
|
||||
@@ -64,4 +64,3 @@ MAIN(testPVType)
|
||||
printf("PASSED\n");
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -203,4 +203,3 @@ MAIN(testPVUnion)
|
||||
testClearUnion();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -68,4 +68,3 @@ MAIN(testStandardField)
|
||||
testPass("testStandardField");
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -73,4 +73,3 @@ MAIN(testStandardPVField)
|
||||
testPass("testStandardPVField");
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
2
testApp/rtemsTestData.c
Normal file
2
testApp/rtemsTestData.c
Normal file
@@ -0,0 +1,2 @@
|
||||
/* no test data */
|
||||
const void* epicsRtemsFSImage = 0;
|
||||
Reference in New Issue
Block a user