Compare commits

...

202 Commits

Author SHA1 Message Date
Andrew Johnson
7f142e03f5 Version number updates for 7.0.5 release
Some checks failed
Base / Ub-20 clang-10 C++11 (push) Has been cancelled
Base / MacOS clang-12 (push) Has been cancelled
Base / Ub-16 clang-9 (push) Has been cancelled
Base / Ub-20 clang-10 (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.10 (push) Has been cancelled
Base / Ub-20 gcc-9 + RT-4.9 (push) Has been cancelled
Base / Ub-20 gcc-9 C++11, static (push) Has been cancelled
Base / Ub-20 gcc-9 + MinGW, static (push) Has been cancelled
Base / Ub-16 gcc-4.8 (push) Has been cancelled
Base / Ub-16 gcc-4.9 (push) Has been cancelled
Base / Ub-20 gcc-8 (push) Has been cancelled
Base / Win2019 MSC-19 (push) Has been cancelled
Base / Win2019 MSC-19, static (push) Has been cancelled
2021-02-28 20:06:40 -06:00
Andrew Johnson
bb7b754730 Documentation updates for release
Mostly version numbers, a few text and formatting changes.
2021-02-28 20:04:16 -06:00
Andrew Johnson
a9ff175cf0 Replace "UNRELEASED" in epicsString.h 2021-02-28 17:37:40 -06:00
Andrew Johnson
458c0af4e9 Checkout submodules at tagged versions for 7.0.5 2021-02-28 17:36:25 -06:00
Andrew Johnson
eacee1b548 Merge Krisztian Loki's issue_97 branch into 7.0 2021-02-28 15:40:11 -06:00
Andrew Johnson
6754404d0f Replace magic "2" with macro AAI_DEVINIT_PASS1 2021-02-28 15:02:27 -06:00
Andrew Johnson
6734918e6e Release notes and aai documentation updates 2021-02-27 22:19:48 -06:00
Andrew Johnson
1c566e2110 Modify aai to support pass-1 device initialization
The Soft Channel device support requests pass-1 initialization.
It no longer needs to initialize the INP link or allocate the
array buffer itself, these are taken care of elsewhere.

The record code uses PACT to remember that the device must be
initialized again in pass 1.
2021-02-27 22:08:50 -06:00
Andrew Johnson
7f878d3074 Merge fix-1908305 branch into 7.0 2021-02-27 17:20:30 -06:00
Andrew Johnson
12ab69402a Improve the message from a DBD field-count mismatch 2021-02-27 17:15:47 -06:00
Andrew Johnson
0926f7db0f Release Notes updates
Added notes for the Windows Monotonic fix, and Apple arm64 support.
Expanded and edited some other notes.
2021-02-27 17:15:35 -06:00
Andrew Johnson
08eaea64d2 Fix up comments & messages, add Release Notes 2021-02-27 16:48:55 -06:00
Andrew Johnson
bee00658ae Limit auto-declaration of record types to regRecDevDrv only
Allowing this while expanding DBD files for IOCs can insert other
device supports before of the Base "Soft Channel" ones, making the
other type the default. Adds a note that DBD file order matters.

Fixes lp: #1908305
2021-02-27 16:48:55 -06:00
Michael Davidsaver
e881cb15c4 registerAllRecordDeviceDrivers() handle function 2021-02-26 07:42:17 -08:00
Krisztián Löki
4a0f488657 Fixed db_post_events to not use bptr 2021-02-25 16:13:48 +01:00
Krisztián Löki
2340c6e6c1 Allow changing the BPTR field
This fixes github issue #97:
Reading into an aai record from a compress or histogram or subArray record
could cause a segfault if the aai record was initialized before the
linked one.
2021-02-25 14:54:07 +01:00
Michael Davidsaver
5593103c11 posix: epicsMutexShowAll() print if PI mutex are used
Confirms that pthread_mutex_t are actually being created
with PTHREAD_PRIO_INHERIT, ie. if both libc and kernel
support is present.
2021-02-21 20:01:45 -08:00
5a8b6e4111 posix: PI for epicsMutex, epicsEvent etc.
Enable priority-inheritance for primitives based on pthread_mutex_t.

Based on work by Till Straumann <till.straumann@psi.ch>
2021-02-21 20:01:45 -08:00
Michael Davidsaver
c4348dc6e0 ci: fix gcc 4.8 builds 2021-02-21 11:16:20 -08:00
Andrew Johnson
9d0597fc15 Fix MS compiler issue that I introduced into Freddie's code
Plus a little more code simplification.
2021-02-21 12:04:07 -06:00
Andrew Johnson
93208af61c Merged Freddie Akeroyd's fix_win32_monotonic_time branch 2021-02-20 17:36:21 -06:00
Andrew Johnson
9c23247c04 Windows: Move cxx warning flag to the right CONFIG file 2021-02-20 17:02:09 -06:00
Michael Davidsaver
552b2d1766 dbConstAddLink bounds check dbrType
cf. 6c914d19c3
2021-02-19 15:53:32 -08:00
Andrew Johnson
1755a46bfe Merge Han's darwin-aarch64 branch into 7.0 2021-02-19 17:36:45 -06:00
Andrew Johnson
36d0fbd7be Another c89 compat fix 2021-02-08 13:34:01 -06:00
Michael Davidsaver
30e1431fb4 c89 compat 2021-02-08 09:43:51 -08:00
Michael Davidsaver
3f209efa3c release notes 2021-02-08 09:23:27 -08:00
Michael Davidsaver
2c1c35268e db: Suggest DBF_MENU values on parser error 2021-02-08 09:22:27 -08:00
Michael Davidsaver
745c3f552e Com: add epicsStrSimilarity() 2021-02-08 09:22:27 -08:00
Michael Davidsaver
27918cb7a1 improve error message from dbPutString() for DBF_MENU/DEVICE 2021-02-08 09:22:27 -08:00
Michael Davidsaver
8723d4d9cb include database S_* in error string table 2021-02-08 09:22:27 -08:00
Michael Ritzert
410921b5ef Use getifaddrs instead of SIOCGIFCONF.
The old code is preserved in osdNetIfConf.c, which is used by the default
platform directory.

Platforms that support getifaddrs use the new code from osdNetIfAddrs.c.
2021-02-06 08:27:21 -08:00
Jeong Han Lee
d3e96c4c2b fixed a typo in CONFIG.Common.darwin-aarch64 2021-02-05 17:02:54 -08:00
Michael Davidsaver
43bd5ee1c2 Com: always skip SOCK_CLOEXEC for RTEMS and vxWorks 2021-02-05 10:32:47 -08:00
Jeong Han Lee
34a0b387b0 add dawrin-aarch64 (arm64) Host Arch 2021-02-02 17:26:12 -08:00
Andrew Johnson
78d685688c Add VALID_BUILDS support for "Command" 2021-02-02 16:06:42 -06:00
Michael Davidsaver
cf3173b6f4 posix: use SOCK_CLOEXEC and accept4()
If available, ensure O_CLOEXEC is set atomically.
Continue to F_SETFD as well (paranoia).

Available at least on Linux, freebsd, and RTEMS 5 w/ libbsd
2021-01-29 08:45:44 -08:00
Michael Davidsaver
c95cbe4a0f ci: re-add .appveyor.yml
Re-introduce default config file for use with repositories
other than the main ones.
2021-01-27 09:19:58 -08:00
Michael Davidsaver
1e471832e9 consolidate osiFileName.h
Don't really need 10 files for this
2021-01-27 09:19:13 -08:00
Ralph Lange
40d9a21c0c Merge 3.15 into 7.0 - build system fixes
- improve silencing the build
- assemblies fix for Windows
2021-01-26 17:44:24 +01:00
Ralph Lange
dd9f38d711 Build: Fix spurious failures with SNIPPETS in Windows
Under some combinations of shell / Make version / Windows version,
Windows make was giving up searching for a target "../"
2021-01-26 17:14:00 +01:00
Andrew Johnson
7050bded31 Update MSVC paths in Windows startup files 2021-01-22 12:32:33 -06:00
Michael Davidsaver
c19605232a epicsAtomicDefault.h typo 2021-01-18 08:23:54 -08:00
Andrew Johnson
4e81eaa7e8 Update pvAccess module (caProvider) 2021-01-05 21:42:59 -06:00
Andrew Johnson
99852c6504 Merge JSON5 support into 7.0 2021-01-05 21:39:15 -06:00
Michael Ritzert
a9e3fa74aa FTBFS on FreeBSD 12 2021-01-05 08:56:57 -08:00
Andrew Johnson
d997690aa5 Build: Fix tests for the 'make -s' flag
'make -j2' or more adds an 's' to MFLAGS in "--jobserver-fds".
This is the correct way to do the check.
2020-12-30 13:08:48 -06:00
Andrew Johnson
326ef00bc9 Merge 3.15 into 7.0 - GHA tapfiles Artifact 2020-12-29 15:42:44 -06:00
Andrew Johnson
a043599e18 GHA: Save .tap files as an artifact 2020-12-28 18:04:06 -06:00
Andrew Johnson
02be10069e Make the CI commit-ignore patterns match 2020-12-28 17:13:45 -06:00
Andrew Johnson
4f14e9e674 Merge up Appveyor changes from 3.15 into 7.0 2020-12-28 16:22:15 -06:00
Andrew Johnson
ff4317d05a Make .appveyor.yml into a branch-specific filename
The name should match the Appveyor account that builds the branch;
From a suggestion by Michael.
2020-12-28 15:59:12 -06:00
Andrew Johnson
63919e199c Fix menuPriority filename in RecordReference index 2020-12-28 13:40:35 -06:00
Andrew Johnson
f775e0b8f6 Merge 3.15 branch into 7.0
Adjust updated test result displays for submodules
2020-12-23 16:18:21 -06:00
Andrew Johnson
518bab9675 Clean up .appveyor.yml
Whitelist the tagged versions too
Exclude MinGW debug builds since (unlike the VS builds) they use
the same system libraries as the non-debug builds.
We aren't building vs2008 any more anyway.
2020-12-23 11:56:32 -06:00
Andrew Johnson
a8036d7f34 posix/osdThread: Use "Once" versions properly
Functions used before epicsThreadInit() returns must call the
checkStatusOnceQuit() version to avoid recursion from errlogInit()
2020-12-23 11:53:05 -06:00
Andrew Johnson
436ce4526b Appveyor: Update CMP from mingw => gcc 2020-12-21 15:49:52 -06:00
Michael Davidsaver
b49f06916e gcc -Werror-implicit-function-declaration
Treat implicit declarations as an error in GCC builds.
2020-12-21 07:38:24 -08:00
Andrew Johnson
9ba0081a82 Change the Appveyor steps to call the new cue.py script 2020-12-18 15:35:18 -06:00
Andrew Johnson
c60056d4d6 Reconfigure and tidy up the testFailure stuff
Many variables renamed.
Generated files are now named .log for .gitignore
Actions are now defined in CONFIG_BASE variables.
2020-12-18 15:32:46 -06:00
Andrew Johnson
68c056f2f8 Fix makeTestfile.pl to report test failures properly
If a test program reports test failures, the Perl wrapper
must return the same error status. On Windows where we use
system() instead of exec() that needs some value fiddling.
2020-12-18 10:20:31 -06:00
Andrew Johnson
48a6d2f781 GH-Actions: Undo my workflow name change
Changing it also modified the names of all previous builds.
2020-12-17 20:59:56 -06:00
Andrew Johnson
79bb9e000b GH-Actions: Tweaks 2020-12-17 20:39:08 -06:00
Andrew Johnson
c404eb3f83 GH-Actions: Add short names for each job 2020-12-17 20:38:06 -06:00
Andrew Johnson
7beb32e209 Extend testFailures.pl to list the failed test programs
Creates a file .taps-failed in each O.<arch> directory,
appending the name of each tapfile that has failures to it.
The testFailures script now reads the .taps-failed files
from each directory listed in .tests-failed and nicely
displays the failing tests listed in each.
2020-12-17 18:34:24 -06:00
Andrew Johnson
a365de2419 Fix return value of epicsUnitTest::testDone()
Wasn't properly returning a non-zero exit status
when HARNESS_ACTIVE was set.
2020-12-17 18:21:07 -06:00
Andrew Johnson
035ffdf045 Additions to .gitignore 2020-12-08 10:11:55 -06:00
Andrew Johnson
5f0d52cd5c errSymLib Fix from Ivo Hanak
Fixes lp: #1907077
2020-12-08 10:10:03 -06:00
Ralph Lange
2035fc641a PCAS: fix scope of tsDLList when used in other classes
Use ::tsDLList to avoid resolving to privately inherited
name (which was breaking builds on newer clang compilers)
2020-12-07 10:07:23 +01:00
Ralph Lange
d25c9a74ad ci: travis-ci -> github actions 2020-12-06 15:12:28 +01:00
Michael Davidsaver
e20151439b ci: use ci-core-dumper 2020-12-03 08:33:57 -08:00
Michael Davidsaver
4e055610b7 epicsUnitTest: SetErrorMode() 2020-12-03 08:33:57 -08:00
Andrew Johnson
db027d4a7f makeTestfile SetErrorMode() 2020-12-02 11:43:39 -08:00
Michael Davidsaver
17ee7dd6c7 update PVA modules 2020-12-02 10:44:21 -08:00
Michael Davidsaver
dc99d63df8 C89 compat
Present for Dirk
2020-11-20 17:25:27 -08:00
Michael Davidsaver
53897d4a82 ci: need apt-get update 2020-11-20 17:23:43 -08:00
Michael Davidsaver
d24a297304 osiSockTest: fix timeout 2020-11-19 13:07:05 -08:00
Michael Davidsaver
761edcae15 travis-ci -> github actions 2020-11-18 11:11:37 -08:00
Michael Davidsaver
b890d584bc softIoc: avoid extra iocInit() 2020-11-18 11:11:37 -08:00
Michael Davidsaver
db2f7d8b92 use auto_ptr or unique_ptr 2020-11-18 10:54:44 -08:00
Michael Davidsaver
d83e3b5de1 osiSockTest: probe for !EPERM 2020-11-18 10:54:44 -08:00
Michael Davidsaver
cbac1c54f5 test/ioc/db: xRecord handle alarms 2020-11-18 10:54:44 -08:00
Michael Davidsaver
2cfbf5c1c9 fix release notes 2020-11-18 10:54:10 -08:00
Michael Davidsaver
d108a1ff11 Merge remote-tracking branch 'lp-zimoch/dbChannelForDBLinks' into 7.0
* lp-zimoch/dbChannelForDBLinks: (43 commits)
  add tests for empty array filter results
  Fix linkFilterTest, move Release Notes to the right place
  do not handle empty arrays (undefined behavior)
  Revert "new error code for empty arrays"
  test code beautification
  make db_init_event_freelists private
  remove unnecessary check
  remove needless pointer access
  new error code for empty arrays
  clean up code structure
  Release notes updated
  set number of planned link filter tests
  removed unnecessary recGblSetSevr call
  re-order link filter tests to alternate between success and failure
  unused variable removed
  Revert "fix crash in PINI: use local db_field_log"
  initialize free lists when starting dbChannel
  db link filter tests added
  bugfix: dbGet should not crash because of empty array requests
  fix crash in PINI: use local db_field_log
  ...

# Conflicts:
#	documentation/RELEASE_NOTES.md
2020-11-18 10:53:50 -08:00
Michael Davidsaver
0a65707383 Merge remote-tracking branch 'githubbhill/timestamp-before-outlink' into 7.0
* githubbhill/timestamp-before-outlink:
  Update RELEASE_NOTES for timestamp-before-outlink
  Patch record processing routines to update timestamp before processing outlinks
2020-11-18 10:48:57 -08:00
9048e998fb add tests for empty array filter results 2020-11-17 15:22:40 +01:00
Andrew Johnson
7632c355ee dbpr: Catch buffer overflow from long link strings.
Fixes lp: #1776141

Currently this just truncates when we hit the end of the buffer,
a better solution is warranted.
2020-11-16 14:25:51 -05:00
Andrew Johnson
4730e14cc7 Document the PINI, POST and PRIO menus 2020-11-13 18:17:47 -06:00
Ralph Lange
c969f05f51 AppVeyor: explicitly set default runner image (VS2015) 2020-11-03 12:04:57 +01:00
Ralph Lange
8fd36d8eef AppVeyor: whitelist 7.0 branch
The AppVeyor epics-base-7 project is supposed to pull the .appveyor.yml from this branch to only build commits and pull requests from/for 7.0.
2020-11-03 10:02:34 +01:00
Ralph Lange
3947b9a061 Appveyor: whitelist 3.15 branch
- DO NOT UPMERGE TO 7.0

The AppVeyor epics-base-3 project is supposed to pull the .appveyor.yml from this branch to only build commits from 3.15.
2020-11-03 09:41:45 +01:00
Andrew Johnson
cf56a0e08e Fix linkFilterTest, move Release Notes to the right place 2020-10-30 17:43:03 -05:00
6b5abf76c8 do not handle empty arrays (undefined behavior) 2020-10-30 17:07:09 -05:00
3b3261c877 Revert "new error code for empty arrays"
This reverts commit d51b5513fda5ca7c6058990396d315cfff81cbfe.

Conflicts:
	modules/database/src/ioc/db/dbAccess.c
	modules/database/src/ioc/db/dbDbLink.c
2020-10-30 17:07:09 -05:00
30d8febb0b test code beautification 2020-10-30 17:07:09 -05:00
4ad98d5b4f make db_init_event_freelists private 2020-10-30 17:07:09 -05:00
14b9ac3277 remove unnecessary check 2020-10-30 17:07:09 -05:00
275c4c7cf4 remove needless pointer access 2020-10-30 17:07:09 -05:00
5d808b7c02 new error code for empty arrays 2020-10-30 17:07:09 -05:00
afdf34b791 clean up code structure 2020-10-30 17:07:09 -05:00
ea05bab26a Release notes updated 2020-10-30 17:07:09 -05:00
edb8f1a5df set number of planned link filter tests 2020-10-30 17:07:09 -05:00
8f5be5f0ad removed unnecessary recGblSetSevr call 2020-10-30 17:07:09 -05:00
bc34526bcb re-order link filter tests to alternate between success and failure 2020-10-30 17:07:09 -05:00
0ee36388cb unused variable removed 2020-10-30 17:07:09 -05:00
c51c83b1d5 Revert "fix crash in PINI: use local db_field_log"
This reverts commit a590151accb1d187562c515a48e013244dd98a45.

Conflicts:
	modules/database/src/ioc/db/dbDbLink.c
2020-10-30 17:07:09 -05:00
d0ef45acc3 initialize free lists when starting dbChannel 2020-10-30 17:07:09 -05:00
7ab56a68d1 db link filter tests added 2020-10-30 17:07:09 -05:00
39c8d5619a bugfix: dbGet should not crash because of empty array requests 2020-10-30 17:07:09 -05:00
e0dfb6cff8 fix crash in PINI: use local db_field_log 2020-10-30 17:07:09 -05:00
3627c38a57 don't crash when filter results in 0 elements 2020-10-30 17:07:09 -05:00
17a8dbc2d7 apply filters in dbDbGetValue 2020-10-30 17:07:09 -05:00
b1f445925d use dbChannel in link instead of DBADDR 2020-10-30 17:07:09 -05:00
Andrew Johnson
297f04bddc Make dbgf display something for an empty array
Also significantly expands on Dirk's Release Notes entries.
2020-10-30 13:37:50 -05:00
Andrew Johnson
a7bf59079f Merge Dirk Zimoch's fix_zero_size_arrays branch 2020-10-29 17:07:35 -05:00
Andrew Johnson
baced535e3 Add -v (verbose) flag to softIoc
Only display the startup steps taken if -v was given.
Show each step *before* running it, so error messages follow it.
2020-10-28 23:55:24 -05:00
Andrew Johnson
be7c6a0a0a Build: Do clean before uninstall actions (if requested) 2020-10-28 23:26:25 -05:00
Andrew Johnson
14476391c0 Warn about NULL dbevEventUserFreeList 2020-10-28 23:25:02 -05:00
Andrew Johnson
223b292c33 Merge fix-wrong-order-phas fixes from 3.15 branch 2020-10-22 10:31:52 -05:00
Andrew Johnson
68121ec907 Merged Dirk's fix_one_element_input_link_arrays branch 2020-10-22 10:14:10 -05:00
Martin Konrad
228ad79b7a Simplify addToList() function 2020-10-13 18:38:17 -04:00
Martin Konrad
bbc0a56d2b Fix wrong PHAS order
Records with lower PHAS value than any previously loaded records
were inserted at the end of the list rather than at the beginning.
This fixes lp: #1899697. Also fixes a proto-bug in that the second
argument to the previously used ellAdd() call assumed that
offsetof(scan_element, node)==0.

Thanks to Bruno Martins for providing this patch.
2020-10-13 18:34:39 -04:00
Andrew Johnson
9726b9efc9 aSubRecord: Fix OVLA..OVLU POD field list 2020-10-12 15:34:43 -05:00
Bruce Hill
f44f4ac7ad Update RELEASE_NOTES for timestamp-before-outlink 2020-10-07 06:47:44 -07:00
Bruce Hill
f1e83b22f2 Patch record processing routines to update timestamp before processing outlinks 2020-10-07 06:47:44 -07:00
Freddie Akeroyd
cdc627a15c Use native Windows type for perfCounterOffset 2020-10-04 01:20:44 +01:00
Freddie Akeroyd
8a90688880 Make returned value relative to IOC boot time to improve accuracy 2020-10-04 00:20:11 +01:00
Freddie Akeroyd
bbdd9392fe Call cantProceed() if performance counter is unavailable 2020-09-27 00:42:20 +01:00
Freddie Akeroyd
fe35e6e703 Remove use of GetTickCount() - only use performance counter 2020-09-25 20:59:20 +01:00
Gabriel Fedel
3e891a12ff Fix asub documentation: alarm happens when retunr status is < 0 2020-09-23 09:36:36 +02:00
Freddie Akeroyd
f8a6735691 Print warning if using GetTickCount() 2020-09-19 00:53:05 +01:00
Freddie Akeroyd
dc579b78db * Fix and enable usage of QueryPerformanceCounter()
* Use GetTickCount64() as fallback on Windows Vista and above
2020-09-19 00:07:06 +01:00
Andrew Johnson
22ee229aca Add support for linux-aarch64 native builds 2020-09-16 00:45:19 -05:00
Andrew Johnson
1ae3bd6c70 Add warnings to CONFIG_SITE files that can't override gnuCommon
Move the clang and '-g' suggestions to the right places
2020-09-08 16:57:48 -05:00
Ralph Lange
cbba08b1ef Merge pull request #88 from HiteshDhola/patch-1
Update README.md
2020-08-26 10:17:42 +02:00
Hitesh Dhola
53044571fb Update README.md
Pointing out few err in the release version. As this is the first document anyone would Read. 

-Corrected released version. Removed old references.
PS : I also use this file to restore my "base" folder with older original version when new EPICS version is released. This way I can keep all of my compiled version isolated.
2020-08-26 12:47:19 +05:30
Ralph Lange
f8df3473ab Redo d3d40689 that was lost in upmerging 2020-08-25 16:06:39 +02:00
Ralph Lange
e8bee54531 Redo 97b29129/0fbfc741 that was lost in upmerging 2020-08-25 16:04:04 +02:00
Michael Davidsaver
0cae0db98b compat IPPORT_USERRESERVED
musl libc doesn't define IPPORT_USERRESERVED
2020-08-22 07:51:33 -07:00
Michael Davidsaver
df6981ceae doc 2020-08-22 07:51:33 -07:00
Michael Davidsaver
11984633dc conditional test of registerAllRecordDeviceDrivers() 2020-08-22 07:50:40 -07:00
Michael Davidsaver
051ba20fe1 fix registerAllRecordDeviceDrivers() prints 2020-08-22 07:50:40 -07:00
Michael Davidsaver
d6cf29e942 add HAS_registerAllRecordDeviceDrivers 2020-08-22 07:50:40 -07:00
Michael Davidsaver
bdd41cca13 move test of registerAllRecordDeviceDrivers() 2020-08-22 07:50:40 -07:00
Michael Davidsaver
e40970bd5e rename dynamic_registerRecordDeviceDriver -> registerAllRecordDeviceDrivers 2020-08-22 07:50:40 -07:00
Michael Davidsaver
9e3d5d52ab iocshRegisterVariable() avoid spurious redefinition warning
Compare the contents, not the container.
2020-08-22 07:50:40 -07:00
Michael Davidsaver
2c389a90d1 test dynamic_registerRecordDeviceDriver() 2020-08-22 07:50:40 -07:00
Michael Davidsaver
8d98387245 add dynamic_registerRecordDeviceDriver()
Use epicsFindSymbol() to build a dynamic and idempotent equivalent
to the code generated by registerRecordDeviceDriver.pl

Also add runRegistrarOnce() to prevent registrars
from running multiple times, except from unittest code.
2020-08-22 07:50:40 -07:00
Andrew Johnson
b36e5262c7 const init a char array from a string value 2020-08-21 17:59:46 -05:00
Andrew Johnson
79d7ac9315 Support undefine in RELEASE files 2020-08-21 16:30:06 -05:00
Andrew Johnson
03c4fe8a8d Merge Record ref updates from 3.15 into 7.0 2020-08-21 15:47:53 -05:00
Andrew Johnson
ad3728d00d Edits to the Record Ref index page 2020-08-21 15:43:48 -05:00
Michael Davidsaver
c465354c67 Set next development version 2020-08-14 13:25:40 -07:00
Andrew Johnson
5f5cc85e28 Release Notes for json5 changes 2020-08-09 00:35:52 -05:00
Andrew Johnson
7cc246afc1 Modify database tests to use JSON5
(except for the tests that check parsing).
Remove escaped double-quotes in map keys where possible.
Replace escaped double-quotes with single quotes.
2020-08-09 00:33:07 -05:00
Andrew Johnson
75b89b40bf Support single-quoted strings in dbStatic JSON5 values
Teach lexer to recognize them.
Strip leading & trailing quotes from string values.
Add some tests.
2020-08-09 00:33:07 -05:00
Andrew Johnson
b34d3c83fc Add support for hex escapes to the dbStatic lexer
Only translate escaped chars that are inside a jsonSTRING value.
2020-08-09 00:33:07 -05:00
Andrew Johnson
c1152f94fd epicsString: Remove support for Octal character escapes \nnn
These changes to the functions epicsStrnRawFromEscaped() and
epicsStrnEscapedFromRaw() were prompted by the addition of JSON5
support to the dbStatic parser.

 * \0 now represents a zero byte
 * Unprintable characters are now escaped in hex

Tests for the octal escapes have been removed.
2020-08-09 00:33:07 -05:00
Andrew Johnson
8c9e42d15e Fixed the response of epicsStrnRawFromEscaped() to numeric overflows
\x only takes 2 hex digits now, and the octal parser ignores a 3rd
digit if it would take the value over 0xff:
    "\400"  => ' ' then '0'
    "\x088" => '\b' then '8'

With additional tests.
2020-08-09 00:33:07 -05:00
Andrew Johnson
0c800d4428 JSON5 in dbStatic: Update bare-word JSON keys
Our bare-word character set is wider than JSON5's. Quote any
keys containing the extra characters so YAJL can parse them,
but don't quote keys unnecessarily.

Tests for this behavior are in dbStaticTest.db

Adjust the other tests that read links parsed by the dbStatic
parser that used bareword keys, which are no longer quoted.
2020-08-09 00:33:07 -05:00
Andrew Johnson
0fca5fc8a9 JSON5 in dbStatic: Lexer support for NaN and Infinity
The JSON5 spec requires exact capitalization of these strings.
Other numeric parsers such as strtod() are usually more lenient.
2020-08-09 00:33:07 -05:00
Andrew Johnson
fe177e40fd JSON5 in dbStatic: Add lexer support for hex integers
dbLex.l accepts hex notation in JSON numbers.
Tested in dbStaticTest.db as before.
2020-08-09 00:33:07 -05:00
Andrew Johnson
fa4af8b27d JSON5 in dbStatic: Modify lexer's number support
dbLex.l acceps a leading or trailing decimal point with float/double
values and an explicit leading + on all numbers.
Tested in dbStaticTest.db but only passing tests.
2020-08-09 00:33:07 -05:00
Andrew Johnson
980711589a database/test: Give xRecord fields of all numeric types
Extend dbStaticTest to check dbVerify() with all types.
2020-08-09 00:33:07 -05:00
Andrew Johnson
b2ef47573c Drop TODOs from regression tests, hex now works in array values 2020-08-09 00:33:07 -05:00
Andrew Johnson
b0d78921fd Final changes to YAJL for use in Base
* Bump the YAJL version number
* Define a HAS_JSON5 macro
* Set yajl_allow_json5 by default, fixing yajl_test and API comments
2020-08-09 00:33:07 -05:00
Andrew Johnson
c00f638f7e yajl: Add yajl_gen_reset() routine
For some reason this never got added with the rest of the generator.
2020-08-09 00:33:07 -05:00
Andrew Johnson
975e9ec553 Doxygen text and markup fixes and updates 2020-08-09 00:33:07 -05:00
Andrew Johnson
de2de5e2fd yajl: Clean up the formatting of some C macros 2020-08-09 00:33:07 -05:00
Andrew Johnson
a8e0de043c Support for 'single-quoted strings'
Also adds missing character flag VIC for 'r'.
The a5_spec_example test was copied from the JSON5 spec.
2020-08-09 00:33:07 -05:00
Andrew Johnson
549d6f67e3 YAJL support for JSON5 \xXX hex escapes in strings, with tests
Teach the lexer/parser to recognize and decode them in JSON5 mode.
Teach the encoder to use them in JSON5 mode.
Add another error message for bad hex digits.
Test cases to show they work, and that the bad-digit check fires.
2020-08-09 00:33:07 -05:00
Andrew Johnson
55f4e55383 Support for JSON5 character escapes in strings
Any character other than the digits 1-9 may be preceded by a
reverse solidus '\', and unless the combination has an explicitly
defined expansion the character is included without the solidus.
JSON5 adds \', \0 and \v to the set of defined escapes, and an
escaped newline is omitted from a string.

In the test case Perl uses \13 instead of \v in the output
but it is the correct character (13 octal = 11 decimal = '\v').
2020-08-09 00:33:07 -05:00
Andrew Johnson
e2256d0663 Accept unquoted identifiers as map keys
Adds another lexer entry point for lexing map keys only,
adjust parser to use this instead of the general lexer.
Also defines another lexer token for internal use only.
2020-08-09 00:33:07 -05:00
Andrew Johnson
88e0ced03e JSON5 support for generating unquoted map keys
Added a new routine to yajl_encode.c that validates bare identifiers.
Use this in yajl_gen_string() to avoid quoting keys we don't have to.
2020-08-09 00:33:07 -05:00
Andrew Johnson
baaf50c6d2 Add yajl_gen_json5 option and generator support for special numbers
When this flag is set, the yajl_gen_double() routine can output
the values NaN, -Infinity and +Infinity.
2020-08-09 00:33:07 -05:00
Andrew Johnson
97b8df6912 Added JSON5 support for parsing special numbers
NaN and both Infinities, with tests.
Special handling was added to yajl_test since different OSs don't
always generate the same output for special numbers (nan/NaN/...).
2020-08-09 00:33:07 -05:00
Andrew Johnson
98a358437f Add JSON5 support for hexadecimal integers
With tests for YAJL.

Note yajl_parse_integer still can't handle LLONG_MIN in base 10 or 16.
2020-08-09 00:33:07 -05:00
Andrew Johnson
00ac15cec5 Turning on JSON5 also enables comments
Includes the simple test case.
2020-08-09 00:33:07 -05:00
Andrew Johnson
456e774d85 JSON5: Modified lexer for some number support
If configured for JSON5 the lexer now allows a leading or trailing
decimal point on doubles, and an explicit leading + sign on integers
or double numbers.

Includes test cases.
2020-08-09 00:33:07 -05:00
Andrew Johnson
91c5b2fee2 Trailing commas now require a json5 parser
Modifies the yajl test case to add the -5 option
2020-08-09 00:33:06 -05:00
Andrew Johnson
ae604b2a55 Start of JSON5 support
Added yajl_allow_json5 config flag, pass it around.
Added -5 option to yajl_test and yajlTestConverter.pl
2020-08-09 00:33:06 -05:00
Andrew Johnson
d381a936b5 Fix for yajl#188 potential UB
Apparently it is UB to use an enum in va_start()
2020-08-09 00:33:06 -05:00
d1491e0860 Use JSON arrays in dbpf 2020-07-17 15:03:53 +02:00
7709239636 make sure put_array_info exists before using it 2020-07-17 09:26:55 +02:00
a9731b90f6 Don't freeze the shell when we are out of memory 2020-07-17 09:12:54 +02:00
4368697f58 Updated RELEASE_NOTES.md 2020-07-13 14:53:20 +02:00
12cfd418d6 fix dbPut to set target to INVALID/LINK alarm when writing empty arrays into scalars 2020-07-06 15:22:54 +02:00
e5a48f152a RELEASE_NOTES updated 2020-06-29 23:00:30 +02:00
0a1fb25e6b fix dbCaGetLink to fail when reading scalars from empty arrays 2020-06-29 22:23:21 +02:00
473790124b bugfix: ai SoftDevice should return error status when get fails 2020-06-29 14:54:39 +02:00
0353ede517 don't use epicsOldString 2020-06-27 16:05:54 +02:00
73b86d4921 prevent buffer overflow in dbpf 2020-06-22 13:23:26 +02:00
dec4fc30d9 bugfix in dbpf 2020-06-22 11:30:59 +02:00
e68e38ad95 update RELEASE_NOTES.md about empty arrays 2020-06-10 17:48:09 +02:00
3176651c71 fix dbGet to fail when reading scalars from empty arrays 2020-06-09 16:14:49 +02:00
a42197f0d6 allow to write empty arrays with caput 2020-06-09 10:57:05 +02:00
f8035d8d5e support arrays in dbpf 2020-06-09 10:56:58 +02:00
e4dcd3cefd fix aSub record to support reading empty arrays 2020-06-09 10:56:52 +02:00
c4c13d8ce0 fix subArray soft device support to support reading empty arrays 2020-06-09 10:56:45 +02:00
19c50d4c3d fix aai and waveform soft device support to support reading empty arrays 2020-06-09 10:56:34 +02:00
8cc20393f1 fix dbr size of empty arrays. Fixes caget returning non 0 in first element 2020-06-09 10:56:24 +02:00
cc616371b1 allow constant links with numeric 1 element arrays like [42] 2020-06-08 15:05:22 +02:00
210 changed files with 4705 additions and 1892 deletions

View File

@@ -1,5 +1,5 @@
# .appveyor.yml for use with EPICS Base ci-scripts
# (see: https://github.com/epics-base/ci-scripts)
# Appveyor configuration file for EPICS Base 7 builds
# (see also https://github.com/epics-base/ci-scripts)
# Version format
version: base-{branch}-{build}
@@ -29,9 +29,10 @@ clone_depth: 5
skip_commits:
files:
- 'documentation/*'
- 'startup/*'
- '.github/*'
- '**/*.html'
- '**/*.md'
- '.travis.yml'
#---------------------------------#
# build matrix configuration #
@@ -77,14 +78,17 @@ matrix:
CMP: vs2012
- platform: x64
CMP: vs2010
- platform: x64
CMP: vs2008
# Exclude more jobs to reduce build time
# Skip 32-bit for "middle-aged" compilers
- platform: x86
CMP: vs2017
- platform: x86
CMP: vs2015
# MinGW debug builds use the same libraries, unlike VS
- configuration: dynamic-debug
CMP: gcc
- configuration: static-debug
CMP: gcc
#---------------------------------#
# building & testing #
@@ -92,18 +96,23 @@ matrix:
install:
- cmd: git submodule update --init --recursive
- cmd: pip install git+https://github.com/mdavidsaver/ci-core-dumper#egg=ci-core-dumper
- cmd: python .ci/cue.py prepare
build_script:
- cmd: python .ci/cue.py build
test_script:
- cmd: python -m ci_core_dumper install
- cmd: python .ci/cue.py test
on_finish:
- ps: Get-ChildItem *.tap -Recurse -Force | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
- cmd: python .ci/cue.py build test-results -s
on_failure:
- cmd: python -m ci_core_dumper report
#---------------------------------#
# debugging #
#---------------------------------#

150
.appveyor/epics-base-7.yml Normal file
View File

@@ -0,0 +1,150 @@
# Appveyor configuration file for EPICS Base 7 builds
# (see also https://github.com/epics-base/ci-scripts)
# branches to build
branches:
# whitelist
only:
- 7.0
- /R7\.0\.\d+.*/
# Version format
version: base-{branch}-{build}
#---------------------------------#
# build cache #
#---------------------------------#
# The AppVeyor cache allowance is way too small (1GB per account across all projects, branches and jobs)
# to be used for the dependency builds.
cache:
- C:\Users\appveyor\.tools
#---------------------------------#
# repository cloning #
#---------------------------------#
# Called at very beginning, before repo cloning
init:
# Set autocrlf to make batch files work
- git config --global core.autocrlf true
# Set clone depth (do not fetch complete history)
clone_depth: 5
# Skipping commits affecting only specific files
skip_commits:
files:
- 'documentation/*'
- 'startup/*'
- '.github/*'
- '**/*.html'
- '**/*.md'
#---------------------------------#
# build matrix configuration #
#---------------------------------#
image: Visual Studio 2015
# Build Configurations: dll/static, regular/debug
configuration:
- dynamic
- static
- dynamic-debug
- static-debug
# Environment variables: compiler toolchain, base version, setup file, ...
environment:
# common / default variables for all jobs
SETUP_PATH: .ci-local:.ci
BASE: SELF
EPICS_TEST_IMPRECISE_TIMING: YES
matrix:
- CMP: vs2019
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- CMP: vs2017
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- CMP: vs2015
- CMP: vs2013
- CMP: vs2012
- CMP: vs2010
- CMP: gcc
# Platform: processor architecture
platform:
- x86
- x64
# Matrix configuration: exclude sets of jobs
matrix:
exclude:
# VS2012 and older installs don't have the 64 bit compiler
- platform: x64
CMP: vs2012
- platform: x64
CMP: vs2010
# Exclude more jobs to reduce build time
# Skip 32-bit for "middle-aged" compilers
- platform: x86
CMP: vs2017
- platform: x86
CMP: vs2015
# MinGW debug builds use the same libraries, unlike VS
- configuration: dynamic-debug
CMP: gcc
- configuration: static-debug
CMP: gcc
#---------------------------------#
# building & testing #
#---------------------------------#
install:
- cmd: git submodule update --init --recursive
- cmd: pip install git+https://github.com/mdavidsaver/ci-core-dumper#egg=ci-core-dumper
- cmd: python .ci/cue.py prepare
build_script:
- cmd: python .ci/cue.py build
test_script:
- cmd: python -m ci_core_dumper install
- cmd: python .ci/cue.py test
on_finish:
- ps: Get-ChildItem *.tap -Recurse -Force | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
- cmd: python .ci/cue.py build test-results -s
on_failure:
- cmd: python -m ci_core_dumper report
#---------------------------------#
# debugging #
#---------------------------------#
## if you want to connect by remote desktop to a failed build, uncomment these lines
## note that you will need to connect within the usual build timeout limit (60 minutes)
## so you may want to adjust the build matrix above to just build the one of interest
# print the connection info
#init:
# - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
# block a failed build (until the watchdog barks)
#on_failure:
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
#---------------------------------#
# notifications #
#---------------------------------#
notifications:
- provider: Email
to:
- core-talk@aps.anl.gov
on_build_success: false
- provider: GitHubPullRequest

2
.ci

Submodule .ci updated: 87942a7c29...3db08b5977

152
.github/workflows/ci-scripts-build.yml vendored Normal file
View File

@@ -0,0 +1,152 @@
# .github/workflows/ci-scripts-build.yml for use with EPICS Base ci-scripts
# (see: https://github.com/epics-base/ci-scripts)
# This is YAML - indentation levels are crucial
# Workflow name, shared by all branches
name: Base
# Trigger on pushes and PRs to any branch
on:
push:
paths-ignore:
- 'documentation/*'
- 'startup/*'
- '.appveyor/*'
- '**/*.html'
- '**/*.md'
pull_request:
env:
SETUP_PATH: .ci-local:.ci
BASE: SELF
EPICS_TEST_IMPRECISE_TIMING: YES
jobs:
build-base:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
# Set environment variables from matrix parameters
env:
CMP: ${{ matrix.cmp }}
BCFG: ${{ matrix.configuration }}
WINE: ${{ matrix.wine }}
RTEMS: ${{ matrix.rtems }}
EXTRA: ${{ matrix.extra }}
strategy:
fail-fast: false
matrix:
# Job names also name artifacts, character limitations apply
include:
- os: ubuntu-20.04
cmp: gcc
configuration: default
wine: "64"
name: "Ub-20 gcc-9 + MinGW"
- os: ubuntu-20.04
cmp: gcc
configuration: static
wine: "64"
name: "Ub-20 gcc-9 + MinGW, static"
- os: ubuntu-20.04
cmp: gcc
configuration: static
extra: "CMD_CXXFLAGS=-std=c++11"
name: "Ub-20 gcc-9 C++11, static"
- os: ubuntu-16.04
cmp: clang
configuration: default
name: "Ub-16 clang-9"
- os: ubuntu-20.04
cmp: clang
configuration: default
extra: "CMD_CXXFLAGS=-std=c++11"
name: "Ub-20 clang-10 C++11"
- os: ubuntu-20.04
cmp: gcc
configuration: default
rtems: "4.10"
name: "Ub-20 gcc-9 + RT-4.10"
- os: ubuntu-20.04
cmp: gcc
configuration: default
rtems: "4.9"
name: "Ub-20 gcc-9 + RT-4.9"
- os: ubuntu-16.04
cmp: gcc-4.8
utoolchain: "4.8"
configuration: default
name: "Ub-16 gcc-4.8"
- os: ubuntu-16.04
cmp: gcc-4.9
utoolchain: "4.9"
configuration: default
name: "Ub-16 gcc-4.9"
- os: ubuntu-20.04
cmp: gcc-8
utoolchain: "8"
configuration: default
name: "Ub-20 gcc-8"
- os: ubuntu-20.04
cmp: clang
configuration: default
name: "Ub-20 clang-10"
- os: macos-latest
cmp: clang
configuration: default
name: "MacOS clang-12"
- os: windows-2019
cmp: vs2019
configuration: default
name: "Win2019 MSC-19"
- os: windows-2019
cmp: vs2019
configuration: static
name: "Win2019 MSC-19, static"
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Automatic core dumper analysis
uses: mdavidsaver/ci-core-dumper@master
- name: "apt-get install"
run: |
sudo apt-get update
sudo apt-get -y install qemu-system-x86 g++-mingw-w64-x86-64 gdb
if: runner.os == 'Linux'
- name: "apt-get install ${{ matrix.cmp }}"
run: |
sudo apt-get update
sudo apt-get -y install software-properties-common
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get -y install g++-${{ matrix.utoolchain }}
if: matrix.utoolchain
- name: Prepare and compile dependencies
run: python .ci/cue.py prepare
- name: Build main module
run: python .ci/cue.py build
- name: Run main module tests
run: python .ci/cue.py test
- name: Upload tapfiles Artifact
uses: actions/upload-artifact@v2
with:
name: tapfiles ${{ matrix.name }}
path: '**/O.*/*.tap'
- name: Collect and show test results
run: python .ci/cue.py test-results

2
.gitignore vendored
View File

@@ -11,6 +11,8 @@
/modules/Makefile.local
O.*/
/QtC-*
/.vscode/
*.orig
*.log
.*.swp
.DS_Store

102
.tools/adjustver.py Executable file
View File

@@ -0,0 +1,102 @@
#!/usr/bin/env python3
import logging
import sys
import re
from io import StringIO
_log = logging.getLogger(__name__)
def main(args):
logging.basicConfig(level=args.level)
if args.dev is True:
actions=[
('DEVELOPMENT_FLAG', '1'),
('DEV_SNAPSHOT', '-DEV'),
]
elif args.dev is False:
actions=[
('DEVELOPMENT_FLAG', '0'),
('DEV_SNAPSHOT', ''),
]
elif args.version:
M=re.match(r'R?(\d+).(\d+).(\d+)(?:.(\d+))?(-.*)?', args.version)
actions=[
('SITE_VERSION', None),
('SHORT_VERSION', None),
('MINOR_VERSION', M[2]),
('REVISION', M[2]),
('MODIFICATION', M[3]),
('MAINTENANCE_VERSION', M[3]),
('PATCH_LEVEL', M[4] or '0'),
('DEVELOPMENT_FLAG', '1' if (M[5] or '').upper().endswith('-DEV') else '0'),
('DEV_SNAPSHOT', M[5] or ''),
('MAJOR_VERSION', M[1]),
('VERSION', M[1]), # plain _VERSION must be last to resolve ambiguity
]
elif args.dry_run:
_log.debug('Print existing')
for fname in args.conf:
print('# ', fname)
with open(fname, 'r') as F:
sys.stdout.write(F.read())
return
else:
print('One of --version, --release, --dev, or --dry-run is required')
sys.exit(1)
for name, val in actions:
_log.debug('Pattern "%s" -> "%s"', name, val)
for fname in args.conf:
OUT=StringIO()
with open(fname, 'r') as F:
for line in F:
_log.debug('Line: %s', repr(line))
for name, val in actions:
M = re.match(r'(\s*[A-Z_]+' + name + r'\s*=[\t ]*)(\S*)(\s*)', line)
if M and val is None:
_log.debug('Ignore')
OUT.write(line)
break
elif M:
_log.debug(' Match %s -> %s', M.re.pattern, M.groups())
OUT.write(M[1]+val+M[3])
break
else:
_log.debug('No match')
OUT.write(line)
if args.dry_run:
print('# ', fname)
print(OUT.getvalue())
else:
with open(fname, 'w') as F:
F.write(OUT.getvalue())
def getargs():
from argparse import ArgumentParser
P = ArgumentParser()
P.add_argument('-n','--dry-run', action='store_true', default=False)
P.add_argument('-d','--debug', dest='level', action='store_const',
const=logging.DEBUG, default=logging.INFO)
P.add_argument('-V', '--version', help='A version in R1.2.3-xyz or 1.2.3 form')
P.add_argument('-D', '--dev', action='store_true', default=None)
P.add_argument('-R', '--release', dest='dev', action='store_false')
P.add_argument('conf', nargs='+',
help='A configure/CONFIG_*_VERSION file name')
return P
if __name__=='__main__':
main(getargs().parse_args())

View File

@@ -1,91 +0,0 @@
# .travis.yml for use with EPICS Base ci-scripts
# (see: https://github.com/epics-base/ci-scripts)
language: cpp
compiler: gcc
dist: xenial
cache:
directories:
- $HOME/.cache
env:
global:
- SETUP_PATH=.ci-local:.ci
- BASE=SELF
- EPICS_TEST_IMPRECISE_TIMING=YES
addons:
apt:
packages:
# for all EPICS builds
- libreadline6-dev
- libncurses5-dev
- perl
# for clang compiler
- clang
# for mingw builds (32bit and 64bit)
- g++-mingw-w64-i686
- g++-mingw-w64-x86-64
# for RTEMS cross builds
- qemu-system-x86
homebrew:
packages:
# for all EPICS builds
- bash
update: true
install:
- ./.ci-local/travis-fixup.sh
- python .ci/cue.py prepare
script:
- python .ci/cue.py build
- python .ci/cue.py test
- python .ci/cue.py test-results
# Define build jobs
jobs:
include:
# Different configurations of default gcc and clang
- dist: bionic
- dist: xenial
- dist: bionic
env: BCFG=static EXTRA="CMD_CXXFLAGS=-std=c++11"
- dist: trusty
env: EXTRA="CMD_CXXFLAGS=-std=c++11"
- dist: bionic
compiler: clang
- compiler: clang
- dist: trusty
compiler: clang
env: BCFG=static
# Cross-compilations to Windows using MinGW and WINE
- env: WINE=32 TEST=NO BCFG=static
- env: WINE=32 TEST=NO
# Cross-compilation to RTEMS
- env: RTEMS=4.10
- env: RTEMS=4.9
# MacOS build
- os: osx
env:
- EXTRA="CMD_CFLAGS=-mmacosx-version-min=10.7"
- EXTRA1="CMD_CXXFLAGS=-mmacosx-version-min=10.7 -std=c++11 -stdlib=libc++"
- EXTRA2="CMD_LDXFLAGS=-mmacosx-version-min=10.7 -std=c++11 -stdlib=libc++"
compiler: clang

View File

@@ -31,7 +31,7 @@ PROF_CFLAGS_YES = -p
GPROF_CFLAGS_YES = -pg
CODE_CFLAGS = $(PROF_CFLAGS_$(PROFILE)) $(GPROF_CFLAGS_$(GPROF))
CODE_CFLAGS += $(ASAN_FLAGS_$(ENABLE_ASAN))
WARN_CFLAGS_YES = -Wall
WARN_CFLAGS_YES = -Wall -Werror-implicit-function-declaration
WARN_CFLAGS_NO = -w
OPT_CFLAGS_YES = -O3
OPT_CFLAGS_NO = -g

View File

@@ -64,10 +64,15 @@ DEPCLEAN = $(call FIND_TOOL,depclean.pl)
#---------------------------------------------------------------
# Tools for testing
TAPTOJUNIT = $(PERL) $(TOOLS)/tap-to-junit-xml.pl
PROVE = $(PERL) $(TOOLS)/epicsProve.pl
PROVE.tap = $(PROVE) --ext .tap --exec "$(CAT)"
TAPS_FAILED_LOG = .taps-failed.log
TESTS_FAILED_LOG = .tests-failed.log
TESTS_FAILED_PATH = $(abspath $(TOP)/$(TESTS_FAILED_LOG))
TEST_FAILURE_FILENAME = .tests-failed.log
TEST_FAILURE_FILE = $(TOP)/$(TEST_FAILURE_FILENAME)
PROVE_FAILURE = echo $(abspath .)>> $(TEST_FAILURE_FILE)
TAPTOJUNIT = $(PERL) $(TOOLS)/tap-to-junit-xml.pl
PROVE = $(PERL) $(TOOLS)/epicsProve.pl --failures --color
PROVE.tap = $(PROVE) --ext .tap --exec "$(CAT)"
TESTFAILURES = $(PERL) $(TOOLS)/testFailures.pl
SHOWTESTFAILURES = $(TESTFAILURES) $(TESTS_FAILED_PATH) $(TAPS_FAILED_LOG)
PROVE_FAILURE = echo $(abspath .)>> $(TESTS_FAILED_PATH)
TAPFILE_FAILURE = echo $@>> $(TAPS_FAILED_LOG)

View File

@@ -48,11 +48,11 @@ EPICS_VERSION = 7
EPICS_REVISION = 0
# EPICS_MODIFICATION must be a number >=0 and <256
EPICS_MODIFICATION = 4
EPICS_MODIFICATION = 5
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
# Not included in the official EPICS version number if zero
EPICS_PATCH_LEVEL = 1
EPICS_PATCH_LEVEL = 0
# Immediately after an official release the EPICS_PATCH_LEVEL is incremented
# and the -DEV suffix is added (similar to the Maven -SNAPSHOT versions)

View File

@@ -2,7 +2,7 @@
EPICS_CA_MAJOR_VERSION = 4
EPICS_CA_MINOR_VERSION = 13
EPICS_CA_MAINTENANCE_VERSION = 7
EPICS_CA_MAINTENANCE_VERSION = 8
# Development flag, set to zero for release versions

View File

@@ -80,12 +80,12 @@ IOCS_APPL_TOP = $(shell $(FULLPATHNAME) $(INSTALL_LOCATION))
#-------------------------------------------------------
# Silencing the build - suppress messages during 'make -s'
NOP = :
ECHO = @$(if $(findstring s,$(MFLAGS)),$(NOP),echo)
QUIET_FLAG := $(if $(findstring s,$(MFLAGS)),-q,)
ECHO = @$(if $(filter -s,$(MFLAGS)),$(NOP),echo)
QUIET_FLAG := $(if $(filter -s,$(MFLAGS)),-q,)
#-------------------------------------------------------
# Convert 'make -q' flag into '-i' for genVersionHeader.pl
QUESTION_FLAG := $(if $(findstring q,$(MFLAGS)),-i,)
QUESTION_FLAG := $(if $(filter -q,$(MFLAGS)),-i,)
#-------------------------------------------------------
ifdef T_A

View File

@@ -24,3 +24,5 @@ MSI3_15 = $(EPICS_DATABASE_HOST_BIN)/msi$(HOSTEXE)
# Libraries needed to link a basic IOC
EPICS_BASE_IOC_LIBS = dbRecStd dbCore ca Com
HAS_registerAllRecordDeviceDrivers=YES

View File

@@ -1,8 +1,8 @@
# Version number for the database APIs and shared library
EPICS_DATABASE_MAJOR_VERSION = 3
EPICS_DATABASE_MINOR_VERSION = 18
EPICS_DATABASE_MAINTENANCE_VERSION = 1
EPICS_DATABASE_MINOR_VERSION = 19
EPICS_DATABASE_MAINTENANCE_VERSION = 0
# Development flag, set to zero for release versions

View File

@@ -1,8 +1,8 @@
# Version number for the libcom APIs and shared library
EPICS_LIBCOM_MAJOR_VERSION = 3
EPICS_LIBCOM_MINOR_VERSION = 18
EPICS_LIBCOM_MAINTENANCE_VERSION = 1
EPICS_LIBCOM_MINOR_VERSION = 19
EPICS_LIBCOM_MAINTENANCE_VERSION = 0
# Development flag, set to zero for release versions

View File

@@ -22,6 +22,7 @@
# darwin-x86 (Intel based Apple running OSX)
# freebsd-x86 (GNU compiler used for host builds)
# freebsd-x86_64 (GNU compiler used for host builds)
# linux-aarch64 (GNU compiler used for host builds)
# linux-arm (GNU compiler used for host builds)
# linux-ppc (GNU compiler used for host builds)
# linux-ppc64 (GNU compiler used for host builds)
@@ -51,7 +52,6 @@
# windows-x64-debug (MS Visual C++ compiler with debug option for host builds)
# EPICS_HOST_ARCH is a required environment variable
# Do not set EPICS_HOST_ARCH in this file.
# Use base/startup files to set EPICS_HOST_ARCH or
# provide EPICS_HOST_ARCH on the GNU make command line.

View File

@@ -32,12 +32,12 @@ vpath %.l $(USR_VPATH) $(ALL_SRC_DIRS)
include $(CONFIG)/CONFIG_ADDONS
#---------------------------------------------------------------
# Set PROD, TESTPROD, OBJS, and LIBRARY
SCRIPTS_HOST += $(PERL_SCRIPTS)
# PERL_SCRIPTS are installed into existing $(INSTALL_BIN) for Host systems
ifeq ($(findstring Host,$(VALID_BUILDS)),Host)
# Host targets can compile and run programs
ifneq (,$(findstring Host,$(VALID_BUILDS)))
LIBRARY += $(LIBRARY_HOST)
LOADABLE_LIBRARY += $(LOADABLE_LIBRARY_HOST)
OBJS += $(OBJS_HOST)
@@ -49,7 +49,21 @@ TESTSCRIPTS += $(TESTSCRIPTS_HOST)
TESTPROD += $(TESTPROD_HOST)
endif
ifeq ($(findstring Ioc,$(VALID_BUILDS)),Ioc)
# Command targets have a command line and support main()
ifneq (,$(findstring Command,$(VALID_BUILDS)))
LIBRARY += $(LIBRARY_CMD)
LOADABLE_LIBRARY += $(LOADABLE_LIBRARY_CMD)
OBJS += $(OBJS_CMD)
PROD += $(PROD_CMD)
SCRIPTS += $(SCRIPTS_CMD)
TARGETS += $(TARGETS_CMD)
TESTLIBRARY += $(TESTLIBRARY_CMD)
TESTSCRIPTS += $(TESTSCRIPTS_CMD)
TESTPROD += $(TESTPROD_CMD)
endif
# Ioc targets can run IOCs
ifneq (,$(findstring Ioc,$(VALID_BUILDS)))
LIBRARY += $(LIBRARY_IOC)
LOADABLE_LIBRARY += $(LOADABLE_LIBRARY_IOC)
OBJS += $(OBJS_IOC)
@@ -358,7 +372,8 @@ runtests: run-tap-tests
run-tap-tests: $(TESTSCRIPTS.t)
ifneq ($(TESTSCRIPTS.t),)
ifdef RUNTESTS_ENABLED
$(PROVE) --failures --color $^ || $(PROVE_FAILURE)
$(ECHO) "$(PROVE) $^"
@$(PROVE) $^ || $(PROVE_FAILURE)
endif
endif
@@ -369,7 +384,8 @@ test-results: tap-results
tap-results: $(TAPFILES)
ifneq ($(strip $(TAPFILES)),)
ifdef RUNTESTS_ENABLED
$(PROVE.tap) --failures --color $^ || $(PROVE_FAILURE)
$(ECHO) "$(PROVE.tap) $^"
@$(PROVE.tap) $^ || $(PROVE_FAILURE)
endif
CURRENT_TAPFILES := $(wildcard $(TAPFILES))
@@ -377,8 +393,8 @@ CURRENT_JUNITFILES := $(wildcard $(JUNITFILES))
endif
clean-tests:
ifneq ($(CURRENT_TAPFILES),)
$(RM) $(CURRENT_TAPFILES)
ifneq ($(CURRENT_TAPFILES)$(TAPS_FAILED_LOG),)
$(RM) $(CURRENT_TAPFILES) $(TAPS_FAILED_LOG)
endif
ifneq ($(CURRENT_JUNITFILES),)
$(RM) $(CURRENT_JUNITFILES)
@@ -387,7 +403,8 @@ endif
# A .tap file is the output from running the associated test script
$(TAPFILES.t): %.tap: %.t
ifdef RUNTESTS_ENABLED
$(PERL) $< -tap > $@
$(ECHO) "$(PERL) $< -tap > $@"
@$(PERL) $< -tap > $@ || $(TAPFILE_FAILURE)
endif
$(JUNITFILES.t): %-results.xml: %.tap

View File

@@ -86,8 +86,10 @@ expand_clean:
ASSEMBLE_TOOL ?= $(PERL) $(TOOLS)/assembleSnippets.pl
define COMMON_ASSEMBLY_template
ifneq '$$($1_PATTERN)' ''
$1_SNIPPETS += $$(foreach dir, .. $$(SRC_DIRS), \
$$(wildcard $$(dir)/$$($1_PATTERN)))
endif
$(COMMON_DIR)/$1: $$($1_SNIPPETS)
$(ECHO) "Assembling common file $$@ from snippets"
@$(RM) $1
@@ -98,8 +100,10 @@ $(foreach asy, $(COMMON_ASSEMBLIES), \
$(eval $(call COMMON_ASSEMBLY_template,$(strip $(asy)))))
define ASSEMBLY_template
ifneq '$$($1_PATTERN)' ''
$1_SNIPPETS += $$(foreach dir, .. $$(SRC_DIRS), \
$$(wildcard $$(dir)/$$($1_PATTERN)))
endif
$1: $$($1_SNIPPETS)
$(ECHO) "Assembling file $$@ from snippets"
@$(RM) $$@

View File

@@ -47,14 +47,9 @@ realclean:
.PHONY: RELEASE.host realclean
# Append all our live submodule failure files
FAILURE_FILES = $(addsuffix /$(TEST_FAILURE_FILENAME), $(LIVE_SUBMODULES))
define combine_failure_files
@$(TOUCH) $(FAILURE_FILES)
@$(CAT) $(FAILURE_FILES) >> $(TEST_FAILURE_FILE)
endef
runtests: | $(addsuffix $(DIVIDER)runtests, $(LIVE_SUBMODULES))
$(if $(FAILURE_FILES), $(combine_failure_files))
test-results: | $(addsuffix $(DIVIDER)test-results, $(LIVE_SUBMODULES))
$(if $(FAILURE_FILES), $(combine_failure_files))
# Testing: Combine test failure logs from the live submodules
TESTS_FAILED_LOGS = $(wildcard $(addsuffix /$(TESTS_FAILED_LOG), \
$(LIVE_SUBMODULES)))
runtests test-results: % : | $(addsuffix $(DIVIDER)%, $(LIVE_SUBMODULES))
$(if $(TESTS_FAILED_LOGS), \
@$(CAT) $(TESTS_FAILED_LOGS)>> $(TESTS_FAILED_PATH))

View File

@@ -33,7 +33,7 @@ UNINSTALL_DIRS += $(INSTALL_INCLUDE) $(INSTALL_TEMPLATES) $(DIRECTORY_TARGETS)
ifneq ($(INSTALL_LOCATION),$(TOP))
UNINSTALL_DIRS += $(INSTALL_CONFIG)
endif
uninstallDirs:
uninstallDirs: | clean
$(RMDIR) $(UNINSTALL_DIRS)
# Remove the bin and lib directories if they have no sub-directories
@@ -41,17 +41,18 @@ uninstallDirs:
EMPTY_INSTALL_DIRS = \
$(if $(wildcard $(INSTALL_LOCATION_BIN)/*),,$(INSTALL_LOCATION_BIN)) \
$(if $(wildcard $(INSTALL_LOCATION_LIB)/*),,$(INSTALL_LOCATION_LIB))
uninstall: archuninstall uninstallDirs
uninstall: archuninstall uninstallDirs | clean
$(RMDIR) $(EMPTY_INSTALL_DIRS)
archuninstall: $(addprefix uninstall$(DIVIDER),$(BUILD_ARCHS))
uninstall$(DIVIDER)%:
uninstall$(DIVIDER)%: | clean
$(RMDIR) $(addsuffix /$(subst uninstall$(DIVIDER),,$@), \
$(INSTALL_LOCATION_BIN) $(INSTALL_LOCATION_LIB))
# Only run this at the top of the parent
runtests test-results:
@$(PERL) $(TOOLS)/testFailures.pl $(TEST_FAILURE_FILE)
@$(SHOWTESTFAILURES)
else
#
@@ -63,10 +64,10 @@ else
endif # DISABLE_TOP_RULES
# Clean out old results
before-runtests before-test-results: rm-failure-file
rm-failure-file:
@$(RM) $(TEST_FAILURE_FILE)
@$(TOUCH) $(TEST_FAILURE_FILE)
$(RM) $(TESTS_FAILED_PATH)
help:
@echo "Usage: gnumake [options] [target] ..."

View File

@@ -76,7 +76,7 @@ CPPFLAGS += $($(BUILD_CLASS)_CPPFLAGS) $(POSIX_CPPFLAGS) $(OPT_CPPFLAGS)\
$(USR_CPPFLAGS) $(CMD_CPPFLAGS) $(ARCH_DEP_CPPFLAGS) $(OP_SYS_CPPFLAGS)\
$(OP_SYS_INCLUDE_CPPFLAGS) $(CODE_CPPFLAGS)
ECHO = @$(if $(findstring s,$(MFLAGS)),$(NOP),echo)
ECHO = @$(if $(filter -s,$(MFLAGS)),$(NOP),echo)
#--------------------------------------------------
# Although RTEMS uses gcc, it wants to use gcc its own way

View File

@@ -8,7 +8,7 @@
#-------------------------------------------------------
# Unix valid build types
VALID_BUILDS = Host Ioc
VALID_BUILDS = Host Ioc Command
#-------------------------------------------------------
# Unix prefix and suffix definitions

View File

@@ -0,0 +1,14 @@
# CONFIG.Common.darwin-aarch64
#
# This file is maintained by the build community.
#
# Definitions for darwin-aarch64 target builds
# Sites may override these definitions in CONFIG_SITE.Common.darwin-aarch64
#-------------------------------------------------------
#
# To build universal binaries, configure ARCH_CLASS
# in the file CONFIG_SITE.Common.darwin-aarch64
# Include definitions common to all Darwin targets
include $(CONFIG)/os/CONFIG.darwinCommon.darwinCommon

View File

@@ -12,7 +12,7 @@ include $(CONFIG)/os/CONFIG.Common.linux-x86
ARCH_DEP_CFLAGS = -march=i386
ifeq ($(BUILD_CLASS),CROSS)
VALID_BUILDS = Ioc
VALID_BUILDS = Ioc Command
endif
# If your crosscompiler name has a GNU target prefix like <gnutarget>-gcc,

View File

@@ -10,7 +10,7 @@ include $(CONFIG)/os/CONFIG.Common.linux-x86
ARCH_DEP_CFLAGS = -march=i486
ifeq ($(BUILD_CLASS),CROSS)
VALID_BUILDS = Ioc
VALID_BUILDS = Ioc Command
endif
# If your crosscompiler name has a GNU target prefix like <gnutarget>-gcc,

View File

@@ -11,7 +11,7 @@ include $(CONFIG)/os/CONFIG.Common.linux-x86
ARCH_DEP_CFLAGS = -march=i586
ifeq ($(BUILD_CLASS),CROSS)
VALID_BUILDS = Ioc
VALID_BUILDS = Ioc Command
endif
# If your crosscompiler name has a GNU target prefix like <gnutarget>-gcc,

View File

@@ -11,7 +11,7 @@ include $(CONFIG)/os/CONFIG.Common.linux-x86
ARCH_DEP_CFLAGS = -march=i686
ifeq ($(BUILD_CLASS),CROSS)
VALID_BUILDS = Ioc
VALID_BUILDS = Ioc Command
endif
# If your crosscompiler name has a GNU target prefix like <gnutarget>-gcc,

View File

@@ -10,7 +10,7 @@ include $(CONFIG)/os/CONFIG.Common.linux-x86
ARCH_DEP_CFLAGS += -march=athlon-mp -mfpmath=sse
ifeq ($(BUILD_CLASS),CROSS)
VALID_BUILDS = Ioc
VALID_BUILDS = Ioc Command
endif
# If your crosscompiler name has a GNU target prefix like <gnutarget>-gcc,

View File

@@ -15,7 +15,7 @@ include $(CONFIG)/os/CONFIG.Common.linuxCommon
ARCH_CLASS = microblaze
ifeq ($(BUILD_CLASS),CROSS)
VALID_BUILDS = Ioc
VALID_BUILDS = Ioc Command
GNU_TARGET = microblazeel-unknown-linux-gnu
CMPLR_PREFIX = $(addsuffix -,$(GNU_TARGET))
endif

View File

@@ -13,7 +13,7 @@ include $(CONFIG)/os/CONFIG.Common.linuxCommon
ARCH_CLASS = xscale
ifeq ($(BUILD_CLASS),CROSS)
VALID_BUILDS = Ioc
VALID_BUILDS = Ioc Command
GNU_TARGET = xscale_be
CMPLR_PREFIX = $(GNU_TARGET:%=%-)

View File

@@ -0,0 +1,8 @@
# CONFIG.darwin-aarch64.Common
#
# Definitions for darwin-aarch64 host builds
# Sites may override these definitions in CONFIG_SITE.darwin-aarch64.Common
#-------------------------------------------------------
#Include definitions common to unix hosts
include $(CONFIG)/os/CONFIG.UnixCommon.Common

View File

@@ -0,0 +1,8 @@
# CONFIG.linux-aarch64.Common
#
# Definitions for linux-aarch64 host builds
# Sites may override these definitions in CONFIG_SITE.linux-aarch64.Common
#-------------------------------------------------------
#Include definitions common to unix hosts
include $(CONFIG)/os/CONFIG.UnixCommon.Common

View File

@@ -0,0 +1,8 @@
# CONFIG.linux-aarch64.linux-aarch64
#
# Definitions for native linux-aarch64 builds
# Override these definitions in CONFIG_SITE.linux-aarch64.linux-aarch64
#-------------------------------------------------------
# Include common gnu compiler definitions
include $(CONFIG)/CONFIG.gnuCommon

View File

@@ -4,7 +4,7 @@
# Override these settings in CONFIG_SITE.linux-x86.linux-arm
#-------------------------------------------------------
VALID_BUILDS = Ioc
VALID_BUILDS = Ioc Command
GNU_TARGET = arm-linux
# prefix of compiler tools

View File

@@ -4,7 +4,7 @@
# Sites may override these in CONFIG_SITE.linux-x86_64.linux-aarch64
#-------------------------------------------------------
VALID_BUILDS = Ioc
VALID_BUILDS = Ioc Command
GNU_TARGET = aarch64-linux
# prefix of compiler tools

View File

@@ -26,6 +26,3 @@ endif
# Needed to find dlls for base installed build tools (antelope,eflex,...)
PATH := $(EPICS_BASE_BIN):$(PATH)
# Silence the tr1 namespace deprecation warnings
USR_CXXFLAGS_WIN32 += -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING

View File

@@ -6,7 +6,7 @@
# Win32 valid build types and include directory suffixes
VALID_BUILDS = Host Ioc
VALID_BUILDS = Host Ioc Command
CMPLR_CLASS = msvc
@@ -107,6 +107,9 @@ CODE_CPPFLAGS += -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
WARN_CXXFLAGS_YES = -W3 -w44355 -w44344 -w44251
WARN_CXXFLAGS_NO = -W1
# Silence tr1 namespace deprecation warnings
WARN_CXXFLAGS += -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING
#
# -Ox maximum optimizations
# -GL whole program optimization

View File

@@ -16,3 +16,9 @@ COMMANDLINE_LIBRARY = READLINE_NCURSESW
# No other libraries needed
#COMMANDLINE_LIBRARY = READLINE
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
# overridden in this file for native builds, e.g. variables such as
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
# They must be set in CONFIG_SITE.cygwin-x86.cygwin-x86 instead.

View File

@@ -11,10 +11,8 @@
#LDLIBS_READLINE = -lreadline -lcurses
# It makes sense to include debugging symbols even in optimized builds
# in case you want to attach gdb to the process or examine a core-dump.
# This does cost disk space, but not memory as debug symbols are not
# loaded into RAM when the binary is loaded.
OPT_CFLAGS_YES += -g
OPT_CXXFLAGS_YES += -g
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
# overridden in this file for native builds, e.g. variables such as
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
# They must be set in CONFIG_SITE.cygwin-x86_64.cygwin-x86_64 instead.

View File

@@ -0,0 +1,9 @@
# CONFIG_SITE.Common.darwin-aarch64
#
# Site override definitions for darwin-aarch64 target builds
#-------------------------------------------------------
#
# arm64 devices: Apple Silicon M1
ARCH_CLASS = arm64

View File

@@ -30,3 +30,9 @@
# Needs -lcurses (older versions)
#COMMANDLINE_LIBRARY = READLINE_CURSES
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
# overridden in this file for native builds, e.g. variables such as
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
# They must be set in CONFIG_SITE.linux-aarch64.linux-aarch64 instead.

View File

@@ -33,3 +33,12 @@ COMMANDLINE_LIBRARY = $(strip $(if $(wildcard \
# Readline is broken or you don't want use it:
#COMMANDLINE_LIBRARY = EPICS
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
# overridden in this file for native builds, e.g. variables such as
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
# They must be set in CONFIG_SITE.linux-arm.linux-arm instead.
# Permit access to 64-bit file-systems
OP_SYS_CFLAGS += -D_FILE_OFFSET_BITS=64

View File

@@ -34,22 +34,17 @@ COMMANDLINE_LIBRARY = $(strip $(if $(wildcard \
#COMMANDLINE_LIBRARY = EPICS
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
# overridden in this file for native builds, e.g. variables such as
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
# They must be set in CONFIG_SITE.linux-x86.linux-x86 instead.
# Permit access to 64-bit file-systems
OP_SYS_CFLAGS += -D_FILE_OFFSET_BITS=64
# Uncomment the followings lines to build with CLANG instead of GCC.
#
#GNU = NO
#CMPLR_CLASS = clang
#CC = clang
#CCC = clang++
# Tune GNU compiler output for a specific 32-bit cpu-type
# (e.g. generic, native, i386, i686, pentium2/3/4, prescott, k6, athlon etc.)
GNU_TUNE_CFLAGS = -mtune=generic
# Developers using a suitable compiler may enable its address sanitizer:
#ENABLE_ASAN = YES

View File

@@ -34,18 +34,14 @@ COMMANDLINE_LIBRARY = $(strip $(if $(wildcard \
#COMMANDLINE_LIBRARY = EPICS
# Uncomment the followings lines to build with CLANG instead of GCC.
#
#GNU = NO
#CMPLR_CLASS = clang
#CC = clang
#CCC = clang++
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
# overridden in this file for native builds, e.g. variables such as
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
# They must be set in CONFIG_SITE.linux-x86_64.linux-x86_64 instead.
# Tune GNU compiler output for a specific 64-bit cpu-type
# (e.g. generic, native, core2, nocona, k8, opteron, athlon64, barcelona etc.)
GNU_TUNE_CFLAGS = -mtune=generic
# Developers using a suitable compiler may enable its address sanitizer:
#ENABLE_ASAN = YES

View File

@@ -2,10 +2,9 @@
#
# Site-specific settings for all linux targets
# WARNING: Variables that are set in $(CONFIG)/CONFIG.gnuCommon cannot be
# overridden in this file for native builds, e.g. variables such as
# OPT_CFLAGS_YES, WARN_CFLAGS, SHRLIB_LDFLAGS
# They must be set in the host+target specific file instead:
# CONFIG_SITE.<linux-arch>.<linux-arch>
# It makes sense to include debugging symbols even in optimized builds
# in case you want to attach gdb to the process or examine a core-dump.
# This does cost disk space, but not memory as debug symbols are not
# loaded into RAM when the binary is loaded.
OPT_CFLAGS_YES += -g
OPT_CXXFLAGS_YES += -g

View File

@@ -6,3 +6,11 @@
# GNU_DIR used when COMMANDLINE_LIBRARY is READLINE
#GNU_DIR=C:/cygwin
# It makes sense to include debugging symbols even in optimized builds
# in case you want to attach gdb to the process or examine a core-dump.
# This does cost disk space, but not memory as debug symbols are not
# loaded into RAM when the binary is loaded.
OPT_CFLAGS_YES += -g
OPT_CXXFLAGS_YES += -g

View File

@@ -0,0 +1,12 @@
# CONFIG_SITE.linux-aarch64.linux-aarch64
#
# Site specific definitions for native linux-aarch64 builds
#-------------------------------------------------------
# It makes sense to include debugging symbols even in optimized builds
# in case you want to attach gdb to the process or examine a core-dump.
# This does cost disk space, but not memory as debug symbols are not
# loaded into RAM when the binary is loaded.
OPT_CFLAGS_YES += -g
OPT_CXXFLAGS_YES += -g

View File

@@ -3,3 +3,17 @@
# Site specific definitions for linux-x86 host - linux-x86 target builds
#-------------------------------------------------------
# It makes sense to include debugging symbols even in optimized builds
# in case you want to attach gdb to the process or examine a core-dump.
# This does cost disk space, but not memory as debug symbols are not
# loaded into RAM when the binary is loaded.
OPT_CFLAGS_YES += -g
OPT_CXXFLAGS_YES += -g
# Uncomment the followings lines to build with CLANG instead of GCC.
#
#GNU = NO
#CMPLR_CLASS = clang
#CC = clang
#CCC = clang++

View File

@@ -3,4 +3,17 @@
# Site specific definitions for linux-x86_64 host - linux-x86_64 target builds
#-------------------------------------------------------
# It makes sense to include debugging symbols even in optimized builds
# in case you want to attach gdb to the process or examine a core-dump.
# This does cost disk space, but not memory as debug symbols are not
# loaded into RAM when the binary is loaded.
OPT_CFLAGS_YES += -g
OPT_CXXFLAGS_YES += -g
# Uncomment the followings lines to build with CLANG instead of GCC.
#
#GNU = NO
#CMPLR_CLASS = clang
#CC = clang
#CCC = clang++

View File

@@ -1,6 +1,6 @@
# Installation Instructions {#install}
## EPICS Base Release 7.0.3.1
## EPICS Base Release 7.0.5
-----
@@ -12,7 +12,6 @@
- [Supported platforms](#0_0_4)
- [Supported compilers](#0_0_5)
- [Software requirements](#0_0_6)
- [Host system storage requirements](#0_0_7)
- [Documentation](#0_0_8)
- [Directory Structure](#0_0_10)
- [Build related components](#0_0_11)
@@ -39,7 +38,7 @@ interfaces) of various types.
Please check the `RELEASE_NOTES` file in the distribution for
description of changes and release migration details.
### <span id="0_0_3">Copyright</span>
### <span id="0_0_3">Copyright Licenses</span>
Please review the LICENSE file included in the distribution for legal
terms of usage.
@@ -68,10 +67,10 @@ path to do EPICS builds; check the definitions of CC and CCC in
**GNU make**
You must use GNU make, gnumake, for any EPICS builds. Set your path so
that a gnumake version 3.81 or later is available.
that a gnumake version 4.1 or later is available.
**Perl**
You must have Perl version 5.8.1 or later installed. The EPICS
You must have Perl version 5.10 or later installed. The EPICS
configuration files do not specify the perl full pathname, so the perl
executable must be found through your normal search path.
@@ -114,13 +113,6 @@ installed on linux-x86. Command-line editing and history will then be
those supplied by the os. On vxWorks the ledLib command-line input
library is used instead.
### <span id="0_0_7">Host system storage requirements</span>
The compressed tar file is approximately 1.6 MB in size. The
distribution source tree takes up approximately 12 MB. Each host
target will need around 40 MB for build files, and each cross-compiled
target around 20 MB.
### <span id="0_0_8">Documentation</span>
EPICS documentation is available through the [EPICS
@@ -237,22 +229,18 @@ Files in the base/startup directory have been provided to help set
required path and other environment variables.
* `EPICS_HOST_ARCH`
Before you can build or use EPICS R3.15, the environment variable
Before you can build or use this EPICS base, the environment variable
`EPICS_HOST_ARCH` must be defined. A perl script EpicsHostArch.pl in
the base/startup directory has been provided to help set
`EPICS_HOST_ARCH.` You should have `EPICS_HOST_ARCH` set to your
host operating system followed by a dash and then your host
architecture, e.g. solaris-sparc. If you are not using the OS
architecture, e.g. linux-x86_64. If you are not using the OS
vendor's c/c++ compiler for host builds, you will need another dash
followed by the alternate compiler name (e.g. "-gnu" for GNU c/c++
compilers on a solaris host or "-mingw" for MinGW c/c++ compilers on
a WIN32 host). See `configure/CONFIG_SITE` for a list of supported
Windows). See `configure/CONFIG_SITE` for a list of supported
`EPICS_HOST_ARCH` values.
* `PERLLIB`
On WIN32, some versions of Perl require that the environment
variable PERLLIB be set to &lt;perl directory location>.
* `PATH`
As already mentioned, you must have the perl executable and you may
need C and C++ compilers in your search path. For building base you
@@ -263,7 +251,7 @@ ranlib in your path, and the C compiler may require as and ld in
your path. On solaris systems you need uname in your path.
* `LD_LIBRARY_PATH`
R3.15 shared libraries and executables normally contain the full
EPICS shared libraries and executables normally contain the full
path to any libraries they require. However, if you move the EPICS
files or directories from their build-time location then in order
for the shared libraries to be found at runtime `LD_LIBRARY_PATH`
@@ -336,10 +324,10 @@ A perl tool, makeBaseApp.pl is included in the distribution file. This
script will create a sample application that can be built and then
executed to try out this release of base.
Instructions for building and executing the 3.15 example application
Instructions for building and executing the EPICS example application
can be found in the section "Example Application" of Chapter 2,
"Getting Started", in the "IOC Application Developer's Guide" for this
release. The "Example IOC Application" section briefly explains how to
"Getting Started", in the "EPICS Application Developer's Guide".
The "Example IOC Application" section briefly explains how to
create and build an example application in a user created &lt;top>
directory. It also explains how to run the example application on a
vxWorks ioc or as a process on the host system. By running the example

View File

@@ -11,11 +11,292 @@ release.
The PVA submodules each have their own individual sets of release notes which
should also be read to understand what has changed since earlier releases.
**This version of EPICS has not been released yet.**
## EPICS Release 7.0.5
## Changes made on the 7.0 branch since 7.0.4.1
### Fix aai's Device Support Initialization
<!-- Insert new items immediately below here ... -->
Krisztian Loki [reported](https://github.com/epics-base/epics-base/issues/97)
segfaults occurring when a Soft Channel aai record INP field was a DB link to
an array field of a compress record. This was caused by the aai record's
pass-0 device support initialization clashing with the semantics of the new
link support API.
The aai record
[has been modified](https://github.com/epics-base/epics-base/pull/114) to
allow the Soft Channel device support to request a pass-1 initialization
callback. See the Device Support section of the Array Analogue Input Record
Reference pages in this release for the API changes, which are fully backwards
compatible for existing aai device support.
### Prevent default DTYPs from changing
[Kay Kasemir reported](https://bugs.launchpad.net/epics-base/+bug/1908305) that
it is possible to change the Base record type's default DTYP if a `device()`
entry is seen before the `recordtype()` definition to which it refers. The
default DTYP is the first device loaded, which is normally the `Soft Channel`
support from Base. A warning was being displayed by dbdExpand when a `device()`
entry was see first, but that was easily missed.
The DBD file parser in dbdExpand.pl has now been modified to make this an error,
although the registerRecordDeviceDriver.pl script will still accept `device()`
entries without having their `recordtype()` loaded since this is necessary to
compile device supports as loadable modules.
### Priority inversion safe Posix mutexes
On Posix systems, epicsMutex now support priority inheritance if available.
The IOC needs to run with SCHED_FIFO engaged to use these.
Support for Posix implementations before POSIX.1-2001 (`_XOPEN_SOURCE < 500`,
glibc version &lt; 2.3.3) has been dropped.
The IOC shell's `epicsMutexShowAll` command prints "PI is enabled" if both
libc and kernel support is present.
### Fix for Periodic Scan threads hanging on Windows
Since 7.0.3.1 a Windows IOC could not run for more than 49.7 days; at that
time the periodic scan threads would stop processing. This issue should now
have been fixed and the Monotonic time functions on Windows should return
values which count at nanosecond resolution. However we have not waited 49.7
days to test the final software, so there is a small chance that it's still
broken.
This fixes [lauchpad bug #1896295](https://bugs.launchpad.net/bugs/1896295).
### Support for Apple M1 (arm64) Processors
Thanks to Jeong Han Lee this release comes with build support for Apple's new
M1 CPUs running macOS, using the target name `darwin-aarch64`.
It should also be possible to build universal binaries containing code for
both the Intel and arm64 processors under either target name: In the
appropriate `configure/os/CONFIG_SITE.Common.darwin-*` file add the other
architecture class name to the `ARCH_CLASS` variable (after a space).
### New String Comparison Routine `epicsStrSimilarity()`
The new `epicsStrSimilarity()` routine in epicsString.h uses a modified
Levenshtein distance to compare two strings, with a character case difference
being half the weight of a full substitution. The double return value falls in
the range 0.0 (identical) through 1.0 (no characters matching), or -1.0 for
error. This is used to provide a new "Did you mean ..." suggestion when a .db
file provides an invalid choice string for a `DBF_MENU` or `DBF_DEVICE` field.
### Build System: New `VALID_BUILDS` type "Command"
Target architectures that support command-line programs that run the `main()`
routine can now be marked as such in their `VALID_BUILDS` definition. This
enables a new set of Makefile target variables `PROD_CMD` (similar to
`PROD_HOST`), `LIBRARY_CMD` (like `LIBRARY_HOST`, etc.), `LOADABLE_LIBRARY_CMD`,
`OBJS_CMD`, `SCRIPTS_CMD`, `TARGETS_CMD`, `TESTLIBRARY_CMD`, `TESTSCRIPTS_CMD`
and `TESTPROD_CMD`. The CA client tools and programs such as `caRepeater` are now built for all such targets (previously they were built for all targets except where the OS was VxWorks, RTEMS and iOS).
If you have created your own site-specific target architectures you may need to
update the `VALID_BUILDS` variable if it gets set in your locally added
`configure/os/CONFIG.Common.<arch>` files. This is usually only needed for
cross-compiled targets though since `CONFIG.Common.UnixCommon` sets it.
The other `VALID_BUILDS` types are "Host" for target architectures that can
compile and run their own programs (`PROD_HOST` etc.), and "Ioc" for targets
that can run IOCs (`PROD_IOC` etc.).
### Support for JSON5
The YAJL parser and generator routines in libcom and in the IOC's dbStatic
parser now support the JSON5 standard. This adds various features to JSON
without altering the API for the code other than adding a new option to the
YAJL parser which can be used to disable JSON5 support if desired. The new
features include:
- The ability to handle numeric values `Infinity`, `-Infinity` and `NaN`.
- String values and map keys may be enclosed in single quotes `'`, inside which
the double-quote character `"` doesn't have to be escaped with a back-slash
`\`, although a single-quote character `'` (or apostrophy) must be escaped
inside a single-quoted string.
- Numbers may start with a plus sign, `+`.
- Integers may be expressed in hexadecimal with a leading `0x` or `0X`.
- Floating-point numbers may start or end with their decimal point `.`
(after the sign or before the exponent respectively if present).
- Map keys that match the regex `[A-Za-z_][A-Za-z_0-9]*` don't have to be
enclosed in quotes at all. The dbStatic parser adds `.+-` to the characters
allowed but will add quotes around such keys before passing them to YAJL.
- Arrays and maps allow a comma before the closing bracket/brace character.
- The YAJL parser will elide a backslash followed by a newline characters from
a string value. The dbStatic parser doesn't allow that however.
Code that must also compile against the older API can use the new C macro
`HAS_JSON5` to detect the new version. This macro is defined on including
either the `yajl_parse.h` or `yajl_gen.h` headers, which also provide the
new configuration options to turn on JSON5 support.
All APIs in the IOC that previously accepted JSON will now accept JSON5.
This includes JSON field modifiers (channel filters), JSON link addresses,
constant input link array values and database info-tag values. JSON values
that get parsed by the dbLoadRecords() routine are still more liberal than
the other uses as the ability to use unquoted strings that was called
"relaxed JSON" is still supported, whereas the JSON5 standard and the YAJL
parser only allow unquoted strings to be used for keys in a JSON map.
This also fixes [lauchpad bug #1714455](https://bugs.launchpad.net/bugs/1714455).
### Character Escape Changes
- The libCom routines `epicsStrnRawFromEscaped()` and `dbTranslateEscape()`
declared in epicsString.h no longer accept octal escaped characters such as
`\123` or `\41`.
- The routine `epicsStrnEscapedFromRaw()` now generates hex
excaped characters for unprintable characters such as `\x1f`.
- Hex escape character sequences `\xXX` must now contain exactly 2 hex digits.
- An escape sequence `\0` now generates a zero byte in the raw string, but the
other digits `1-9` should not appear after a back-slash.
These changes are to more closely follow the JSON5 standard, which doesn't
support octal character escapes or the `\a` (Bel, `\x07`) escape sequence.
### Filters in database input links
Input database links can now use channel filters, it is not necessary to
make them CA links for the filters to work.
### ai Soft Channel support
The Soft Channel device support for ai records now returns failure when
fetching the INP link fails.
### Support for zero-length arrays
Several modifications have been made to properly support zero-length
array values inside the IOC and over Channel Access. Some of these changes
may affect external code that interfaces with the IOC, either directly or
over the CA client API so we recommend thorough testing of any external
code that handles array fields when upgrading to this release.
Since these changes affect the Channel Access client-side API they will
require rebuilding any CA Gateways against this version or Base to
properly handle zero-length arrays. The `caget`, `caput` and `camonitor`
client programs are known to work with empty arrays as long as they were
built with this or a later version of EPICS.
#### Change to the db_access.h `dbr_size_n(TYPE, COUNT)` macro
When called with COUNT=0 this macro no longer returns the number of bytes
required for a scalar (1 element) but for an empty array (0 elements).
Make sure code that uses this doesn't call it with COUNT=0 when it really
means COUNT=1.
Note that the db_access.h header file is included by cadef.h so the change
can impact Channel Access client programs that use this macro.
#### Channel Access support for zero-length arrays
The `ca_array_put()` and `ca_array_put_callback()` routines now accept an
element count of zero, and will write a zero-length array to the PV if
possible. No error will be raised if the target is a scalar field though,
and the field's value will not be changed.
The `ca_array_get_callback()` and `ca_create_subscription()` routines
still accept a count of zero to mean fetch as many elements as the PV
currently holds.
Client programs should be prepared for the `count` fields of any
`struct event_handler_args` or `struct exception_handler_args` passed to
their callback routines to be zero.
#### Array records
The soft device support for the array records aai, waveform, and subArray
as well as the aSub record type now correctly report reading 0 elements
when getting an empty array from an input link.
#### Array support for dbpf
The dbpf command now accepts array values, including empty arrays, when
provided as a JSON string. This must be enclosed in quotes so the iocsh
argument parser sees the JSON as a single argument:
```
epics> dbpf wf10:i32 '[1, 2, 3, 4, 5]'
DBF_LONG[5]: 1 = 0x1 2 = 0x2 3 = 0x3 4 = 0x4 5 = 0x5
```
#### Reading empty arrays as scalar values
Record links that get a scalar value from an array that is currently
empty will cause the record that has the link field to be set to an
`INVALID/LINK` alarm status.
The record code must call `dbGetLink()` with `pnRequest=NULL` for it to
be recognized as a request for a scalar value though.
This changes the semantics of passing `pnRequest=NULL` to `dbGetLink()`,
which now behaves differently than passing it a pointer to a long integer
containing the value 1, which was previously equivalent.
The latter can successfully fetch a zero-element array without triggering
a LINK alarm.
#### Writing empty arrays to scalar fields
Record links that put a zero-element array into a scalar field will now set
the target record to `INVALID/LINK` alarm without changing the field's value.
Previously the field was set to 0 in this case (with no alarm).
The target field must be marked as `special(SPC_DBADDR)` to be recognized
as an array field, and its record support must define a `put_array_info()`
routine.
### Timestamp before processing output links
The record processing code for records with output links has been modified to
update the timestamp via recGblGetTimeStamp() _before_ processing the output
links. This ensures that other records which get processed via an output link
can use TSEL links to fetch the timestamp corresponding to the data processed
by the output link.
This change could result in a slightly earlier timestamp for records whose
output link is handled by a device driver, but only if the device driver does
not handle its own timestamping via TSE -2 and instead uses TSE 0 or TSE -1 to
get current time or best time, and the time spent in the device driver is
greater than your timestamp provider resolution. For these situations it is
recommended to set TSE to -2 and set the timestamp in the driver code.
### Add registerAllRecordDeviceDrivers()
A new iocsh command `registerAllRecordDeviceDrivers` is provided and also
defined as a function in iocshRegisterCommon.h. This uses dynamic symbol
lookup with `epicsFindSymbol()` to perform the same function as a generated
`*_registerRecordDeviceDriver()` function. This allows for an alternative
approach to dynamic loading of support modules without code generation.
This feature is not intended for use by IOCs constructed using the standard
EPICS application build process and booted from a startup script in an iocBoot
subdirectory, although it might work in some of those cases &mdash; the
generated registerRecordDeviceDriver.cpp file is normally required to link
everything referred to in the DBD file into the IOC's executable. It also
won't work with some static build configurations, or if the symbol table has
been stripped from the executable.
### Using a `{const:"string"}` to initialize an array of `DBF_CHAR`
It is now possible to use a JSON Const link with a string value to initialize
an aai or waveform record that has `FTVL` set to `CHAR` through the INP link.
The string length is not limited to 40 characters. This should also work for
aSub record inputs similarly configured as long strings.
```
record(waveform, "wf") {
field(NELM, 100)
field(FTVL, CHAR)
field(INP, {const:"This is a waveform and more than 40 characters"})
}
```
### RELEASE files may use `undefine`
GNUmake added the directive `undefine` in version 3.82 to allow variables to
be undefined. Support for this has been added to the EPICS Release file parser,
so `undefine` can now be used in configure/RELEASE files to unset variables.
-----
## EPICS Release 7.0.4.1
@@ -64,6 +345,8 @@ Bad character ' ' in record name "bad practice"
if a record name begins with a minus, plus, left square bracket,
or left curly bracket.
-----
## EPICS Release 7.0.4
### Bug fixes
@@ -248,6 +531,8 @@ devLsiEtherIP = {
};
```
-----
## EPICS Release 7.0.3.1
**IMPORTANT NOTE:** *Some record types in this release will not be compatible
@@ -441,6 +726,8 @@ necessary, all RTEMS targets should now link although the IOC won't be able to
be used with the VME I/O on those systems (that we don't have VMEbus I/O
support for in libCom).
-----
## EPICS Release 7.0.3
### `epicsTimeGetCurrent()` optimization
@@ -461,6 +748,8 @@ This may result in slightly fewer, but larger frames being sent.
Report NOBT as "precision" through the dbAccess API. This is not accessible
through CA, but is planned to be used through QSRV.
-----
## EPICS Release 7.0.2.2
### Build System changes
@@ -495,6 +784,8 @@ substantial than bug fixes.
Turns out this is ~10x slower to query than `CLOCK_MONOTONIC`.
-----
## EPICS Release 7.0.2.1
### Linking shared libraries on macOS
@@ -546,6 +837,8 @@ rewrite of the link address parser code in dbStaticLib. This release fixes that
issue, although in some cases the output may be slightly different than it used
to be.
-----
## EPICS Release 7.0.2
### Launchpad Bugs
@@ -563,6 +856,8 @@ modules. The layout of the source files has not changed at all however, so the
source code for libcom, ca and the database are still found separately under
the module subdirectory.
-----
## EPICS Release 7.0.1.1
### Changed SIML failure behavior
@@ -621,7 +916,11 @@ than is currently available, but as developers we generally much prefer to
write code than documentation. Send questions to the tech-talk mailing list
and we'll be happy to try and answer them!
## Changes between 3.16.1 and 3.16.2
-----
## Changes made between 3.16.1 and 3.16.2
### Launchpad Bugs
The list of tracked bugs fixed in this release can be found on the
[Launchpad Milestone page for EPICS Base 3.16.2](https://launchpad.net/epics-base/+milestone/3.16.2).
@@ -828,6 +1127,8 @@ array is made even larger; the previous array buffer was not being released
correctly. See Launchpad
[bug #1706703](https://bugs.launchpad.net/epics-base/+bug/1706703).
-----
## Changes made between 3.16.0.1 and 3.16.1
### IOC Database Support for 64-bit integers
@@ -1264,6 +1565,7 @@ and then replace `(RECSUPFUN)` with `RECSUPFUN_CAST` when initializing the
rset. Further changes might also be needed, e.g. to adapt `const`-ness of
method parameters.
-----
## Changes made between 3.15.3 and 3.16.0.1
@@ -1372,6 +1674,8 @@ header and removed the need for dbScan.c to reach into the internals of its
`CALLBACK` objects.
-----
# Changes incorporated from the 3.15 branch
@@ -1383,6 +1687,7 @@ The names of the generated junit xml test output files have been changed
from `<testname>.xml` to `<testname>-results.xml`, to allow better
distinction from other xml files. (I.e., for easy wildcard matching.)
-----
## Changes made between 3.15.7 and 3.15.8
@@ -1488,6 +1793,7 @@ don't provide it any more.
If multiple IOCs were started at the same time, by systemd say, they could race
to obtain the Channel Access TCP port number 5064. This issue has been fixed.
-----
## Changes made between 3.15.6 and 3.15.7
@@ -1631,6 +1937,8 @@ into the htmls directory. Thanks to Tony Pietryla.
This displays the version numbers of EPICS Base and the CA protocol.
-----
## Changes made between 3.15.5 and 3.15.6
### Unsetting environment variables
@@ -1856,6 +2164,8 @@ choice string cannot be parsed, the associated periodic scan thread will no
longer be started by the IOC and a warning message will be displayed at iocInit
time. The `scanppl` command will also flag the faulty menuScan value.
-----
## Changes made between 3.15.4 and 3.15.5
### dbStatic Library Speedup and Cleanup
@@ -1987,6 +2297,8 @@ will be installed into the target bin directory, from where it can be copied
into the appropriate systemd location and modified as necessary. Installation
instructions are included as comments in the file.
-----
## Changes made between 3.15.3 and 3.15.4
### New string input device support "getenv"
@@ -2092,6 +2404,8 @@ variable to a non-zero value before loading the file, like this:
This was [Launchpad bug
541119](https://bugs.launchpad.net/bugs/541119).
-----
## Changes from the 3.14 branch between 3.15.3 and 3.15.4
### NTP Time Provider adjusts to OS tick rate changes

View File

@@ -1,9 +1,12 @@
# Record Reference Documentation {#recordrefmanual}
The following documentation for the record types and menus include with Base was
The documentation below for the record types and menus included with Base was
converted from the old EPICS Wiki pages and updated. This list only includes the
record types supplied with Base.
record types supplied with Base. The first two links below are to an external
website where these original reference chapters are now being published.
* [Introduction to EPICS](https://docs.epics-controls.org/en/latest/guides/EPICS_Intro.html)
* [Process Database Concepts](https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html)
* [Fields Common to All Record Types](dbCommonRecord.html)
* [Fields Common to Input Record Types](dbCommonInput.html)
* [Fields Common to Output Record Types](dbCommonOutput.html)
@@ -35,7 +38,7 @@ record types supplied with Base.
* [Multi-Bit Binary Output Direct Record (mbboDirect)](mbboDirectRecord.html)
* [Multi-Bit Binary Output Record (mbbo)](mbboRecord.html)
* [Permissive Record (permissive)](permissiveRecord.html)
* [Printf Record (prinf)](printfRecord.html)
* [Printf Record (printf)](printfRecord.html)
* [Select Record (sel)](selRecord.html)
* [Sequence Record (seq)](seqRecord.html)
* [State Record (state)](stateRecord.html)
@@ -53,6 +56,9 @@ record types supplied with Base.
* [Field Type Menu](menuFtype.html)
* [Invalid Value Output Action Menu](menuIvoa.html)
* [Output Mode Select Menu](menuOmsl.html)
* [Process at iocInit Menu](menuPini.html)
* [Post Monitors Menu](menuPost.html)
* [Priority Menu](menuPriority.html)
* [Scan Menu](menuScan.html)
* [Simulation Mode Menu](menuSimm.html)
* [Yes/No Menu](menuYesNo.html)

View File

@@ -147,17 +147,17 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
<td>Tag the module in Git, using these tag conventions:
<ul>
<li>
<tt>R7.0.4.1-pre<i>n</i></tt>
<tt>R7.0.5-pre<i>n</i></tt>
&mdash; pre-release tag
</li>
<li>
<tt>R7.0.4.1-rc<i>n</i></tt>
<tt>R7.0.5-rc<i>n</i></tt>
&mdash; release candidate tag
</li>
</ul>
<blockquote><tt>
cd base-7.0<br />
git tag -m 'ANJ: Tagged for 7.0.4.1-rc1' R7.0.4.1-rc1
git tag -m 'ANJ: Tagged for 7.0.5-rc1' R7.0.5-rc1
</tt></blockquote>
Note that submodules must <em>not</em> be tagged with the version used
for the top-level, they each have their own separate version numbers
@@ -171,11 +171,11 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
files and directories that are only used for continuous integration:
<blockquote><tt>
cd base-7.0<br />
./.tools/make-tar.sh R7.0.4.1-rc1 base-7.0.4.1-rc1.tar.gz base-7.0.4.1-rc1/
./.tools/make-tar.sh R7.0.5-rc1 base-7.0.5-rc1.tar.gz base-7.0.5-rc1/
</tt></blockquote>
Create a GPG signature file of the tarfile as follows:
<blockquote><tt>
gpg --armor --sign --detach-sig base-7.0.4.1-rc1.tar.gz
gpg --armor --sign --detach-sig base-7.0.5-rc1.tar.gz
</tt></blockquote>
</td>
</tr>
@@ -298,7 +298,7 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
<li>Tag the module:
<blockquote><tt>
git tag -m 'ANJ: Tag for EPICS 7.0.4.1' &lt;module-version&gt;
git tag -m 'ANJ: Tag for EPICS 7.0.5' &lt;module-version&gt;
</tt></blockquote>
</li>
@@ -355,7 +355,7 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
<td>Tag the epics-base module in Git:
<blockquote><tt>
cd base-7.0<br />
git tag -m 'ANJ: Tagged for release' R7.0.4.1
git tag -m 'ANJ: Tagged for release' R7.0.5
</tt></blockquote>
<p>Don't push these commits or the new tag to the Launchpad repository
yet.</p>
@@ -387,12 +387,12 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
files and directories that are only used for continuous integration:
<blockquote><tt>
cd base-7.0<br />
./.tools/make-tar.sh R7.0.4.1 ../base-7.0.4.1.tar.gz base-7.0.4.1/
./.tools/make-tar.sh R7.0.5 ../base-7.0.5.tar.gz base-7.0.5/
</tt></blockquote>
Create a GPG signature file of the tarfile as follows:
<blockquote><tt>
cd ..<br />
gpg --armor --sign --detach-sig base-7.0.4.1.tar.gz
gpg --armor --sign --detach-sig base-7.0.5.tar.gz
</tt></blockquote>
</td>
</tr>
@@ -457,7 +457,7 @@ starting at <a href="#ReleaseApproval">Release Approval</a>.</p>
<td>Upload the tar file and its <tt>.asc</tt> signature file to the
epics-controls web-server.
<blockquote><tt>
scp base-7.0.4.1.tar.gz base-7.0.4.1.tar.gz.asc epics-controls:download/base<br />
scp base-7.0.5.tar.gz base-7.0.5.tar.gz.asc epics-controls:download/base<br />
</tt></blockquote>
</td>
</tr>

View File

@@ -95,10 +95,7 @@ PROD_LIBS = ca Com
# needed when its an object library build
PROD_SYS_LIBS_WIN32 = ws2_32 advapi32 user32
PROD_DEFAULT += caRepeater catime acctst caConnTest casw caEventRate
PROD_vxWorks = -nil-
PROD_RTEMS = -nil-
PROD_iOS = -nil-
PROD_CMD += caRepeater catime acctst caConnTest casw caEventRate
OBJS_vxWorks = catime acctst caConnTest casw caEventRate acctstRegister

View File

@@ -153,13 +153,13 @@ ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) :
this->localPort = htons ( tmpAddr.ia.sin_port );
}
std::auto_ptr < CallbackGuard > pCBGuard;
ca::auto_ptr < CallbackGuard > pCBGuard;
if ( ! enablePreemptiveCallback ) {
pCBGuard.reset ( new CallbackGuard ( this->cbMutex ) );
}
// multiple steps ensure exception safety
this->pCallbackGuard = pCBGuard;
this->pCallbackGuard = PTRMOVE(pCBGuard);
}
ca_client_context::~ca_client_context ()

View File

@@ -517,7 +517,7 @@ struct dbr_ctrl_double{
};
#define dbr_size_n(TYPE,COUNT)\
((unsigned)((COUNT)<=0?dbr_size[TYPE]:dbr_size[TYPE]+((COUNT)-1)*dbr_value_size[TYPE]))
((unsigned)((COUNT)<0?dbr_size[TYPE]:dbr_size[TYPE]+((COUNT)-1)*dbr_value_size[TYPE]))
/* size for each type - array indexed by the DBR_ type code */
LIBCA_API extern const unsigned short dbr_size[];

View File

@@ -329,7 +329,7 @@ void nciu::write (
if ( ! this->accessRightState.writePermit() ) {
throw cacChannel::noWriteAccess();
}
if ( countIn > this->count || countIn == 0 ) {
if ( countIn > this->count) {
throw cacChannel::outOfBounds();
}
if ( type == DBR_STRING ) {
@@ -350,7 +350,7 @@ cacChannel::ioStatus nciu::write (
if ( ! this->accessRightState.writePermit() ) {
throw cacChannel::noWriteAccess();
}
if ( countIn > this->count || countIn == 0 ) {
if ( countIn > this->count) {
throw cacChannel::outOfBounds();
}
if ( type == DBR_STRING ) {

View File

@@ -38,6 +38,17 @@
#include "cadef.h"
#include "syncGroup.h"
namespace ca {
#if __cplusplus>=201103L
template<typename T>
using auto_ptr = std::unique_ptr<T>;
#define PTRMOVE(AUTO) std::move(AUTO)
#else
using std::auto_ptr;
#define PTRMOVE(AUTO) (AUTO)
#endif
}
struct oldChannelNotify : private cacChannelNotify {
public:
oldChannelNotify (
@@ -393,8 +404,8 @@ private:
epicsEvent ioDone;
epicsEvent callbackThreadActivityComplete;
epicsThreadId createdByThread;
std::auto_ptr < CallbackGuard > pCallbackGuard;
std::auto_ptr < cacContext > pServiceContext;
ca::auto_ptr < CallbackGuard > pCallbackGuard;
ca::auto_ptr < cacContext > pServiceContext;
caExceptionHandler * ca_exception_func;
void * ca_exception_arg;
caPrintfFunc * pVPrintfFunc;

View File

@@ -40,6 +40,17 @@
#include "repeaterSubscribeTimer.h"
#include "SearchDest.h"
namespace ca {
#if __cplusplus>=201103L
template<typename T>
using auto_ptr = std::unique_ptr<T>;
#define PTRMOVE(AUTO) std::move(AUTO)
#else
using std::auto_ptr;
#define PTRMOVE(AUTO) (AUTO)
#endif
}
extern "C" void cacRecvThreadUDP ( void *pParam );
LIBCA_API void epicsStdCall caStartRepeaterIfNotInstalled (
@@ -161,7 +172,7 @@ private:
epicsMutex & cacMutex;
const unsigned nTimers;
struct SearchArray {
typedef std::auto_ptr <searchTimer> value_type;
typedef ca::auto_ptr <searchTimer> value_type;
value_type *arr;
SearchArray(size_t n) : arr(new value_type[n]) {}
~SearchArray() { delete[] arr; }

View File

@@ -13,10 +13,7 @@ TOP = ../../../..
include $(TOP)/configure/CONFIG
PROD_DEFAULT += caget camonitor cainfo caput
PROD_vxWorks = -nil-
PROD_RTEMS = -nil-
PROD_iOS = -nil-
PROD_CMD = caget camonitor cainfo caput
PROD_SRCS = tool_lib.c

View File

@@ -946,13 +946,18 @@ long dbGet(DBADDR *paddr, short dbrType,
if (offset == 0 && (!nRequest || no_elements == 1)) {
if (nRequest)
*nRequest = 1;
else if (no_elements < 1) {
status = S_db_onlyOne;
goto done;
}
if (!pfl || pfl->type == dbfl_type_rec) {
status = dbFastGetConvertRoutine[field_type][dbrType]
(paddr->pfield, pbuf, paddr);
} else {
DBADDR localAddr = *paddr; /* Structure copy */
if (pfl->no_elements < 1) {
if (no_elements < 1) {
status = S_db_badField;
goto done;
}
@@ -996,6 +1001,11 @@ long dbGet(DBADDR *paddr, short dbrType,
} else {
DBADDR localAddr = *paddr; /* Structure copy */
if (pfl->no_elements < 1) {
status = S_db_badField;
goto done;
}
localAddr.field_type = pfl->field_type;
localAddr.field_size = pfl->field_size;
localAddr.no_elements = pfl->no_elements;
@@ -1037,7 +1047,7 @@ static long dbPutFieldLink(DBADDR *paddr,
short dbrType, const void *pbuffer, long nRequest)
{
dbLinkInfo link_info;
DBADDR *pdbaddr = NULL;
dbChannel *chan = NULL;
dbCommon *precord = paddr->precord;
dbCommon *lockrecs[2];
dbLocker locker;
@@ -1075,16 +1085,11 @@ static long dbPutFieldLink(DBADDR *paddr,
if (link_info.ltype == PV_LINK &&
(link_info.modifiers & (pvlOptCA | pvlOptCP | pvlOptCPP)) == 0) {
DBADDR tempaddr;
if (dbNameToAddr(link_info.target, &tempaddr)==0) {
/* This will become a DB link. */
pdbaddr = malloc(sizeof(*pdbaddr));
if (!pdbaddr) {
status = S_db_noMemory;
goto cleanup;
}
*pdbaddr = tempaddr; /* struct copy */
chan = dbChannelCreate(link_info.target);
if (chan && dbChannelOpen(chan) != 0) {
errlogPrintf("ERROR: dbPutFieldLink %s.%s=%s: dbChannelOpen() failed\n",
precord->name, pfldDes->name, link_info.target);
goto cleanup;
}
}
@@ -1093,7 +1098,7 @@ static long dbPutFieldLink(DBADDR *paddr,
memset(&locker, 0, sizeof(locker));
lockrecs[0] = precord;
lockrecs[1] = pdbaddr ? pdbaddr->precord : NULL;
lockrecs[1] = chan ? dbChannelRecord(chan) : NULL;
dbLockerPrepare(&locker, lockrecs, 2);
dbScanLockMany(&locker);
@@ -1181,7 +1186,8 @@ static long dbPutFieldLink(DBADDR *paddr,
case PV_LINK:
case CONSTANT:
case JSON_LINK:
dbAddLink(&locker, plink, pfldDes->field_type, pdbaddr);
dbAddLink(&locker, plink, pfldDes->field_type, chan);
chan = NULL; /* don't clean it up */
break;
case DB_LINK:
@@ -1211,6 +1217,8 @@ unlock:
dbScanUnlockMany(&locker);
dbLockerFinalize(&locker);
cleanup:
if (chan)
dbChannelDelete(chan);
free(link_info.target);
return status;
}
@@ -1330,25 +1338,21 @@ long dbPut(DBADDR *paddr, short dbrType,
status = prset->get_array_info(paddr, &dummy, &offset);
/* paddr->pfield may be modified */
if (status) goto done;
} else
offset = 0;
if (no_elements <= 1) {
status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer,
paddr->pfield, paddr);
nRequest = 1;
} else {
if (no_elements < nRequest)
nRequest = no_elements;
status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer,
nRequest, no_elements, offset);
}
/* update array info */
if (!status &&
paddr->pfldDes->special == SPC_DBADDR &&
prset && prset->put_array_info) {
status = prset->put_array_info(paddr, nRequest);
/* update array info */
if (!status && prset->put_array_info)
status = prset->put_array_info(paddr, nRequest);
} else {
if (nRequest < 1) {
recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM);
} else {
status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer,
paddr->pfield, paddr);
nRequest = 1;
}
}
/* Always do special processing if needed */

View File

@@ -173,9 +173,8 @@ struct dbr_alDouble {DBRalDouble};
#define dbr_alLong_size sizeof(struct dbr_alLong)
#define dbr_alDouble_size sizeof(struct dbr_alDouble)
#ifndef INCerrMdefh
#include "errMdef.h"
#endif
#define S_db_notFound (M_dbAccess| 1) /*Process Variable Not Found*/
#define S_db_badDbrtype (M_dbAccess| 3) /*Illegal Database Request Type*/
#define S_db_noMod (M_dbAccess| 5) /*Attempt to modify noMod field*/

View File

@@ -48,6 +48,17 @@
#include "db_convert.h"
#include "resourceLib.h"
namespace ca {
#if __cplusplus>=201103L
template<typename T>
using auto_ptr = std::unique_ptr<T>;
#define PTRMOVE(AUTO) std::move(AUTO)
#else
using std::auto_ptr;
#define PTRMOVE(AUTO) (AUTO)
#endif
}
extern "C" int putNotifyPut ( processNotify *ppn, notifyPutType notifyPutType );
extern "C" void putNotifyCompletion ( processNotify *ppn );
@@ -194,7 +205,7 @@ private:
epicsMutex & mutex;
epicsMutex & cbMutex;
cacContextNotify & notify;
std::auto_ptr < cacContext > pNetContext;
ca::auto_ptr < cacContext > pNetContext;
char * pStateNotifyCache;
bool isolated;

View File

@@ -411,9 +411,15 @@ long dbCaGetLink(struct link *plink, short dbrType, void *pdest,
goto done;
}
newType = dbDBRoldToDBFnew[pca->dbrType];
if (!nelements || *nelements == 1) {
if (!nelements) {
long (*fConvert)(const void *from, void *to, struct dbAddr *paddr);
if (pca->usedelements < 1) {
pca->sevr = INVALID_ALARM;
pca->stat = LINK_ALARM;
status = -1;
goto done;
}
fConvert = dbFastGetConvertRoutine[newType][dbrType];
assert(pca->pgetNative);
status = fConvert(pca->pgetNative, pdest, 0);

View File

@@ -18,6 +18,8 @@
#include <stddef.h>
#include <string.h>
#define EPICS_PRIVATE_API
#include "cantProceed.h"
#include "epicsAssert.h"
#include "epicsString.h"
@@ -68,6 +70,7 @@ void dbChannelInit (void)
freeListInitPvt(&dbChannelFreeList, sizeof(dbChannel), 128);
freeListInitPvt(&chFilterFreeList, sizeof(chFilter), 64);
freeListInitPvt(&dbchStringFreeList, sizeof(epicsOldString), 128);
db_init_event_freelists();
}
static void chf_value(parseContext *parser, parse_result *presult)

View File

@@ -169,6 +169,9 @@ static long dbConstLoadScalar(struct link *plink, short dbrType, void *pbuffer)
return dbPutConvertJSON(pstr, dbrType, pbuffer, &nReq);
}
if(dbrType>=NELEMENTS(convert))
return S_db_badDbrtype;
return convert[dbrType](pstr, pbuffer, NULL);
}

View File

@@ -71,7 +71,7 @@ dbContext::dbContext ( epicsMutex & cbMutexIn,
epicsMutex & mutexIn, cacContextNotify & notifyIn ) :
readNotifyCache ( mutexIn ), ctx ( 0 ),
stateNotifyCacheSize ( 0 ), mutex ( mutexIn ), cbMutex ( cbMutexIn ),
notify ( notifyIn ), pNetContext ( 0 ), pStateNotifyCache ( 0 ),
notify ( notifyIn ), pStateNotifyCache ( 0 ),
isolated(dbServiceIsolate)
{
}

View File

@@ -61,6 +61,7 @@
#include "dbConvertFast.h"
#include "dbConvert.h"
#include "db_field_log.h"
#include "db_access_routines.h"
#include "dbFldTypes.h"
#include "dbLink.h"
#include "dbLockPvt.h"
@@ -74,7 +75,7 @@
#include "recSup.h"
#include "special.h"
#include "dbDbLink.h"
#include "dbChannel.h"
/***************************** Database Links *****************************/
@@ -83,45 +84,51 @@ static lset dbDb_lset;
static long processTarget(dbCommon *psrc, dbCommon *pdst);
#define linkChannel(plink) ((dbChannel *) (plink)->value.pv_link.pvt)
long dbDbInitLink(struct link *plink, short dbfType)
{
DBADDR dbaddr;
long status;
DBADDR *pdbAddr;
dbChannel *chan;
dbCommon *precord;
status = dbNameToAddr(plink->value.pv_link.pvname, &dbaddr);
chan = dbChannelCreate(plink->value.pv_link.pvname);
if (!chan)
return S_db_notFound;
status = dbChannelOpen(chan);
if (status)
return status;
precord = dbChannelRecord(chan);
plink->lset = &dbDb_lset;
plink->type = DB_LINK;
pdbAddr = dbCalloc(1, sizeof(struct dbAddr));
*pdbAddr = dbaddr; /* structure copy */
plink->value.pv_link.pvt = pdbAddr;
ellAdd(&dbaddr.precord->bklnk, &plink->value.pv_link.backlinknode);
plink->value.pv_link.pvt = chan;
ellAdd(&precord->bklnk, &plink->value.pv_link.backlinknode);
/* merging into the same lockset is deferred to the caller.
* cf. initPVLinks()
*/
dbLockSetMerge(NULL, plink->precord, dbaddr.precord);
assert(plink->precord->lset->plockSet == dbaddr.precord->lset->plockSet);
dbLockSetMerge(NULL, plink->precord, precord);
assert(plink->precord->lset->plockSet == precord->lset->plockSet);
return 0;
}
void dbDbAddLink(struct dbLocker *locker, struct link *plink, short dbfType,
DBADDR *ptarget)
dbChannel *chan)
{
plink->lset = &dbDb_lset;
plink->type = DB_LINK;
plink->value.pv_link.pvt = ptarget;
ellAdd(&ptarget->precord->bklnk, &plink->value.pv_link.backlinknode);
plink->value.pv_link.pvt = chan;
ellAdd(&dbChannelRecord(chan)->bklnk, &plink->value.pv_link.backlinknode);
/* target record is already locked in dbPutFieldLink() */
dbLockSetMerge(locker, plink->precord, ptarget->precord);
dbLockSetMerge(locker, plink->precord, dbChannelRecord(chan));
}
static void dbDbRemoveLink(struct dbLocker *locker, struct link *plink)
{
DBADDR *pdbAddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
dbCommon *precord = dbChannelRecord(chan);
plink->type = PV_LINK;
@@ -131,10 +138,10 @@ static void dbDbRemoveLink(struct dbLocker *locker, struct link *plink)
plink->value.pv_link.getCvt = 0;
plink->value.pv_link.pvlMask = 0;
plink->value.pv_link.lastGetdbrType = 0;
ellDelete(&pdbAddr->precord->bklnk, &plink->value.pv_link.backlinknode);
dbLockSetSplit(locker, plink->precord, pdbAddr->precord);
ellDelete(&precord->bklnk, &plink->value.pv_link.backlinknode);
dbLockSetSplit(locker, plink->precord, precord);
}
free(pdbAddr);
dbChannelDelete(chan);
}
static int dbDbIsConnected(const struct link *plink)
@@ -144,16 +151,14 @@ static int dbDbIsConnected(const struct link *plink)
static int dbDbGetDBFtype(const struct link *plink)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
return paddr->field_type;
dbChannel *chan = linkChannel(plink);
return dbChannelFinalFieldType(chan);
}
static long dbDbGetElements(const struct link *plink, long *nelements)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
*nelements = paddr->no_elements;
dbChannel *chan = linkChannel(plink);
*nelements = dbChannelFinalElements(chan);
return 0;
}
@@ -161,47 +166,75 @@ static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer,
long *pnRequest)
{
struct pv_link *ppv_link = &plink->value.pv_link;
DBADDR *paddr = ppv_link->pvt;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
dbCommon *precord = plink->precord;
db_field_log *pfl = NULL;
long status;
/* scan passive records if link is process passive */
if (ppv_link->pvlMask & pvlOptPP) {
status = dbScanPassive(precord, paddr->precord);
status = dbScanPassive(precord, dbChannelRecord(chan));
if (status)
return status;
}
if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType) {
status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr);
} else {
unsigned short dbfType = paddr->field_type;
if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType)
{
/* shortcut: scalar with known conversion, no filter */
status = ppv_link->getCvt(dbChannelField(chan), pbuffer, paddr);
}
else if (dbChannelFinalElements(chan) == 1 && (!pnRequest || *pnRequest == 1)
&& dbChannelSpecial(chan) != SPC_DBADDR
&& dbChannelSpecial(chan) != SPC_ATTRIBUTE
&& ellCount(&chan->filters) == 0)
{
/* simple scalar: set up shortcut */
unsigned short dbfType = dbChannelFinalFieldType(chan);
if (dbrType < 0 || dbrType > DBR_ENUM || dbfType > DBF_DEVICE)
return S_db_badDbrtype;
if (paddr->no_elements == 1 && (!pnRequest || *pnRequest == 1)
&& paddr->special != SPC_DBADDR
&& paddr->special != SPC_ATTRIBUTE) {
ppv_link->getCvt = dbFastGetConvertRoutine[dbfType][dbrType];
status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr);
} else {
ppv_link->getCvt = NULL;
status = dbGet(paddr, dbrType, pbuffer, NULL, pnRequest, NULL);
}
ppv_link->getCvt = dbFastGetConvertRoutine[dbfType][dbrType];
ppv_link->lastGetdbrType = dbrType;
status = ppv_link->getCvt(dbChannelField(chan), pbuffer, paddr);
}
else
{
/* filter, array, or special */
ppv_link->getCvt = NULL;
if (ellCount(&chan->filters)) {
/* If filters are involved in a read, create field log and run filters */
pfl = db_create_read_log(chan);
if (!pfl)
return S_db_noMemory;
pfl = dbChannelRunPreChain(chan, pfl);
pfl = dbChannelRunPostChain(chan, pfl);
}
status = dbChannelGet(chan, dbrType, pbuffer, NULL, pnRequest, pfl);
if (pfl)
db_delete_field_log(pfl);
if (status)
return status;
}
if (!status && precord != paddr->precord)
if (!status && precord != dbChannelRecord(chan))
recGblInheritSevr(plink->value.pv_link.pvlMask & pvlOptMsMode,
plink->precord, paddr->precord->stat, paddr->precord->sevr);
plink->precord,
dbChannelRecord(chan)->stat, dbChannelRecord(chan)->sevr);
return status;
}
static long dbDbGetControlLimits(const struct link *plink, double *low,
double *high)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRctrlDouble
double value;
@@ -222,7 +255,8 @@ static long dbDbGetControlLimits(const struct link *plink, double *low,
static long dbDbGetGraphicLimits(const struct link *plink, double *low,
double *high)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRgrDouble
double value;
@@ -243,7 +277,8 @@ static long dbDbGetGraphicLimits(const struct link *plink, double *low,
static long dbDbGetAlarmLimits(const struct link *plink, double *lolo,
double *low, double *high, double *hihi)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRalDouble
double value;
@@ -265,7 +300,8 @@ static long dbDbGetAlarmLimits(const struct link *plink, double *lolo,
static long dbDbGetPrecision(const struct link *plink, short *precision)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRprecision
double value;
@@ -284,7 +320,8 @@ static long dbDbGetPrecision(const struct link *plink, short *precision)
static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
DBADDR *paddr = &chan->addr;
struct buffer {
DBRunits
double value;
@@ -304,20 +341,20 @@ static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize)
static long dbDbGetAlarm(const struct link *plink, epicsEnum16 *status,
epicsEnum16 *severity)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
dbChannel *chan = linkChannel(plink);
dbCommon *precord = dbChannelRecord(chan);
if (status)
*status = paddr->precord->stat;
*status = precord->stat;
if (severity)
*severity = paddr->precord->sevr;
*severity = precord->sevr;
return 0;
}
static long dbDbGetTimeStamp(const struct link *plink, epicsTimeStamp *pstamp)
{
DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt;
*pstamp = paddr->precord->time;
dbChannel *chan = linkChannel(plink);
dbCommon *precord = dbChannelRecord(chan);
*pstamp = precord->time;
return 0;
}
@@ -325,9 +362,10 @@ static long dbDbPutValue(struct link *plink, short dbrType,
const void *pbuffer, long nRequest)
{
struct pv_link *ppv_link = &plink->value.pv_link;
dbChannel *chan = linkChannel(plink);
struct dbCommon *psrce = plink->precord;
DBADDR *paddr = (DBADDR *) ppv_link->pvt;
dbCommon *pdest = paddr->precord;
DBADDR *paddr = &chan->addr;
dbCommon *pdest = dbChannelRecord(chan);
long status = dbPut(paddr, dbrType, pbuffer, nRequest);
recGblInheritSevr(ppv_link->pvlMask & pvlOptMsMode, pdest, psrce->nsta,
@@ -335,7 +373,7 @@ static long dbDbPutValue(struct link *plink, short dbrType,
if (status)
return status;
if (paddr->pfield == (void *) &pdest->proc ||
if (dbChannelField(chan) == (void *) &pdest->proc ||
(ppv_link->pvlMask & pvlOptPP && pdest->scan == 0)) {
status = processTarget(psrce, pdest);
}
@@ -346,9 +384,8 @@ static long dbDbPutValue(struct link *plink, short dbrType,
static void dbDbScanFwdLink(struct link *plink)
{
dbCommon *precord = plink->precord;
dbAddr *paddr = (dbAddr *) plink->value.pv_link.pvt;
dbScanPassive(precord, paddr->precord);
dbChannel *chan = linkChannel(plink);
dbScanPassive(precord, dbChannelRecord(chan));
}
static long doLocked(struct link *plink, dbLinkUserCallback rtn, void *priv)

View File

@@ -27,7 +27,7 @@ struct dbLocker;
epicsShareFunc long dbDbInitLink(struct link *plink, short dbfType);
epicsShareFunc void dbDbAddLink(struct dbLocker *locker, struct link *plink,
short dbfType, DBADDR *ptarget);
short dbfType, dbChannel *ptarget);
#ifdef __cplusplus
}

View File

@@ -252,18 +252,15 @@ int dbel ( const char *pname, unsigned level )
}
/*
* DB_INIT_EVENTS()
* DB_INIT_EVENT_FREELISTS()
*
*
* Initialize the event facility for this task. Must be called at least once
* by each task which uses the db event facility
* Initialize the free lists used by the event facility.
* Safe to be called multiple times.
*
* returns: ptr to event user block or NULL if memory can't be allocated
*/
dbEventCtx db_init_events (void)
void db_init_event_freelists (void)
{
struct event_user * evUser;
if (!dbevEventUserFreeList) {
freeListInitPvt(&dbevEventUserFreeList,
sizeof(struct event_user),8);
@@ -280,6 +277,22 @@ dbEventCtx db_init_events (void)
freeListInitPvt(&dbevFieldLogFreeList,
sizeof(struct db_field_log),2048);
}
}
/*
* DB_INIT_EVENTS()
*
*
* Initialize the event facility for this task. Must be called at least once
* by each task which uses the db event facility
*
* returns: ptr to event user block or NULL if memory can't be allocated
*/
dbEventCtx db_init_events (void)
{
struct event_user * evUser;
db_init_event_freelists();
evUser = (struct event_user *)
freeListCalloc(dbevEventUserFreeList);
@@ -1048,7 +1061,11 @@ static void event_task (void *pParm)
epicsEventDestroy(evUser->pflush_sem);
epicsMutexDestroy(evUser->lock);
freeListFree(dbevEventUserFreeList, evUser);
if (dbevEventUserFreeList)
freeListFree(dbevEventUserFreeList, evUser);
else
fprintf(stderr, "%s exiting but dbevEventUserFreeList already NULL\n",
__FUNCTION__);
taskwdRemove(epicsThreadGetIdSelf());

View File

@@ -66,6 +66,7 @@ epicsShareFunc void db_event_change_priority ( dbEventCtx ctx, unsigned epicsPri
#ifdef EPICS_PRIVATE_API
epicsShareFunc void db_cleanup_events(void);
epicsShareFunc void db_init_event_freelists (void);
#endif
typedef void EVENTFUNC (void *user_arg, struct dbChannel *chan,

View File

@@ -144,7 +144,7 @@ void dbInitLink(struct link *plink, short dbfType)
}
void dbAddLink(struct dbLocker *locker, struct link *plink, short dbfType,
DBADDR *ptarget)
dbChannel *ptarget)
{
struct dbCommon *precord = plink->precord;

View File

@@ -21,6 +21,7 @@
#include "epicsTypes.h"
#include "epicsTime.h"
#include "dbAddr.h"
#include "dbChannel.h"
#ifdef __cplusplus
extern "C" {
@@ -369,7 +370,7 @@ epicsShareFunc const char * dbLinkFieldName(const struct link *plink);
epicsShareFunc void dbInitLink(struct link *plink, short dbfType);
epicsShareFunc void dbAddLink(struct dbLocker *locker, struct link *plink,
short dbfType, DBADDR *ptarget);
short dbfType, dbChannel *ptarget);
epicsShareFunc void dbLinkOpen(struct link *plink);
epicsShareFunc void dbRemoveLink(struct dbLocker *locker, struct link *plink);

View File

@@ -743,14 +743,14 @@ void dbLockSetSplit(dbLocker *locker, dbCommon *pfirst, dbCommon *psecond)
for(i=0; i<rtype->no_links; i++) {
dbFldDes *pdesc = rtype->papFldDes[rtype->link_ind[i]];
DBLINK *plink = (DBLINK*)((char*)prec + pdesc->offset);
DBADDR *ptarget;
dbChannel *chan;
lockRecord *lr;
if(plink->type!=DB_LINK)
continue;
ptarget = plink->value.pv_link.pvt;
lr = ptarget->precord->lset;
chan = plink->value.pv_link.pvt;
lr = dbChannelRecord(chan)->lset;
assert(lr);
if(lr->precord==pfirst) {

View File

@@ -1076,13 +1076,10 @@ static void addToList(struct dbCommon *precord, scan_list *psl)
pse->pscan_list = psl;
ptemp = (scan_element *)ellLast(&psl->list);
while (ptemp) {
if (ptemp->precord->phas <= precord->phas) {
ellInsert(&psl->list, &ptemp->node, &pse->node);
break;
}
if (ptemp->precord->phas <= precord->phas) break;
ptemp = (scan_element *)ellPrevious(&ptemp->node);
}
if (ptemp == NULL) ellAdd(&psl->list, (void *)pse);
ellInsert(&psl->list, (ptemp ? &ptemp->node : NULL), &pse->node);
psl->modified = TRUE;
epicsMutexUnlock(psl->lock);
}
@@ -1108,7 +1105,7 @@ static void deleteFromList(struct dbCommon *precord, scan_list *psl)
return;
}
pse->pscan_list = NULL;
ellDelete(&psl->list, (void *)pse);
ellDelete(&psl->list, &pse->node);
psl->modified = TRUE;
epicsMutexUnlock(psl->lock);
}

View File

@@ -41,6 +41,7 @@
#include "recGbl.h"
#include "recSup.h"
#include "special.h"
#include "dbConvertJSON.h"
#define MAXLINE 80
#define MAXMESS 128
@@ -364,8 +365,9 @@ long dbpf(const char *pname,const char *pvalue)
{
DBADDR addr;
long status;
short dbrType;
size_t n = 1;
short dbrType = DBR_STRING;
long n = 1;
char *array = NULL;
if (!pname || !*pname || !pvalue) {
printf("Usage: dbpf \"pv name\", \"value\"\n");
@@ -380,16 +382,25 @@ long dbpf(const char *pname,const char *pvalue)
return -1;
}
if (addr.no_elements > 1 &&
(addr.dbr_field_type == DBR_CHAR || addr.dbr_field_type == DBR_UCHAR)) {
if (addr.no_elements > 1) {
dbrType = addr.dbr_field_type;
n = strlen(pvalue) + 1;
if (addr.dbr_field_type == DBR_CHAR || addr.dbr_field_type == DBR_UCHAR) {
n = (long)strlen(pvalue) + 1;
} else {
n = addr.no_elements;
array = calloc(n, dbValueSize(dbrType));
if (!array) {
printf("Out of memory\n");
return -1;
}
status = dbPutConvertJSON(pvalue, dbrType, array, &n);
if (status)
return status;
pvalue = array;
}
}
else {
dbrType = DBR_STRING;
}
status = dbPutField(&addr, dbrType, pvalue, (long) n);
status = dbPutField(&addr, dbrType, pvalue, n);
free(array);
dbgf(pname);
return status;
}
@@ -943,13 +954,13 @@ static void printBuffer(
}
/* Now print values */
if (no_elements == 0)
return;
if (no_elements == 1)
sprintf(pmsg, "DBF_%s: ", dbr[dbr_type]);
else
else {
sprintf(pmsg, "DBF_%s[%ld]: ", dbr[dbr_type], no_elements);
if (no_elements == 0)
strcat(pmsg, "(empty)");
}
dbpr_msgOut(pMsgBuff, tab_size);
if (status != 0) {

View File

@@ -33,6 +33,7 @@
#include "initHooks.h"
#include "iocInit.h"
#include "errSymTbl.h"
#include "iocshRegisterCommon.h"
static dbEventCtx testEvtCtx;
static epicsMutexId testEvtLock;
@@ -98,6 +99,7 @@ void testdbCleanup(void)
db_cleanup_events();
initHookFree();
registryFree();
clearRegistrarOnce();
pdbbase = NULL;
dbmfFreeChunks();
}

View File

@@ -9,7 +9,7 @@
=head1 Menu menuIvoa
This menu specifies the possibile actions to take when the INVALID alarm is
This menu specifies the possible actions to take when the INVALID alarm is
triggered. See individual record types for more information.
=menu menuIvoa

View File

@@ -1,16 +0,0 @@
#*************************************************************************
# Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE is distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
menu(menuPini) {
choice(menuPiniNO,"NO")
choice(menuPiniYES,"YES")
choice(menuPiniRUN,"RUN")
choice(menuPiniRUNNING,"RUNNING")
choice(menuPiniPAUSE,"PAUSE")
choice(menuPiniPAUSED,"PAUSED")
}

View File

@@ -0,0 +1,66 @@
#*************************************************************************
# Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE is distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
=head1 Menu menuPini
This menu defines the choices for the C<PINI> field, which controls whether
and when each record should be processed during initialization or pausing
of the IOC. Choices other than C<NO> cause record processing at the
following initHook transitions:
=over 4
=item YES
C<initHookAfterScanInit> E<mdash> All records and links have been
initialized but the scan threads and CA server are not running yet, nor
have CA links been connected up. The initHook C<initHookAfterInitialProcess>
immediately follows this procssing.
=item RUN
C<initHookAtIocRun> E<mdash> The C<iocRun()> routine has just been called,
although not necessarily for the first time.
=item RUNNING
C<initHookAfterIocRunning> E<mdash> All remaining initializations have
taken place, C<interruptAccept> is enabled, the scan threads and CA server
are running and the IOC is processing records. CA links might not have
finished connecting though, and sequence programs won't usually have been
started yet.
=item PAUSE
C<initHookAtIocPause> E<mdash> The C<iocPause()> routine has just been
called and the IOC is about to suspend operations.
=item PAUSED
C<initHookAfterIocPaused> E<mdash> The CA server, CA link operations and
the scan threads have been paused and C<interruptAccept> disabled.
=back
Note that the order in which records that have the same C<PINI> value get
processed can be controlled by setting their C<PHAS> field, which is honored
for C<PINI> processing as well as for regular scanning.
=menu menuPini
=cut
menu(menuPini) {
choice(menuPiniNO,"NO")
choice(menuPiniYES,"YES")
choice(menuPiniRUN,"RUN")
choice(menuPiniRUNNING,"RUNNING")
choice(menuPiniPAUSE,"PAUSE")
choice(menuPiniPAUSED,"PAUSED")
}

View File

@@ -5,6 +5,16 @@
# in file LICENSE that is included with this distribution.
#*************************************************************************
=head1 Menu menuPost
This menu is used by the long string record types to specify whether they
should generate a monitor event only when their string value changes, or
every time it gets written to even if the value is the same.
=menu menuPost
=cut
menu(menuPost) {
choice(menuPost_OnChange, "On Change")
choice(menuPost_Always, "Always")

View File

@@ -7,6 +7,20 @@
# EPICS Base is distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
=head1 Menu menuPriority
This menu is used for the C<PRIO> field of all record types. It controls
the relative priority of records scheduled with C<SCAN=Event> or
C<SCAN=I/O Intr>, and also of records that use asynchronous completion.
=menu menuPriority
The number of priorities is set in various other places in the code too,
so adding new entries to this menu will probably break the IOC build.
=cut
menu(menuPriority) {
choice(menuPriorityLOW,"LOW")
choice(menuPriorityMEDIUM,"MEDIUM")

View File

@@ -10,6 +10,7 @@
newline "\n"
backslash "\\"
singlequote "'"
doublequote "\""
comment "#"
whitespace [ \t\r\n]
@@ -18,17 +19,30 @@ stringchar [^"\n\\]
bareword [a-zA-Z0-9_\-+:.\[\]<>;]
punctuation [:,\[\]{}]
normalchar [^"\\\0-\x1f]
normalchar [^"'\\\0-\x1f]
barechar [a-zA-Z0-9_\-+.]
escapedchar ({backslash}["\\/bfnrt])
escapedchar ({backslash}[^ux1-9])
hexdigit [0-9a-fA-F]
latinchar ({backslash}"x"{hexdigit}{2})
unicodechar ({backslash}"u"{hexdigit}{4})
jsonchar ({normalchar}|{escapedchar}|{unicodechar})
jsondqstr ({doublequote}{jsonchar}*{doublequote})
int ("-"?([0-9]|[1-9][0-9]+))
jsondqchar ({normalchar}|{singlequote}|{escapedchar}|{latinchar}|{unicodechar})
jsondqstr ({doublequote}{jsondqchar}*{doublequote})
jsonsqchar ({normalchar}|{doublequote}|{escapedchar}|{latinchar}|{unicodechar})
jsonsqstr ({singlequote}{jsonsqchar}*{singlequote})
jsonstr ({jsondqstr}|{jsonsqstr})
sign ([+-]?)
int ({sign}([0-9]|[1-9][0-9]+))
frac ("."[0-9]+)
exp ([eE][+-]?[0-9]+)
number ({int}{frac}?{exp}?)
exp ([eE]{sign}[0-9]+)
jsonnum ({int}{frac}?{exp}?)
intexp ({int}"."{exp}?)
fracexp ({sign}{frac}{exp}?)
specialnum ("NaN"|{sign}"Infinity")
zerox ("0x"|"0X")
hexint ({sign}{zerox}{hexdigit}+)
number ({jsonnum}|{intexp}|{fracexp}|{specialnum}|{hexint})
%{
#undef YY_INPUT
@@ -97,7 +111,7 @@ static int yyreset(void)
<JSON>{punctuation} return yytext[0];
<JSON>{jsondqstr} {
<JSON>{jsonstr} {
yylval.Str = dbmfStrdup((char *) yytext);
return jsonSTRING;
}

View File

@@ -1172,19 +1172,22 @@ static void dbRecordField(char *name,char *value)
yyerror(NULL);
return;
}
if (*value == '"') {
if (*value == '"' || *value == '\'') {
/* jsonSTRING values still have their quotes */
value++;
value[strlen(value) - 1] = 0;
dbTranslateEscape(value, value); /* in-place; safe & legal */
}
dbTranslateEscape(value, value); /* in-place; safe & legal */
status = dbPutString(pdbentry,value);
if (status) {
char msg[128];
errSymLookup(status, msg, sizeof(msg));
epicsPrintf("Can't set \"%s.%s\" to \"%s\" %s\n",
dbGetRecordName(pdbentry), name, value, msg);
epicsPrintf("Can't set \"%s.%s\" to \"%s\" %s : %s\n",
dbGetRecordName(pdbentry), name, value, pdbentry->message ? pdbentry->message : "", msg);
dbPutStringSuggest(pdbentry, value);
yyerror(NULL);
return;
}
@@ -1203,12 +1206,14 @@ static void dbRecordInfo(char *name, char *value)
if (duplicate) return;
ptempListNode = (tempListNode *)ellFirst(&tempList);
pdbentry = ptempListNode->item;
if (*value == '"') {
if (*value == '"' || *value == '\'') {
/* jsonSTRING values still have their quotes */
value++;
value[strlen(value) - 1] = 0;
dbTranslateEscape(value, value); /* in-place; safe & legal */
}
dbTranslateEscape(value, value); /* yuck: in-place, but safe */
status = dbPutInfo(pdbentry,name,value);
if (status) {
epicsPrintf("Can't set \"%s\" info \"%s\" to \"%s\"\n",

View File

@@ -81,8 +81,6 @@ maplinkType pamaplinkType[LINK_NTYPES] = {
};
/*forward references for private routines*/
static void dbMsgPrint(DBENTRY *pdbentry, const char *fmt, ...)
EPICS_PRINTF_STYLE(2,3);
static long dbAddOnePath (DBBASE *pdbbase, const char *path, unsigned length);
/* internal routines*/
@@ -199,7 +197,6 @@ void dbMsgNCpy(DBENTRY *pdbentry, const char *msg, size_t len)
pdbentry->message[len] = '\0';
}
static
void dbMsgPrint(DBENTRY *pdbentry, const char *fmt, ...)
{
va_list args;
@@ -2331,8 +2328,7 @@ long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
}
/* Link may be an array constant */
if (pstr[0] == '[' && pstr[len-1] == ']' &&
(strchr(pstr, ',') || strchr(pstr, '"'))) {
if (pstr[0] == '[' && pstr[len-1] == ']') {
pinfo->ltype = CONSTANT;
return 0;
}
@@ -2636,6 +2632,52 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
return(status);
}
void dbPutStringSuggest(DBENTRY *pdbentry, const char *pstring)
{
dbFldDes *pflddes = pdbentry->pflddes;
switch (pflddes->field_type) {
case DBF_MENU:
case DBF_DEVICE: {
int i, nchoices = 0;
char** choices = NULL;
const char *best = NULL;
double maxdist = 0.0; /* don't offer suggestions which have no similarity */
if(pflddes->field_type==DBF_MENU) {
dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt;
if(!pdbMenu)
return;
choices = pdbMenu->papChoiceValue;
nchoices = pdbMenu->nChoice;
} else {
dbDeviceMenu *pdbDeviceMenu = dbGetDeviceMenu(pdbentry);
if(!pdbDeviceMenu)
return;
choices = pdbDeviceMenu->papChoice;
nchoices = pdbDeviceMenu->nChoice;
}
for(i=0; i<nchoices; i++) {
double dist = epicsStrSimilarity(pstring, choices[i]);
if(dist>maxdist) {
best = choices[i];
maxdist = dist;
}
}
if(best) {
epicsPrintf(" Did you mean \"%s\"?\n", best);
}
}
break;
default:
break;
}
}
char * dbVerify(DBENTRY *pdbentry, const char *pstring)
{
dbFldDes *pflddes = pdbentry->pflddes;

View File

@@ -36,6 +36,10 @@ char *dbRecordName(DBENTRY *pdbentry);
char *dbGetStringNum(DBENTRY *pdbentry);
long dbPutStringNum(DBENTRY *pdbentry,const char *pstring);
void dbMsgPrint(DBENTRY *pdbentry, const char *fmt, ...) EPICS_PRINTF_STYLE(2,3);
void dbPutStringSuggest(DBENTRY *pdbentry, const char *pstring);
struct jlink;
typedef struct dbLinkInfo {

View File

@@ -28,6 +28,7 @@
#include "dbCommonPvt.h"
#include "dbStaticLib.h"
#include "dbStaticPvt.h"
#include "dbAccess.h"
#include "devSup.h"
#include "special.h"
@@ -479,8 +480,17 @@ long dbPutStringNum(DBENTRY *pdbentry, const char *pstring)
epicsEnum16 value;
long status = epicsParseUInt16(pstring, &value, 0, NULL);
if (status)
if (status) {
status = S_db_badChoice;
if(pflddes->field_type==DBF_MENU) {
dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt;
dbMsgPrint(pdbentry, "using menu %s", pdbMenu->name);
} else if(pflddes->field_type==DBF_DEVICE) {
dbMsgPrint(pdbentry, "no such device support for '%s' record type", pdbentry->precordType->name);
}
return status;
}
index = dbGetNMenuChoices(pdbentry);
if (value > index && index > 0 && value < USHRT_MAX)

View File

@@ -32,8 +32,8 @@ static int yyAbort = 0;
%token jsonNULL jsonTRUE jsonFALSE
%token <Str> jsonNUMBER jsonSTRING jsonBARE
%type <Str> json_value json_object json_array
%type <Str> json_members json_pair json_elements json_string
%type <Str> json_value json_string json_object json_array
%type <Str> json_members json_pair json_key json_elements
%%
@@ -299,13 +299,24 @@ json_members: json_pair
if (dbStaticDebug>2) printf("json %s\n", $$);
};
json_pair: json_string ':' json_value
json_pair: json_key ':' json_value
{
$$ = dbmfStrcat3($1, ":", $3);
dbmfFree($1); dbmfFree($3);
if (dbStaticDebug>2) printf("json %s\n", $$);
};
json_key: jsonSTRING
| jsonBARE
{
/* A key containing any of these characters must be quoted for YAJL */
if (strcspn($1, "+-.") < strlen($1)) {
$$ = dbmfStrcat3("\"", $1, "\"");
dbmfFree($1);
}
if (dbStaticDebug>2) printf("json %s\n", $$);
};
json_string: jsonSTRING
| jsonBARE
{

View File

@@ -25,5 +25,6 @@ dbCore_SRCS += iocInit.c
dbCore_SRCS += miscIocRegister.c
dbCore_SRCS += dlload.c
dbCore_SRCS += iocshRegisterCommon.c
dbCore_SRCS += registerAllRecordDeviceDrivers.cpp
miscIocRegister_CFLAGS_iOS = -DSYSTEM_UNAVAILABLE

View File

@@ -26,6 +26,16 @@
#define quote(v) #v
#define str(v) quote(v)
/* registerAllRecordDeviceDrivers */
static const iocshArg rrddArg0 = {"pdbbase", iocshArgPdbbase};
static const iocshArg *rrddArgs[] = {&rrddArg0};
static const iocshFuncDef rrddFuncDef =
{"registerAllRecordDeviceDrivers", 1, rrddArgs};
static void rrddCallFunc(const iocshArgBuf *args)
{
iocshSetError(registerAllRecordDeviceDrivers(*iocshPpdbbase));
}
void iocshRegisterCommon(void)
{
const char *targetArch = envGetConfigParamPtr(&EPICS_BUILD_TARGET_ARCH);
@@ -53,4 +63,5 @@ void iocshRegisterCommon(void)
asIocRegister();
miscIocRegister();
libComRegister();
iocshRegister(&rrddFuncDef, rrddCallFunc);
}

View File

@@ -19,9 +19,25 @@
extern "C" {
#endif
struct dbBase;
/* register many useful commands */
epicsShareFunc void iocshRegisterCommon(void);
#define HAS_registerAllRecordDeviceDrivers
epicsShareFunc
long
registerAllRecordDeviceDrivers(struct dbBase *pdbbase);
epicsShareFunc
void runRegistrarOnce(void (*reg_func)(void));
#ifdef EPICS_PRIVATE_API
epicsShareFunc
void clearRegistrarOnce(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,255 @@
/*************************************************************************\
* Copyright (c) 2020 Michael Davidsaver
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include <exception>
#include <string>
#include <set>
#include <map>
#include <string.h>
#define EPICS_PRIVATE_API
#include <iocsh.h>
#include <epicsStdio.h>
#include <epicsFindSymbol.h>
#define epicsExportSharedSymbols
#include <registryRecordType.h>
#include <registryDeviceSupport.h>
#include <registryDriverSupport.h>
#include <iocshRegisterCommon.h>
#include <registryCommon.h>
#include <dbAccess.h>
#include <dbBase.h>
#include <dbStaticLib.h>
namespace {
struct compareLoc {
bool operator()(const recordTypeLocation& lhs, const recordTypeLocation& rhs) const
{
if(lhs.prset<rhs.prset)
return true;
else if(lhs.prset>rhs.prset)
return false;
return lhs.sizeOffset<rhs.sizeOffset;
}
};
// storage which will be referenced by pdbbase. Must never be free'd
std::set<std::string> names;
std::set<recordTypeLocation, compareLoc> reclocs;
template<typename T, typename Y>
const T& intern(std::set<T,Y>& coll, const T& val)
{
return *coll.insert(val).first;
}
std::set<void*> registrarsRun;
// gcc circa 4.4 doesn't like iocshVarDef[2] as mapped_type
struct varDef {
iocshVarDef def[2];
};
typedef std::map<std::string, varDef> vardefs_t;
vardefs_t vardefs;
template<typename T>
T lookupAs(const char* a, const char* b =0, const char* c =0, const char* d =0)
{
std::string name(a);
if(b)
name += b;
if(c)
name += c;
if(d)
name += d;
T ret = (T)epicsFindSymbol(name.c_str());
if(!ret) {
fprintf(stderr, "Unable to find symbol '%s' : %s\n", name.c_str(), epicsLoadError());
// all pvar_* are pointers to the exported object
} else if(ret && !*ret) {
fprintf(stderr, "symbol '%s' holds NULL\n", name.c_str());
}
return ret;
}
} // namespace
void runRegistrarOnce(void (*reg_func)(void))
{
if(registrarsRun.find((void*)reg_func)!=registrarsRun.end())
return;
registrarsRun.insert((void*)reg_func);
reg_func();
}
void clearRegistrarOnce()
{
registrarsRun.clear();
}
long
registerAllRecordDeviceDrivers(DBBASE *pdbbase)
{
DBENTRY entry;
if(!pdbbase) {
fprintf(stderr, "Must call dbLoadRecords() before registerAllRecordDeviceDrivers(pdbbase)\n");
return 1;
}
dbInitEntry(pdbbase, &entry);
try {
// for each recordType
for(long status=dbFirstRecordType(&entry); !status; status=dbNextRecordType(&entry)) {
dbRecordType *rtype = entry.precordType;
if(!registryRecordTypeFind(rtype->name)) {
rset** prset = lookupAs<rset**>("pvar_rset_", rtype->name, "RSET");
computeSizeOffset* sizeOffset = lookupAs<computeSizeOffset*>("pvar_func_", rtype->name, "RecordSizeOffset");
if(!prset || !*prset || !sizeOffset || !*sizeOffset) {
fprintf(stderr, "Unable to find support for record type '%s' : %s\n",
rtype->name, epicsLoadError());
return 1;
}
recordTypeLocation sup;
sup.prset = *prset;
sup.sizeOffset = *sizeOffset;
const char *cname = intern<std::string>(names, rtype->name).c_str();
const recordTypeLocation* csup = &intern<recordTypeLocation>(reclocs, sup);
registerRecordTypes(pdbbase, 1, &cname, csup);
}
// for each device support for this recordType
for(ELLNODE *cur = ellFirst(&rtype->devList); cur; cur = ellNext(cur)) {
devSup& devsup = *CONTAINER(cur, devSup, node);
if(registryDeviceSupportFind(devsup.name))
continue;
dset** ptr = lookupAs<dset**>("pvar_dset_", devsup.name);
if(!ptr || !*ptr) {
fprintf(stderr, "Unable to find dset for record type '%s' support '%s' : %s\n",
rtype->name, devsup.name, epicsLoadError());
return 1;
}
const char *cname = intern<std::string>(names, devsup.name).c_str();
registerDevices(pdbbase, 1, &cname, ptr);
}
}
// for each driver
for(ELLNODE *cur = ellFirst(&pdbbase->drvList); cur; cur = ellNext(cur)) {
drvSup& drv = *CONTAINER(cur, drvSup, node);
if(registryDriverSupportFind(drv.name))
continue;
drvet** ptr = lookupAs<drvet**>("pvar_drvet_", drv.name);
if(!ptr || !*ptr) {
fprintf(stderr, "Unable to find drvet '%s' : %s\n", drv.name, epicsLoadError());
return 1;
}
const char *cname = intern<std::string>(names, drv.name).c_str();
registerDrivers(pdbbase, 1, &cname, ptr);
}
// for each link support
for(ELLNODE *cur = ellFirst(&pdbbase->linkList); cur; cur = ellNext(cur)) {
linkSup& lnk = *CONTAINER(cur, linkSup, node);
jlif** ptr = lookupAs<jlif**>("pvar_jlif_", lnk.jlif_name);
if(!ptr || !*ptr) {
fprintf(stderr, "Unable to find link support '%s' : %s\n", lnk.jlif_name, epicsLoadError());
return 1;
}
registerJLinks(pdbbase, 1, ptr);
}
// for each function()
for(ELLNODE *cur = ellFirst(&pdbbase->functionList); cur; cur = ellNext(cur)) {
dbText& reg = *CONTAINER(cur, dbText, node);
typedef void(*registrar)(void);
registrar* ptr = lookupAs<registrar*>("pvar_func_register_func_", reg.text);
if(!ptr || !*ptr) {
fprintf(stderr, "Unable to find function '%s' : %s\n", reg.text, epicsLoadError());
return 1;
}
runRegistrarOnce(*ptr);
}
// for each registrar()
for(ELLNODE *cur = ellFirst(&pdbbase->registrarList); cur; cur = ellNext(cur)) {
dbText& reg = *CONTAINER(cur, dbText, node);
typedef void(*registrar)(void);
registrar* ptr = lookupAs<registrar*>("pvar_func_", reg.text);
if(!ptr || !*ptr) {
fprintf(stderr, "Unable to find registrar '%s' : %s\n", reg.text, epicsLoadError());
return 1;
}
runRegistrarOnce(*ptr);
}
// for each iocsh variable
for(ELLNODE *cur = ellFirst(&pdbbase->variableList); cur; cur = ellNext(cur)) {
dbVariableDef& var = *CONTAINER(cur, dbVariableDef, node);
if(iocshFindVariable(var.name))
continue;
void** ptr = lookupAs<void**>("pvar_", var.type, "_", var.name);
if(!ptr || !*ptr) {
fprintf(stderr, "Unable to find variable '%s' : %s\n", var.name, epicsLoadError());
return 1;
}
vardefs_t::mapped_type& vdef = vardefs[var.name];
vdef.def[0].name = intern<std::string>(names, var.name).c_str();
vdef.def[0].pval = *ptr;
if(strcmp(var.type, "double")==0) {
vdef.def[0].type = iocshArgDouble;
} else if(strcmp(var.type, "int")==0) {
vdef.def[0].type = iocshArgInt;
} else {
fprintf(stderr, "Unsupported type %s of variable '%s' : %s\n", var.type, var.name, epicsLoadError());
return 1;
}
vdef.def[1].name = 0;
iocshRegisterVariable(vdef.def);
}
dbFinishEntry(&entry);
return 0;
} catch(std::exception& e) {
dbFinishEntry(&entry);
fprintf(stderr, "Error: %s\n", e.what());
return 2;
}
}

View File

@@ -47,23 +47,20 @@ static long init_record(dbCommon *pcommon)
aaiRecord *prec = (aaiRecord *)pcommon;
DBLINK *plink = &prec->inp;
/* This is pass 0, link hasn't been initialized yet */
dbInitLink(plink, DBF_INLINK);
/* Ask record to call us in pass 1 instead */
if (prec->pact != AAI_DEVINIT_PASS1) {
return AAI_DEVINIT_PASS1;
}
if (dbLinkIsConstant(plink)) {
long nRequest = prec->nelm;
long status;
/* Allocate a buffer, record support hasn't done that yet */
if (!prec->bptr) {
prec->bptr = callocMustSucceed(nRequest, dbValueSize(prec->ftvl),
"devAaiSoft: buffer calloc failed");
}
status = dbLoadLinkArray(plink, prec->ftvl, prec->bptr, &nRequest);
if (!status && nRequest > 0) {
if (!status) {
prec->nord = nRequest;
prec->udf = FALSE;
return status;
}
}
return 0;
@@ -75,7 +72,7 @@ static long readLocked(struct link *pinp, void *dummy)
long nRequest = prec->nelm;
long status = dbGetLink(pinp, prec->ftvl, prec->bptr, 0, &nRequest);
if (!status && nRequest > 0) {
if (!status) {
prec->nord = nRequest;
prec->udf = FALSE;
@@ -90,8 +87,12 @@ static long read_aai(aaiRecord *prec)
{
epicsUInt32 nord = prec->nord;
struct link *pinp = prec->simm == menuYesNoYES ? &prec->siol : &prec->inp;
long status = dbLinkDoLocked(pinp, readLocked, NULL);
long status;
if (dbLinkIsConstant(pinp))
return 0;
status = dbLinkDoLocked(pinp, readLocked, NULL);
if (status == S_db_noLSET)
status = readLocked(pinp, NULL);

View File

@@ -86,9 +86,10 @@ static long read_ai(aiRecord *prec)
prec->udf = FALSE;
prec->dpvt = &devAiSoft; /* Any non-zero value */
return 2;
}
else
prec->dpvt = NULL;
return 2;
return status;
}

View File

@@ -66,7 +66,7 @@ static long init_record(dbCommon *pcommon)
status = dbLoadLinkArray(&prec->inp, prec->ftvl, prec->bptr, &nRequest);
if (!status && nRequest > 0)
if (!status)
subset(prec, nRequest);
return status;
@@ -116,7 +116,7 @@ static long read_sa(subArrayRecord *prec)
status = readLocked(&prec->inp, &rt);
}
if (!status && rt.nRequest > 0) {
if (!status) {
subset(prec, rt.nRequest);
if (nord != prec->nord)

View File

@@ -42,7 +42,7 @@ static long init_record(dbCommon *pcommon)
long nelm = prec->nelm;
long status = dbLoadLinkArray(&prec->inp, prec->ftvl, prec->bptr, &nelm);
if (!status && nelm > 0) {
if (!status) {
prec->nord = nelm;
prec->udf = FALSE;
}
@@ -78,11 +78,14 @@ static long read_wf(waveformRecord *prec)
rt.ptime = (dbLinkIsConstant(&prec->tsel) &&
prec->tse == epicsTimeEventDeviceTime) ? &prec->time : NULL;
if (dbLinkIsConstant(&prec->inp))
return 0;
status = dbLinkDoLocked(&prec->inp, readLocked, &rt);
if (status == S_db_noLSET)
status = readLocked(&prec->inp, &rt);
if (!status && rt.nRequest > 0) {
if (!status) {
prec->nord = rt.nRequest;
prec->udf = FALSE;
if (nord != prec->nord)

View File

@@ -489,8 +489,17 @@ static long lnkConst_loadArray(struct link *plink, short dbrType, void *pbuffer,
case sc40:
if (clink->jlink.debug)
printf(" sc40 '%s'\n", clink->value.scalar_string);
status = dbFastPutConvertRoutine[DBF_STRING][dbrType]
(clink->value.scalar_string, pbuffer, NULL);
if (dbrType != DBF_CHAR) {
status = dbFastPutConvertRoutine[DBF_STRING][dbrType]
(clink->value.scalar_string, pbuffer, NULL);
}
else {
/* Long string conversion */
strncpy(pbuffer, clink->value.scalar_string, *pnReq);
((char *)pbuffer)[*pnReq] = 0;
nElems = strlen(pbuffer) + 1;
status = 0;
}
break;
case ai64:

View File

@@ -227,6 +227,7 @@ static long process(struct dbCommon *pcommon)
return 0;
prec->pact = TRUE;
recGblGetTimeStamp(prec);
/* Push the output link values */
if (!status) {
@@ -237,7 +238,6 @@ static long process(struct dbCommon *pcommon)
(&prec->neva)[i]);
}
recGblGetTimeStamp(prec);
monitor(prec);
recGblFwdLink(prec);
prec->pact = FALSE;
@@ -278,10 +278,9 @@ static long fetch_values(aSubRecord *prec)
long nRequest = (&prec->noa)[i];
status = dbGetLink(&(&prec->inpa)[i], (&prec->fta)[i], (&prec->a)[i], 0,
&nRequest);
if (nRequest > 0)
(&prec->nea)[i] = nRequest;
if (status)
return status;
(&prec->nea)[i] = nRequest;
}
return 0;
}

View File

@@ -90,7 +90,7 @@ The VAL field is set to the value returned by the user subroutine.
The value is treated as an error status value where zero mean success.
The output links OUTA ... OUTU will only be used to forward the associated
output value fields when the subroutine has returned a zero status.
If the return status was non-zero, the record will be put into C<SOFT_ALARM>
If the return status was less than zero, the record will be put into C<SOFT_ALARM>
state with severity given by the BRSV field.
The INAM field may be used to name a subroutine that will be called once at
@@ -1363,7 +1363,7 @@ be sent through the OUTA ... OUTU links during record processing.
The previous values of the output fields.
These are used to determine when to post events if EFLG is set to C<ON CHANGE>.
=fields VALA, VALB, VALC, VALD, VALE, VALF, VALG, VALH, VALI, VALJ, VALK, VALL, VALM, VALN, VALO, VALP, VALQ, VALR, VALS, VALT, VALU
=fields OVLA, OVLB, OVLC, OVLD, OVLE, OVLF, OVLG, OVLH, OVLI, OVLJ, OVLK, OVLL, OVLM, OVLN, OVLO, OVLP, OVLQ, OVLR, OVLS, OVLT, OVLU
=cut

View File

@@ -112,16 +112,18 @@ static long init_record(struct dbCommon *pcommon, int pass)
prec->ftvl = DBF_UCHAR;
prec->nord = (prec->nelm == 1);
/* we must call pdset->init_record in pass 0
because it may set prec->bptr which must
not change after links are established before pass 1
*/
/* call pdset->init_record() in pass 0 so it can do its own
* memory allocation and set prec->bptr, which must be set by
* the end of pass 0.
*/
if (pdset->common.init_record) {
long status = pdset->common.init_record(pcommon);
/* init_record may set the bptr to point to the data */
if (status)
if (status == AAI_DEVINIT_PASS1) {
/* requesting pass 1 callback, remember to do that */
prec->pact = AAI_DEVINIT_PASS1;
}
else if (status)
return status;
}
if (!prec->bptr) {
@@ -132,6 +134,14 @@ static long init_record(struct dbCommon *pcommon, int pass)
return 0;
}
if (prec->pact == AAI_DEVINIT_PASS1) {
/* device support asked for an init_record() callback in pass 1 */
long status = pdset->common.init_record(pcommon);
if (status)
return status;
prec->pact = FALSE;
}
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
/* must have read_aai function defined */

Some files were not shown because too many files have changed in this diff Show More