Merge branch 7.0.9 into PSI-7.0
This commit is contained in:
@ -48,11 +48,11 @@ EPICS_VERSION = 7
|
|||||||
EPICS_REVISION = 0
|
EPICS_REVISION = 0
|
||||||
|
|
||||||
# EPICS_MODIFICATION must be a number >=0 and <256
|
# EPICS_MODIFICATION must be a number >=0 and <256
|
||||||
EPICS_MODIFICATION = 8
|
EPICS_MODIFICATION = 9
|
||||||
|
|
||||||
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
|
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
|
||||||
# Not included in the official EPICS version number if zero
|
# Not included in the official EPICS version number if zero
|
||||||
EPICS_PATCH_LEVEL = 2
|
EPICS_PATCH_LEVEL = 1
|
||||||
|
|
||||||
# Immediately after an official release the EPICS_PATCH_LEVEL is incremented
|
# Immediately after an official release the EPICS_PATCH_LEVEL is incremented
|
||||||
# and the -DEV suffix is added (similar to the Maven -SNAPSHOT versions)
|
# and the -DEV suffix is added (similar to the Maven -SNAPSHOT versions)
|
||||||
@ -71,6 +71,3 @@ endif
|
|||||||
EPICS_SHORT_VERSION=$(EPICS_VERSION).$(EPICS_REVISION).$(EPICS_MODIFICATION)$(EPICS_PATCH_VSTRING)
|
EPICS_SHORT_VERSION=$(EPICS_VERSION).$(EPICS_REVISION).$(EPICS_MODIFICATION)$(EPICS_PATCH_VSTRING)
|
||||||
EPICS_VERSION_NUMBER=$(EPICS_SHORT_VERSION)$(EPICS_DEV_SNAPSHOT)$(EPICS_SITE_VSTRING)
|
EPICS_VERSION_NUMBER=$(EPICS_SHORT_VERSION)$(EPICS_DEV_SNAPSHOT)$(EPICS_SITE_VSTRING)
|
||||||
EPICS_VERSION_STRING="EPICS Version $(EPICS_VERSION_NUMBER)"
|
EPICS_VERSION_STRING="EPICS Version $(EPICS_VERSION_NUMBER)"
|
||||||
|
|
||||||
# Provide this in case anyone is still using the old name
|
|
||||||
COMMIT_DATE="-no-date-"
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
EPICS_CA_MAJOR_VERSION = 4
|
EPICS_CA_MAJOR_VERSION = 4
|
||||||
EPICS_CA_MINOR_VERSION = 14
|
EPICS_CA_MINOR_VERSION = 14
|
||||||
EPICS_CA_MAINTENANCE_VERSION = 4
|
EPICS_CA_MAINTENANCE_VERSION = 6
|
||||||
|
|
||||||
# Development flag, set to zero for release versions
|
# Development flag, set to zero for release versions
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Version number for the database APIs and shared library
|
# Version number for the database APIs and shared library
|
||||||
|
|
||||||
EPICS_DATABASE_MAJOR_VERSION = 3
|
EPICS_DATABASE_MAJOR_VERSION = 3
|
||||||
EPICS_DATABASE_MINOR_VERSION = 23
|
EPICS_DATABASE_MINOR_VERSION = 24
|
||||||
EPICS_DATABASE_MAINTENANCE_VERSION = 1
|
EPICS_DATABASE_MAINTENANCE_VERSION = 1
|
||||||
|
|
||||||
# Development flag, set to zero for release versions
|
# Development flag, set to zero for release versions
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Version number for the libcom APIs and shared library
|
# Version number for the libcom APIs and shared library
|
||||||
|
|
||||||
EPICS_LIBCOM_MAJOR_VERSION = 3
|
EPICS_LIBCOM_MAJOR_VERSION = 3
|
||||||
EPICS_LIBCOM_MINOR_VERSION = 23
|
EPICS_LIBCOM_MINOR_VERSION = 24
|
||||||
EPICS_LIBCOM_MAINTENANCE_VERSION = 1
|
EPICS_LIBCOM_MAINTENANCE_VERSION = 1
|
||||||
|
|
||||||
# Development flag, set to zero for release versions
|
# Development flag, set to zero for release versions
|
||||||
|
@ -92,3 +92,6 @@ EPICS_IOC_LOG_FILE_NAME=
|
|||||||
EPICS_IOC_LOG_FILE_COMMAND=
|
EPICS_IOC_LOG_FILE_COMMAND=
|
||||||
EPICS_IOC_LOG_FILE_LIMIT=1000000
|
EPICS_IOC_LOG_FILE_LIMIT=1000000
|
||||||
|
|
||||||
|
# Set to 'YES' to call abort() rather than suspend the current thread
|
||||||
|
# when an assert() fails
|
||||||
|
EPICS_ABORT_ON_ASSERT=NO
|
||||||
|
11
configure/os/CONFIG.darwin-aarch64-debug.Common
Normal file
11
configure/os/CONFIG.darwin-aarch64-debug.Common
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# CONFIG.darwin-aarch64-debug.Common
|
||||||
|
#
|
||||||
|
# Definitions for darwin-aarch64-debug host builds - darwin-aarch64 target build with debug compiler flags
|
||||||
|
# Sites may override these definitions in CONFIG_SITE.darwin-aarch64-debug.Common
|
||||||
|
#-------------------------------------------------------
|
||||||
|
|
||||||
|
include $(CONFIG)/os/CONFIG.darwin-aarch64.Common
|
||||||
|
|
||||||
|
# Removes -O optimization and adds -g compile option
|
||||||
|
HOST_OPT=NO
|
||||||
|
|
14
configure/os/CONFIG.darwin-aarch64.darwin-aarch64-debug
Normal file
14
configure/os/CONFIG.darwin-aarch64.darwin-aarch64-debug
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# CONFIG.darwin-aarch64.darwin-aarch64-debug
|
||||||
|
#
|
||||||
|
# Definitions for darwin-aarch64 host - darwin-aarch64-debug target build with debug compiler flags
|
||||||
|
# Sites may override these definitions in CONFIG_SITE.darwin-aarch64.darwin-aarch64-debug
|
||||||
|
#-------------------------------------------------------
|
||||||
|
|
||||||
|
-include $(CONFIG)/os/CONFIG.Common.darwin-aarch64
|
||||||
|
-include $(CONFIG)/os/CONFIG.darwin-aarch64.darwin-aarch64
|
||||||
|
-include $(CONFIG)/os/CONFIG_SITE.Common.darwin-aarch64
|
||||||
|
-include $(CONFIG)/os/CONFIG_SITE.darwin-aarch64.darwin-aarch64
|
||||||
|
|
||||||
|
|
||||||
|
BUILD_CLASS=HOST
|
||||||
|
HOST_OPT = NO
|
11
configure/os/CONFIG.darwin-x86-debug.Common
Normal file
11
configure/os/CONFIG.darwin-x86-debug.Common
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# CONFIG.darwin-x86-debug.Common
|
||||||
|
#
|
||||||
|
# Definitions for darwin-x86-debug host builds - darwin-x86 target build with debug compiler flags
|
||||||
|
# Sites may override these definitions in CONFIG_SITE.darwin-x86-debug.Common
|
||||||
|
#-------------------------------------------------------
|
||||||
|
|
||||||
|
include $(CONFIG)/os/CONFIG.darwin-x86.Common
|
||||||
|
|
||||||
|
# Removes -O optimization and adds -g compile option
|
||||||
|
HOST_OPT=NO
|
||||||
|
|
@ -64,7 +64,3 @@ COMMANDLINE_LIBRARY ?= EPICS
|
|||||||
#else
|
#else
|
||||||
COMMANDLINE_LIBRARY ?= $(strip $(if $(wildcard $(if $(GNU_DIR),$(GNU_DIR)/include/readline/readline.h)), READLINE, EPICS))
|
COMMANDLINE_LIBRARY ?= $(strip $(if $(wildcard $(if $(GNU_DIR),$(GNU_DIR)/include/readline/readline.h)), READLINE, EPICS))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE>2
|
|
||||||
OP_SYS_CPPFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
|
|
||||||
#endif
|
|
||||||
|
@ -8,41 +8,142 @@ under the 3.15 release to which they were originally committed.** Thus it is
|
|||||||
important to read more than just the first section to understand everything that
|
important to read more than just the first section to understand everything that
|
||||||
has changed in each release.
|
has changed in each release.
|
||||||
|
|
||||||
The PVA submodules each have their own individual sets of release notes which
|
The external PVA submodules each have their own individual release notes files.
|
||||||
should also be read to understand what has changed since earlier releases:
|
However the entries describing changes included in those submodules since EPICS
|
||||||
|
7.0.5 have now been copied into the appropriate place of this file.
|
||||||
|
|
||||||
- [normativeTypes](https://github.com/epics-base/normativeTypesCPP/blob/master/documentation/RELEASE_NOTES.md)
|
__This version of EPICS has not been released yet.__
|
||||||
- [pvAccess](http://epics-base.github.io/pvAccessCPP/pvarelease_notes.html)
|
|
||||||
- [pvData](http://epics-base.github.io/pvDataCPP/release_notes.html)
|
|
||||||
- [pvDatabase](https://github.com/epics-base/pvDatabaseCPP/blob/master/documentation/RELEASE_NOTES.md)
|
|
||||||
- [pva2pva](https://epics-base.github.io/pva2pva/release_notes.html)
|
|
||||||
- [pvaClient](https://github.com/epics-base/pvaClientCPP/blob/master/documentation/RELEASE_NOTES.md)
|
|
||||||
|
|
||||||
**This version of EPICS has not been released yet.**
|
## Changes made on the 7.0 branch since 7.0.9
|
||||||
|
|
||||||
## Changes made on the 7.0 branch since 7.0.8.1
|
__Add new items below here__
|
||||||
|
|
||||||
### DBE_PROPERTY event rate changed
|
-----
|
||||||
|
|
||||||
Updating property fields now only post DBE_PROPERTY events if the
|
## EPICS Release 7.0.9
|
||||||
|
|
||||||
|
### Core documentation published at ReadTheDocs
|
||||||
|
|
||||||
|
The `documentation` directory's `Makefile` can now run various publication scripts including Sphinx and Doxygen to generate formatted documentation that is now being published
|
||||||
|
[at docs.epics-controls.org](https://docs.epics-controls.org/projects/base/en/latest/index.html)
|
||||||
|
and integrated into the main [EPICS Documentation website](https://docs.epics-controls.org/en/latest/index.html).
|
||||||
|
The best place to find out more about these mechanisms is the
|
||||||
|
[Contribution Guide](https://docs.epics-controls.org/en/latest/CONTRIBUTING.html)
|
||||||
|
although it doesn't currently cover the new processes added to epics-base.
|
||||||
|
|
||||||
|
Much of the documentation generated from .dbd.pod files at build time is now
|
||||||
|
also being converted into MarkDown (.md) files and installed into the top-level
|
||||||
|
`doc` directory. Some users might find it quicker to look up information about a
|
||||||
|
record type by opening these files in a text editor intead of opening a browser
|
||||||
|
and loading the HTML versions or finding and opening the files from the EPICS
|
||||||
|
Documentation site.
|
||||||
|
|
||||||
|
### Post monitors from compress record when it's reset
|
||||||
|
|
||||||
|
Writing into a compress record's `RES` field now posts a monitor event instead
|
||||||
|
of only changing `VAL`. Monitor clients will therefore receive an empty array.
|
||||||
|
|
||||||
|
### The AMSG error message propagates through MSS links
|
||||||
|
|
||||||
|
A database link with the MSS attribute will now propagate not only SEVR and
|
||||||
|
STAT, but also AMSG. This field contains additional information that complements
|
||||||
|
STAT. Links with MS or MSI attributes do not propagate STAT, and therefore do
|
||||||
|
not propagate AMSG, either.
|
||||||
|
|
||||||
|
Channel Access links do not propagate AMSG, regardless of the MSS attribute,
|
||||||
|
because the message is not available as Channel metadata.
|
||||||
|
|
||||||
|
### Reloading record aliases
|
||||||
|
|
||||||
|
Aliases can now be defined more than once as long as they still refer to the
|
||||||
|
same record, unless the global variable `dbRecordsOnceOnly` is non-zero.
|
||||||
|
This allows database files to be loaded multiple times, even if they contain
|
||||||
|
alias definitions.
|
||||||
|
|
||||||
|
### `DBE_PROPERTY` event rate changed
|
||||||
|
|
||||||
|
Updating property fields now only posts `DBE_PROPERTY` events if the
|
||||||
field actually changed.
|
field actually changed.
|
||||||
|
|
||||||
|
### Changes to msi related to include paths
|
||||||
|
|
||||||
|
There are two changes to `msi` included here.
|
||||||
|
|
||||||
|
`msi` now treats files included by .template or .substutiions files in a more
|
||||||
|
consistent way: for relative paths, it will always look relative to the current
|
||||||
|
working directory if no `-I` flags are passed, and if they are passed then it
|
||||||
|
will search for the _relative_ path from each of those flags. That is, the
|
||||||
|
following will now find the file `bar.template` located at
|
||||||
|
`/some/path/rel/path/bar.template`
|
||||||
|
```
|
||||||
|
$ cat foo.substitutions
|
||||||
|
file rel/path/bar.template {
|
||||||
|
# contents
|
||||||
|
}
|
||||||
|
$ msi -I /some/path foo.substitutions
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that this does provide one change from previous behaviour: when opening a
|
||||||
|
file from the command line, `msi` will not use the `-I`-specified paths to
|
||||||
|
search for the file, but will only work relative to the current working
|
||||||
|
directory, consistent with most commandline utilities.
|
||||||
|
|
||||||
### Allow users to delete previously created records from the database
|
### Allow users to delete previously created records from the database
|
||||||
|
|
||||||
From this release, record instances and aliases that have already been loaded
|
From this release, record instances and aliases that have already been loaded
|
||||||
by an IOC can be removed from the database again before the call to iocInit
|
by an IOC can be removed from the database again before the call to iocInit
|
||||||
by loading a second instance of the named records but using `"#"` in place of
|
by loading a second instance of the named records but using `"#"` in place of
|
||||||
the record type. Values for the fields are not required or advised, just use
|
the record type. Values for the fields are not required or advised, just use
|
||||||
an empty record body { }. This is useful when a template defines records that
|
an empty record body `{}`. This is useful when a template defines records that
|
||||||
are not wanted in some IOCs, without having to split or duplicate the original
|
are not wanted in some IOCs, without having to split or duplicate the original
|
||||||
template.
|
template.
|
||||||
|
|
||||||
For example this will remove the record named "unwanted":
|
For example this will remove the record named "unwanted":
|
||||||
|
|
||||||
```
|
```
|
||||||
record("#", "unwanted") { }
|
record("#", "unwanted") {}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Only keep readline history for interactive sessions
|
||||||
|
|
||||||
|
Previously, all IOCsh commands were persisited in the libreadline history
|
||||||
|
(when readline support is included).
|
||||||
|
Going forward, only interactive commands are saved.
|
||||||
|
|
||||||
|
### Type change to asTrap serverSpecific data
|
||||||
|
|
||||||
|
Change `void*` to `dbChannel*` in `asTrapWriteBeforeWithData()` and
|
||||||
|
`asTrapWriteMessage::serverSpecific` to reflect the reality since
|
||||||
|
the `dbAddr*` to `dbChannel*` migration.
|
||||||
|
External code wishing to support both before and after 3.15 should
|
||||||
|
already be conditionally casting to/from the appropriate type.
|
||||||
|
|
||||||
|
### Fix issues with `_FORTIFY_SOURCE=3`
|
||||||
|
|
||||||
|
This release fixes the false positives failures whhen building with `_FORTIFY_SOURCE` level 3.
|
||||||
|
The override introduced in 7.0.8.1 has been removed.
|
||||||
|
|
||||||
|
### Other
|
||||||
|
|
||||||
|
- genVersionHeader: work with git submodules and worktrees.
|
||||||
|
- avoid UB with self `pthread_join()`
|
||||||
|
- freebsd: Add support for x86 and amd64 builds
|
||||||
|
- Clear AMSG when SEVR becomes zero.
|
||||||
|
- `seqRecord` fix support for link `DLY0`
|
||||||
|
- Add `ABORT_ON_ASSERT` flag to `CONFIG_SITE_ENV`
|
||||||
|
- rationalize osdMutex
|
||||||
|
|
||||||
|
### Submodule updates
|
||||||
|
|
||||||
|
The pvDatabase module was updated to version 4.7.2:
|
||||||
|
|
||||||
|
* Resolved issue with changed field set in the case where the top level (master)
|
||||||
|
field ("_") is not requested by the client, but the master field callback causes
|
||||||
|
all fields to be marked as updated, rather than only those fields that have
|
||||||
|
actually been modified.
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
## EPICS Release 7.0.8.1
|
## EPICS Release 7.0.8.1
|
||||||
|
|
||||||
### Limit to `_FORTIFY_SOURCE=2`
|
### Limit to `_FORTIFY_SOURCE=2`
|
||||||
@ -280,6 +381,50 @@ The floating point modulo function `FMOD(NUM,DEN)` has been added to the CALC
|
|||||||
expression engine and is available to all software using that (calc and calcout
|
expression engine and is available to all software using that (calc and calcout
|
||||||
record types, access security library and some extensions).
|
record types, access security library and some extensions).
|
||||||
|
|
||||||
|
### Submodule updates
|
||||||
|
|
||||||
|
The pvData module was updated to version 8.0.6:
|
||||||
|
|
||||||
|
- Compatible changes
|
||||||
|
- Actually enable JSON-5 output in PVStructure::Formatter::JSON when available.
|
||||||
|
- Fix unaligned access issues for some ARM/Linux targets.
|
||||||
|
|
||||||
|
The pvAccess module was updated to version 7.1.7:
|
||||||
|
|
||||||
|
- Changes
|
||||||
|
- Registering the PVA server with the IOC now sets the `PVAS_SERVER_PORT`
|
||||||
|
variable in the environment.
|
||||||
|
|
||||||
|
The pva2pva module was updated to version 1.4.1:
|
||||||
|
|
||||||
|
- Bug Fixes
|
||||||
|
- `dbLoadGroup` was fixed
|
||||||
|
- Additions
|
||||||
|
- Support for "meta" member at top of array of structs
|
||||||
|
|
||||||
|
The pvDatabase module was updated to version 4.7.1:
|
||||||
|
|
||||||
|
* Added data distributor plugin which can be used for distributing data between
|
||||||
|
a group of clients. The plugin is triggered by the request string of the
|
||||||
|
form:
|
||||||
|
|
||||||
|
`_[distributor=group:<group id>;set:<set_id>;trigger:<field_name>;updates:<n_updates>;mode:<update_mode>]`
|
||||||
|
|
||||||
|
The plugin parameters are optional and are described bellow:
|
||||||
|
|
||||||
|
- group: this parameter indicates a group that client application belongs to (default value: "default"); groups of clients are completely independent of each other
|
||||||
|
|
||||||
|
- set: this parameter designates a client set that application belongs to within its group (default value: "default")
|
||||||
|
|
||||||
|
- trigger: this is the PV structure field that distinguishes different channel updates (default value: "timeStamp"); for example, for area detector images one could use the "uniqueId" field of the NTND structure
|
||||||
|
|
||||||
|
- updates: this parameter configures how many sequential updates a client (or a set of clients) will receive before the data distributor starts updating the next one (default value: "1")
|
||||||
|
|
||||||
|
- mode: this parameter configures how channel updates are to be distributed between clients in a set:
|
||||||
|
- one: update goes to one client per set
|
||||||
|
- all: update goes to all clients in a set
|
||||||
|
- default is "one" if client set id is not specified, and "all" if set id is specified
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
## EPICS Release 7.0.7
|
## EPICS Release 7.0.7
|
||||||
@ -358,10 +503,10 @@ changed to `(p)->dtor`.
|
|||||||
The order over operations when processing a waveformRecord is adjusted
|
The order over operations when processing a waveformRecord is adjusted
|
||||||
so that updates to NORD is posted with the correct timestamp.
|
so that updates to NORD is posted with the correct timestamp.
|
||||||
|
|
||||||
### Automatic COMMANDLINE_LIBRARY w/ newer compilers
|
### Automatic `COMMANDLINE_LIBRARY` with newer compilers
|
||||||
|
|
||||||
When built with a compiler supporting `__has_include<>`, the presence
|
When built with a compiler supporting `__has_include<>`, the presence
|
||||||
of the `<readline/readline.h>` will be used to automatically determine
|
of a `readline/readline.h` header will be used to automatically determine
|
||||||
a default value for `COMMANDLINE_LIBRARY`.
|
a default value for `COMMANDLINE_LIBRARY`.
|
||||||
|
|
||||||
Mingw builds with readline support now link `-ltermcap` instead of `-lcurses`.
|
Mingw builds with readline support now link `-ltermcap` instead of `-lcurses`.
|
||||||
@ -530,6 +675,44 @@ or if unsupported (`$TERM` not set, or Windows < 10).
|
|||||||
The `dbnd` server side filter now passes through alarm and property
|
The `dbnd` server side filter now passes through alarm and property
|
||||||
change events, even when not exceeding the deadband.
|
change events, even when not exceeding the deadband.
|
||||||
|
|
||||||
|
### Submodule updates
|
||||||
|
|
||||||
|
The pvData module was updated to version 8.0.5:
|
||||||
|
|
||||||
|
- Compatible changes
|
||||||
|
- Internal changes to use the YAJL API for generating JSON and JSON-5 output.
|
||||||
|
|
||||||
|
The pvAccess module was updated to version 7.1.6:
|
||||||
|
|
||||||
|
- Changes to caProvider
|
||||||
|
- Bug fix related to enum values.
|
||||||
|
- More internal changes to improve performance when connecting tens of
|
||||||
|
thousands of CA channels.
|
||||||
|
- Several minor internal improvements.
|
||||||
|
|
||||||
|
The pva2pva module was updated to version 1.4.0:
|
||||||
|
|
||||||
|
- Bug Fixes
|
||||||
|
- Apply ACF when writing to atomic group
|
||||||
|
- Additions
|
||||||
|
- Add new "structure" to @ref qsrv_group_map_types
|
||||||
|
- Changes
|
||||||
|
- Add Access Security hooks for single and group writes.
|
||||||
|
- Enable "Async Soft Channel" for output links
|
||||||
|
- When built against Base 7.0.6.1, set timeStamp.userTag from UTAG field.
|
||||||
|
- Add DTYP="QSRV Set UTag" for longin, which sets UTAG=VAL.
|
||||||
|
|
||||||
|
The pvDatabase module was updated to version 4.7.0:
|
||||||
|
|
||||||
|
* Added support for the whole structure (master field) server side plugins.
|
||||||
|
The whole structure is identified as the `_` string, and a pvRequest string
|
||||||
|
that applies a plugin to it takes the form:
|
||||||
|
|
||||||
|
`field(_[XYZ=A:3;B:uniqueId])`
|
||||||
|
|
||||||
|
where `XYZ` is the name of a specific filter plugin that takes parameters
|
||||||
|
`A` and `B` with values `3` and `uniqueId` respectively.
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
## EPICS Release 7.0.6.1
|
## EPICS Release 7.0.6.1
|
||||||
@ -596,6 +779,15 @@ This was done to simplify the code and may have improved performance slightly fo
|
|||||||
|
|
||||||
Many of the built-in record types have had improvements to their documentation with additional fields added to the tables, rewrites of descriptions and links to other documents added or fixed.
|
Many of the built-in record types have had improvements to their documentation with additional fields added to the tables, rewrites of descriptions and links to other documents added or fixed.
|
||||||
|
|
||||||
|
### Submodule updates
|
||||||
|
|
||||||
|
The pvAccess module was updated to version 7.1.4:
|
||||||
|
|
||||||
|
- Changes to caProvider
|
||||||
|
- Resolve issues with pv structures that don't have a value field
|
||||||
|
- Add NULL checks for handling unusual structures
|
||||||
|
- Speed up channel creation when using large numbers of channels
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
## EPICS Release 7.0.6
|
## EPICS Release 7.0.6
|
||||||
@ -606,7 +798,7 @@ These target architectures have been removed:
|
|||||||
|
|
||||||
+ darwin-ppc, darwin-ppcx86
|
+ darwin-ppc, darwin-ppcx86
|
||||||
+ linux-386, linux-486, linux-586, linux-686, linux-athlon (cross-build)
|
+ linux-386, linux-486, linux-586, linux-686, linux-athlon (cross-build)
|
||||||
+ linux-cris, linux-cris_v10, linux-cris_v32 (cross-build)
|
+ linux-cris, linux-cris\_v10, linux-cris\_v32 (cross-build)
|
||||||
+ RTEMS-at91rm9200ek, RTEMS-gen68360, RTEMS-mcp750, RTEMS-mvme167,
|
+ RTEMS-at91rm9200ek, RTEMS-gen68360, RTEMS-mcp750, RTEMS-mvme167,
|
||||||
RTEMS-psim (cross-build)
|
RTEMS-psim (cross-build)
|
||||||
|
|
||||||
@ -624,9 +816,9 @@ running on RTEMS 5:
|
|||||||
|
|
||||||
- RTEMS-beagleboneblack
|
- RTEMS-beagleboneblack
|
||||||
- RTEMS-pc686
|
- RTEMS-pc686
|
||||||
- RTEMS-qoriq_e500 (MVME2500)
|
- RTEMS-qoriq\_e500 (MVME2500)
|
||||||
- RTEMS-xilinx_zynq_a9_qemu
|
- RTEMS-xilinx\_zynq\_a9\_qemu
|
||||||
- RTEMS-xilinx_zynq_zedboard
|
- RTEMS-xilinx\_zynq\_zedboard
|
||||||
|
|
||||||
The EPICS support for RTEMS 4 has always relied on RTEMS-specific
|
The EPICS support for RTEMS 4 has always relied on RTEMS-specific
|
||||||
kernel APIs which cannot be used on an SMP system, so a new port was
|
kernel APIs which cannot be used on an SMP system, so a new port was
|
||||||
@ -638,7 +830,7 @@ to run `make distclean` if switching a single source tree from one
|
|||||||
to the other (both header files and dependency files are different
|
to the other (both header files and dependency files are different
|
||||||
between the two and must be cleaned out).
|
between the two and must be cleaned out).
|
||||||
|
|
||||||
The configuration variable RTEMS_VERSION in the EPICS config file
|
The configuration variable `RTEMS_VERSION` in the EPICS config file
|
||||||
`configure/os/CONFIG_SITE.Common.RTEMS` must be set to the full 3-
|
`configure/os/CONFIG_SITE.Common.RTEMS` must be set to the full 3-
|
||||||
part version number for RTEMS 4 releases, e.g. `4.9.1`, `4.10.2`
|
part version number for RTEMS 4 releases, e.g. `4.9.1`, `4.10.2`
|
||||||
but for RTEMS 5.1 and later it must only contain the major version
|
but for RTEMS 5.1 and later it must only contain the major version
|
||||||
@ -836,6 +1028,39 @@ Test programs written directly in Perl as a `.plt` script should implement a
|
|||||||
similar timeout for themselves. The "netget" test in Base does this in a way
|
similar timeout for themselves. The "netget" test in Base does this in a way
|
||||||
that works on Windows as well as Unix-like hosts.
|
that works on Windows as well as Unix-like hosts.
|
||||||
|
|
||||||
|
### Submodule updates
|
||||||
|
|
||||||
|
The pvAccess module was updated to version 7.1.4:
|
||||||
|
|
||||||
|
- Changes
|
||||||
|
- Adjust argument parsing with pvput (Jesus Vasquez).
|
||||||
|
|
||||||
|
The pva2pva module was updated to version 1.3.1:
|
||||||
|
|
||||||
|
- Bug Fixes
|
||||||
|
- Correct handling for server side filters.
|
||||||
|
- Changes
|
||||||
|
- Syncing softMain.cpp with epics-base
|
||||||
|
|
||||||
|
The pvDatabase module was updated to version 4.6.0:
|
||||||
|
|
||||||
|
* Access Security is now supported.
|
||||||
|
* <b>special</b> has been revised and extended.
|
||||||
|
* addRecord, removeRecord, processRecord, and traceRecord are replaced by pvdbcr versions.
|
||||||
|
* <b>support</b> is DEPRECATED
|
||||||
|
|
||||||
|
The pvaClient module was updated to version 4.8.0:
|
||||||
|
|
||||||
|
* `PvaClientNTMultiData::getChannelChangeFlags` is a new method. It fixes
|
||||||
|
issue #66.
|
||||||
|
* Fix for issue #68. Both `PvaClientArray` and `PvaClientField` are not longer
|
||||||
|
present. Neither was previously implemented.
|
||||||
|
* Several public methods are now protected. They were never meant to be called
|
||||||
|
by clients.
|
||||||
|
* Issue #70 has been fixed.
|
||||||
|
* Changes was made to increase the performance of `pvaMultiChannel`.
|
||||||
|
* doxygen changes were made.
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
## EPICS Release 7.0.5
|
## EPICS Release 7.0.5
|
||||||
@ -873,7 +1098,7 @@ compile device supports as loadable modules.
|
|||||||
### Priority inversion safe Posix mutexes
|
### Priority inversion safe Posix mutexes
|
||||||
|
|
||||||
On Posix systems, epicsMutex now support priority inheritance if available.
|
On Posix systems, epicsMutex now support priority inheritance if available.
|
||||||
The IOC needs to run with SCHED_FIFO engaged to use these.
|
The IOC needs to run with `SCHED_FIFO` engaged to use these.
|
||||||
Support for Posix implementations before POSIX.1-2001 (`_XOPEN_SOURCE < 500`,
|
Support for Posix implementations before POSIX.1-2001 (`_XOPEN_SOURCE < 500`,
|
||||||
glibc version < 2.3.3) has been dropped.
|
glibc version < 2.3.3) has been dropped.
|
||||||
|
|
||||||
@ -1006,14 +1231,14 @@ properly handle zero-length arrays. The `caget`, `caput` and `camonitor`
|
|||||||
client programs are known to work with empty arrays as long as they were
|
client programs are known to work with empty arrays as long as they were
|
||||||
built with this or a later version of EPICS.
|
built with this or a later version of EPICS.
|
||||||
|
|
||||||
#### Change to the db_access.h `dbr_size_n(TYPE, COUNT)` macro
|
#### Change to the db\_access.h `dbr_size_n(TYPE, COUNT)` macro
|
||||||
|
|
||||||
When called with COUNT=0 this macro no longer returns the number of bytes
|
When called with COUNT=0 this macro no longer returns the number of bytes
|
||||||
required for a scalar (1 element) but for an empty array (0 elements).
|
required for a scalar (1 element) but for an empty array (0 elements).
|
||||||
Make sure code that uses this doesn't call it with COUNT=0 when it really
|
Make sure code that uses this doesn't call it with COUNT=0 when it really
|
||||||
means COUNT=1.
|
means COUNT=1.
|
||||||
|
|
||||||
Note that the db_access.h header file is included by cadef.h so the change
|
Note that the db\_access.h header file is included by cadef.h so the change
|
||||||
can impact Channel Access client programs that use this macro.
|
can impact Channel Access client programs that use this macro.
|
||||||
|
|
||||||
#### Channel Access support for zero-length arrays
|
#### Channel Access support for zero-length arrays
|
||||||
@ -1123,6 +1348,35 @@ GNUmake added the directive `undefine` in version 3.82 to allow variables to
|
|||||||
be undefined. Support for this has been added to the EPICS Release file parser,
|
be undefined. Support for this has been added to the EPICS Release file parser,
|
||||||
so `undefine` can now be used in configure/RELEASE files to unset variables.
|
so `undefine` can now be used in configure/RELEASE files to unset variables.
|
||||||
|
|
||||||
|
|
||||||
|
### Submodule updates
|
||||||
|
|
||||||
|
The pvData module was updated to version 8.0.4:
|
||||||
|
|
||||||
|
- Incompatible changes
|
||||||
|
- Remove `ByteBuffer::align()`
|
||||||
|
- Compatible changes
|
||||||
|
- Deprecate `SerializableControl::alignBuffer()` and
|
||||||
|
`DeserializableControl::alignData()`
|
||||||
|
- `shared_vector_convert<>()` fix convert of empty, untyped, array
|
||||||
|
|
||||||
|
The pvAccess module was updated to version 7.1.3:
|
||||||
|
|
||||||
|
- Bug fixes
|
||||||
|
- Increase default TCP timeout to 40 seconds.
|
||||||
|
Applies a 4/3 multiplier on `$EPICS_PVA_CONN_TMO` for compatibility.
|
||||||
|
- CA Provider implementation restructured to simplify, reduce duplication
|
||||||
|
and fix issues #163 and #165.
|
||||||
|
- Changes
|
||||||
|
- Enable building of pvtools to all except vxWorks, RTEMS and iOS.
|
||||||
|
|
||||||
|
The pva2pva module was updated to version 1.3.0:
|
||||||
|
|
||||||
|
- Changes
|
||||||
|
- Add `dbLoadGroup()` iocsh function to read group JSON definitions
|
||||||
|
from a file. Mappings in files must refer to full record names
|
||||||
|
instead of fields. eg. 'recname.VAL' instead of 'VAL'.
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
## EPICS Release 7.0.4.1
|
## EPICS Release 7.0.4.1
|
||||||
@ -1188,7 +1442,7 @@ The following launchpad bugs have fixes included in this release:
|
|||||||
operators on aarch64
|
operators on aarch64
|
||||||
- [lp: 1853148](https://bugs.launchpad.net/bugs/1853148), mingw compiler
|
- [lp: 1853148](https://bugs.launchpad.net/bugs/1853148), mingw compiler
|
||||||
problem with printf/scanf formats
|
problem with printf/scanf formats
|
||||||
- [lp: 1852653](https://bugs.launchpad.net/bugs/1852653), USE_TYPED_DSET
|
- [lp: 1852653](https://bugs.launchpad.net/bugs/1852653), `USE_TYPED_DSET`
|
||||||
incompatible with C++
|
incompatible with C++
|
||||||
- [lp: 1862328](https://bugs.launchpad.net/bugs/1862328), Race condition on
|
- [lp: 1862328](https://bugs.launchpad.net/bugs/1862328), Race condition on
|
||||||
IOC start leaves rsrv unresponsive
|
IOC start leaves rsrv unresponsive
|
||||||
@ -1198,7 +1452,7 @@ The following launchpad bugs have fixes included in this release:
|
|||||||
- [lp: 1868680](https://bugs.launchpad.net/bugs/1868680), Access Security file
|
- [lp: 1868680](https://bugs.launchpad.net/bugs/1868680), Access Security file
|
||||||
reload (asInit) fails
|
reload (asInit) fails
|
||||||
|
|
||||||
### \*_API macros in EPICS headers
|
### `*_API` macros in EPICS headers
|
||||||
|
|
||||||
Internally, the Com and ca libraries now express dllimport/export (Windows)
|
Internally, the Com and ca libraries now express dllimport/export (Windows)
|
||||||
and symbol visibility (GCC) using library-specific macros (eg. `LIBCOM_API`)
|
and symbol visibility (GCC) using library-specific macros (eg. `LIBCOM_API`)
|
||||||
@ -1432,7 +1686,7 @@ The API functions `epicsGetExecDir()` and `epicsGetExecName()` are also
|
|||||||
added to `osiFileName.h` to provide runtime access to the directory or
|
added to `osiFileName.h` to provide runtime access to the directory or
|
||||||
filename of the executable with which the process was started.
|
filename of the executable with which the process was started.
|
||||||
|
|
||||||
### Decouple LINKER_USE_RPATH and STATIC_BUILD
|
### Decouple `LINKER_USE_RPATH` and `STATIC_BUILD`
|
||||||
|
|
||||||
Previously, setting `STATIC_BUILD=NO` implied `LINKER_USE_RPATH=NO`.
|
Previously, setting `STATIC_BUILD=NO` implied `LINKER_USE_RPATH=NO`.
|
||||||
This is no longer the case. Setting `LINKER_USE_RPATH=YES` will
|
This is no longer the case. Setting `LINKER_USE_RPATH=YES` will
|
||||||
@ -2011,7 +2265,7 @@ number instead, like this:
|
|||||||
Channel Access does not (and probably never will) directly support 64-bit
|
Channel Access does not (and probably never will) directly support 64-bit
|
||||||
integer types, so the new field types are presented to the CA server as
|
integer types, so the new field types are presented to the CA server as
|
||||||
`DBF_DOUBLE` values. This means that field values larger than 2^52
|
`DBF_DOUBLE` values. This means that field values larger than 2^52
|
||||||
(0x10_0000_0000_0000 = 4503599627370496) cannot be transported over Channel
|
(0x10\_0000\_0000\_0000 = 4503599627370496) cannot be transported over Channel
|
||||||
Access without their least significant bits being truncated. The EPICS V4
|
Access without their least significant bits being truncated. The EPICS V4
|
||||||
pvAccess network protocol _can_ transport 64-bit data types however, and a
|
pvAccess network protocol _can_ transport 64-bit data types however, and a
|
||||||
future release of the pvaSrv module will connect this ability to the fields of
|
future release of the pvaSrv module will connect this ability to the fields of
|
||||||
|
@ -286,7 +286,11 @@ Inf (Infinite) value. UDF defaults to TRUE but can be set in a database file.
|
|||||||
Record and device support routines which write to the VAL field are generally
|
Record and device support routines which write to the VAL field are generally
|
||||||
responsible for setting and clearing UDF.
|
responsible for setting and clearing UDF.
|
||||||
|
|
||||||
=fields STAT, SEVR, AMSG, NSTA, NSEV, NAMSG, ACKS, ACKT, UDF
|
The B<UDFS> field specifies the alarm severity that the record will be set to
|
||||||
|
whenever its value is undefined (i.e., the UDF field is 1). This includes the
|
||||||
|
initial severity of the record being undefined after the IOC boots.
|
||||||
|
|
||||||
|
=fields STAT, SEVR, AMSG, NSTA, NSEV, NAMSG, ACKS, ACKT, UDF, UDFS
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
@ -226,9 +226,10 @@ static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!status && precord != dbChannelRecord(chan))
|
if (!status && precord != dbChannelRecord(chan))
|
||||||
recGblInheritSevr(plink->value.pv_link.pvlMask & pvlOptMsMode,
|
recGblInheritSevrMsg(plink->value.pv_link.pvlMask & pvlOptMsMode,
|
||||||
plink->precord,
|
plink->precord,
|
||||||
dbChannelRecord(chan)->stat, dbChannelRecord(chan)->sevr);
|
dbChannelRecord(chan)->stat, dbChannelRecord(chan)->sevr,
|
||||||
|
dbChannelRecord(chan)->amsg);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,8 +379,8 @@ static long dbDbPutValue(struct link *plink, short dbrType,
|
|||||||
dbCommon *pdest = dbChannelRecord(chan);
|
dbCommon *pdest = dbChannelRecord(chan);
|
||||||
long status = dbPut(paddr, dbrType, pbuffer, nRequest);
|
long status = dbPut(paddr, dbrType, pbuffer, nRequest);
|
||||||
|
|
||||||
recGblInheritSevr(ppv_link->pvlMask & pvlOptMsMode, pdest, psrce->nsta,
|
recGblInheritSevrMsg(ppv_link->pvlMask & pvlOptMsMode, pdest, psrce->nsta,
|
||||||
psrce->nsev);
|
psrce->nsev, psrce->namsg);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
@ -75,21 +75,21 @@ static const iocshFuncDef dbbFuncDef = {"dbb",1,dbbArgs,
|
|||||||
"Set Breakpoint on a record\n"
|
"Set Breakpoint on a record\n"
|
||||||
"This command spawns one breakpoint continuation task per lockset,"
|
"This command spawns one breakpoint continuation task per lockset,"
|
||||||
" in which further record execution is run\n"};
|
" in which further record execution is run\n"};
|
||||||
static void dbbCallFunc(const iocshArgBuf *args) { dbb(args[0].sval);}
|
static void dbbCallFunc(const iocshArgBuf *args) { iocshSetError(dbb(args[0].sval));}
|
||||||
|
|
||||||
/* dbd */
|
/* dbd */
|
||||||
static const iocshArg dbdArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dbdArg0 = { "record name",iocshArgStringRecord};
|
||||||
static const iocshArg * const dbdArgs[1] = {&dbdArg0};
|
static const iocshArg * const dbdArgs[1] = {&dbdArg0};
|
||||||
static const iocshFuncDef dbdFuncDef = {"dbd",1,dbdArgs,
|
static const iocshFuncDef dbdFuncDef = {"dbd",1,dbdArgs,
|
||||||
"Remove breakpoint from a record.\n"};
|
"Remove breakpoint from a record.\n"};
|
||||||
static void dbdCallFunc(const iocshArgBuf *args) { dbd(args[0].sval);}
|
static void dbdCallFunc(const iocshArgBuf *args) { iocshSetError(dbd(args[0].sval));}
|
||||||
|
|
||||||
/* dbc */
|
/* dbc */
|
||||||
static const iocshArg dbcArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dbcArg0 = { "record name",iocshArgStringRecord};
|
||||||
static const iocshArg * const dbcArgs[1] = {&dbcArg0};
|
static const iocshArg * const dbcArgs[1] = {&dbcArg0};
|
||||||
static const iocshFuncDef dbcFuncDef = {"dbc",1,dbcArgs,
|
static const iocshFuncDef dbcFuncDef = {"dbc",1,dbcArgs,
|
||||||
"Continue processing in a lockset until next breakpoint is found.\n"};
|
"Continue processing in a lockset until next breakpoint is found.\n"};
|
||||||
static void dbcCallFunc(const iocshArgBuf *args) { dbc(args[0].sval);}
|
static void dbcCallFunc(const iocshArgBuf *args) { iocshSetError(dbc(args[0].sval));}
|
||||||
|
|
||||||
/* dbs */
|
/* dbs */
|
||||||
static const iocshArg dbsArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dbsArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -97,12 +97,12 @@ static const iocshArg * const dbsArgs[1] = {&dbsArg0};
|
|||||||
static const iocshFuncDef dbsFuncDef = {"dbs",1,dbsArgs,
|
static const iocshFuncDef dbsFuncDef = {"dbs",1,dbsArgs,
|
||||||
"Step through record processing within a lockset.\n"
|
"Step through record processing within a lockset.\n"
|
||||||
"If called without an argument, automatically steps with the last breakpoint.\n"};
|
"If called without an argument, automatically steps with the last breakpoint.\n"};
|
||||||
static void dbsCallFunc(const iocshArgBuf *args) { dbs(args[0].sval);}
|
static void dbsCallFunc(const iocshArgBuf *args) { iocshSetError(dbs(args[0].sval));}
|
||||||
|
|
||||||
/* dbstat */
|
/* dbstat */
|
||||||
static const iocshFuncDef dbstatFuncDef = {"dbstat",0,0,
|
static const iocshFuncDef dbstatFuncDef = {"dbstat",0,0,
|
||||||
"Print list of suspended records, and breakpoints set in locksets.\n"};
|
"Print list of suspended records, and breakpoints set in locksets.\n"};
|
||||||
static void dbstatCallFunc(const iocshArgBuf *args) { dbstat();}
|
static void dbstatCallFunc(const iocshArgBuf *args) { iocshSetError(dbstat());}
|
||||||
|
|
||||||
/* dbp */
|
/* dbp */
|
||||||
static const iocshArg dbpArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dbpArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -119,7 +119,9 @@ static const iocshFuncDef dbpFuncDef = {
|
|||||||
" 3 - Fields of minor interest to a System developer.\n"
|
" 3 - Fields of minor interest to a System developer.\n"
|
||||||
" 4 - Internal record fields.\n"};
|
" 4 - Internal record fields.\n"};
|
||||||
static void dbpCallFunc(const iocshArgBuf *args)
|
static void dbpCallFunc(const iocshArgBuf *args)
|
||||||
{ dbp(args[0].sval,args[1].ival);}
|
{
|
||||||
|
iocshSetError(dbp(args[0].sval,args[1].ival));
|
||||||
|
}
|
||||||
|
|
||||||
/* dbap */
|
/* dbap */
|
||||||
static const iocshArg dbapArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dbapArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -127,7 +129,7 @@ static const iocshArg * const dbapArgs[1] = {&dbapArg0};
|
|||||||
static const iocshFuncDef dbapFuncDef = {"dbap",1,dbapArgs,
|
static const iocshFuncDef dbapFuncDef = {"dbap",1,dbapArgs,
|
||||||
"Auto Print.\n"
|
"Auto Print.\n"
|
||||||
"Toggle automatic printing after processing a record that has a breakpoint.\n"};
|
"Toggle automatic printing after processing a record that has a breakpoint.\n"};
|
||||||
static void dbapCallFunc(const iocshArgBuf *args) { dbap(args[0].sval);}
|
static void dbapCallFunc(const iocshArgBuf *args) { iocshSetError(dbap(args[0].sval));}
|
||||||
|
|
||||||
/* dbsr */
|
/* dbsr */
|
||||||
static const iocshArg dbsrArg0 = { "interest level",iocshArgInt};
|
static const iocshArg dbsrArg0 = { "interest level",iocshArgInt};
|
||||||
@ -150,7 +152,7 @@ static const iocshFuncDef dbcarFuncDef = {"dbcar",2,dbcarArgs,
|
|||||||
" 2 - Shows info. for all links.\n"};
|
" 2 - Shows info. for all links.\n"};
|
||||||
static void dbcarCallFunc(const iocshArgBuf *args)
|
static void dbcarCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
dbcar(args[0].sval,args[1].ival);
|
iocshSetError(dbcar(args[0].sval,args[1].ival));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dbjlr */
|
/* dbjlr */
|
||||||
@ -162,7 +164,7 @@ static const iocshFuncDef dbjlrFuncDef = {"dbjlr",2,dbjlrArgs,
|
|||||||
"List all JSON links in a record. If no record is specified, print for all\n"};
|
"List all JSON links in a record. If no record is specified, print for all\n"};
|
||||||
static void dbjlrCallFunc(const iocshArgBuf *args)
|
static void dbjlrCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
dbjlr(args[0].sval,args[1].ival);
|
iocshSetError(dbjlr(args[0].sval,args[1].ival));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dbel */
|
/* dbel */
|
||||||
@ -176,7 +178,7 @@ static const iocshFuncDef dbelFuncDef = {"dbel",2,dbelArgs,
|
|||||||
"Example: dbel aitest 2\n"};
|
"Example: dbel aitest 2\n"};
|
||||||
static void dbelCallFunc(const iocshArgBuf *args)
|
static void dbelCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
dbel(args[0].sval, args[1].ival);
|
iocshSetError(dbel(args[0].sval, args[1].ival));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dba */
|
/* dba */
|
||||||
@ -187,7 +189,7 @@ static const iocshFuncDef dbaFuncDef = {"dba",1,dbaArgs,
|
|||||||
"Print information in the dbAddr structure for a specific field.\n"
|
"Print information in the dbAddr structure for a specific field.\n"
|
||||||
"If no field is specified, VAL is assumed.\n\n"
|
"If no field is specified, VAL is assumed.\n\n"
|
||||||
"Example: dba(\"aitest.HIGH\")\n"};
|
"Example: dba(\"aitest.HIGH\")\n"};
|
||||||
static void dbaCallFunc(const iocshArgBuf *args) { dba(args[0].sval);}
|
static void dbaCallFunc(const iocshArgBuf *args) { iocshSetError(dba(args[0].sval));}
|
||||||
|
|
||||||
/* dbl */
|
/* dbl */
|
||||||
static const iocshArg dblArg0 = { "record type",iocshArgString};
|
static const iocshArg dblArg0 = { "record type",iocshArgString};
|
||||||
@ -204,7 +206,7 @@ static const iocshFuncDef dblFuncDef = {"dbl",2,dblArgs,
|
|||||||
" dbl(\"ai\",\"HIGH LOW VAL PREC\")\n"};
|
" dbl(\"ai\",\"HIGH LOW VAL PREC\")\n"};
|
||||||
static void dblCallFunc(const iocshArgBuf *args)
|
static void dblCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
dbl(args[0].sval,args[1].sval);
|
iocshSetError(dbl(args[0].sval,args[1].sval));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dbnr */
|
/* dbnr */
|
||||||
@ -213,7 +215,7 @@ static const iocshArg * const dbnrArgs[1] = {&dbnrArg0};
|
|||||||
static const iocshFuncDef dbnrFuncDef = {"dbnr",1,dbnrArgs,
|
static const iocshFuncDef dbnrFuncDef = {"dbnr",1,dbnrArgs,
|
||||||
"List number of records and aliases by type.\n"
|
"List number of records and aliases by type.\n"
|
||||||
"If verbose, list all record types regardless of being instanced\n"};
|
"If verbose, list all record types regardless of being instanced\n"};
|
||||||
static void dbnrCallFunc(const iocshArgBuf *args) { dbnr(args[0].ival);}
|
static void dbnrCallFunc(const iocshArgBuf *args) { iocshSetError(dbnr(args[0].ival));}
|
||||||
|
|
||||||
/* dbli */
|
/* dbli */
|
||||||
static const iocshArg dbliArg0 = { "pattern",iocshArgString};
|
static const iocshArg dbliArg0 = { "pattern",iocshArgString};
|
||||||
@ -221,7 +223,7 @@ static const iocshArg * const dbliArgs[1] = {&dbliArg0};
|
|||||||
static const iocshFuncDef dbliFuncDef = {"dbli",1,dbliArgs,
|
static const iocshFuncDef dbliFuncDef = {"dbli",1,dbliArgs,
|
||||||
"List info() tags with names matching pattern.\n\n"
|
"List info() tags with names matching pattern.\n\n"
|
||||||
"Example: dbli(\"autosave*\")\n"};
|
"Example: dbli(\"autosave*\")\n"};
|
||||||
static void dbliCallFunc(const iocshArgBuf *args) { dbli(args[0].sval);}
|
static void dbliCallFunc(const iocshArgBuf *args) { iocshSetError(dbli(args[0].sval));}
|
||||||
|
|
||||||
/* dbla */
|
/* dbla */
|
||||||
static const iocshArg dblaArg0 = { "pattern",iocshArgStringRecord};
|
static const iocshArg dblaArg0 = { "pattern",iocshArgStringRecord};
|
||||||
@ -229,7 +231,7 @@ static const iocshArg * const dblaArgs[1] = {&dblaArg0};
|
|||||||
static const iocshFuncDef dblaFuncDef = {"dbla",1,dblaArgs,
|
static const iocshFuncDef dblaFuncDef = {"dbla",1,dblaArgs,
|
||||||
"List record alias()s by alias name pattern.\n\n"
|
"List record alias()s by alias name pattern.\n\n"
|
||||||
"Example: dbla(\"alia*\")\n"};
|
"Example: dbla(\"alia*\")\n"};
|
||||||
static void dblaCallFunc(const iocshArgBuf *args) { dbla(args[0].sval);}
|
static void dblaCallFunc(const iocshArgBuf *args) { iocshSetError(dbla(args[0].sval));}
|
||||||
|
|
||||||
/* dbgrep */
|
/* dbgrep */
|
||||||
static const iocshArg dbgrepArg0 = { "pattern",iocshArgStringRecord};
|
static const iocshArg dbgrepArg0 = { "pattern",iocshArgStringRecord};
|
||||||
@ -240,7 +242,7 @@ static const iocshFuncDef dbgrepFuncDef = {"dbgrep",1,dbgrepArgs,
|
|||||||
" - \"?\", which matches 0 or one characters.\n"
|
" - \"?\", which matches 0 or one characters.\n"
|
||||||
" - \"*\", which matches 0 or more characters.\n\n"
|
" - \"*\", which matches 0 or more characters.\n\n"
|
||||||
"Example: dbgrep(\"*gpibAi*\")\n"};
|
"Example: dbgrep(\"*gpibAi*\")\n"};
|
||||||
static void dbgrepCallFunc(const iocshArgBuf *args) { dbgrep(args[0].sval);}
|
static void dbgrepCallFunc(const iocshArgBuf *args) { iocshSetError(dbgrep(args[0].sval));}
|
||||||
|
|
||||||
/* dbgf */
|
/* dbgf */
|
||||||
static const iocshArg dbgfArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dbgfArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -250,7 +252,7 @@ static const iocshFuncDef dbgfFuncDef = {"dbgf",1,dbgfArgs,
|
|||||||
"Print current value of record field.\n"
|
"Print current value of record field.\n"
|
||||||
"If no field name is specified, VAL is assumed.\n\n"
|
"If no field name is specified, VAL is assumed.\n\n"
|
||||||
"Example: dbgf(\"aitest.VAL\")\n"};
|
"Example: dbgf(\"aitest.VAL\")\n"};
|
||||||
static void dbgfCallFunc(const iocshArgBuf *args) { dbgf(args[0].sval);}
|
static void dbgfCallFunc(const iocshArgBuf *args) { iocshSetError(dbgf(args[0].sval));}
|
||||||
|
|
||||||
/* dbpf */
|
/* dbpf */
|
||||||
static const iocshArg dbpfArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dbpfArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -261,7 +263,7 @@ static const iocshFuncDef dbpfFuncDef = {"dbpf",2,dbpfArgs,
|
|||||||
"Change value of record field and read it back with dbgf.\n"
|
"Change value of record field and read it back with dbgf.\n"
|
||||||
"If no field is specified, VAL is assumed\n"};
|
"If no field is specified, VAL is assumed\n"};
|
||||||
static void dbpfCallFunc(const iocshArgBuf *args)
|
static void dbpfCallFunc(const iocshArgBuf *args)
|
||||||
{ dbpf(args[0].sval,args[1].sval);}
|
{ iocshSetError(dbpf(args[0].sval,args[1].sval));}
|
||||||
|
|
||||||
/* dbpr */
|
/* dbpr */
|
||||||
static const iocshArg dbprArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dbprArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -279,14 +281,14 @@ static const iocshFuncDef dbprFuncDef = {
|
|||||||
"Example: dbpr aitest 3\n"
|
"Example: dbpr aitest 3\n"
|
||||||
};
|
};
|
||||||
static void dbprCallFunc(const iocshArgBuf *args)
|
static void dbprCallFunc(const iocshArgBuf *args)
|
||||||
{ dbpr(args[0].sval,args[1].ival);}
|
{ iocshSetError(dbpr(args[0].sval,args[1].ival));}
|
||||||
|
|
||||||
/* dbtr */
|
/* dbtr */
|
||||||
static const iocshArg dbtrArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dbtrArg0 = { "record name",iocshArgStringRecord};
|
||||||
static const iocshArg * const dbtrArgs[1] = {&dbtrArg0};
|
static const iocshArg * const dbtrArgs[1] = {&dbtrArg0};
|
||||||
static const iocshFuncDef dbtrFuncDef = {"dbtr",1,dbtrArgs,
|
static const iocshFuncDef dbtrFuncDef = {"dbtr",1,dbtrArgs,
|
||||||
"Process record and then some fields.\n"};
|
"Process record and then some fields.\n"};
|
||||||
static void dbtrCallFunc(const iocshArgBuf *args) { dbtr(args[0].sval);}
|
static void dbtrCallFunc(const iocshArgBuf *args) { iocshSetError(dbtr(args[0].sval));}
|
||||||
|
|
||||||
/* dbtgf */
|
/* dbtgf */
|
||||||
static const iocshArg dbtgfArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dbtgfArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -296,7 +298,7 @@ static const iocshFuncDef dbtgfFuncDef = {"dbtgf",1,dbtgfArgs,
|
|||||||
"Get and print the specified field with all possible DBR_* types\n"
|
"Get and print the specified field with all possible DBR_* types\n"
|
||||||
"Example: dbtgf aitest\n"
|
"Example: dbtgf aitest\n"
|
||||||
"Example: dbtgf aitest.VAL\n"};
|
"Example: dbtgf aitest.VAL\n"};
|
||||||
static void dbtgfCallFunc(const iocshArgBuf *args) { dbtgf(args[0].sval);}
|
static void dbtgfCallFunc(const iocshArgBuf *args) { iocshSetError(dbtgf(args[0].sval));}
|
||||||
|
|
||||||
/* dbtpf */
|
/* dbtpf */
|
||||||
static const iocshArg dbtpfArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dbtpfArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -308,7 +310,7 @@ static const iocshFuncDef dbtpfFuncDef = {"dbtpf",2,dbtpfArgs,
|
|||||||
"for all possible DBR_* types\n\n"
|
"for all possible DBR_* types\n\n"
|
||||||
"Example: dbtpf aitest 5.0\n"};
|
"Example: dbtpf aitest 5.0\n"};
|
||||||
static void dbtpfCallFunc(const iocshArgBuf *args)
|
static void dbtpfCallFunc(const iocshArgBuf *args)
|
||||||
{ dbtpf(args[0].sval,args[1].sval);}
|
{ iocshSetError(dbtpf(args[0].sval,args[1].sval));}
|
||||||
|
|
||||||
/* dbior */
|
/* dbior */
|
||||||
static const iocshArg dbiorArg0 = { "driver name",iocshArgString};
|
static const iocshArg dbiorArg0 = { "driver name",iocshArgString};
|
||||||
@ -317,7 +319,7 @@ static const iocshArg * const dbiorArgs[] = {&dbiorArg0,&dbiorArg1};
|
|||||||
static const iocshFuncDef dbiorFuncDef = {"dbior",2,dbiorArgs,
|
static const iocshFuncDef dbiorFuncDef = {"dbior",2,dbiorArgs,
|
||||||
"Driver Report.\n"};
|
"Driver Report.\n"};
|
||||||
static void dbiorCallFunc(const iocshArgBuf *args)
|
static void dbiorCallFunc(const iocshArgBuf *args)
|
||||||
{ dbior(args[0].sval,args[1].ival);}
|
{ iocshSetError(dbior(args[0].sval,args[1].ival));}
|
||||||
|
|
||||||
/* dbhcr */
|
/* dbhcr */
|
||||||
static const iocshFuncDef dbhcrFuncDef = {"dbhcr",0,0,
|
static const iocshFuncDef dbhcrFuncDef = {"dbhcr",0,0,
|
||||||
@ -327,7 +329,7 @@ static const iocshFuncDef dbhcrFuncDef = {"dbhcr",0,0,
|
|||||||
"Use the UNIX sort command:\n"
|
"Use the UNIX sort command:\n"
|
||||||
"dbhcr > report\n"
|
"dbhcr > report\n"
|
||||||
"sort report > report.sorted\n"};
|
"sort report > report.sorted\n"};
|
||||||
static void dbhcrCallFunc(const iocshArgBuf *args) { dbhcr();}
|
static void dbhcrCallFunc(const iocshArgBuf *args) { iocshSetError(dbhcr());}
|
||||||
|
|
||||||
/* gft */
|
/* gft */
|
||||||
static const iocshArg gftArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg gftArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -336,7 +338,7 @@ static const iocshFuncDef gftFuncDef = {"gft",1,gftArgs,
|
|||||||
"Report dbChannel info and value.\n"
|
"Report dbChannel info and value.\n"
|
||||||
"Example: gft aitest\n"
|
"Example: gft aitest\n"
|
||||||
"Example: gft aitest.VAL\n"};
|
"Example: gft aitest.VAL\n"};
|
||||||
static void gftCallFunc(const iocshArgBuf *args) { gft(args[0].sval);}
|
static void gftCallFunc(const iocshArgBuf *args) { iocshSetError(gft(args[0].sval));}
|
||||||
|
|
||||||
/* pft */
|
/* pft */
|
||||||
static const iocshArg pftArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg pftArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -346,7 +348,7 @@ static const iocshFuncDef pftFuncDef = {"pft",2,pftArgs,
|
|||||||
"dbChannel put value.\n"
|
"dbChannel put value.\n"
|
||||||
"Example: pft aitest 5.0\n"};
|
"Example: pft aitest 5.0\n"};
|
||||||
static void pftCallFunc(const iocshArgBuf *args)
|
static void pftCallFunc(const iocshArgBuf *args)
|
||||||
{ pft(args[0].sval,args[1].sval);}
|
{ iocshSetError(pft(args[0].sval,args[1].sval));}
|
||||||
|
|
||||||
/* dbtpn */
|
/* dbtpn */
|
||||||
static const iocshArg dbtpnArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dbtpnArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -359,12 +361,12 @@ static const iocshFuncDef dbtpnFuncDef = {"dbtpn",2,dbtpnArgs,
|
|||||||
"Example: dbtpn aitest\n"
|
"Example: dbtpn aitest\n"
|
||||||
"Example: dbtpn aitest 5.0\n"};
|
"Example: dbtpn aitest 5.0\n"};
|
||||||
static void dbtpnCallFunc(const iocshArgBuf *args)
|
static void dbtpnCallFunc(const iocshArgBuf *args)
|
||||||
{ dbtpn(args[0].sval,args[1].sval);}
|
{ iocshSetError(dbtpn(args[0].sval,args[1].sval));}
|
||||||
|
|
||||||
/* dbNotifyDump */
|
/* dbNotifyDump */
|
||||||
static const iocshFuncDef dbNotifyDumpFuncDef = {"dbNotifyDump",0,0,
|
static const iocshFuncDef dbNotifyDumpFuncDef = {"dbNotifyDump",0,0,
|
||||||
"Report status of any active async processing with completion notification.\n"};
|
"Report status of any active async processing with completion notification.\n"};
|
||||||
static void dbNotifyDumpCallFunc(const iocshArgBuf *args) { dbNotifyDump();}
|
static void dbNotifyDumpCallFunc(const iocshArgBuf *args) { iocshSetError(dbNotifyDump());}
|
||||||
|
|
||||||
/* dbPutAttribute */
|
/* dbPutAttribute */
|
||||||
static const iocshArg dbPutAttrArg0 = { "record type",iocshArgString};
|
static const iocshArg dbPutAttrArg0 = { "record type",iocshArgString};
|
||||||
@ -375,7 +377,7 @@ static const iocshArg * const dbPutAttrArgs[] =
|
|||||||
static const iocshFuncDef dbPutAttrFuncDef = {"dbPutAttribute",3,dbPutAttrArgs,
|
static const iocshFuncDef dbPutAttrFuncDef = {"dbPutAttribute",3,dbPutAttrArgs,
|
||||||
"Set/Create record attribute.\n"};
|
"Set/Create record attribute.\n"};
|
||||||
static void dbPutAttrCallFunc(const iocshArgBuf *args)
|
static void dbPutAttrCallFunc(const iocshArgBuf *args)
|
||||||
{ dbPutAttribute(args[0].sval,args[1].sval,args[2].sval);}
|
{ iocshSetError(dbPutAttribute(args[0].sval,args[1].sval,args[2].sval));}
|
||||||
|
|
||||||
/* tpn */
|
/* tpn */
|
||||||
static const iocshArg tpnArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg tpnArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -385,7 +387,7 @@ static const iocshFuncDef tpnFuncDef = {"tpn",2,tpnArgs,
|
|||||||
"Test Process Notify.\n\n"
|
"Test Process Notify.\n\n"
|
||||||
"Example: tpn aitest 5.0\n"};
|
"Example: tpn aitest 5.0\n"};
|
||||||
static void tpnCallFunc(const iocshArgBuf *args)
|
static void tpnCallFunc(const iocshArgBuf *args)
|
||||||
{ tpn(args[0].sval,args[1].sval);}
|
{ iocshSetError(tpn(args[0].sval,args[1].sval));}
|
||||||
|
|
||||||
/* dblsr */
|
/* dblsr */
|
||||||
static const iocshArg dblsrArg0 = { "record name",iocshArgStringRecord};
|
static const iocshArg dblsrArg0 = { "record name",iocshArgStringRecord};
|
||||||
@ -399,7 +401,7 @@ static const iocshFuncDef dblsrFuncDef = {"dblsr",2,dblsrArgs,
|
|||||||
" 2 - Show each record and all database links in the lock set.\n\n"
|
" 2 - Show each record and all database links in the lock set.\n\n"
|
||||||
"Example: dblsr aitest 2\n"};
|
"Example: dblsr aitest 2\n"};
|
||||||
static void dblsrCallFunc(const iocshArgBuf *args)
|
static void dblsrCallFunc(const iocshArgBuf *args)
|
||||||
{ dblsr(args[0].sval,args[1].ival);}
|
{ iocshSetError(dblsr(args[0].sval,args[1].ival));}
|
||||||
|
|
||||||
/* dbLockShowLocked */
|
/* dbLockShowLocked */
|
||||||
static const iocshArg dbLockShowLockedArg0 = { "interest level",iocshArgInt};
|
static const iocshArg dbLockShowLockedArg0 = { "interest level",iocshArgInt};
|
||||||
@ -412,7 +414,7 @@ static const iocshFuncDef dbLockShowLockedFuncDef = {
|
|||||||
"Example: dbLockShowLocked 0\n"
|
"Example: dbLockShowLocked 0\n"
|
||||||
};
|
};
|
||||||
static void dbLockShowLockedCallFunc(const iocshArgBuf *args)
|
static void dbLockShowLockedCallFunc(const iocshArgBuf *args)
|
||||||
{ dbLockShowLocked(args[0].ival);}
|
{ iocshSetError(dbLockShowLocked(args[0].ival));}
|
||||||
|
|
||||||
/* scanOnceSetQueueSize */
|
/* scanOnceSetQueueSize */
|
||||||
static const iocshArg scanOnceSetQueueSizeArg0 = { "size",iocshArgInt};
|
static const iocshArg scanOnceSetQueueSizeArg0 = { "size",iocshArgInt};
|
||||||
@ -423,7 +425,7 @@ static const iocshFuncDef scanOnceSetQueueSizeFuncDef = {"scanOnceSetQueueSize",
|
|||||||
"Must be called before iocInit().\n"};
|
"Must be called before iocInit().\n"};
|
||||||
static void scanOnceSetQueueSizeCallFunc(const iocshArgBuf *args)
|
static void scanOnceSetQueueSizeCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
scanOnceSetQueueSize(args[0].ival);
|
iocshSetError(scanOnceSetQueueSize(args[0].ival));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* scanOnceQueueShow */
|
/* scanOnceQueueShow */
|
||||||
@ -444,7 +446,7 @@ static const iocshFuncDef scanpplFuncDef = {"scanppl",1,scanpplArgs,
|
|||||||
"Print info for records with periodic scan.\n"
|
"Print info for records with periodic scan.\n"
|
||||||
"If rate == 0.0, all periods are shown.\n"};
|
"If rate == 0.0, all periods are shown.\n"};
|
||||||
static void scanpplCallFunc(const iocshArgBuf *args)
|
static void scanpplCallFunc(const iocshArgBuf *args)
|
||||||
{ scanppl(args[0].dval);}
|
{ iocshSetError(scanppl(args[0].dval));}
|
||||||
|
|
||||||
/* scanpel */
|
/* scanpel */
|
||||||
static const iocshArg scanpelArg0 = { "event name",iocshArgString};
|
static const iocshArg scanpelArg0 = { "event name",iocshArgString};
|
||||||
@ -452,7 +454,7 @@ static const iocshArg * const scanpelArgs[1] = {&scanpelArg0};
|
|||||||
static const iocshFuncDef scanpelFuncDef = {"scanpel",1,scanpelArgs,
|
static const iocshFuncDef scanpelFuncDef = {"scanpel",1,scanpelArgs,
|
||||||
"Print info for records with SCAN = \"Event\".\n"};
|
"Print info for records with SCAN = \"Event\".\n"};
|
||||||
static void scanpelCallFunc(const iocshArgBuf *args)
|
static void scanpelCallFunc(const iocshArgBuf *args)
|
||||||
{ scanpel(args[0].sval);}
|
{ iocshSetError(scanpel(args[0].sval));}
|
||||||
|
|
||||||
/* postEvent */
|
/* postEvent */
|
||||||
static const iocshArg postEventArg0 = { "event name",iocshArgString};
|
static const iocshArg postEventArg0 = { "event name",iocshArgString};
|
||||||
@ -468,7 +470,7 @@ static void postEventCallFunc(const iocshArgBuf *args)
|
|||||||
/* scanpiol */
|
/* scanpiol */
|
||||||
static const iocshFuncDef scanpiolFuncDef = {"scanpiol",0,0,
|
static const iocshFuncDef scanpiolFuncDef = {"scanpiol",0,0,
|
||||||
"Print info for records with SCAN = \"I/O Intr\".\n"};
|
"Print info for records with SCAN = \"I/O Intr\".\n"};
|
||||||
static void scanpiolCallFunc(const iocshArgBuf *args) { scanpiol();}
|
static void scanpiolCallFunc(const iocshArgBuf *args) { iocshSetError(scanpiol());}
|
||||||
|
|
||||||
/* callbackSetQueueSize */
|
/* callbackSetQueueSize */
|
||||||
static const iocshArg callbackSetQueueSizeArg0 = { "bufsize",iocshArgInt};
|
static const iocshArg callbackSetQueueSizeArg0 = { "bufsize",iocshArgInt};
|
||||||
@ -479,7 +481,7 @@ static const iocshFuncDef callbackSetQueueSizeFuncDef = {"callbackSetQueueSize",
|
|||||||
"Must be called before iocInit().\n"};
|
"Must be called before iocInit().\n"};
|
||||||
static void callbackSetQueueSizeCallFunc(const iocshArgBuf *args)
|
static void callbackSetQueueSizeCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
callbackSetQueueSize(args[0].ival);
|
iocshSetError(callbackSetQueueSize(args[0].ival));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* callbackQueueShow */
|
/* callbackQueueShow */
|
||||||
@ -504,7 +506,7 @@ static const iocshFuncDef callbackParallelThreadsFuncDef = {"callbackParallelThr
|
|||||||
"or one of LOW, MEDIUM, or HIGH.\n"};
|
"or one of LOW, MEDIUM, or HIGH.\n"};
|
||||||
static void callbackParallelThreadsCallFunc(const iocshArgBuf *args)
|
static void callbackParallelThreadsCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
callbackParallelThreads(args[0].ival, args[1].sval);
|
iocshSetError(callbackParallelThreads(args[0].ival, args[1].sval));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dbStateCreate */
|
/* dbStateCreate */
|
||||||
@ -514,7 +516,8 @@ static const iocshFuncDef dbStateCreateFuncDef = {"dbStateCreate", 1, dbStateCre
|
|||||||
"Allocate new state name for \"state\" filter.\n"};
|
"Allocate new state name for \"state\" filter.\n"};
|
||||||
static void dbStateCreateCallFunc (const iocshArgBuf *args)
|
static void dbStateCreateCallFunc (const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
dbStateCreate(args[0].sval);
|
if (!dbStateCreate(args[0].sval))
|
||||||
|
iocshSetError(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dbStateSet */
|
/* dbStateSet */
|
||||||
@ -527,6 +530,8 @@ static void dbStateSetCallFunc (const iocshArgBuf *args)
|
|||||||
|
|
||||||
if (sid)
|
if (sid)
|
||||||
dbStateSet(sid);
|
dbStateSet(sid);
|
||||||
|
else
|
||||||
|
iocshSetError(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dbStateClear */
|
/* dbStateClear */
|
||||||
@ -539,6 +544,8 @@ static void dbStateClearCallFunc (const iocshArgBuf *args)
|
|||||||
|
|
||||||
if (sid)
|
if (sid)
|
||||||
dbStateClear(sid);
|
dbStateClear(sid);
|
||||||
|
else
|
||||||
|
iocshSetError(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dbStateShow */
|
/* dbStateShow */
|
||||||
@ -552,6 +559,8 @@ static void dbStateShowCallFunc (const iocshArgBuf *args)
|
|||||||
|
|
||||||
if (sid)
|
if (sid)
|
||||||
dbStateShow(sid, args[1].ival);
|
dbStateShow(sid, args[1].ival);
|
||||||
|
else
|
||||||
|
iocshSetError(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dbStateShowAll */
|
/* dbStateShowAll */
|
||||||
|
@ -391,6 +391,10 @@ typedef struct lset {
|
|||||||
#define dbGetSevr(link, sevr) \
|
#define dbGetSevr(link, sevr) \
|
||||||
dbGetAlarm(link, NULL, sevr)
|
dbGetAlarm(link, NULL, sevr)
|
||||||
|
|
||||||
|
/** @brief Lookup link field name from pointer.
|
||||||
|
* Returns only field name. aka. value of ``dbFldDes::name``
|
||||||
|
* @since 3.16.2
|
||||||
|
*/
|
||||||
DBCORE_API const char * dbLinkFieldName(const struct link *plink);
|
DBCORE_API const char * dbLinkFieldName(const struct link *plink);
|
||||||
|
|
||||||
DBCORE_API void dbInitLink(struct link *plink, short dbfType);
|
DBCORE_API void dbInitLink(struct link *plink, short dbfType);
|
||||||
|
@ -260,8 +260,8 @@ int recGblSetSevr(void *precord, epicsEnum16 new_stat, epicsEnum16 new_sevr)
|
|||||||
return recGblSetSevrMsg(precord, new_stat, new_sevr, NULL);
|
return recGblSetSevrMsg(precord, new_stat, new_sevr, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recGblInheritSevr(int msMode, void *precord, epicsEnum16 stat,
|
void recGblInheritSevrMsg(int msMode, void *precord, epicsEnum16 stat,
|
||||||
epicsEnum16 sevr)
|
epicsEnum16 sevr, const char *msg)
|
||||||
{
|
{
|
||||||
switch (msMode) {
|
switch (msMode) {
|
||||||
case pvlOptNMS:
|
case pvlOptNMS:
|
||||||
@ -274,11 +274,17 @@ void recGblInheritSevr(int msMode, void *precord, epicsEnum16 stat,
|
|||||||
recGblSetSevr(precord, LINK_ALARM, sevr);
|
recGblSetSevr(precord, LINK_ALARM, sevr);
|
||||||
break;
|
break;
|
||||||
case pvlOptMSS:
|
case pvlOptMSS:
|
||||||
recGblSetSevr(precord, stat, sevr);
|
/* Only MSS inherits msg */
|
||||||
|
recGblSetSevrMsg(precord, stat, sevr, "%s", msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void recGblInheritSevr(int msMode, void *precord, epicsEnum16 stat,
|
||||||
|
epicsEnum16 sevr)
|
||||||
|
{
|
||||||
|
recGblInheritSevrMsg(msMode, precord, stat, sevr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void recGblFwdLink(void *precord)
|
void recGblFwdLink(void *precord)
|
||||||
{
|
{
|
||||||
|
@ -73,6 +73,8 @@ DBCORE_API int recGblSetSevr(void *precord, epicsEnum16 new_stat,
|
|||||||
epicsEnum16 new_sevr);
|
epicsEnum16 new_sevr);
|
||||||
DBCORE_API void recGblInheritSevr(int msMode, void *precord, epicsEnum16 stat,
|
DBCORE_API void recGblInheritSevr(int msMode, void *precord, epicsEnum16 stat,
|
||||||
epicsEnum16 sevr);
|
epicsEnum16 sevr);
|
||||||
|
DBCORE_API void recGblInheritSevrMsg(int msMode, void *precord, epicsEnum16 stat,
|
||||||
|
epicsEnum16 sevr, const char *msg);
|
||||||
DBCORE_API int recGblSetSevrMsg(void *precord, epicsEnum16 new_stat,
|
DBCORE_API int recGblSetSevrMsg(void *precord, epicsEnum16 new_stat,
|
||||||
epicsEnum16 new_sevr,
|
epicsEnum16 new_sevr,
|
||||||
EPICS_PRINTF_FMT(const char *msg), ...) EPICS_PRINTF_STYLE(4,5);
|
EPICS_PRINTF_FMT(const char *msg), ...) EPICS_PRINTF_STYLE(4,5);
|
||||||
|
@ -207,7 +207,7 @@ static const iocshFuncDef dbPvdTableSizeFuncDef = {
|
|||||||
};
|
};
|
||||||
static void dbPvdTableSizeCallFunc(const iocshArgBuf *args)
|
static void dbPvdTableSizeCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
dbPvdTableSize(args[0].ival);
|
iocshSetError(dbPvdTableSize(args[0].ival));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dbReportDeviceConfig */
|
/* dbReportDeviceConfig */
|
||||||
|
@ -14,6 +14,7 @@ SRC_DIRS += $(IOCDIR)/dbtemplate
|
|||||||
PROD_CMD += msi
|
PROD_CMD += msi
|
||||||
|
|
||||||
msi_SRCS = msi.cpp
|
msi_SRCS = msi.cpp
|
||||||
|
msi_SYS_LIBS_WIN32 = shlwapi
|
||||||
DOCS += msi.md
|
DOCS += msi.md
|
||||||
|
|
||||||
INC += dbLoadTemplate.h
|
INC += dbLoadTemplate.h
|
||||||
|
@ -41,6 +41,17 @@ static int var_count, sub_count;
|
|||||||
int dbTemplateMaxVars = 100;
|
int dbTemplateMaxVars = 100;
|
||||||
epicsExportAddress(int, dbTemplateMaxVars);
|
epicsExportAddress(int, dbTemplateMaxVars);
|
||||||
|
|
||||||
|
static
|
||||||
|
int msiLoadRecords(const char *fname, const char *subs)
|
||||||
|
{
|
||||||
|
int ret = dbLoadRecords(fname, subs);
|
||||||
|
if(ret) {
|
||||||
|
fprintf(stderr, "dbLoadRecords(\"%s\", %s)\n", fname, subs);
|
||||||
|
yyerror("Error while reading included file");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%start substitution_file
|
%start substitution_file
|
||||||
@ -167,7 +178,7 @@ pattern_definition: global_definitions
|
|||||||
fprintf(stderr, "pattern_definition: pattern_values empty\n");
|
fprintf(stderr, "pattern_definition: pattern_values empty\n");
|
||||||
fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
|
fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
|
||||||
#endif
|
#endif
|
||||||
dbLoadRecords(db_file_name, sub_collect+1);
|
if(msiLoadRecords(db_file_name, sub_collect+1)) YYABORT;
|
||||||
}
|
}
|
||||||
| O_BRACE pattern_values C_BRACE
|
| O_BRACE pattern_values C_BRACE
|
||||||
{
|
{
|
||||||
@ -175,7 +186,7 @@ pattern_definition: global_definitions
|
|||||||
fprintf(stderr, "pattern_definition:\n");
|
fprintf(stderr, "pattern_definition:\n");
|
||||||
fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
|
fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
|
||||||
#endif
|
#endif
|
||||||
dbLoadRecords(db_file_name, sub_collect+1);
|
if(msiLoadRecords(db_file_name, sub_collect+1)) YYABORT;
|
||||||
*sub_locals = '\0';
|
*sub_locals = '\0';
|
||||||
sub_count = 0;
|
sub_count = 0;
|
||||||
}
|
}
|
||||||
@ -190,7 +201,7 @@ pattern_definition: global_definitions
|
|||||||
fprintf(stderr, "pattern_definition:\n");
|
fprintf(stderr, "pattern_definition:\n");
|
||||||
fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
|
fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
|
||||||
#endif
|
#endif
|
||||||
dbLoadRecords(db_file_name, sub_collect+1);
|
if(msiLoadRecords(db_file_name, sub_collect+1)) YYABORT;
|
||||||
dbmfFree($1);
|
dbmfFree($1);
|
||||||
*sub_locals = '\0';
|
*sub_locals = '\0';
|
||||||
sub_count = 0;
|
sub_count = 0;
|
||||||
@ -250,7 +261,7 @@ variable_substitution: global_definitions
|
|||||||
fprintf(stderr, "variable_substitution: variable_definitions empty\n");
|
fprintf(stderr, "variable_substitution: variable_definitions empty\n");
|
||||||
fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
|
fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
|
||||||
#endif
|
#endif
|
||||||
dbLoadRecords(db_file_name, sub_collect+1);
|
if(msiLoadRecords(db_file_name, sub_collect+1)) YYABORT;
|
||||||
}
|
}
|
||||||
| O_BRACE variable_definitions C_BRACE
|
| O_BRACE variable_definitions C_BRACE
|
||||||
{
|
{
|
||||||
@ -258,7 +269,7 @@ variable_substitution: global_definitions
|
|||||||
fprintf(stderr, "variable_substitution:\n");
|
fprintf(stderr, "variable_substitution:\n");
|
||||||
fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
|
fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
|
||||||
#endif
|
#endif
|
||||||
dbLoadRecords(db_file_name, sub_collect+1);
|
if(msiLoadRecords(db_file_name, sub_collect+1)) YYABORT;
|
||||||
*sub_locals = '\0';
|
*sub_locals = '\0';
|
||||||
}
|
}
|
||||||
| WORD O_BRACE variable_definitions C_BRACE
|
| WORD O_BRACE variable_definitions C_BRACE
|
||||||
@ -272,7 +283,7 @@ variable_substitution: global_definitions
|
|||||||
fprintf(stderr, "variable_substitution:\n");
|
fprintf(stderr, "variable_substitution:\n");
|
||||||
fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
|
fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
|
||||||
#endif
|
#endif
|
||||||
dbLoadRecords(db_file_name, sub_collect+1);
|
if(msiLoadRecords(db_file_name, sub_collect+1)) YYABORT;
|
||||||
dbmfFree($1);
|
dbmfFree($1);
|
||||||
*sub_locals = '\0';
|
*sub_locals = '\0';
|
||||||
}
|
}
|
||||||
@ -328,6 +339,7 @@ int dbLoadTemplate(const char *sub_file, const char *cmd_collect)
|
|||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int i;
|
int i;
|
||||||
|
int err;
|
||||||
|
|
||||||
line_num = 1;
|
line_num = 1;
|
||||||
|
|
||||||
@ -377,7 +389,7 @@ int dbLoadTemplate(const char *sub_file, const char *cmd_collect)
|
|||||||
yyrestart(fp);
|
yyrestart(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
yyparse();
|
err = yyparse();
|
||||||
|
|
||||||
for (i = 0; i < var_count; i++) {
|
for (i = 0; i < var_count; i++) {
|
||||||
dbmfFree(vars[i]);
|
dbmfFree(vars[i]);
|
||||||
@ -390,5 +402,5 @@ int dbLoadTemplate(const char *sub_file, const char *cmd_collect)
|
|||||||
dbmfFree(db_file_name);
|
dbmfFree(db_file_name);
|
||||||
db_file_name = NULL;
|
db_file_name = NULL;
|
||||||
}
|
}
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,10 @@
|
|||||||
#include <osiFileName.h>
|
#include <osiFileName.h>
|
||||||
#include <osiUnistd.h>
|
#include <osiUnistd.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <shlwapi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MAX_BUFFER_SIZE 4096
|
#define MAX_BUFFER_SIZE 4096
|
||||||
#define MAX_DEPS 1024
|
#define MAX_DEPS 1024
|
||||||
|
|
||||||
@ -61,7 +65,7 @@ typedef struct inputData inputData;
|
|||||||
static void inputConstruct(inputData **ppvt);
|
static void inputConstruct(inputData **ppvt);
|
||||||
static void inputDestruct(inputData * const pvt);
|
static void inputDestruct(inputData * const pvt);
|
||||||
static void inputAddPath(inputData * const pvt, const char * const pval);
|
static void inputAddPath(inputData * const pvt, const char * const pval);
|
||||||
static void inputBegin(inputData * const pvt, const char * const fileName);
|
static void inputBegin(inputData * const pvt, const char * const fileName, bool fromCmdLine);
|
||||||
static char *inputNextLine(inputData * const pvt);
|
static char *inputNextLine(inputData * const pvt);
|
||||||
static void inputNewIncludeFile(inputData * const pvt, const char * const name);
|
static void inputNewIncludeFile(inputData * const pvt, const char * const name);
|
||||||
static void inputErrPrint(const inputData * const pvt);
|
static void inputErrPrint(const inputData * const pvt);
|
||||||
@ -83,7 +87,8 @@ static void addMacroReplacements(MAC_HANDLE * const macPvt,
|
|||||||
const char * const pval);
|
const char * const pval);
|
||||||
static void makeSubstitutions(inputData * const inputPvt,
|
static void makeSubstitutions(inputData * const inputPvt,
|
||||||
MAC_HANDLE * const macPvt,
|
MAC_HANDLE * const macPvt,
|
||||||
const char * const templateName);
|
const char * const templateName,
|
||||||
|
bool fromCmdLine);
|
||||||
|
|
||||||
/*Global variables */
|
/*Global variables */
|
||||||
static int opt_V = 0;
|
static int opt_V = 0;
|
||||||
@ -171,7 +176,7 @@ int main(int argc,char **argv)
|
|||||||
|
|
||||||
if (substitutionName.empty()) {
|
if (substitutionName.empty()) {
|
||||||
STEP("Single template+substitutions file");
|
STEP("Single template+substitutions file");
|
||||||
makeSubstitutions(inputPvt, macPvt, templateName);
|
makeSubstitutions(inputPvt, macPvt, templateName, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
subInfo *substitutePvt;
|
subInfo *substitutePvt;
|
||||||
@ -203,7 +208,7 @@ int main(int argc,char **argv)
|
|||||||
macPushScope(macPvt);
|
macPushScope(macPvt);
|
||||||
|
|
||||||
addMacroReplacements(macPvt, macStr);
|
addMacroReplacements(macPvt, macStr);
|
||||||
makeSubstitutions(inputPvt, macPvt, filename);
|
makeSubstitutions(inputPvt, macPvt, filename, false);
|
||||||
|
|
||||||
if (localScope)
|
if (localScope)
|
||||||
macPopScope(macPvt);
|
macPopScope(macPvt);
|
||||||
@ -276,14 +281,15 @@ static const char *cmdNames[] = {"include","substitute"};
|
|||||||
|
|
||||||
static void makeSubstitutions(inputData * const inputPvt,
|
static void makeSubstitutions(inputData * const inputPvt,
|
||||||
MAC_HANDLE * const macPvt,
|
MAC_HANDLE * const macPvt,
|
||||||
const char * const templateName)
|
const char * const templateName,
|
||||||
|
bool fromCmdLine)
|
||||||
{
|
{
|
||||||
char *input;
|
char *input;
|
||||||
static char buffer[MAX_BUFFER_SIZE];
|
static char buffer[MAX_BUFFER_SIZE];
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
ENTER;
|
ENTER;
|
||||||
inputBegin(inputPvt, templateName);
|
inputBegin(inputPvt, templateName, fromCmdLine);
|
||||||
while ((input = inputNextLine(inputPvt))) {
|
while ((input = inputNextLine(inputPvt))) {
|
||||||
int expand=1;
|
int expand=1;
|
||||||
char *p;
|
char *p;
|
||||||
@ -378,7 +384,7 @@ struct inputData {
|
|||||||
inputData() { memset(inputBuffer, 0, sizeof(inputBuffer) * sizeof(inputBuffer[0])); };
|
inputData() { memset(inputBuffer, 0, sizeof(inputBuffer) * sizeof(inputBuffer[0])); };
|
||||||
};
|
};
|
||||||
|
|
||||||
static void inputOpenFile(inputData *pinputData, const char * const filename);
|
static void inputOpenFile(inputData *pinputData, const char * const filename, bool fromCmdLine);
|
||||||
static void inputCloseFile(inputData *pinputData);
|
static void inputCloseFile(inputData *pinputData);
|
||||||
static void inputCloseAllFiles(inputData *pinputData);
|
static void inputCloseAllFiles(inputData *pinputData);
|
||||||
|
|
||||||
@ -431,11 +437,11 @@ static void inputAddPath(inputData * const pinputData, const char * const path)
|
|||||||
EXIT;
|
EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inputBegin(inputData * const pinputData, const char * const fileName)
|
static void inputBegin(inputData * const pinputData, const char * const fileName, bool fromCmdLine)
|
||||||
{
|
{
|
||||||
ENTER;
|
ENTER;
|
||||||
inputCloseAllFiles(pinputData);
|
inputCloseAllFiles(pinputData);
|
||||||
inputOpenFile(pinputData, fileName);
|
inputOpenFile(pinputData, fileName, fromCmdLine);
|
||||||
EXIT;
|
EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,7 +468,7 @@ static void inputNewIncludeFile(inputData * const pinputData,
|
|||||||
const char * const name)
|
const char * const name)
|
||||||
{
|
{
|
||||||
ENTER;
|
ENTER;
|
||||||
inputOpenFile(pinputData,name);
|
inputOpenFile(pinputData, name, false);
|
||||||
EXIT;
|
EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,7 +499,15 @@ static void inputErrPrint(const inputData *const pinputData)
|
|||||||
EXIT;
|
EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inputOpenFile(inputData *pinputData, const char * const filename)
|
static int isPathRelative(const char * const path) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
return path && PathIsRelativeA(path);
|
||||||
|
#else
|
||||||
|
return path && path[0] != '/';
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inputOpenFile(inputData *pinputData, const char * const filename, bool fromCmdLine)
|
||||||
{
|
{
|
||||||
std::list<std::string>& pathList = pinputData->pathList;
|
std::list<std::string>& pathList = pinputData->pathList;
|
||||||
std::list<std::string>::iterator pathIt = pathList.end();
|
std::list<std::string>::iterator pathIt = pathList.end();
|
||||||
@ -505,7 +519,7 @@ static void inputOpenFile(inputData *pinputData, const char * const filename)
|
|||||||
STEP("Using stdin");
|
STEP("Using stdin");
|
||||||
fp = stdin;
|
fp = stdin;
|
||||||
}
|
}
|
||||||
else if (pathList.empty() || strchr(filename, '/')){
|
else if (fromCmdLine || pathList.empty() || !isPathRelative(filename)){
|
||||||
STEPS("Opening ", filename);
|
STEPS("Opening ", filename);
|
||||||
fp = fopen(filename, "r");
|
fp = fopen(filename, "r");
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,18 @@ Switches have the following meanings:
|
|||||||
2. . (the current directory)
|
2. . (the current directory)
|
||||||
3. .. (the parent of the current directory)
|
3. .. (the parent of the current directory)
|
||||||
|
|
||||||
|
Note that relative path searching is handled as
|
||||||
|
|
||||||
|
$ cat foo.substitutions
|
||||||
|
file rel/path/bar.template {
|
||||||
|
# contents
|
||||||
|
}
|
||||||
|
$ msi -I . -I /some/path foo.substitutions
|
||||||
|
|
||||||
|
which will try to find `bar.template` at the path `./rel/path/` followed by
|
||||||
|
`/some/path/rel/path`.
|
||||||
|
|
||||||
|
|
||||||
- **-M _substitutions_**
|
- **-M _substitutions_**
|
||||||
|
|
||||||
This parameter specifies macro values for the template instance.
|
This parameter specifies macro values for the template instance.
|
||||||
|
@ -10,11 +10,13 @@
|
|||||||
#include "iocsh.h"
|
#include "iocsh.h"
|
||||||
#include "epicsExport.h"
|
#include "epicsExport.h"
|
||||||
|
|
||||||
IOCSH_STATIC_FUNC void dlload(const char* name)
|
IOCSH_STATIC_FUNC int dlload(const char* name)
|
||||||
{
|
{
|
||||||
if (!epicsLoadLibrary(name)) {
|
if (!epicsLoadLibrary(name)) {
|
||||||
printf("epicsLoadLibrary failed: %s\n", epicsLoadError());
|
printf("epicsLoadLibrary failed: %s\n", epicsLoadError());
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const iocshArg dlloadArg0 = { "path/library.so", iocshArgStringPath};
|
static const iocshArg dlloadArg0 = { "path/library.so", iocshArgStringPath};
|
||||||
@ -28,7 +30,7 @@ static const iocshFuncDef dlloadFuncDef = {
|
|||||||
};
|
};
|
||||||
static void dlloadCallFunc(const iocshArgBuf *args)
|
static void dlloadCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
dlload(args[0].sval);
|
iocshSetError(dlload(args[0].sval));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dlloadRegistar(void) {
|
static void dlloadRegistar(void) {
|
||||||
|
@ -22,6 +22,9 @@ enum iocStateEnum {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Query present IOC run state
|
||||||
|
* @since 3.15.8
|
||||||
|
*/
|
||||||
DBCORE_API enum iocStateEnum getIocState(void);
|
DBCORE_API enum iocStateEnum getIocState(void);
|
||||||
DBCORE_API int iocInit(void);
|
DBCORE_API int iocInit(void);
|
||||||
DBCORE_API int iocBuild(void);
|
DBCORE_API int iocBuild(void);
|
||||||
|
@ -163,9 +163,11 @@ void camsgtask ( void *pParm )
|
|||||||
|
|
||||||
int casClientInitiatingCurrentThread ( char * pBuf, size_t bufSize )
|
int casClientInitiatingCurrentThread ( char * pBuf, size_t bufSize )
|
||||||
{
|
{
|
||||||
struct client * pClient = ( struct client * )
|
struct client * pClient;
|
||||||
epicsThreadPrivateGet ( rsrvCurrentClient );
|
if ( ! rsrvCurrentClient )
|
||||||
|
return RSRV_ERROR; /* not yet initialized, or disabled via dbServer */
|
||||||
|
|
||||||
|
pClient = ( struct client * ) epicsThreadPrivateGet ( rsrvCurrentClient );
|
||||||
if ( ! pClient )
|
if ( ! pClient )
|
||||||
return RSRV_ERROR;
|
return RSRV_ERROR;
|
||||||
|
|
||||||
|
@ -1536,6 +1536,13 @@ struct client *create_tcp_client (SOCKET sock , const osiSockAddr *peerAddr)
|
|||||||
|
|
||||||
void casStatsFetch ( unsigned *pChanCount, unsigned *pCircuitCount )
|
void casStatsFetch ( unsigned *pChanCount, unsigned *pCircuitCount )
|
||||||
{
|
{
|
||||||
|
if(!clientQlock) { /* not yet initialized, or disabled via dbServer */
|
||||||
|
if(pChanCount)
|
||||||
|
*pChanCount = 0;
|
||||||
|
if(pCircuitCount)
|
||||||
|
*pCircuitCount = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
LOCK_CLIENTQ;
|
LOCK_CLIENTQ;
|
||||||
{
|
{
|
||||||
int circuitCount = ellCount ( &clientQ );
|
int circuitCount = ellCount ( &clientQ );
|
||||||
|
@ -33,7 +33,7 @@ These fields control where the record will read data from when it is processed:
|
|||||||
The DTYP field selects which device support layer should be responsible for
|
The DTYP field selects which device support layer should be responsible for
|
||||||
providing input data to the record.
|
providing input data to the record.
|
||||||
The ai device support layers provided by EPICS Base are documented in the
|
The ai device support layers provided by EPICS Base are documented in the
|
||||||
L<Device Support|devSoft> section.
|
L<Device Support Interface> section.
|
||||||
External support modules may provide additional device support for this record
|
External support modules may provide additional device support for this record
|
||||||
type.
|
type.
|
||||||
If not set explicitly, the DTYP value defaults to the first device support that
|
If not set explicitly, the DTYP value defaults to the first device support that
|
||||||
|
@ -384,6 +384,7 @@ static long special(DBADDR *paddr, int after)
|
|||||||
|
|
||||||
if (special_type == SPC_RESET) {
|
if (special_type == SPC_RESET) {
|
||||||
reset(prec);
|
reset(prec);
|
||||||
|
monitor(prec);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
use strict;
|
use strict;
|
||||||
use Test;
|
use Test;
|
||||||
|
|
||||||
BEGIN {plan tests => 12}
|
BEGIN {plan tests => 14}
|
||||||
|
|
||||||
# Check include/substitute command model
|
# Check include/substitute command model
|
||||||
ok(msi('-I .. ../t1-template.txt'), slurp('../t1-result.txt'));
|
ok(msi('-I .. ../t1-template.txt'), slurp('../t1-result.txt'));
|
||||||
@ -56,6 +56,12 @@ my %envs = (TEST_NO => 12, PREFIX => 't');
|
|||||||
ok(msi('-I. -I.. -S ../t12-substitute.txt'), slurp('../t12-result.txt'));
|
ok(msi('-I. -I.. -S ../t12-substitute.txt'), slurp('../t12-result.txt'));
|
||||||
delete @ENV{ keys %envs }; # Not really needed
|
delete @ENV{ keys %envs }; # Not really needed
|
||||||
|
|
||||||
|
# Substitution file, relative path includes
|
||||||
|
ok(msi('-I @TOP@/modules -S ../t13-substitute.txt'), slurp('../t13-result.txt'));
|
||||||
|
|
||||||
|
# Template file, relative path includes
|
||||||
|
ok(msi('-I @TOP@/modules ../t14-template.txt'), slurp('../t14-result.txt'));
|
||||||
|
|
||||||
# Test support routines
|
# Test support routines
|
||||||
|
|
||||||
sub slurp {
|
sub slurp {
|
||||||
|
2
modules/database/test/ioc/dbtemplate/t13-result.txt
Normal file
2
modules/database/test/ioc/dbtemplate/t13-result.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# comment line
|
||||||
|
a=foo
|
3
modules/database/test/ioc/dbtemplate/t13-substitute.txt
Normal file
3
modules/database/test/ioc/dbtemplate/t13-substitute.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
file database/test/ioc/dbtemplate/t13-template.txt {
|
||||||
|
{ a=foo }
|
||||||
|
}
|
2
modules/database/test/ioc/dbtemplate/t13-template.txt
Normal file
2
modules/database/test/ioc/dbtemplate/t13-template.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# comment line
|
||||||
|
a=$(a)
|
1
modules/database/test/ioc/dbtemplate/t14-include.txt
Normal file
1
modules/database/test/ioc/dbtemplate/t14-include.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
I'm a file!
|
5
modules/database/test/ioc/dbtemplate/t14-result.txt
Normal file
5
modules/database/test/ioc/dbtemplate/t14-result.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
This is t14-template.txt
|
||||||
|
|
||||||
|
I'm a file!
|
||||||
|
|
||||||
|
End of t14-template.txt
|
5
modules/database/test/ioc/dbtemplate/t14-template.txt
Normal file
5
modules/database/test/ioc/dbtemplate/t14-template.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
This is t14-template.txt
|
||||||
|
|
||||||
|
include "database/test/ioc/dbtemplate/t14-include.txt"
|
||||||
|
|
||||||
|
End of t14-template.txt
|
@ -510,6 +510,7 @@ static void rtshellCallFunc(const iocshArgBuf *args)
|
|||||||
|
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
fprintf(stderr, "ERR: No such command\n");
|
fprintf(stderr, "ERR: No such command\n");
|
||||||
|
iocshSetError(-1);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@ -517,6 +518,7 @@ static void rtshellCallFunc(const iocshArgBuf *args)
|
|||||||
ret = (*cmd->command)(args[1].aval.ac,args[1].aval.av);
|
ret = (*cmd->command)(args[1].aval.ac,args[1].aval.av);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
iocshSetError(ret);
|
||||||
if(ret)
|
if(ret)
|
||||||
fprintf(stderr, "ERR: %d\n",ret);
|
fprintf(stderr, "ERR: %d\n",ret);
|
||||||
}
|
}
|
||||||
@ -611,18 +613,27 @@ static void nfsMountCallFunc(const iocshArgBuf *args)
|
|||||||
}
|
}
|
||||||
*cp = '/';
|
*cp = '/';
|
||||||
}
|
}
|
||||||
nfsMount(args[0].sval, args[1].sval, args[2].sval);
|
iocshSetError(nfsMount(args[0].sval, args[1].sval, args[2].sval));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void zoneset(const char *zone)
|
int zoneset(const char *zone)
|
||||||
{
|
{
|
||||||
if(zone)
|
int ret;
|
||||||
setenv("TZ", zone, 1);
|
if(zone) {
|
||||||
else
|
if ((ret = setenv("TZ", zone, 1)) < 0)
|
||||||
unsetenv("TZ");
|
return ret;
|
||||||
|
}
|
||||||
|
#if defined( __NEWLIB_MINOR__ ) /* Added in newlib 2.2.0 */
|
||||||
|
else if ((ret = unsetenv("TZ")) < 0)
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
else
|
||||||
|
unsetenv("TZ");
|
||||||
|
#endif
|
||||||
tzset();
|
tzset();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const iocshArg zonesetArg0 = {"zone string", iocshArgString};
|
static const iocshArg zonesetArg0 = {"zone string", iocshArgString};
|
||||||
@ -634,7 +645,7 @@ static const iocshFuncDef zonesetFuncDef = {"zoneset",1,zonesetArgs
|
|||||||
};
|
};
|
||||||
static void zonesetCallFunc(const iocshArgBuf *args)
|
static void zonesetCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
zoneset(args[0].sval);
|
iocshSetError(zoneset(args[0].sval));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef RTEMS_LEGACY_STACK
|
#ifndef RTEMS_LEGACY_STACK
|
||||||
@ -667,6 +678,7 @@ static void setlogmaskCallFunc(const iocshArgBuf *args)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("Error: unknown log level.\n");
|
printf("Error: unknown log level.\n");
|
||||||
|
iocshSetError(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static const iocshArg setlogmaskArg0 = {"level name", iocshArgString};
|
static const iocshArg setlogmaskArg0 = {"level name", iocshArgString};
|
||||||
|
@ -483,18 +483,27 @@ static void nfsMountCallFunc(const iocshArgBuf *args)
|
|||||||
}
|
}
|
||||||
*cp = '/';
|
*cp = '/';
|
||||||
}
|
}
|
||||||
nfsMount(args[0].sval, args[1].sval, args[2].sval);
|
iocshSetError(nfsMount(args[0].sval, args[1].sval, args[2].sval));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void zoneset(const char *zone)
|
int zoneset(const char *zone)
|
||||||
{
|
{
|
||||||
if(zone)
|
int ret;
|
||||||
setenv("TZ", zone, 1);
|
if(zone) {
|
||||||
else
|
if ((ret = setenv("TZ", zone, 1)) < 0)
|
||||||
unsetenv("TZ");
|
return ret;
|
||||||
|
}
|
||||||
|
#if defined( __NEWLIB_MINOR__ ) /* Added in newlib 2.2.0 */
|
||||||
|
else if ((ret = unsetenv("TZ")) < 0)
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
else
|
||||||
|
unsetenv("TZ");
|
||||||
|
#endif
|
||||||
tzset();
|
tzset();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const iocshArg zonesetArg0 = {"zone string", iocshArgString};
|
static const iocshArg zonesetArg0 = {"zone string", iocshArgString};
|
||||||
@ -502,7 +511,7 @@ static const iocshArg * const zonesetArgs[1] = {&zonesetArg0};
|
|||||||
static const iocshFuncDef zonesetFuncDef = {"zoneset",1,zonesetArgs};
|
static const iocshFuncDef zonesetFuncDef = {"zoneset",1,zonesetArgs};
|
||||||
static void zonesetCallFunc(const iocshArgBuf *args)
|
static void zonesetCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
zoneset(args[0].sval);
|
iocshSetError(zoneset(args[0].sval));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -311,13 +311,13 @@ inline bool tsSLIterConst<T>::valid () const
|
|||||||
template < class T >
|
template < class T >
|
||||||
inline bool tsSLIterConst<T>::operator == ( const tsSLIterConst<T> &rhs ) const
|
inline bool tsSLIterConst<T>::operator == ( const tsSLIterConst<T> &rhs ) const
|
||||||
{
|
{
|
||||||
return this->pEntry == rhs.pConstEntry;
|
return this->pEntry == rhs.pEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T >
|
template < class T >
|
||||||
inline bool tsSLIterConst<T>::operator != (const tsSLIterConst<T> &rhs) const
|
inline bool tsSLIterConst<T>::operator != (const tsSLIterConst<T> &rhs) const
|
||||||
{
|
{
|
||||||
return this->pEntry != rhs.pConstEntry;
|
return this->pEntry != rhs.pEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T >
|
template < class T >
|
||||||
|
1
modules/libcom/src/env/envDefs.h
vendored
1
modules/libcom/src/env/envDefs.h
vendored
@ -77,6 +77,7 @@ LIBCOM_API extern const ENV_PARAM IOCSH_PS1;
|
|||||||
LIBCOM_API extern const ENV_PARAM IOCSH_HISTSIZE;
|
LIBCOM_API extern const ENV_PARAM IOCSH_HISTSIZE;
|
||||||
LIBCOM_API extern const ENV_PARAM IOCSH_HISTEDIT_DISABLE;
|
LIBCOM_API extern const ENV_PARAM IOCSH_HISTEDIT_DISABLE;
|
||||||
LIBCOM_API extern const ENV_PARAM EPICS_MUTEX_USE_PRIORITY_INHERITANCE;
|
LIBCOM_API extern const ENV_PARAM EPICS_MUTEX_USE_PRIORITY_INHERITANCE;
|
||||||
|
LIBCOM_API extern const ENV_PARAM EPICS_ABORT_ON_ASSERT;
|
||||||
LIBCOM_API extern const ENV_PARAM *env_param_list[];
|
LIBCOM_API extern const ENV_PARAM *env_param_list[];
|
||||||
|
|
||||||
struct in_addr;
|
struct in_addr;
|
||||||
|
@ -1329,7 +1329,7 @@ iocshCmd (const char *cmd)
|
|||||||
int epicsStdCall
|
int epicsStdCall
|
||||||
iocshLoad(const char *pathname, const char *macros)
|
iocshLoad(const char *pathname, const char *macros)
|
||||||
{
|
{
|
||||||
if (pathname)
|
if (pathname && !getenv("IOCSH_STARTUP_SCRIPT"))
|
||||||
epicsEnvSet("IOCSH_STARTUP_SCRIPT", pathname);
|
epicsEnvSet("IOCSH_STARTUP_SCRIPT", pathname);
|
||||||
return iocshBody(pathname, NULL, macros);
|
return iocshBody(pathname, NULL, macros);
|
||||||
}
|
}
|
||||||
|
@ -139,10 +139,12 @@ static void epicsEnvSetCallFunc(const iocshArgBuf *args)
|
|||||||
|
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
fprintf(stderr, "Missing environment variable name argument.\n");
|
fprintf(stderr, "Missing environment variable name argument.\n");
|
||||||
|
iocshSetError(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
fprintf(stderr, "Missing environment variable value argument.\n");
|
fprintf(stderr, "Missing environment variable value argument.\n");
|
||||||
|
iocshSetError(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
epicsEnvSet (name, value);
|
epicsEnvSet (name, value);
|
||||||
@ -159,6 +161,7 @@ static void epicsEnvUnsetCallFunc(const iocshArgBuf *args)
|
|||||||
|
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
fprintf(stderr, "Missing environment variable name argument.\n");
|
fprintf(stderr, "Missing environment variable name argument.\n");
|
||||||
|
iocshSetError(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
epicsEnvUnset (name);
|
epicsEnvUnset (name);
|
||||||
@ -215,7 +218,7 @@ static const iocshFuncDef iocLogInitFuncDef = {"iocLogInit",0,0,
|
|||||||
" see 'setIocLogDisable' command\n"};
|
" see 'setIocLogDisable' command\n"};
|
||||||
static void iocLogInitCallFunc(const iocshArgBuf *args)
|
static void iocLogInitCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
iocLogInit ();
|
iocshSetError(iocLogInit ());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* iocLogDisable */
|
/* iocLogDisable */
|
||||||
@ -354,6 +357,7 @@ static void threadCallFunc(const iocshArgBuf *args)
|
|||||||
tid = epicsThreadGetId (cp);
|
tid = epicsThreadGetId (cp);
|
||||||
if (!tid) {
|
if (!tid) {
|
||||||
fprintf(stderr, "\t'%s' is not a known thread name\n", cp);
|
fprintf(stderr, "\t'%s' is not a known thread name\n", cp);
|
||||||
|
iocshSetError(-1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -429,6 +433,7 @@ static void epicsThreadResumeCallFunc(const iocshArgBuf *args)
|
|||||||
tid = epicsThreadGetId(cp);
|
tid = epicsThreadGetId(cp);
|
||||||
if (!tid) {
|
if (!tid) {
|
||||||
fprintf(stderr, "'%s' is not a valid thread name\n", cp);
|
fprintf(stderr, "'%s' is not a valid thread name\n", cp);
|
||||||
|
iocshSetError(-1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -437,12 +442,14 @@ static void epicsThreadResumeCallFunc(const iocshArgBuf *args)
|
|||||||
epicsThreadGetName(tid, nameBuf, sizeof nameBuf);
|
epicsThreadGetName(tid, nameBuf, sizeof nameBuf);
|
||||||
if (nameBuf[0] == '\0') {
|
if (nameBuf[0] == '\0') {
|
||||||
fprintf(stderr, "'%s' is not a valid thread id\n", cp);
|
fprintf(stderr, "'%s' is not a valid thread id\n", cp);
|
||||||
|
iocshSetError(-1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!epicsThreadIsSuspended(tid)) {
|
if (!epicsThreadIsSuspended(tid)) {
|
||||||
fprintf(stderr, "Thread %s is not suspended\n", cp);
|
fprintf(stderr, "Thread %s is not suspended\n", cp);
|
||||||
|
iocshSetError(-1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
epicsThreadResume(tid);
|
epicsThreadResume(tid);
|
||||||
@ -458,7 +465,7 @@ static const iocshFuncDef generalTimeReportFuncDef = {"generalTimeReport",1,gene
|
|||||||
" 1 - Additionally show current time obtained from each provider.\n"};
|
" 1 - Additionally show current time obtained from each provider.\n"};
|
||||||
static void generalTimeReportCallFunc(const iocshArgBuf *args)
|
static void generalTimeReportCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
generalTimeReport(args[0].ival);
|
iocshSetError(generalTimeReport(args[0].ival));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* installLastResortEventProvider */
|
/* installLastResortEventProvider */
|
||||||
@ -467,7 +474,7 @@ static const iocshFuncDef installLastResortEventProviderFuncDef = {"installLastR
|
|||||||
"which returns the current time for every event number\n"};
|
"which returns the current time for every event number\n"};
|
||||||
static void installLastResortEventProviderCallFunc(const iocshArgBuf *args)
|
static void installLastResortEventProviderCallFunc(const iocshArgBuf *args)
|
||||||
{
|
{
|
||||||
installLastResortEventProvider();
|
iocshSetError(installLastResortEventProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
static iocshVarDef comDefs[] = {
|
static iocshVarDef comDefs[] = {
|
||||||
|
@ -24,7 +24,7 @@ LIBCOM_API void * callocMustSucceed(size_t count, size_t size, const char *msg)
|
|||||||
void * mem = NULL;
|
void * mem = NULL;
|
||||||
if (count > 0 && size > 0) {
|
if (count > 0 && size > 0) {
|
||||||
while ((mem = calloc(count, size)) == NULL) {
|
while ((mem = calloc(count, size)) == NULL) {
|
||||||
errlogPrintf("%s: callocMustSucceed(%lu, %lu) - calloc failed\n",
|
errlogPrintf("%s: callocMustSucceed(%lu, %lu) - " ERL_ERROR " calloc failed\n",
|
||||||
msg, (unsigned long)count, (unsigned long)size);
|
msg, (unsigned long)count, (unsigned long)size);
|
||||||
errlogPrintf("Thread %s (%p) suspending.\n",
|
errlogPrintf("Thread %s (%p) suspending.\n",
|
||||||
epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf());
|
epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf());
|
||||||
@ -40,7 +40,7 @@ LIBCOM_API void * mallocMustSucceed(size_t size, const char *msg)
|
|||||||
void * mem = NULL;
|
void * mem = NULL;
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
while ((mem = malloc(size)) == NULL) {
|
while ((mem = malloc(size)) == NULL) {
|
||||||
errlogPrintf("%s: mallocMustSucceed(%lu) - malloc failed\n",
|
errlogPrintf("%s: mallocMustSucceed(%lu) - " ERL_ERROR " malloc failed\n",
|
||||||
msg, (unsigned long)size);
|
msg, (unsigned long)size);
|
||||||
errlogPrintf("Thread %s (%p) suspending.\n",
|
errlogPrintf("Thread %s (%p) suspending.\n",
|
||||||
epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf());
|
epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf());
|
||||||
@ -59,7 +59,7 @@ LIBCOM_API void cantProceed(const char *msg, ...)
|
|||||||
errlogVprintf(msg, pvar);
|
errlogVprintf(msg, pvar);
|
||||||
va_end(pvar);
|
va_end(pvar);
|
||||||
|
|
||||||
errlogPrintf("Thread %s (%p) can't proceed, suspending.\n",
|
errlogPrintf(ANSI_RED("CRITICAL ERROR") " Thread %s (%p) can't proceed, suspending.\n",
|
||||||
epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf());
|
epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf());
|
||||||
|
|
||||||
epicsStackTrace();
|
epicsStackTrace();
|
||||||
|
@ -56,18 +56,24 @@ LIBCOM_API void cantProceed(
|
|||||||
* gracefully when memory runs out.
|
* gracefully when memory runs out.
|
||||||
*/
|
*/
|
||||||
/** @{ */
|
/** @{ */
|
||||||
/** \brief A calloc() that never returns NULL.
|
/** \brief A calloc() which suspends on error.
|
||||||
* \param count Number of objects.
|
* \param count Number of objects.
|
||||||
* \param size Size of each object.
|
* \param size Size of each object.
|
||||||
* \param errorMessage What this memory is needed for.
|
* \param errorMessage Context added to logged error message
|
||||||
* \return Pointer to zeroed allocated memory.
|
* \return Pointer to zeroed allocated memory. Should later be free() d
|
||||||
|
*
|
||||||
|
* Will always return NULL for a zero length allocation.
|
||||||
|
* Will never return NULL otherwise.
|
||||||
*/
|
*/
|
||||||
LIBCOM_API void * callocMustSucceed(size_t count, size_t size,
|
LIBCOM_API void * callocMustSucceed(size_t count, size_t size,
|
||||||
const char *errorMessage);
|
const char *errorMessage);
|
||||||
/** \brief A malloc() that never returns NULL.
|
/** \brief A malloc() which suspends on error.
|
||||||
* \param size Size of block to allocate.
|
* \param size Size of block to allocate.
|
||||||
* \param errorMessage What this memory is needed for.
|
* \param errorMessage Context added to logged error message
|
||||||
* \return Pointer to allocated memory.
|
* \return Pointer to allocated memory. Should later be free() d
|
||||||
|
*
|
||||||
|
* Will always return NULL for a zero length allocation.
|
||||||
|
* Will never return NULL otherwise.
|
||||||
*/
|
*/
|
||||||
LIBCOM_API void * mallocMustSucceed(size_t size, const char *errorMessage);
|
LIBCOM_API void * mallocMustSucceed(size_t size, const char *errorMessage);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -48,7 +48,6 @@ epicsEventCreate(epicsEventInitialState initialState)
|
|||||||
{
|
{
|
||||||
rtems_status_code sc;
|
rtems_status_code sc;
|
||||||
rtems_id sid;
|
rtems_id sid;
|
||||||
rtems_interrupt_level level;
|
|
||||||
static uint32_t name;
|
static uint32_t name;
|
||||||
|
|
||||||
sc = rtems_semaphore_create (next_rtems_name ('B', &name),
|
sc = rtems_semaphore_create (next_rtems_name ('B', &name),
|
||||||
|
@ -20,12 +20,14 @@
|
|||||||
#include "epicsTime.h"
|
#include "epicsTime.h"
|
||||||
#include "cantProceed.h"
|
#include "cantProceed.h"
|
||||||
#include "epicsStackTrace.h"
|
#include "epicsStackTrace.h"
|
||||||
|
#include "envDefs.h"
|
||||||
|
|
||||||
|
|
||||||
void epicsAssert (const char *pFile, const unsigned line,
|
void epicsAssert (const char *pFile, const unsigned line,
|
||||||
const char *pExp, const char *pAuthorName)
|
const char *pExp, const char *pAuthorName)
|
||||||
{
|
{
|
||||||
epicsTimeStamp current;
|
epicsTimeStamp current;
|
||||||
|
int shouldAbort = 0;
|
||||||
|
|
||||||
errlogPrintf("\n\n\n"
|
errlogPrintf("\n\n\n"
|
||||||
"A call to 'assert(%s)'\n"
|
"A call to 'assert(%s)'\n"
|
||||||
@ -50,6 +52,13 @@ void epicsAssert (const char *pFile, const unsigned line,
|
|||||||
errlogPrintf("Please E-mail this message to %s or to tech-talk@aps.anl.gov\n",
|
errlogPrintf("Please E-mail this message to %s or to tech-talk@aps.anl.gov\n",
|
||||||
pAuthorName);
|
pAuthorName);
|
||||||
|
|
||||||
errlogPrintf("Calling epicsThreadSuspendSelf()\n");
|
if (envGetBoolConfigParam(&EPICS_ABORT_ON_ASSERT, &shouldAbort) == 0 && shouldAbort) {
|
||||||
epicsThreadSuspendSelf ();
|
errlogPrintf("Calling abort()\n");
|
||||||
|
errlogFlush();
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errlogPrintf("Calling epicsThreadSuspendSelf()\n");
|
||||||
|
epicsThreadSuspendSelf ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Submodule modules/pvAccess updated: f1268adb8e...dafb6aad31
Submodule modules/pvData updated: 7c10c29c33...2be3bc40e0
Submodule modules/pvDatabase updated: f207e512d6...073d2acafc
Submodule modules/pva2pva updated: 949b3f63c2...8fa231352d
Submodule modules/pvaClient updated: 8ed07fef96...09cf317521
Reference in New Issue
Block a user