Compare commits

...

315 Commits

Author SHA1 Message Date
Andrew Johnson
74a90d141b Update version numbers
Also contains some reformatting in README.md
2019-10-31 13:00:24 -05:00
Andrew Johnson
ed9d7550f2 Configure linux targets to detect GNU Readline automatically 2019-10-25 00:20:50 -05:00
Ben Franksen
87c68663f3 Document OMSL=closed_loop doesn't work with constant DOL
Fixes lp: #1844537
2019-10-24 12:52:35 -05:00
Andrew Johnson
3881328f2f Merge branch 'vxworks-tz-support' into 3.15 2019-10-22 15:32:46 -05:00
Andrew Johnson
9722e707fd Merge decimate filter branch 2019-10-21 22:56:05 -05:00
Andrew Johnson
10e9db3710 Fix dbdToHtml.pl for old versions of Pod::Simple::XHTML 2019-10-21 17:54:06 -05:00
Andrew Johnson
ec31feea05 Word-wrap release notes to 80 columns 2019-10-20 16:55:10 -05:00
Andrew Johnson
d0ff3c7672 Release notes describing Record POD changes 2019-10-20 16:55:10 -05:00
Andrew Johnson
178d5779a2 Cleanup of POD documentation, unifying some things
Incomplete, still lots to do in these files.
2019-10-20 16:52:10 -05:00
Andrew Johnson
00334c981c Perl-generated HTML is UTF-8; mark it so 2019-10-20 16:52:10 -05:00
Andrew Johnson
5b5fd8004c Add converted mbbo POD 2019-10-20 16:52:10 -05:00
Andrew Johnson
c7db681e25 rename .dbd to .dpd.pod for mbbo 2019-10-20 16:52:10 -05:00
Joao Paulo Martins
3ff62f4ddb Add converted mbbiDirect POD 2019-10-20 16:52:09 -05:00
Joao Paulo Martins
b34859fb86 rename .dbd to .dpd.pod for mbbiDirect 2019-10-20 16:52:09 -05:00
Andrew Johnson
953dd2b7f9 Document use of epicsProve.pl
Also replaced UTF-8 smart-quotes and m-dashes with ASCII/Markdown
2019-10-17 17:17:05 -05:00
Andrew Johnson
3128fdb930 Add and use epicsProve.pl script
Some Windows Perl installations don't have a working prove.bat
so 'make test-results' doesn't work properly on them.
2019-10-17 16:14:59 -05:00
Andrew Johnson
47f295fecb Clean up permissive POD links 2019-10-10 15:02:06 -04:00
Andrew Johnson
4816a3c04b Merge Saeed's permissive POD conversion branch 2019-10-10 14:54:21 -04:00
Andrew Johnson
e0950643bb Clean up state POD links 2019-10-10 14:53:10 -04:00
Andrew Johnson
252983efca Merge Saeed's state POD conversion branch 2019-10-10 14:48:12 -04:00
Andrew Johnson
7ca26c515a Clean up stringin POD links 2019-10-10 14:46:18 -04:00
Andrew Johnson
a961ca2fe5 Merge Saeed's stringin POD conversion branch 2019-10-10 14:40:23 -04:00
Andrew Johnson
a2fe07aa76 Merge Joao's mbboDirect POD conversion branch 2019-10-10 14:33:45 -04:00
Andrew Johnson
a69803f278 Merge Joao's mbbi POD conversion branch 2019-10-10 14:22:16 -04:00
Saeed Haghtalab
ee38b99e0f Adding POD to stringout record
Also to menuYesNo, menuOmsl, menuIvoa menus
2019-10-10 12:43:32 -04:00
Andrew Johnson
0a01c38698 File renames .dbd to .dbd.pod for stringout 2019-10-10 12:12:41 -04:00
Andrew Johnson
9efefad955 Fix markdown formatting issue 2019-10-10 00:57:45 -04:00
Andrew Johnson
0c62fc8d84 Merge Niamh Dougan's release-notes conversion 2019-10-10 00:21:43 -04:00
Niamh Dougan
292dfe8e16 Convert RELEASE_NOTES from html to .md
Reformat relocations table, escape words with underscores
inside `back-ticks`.
2019-10-10 00:16:17 -04:00
Niamh Dougan
1c93726ee6 renamed RELEASE_NOTES.html -> RELEASE_NOTES.md 2019-10-09 22:40:30 -04:00
Ralph Lange
643d58fd04 appveyor-ci: completely remove cygwin builds 2019-10-02 15:49:12 -04:00
Andrew Johnson
f08b412a18 Have CA Repeater cd to / before running
to avoid holding the CWD open unnecessarily.
2019-09-18 14:43:08 -05:00
Michael Davidsaver
77574022a1 update RELEASE_NOTES 2019-09-09 16:56:28 -07:00
Michael Davidsaver
75a1b82322 add option EPICS_NO_CALLBACK
Allow the CALLBACK definition to be hidden to prevent
conflicts on WIN32.
2019-09-09 16:22:20 -07:00
Michael Davidsaver
73fec88168 replace CALLBACK -> epicsCallback
git grep -l -w CALLBACK -- src|xargs sed -i -e 's/\bCALLBACK\b/epicsCallback/g'

with exceptions in callback.h
2019-09-09 16:22:20 -07:00
krmpotic
2461dc3574 Update dbTest.c
Fix MAX define.
2019-09-09 11:42:04 +02:00
Andrew Johnson
704e6251e6 Remove links to wiki-ext 2019-09-06 18:33:55 +02:00
Saeed Haghtalab
f70c17ee69 Add POD annotations from Wiki to subArrayRecord and menuAlarmStat 2019-09-06 18:20:43 +02:00
Saeed Haghtalab
96e3e678e9 Rename subArrayRecord.dbd and menuAlarmStat.dbd to .pod 2019-09-06 18:02:39 +02:00
Joao Paulo Martins
9d4b652c5e First version of mbbo POD file 2019-09-06 17:20:54 +02:00
Saeed Haghtalab
0d3cc5a20a Added POD to state record with a note that it is deprecated 2019-09-06 15:49:58 +02:00
Saeed Haghtalab
9255256f15 Added POD to permissive record with a note that it is deprecated. 2019-09-06 15:48:46 +02:00
Saeed Haghtalab
4685f7567b Rename permissiveRecord.dbd -> permissiveRecord.dbd.pod 2019-09-06 15:13:25 +02:00
Joao Paulo Martins
e5f8683144 Renaming dbd file to dbd.pod 2019-09-06 15:00:52 +02:00
Saeed Haghtalab
4f63bf139f Rename stateRecord.dbd -> stateRecord.dbd.pod 2019-09-06 14:36:36 +02:00
Saeed Haghtalab
d7d142650b Adding POD to stringin record 2019-09-06 14:11:20 +02:00
Joao Paulo Martins
eac3d2719b Add POD annotations to longoutRecord from Wiki 2019-09-06 14:00:17 +02:00
Joao Paulo Martins
a3d0699b84 Rename longoutRecord.dbd longoutRecord.dbd.pod 2019-09-06 13:59:31 +02:00
Joao Paulo Martins
a16bf2dc38 Add POD annotations to longinRecord from Wiki 2019-09-06 13:55:14 +02:00
Joao Paulo Martins
13936680e9 Rename longinRecord.dbd longinRecord.dbd.pod 2019-09-06 13:54:10 +02:00
Saeed Haghtalab
7b6c67b51b Add POD annotations to subRecord from Wiki 2019-09-06 13:28:55 +02:00
Saeed Haghtalab
33febb52ba Rename subRecord.dbd subRecord.dbd.pod 2019-09-06 13:28:11 +02:00
Saeed Haghtalab
44149c170e Add POD annotations to selRecord from Wiki 2019-09-06 13:14:48 +02:00
Saeed Haghtalab
db6825f62e Rename selRecord.dbd selRecord.dbd.pod 2019-09-06 13:13:46 +02:00
Joao Paulo Martins
6905ded0d0 First version of mbbi POD file 2019-09-06 12:14:55 +02:00
Saeed Haghtalab
4f31205188 Rename stringinRecord.dbd -> stringinRecord.dbd.pod 2019-09-06 11:56:46 +02:00
Joao Paulo Martins
90d9be1c00 Renaming mbbiRecord.dbd with POD file extension 2019-09-06 11:53:28 +02:00
Joao Paulo Martins
b93f92c843 Add POD annotations to seqRecord from Wiki 2019-09-06 11:26:39 +02:00
Joao Paulo Martins
83458421aa Rename seqRecord.dbd seqRecord.dbd.pod 2019-09-06 11:20:11 +02:00
Andrew Johnson
89e3c582b5 Fix menu declaration test too 2019-09-06 10:44:02 +02:00
Andrew Johnson
623539c3e8 Add redefinition guard to menu-generated typedefs 2019-09-06 10:14:39 +02:00
Andrew Johnson
2a0df61974 Merge compress RecRef wiki as dbd.pod 2019-09-05 17:10:11 +02:00
Andrew Johnson
6e3a15e318 Merge waveform RecRef wiki as dbd.pod 2019-09-05 17:07:27 +02:00
Andrew Johnson
86b1882186 Updates to existing .dbd.pod texts, add event and fanout from wiki 2019-09-05 16:09:20 +02:00
Andrew Johnson
03e613cec0 Adding POD to event and fanout records 2019-09-05 16:09:20 +02:00
Niamh Dougan
177c377b81 Amend documentation filenames in README
Also deleted old README.1st
2019-09-05 15:12:19 +02:00
Niamh Dougan
1cf831939a Convert HTML in README.md to Github Markdown 2019-09-05 15:07:01 +02:00
Niamh Dougan
26cd81d35f Rename README to .md 2019-09-05 15:05:42 +02:00
Saeed Haghtalab
31811e53b3 Compress record pod update after review
- Revert "N to 1 Median" choice entry place
- Convert images to PNG and update Makefile
- Update record support routins definition based on epics7 recSup.h
2019-09-04 21:15:46 +02:00
Joao Paulo Martins
128d2a93c8 Fixing waveform record documentation after review 2019-09-04 17:25:28 +02:00
Saeed Haghtalab
67583b4bda Update compressRecord.dbd.pod based on Wiki + Content update 2019-09-04 11:29:43 +02:00
Joao Paulo Martins
8a39ca7489 Preparing the waveform record DBD-POD file; Creation of the menuFtype DBD-POD file 2019-09-03 14:20:24 +02:00
Ralph Lange
b9bc836d1e appveyor-ci: disable cygwin x86 builds (install is broken) 2019-09-02 14:47:39 +02:00
Andrew Johnson
9b5034f307 Restore errlogFlush() call to msi.cpp 2019-07-25 14:35:41 -05:00
Andrew Johnson
a6812c5869 Revert "More msi.plt retries for Jenkins builds on Windows"
This reverts commit a69bd833fc.
2019-07-17 16:19:37 -05:00
Michael Davidsaver
b89494a840 Revert "Testing msi: Add retries if necessary"
This reverts commit 29c069db3d.

# Conflicts:
#	src/ioc/dbtemplate/test/msi.plt
2019-07-17 11:20:03 -07:00
Freddie Akeroyd
771ad6a442 msi: Flush stdout on program exit
On WIN32 if the reopen()ed stdout is not closed it can occasionally
result in missing lines in the output file
2019-07-17 10:45:09 -07:00
Andrew Johnson
84c86e67e8 Fix valgrind warnings in filter tests 2019-07-08 12:55:21 -05:00
Andrew Johnson
cac3e2dc3b Add checks of freelist to dbndTest.c 2019-07-07 23:32:12 -05:00
Andrew Johnson
8ff6ce4821 Fix leak in sync filter (while, unless modes)
Always release field logs when we drop them.
Adjust how first and after modes work to make them easier to test.
Change stream checking code, fix leaks and double frees.
Add mustStash(), mustSwap(), streamReset(), drop mustPassOld().
Modify test code to check free-list count and release all of
the field-logs returned by the filter; it must release any of
the field-logs that it decides to drop.
2019-07-07 23:30:07 -05:00
Andrew Johnson
44ea66aaaf Add checks and summary of free-list size to decTest.c 2019-07-07 23:11:21 -05:00
Andrew Johnson
c9c4eea0f8 Now fix the non-windows systems 2019-06-27 15:21:41 -05:00
Andrew Johnson
78ce2dac05 Don't use / in Windows program paths
Fixing Windows msi.t script failures...
2019-06-27 13:28:56 -05:00
Andrew Johnson
b2285bb8aa Redirect msi's STDERR to /dev/null (NUL on Windows) during tests
Also moves the environment variable handling code out to the only
test that needs it and simplifies it; some Perl versions were giving
warnings from splitting an undef value.
2019-06-27 12:01:42 -05:00
Andrew Johnson
f79c69f0a0 Fix the decimate filter, free field-logs when dropping them 2019-06-26 23:33:35 -05:00
Andrew Johnson
e03c7edfe5 Check free-list size to ensure field-logs freed properly
Moves where the field-logs get freed into the mustPass/mustDrop routines,
where it only happens if the filter didn't free them itself.

Filters that save field-logs can't use this code as-is.
2019-06-26 23:32:52 -05:00
Andrew Johnson
398fdee33e Added db_available_logs() for filter test code to use
Returns the number of items available on the db_field_log free-list.
2019-06-26 23:28:51 -05:00
Michael Davidsaver
59cb5ba6a0 Merge remote-tracking branch 'konrad/clean-up-msi' into 3.15
* konrad/clean-up-msi:
  Add test for macro expansion in file names
  Reduce scope of some variables
  Convert substitutionName to std::string
  Use bool for more clarity
  Remove unneeded errlogFlush()
  Manage psubFile with new/delete
  Convert copy to std::string
  Use std::list for patternList
  Convert patternNode.var to std::string
  Convert fullname to std::string
  Convert inputFile.filename to std::string
  Simplify inputConstruct()
  Use std::list for pathList
  Use std::list for inputFileList
  Constructor for struct inputData
  Simplify catMacroReplacements()
  Constructor for struct subInfo
  Add some const keywords
  Convert MSI to C++
  Test expansion of empty patterns with MSI
2019-06-26 14:55:40 -07:00
Michael Davidsaver
2db2f1a53f Merge remote-tracking branch 'konrad/fix-compiler-warnings' into 3.15
* konrad/fix-compiler-warnings:
  epicsTime: rely on implicit copy constructor
  iocLogServer: check return values
  Fix potential buffer overflow in iocLogServer
  Fix weird use of strncpy
2019-06-24 18:21:32 -07:00
Michael Davidsaver
b811d3402f Merge remote-tracking branch 'konrad/dont-nuke-global-cac-thread-id-in-exit-handler' into 3.15
* konrad/dont-nuke-global-cac-thread-id-in-exit-handler:
  Remove cacExitHandler
2019-06-24 18:12:58 -07:00
Andrew Johnson
e75a72ef76 VxWorks: Mark undetected underflow parse test as ToDo 2019-06-07 17:22:40 -05:00
Andrew Johnson
33e099a51b Fix VxWorks osiSockOptMcastLoop_t => char
Repairs osiSockTest
2019-06-07 17:21:18 -05:00
Andrew Johnson
d3a8a49552 Release Notes 2019-06-07 15:37:46 -05:00
Andrew Johnson
96998f55e0 Have VxWorks call tz2timezone() once clock is sync'd 2019-06-07 14:55:26 -05:00
Andrew Johnson
b57f02ece2 epicsTimeTo[GM]TM(): Allow pNSecDest==NULL 2019-06-07 13:26:24 -05:00
Andrew Johnson
b0db6568ea Replace EPICS_TIMEZONE envParam with EPICS_TZ
Adjust rtems_init() to use it.
2019-06-07 13:24:39 -05:00
Andrew Johnson
30812c23f0 Internal cleanup in osiClockTime.c 2019-06-07 13:17:35 -05:00
Andrew Johnson
5cfff383b2 Synchronization hook support for osiClockTime 2019-06-07 13:16:42 -05:00
Andrew Johnson
345cfcffa8 Fix sync filter example in dbd.pod 2019-06-04 12:53:41 -05:00
Andrew Johnson
deb9dbcd77 Added decimation filter, documentation and tests 2019-06-04 12:23:13 -05:00
Ralph Lange
96259b7bdc doc/ca: clarify variable size array subscription 2019-05-09 17:28:36 +02:00
Martin Konrad
25576c316a Remove cacExitHandler
We need to ensure the allocated resources stick around until
the last instance using them doesn't need them anymore. Sharing
a raw pointer by exporting it as a global variable is not
compatible with cleaning up at all. For now we remove the
clean-up code.

Note: This fixes a segfault during IOC shutdown when using both
pyDevSup and pyepics. See the discussion on
https://epics.anl.gov/tech-talk/2019/msg00778.php for details.
2019-05-06 19:50:01 -04:00
Andrew Johnson
2d3de1916b Don't clear caClientCallbackThreadId in CA's exit handler 2019-05-06 12:22:34 -05:00
Ralph Lange
16ddcaeaed appveyor-ci: ANL Make install 4.1 -> 4.2.1 2019-05-03 15:30:59 +02:00
Ralph Lange
297206e247 appveyor-ci: use pre-installed AppVeyor MinGW 2019-05-03 15:29:07 +02:00
Ralph Lange
63bf8a8219 appveyor-ci: use choco MinGW 5.3.0 to work around build problem
(fixes lp:1827225)
2019-05-02 11:39:04 +02:00
Ralph Lange
ec7193d0be appveyor-ci: exclude some cygwin builds (broken compiler)
appveyor-ci: remove slack, add email and GitHub notifications
(cherry-picked from branch 7.0)
2019-04-30 15:53:50 +02:00
Martin Konrad
1f95d0db12 epicsTime: rely on implicit copy constructor
When a custom copy constructor is defined the assignment operator
also needs to be defined explicitly. For this simple class the
implicit copy ctor/assignment operator are sufficient, though. This
fixes a warning emitted by GCC9.
2019-04-25 11:00:39 -04:00
Martin Konrad
e02c5c3026 iocLogServer: check return values
No serious issues here just fixing some warnings.
2019-04-24 22:25:31 -04:00
Martin Konrad
8e9d75ad71 Fix potential buffer overflow in iocLogServer 2019-04-24 22:25:31 -04:00
Martin Konrad
630663caa8 Fix weird use of strncpy
Note: The old code was correct. This change just gets rid of
a bunch of warnings.
2019-04-24 22:25:31 -04:00
Andrew Johnson
736075daf6 Document macOS Mojave fix 2019-02-01 16:49:11 -06:00
Andrew Johnson
9ef3b77348 Fix ca/client/perl/Makefile for macOS Mojave
... in which Apple moved the Perl headers into XCode.
This should also make the build a little more forgiving on other
architectures that have incomplete Perl installations; it gives up
trying to build the Perl bindings with a warning if perl.h is missing.
2019-02-01 16:14:45 -06:00
Andrew Johnson
5e1bad2b34 dbStatic parser: Reject empty object names 2019-01-10 14:45:18 -06:00
Martin Konrad
a9606dbf6e Add test for macro expansion in file names 2019-01-08 09:34:55 -05:00
Martin Konrad
409ee26fae Reduce scope of some variables 2019-01-08 09:34:55 -05:00
Martin Konrad
9a4787155c Convert substitutionName to std::string 2019-01-08 09:34:55 -05:00
Martin Konrad
84dba0d2b7 Use bool for more clarity 2019-01-08 09:34:55 -05:00
Martin Konrad
87f6c3dec9 Remove unneeded errlogFlush() 2019-01-08 09:34:55 -05:00
Martin Konrad
940814becf Manage psubFile with new/delete 2019-01-08 09:34:55 -05:00
Martin Konrad
68a1a529b2 Convert copy to std::string 2019-01-08 09:34:55 -05:00
Martin Konrad
ce38caf41b Use std::list for patternList
This improves type safety and readability.
2019-01-08 09:34:55 -05:00
Martin Konrad
f03f10e664 Convert patternNode.var to std::string 2019-01-08 09:34:55 -05:00
Martin Konrad
b4f4fb853d Convert fullname to std::string 2019-01-08 09:34:55 -05:00
Martin Konrad
b518ebe85b Convert inputFile.filename to std::string 2019-01-08 09:34:55 -05:00
Martin Konrad
e461d782f4 Simplify inputConstruct() 2019-01-08 09:34:55 -05:00
Martin Konrad
ef2a381e92 Use std::list for pathList
This improves type safety and readability.
2019-01-08 09:34:55 -05:00
Martin Konrad
265d4962a4 Use std::list for inputFileList
This improves type safety and readability.
2019-01-08 09:34:55 -05:00
Martin Konrad
db9267bbd5 Constructor for struct inputData 2019-01-08 09:34:55 -05:00
Martin Konrad
1cf3fa9ba9 Simplify catMacroReplacements()
This fixes lp:1810946 and lp:1810949.
2019-01-08 09:34:40 -05:00
Martin Konrad
3e8b0028dc Constructor for struct subInfo 2019-01-08 09:22:52 -05:00
Martin Konrad
d8f18c27f4 Add some const keywords 2019-01-08 09:22:52 -05:00
Martin Konrad
801c01b9b6 Convert MSI to C++ 2019-01-08 09:22:52 -05:00
Martin Konrad
0c1874bbfe Test expansion of empty patterns with MSI
This was subject to a regression in 3.15.6. See lp:1810946.
2019-01-08 09:22:40 -05:00
Andrew Johnson
5f46d6dcee Release notes updated 2018-12-14 16:58:43 -06:00
Eric Norum
d41355e0fc Add error checking to the copy-back loop in truncateFile() 2018-12-14 16:06:38 -06:00
Eric Norum
a5aa5459e3 Drop extraneous extern "C" 2018-12-14 16:06:37 -06:00
Eric Norum
6201d37756 Remove epicsTempName() routine
It's unsafe and generates obnoxious warnings on modern compilers.
This also replaces internal useage with epicsTempFile().
There appears to be no external code that calls this routine.
2018-12-14 16:06:36 -06:00
Andrew Johnson
84b7612036 Fix for lp: #1801145 recordtype defined after use in device
Add proper equals() method for DBD::Recfield and DBD::Recordtype.
In Parser::parse_recordtype() check for and re-use a declaration
(i.e. an empty recordtype object) when parsing a later definition
of the same recordtype.
2018-12-10 00:25:27 -06:00
Andrew Johnson
64d9d1a4c9 Fix field links to local menu anchors
Anchor IDs are different for XHTML vs HTML generation.
2018-12-07 13:16:06 -06:00
Andrew Johnson
e53244df1f Cherry-pick Dirk's dbState NULL checks from the 7.0 branch
Prevent segfaults in iocsh
2018-12-07 11:45:12 -06:00
Andrew Johnson
49f5527cd7 iocsh: Add protection if realloc() fails 2018-12-06 16:35:30 -06:00
Andrew Johnson
ee90dffd40 Add flush to the iocsh errlog command 2018-12-06 16:33:20 -06:00
Andrew Johnson
6664ccfc64 Wiki to POD conversions for bi, bo, calc, calcout and dfanout
These still need going through to update and edit.
Conversions by Tony Pietryla, Argonne.
2018-12-05 16:55:13 -06:00
Andrew Johnson
444cac337c Add POD text for menuScan 2018-12-05 16:55:12 -06:00
Andrew Johnson
313afc4a4c Fix HTMLS generation from IOC menu*.dbd.pod files 2018-12-05 16:55:11 -06:00
Andrew Johnson
0fae0fcc17 Rename various dbd files to dbd.pod 2018-12-05 16:55:10 -06:00
Ralph Lange
a43b805b65 ca/pcas: fix misleading error message (TCP name resolution) 2018-11-30 17:19:56 +01:00
Andrew Johnson
937878e0a9 Merge Bruce Hill's EPICS-and-CA-version-from-CA-tools branch into 3.15 2018-11-20 10:22:43 -06:00
Andrew Johnson
6e536e1ee0 Fix msi-copy target for cross-build host arch's 2018-11-19 17:59:27 -06:00
Andrew Johnson
6ea6c6ff66 VxWorks: Don't use GCC 2.x for dependency file generation 2018-11-06 13:02:36 -06:00
Andrew Johnson
168d430921 Unify shebang line in tap-to-junit-xml 2018-11-06 10:15:06 -06:00
Bruce Hill
9a8860b771 Expand tabs and revert #include lines to <> instead of quotes. 2018-11-05 18:44:46 -08:00
Bruce Hill
3d8e2d933d Include epicsStdio.h so driver report output can be redirected from iocsh 2018-11-04 20:57:58 -08:00
Andrew Johnson
5f3f87a365 Merge Bruce Hill's MAKEFLAGS-to-MFLAGS branch into 3.15
Added a couple other places where this needed to happen too.
2018-11-02 18:14:39 -05:00
Andrew Johnson
072dbd53e7 Adjust clean-tests rule
Only delete test-result files that actually exist.
2018-11-02 17:47:13 -05:00
Bruce Hill
43322335df Add -V flag to ca client tools to show EPICS and CA versions. 2018-10-31 22:22:19 -07:00
Martin Konrad
eed208afaa Fix shebang line of tap-to-junit-xml.pl
This fixes lp:1797634.
2018-10-12 17:09:26 -04:00
Ralph Lange
ae63854dff Set version to 3.15.6-DEV, prepare new release notes chapter 2018-10-11 15:33:31 +02:00
Ralph Lange
ce7943fb44 Update version to 3.15.6, remove "not released" from release notes 2018-10-11 15:24:36 +02:00
Ralph Lange
4e865a03d8 libCom/osi: fix epicsEnvUnset for WIN32 and solaris 2018-10-11 15:12:10 +02:00
Ralph Lange
9a4febd3bc Merge Dirk Zimoch's 'epicsEnvUnset' branch into 3.15 2018-10-11 11:42:19 +02:00
Andrew Johnson
dc5d373b57 Revert "configure: add vpath for CONFIG* and RULES* (look in SRC_DIRS)"
Unfortunately this causes really bad things to happen; the
configure/RULES file is getting overwritten by the contents of
src/libCom/as/RULES, so we need a different approach.

This reverts commit 47c361f135.
2018-10-10 13:04:54 -05:00
Ralph Lange
47c361f135 configure: add vpath for CONFIG* and RULES* (look in SRC_DIRS) 2018-10-10 17:10:14 +02:00
Ralph Lange
9943796f7f libCom/osi: fix recent epicsStdio.h change for gcc 2.x 2018-10-08 15:46:50 +02:00
3cb72ec209 Merge branch '3.15' into epicsEnvUnset
Conflicts:
	documentation/RELEASE_NOTES.html
2018-10-08 11:02:03 +02:00
701ef5b936 mention epicsEnvUnset in RELEASE_NOTES.html 2018-10-08 10:49:25 +02:00
c3995a9d63 added simple test case for epicsEnvUnset 2018-10-08 10:48:09 +02:00
ce3eadde34 add missing epicsEnvUnset to header 2018-10-08 10:37:34 +02:00
Andrew Johnson
62929fcbd1 Adjust the 'git archive' commands in Release Checklist
The tarfile should not include any files that were added to
support our development process and CI build agents. I have
even excluded .gitignore from previous releases.

I had already done this in 3.16, and 7.0 has a script for
generating the tarfile.
2018-10-05 17:43:33 -05:00
Ralph Lange
456a68eb96 Version number update to 3.15.6-rc1-DEV 2018-10-05 17:05:23 +02:00
Ralph Lange
b319b4722f Update version to 3.15.6-rc1 2018-10-05 15:21:58 +02:00
Ralph Lange
b4cc5fdf4b doc: update release checklist 2018-10-05 15:21:57 +02:00
Ralph Lange
d35835659c libCom/osi: Add epicsStdio functions to std namespace; allow to skip macro magic
(fixes lp:1786927)
2018-10-05 10:54:10 +02:00
65714033ea remove compiler warning 2018-10-03 15:29:30 +02:00
7151fbe498 implement epicsEnvUnset 2018-10-03 15:18:59 +02:00
Andrew Johnson
cbb13bf6b1 Darwin: Don't link using -flat_namespace 2018-09-18 10:22:29 -05:00
Andrew Johnson
150d764d28 Merge 3.14.12.8 (+ the Travis fix) into 3.15 2018-09-17 16:15:55 -05:00
Andrew Johnson
7dd1ea4cab GNU Make 3.81 (as used on Travis) doesn't have 'undefine' 2018-09-17 10:24:51 -05:00
Andrew Johnson
922ed30136 Set EPICS_DEV_SNAPSHOT for the final 3.14.12.8 release 2018-09-14 13:44:05 -05:00
Andrew Johnson
9f9f119e7e Release notes about iocLogServer 2018-09-14 13:21:06 -05:00
Andrew Johnson
d8214a4531 Merge Martin Konrad's fix-logserver-file-limit branch into 3.14 2018-09-14 12:24:14 -05:00
Andrew Johnson
120b100e7e startup: Fix EHA argument quoting per J. Lewis Muir 2018-09-14 12:15:29 -05:00
Andrew Johnson
949e9d788a Make startup/EpicsHostArch script executable 2018-09-14 11:23:14 -05:00
Martin Konrad
27c6e6a385 Make EpicsHostArch compatible with sh 2018-09-14 09:12:10 -04:00
Andrew Johnson
4b59476170 Merge branch 'tidy-startup' into 3.14 2018-09-13 16:49:21 -05:00
Andrew Johnson
526b565c6b configure/CONFIG: Undefine EHA after use 2018-09-10 18:19:03 -05:00
Andrew Johnson
1b7b2bcceb Update README's list of files 2018-09-10 18:16:16 -05:00
Andrew Johnson
49c925d064 Fix shebang line in makeInstallDir.pl 2018-09-10 16:08:19 -05:00
Ralph Lange
6a2ed4b333 libcom/osi/windows: log errors using fprintf() instead of pop-up
(fixes lp:1785712)
2018-09-05 21:47:25 +02:00
Andrew Johnson
d3bcf5737f Latest Xcode also doesn't like compiling system() for iOS 2018-08-17 14:57:22 -05:00
Andrew Johnson
6c5505ad3e osiClockTime again: Don't compile ClockTimeSync() on iOS either 2018-08-17 13:48:00 -05:00
Andrew Johnson
4247d98b08 Add fix to Release Notes 2018-08-17 13:25:18 -05:00
Andrew Johnson
13735a8088 Fix for lp: #1786320
A dbCa link that reads an enum as a string subscribes to the link target
twice, once as DBR_TIME_ENUM and again as DBR_TIME_STRING. This change
prevents ENUM updates from triggering CP/CPP record processing if there
is also a STRING subscription for this link.
2018-08-17 13:18:47 -05:00
Andrew Johnson
58d4242b68 osiClockTime: Only call clock_setting() on embedded OSs
An update to Apple's XCode broke the iOS build because they have
added Posix CLOCK_REALTIME support since this code was written and
now if you compile a call to clock_settime() it stops the build.
2018-08-17 13:09:33 -05:00
Martin Konrad
8e42f516b0 iocLogserver: allow log file limit to be disabled
According to the Application Developer's Guide setting the environment
variable EPICS_IOC_LOG_FILE_LIMIT=0 should disable the limit on the
file size.
2018-08-13 18:16:26 -04:00
Andrew Johnson
9051cdbb34 Added a simpler startup/EpicsHostArch for backwards-compatibility
Many downstream modules seem to be using the EpicsHostArch script in
their CI build scripts and would break if we remove that. I created
a new version that finds and execs the Perl script directly.

Also reworded and expanded the Release Notes about the EpicsHostArch
scripts.
2018-08-10 15:20:29 -05:00
Andrew Johnson
8ffea9de27 Remove macLib warning indicators
Only add ',undefined' tags to macLib output when we aren't
suppressing warnings, e.g. using msi's -V flag.
2018-08-10 14:12:19 -05:00
Andrew Johnson
2548a37267 Update/clean up EpicsHostArch.pl 2018-08-08 16:53:32 -05:00
Andrew Johnson
1dc1b25aaa caget.pl: Add missing acks and ackt metadata to display output 2018-07-31 17:58:38 -05:00
Andrew Johnson
fb31dd784b recGbl: Prevent record alarm severities > INVALID_ALARM 2018-07-31 16:30:11 -05:00
Andrew Johnson
fe7260e263 msi: Source code reformatting, typo fixes, unify messages
Added lots of debug tracing macros.
Release notes.
2018-07-25 00:47:18 -05:00
Andrew Johnson
67e2b74758 Fix for lp: #1503661
Delete output file if parse errors found in substitution file
2018-07-25 00:31:48 -05:00
Andrew Johnson
c09b6e2f1b libCom: Add and use a -o<filename> option to e_flex
Note that like the -S option the filename must follow immediately in
the same command-line argument with no space.
2018-07-21 01:47:33 -05:00
Andrew Johnson
45be2306bd Add missing includes for db_post_events() 2018-07-21 01:04:05 -05:00
Andrew Johnson
6027f906c3 Merge documentation changes from 3.14 into 3.15 2018-07-20 23:29:47 -05:00
Andrew Johnson
ec351c5e2f Fix for lp: #1730727
Post monitors on all array-length record fields (often NORD)
when their values get changed.
2018-07-20 23:10:34 -05:00
89870e2817 Remove trailing space in license of startup/unix.* 2018-07-20 17:47:39 -05:00
4e9cf72d71 Remove execute file mode bit on EpicsHostArch.pl 2018-07-20 17:45:47 -05:00
80869a0868 Rewrite startup/windows.bat
Remove extraneous things unrelated to EPICS Base.

Make it behave consistently with the other startup scripts.

Make it easy to configure both for a human and a program.
2018-07-20 17:43:01 -05:00
998fa984ba Rewrite startup/win32.bat
Remove extraneous things unrelated to EPICS Base.

Make it behave consistently with the other startup scripts.

Make it easy to configure both for a human and a program.
2018-07-20 17:39:29 -05:00
31844af88e Rewrite startup/unix.csh
Remove extraneous things unrelated to EPICS Base.

Make it behave consistently with the other startup scripts.

Make it easy to configure both for a human and a program.
2018-07-20 17:29:47 -05:00
8f161f9463 Rewrite startup/unix.sh
Remove extraneous things unrelated to EPICS Base.

Make it behave consistently with the other startup scripts.

Make it easy to configure both for a human and a program.
2018-07-20 17:18:22 -05:00
e0399478ad Remove startup/cygwin.bat
Cygwin is no longer supported for Microsoft API builds, so remove it.
2018-07-20 17:14:43 -05:00
Andrew Johnson
2a2a1e54ac Post-tag version number update 2018-07-19 12:35:40 -05:00
Andrew Johnson
20d2cff501 Update version number to 3.14.12.8-rc1 2018-07-19 12:31:52 -05:00
Andrew Johnson
860ce156a2 Documentation updates for 3.14.12.8 2018-07-19 12:20:41 -05:00
Andrew Johnson
0f21196670 Merge 3.14 branch into 3.15 2018-07-13 13:23:11 -05:00
Andrew Johnson
31fc35fbe8 dbCa: Fix for lp: #541221
I'd looked at this a few times since it was reported, but never
actually fixed the bug I described in the comments. Apparently
the only thing left to do was to store the eventId and use it to
clear the subscription when we saw a type-change to a PV.
2018-07-13 13:05:54 -05:00
Andrew Johnson
f892731b3f Fix epicsCalcTest for gcc 7.1.0 on minGW
Another case where the compile-time evaluation returns +1
but at run-time isnan() returns -1.
2018-06-29 15:03:45 -05:00
ab493264b2 Make EpicsHostArch.pl print newline
Print a newline after the EPICS host architecture spec.  This is typical
for a UNIX-like program (e.g., date).
2018-06-26 17:56:58 -05:00
68779943eb Remove execute file mode bit 2018-06-26 16:34:04 -05:00
7a5ff26984 Remove EpicsHostArch 2018-06-26 16:20:07 -05:00
eae59183cc Rename Site.{cshrc,profile} to unix.{csh,sh} 2018-06-26 16:09:04 -05:00
Andrew Johnson
8144d2ea01 Add HOWTO: Converting Wiki Record Reference to POD 2018-06-26 14:47:59 -05:00
Andrew Johnson
b32629c3bf Start release notes for tidy-startup branch. 2018-06-26 11:23:35 -05:00
Andrew Johnson
220e404203 Move EpicsHostArch.pl into src/tools, install to lib/perl 2018-06-26 11:23:15 -05:00
Andrew Johnson
8f55a1307d startup: Update win*.bat files 2018-06-22 14:54:06 -05:00
Ralph Lange
e459e8bdd4 cas: don't spin on zero-length search requests
(fix lp:1743321)
2018-06-07 11:32:16 +02:00
Ralph Lange
b558bd9b16 Cherry-picking e794639e from 3.15
(lp:1730982 lp:1762543)
2018-06-07 11:21:04 +02:00
Michael Davidsaver
3c16c3c0da Cherry-picking d2b0e920 from 3.15
(closes lp:1773373)
2018-06-07 11:07:29 +02:00
Andrew Johnson
a9d7f7be13 Template iocBoot/ioc Makefile fix for Unix-like OSs
Fixes lp: #1766349
2018-06-04 23:14:45 -05:00
Andrew Johnson
23c4eb42a3 Perl s/use vars/our/ 2018-05-28 17:31:16 -05:00
Andrew Johnson
6d7f70f200 Merge changes from 3.14 branch into 3.15 2018-05-28 17:00:35 -05:00
Andrew Johnson
67844bacc3 Perl s/use vars/our/ 2018-05-28 16:13:14 -05:00
Ralph Lange
7e7d230d8c templates: fix warnings for xxxRecord.c in exampleApp
(fixes #1772833)
2018-05-23 09:24:56 +02:00
Andrew Johnson
c1ece40f41 Updated Release Notes for Base-3.14.12.8 2018-05-19 22:42:23 -05:00
Andrew Johnson
a732539eee epicsMath.h defines 'finite()' not 'isfinite()' 2018-05-19 21:14:36 -05:00
Ralph Lange
3bc0805a89 rec: fix missing includes in longin/longout 2018-05-18 09:54:42 +02:00
Ralph Lange
c72e35c769 Merge Ralph's fix-1770292 branch into 3.14 2018-05-17 17:16:07 +02:00
Ralph Lange
2d9c5e99a1 db: correctly convert NaN alarm levels to integers
(fixes lp #1771298)
2018-05-15 11:18:11 +02:00
Ralph Lange
ca22d50831 rec: consistent get_alarm_double() for longin/longout
(fixes lp #1770292)
2018-05-15 11:18:10 +02:00
Michael Davidsaver
4972803ce2 scanEventTest: use testSyncCallback() 2018-05-14 10:49:49 -07:00
Michael Davidsaver
3b7e348a8c dbUnitTest.h add callback sync. and global mutex
Add testSyncCallback() to wait for in queued and
in-progress callbacks to complete.

Also add testGlobalLock() to help tests avoid
use after free when destroying sync. primitives.
2018-05-14 10:49:49 -07:00
Michael Davidsaver
00a974ce52 callback.h: add epicsCallback alternative to CALLBACK
Add epicsCallback as an IDE friendly alternative to CALLBACK.

IDEs like qtcreator have long been confused by the use
of CALLBACK, a name which has long been used by other libraries,
which prevents code using it from being parsed correctly.
2018-05-14 10:49:49 -07:00
Michael Davidsaver
490c504736 scanEventTest: use dbUnitTest.h for IOC lifecycle 2018-05-14 10:49:49 -07:00
Andrew Johnson
49371cfe00 Fix RTEMS build in src/std/rec/test
Also back-ported Michael's change from commit b9b8cde5f6 to avoid
using callocMustSucceed() in eventNameToHandle()
2018-05-12 22:25:15 -05:00
Andrew Johnson
06ad4a0d70 Merge Bruce Hill's pv-name-in-ca-error-msgs branch into 3.15
Actually this is fixing CAS error messages.
I added the additional changes suggested by Ralph in his code-review.
2018-05-12 21:37:44 -05:00
Andrew Johnson
a2ae07dfcd Merge Dirk Zimoch's named-events-backward-compatibility branch into 3.15 2018-05-12 21:15:26 -05:00
Andrew Johnson
b539ced6d5 Merge J. Lewis Muir's doc-filters-typo branch into 3.15 2018-05-12 20:54:20 -05:00
Andrew Johnson
1b332361e7 Merge changes from 3.14 into 3.15 2018-05-12 20:47:54 -05:00
Andrew Johnson
5cb91d9f6d Merge Ben Franksen's deadlock_warning branch into 3.14 2018-05-12 20:20:30 -05:00
Andrew Johnson
116c90c2ea Reformatting, no code changes 2018-05-03 14:40:12 -05:00
Andrew Johnson
3f3696fb91 dbStatic: Prevent modifying a NAME field using a DB file
Fixes LP: #1597809
2018-05-03 14:28:44 -05:00
Bruce Hill
b84ee89d87 Fix ECHO definition to not match variables in MAKEFLAGS by using MFLAGS instead.
Prior ECHO definition strips T_A=XXX command line variable definitions
from MAKEFLAGS but doesn't strip other variable definitions such as
INSTALL_LOCATION.  As a result, if you "make INSTALL_LOCATION=XXX"
the ECHO definition erroneously matches if your install location
contains 's'.   Changing the ECHO definition to MFLAGS avoids
all command line variable definitions.
2018-04-16 19:11:40 -07:00
Benjamin Franksen
91ce807e8b Fix for lp: #1751380
Add warnings about possible deadlock to the docs for ca_clear_channel,
ca_clear_subscription, and ca_context_destroy.
2018-04-11 12:58:28 +02:00
Andrew Johnson
3d88316eab Merge 3.14 into 3.15 (MSVC absolute filenames fix) 2018-03-26 16:49:28 -05:00
Andrew Johnson
b9443f8813 Tell MSVC to use absolute filenames in diagnostics (-FC flag) 2018-03-23 11:39:53 -05:00
Andrew Johnson
d8802c8b24 Merge 3.14 into 3.15 2018-03-15 17:46:48 -05:00
Andrew Johnson
b7d4609e57 Merge Bruce Hill's camonitor-server-relative-ts-bug-3.14 branch 2018-03-15 17:33:32 -05:00
Andrew Johnson
7b5b23f6d3 Merge 3.14 into 3.15 2018-03-15 17:11:20 -05:00
Andrew Johnson
c8a7e1597d VxWorks Timezone updates
Remove 2017; fix hour in MET settings
2018-03-15 10:57:55 -05:00
Andrew Johnson
8333338f99 Merge 3.14 into 3.15 2018-03-14 16:08:07 -05:00
Andrew Johnson
ceaff61c09 Pull in the podToHtml.pl script and rules from 3.15
This lets src/cap5 build with Perl installations that lack Perl's
podchecker and pod2html scripts (e.g. Fedora 27).
2018-03-14 14:12:12 -05:00
Andrew Johnson
2307e94d1c Rules for building bootable TESTPROD_RTEMS targets
Previously if you wanted a .boot file it had to be installed.
2018-03-12 16:34:54 -05:00
Bruce Hill
05a3699b49 Update pcas CA error msgs to include the pv name for easier debugging. 2018-03-09 21:23:43 -08:00
Andrew Johnson
be8f35d782 Fix for lp: #1754298
Cleaned up and reformatted since Dirk's original.
2018-03-09 12:46:46 -06:00
Bruce Hill
6cc623a7b4 Fixed camonitor server side relative timestamps bug
tsFirst needs to get initialized from the first server side
timestamp instead of the client side tsNow.
2018-03-08 01:40:11 -08:00
2b4a9632b7 update RELEASE_NOTES for named event fix 2018-03-07 14:51:38 +01:00
396cf4ee3f remove special handling for inf and nan events 2018-03-07 14:49:12 +01:00
Andrew Johnson
a9764c8f62 tools/caput: Report errors from ca_array_put*()
Fixes LP: #1747983
2018-03-04 15:51:39 -06:00
Andrew Johnson
98d9ea4545 ca/client: Catch by reference, missing '&' 2018-03-04 15:45:15 -06:00
Andrew Johnson
8eb4eec7d2 Corrected fix from Bruce Hill's Github PR#19 2018-03-03 17:17:34 -06:00
Andrew Johnson
98930eebc4 strcpy() -> strncpy() changes from Bruce Hill
Also added some additional static assertions for string field sizes.
2018-03-03 00:12:59 -06:00
e50c468512 moved scanEventTest from src/ioc/db/test to src/std/rec/test 2018-02-26 11:41:54 +01:00
Andrew Johnson
c18b6f2ccf Deny use of dbgf, dbpf, dbtr, dbtgf and dbtpf before iocInit
Can't use locking dbAccess routines until lock-sets have been calculated.
Fixes LP: #1725248
2018-02-24 20:15:08 -06:00
Andrew Johnson
e41f8bf518 Translate and escape chars in info tag strings
Fixes LP: #1716998
2018-02-24 19:11:54 -06:00
Andrew Johnson
ae548d3400 Remove cantProceed() from dbGetLink() and dbPutLink()
Fixes LP: #1528314
Affects 3.15 branch only.
2018-02-24 17:40:45 -06:00
428a8f57e9 Fix typos in Channel Filters doc 2018-02-20 10:20:37 -06:00
29795656e6 bugfix for soft events >= 256 2018-02-20 09:53:06 +01:00
b2d6b67b06 removed obsolete code in scanpel 2018-02-16 11:03:12 +01:00
1e9826d187 add tests for calculated numeric soft events 2018-02-13 15:36:21 +01:00
0691fc5f57 fix scanEvent test 2018-02-13 14:10:29 +01:00
8a3080c16f added test for named soft events 2018-02-13 13:50:19 +01:00
d19afc73af Updated RELEASE_NOTES.html with soft event fix. 2018-02-12 12:06:12 +01:00
adf5375616 fix scanpel glob matching 2018-02-12 09:01:05 +01:00
Andrew Johnson
550beeab9f More clang warning clean-ups
The short => int change is a UB issue, the second argument to va_start()
must be of a type that does not undergo promotion. See
https://wiki.sei.cmu.edu/confluence/display/cplusplus/EXP58-CPP.+Pass+an+object+of+the+correct+type+to+va_start
2018-02-09 11:29:16 -06:00
Andrew Johnson
bf91275200 Merge clang fixes from 3.14 into 3.15 2018-02-09 11:16:26 -06:00
Andrew Johnson
ac4d5c95ac Clean up some compiler warnings from clang 2018-02-09 10:56:52 -06:00
7d836d9554 some cleanup and scanpel improvement 2018-02-09 16:58:36 +01:00
51e492fbb1 Fix numeric events: any number from 0 up to less than 256 is theated as an integer event. Event 0 is no event. 2018-02-09 14:37:45 +01:00
Andrew Johnson
61296b8cff Merge 3.14 into 3.15
Fix for LP: #1743076
2018-02-05 12:03:28 -06:00
Andrew Johnson
de442e9584 Fix for LP: #1743076
Never zero the CA client context private ID.
2018-02-05 12:02:13 -06:00
Andrew Johnson
ac367398b3 Merge fix for lp: #1747091 from 3.14 into 3.15 2018-02-02 17:49:00 -06:00
Andrew Johnson
713c2d5080 Fix for lp: #1747091
generalTimeGetEvent()
2018-02-02 17:47:35 -06:00
Andrew Johnson
af07016464 Merge 3.14 branch into 3.15
Actually a different fix to Michael's 3.14 commit due to divergent code.
2018-02-01 14:20:47 -06:00
Michael Davidsaver
734d16291f rsrv: buffer for IP too small
An IPv4 address and port number
has 21 characters max.
2018-02-01 09:42:51 -08:00
Andrew Johnson
f1e5e9689b Merge 3.14 branch into 3.15 2018-02-01 11:23:29 -06:00
Andrew Johnson
1454f42a27 Config fix for parallel builds with MSVC 2015 and later
From Mark Rivers and Freddie Akeroyd.
2018-02-01 11:19:08 -06:00
Andrew Johnson
ddbdcf9462 rec/test: Add missing filename to DBDDEPENDS_FILES 2018-01-21 00:44:10 -06:00
Andrew Johnson
729e6fda4d tools: Add some context to the 'Undefined macro' warning
Mark Rivers saw this warning when he forgot to configure and build a
dependent module properly. The additional information given by this
change would have helped him track down the problem faster.
2018-01-19 13:14:13 -06:00
Andrew Johnson
0315e90e6e Revert "tools: Use Carp"
This reverts commit f207b00b05.

None of these warn/die messages request a stack dump since they all
end with \n, but carp & croak ignore that.
2018-01-19 11:06:23 -06:00
Andrew Johnson
66c6aaa44f Merge URL updates from 3.14 branch into 3.15 2018-01-18 23:46:42 -06:00
Andrew Johnson
c830a3a4ee Updated links to new EPICS website at Argonne
Only done for documents that are still present in EPICS 7.
2018-01-18 23:35:09 -06:00
Andrew Johnson
8766ce05aa Fix slow callback test failures.
Slow callbacks no longer cause test failures, now they just emit a
diagnostic. Jenkins on MacOS frequently failed those tests.

We should never test for something that we can't fix.
2018-01-04 11:41:38 -06:00
Ralph Lange
8f62940265 Merge appveyor change from 3.14 2018-01-04 09:03:50 +01:00
Ralph Lange
8a1477ecab appveyor-ci: update APS download URL 2018-01-04 09:00:18 +01:00
Ralph Lange
89cbb95c2c Merge appveyor changes from 3.14 2017-12-19 09:52:15 +01:00
Ralph Lange
006ce1a240 appveyor-ci: remove VS 2008, add VS 2017 2017-12-19 09:39:57 +01:00
Ralph Lange
276dee2c3e appveyor-ci: use curl for download of make.zip 2017-12-19 09:39:10 +01:00
Andrew Johnson
98a2871727 Reset SNAPSHOT to -DEV after tagging 3.14.12.7 2017-12-15 16:09:21 -06:00
Andrew Johnson
5ca1bb3bd5 Set SNAPSHOT for 3.14.12.7 final release 2017-12-15 16:06:08 -06:00
Andrew Johnson
f6be3c7f70 Set snapshot to -rc1-DEV 2017-12-08 16:40:08 -06:00
Andrew Johnson
00924dcba0 About to tag 3.14.12.7-rc1 2017-12-08 16:37:03 -06:00
Andrew Johnson
3b0f34e0be Fix recursive check in Release.pm 2017-12-06 16:29:31 -06:00
263 changed files with 18914 additions and 9517 deletions

2
README
View File

@@ -20,5 +20,5 @@ Additional information about EPICS including mailing list
archives and subscription instructions, documentation and
training materials, additional components, links to other
websites etc. is available on the EPICS home page at
http://www.aps.anl.gov/epics/
https://epics.anl.gov/

View File

@@ -40,13 +40,14 @@ configuration:
# Environment variables: compiler toolchain
environment:
matrix:
- TOOLCHAIN: 9.0
- TOOLCHAIN: 10.0
- TOOLCHAIN: 11.0
- TOOLCHAIN: 12.0
- TOOLCHAIN: 14.0
- TOOLCHAIN: cygwin
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLCHAIN: 2017
- TOOLCHAIN: mingw
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# Platform: architecture
platform:
@@ -57,11 +58,10 @@ platform:
matrix:
exclude:
# VS Express installs don't have the 64 bit compiler
- platform: x64
TOOLCHAIN: 9.0
- platform: x64
TOOLCHAIN: 10.0
#---------------------------------#
# building & testing #
#---------------------------------#
@@ -81,6 +81,9 @@ test_script:
notifications:
- provider: Slack
incoming_webhook:
secure: RYOm3FIUYeZGjWKaeTVKwq+C3fzK54AKwbmAoECED45mex3lN+8HmrC845a6mg9xPUJ/ND51RopWVaKDD9/UzaM0SO195RQLKqUTIUafiuM=
- provider: Email
to:
- core-talk@aps.anl.gov
on_build_success: false
- provider: GitHubPullRequest

View File

@@ -1,6 +1,6 @@
:: Universal build script for AppVeyor (https://ci.appveyor.com/)
:: Environment:
:: TOOLCHAIN - toolchain version [9.0/10.0/11.0/12.0/14.0/cygwin/mingw]
:: TOOLCHAIN - toolchain version [10.0/11.0/12.0/14.0/2017/mingw]
:: CONFIGURATION - determines EPICS build [dynamic/static]
:: PLATFORM - architecture [x86/x64]
::
@@ -20,35 +20,17 @@ echo [INFO] Platform: %OS%
set "MAKEARGS=-j2 -Otarget"
if "%APPVEYOR_REPO_BRANCH%"=="3.14" set MAKEARGS=
if "%TOOLCHAIN%"=="cygwin" (
set "MAKE=make"
if "%OS%"=="64BIT" (
set "EPICS_HOST_ARCH=cygwin-x86_64"
set "INCLUDE=C:\cygwin64\include;%INCLUDE%"
set "PATH=C:\cygwin64\bin;%PATH%"
echo [INFO] Cygwin Toolchain 64bit
) else (
set "EPICS_HOST_ARCH=cygwin-x86"
set "INCLUDE=C:\cygwin\include;%INCLUDE%"
set "PATH=C:\cygwin\bin;%PATH%"
echo [INFO] Cygwin Toolchain 32bit
)
echo [INFO] Compiler Version
gcc -v
goto Finish
)
if "%TOOLCHAIN%"=="mingw" (
set "MAKE=mingw32-make"
if "%OS%"=="64BIT" (
set "EPICS_HOST_ARCH=windows-x64-mingw"
set "INCLUDE=C:\tools\mingw64\include;%INCLUDE%"
set "PATH=C:\tools\mingw64\bin;%PATH%"
set "INCLUDE=C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\include;%INCLUDE%"
set "PATH=C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;%PATH%"
echo [INFO] MinGW Toolchain 64bit
) else (
set "EPICS_HOST_ARCH=win32-x86-mingw"
set "INCLUDE=C:\tools\mingw32\include;%INCLUDE%"
set "PATH=C:\tools\mingw32\bin;%PATH%"
set "INCLUDE=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\include;%INCLUDE%"
set "PATH=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin;%PATH%"
echo [INFO] MinGW Toolchain 32bit
)
echo [INFO] Compiler Version
@@ -57,10 +39,22 @@ if "%TOOLCHAIN%"=="mingw" (
)
set "VSINSTALL=C:\Program Files (x86)\Microsoft Visual Studio %TOOLCHAIN%"
if not exist "%VSINSTALL%\" set "VSINSTALL=C:\Program Files (x86)\Microsoft Visual Studio\%TOOLCHAIN%\Community"
if not exist "%VSINSTALL%\" goto MSMissing
set "MAKE=C:\tools\make"
echo [INFO] APPVEYOR_BUILD_WORKER_IMAGE=%APPVEYOR_BUILD_WORKER_IMAGE%
if "%OS%"=="64BIT" (
set EPICS_HOST_ARCH=windows-x64%ST%
:: VS 2017
if exist "%VSINSTALL%\VC\Auxiliary\Build\vcvars64.bat" (
call "%VSINSTALL%\VC\Auxiliary\Build\vcvars64.bat"
where cl
if !ERRORLEVEL! NEQ 0 goto MSMissing
goto MSFound
)
if exist "%VSINSTALL%\VC\vcvarsall.bat" (
call "%VSINSTALL%\VC\vcvarsall.bat" amd64
where cl
@@ -79,12 +73,19 @@ if "%OS%"=="64BIT" (
)
) else (
set EPICS_HOST_ARCH=win32-x86%ST%
:: VS 2017
if exist "%VSINSTALL%\VC\Auxiliary\Build\vcvars32.bat" (
call "%VSINSTALL%\VC\Auxiliary\Build\vcvars32.bat"
where cl
if !ERRORLEVEL! NEQ 0 goto MSMissing
goto MSFound
)
if exist "%VSINSTALL%\VC\vcvarsall.bat" (
call "%VSINSTALL%\VC\vcvarsall.bat" x86
where cl
if !ERRORLEVEL! NEQ 0 goto MSMissing
goto MSFound
)
)
if exist "%VSINSTALL%\VC\bin\vcvars32.bat" (
call "%VSINSTALL%\VC\bin\vcvars32.bat"
where cl

View File

@@ -1,12 +1,12 @@
:: Build script for AppVeyor (https://ci.appveyor.com/)
:: Environment:
:: TOOLCHAIN - Toolchain Version [9.0/10.0/11.0/12.0/14.0/cygwin/mingw]
:: TOOLCHAIN - Toolchain Version [9.0/10.0/11.0/12.0/14.0/mingw]
:: CONFIGURATION - determines EPICS build [dynamic/static, -debug]
:: PLATFORM - "x86" -> use 32bit architecture
::
:: Prepares an Appveyor build by excuting the following steps
:: - Set up configure\CONFIG_SITE for static vs. dynamic build
:: - Install Cygwin / Mingw (TOOLCHAIN setting) in the in the appropriate flavor
:: - Install Mingw (TOOLCHAIN setting) in the in the appropriate flavor
:: - Download and install Make-4.1 from EPICS download page
Setlocal EnableDelayedExpansion
@@ -16,31 +16,6 @@ if "%PLATFORM%"=="x86" set OS=32BIT
echo [INFO] Platform: %OS%
if "%TOOLCHAIN%"=="cygwin" (
echo.%CONFIGURATION% | findstr /C:"static">nul && (
echo SHARED_LIBRARIES=NO>> configure\CONFIG_SITE
echo STATIC_BUILD=YES>> configure\CONFIG_SITE
echo [INFO] EPICS set up for static build
) || (
echo [INFO] EPICS set up for dynamic build
)
echo.%CONFIGURATION% | findstr /C:"debug">nul && (
echo HOST_OPT=NO>> configure\CONFIG_SITE
echo [INFO] EPICS set up for debug build
) || (
echo [INFO] EPICS set up for optimized build
)
if "%OS%"=="64BIT" (
echo [INFO] Installing Cygwin 64bit and dependencies
@powershell -Command "(new-object net.webclient).DownloadFile('http://www.cygwin.com/setup-x86_64.exe', 'C:\cygwin64\setup-x86_64.exe')"
C:\cygwin64\setup-x86_64.exe -q -P "libreadline-devel,libncursesw-devel"
) else (
echo [INFO] Installing Cygwin 32bit and dependencies
@powershell -Command "(new-object net.webclient).DownloadFile('http://www.cygwin.com/setup-x86.exe', 'C:\cygwin\setup-x86.exe')"
C:\cygwin\setup-x86.exe -q -P "libreadline-devel,libncursesw-devel"
)
)
if "%TOOLCHAIN%"=="mingw" (
echo.%CONFIGURATION% | findstr /C:"static">nul && (
echo SHARED_LIBRARIES=NO>> configure\CONFIG_SITE
@@ -55,16 +30,9 @@ if "%TOOLCHAIN%"=="mingw" (
) || (
echo [INFO] EPICS set up for optimized build
)
if "%OS%"=="64BIT" (
echo [INFO] Installing MinGW 64bit
cinst mingw || cinst mingw
) else (
echo [INFO] Installing MinGW 32bit
cinst mingw --x86 || cinst mingw --x86
)
)
echo [INFO] Installing Make 4.1
@powershell -Command "(new-object net.webclient).DownloadFile('https://www.aps.anl.gov/epics/download/tools/make-4.1-win64.zip', 'C:\tools\make-4.1.zip')"
echo [INFO] Installing Make 4.2.1 from ANL web site
curl -fsS --retry 3 -o C:\tools\make-4.2.1.zip https://epics.anl.gov/download/tools/make-4.2.1-win64.zip
cd \tools
"C:\Program Files\7-Zip\7z" e make-4.1.zip
"C:\Program Files\7-Zip\7z" e make-4.2.1.zip

View File

@@ -17,7 +17,7 @@ ticker() {
CACHEKEY=1
EPICS_HOST_ARCH=`sh startup/EpicsHostArch`
EPICS_HOST_ARCH=`perl src/tools/EpicsHostArch.pl`
[ -e configure/os/CONFIG_SITE.Common.linux-x86 ] || die "Wrong location: $PWD"

View File

@@ -20,11 +20,15 @@ else
endif
# Provide a default if the user hasn't set EPICS_HOST_ARCH
ifeq ($(origin EPICS_HOST_ARCH), undefined)
# NB: We use a simply expanded variable here for performance:
EPICS_HOST_ARCH := $(shell $(CONFIG)/../startup/EpicsHostArch.pl)
endif
#
ifeq ($(origin EPICS_HOST_ARCH), undefined)
# Bootstrapping ...
EHA := $(firstword $(wildcard $(EPICS_BASE)/lib/perl/EpicsHostArch.pl \
$(TOP)/src/tools/EpicsHostArch.pl))
# NB: We use a simply expanded variable here for performance:
export EPICS_HOST_ARCH := $(shell perl $(EHA))
EHA :=
endif
-include $(CONFIG)/RELEASE
-include $(CONFIG)/RELEASE.$(EPICS_HOST_ARCH)

View File

@@ -69,10 +69,11 @@ REGISTERRECORDDEVICEDRIVER = $(PERL) $(TOOLS)/registerRecordDeviceDriver.pl
CONVERTRELEASE = $(PERL) $(call FIND_TOOL,convertRelease.pl)
FULLPATHNAME = $(PERL) $(TOOLS)/fullPathName.pl
TAPTOJUNIT = $(PERL) $(TOOLS)/tap-to-junit-xml.pl
PROVE = $(PERL) $(TOOLS)/epicsProve.pl
#-------------------------------------------------------
# tools for installing libraries and products
INSTALL_QUIETLY := $(if $(findstring s,$(MAKEFLAGS)),-q,)
INSTALL_QUIETLY := $(if $(findstring s,$(MFLAGS)),-q,)
INSTALL = $(PERL) $(TOOLS)/installEpics.pl $(INSTALL_QUIETLY)
INSTALL_PRODUCT = $(INSTALL)
INSTALL_LIBRARY = $(INSTALL)

View File

@@ -27,14 +27,14 @@ EPICS_VERSION = 3
EPICS_REVISION = 15
# EPICS_MODIFICATION must be a number >=0 and <256
EPICS_MODIFICATION = 5
EPICS_MODIFICATION = 7
# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
# Not included if zero
EPICS_PATCH_LEVEL = 0
# This will end in -DEV between official releases
EPICS_DEV_SNAPSHOT=-DEV
#EPICS_DEV_SNAPSHOT=-DEV
#EPICS_DEV_SNAPSHOT=-pre1
#EPICS_DEV_SNAPSHOT=-pre1-DEV
#EPICS_DEV_SNAPSHOT=-pre2
@@ -43,7 +43,7 @@ EPICS_DEV_SNAPSHOT=-DEV
#EPICS_DEV_SNAPSHOT=-rc1-DEV
#EPICS_DEV_SNAPSHOT=-rc2
#EPICS_DEV_SNAPSHOT=-rc2-DEV
#EPICS_DEV_SNAPSHOT=
EPICS_DEV_SNAPSHOT=
# No changes should be needed below here

View File

@@ -82,7 +82,7 @@ IOCS_APPL_TOP = $(shell $(FULLPATHNAME) $(INSTALL_LOCATION))
#-------------------------------------------------------
# Make echo output - suppress echoing if make's '-s' flag is set
NOP = :
ECHO = @$(if $(findstring s,$(patsubst T_A=%,,$(MAKEFLAGS))),$(NOP),echo)
ECHO = @$(if $(findstring s,$(MFLAGS)),$(NOP),echo)
#-------------------------------------------------------
ifdef T_A

View File

@@ -24,45 +24,41 @@
# Site-specific environment settings
# Time service:
# EPICS_TIMEZONE
# Local timezone info for vxWorks and RTEMS. The format is
# <name>::<minutesWest>:<startDST>:<endDST>
# where <name> is only used by strftime() for %Z conversions,
# and <startDST> and <endDST> are mmddhh - that is month,day,hour
# e.g. for ANL in 2018: EPICS_TIMEZONE=CUS::360:031102:110402
# The future dates below assume the rules don't get changed;
# see http://www.timeanddate.com/time/dst/2018.html to check.
#
# DST for 2017 US: Mar 12 - Nov 05
# EU: Mar 26 - Oct 29
EPICS_TIMEZONE = CUS::360:031202:110502
#EPICS_TIMEZONE = MET::-60:032602:102902
#
# DST for 2018 US: Mar 11 - Nov 04
# EU: Mar 25 - Oct 28
#EPICS_TIMEZONE = CUS::360:031102:110402
#EPICS_TIMEZONE = MET::-60:032502:102802
#
# DST for 2019 US: Mar 10 - Nov 03
# EU: Mar 31 - Oct 27
#EPICS_TIMEZONE = CUS::360:031002:110302
#EPICS_TIMEZONE = MET::-60:033102:102702
#
# DST for 2020 US: Mar 08 - Nov 01
# EU: Mar 29 - Oct 25
#EPICS_TIMEZONE = CUS::360:030802:110102
#EPICS_TIMEZONE = MET::-60:032902:102502
#
# DST for 2021 US: Mar 14 - Nov 07
# EU: Mar 28 - Oct 31
#EPICS_TIMEZONE = CUS::360:031402:110702
#EPICS_TIMEZONE = MET::-60:032802:103102
#
# DST for 2022 US: Mar 13 - Nov 06
# EU: Mar 27 - Oct 30
#EPICS_TIMEZONE = CUS::360:031302:110602
#EPICS_TIMEZONE = MET::-60:032702:103002
## Time service:
# EPICS_TZ
# Local timezone rules for vxWorks and RTEMS. The value follows the Posix
# TZ environment variable's Mm.n.d/h format (see the IBM link below for
# details). If TZ hasn't already been set when the osdTime timeRegister()
# C++ static constructor runs, this parameter will be copied into the TZ
# environment variable. Once the OS clock has been synchronized to NTP the
# routine tz2timezone() will be run to convert TZ into the TIMEZONE
# variable format that VxWorks needs.
# https://developer.ibm.com/articles/au-aix-posix/
# Japan Standard Time, no DST:
#EPICS_TZ = "JST-9"
# Central European (Summer) Time:
#EPICS_TZ = "CET-1CEST,M3.5.0/2,M10.5.0/3"
# Greenwich Mean/British Summer Time:
#EPICS_TZ = "GMT0BST,M3.5.0/1,M10.5.0/2"
# US Eastern Standard/Daylight Time:
#EPICS_TZ = "EST5EDT,M3.2.0/2,M11.1.0/2"
# US Central Standard/Daylight Time:
EPICS_TZ = "CST6CDT,M3.2.0/2,M11.1.0/2"
# US Mountain Standard/Daylight Time:
#EPICS_TZ = "MST7MDT,M3.2.0/2,M11.1.0/2"
# US Pacific Standard/Daylight Time:
#EPICS_TZ = "PST8PDT,M3.2.0/2,M11.1.0/2"
# US Hawaiian Standard Time, no DST:
#EPICS_TZ = "HST10"
# EPICS_TS_NTP_INET
# NTP time server ip address for VxWorks and RTEMS.

View File

@@ -102,6 +102,7 @@ endif
# Products and Object libraries
#
PRODTARGETS += $(PRODNAME) $(MUNCHNAME) $(CTDT_SRCS) $(CTDT_OBJS) $(NMS)
TESTPRODTARGETS += $(TESTPRODNAME) $(TESTMUNCHNAME)
#---------------------------------------------------------------
# Test specifications and test result files
@@ -140,7 +141,7 @@ rebuild: clean install
build: inc
build: $(OBJSNAME) $(LIBTARGETS) $(PRODTARGETS) $(TESTPRODNAME) \
build: $(OBJSNAME) $(LIBTARGETS) $(PRODTARGETS) $(TESTPRODTARGETS) \
$(TARGETS) $(TESTSCRIPTS) $(INSTALL_LIB_INSTALLS)
inc : $(COMMON_INC) $(INSTALL_INC) $(INSTALL_CONFIGS)
@@ -158,20 +159,21 @@ clean: build_clean
build_clean:
$(ECHO) "Cleaning"
@$(RM) *.i *$(OBJ) *.a $(TESTPRODNAME) \
@$(RM) *.i *$(OBJ) *.a \
$(LIBNAME) $(TESTLIBNAME) $(SHRLIBNAME) $(TESTSHRLIBNAME) \
$(DLLSTUB_LIBNAME) $(TESTDLLSTUB_LIBNAME) \
$(LOADABLE_SHRLIBNAME) \
$(INC) $(TARGETS) $(TDS) $(CLEANS) \
*.out MakefileInclude *.manifest *.exp \
$(COMMON_INC) $(HDEPENDS_FILES) $(PRODTARGETS) \
$(COMMON_INC) $(HDEPENDS_FILES) $(PRODTARGETS) $(TESTPRODTARGETS) \
$(TESTSCRIPTS) $(TAPFILES) $(JUNITFILES)
ifdef RES
@$(RM) *$(RES)
endif
$(DIRECTORY_TARGETS) :
$(MKDIR) -p $@
# Sort mkdir targets to remove duplicates & make parents first
$(DIRECTORY_TARGETS):
$(MKDIR) $(sort $@)
# Install LIB_INSTALLS libraries before linking executables
$(TESTPRODNAME) $(PRODNAME): | $(INSTALL_LIB_INSTALLS)
@@ -254,15 +256,13 @@ YACCOPT ?= $($*_YACCOPT)
$(MV) $*.tab.c $*.c
$(if $(findstring -d, $(YACCOPT)),$(MV) $*.tab.h $*.h,)
# must be a seperate rule since when not using '-d' the
# must be a separate rule since when not using '-d' the
# prefix for .h will be different then .c
%.h : %.c %.y
%.c: %.l
@$(RM) $*.yy.c
$(LEX) $(LEXOPT) -t $< > $*.yy.c
@$(RM) $@
$(MV) $*.yy.c $@
$(LEX) $(LEXOPT) -o$@ $<
#---------------------------------------------------------------
# Libraries, shared/DLL and stubs
@@ -321,6 +321,10 @@ $(MUNCHNAME): %$(MUNCH_SUFFIX): $(MUNCH_DEPENDS) %$(EXE)
@$(RM) $@
$(MUNCH_CMD)
$(TESTMUNCHNAME): %$(MUNCH_SUFFIX): $(MUNCH_DEPENDS) %$(EXE)
@$(RM) $@
$(MUNCH_CMD)
#---------------------------------------------------------------
# GeSys modules for RTEMS
$(MODNAME): %$(MODEXT): %$(EXE)
@@ -347,16 +351,19 @@ testspec: $(TESTSCRIPTS)
test-results: tapfiles
ifneq ($(TAPFILES),)
ifdef RUNTESTS_ENABLED
prove --failures --ext .tap --exec "$(CAT)" --color $(TAPFILES)
$(PROVE) --failures --ext .tap --exec "$(CAT)" --color $(TAPFILES)
endif
CURRENT_TAPFILES := $(wildcard $(TAPFILES))
CURRENT_JUNITFILES := $(wildcard $(JUNITFILES))
endif
clean-tests:
ifneq ($(TAPFILES),)
$(RM) $(TAPFILES)
ifneq ($(CURRENT_TAPFILES),)
$(RM) $(CURRENT_TAPFILES)
endif
ifneq ($(JUNITFILES),)
$(RM) $(JUNITFILES)
ifneq ($(CURRENT_JUNITFILES),)
$(RM) $(CURRENT_JUNITFILES)
endif
tapfiles: $(TESTSCRIPTS) $(TAPFILES)

View File

@@ -72,7 +72,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,$(patsubst T_A=%,,$(MAKEFLAGS))),$(NOP),echo)
ECHO = @$(if $(findstring s,$(MFLAGS)),$(NOP),echo)
#--------------------------------------------------
# Although RTEMS uses gcc, it wants to use gcc its own way
@@ -136,6 +136,13 @@ MOD_LDFLAGS = $(OPT_LDFLAGS) $(TARGET_LDFLAGS) $(USR_LDFLAGS) $(POSIX_LDFLAGS) \
LINK.mod = $(CCC) -o $@ $(PRODDIR_LDFLAGS) $(MOD_LDFLAGS)
LINK.mod += $(PROD_LDFLAGS) $(PROD_LD_OBJS) $(PROD_LD_RESS) $(MOD_LDLIBS)
#--------------------------------------------------
# Here munching means creating a bootable object binary
ifdef MUNCH_SUFFIX
MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
TESTMUNCHNAME = $(TESTPRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
endif
#--------------------------------------------------
# RTEMS has neither shared libraries nor dynamic loading
STATIC_BUILD=YES

View File

@@ -15,7 +15,6 @@ ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120
OP_SYS_LDLIBS += -lbspExt
MUNCH_SUFFIX = .boot
MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
define MUNCH_CMD
$(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@
endef

View File

@@ -13,7 +13,6 @@ ARCH_DEP_CFLAGS += -DHAVE_PPCBUG
OP_SYS_LDLIBS += -lbspExt
MUNCH_SUFFIX = .boot
MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
define MUNCH_CMD
$(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< rtems
gzip -f9 rtems

View File

@@ -7,7 +7,6 @@ ARCH_DEP_CFLAGS += -DHAVE_PPCBUG
ARCH_DEP_CFLAGS += -DNVRAM_INDIRECT
MUNCH_SUFFIX = .boot
MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
define MUNCH_CMD
$(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< rtems
gzip -f9 rtems

View File

@@ -15,7 +15,6 @@ ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120
OP_SYS_LDLIBS += -lbspExt
MUNCH_SUFFIX = .boot
MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
define MUNCH_CMD
$(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@
endef

View File

@@ -16,7 +16,6 @@ ARCH_DEP_CFLAGS += -DBSP_NVRAM_BASE_ADDR=0xf1110000
OP_SYS_LDLIBS += -lbspExt
MUNCH_SUFFIX = .boot
MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
define MUNCH_CMD
$(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@
endef

View File

@@ -8,7 +8,6 @@
RTEMS_TARGET_CPU=i386
MUNCH_SUFFIX = .boot
MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
define MUNCH_CMD
$(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< temp.bin
$(BIN2BOOT) $@ 0x00097E00 \

View File

@@ -9,7 +9,6 @@ RTEMS_TARGET_CPU = m68k
ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL
MUNCH_SUFFIX = .boot
MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX))
define MUNCH_CMD
$(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< $@
endef

View File

@@ -185,6 +185,12 @@ COMPILE.ctdt = $(CC) -c $(CPPFLAGS) $(CFLAGS_ctdt) $(INCLUDES) $(SOURCE_FLAG)
VXCPPFLAGS = $(filter-out $(OP_SYS_INCLUDE_CPPFLAGS),$(CPPFLAGS))
PREPROCESS.cpp = $(CPP) $(VXCPPFLAGS) $(INCLUDES) $< > $@
#--------------------------------------------------
# Don't use gcc 2.x for dependency generation
HDEPENDS_METHOD_2 = MKMF
HDEPENDS_METHOD = $(firstword $(HDEPENDS_METHOD_$(VX_GNU_MAJOR_VERSION)) COMP)
#--------------------------------------------------
# Allow site overrides
-include $(CONFIG)/os/CONFIG_SITE.Common.vxWorksCommon

View File

@@ -65,14 +65,14 @@ GNU = NO
#
# Darwin shared libraries
#
SHRLIB_LDFLAGS = -dynamiclib -flat_namespace -undefined suppress \
SHRLIB_LDFLAGS = -dynamiclib -undefined dynamic_lookup \
-install_name $(shell $(FULLPATHNAME) $(INSTALL_LIB))/$@ \
$(addprefix -compatibility_version , $(SHRLIB_VERSION)) \
$(addprefix -current_version , $(SHRLIB_VERSION))
SHRLIB_SUFFIX_BASE = .dylib
SHRLIB_SUFFIX = $(addprefix ., $(SHRLIB_VERSION))$(SHRLIB_SUFFIX_BASE)
LOADABLE_SHRLIB_LDFLAGS = -bundle -flat_namespace -undefined suppress
LOADABLE_SHRLIB_LDFLAGS = -bundle -undefined dynamic_lookup
#
# Position-independent code is the default on Darwin.

View File

@@ -79,16 +79,20 @@ CPP = cl -nologo -C -E
# Configure OS vendor C++ compiler
#
# __STDC__=0 gives us both:
# 1) define STDC for code (pretend ANSI conformance)
# 2) set it to 0 to use MS C "extensions" (open for _open etc.)
# because MS uses: if __STDC__ ... disable many nice things
#
# -EHsc - generate code for exceptions
# -GR - generate code for run time type identification
#
CCC = cl -EHsc -GR
CODE_CPPFLAGS += -nologo -D__STDC__=0
# Other compiler flags, used for CPP, C and C++
#
# -FC - Show absolute path of source file in diagnostics
# -D__STDC__=0 gives us both:
# 1) define STDC for code (pretend ANSI conformance)
# 2) set it to 0 to use MS C "extensions" (open for _open etc.)
# because MS uses: if __STDC__ ... disable many nice things
#
CODE_CPPFLAGS += -nologo -FC -D__STDC__=0
CODE_CPPFLAGS += -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
@@ -136,6 +140,16 @@ STATIC_LDLIBS_NO=
STATIC_LDFLAGS=
RANLIB=
#
# option needed for parallel builds with Visual Studio 2015 onward
#
# -FS Force Synchronous PDB Writes
ifneq ($(VisualStudioVersion),)
OPT_CXXFLAGS_NO += -FS
OPT_CFLAGS_NO += -FS
endif
#
# add -profile here to run the ms profiler
# -LTCG whole program optimization

View File

@@ -1,39 +1,35 @@
# CONFIG_SITE.Common.linux-arm
#
# Site Specific definitions for all linux-arm targets
#-------------------------------------------------------
# Site-specific settings for the linux-arm target
# NOTE for SHARED_LIBRARIES: In most cases if this is set to YES the
# NOTE: In most cases if SHARED_LIBRARIES is set to YES the
# shared libraries will be found automatically. However if the .so
# files are installed at a different path to their compile-time path
# then in order to be found at runtime do one of these:
# a) LD_LIBRARY_PATH must include the full absolute pathname to
# $(INSTALL_LOCATION)/lib/$(EPICS_HOST_ARCH) when invoking base
# executables.
# b) Add the runtime path to SHRLIB_DEPLIB_DIRS and PROD_DEPLIB_DIRS, which
# b) Add the runtime path to SHRLIB_DEPLIB_DIRS and PROD_DEPLIB_DIRS, which
# will add the named directory to the list contained in the executables.
# c) Add the runtime path to /etc/ld.so.conf and run ldconfig
# to inform the system of the shared library location.
# Depending on your version of Linux you'll want one of the following
# lines to enable command-line editing and history in iocsh. If you're
# not sure which, start with the top one and work downwards until the
# build doesn't fail to link the readline library. If none of them work,
# comment them all out to build without readline support.
# No other libraries needed (recent Fedora, Ubuntu etc.):
#COMMANDLINE_LIBRARY = READLINE
# Use GNU Readline if the header file is installed
COMMANDLINE_LIBRARY = $(strip $(if $(wildcard \
$(firstword $(READLINE_DIR) $(GNU_DIR))/include/readline/readline.h), \
READLINE, EPICS))
# Needs -lncurses (RHEL 5 etc.):
# If libreadline needs additional libraries to be linked with it, try
# uncommenting each of the lines below in turn, starting with the top
# one and working downwards, until the build succeeds. Do a 'make rebuild'
# from the top of the Base tree after changing this setting.
# Needs -lncurses:
#COMMANDLINE_LIBRARY = READLINE_NCURSES
# Needs -lcurses (older versions)
# Needs -lcurses:
#COMMANDLINE_LIBRARY = READLINE_CURSES
# 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
# Readline is broken or you don't want use it:
#COMMANDLINE_LIBRARY = EPICS

View File

@@ -1,9 +1,8 @@
# CONFIG_SITE.Common.linux-cris
#
# Site Specific definitions for linux-cris target
# Only the local epics system manager should modify this file
# Site-specific settings for the linux-cris target
# NOTE for SHARED_LIBRARIES: In most cases if this is set to YES the
# NOTE: In most cases if SHARED_LIBRARIES is set to YES the
# shared libraries will be found automatically. However if the .so
# files are installed at a different path to their compile-time path
# then in order to be found at runtime do one of these:
@@ -15,21 +14,21 @@
# c) Add the runtime path to /etc/ld.so.conf and run ldconfig
# to inform the system of the shared library location.
# Depending on your version of Linux you may want one of the following
# lines to enable command-line editing and history in iocsh. If you're
# not sure which, start with the top one and work downwards until the
# build doesn't fail to link the readline library. If none of them work,
# comment them all out to build without readline support.
# No other libraries needed (recent Fedora, Ubuntu etc.):
#COMMANDLINE_LIBRARY = READLINE
# Use GNU Readline if the header file is installed
COMMANDLINE_LIBRARY = $(strip $(if $(wildcard \
$(GNU_DIR)/include/readline/readline.h), READLINE, EPICS))
# Needs -lncurses (RHEL 5 etc.):
# If libreadline needs additional libraries to be linked with it, try
# uncommenting each of the lines below in turn, starting with the top
# one and working downwards, until the build succeeds. Do a 'make rebuild'
# from the top of the Base tree after changing this setting.
# Needs -lncurses:
#COMMANDLINE_LIBRARY = READLINE_NCURSES
# Needs -lcurses (older versions)
# Needs -lcurses:
#COMMANDLINE_LIBRARY = READLINE_CURSES
OP_SYS_CFLAGS += -g
# Readline is broken or you don't want use it:
#COMMANDLINE_LIBRARY = EPICS

View File

@@ -1,7 +1,6 @@
# CONFIG_SITE.Common.linux-microblaze
#
# Site specific definitions for linux-microblaze target builds.
#-------------------------------------------------------
# Site-specific settings for the linux-microblaze target
# The gnu tools for cross compiling for MicroBlaze (little endian)
# on Linux can be downloaded from the Xilinx git server:
@@ -12,3 +11,21 @@
GNU_DIR = /usr/local/vw/microblaze-2.0/microblazeel-unknown-linux-gnu
# Use GNU Readline if the header file is installed
COMMANDLINE_LIBRARY = $(strip $(if $(wildcard \
$(GNU_DIR)/include/readline/readline.h), READLINE, EPICS))
# If libreadline needs additional libraries to be linked with it, try
# uncommenting each of the lines below in turn, starting with the top
# one and working downwards, until the build succeeds. Do a 'make rebuild'
# from the top of the Base tree after changing this setting.
# Needs -lncurses:
#COMMANDLINE_LIBRARY = READLINE_NCURSES
# Needs -lcurses:
#COMMANDLINE_LIBRARY = READLINE_CURSES
# Readline is broken or you don't want use it:
#COMMANDLINE_LIBRARY = EPICS

View File

@@ -1,9 +1,8 @@
# CONFIG_SITE.Common.linux-x86
#
# Site Specific definitions for linux-x86 target
# Only the local epics system manager should modify this file
# Site-specific settings for the linux-x86 target
# NOTE for SHARED_LIBRARIES: In most cases if this is set to YES the
# NOTE: In most cases if SHARED_LIBRARIES is set to YES the
# shared libraries will be found automatically. However if the .so
# files are installed at a different path to their compile-time path
# then in order to be found at runtime do one of these:
@@ -15,14 +14,15 @@
# c) Add the runtime path to /etc/ld.so.conf and run ldconfig
# to inform the system of the shared library location.
# Depending on your version of Linux you'll want one of the following
# lines to enable command-line editing and history in iocsh. If you're
# not sure which, start with the top one and work downwards until the
# build doesn't fail to link the readline library. If none of them work,
# comment them all out to build without readline support.
# No other libraries needed (recent Fedora, Ubuntu etc.):
COMMANDLINE_LIBRARY = READLINE
# Use GNU Readline if the header file is installed
COMMANDLINE_LIBRARY = $(strip $(if $(wildcard \
$(GNU_DIR)/include/readline/readline.h), READLINE, EPICS))
# If libreadline needs additional libraries to be linked with it, try
# uncommenting each of the lines below in turn, starting with the top
# one and working downwards, until the build succeeds. Do a 'make rebuild'
# from the top of the Base tree after changing this setting.
# Needs -lncurses (RHEL 5 etc.):
#COMMANDLINE_LIBRARY = READLINE_NCURSES
@@ -30,6 +30,9 @@ COMMANDLINE_LIBRARY = READLINE
# Needs -lcurses (older versions)
#COMMANDLINE_LIBRARY = READLINE_CURSES
# Readline is broken or you don't want use it:
#COMMANDLINE_LIBRARY = EPICS
# Permit access to 64-bit file-systems
OP_SYS_CFLAGS += -D_FILE_OFFSET_BITS=64
@@ -43,14 +46,6 @@ OP_SYS_CFLAGS += -D_FILE_OFFSET_BITS=64
#CCC = clang++
# 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
# 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

View File

@@ -1,9 +1,8 @@
# CONFIG_SITE.Common.linux-x86_64
#
# Site Specific definitions for linux-x86_64 target
# Only the local epics system manager should modify this file
# Site-specific settings for the linux-x86_64 target
# NOTE for SHARED_LIBRARIES: In most cases if this is set to YES the
# NOTE: In most cases if SHARED_LIBRARIES is set to YES the
# shared libraries will be found automatically. However if the .so
# files are installed at a different path to their compile-time path
# then in order to be found at runtime do one of these:
@@ -15,14 +14,15 @@
# c) Add the runtime path to /etc/ld.so.conf and run ldconfig
# to inform the system of the shared library location.
# Depending on your version of Linux you'll want one of the following
# lines to enable command-line editing and history in iocsh. If you're
# not sure which, start with the top one and work downwards until the
# build doesn't fail to link the readline library. If none of them work,
# comment them all out to build without readline support.
# No other libraries needed (recent Fedora, Ubuntu etc.):
COMMANDLINE_LIBRARY = READLINE
# Use GNU Readline if the header file is installed
COMMANDLINE_LIBRARY = $(strip $(if $(wildcard \
$(GNU_DIR)/include/readline/readline.h), READLINE, EPICS))
# If libreadline needs additional libraries to be linked with it, try
# uncommenting each of the lines below in turn, starting with the top
# one and working downwards, until the build succeeds. Do a 'make rebuild'
# from the top of the Base tree after changing this setting.
# Needs -lncurses (RHEL 5 etc.):
#COMMANDLINE_LIBRARY = READLINE_NCURSES
@@ -30,6 +30,9 @@ COMMANDLINE_LIBRARY = READLINE
# Needs -lcurses (older versions)
#COMMANDLINE_LIBRARY = READLINE_CURSES
# Readline is broken or you don't want use it:
#COMMANDLINE_LIBRARY = EPICS
# Uncomment the followings lines to build with CLANG instead of GCC.
#
@@ -39,14 +42,6 @@ COMMANDLINE_LIBRARY = READLINE
#CCC = clang++
# 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
# 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

View File

@@ -1,4 +1,23 @@
# CONFIG_SITE.Common.linux-xscale_be
#
# Site specific definitions for all linux-xscale_be target builds.
#-------------------------------------------------------
# Site-specific settings for the linux-xscale_be target
# Use GNU Readline if the header file is installed
COMMANDLINE_LIBRARY = $(strip $(if $(wildcard \
$(firstword $(READLINE_DIR) $(GNU_DIR))/include/readline/readline.h), \
READLINE, EPICS))
# If libreadline needs additional libraries to be linked with it, try
# uncommenting each of the lines below in turn, starting with the top
# one and working downwards, until the build succeeds. Do a 'make rebuild'
# from the top of the Base tree after changing this setting.
# Needs -lncurses:
#COMMANDLINE_LIBRARY = READLINE_NCURSES
# Needs -lcurses:
#COMMANDLINE_LIBRARY = READLINE_CURSES
# Readline is broken or you don't want use it:
#COMMANDLINE_LIBRARY = EPICS

View File

@@ -0,0 +1,11 @@
# CONFIG_SITE.Common.linuxCommon
#
# Site-specific settings for all linux targets
# 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

@@ -4,18 +4,18 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Known Problems in R3.15.6</title>
<title>Known Problems in R3.15.7</title>
</head>
<body>
<h1 style="text-align: center">EPICS Base R3.15.6: Known Problems</h1>
<h1 style="text-align: center">EPICS Base R3.15.7: Known Problems</h1>
<p>Any patch files linked below should be applied at the root of the
base-3.15.6 tree. Download them, then use the GNU Patch program as
base-3.15.7 tree. Download them, then use the GNU Patch program as
follows:</p>
<blockquote><pre>% <b>cd <i>/path/to/</i>base-3.15.6</b>
% <b>patch -p0 &lt; <i>/path/to/</i>file.patch</b></pre></blockquote>
<blockquote><pre>% <b>cd <i>/path/to/</i>base-3.15.7</b>
% <b>patch -p1 &lt; <i>/path/to/</i>file.patch</b></pre></blockquote>
<p>The following significant problems have been reported with this
version of EPICS Base:</p>

View File

@@ -1,347 +0,0 @@
Installation Instructions
EPICS Base Release 3.15.6
--------------------------------------------------------------------------
Table of Contents
* What is EPICS base?
* What is new in this release?
* Copyright
* Supported platforms
* Supported compilers
* Software requirements
* Host system storage requirements
* Documentation
* Directory Structure
* Build related components
* Building EPICS base (Unix and Win32)
* Example application and extension
* Multiple host platforms
--------------------------------------------------------------------------
What is EPICS base?
The Experimental Physics and Industrial Control Systems (EPICS) is an
extensible set of software components and tools with which application
developers can create a control system. This control system can be used
to control accelerators, detectors, telescopes, or other scientific
experimental equipment. EPICS base is the set of core software, i.e. the
components of EPICS without which EPICS would not function. EPICS base
allows an arbitrary number of target systems, IOCs (input/output
controllers), and host systems, OPIs (operator interfaces) of various
types.
What is new in this release?
Please check the RELEASE_NOTES file in the distribution for description
of changes and release migration details.
Copyright
Please review the LICENSE file included in the distribution for legal
terms of usage.
Supported platforms
The list of platforms supported by this version of EPICS base is given
in the configure/CONFIG_SITE file. If you are trying to build EPICS Base
on an unlisted host or for a different target machine you must have the
proper host/target cross compiler and header files, and you will have to
create and add the appropriate new configure files to the
base/configure/os/directory. You can start by copying existing
configuration files in the configure/os directory and then make changes
for your new platforms.
Supported compilers
This version of EPICS base has been built and tested using the host
vendor's C and C++ compilers, as well as the GNU gcc and g++ compilers.
The GNU cross-compilers work for all cross-compiled targets. You may
need the C and C++ compilers to be in your search path to do EPICS
builds; check the definitions of CC and CCC in
base/configure/os/CONFIG.<host>.<host> if you have problems.
Software requirements
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.
Perl
You must have Perl version 5.8.1 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.
Unzip and tar (Winzip on WIN32 systems)
You must have tools available to unzip and untar the EPICS base
distribution file.
Target systems
EPICS supports IOCs running on embedded platforms such as VxWorks and
RTEMS built using a cross-compiler, and also supports soft IOCs running
as processes on the host platform.
vxWorks
You must have vxWorks 5.5.x or 6.x installed if any of your target
systems are vxWorks systems; the C++ compiler for vxWorks 5.4 is now too
old to support. The vxWorks installation provides the cross-compiler and
header files needed to build for these targets. The absolute path to and
the version number of the vxWorks installation must be set in the
base/configure/os/CONFIG_SITE.Common.vxWorksCommon file or in one of its
target-specific overrides.
Consult the vxWorks 5.x or vxWorks 6.x EPICS web pages about and the
vxWorks documentation for information about configuring your vxWorks
operating system for use with EPICS.
RTEMS
For RTEMS targets, you need RTEMS core and toolset version 4.9.2 or
later.
GNU readline or Tecla library
GNU readline and Tecla libraries can be used by the IOC shell to provide
command line editing and command line history recall and edit. GNU
readline (or Tecla library) must be installed on your target system when
COMMANDLINE_LIBRARY is set to READLINE (or TECLA) for that target. EPICS
(EPICS shell) is the default specified in CONFIG_COMMON. A READLINE
override is defined for linux-x86 in the EPICS distribution. Comment out
COMMANDLINE_LIBRARY=READLINE in
configure/os/CONFIG_SITE.Common.linux-x86 if readline is not 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.
Host system storage requirements
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.
Documentation
EPICS documentation is available through the EPICS website at Argonne.
Release specific documentation can also be found in the
base/documentation directory of the distribution.
Directory Structure
Distribution directory structure:
base Root directory of the base distribution
base/configure Operating system independent build config files
base/configure/os Operating system dependent build config files
base/documentation Distribution documentation
base/src Source code in various subdirectories
base/startup Scripts for setting up path and environment
Install directories created by the build:
bin Installed scripts and executables in subdirs
cfg Installed build configuration files
db Installed data bases
dbd Installed data base definitions
doc Installed documentation files
html Installed html documentation
include Installed header files
include/os Installed os specific header files in subdirs
include/compiler Installed compiler-specific header files
lib Installed libraries in arch subdirectories
lib/perl Installed perl modules
templates Installed templates
Build related components
base/documentation directory - contains setup, build, and install documents
README.1st Instructions for setup and building epics base
README.html html version of README.1st
README.darwin.html Installation notes for Mac OS X (Darwin)
RELEASE_NOTES.html Notes on release changes
KnownProblems.html List of known problems and workarounds
base/startup directory - contains scripts to set environment and path
EpicsHostArch C shell script to set EPICS_HOST_ARCH env variable
EpicsHostArch.pl Perl script to set EPICS_HOST_ARCH env variable
Site.profile bourne shell script to set path and env variables
Site.cshrc c shell script to set path and env variables
cygwin.bat WIN32 bat file to set cygwin path and env variables
win32.bat WIN32 bat file to set path and env variables
base/configure directory - contains build definitions and rules
CONFIG Includes configure files and allows variable overrides
CONFIG.CrossCommon Cross build definitions
CONFIG.gnuCommon Gnu compiler build definitions for all archs
CONFIG_ADDONS Definitions for <osclass> and DEFAULT options
CONFIG_APP_INCLUDE
CONFIG_BASE EPICS base tool and location definitions
CONFIG_BASE_VERSION Definitions for EPICS base version number
CONFIG_COMMON Definitions common to all builds
CONFIG_ENV Definitions of EPICS environment variables
CONFIG_FILE_TYPE
CONFIG_SITE Site specific make definitions
CONFIG_SITE_ENV Site defaults for EPICS environment variables
MAKEFILE Installs CONFIG* RULES* creates
RELEASE Location of external products
RULES Includes appropriate rules file
RULES.Db Rules for database and database definition files
RULES.ioc Rules for application iocBoot/ioc* directory
RULES_ARCHS Definitions and rules for building architectures
RULES_BUILD Build and install rules and definitions
RULES_DIRS Definitions and rules for building subdirectories
RULES_EXPAND
RULES_FILE_TYPE
RULES_TARGET
RULES_TOP Rules specific to a <top> dir (uninstall and tar)
Sample.Makefile Sample makefile with comments
base/configure/os directory - contains os-arch specific definitions
CONFIG.<host>.<target> Specific host-target build definitions
CONFIG.Common.<target> Specific target definitions for all hosts
CONFIG.<host>.Common Specific host definitions for all targets
CONFIG.UnixCommon.Common Definitions for Unix hosts and all targets
CONFIG.Common.UnixCommon Definitions for Unix targets and all hosts
CONFIG.Common.vxWorksCommon Specific host definitions for all vx targets
CONFIG_SITE.<host>.<target> Site specific host-target definitions
CONFIG_SITE.Common.<target> Site specific target defs for all hosts
CONFIG_SITE.<host>.Common Site specific host defs for all targets
Building EPICS base (Unix and Win32)
Unpack file
Unzip and untar the distribution file. Use WinZip on Windows systems.
Set environment variables
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
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 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 EPICS_HOST_ARCH values.
PERLLIB
On WIN32, some versions of Perl require that the environment variable
PERLLIB be set to <perl directory location>.
PATH
As already mentioned, you must have the perl executable and you may
need C and C++ compilers in your search path. For building base you
also must have echo in your search path. For Unix host builds you also
need ln, cpp, cp, rm, mv, and mkdir in your search path and /bin/chmod
must exist. On some Unix systems you may also need ar and 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 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 must include
the full pathname to $(INSTALL_LOCATION)/lib/$(EPICS_HOST_ARCH) when
invoking executables, or some equivalent OS-specific mechanism (such
as /etc/ld.so.conf on Linux) must be used. Shared libraries are now
built by default on all Unix type hosts.
Do site-specific build configuration
Site configuration
To configure EPICS, you may want to modify the default definitions in
the following files:
configure/CONFIG_SITE Build choices. Specify target archs.
configure/CONFIG_SITE_ENV Environment variable defaults
configure/RELEASE TORNADO2 full path location
Host configuration
To configure each host system, you may override the default
definitions by adding a new file in the configure/os directory with
override definitions. The new file should have the same name as the
distribution file to be overridden except with CONFIG in the name
changed to CONFIG_SITE.
configure/os/CONFIG.<host>.<host> Host build settings
configure/os/CONFIG.<host>.Common Host common build settings
Target configuration
To configure each target system, you may override the default
definitions by adding a new file in the configure/os directory with
override definitions. The new file should have the same name as the
distribution file to be overridden except with CONFIG in the name
replaced by CONFIG_SITE. This step is necessary even if the host
system is the only target system.
configure/os/CONFIG.Common.<target> Target common settings
configure/os/CONFIG.<host>.<target> Host-target settings
Build EPICS base
After configuring the build you should be able to build EPICS base by
issuing the following commands in the distribution's root directory
(base):
gnumake clean uninstall
gnumake
The command "gnumake clean uninstall" will remove all files and
directories generated by a previous build. The command "gnumake" will
build and install everything for the configured host and targets.
It is recommended that you do a "gnumake clean uninstall" at the root
directory of an EPICS directory structure before each complete rebuild
to ensure that all components will be rebuilt.
Example application and extension
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 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 create and
build an example application in a user created <top> directory. It also
explains how to run the example application on a vxWorks ioc or as a
process on the host system. By running the example application as a
host-based IOC, you will be able to quickly implement a complete EPICS
system and be able to run channel access clients on the host system.
A perl script, makeBaseExt.pl, is included in the distribution file.
This script will create a sample extension that can be built and
executed. The makeBaseApp.pl and makeBaseExt.pl scripts are installed
into the install location bin/<hostarch> directory during the base
build.
Multiple host platforms
You can build using a single EPICS directory structure on multiple host
systems and for multiple cross target systems. The intermediate and
binary files generated by the build will be created in separate
subdirectories and installed into the appropriate separate host/target
install directories. EPICS executables and perl scripts are installed
into the $(INSTALL_LOCATION)/bin/<arch> directories. Libraries are
installed into $(INSTALL_LOCATION)/lib/<arch>. The default definition
for $(INSTALL_LOCATION) is $(TOP) which is the root directory in the
distribution directory structure, base. Created object files are stored
in O.<arch> source subdirectories, This allows objects for multiple
cross target architectures to be maintained at the same time. To build
EPICS base for a specific host/target combination you must have the
proper host/target C/C++ cross compiler and target header files and the
base/configure/os directory must have the appropriate configure files.

View File

@@ -21,7 +21,7 @@ of my Bash login script (~/.bash_login):
#
EPICS_BASE="${HOME}/src/EPICS/base"
EPICS_EXTENSIONS="${HOME}/src/EPICS/extensions"
<strong>.</strong> "${EPICS_BASE}"/startup/Site.profile
<strong>.</strong> "${EPICS_BASE}"/startup/unix.sh
</pre>
</li>
<li>

View File

@@ -1,384 +0,0 @@
<!DOCTYPE HTML>
<!-- Generate the README.1st file from this file using:
elinks -dump -no-numbering -no-references -dump-width 80 README.html
-->
<HTML>
<HEAD>
<TITLE>README - EPICS Base Installation Instructions</TITLE>
</HEAD>
<BODY>
<CENTER>
<H1>Installation Instructions</H1>
<H2>EPICS Base Release 3.15.6</H2><BR>
</CENTER>
<HR>
<H3> Table of Contents</H3>
<UL>
<LI><A HREF="#0_0_1"> What is EPICS base?</A></LI>
<LI><A HREF="#0_0_2"> What is new in this release?</A></LI>
<LI><A HREF="#0_0_3"> Copyright</A></LI>
<LI><A HREF="#0_0_4"> Supported platforms</A></LI>
<LI><A HREF="#0_0_5"> Supported compilers</A></LI>
<LI><A HREF="#0_0_6"> Software requirements</A></LI>
<LI><A HREF="#0_0_7"> Host system storage requirements</A></LI>
<LI><A HREF="#0_0_8"> Documentation</A></LI>
<LI><A HREF="#0_0_10"> Directory Structure</A></LI>
<LI><A HREF="#0_0_11"> Build related components</A></LI>
<LI><A HREF="#0_0_12"> Building EPICS base (Unix and Win32)</A></LI>
<LI><A HREF="#0_0_13"> Example application and extension</A></LI>
<LI><A HREF="#0_0_14"> Multiple host platforms</A></LI>
</UL>
<HR>
<H3><A NAME="0_0_1"> What is EPICS base?</A></H3>
<BLOCKQUOTE>The Experimental Physics and Industrial Control Systems
(EPICS) is an extensible set of software components and tools with
which application developers can create a control system. This control
system can be used to control accelerators, detectors, telescopes, or
other scientific experimental equipment. EPICS base is the set of core
software, i.e. the components of EPICS without which EPICS would not
function. EPICS base allows an arbitrary number of target systems, IOCs
(input/output controllers), and host systems, OPIs (operator
interfaces) of various types.</BLOCKQUOTE>
<H3><A NAME="0_0_2"> What is new in this release?</A></H3>
<BLOCKQUOTE> Please check the RELEASE_NOTES file in the distribution for
description of changes and release migration details.</BLOCKQUOTE>
<H3><A NAME="0_0_3"> Copyright</A></H3>
<BLOCKQUOTE>Please review the LICENSE file included in the
distribution for legal terms of usage.</BLOCKQUOTE>
<H3><A NAME="0_0_4"> Supported platforms</A></H3>
<BLOCKQUOTE>The list of platforms supported by this version of EPICS base
is given in the configure/CONFIG_SITE file. If you are trying to build
EPICS Base on an unlisted host or for a different target machine you
must have the proper host/target cross compiler and header files, and
you will have to create and add the appropriate new configure files to
the base/configure/os/directory. You can start by copying existing
configuration files in the configure/os directory and then make changes
for your new platforms.</BLOCKQUOTE>
<H3><A NAME="0_0_5"> Supported compilers</A></H3>
<BLOCKQUOTE>This version of EPICS base has been built and tested using the host
vendor's C and C++ compilers, as well as the GNU gcc and g++ compilers. The GNU
cross-compilers work for all cross-compiled targets. You may need the C and C++
compilers to be in your search path to do EPICS builds; check the definitions
of CC and CCC in base/configure/os/CONFIG.&lt;host&gt;.&lt;host&gt; if you have
problems.</BLOCKQUOTE>
<H3><A NAME="0_0_6"> Software requirements</A></H3>
<BLOCKQUOTE><B>GNU make</B><BR>
You must use GNU make, gnumake, for any EPICS builds. Set your path
so that a gnumake version 3.81 or later is available.
<P><B>Perl</B><BR>
You must have Perl version 5.8.1 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.</P>
<P><B>Unzip and tar (Winzip on WIN32 systems)</B><BR>
You must have tools available to unzip and untar the EPICS base
distribution file.</P>
<P><B>Target systems</B><BR>
EPICS supports IOCs running on embedded platforms such as VxWorks
and RTEMS built using a cross-compiler, and also supports soft IOCs running
as processes on the host platform.</P>
<P><B>vxWorks</B><BR>
You must have vxWorks 5.5.x or 6.x installed if any of your target systems are
vxWorks systems; the C++ compiler for vxWorks 5.4 is now too old to support.
The vxWorks installation provides the cross-compiler and header files needed to
build for these targets. The absolute path to and the version number of the
vxWorks installation must be set in the
base/configure/os/CONFIG_SITE.Common.vxWorksCommon file or in one of its
target-specific overrides.</P>
<P>Consult the <a href="http://www.aps.anl.gov/epics/base/tornado.php">vxWorks
5.x</a> or <a href="http://www.aps.anl.gov/epics/base/vxWorks6.php">vxWorks
6.x</a> EPICS web pages about and the vxWorks documentation for information
about configuring your vxWorks operating system for use with EPICS.</P>
<P><B>RTEMS</B><BR>
For RTEMS targets, you need RTEMS core and toolset version 4.9.2 or later.</P>
<P><B>GNU readline or Tecla library</B><BR>
GNU readline and Tecla libraries can be used by the IOC shell to
provide command line editing and command line history recall and edit.
GNU readline (or Tecla library) must be installed on your target system
when COMMANDLINE_LIBRARY is set to READLINE (or TECLA) for that target.
EPICS (EPICS shell) is the default specified in CONFIG_COMMON. A
READLINE override is defined for linux-x86 in the EPICS distribution.
Comment out COMMANDLINE_LIBRARY=READLINE in
configure/os/CONFIG_SITE.Common.linux-x86 if readline is not 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.</P>
</BLOCKQUOTE>
<H3><A NAME="0_0_7"> Host system storage requirements</A></H3>
<BLOCKQUOTE>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.</BLOCKQUOTE>
<H3><A NAME="0_0_8"> Documentation</A></H3>
<BLOCKQUOTE>EPICS documentation is available through the
<a href="http://www.aps.anl.gov/epics/">EPICS website</a> at Argonne.
<P>Release specific documentation can also be found in the base/documentation
directory of the distribution.</BLOCKQUOTE>
<H3><A NAME="0_0_10"> Directory Structure</A></H3>
<BLOCKQUOTE><H4>Distribution directory structure:</H4>
<PRE>
base Root directory of the base distribution
base/configure Operating system independent build config files
base/configure/os Operating system dependent build config files
base/documentation Distribution documentation
base/src Source code in various subdirectories
base/startup Scripts for setting up path and environment
</PRE>
<H4>Install directories created by the build:</H4>
<PRE>
bin Installed scripts and executables in subdirs
cfg Installed build configuration files
db Installed data bases
dbd Installed data base definitions
doc Installed documentation files
html Installed html documentation
include Installed header files
include/os Installed os specific header files in subdirs
include/compiler Installed compiler-specific header files
lib Installed libraries in arch subdirectories
lib/perl Installed perl modules
templates Installed templates
</PRE>
</BLOCKQUOTE>
<H3><A NAME="0_0_11"> Build related components</A></H3>
<BLOCKQUOTE>
<H4>base/documentation directory - contains setup, build, and install
documents</H4>
<PRE>
README.1st Instructions for setup and building epics base
README.html html version of README.1st
README.darwin.html Installation notes for Mac OS X (Darwin)
RELEASE_NOTES.html Notes on release changes
KnownProblems.html List of known problems and workarounds
</PRE>
<H4>base/startup directory - contains scripts to set environment and path</H4>
<PRE>
EpicsHostArch C shell script to set EPICS_HOST_ARCH env variable
EpicsHostArch.pl Perl script to set EPICS_HOST_ARCH env variable
Site.profile bourne shell script to set path and env variables
Site.cshrc c shell script to set path and env variables
cygwin.bat WIN32 bat file to set cygwin path and env variables
win32.bat WIN32 bat file to set path and env variables
</PRE>
<H4>base/configure directory - contains build definitions and rules</H4>
<PRE>
CONFIG Includes configure files and allows variable overrides
CONFIG.CrossCommon Cross build definitions
CONFIG.gnuCommon Gnu compiler build definitions for all archs
CONFIG_ADDONS Definitions for &lt;osclass&gt; and DEFAULT options
CONFIG_APP_INCLUDE
CONFIG_BASE EPICS base tool and location definitions
CONFIG_BASE_VERSION Definitions for EPICS base version number
CONFIG_COMMON Definitions common to all builds
CONFIG_ENV Definitions of EPICS environment variables
CONFIG_FILE_TYPE
CONFIG_SITE Site specific make definitions
CONFIG_SITE_ENV Site defaults for EPICS environment variables
MAKEFILE Installs CONFIG* RULES* creates
RELEASE Location of external products
RULES Includes appropriate rules file
RULES.Db Rules for database and database definition files
RULES.ioc Rules for application iocBoot/ioc* directory
RULES_ARCHS Definitions and rules for building architectures
RULES_BUILD Build and install rules and definitions
RULES_DIRS Definitions and rules for building subdirectories
RULES_EXPAND
RULES_FILE_TYPE
RULES_TARGET
RULES_TOP Rules specific to a &lt;top&gt; dir (uninstall and tar)
Sample.Makefile Sample makefile with comments
</PRE>
<H4>base/configure/os directory - contains os-arch specific definitions</H4>
<PRE>
CONFIG.&lt;host&gt;.&lt;target&gt; Specific host-target build definitions
CONFIG.Common.&lt;target&gt; Specific target definitions for all hosts
CONFIG.&lt;host&gt;.Common Specific host definitions for all targets
CONFIG.UnixCommon.Common Definitions for Unix hosts and all targets
CONFIG.Common.UnixCommon Definitions for Unix targets and all hosts
CONFIG.Common.vxWorksCommon Specific host definitions for all vx targets
CONFIG_SITE.&lt;host&gt;.&lt;target&gt; Site specific host-target definitions
CONFIG_SITE.Common.&lt;target&gt; Site specific target defs for all hosts
CONFIG_SITE.&lt;host&gt;.Common Site specific host defs for all targets
</PRE>
</BLOCKQUOTE>
<H3><A NAME="0_0_12"> Building EPICS base (Unix and Win32)</A></H3>
<BLOCKQUOTE>
<H4> Unpack file</H4>
<BLOCKQUOTE>
Unzip and untar the distribution file. Use WinZip on Windows
systems.
</BLOCKQUOTE>
<H4>Set environment variables</H4>
<BLOCKQUOTE>
Files in the base/startup directory have been provided to
help set required path and other environment variables.
<P><B>EPICS_HOST_ARCH</B><BR>
Before you can build or use EPICS R3.15, 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 vendor's c/c++ compiler for host builds,
you will need another dash followed by the alternate compiler name
(e.g. &quot;-gnu&quot; for GNU c/c++ compilers on a solaris host or &quot;-mingw&quot;
for MinGW c/c++ compilers on a WIN32 host). See configure/CONFIG_SITE
for a list of supported EPICS_HOST_ARCH values.</P>
<P><B>PERLLIB</B><BR>
On WIN32, some versions of Perl require that the environment
variable PERLLIB be set to &lt;perl directory location&gt;.</P>
<P><B>PATH</B><BR>
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
also must have echo in your search path. For Unix host builds you also
need ln, cpp, cp, rm, mv, and mkdir in your search path and /bin/chmod
must exist. On some Unix systems you may also need ar and 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.</P>
<P><B>LD_LIBRARY_PATH</B><BR>
R3.15 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 must include the full pathname to
$(INSTALL_LOCATION)/lib/$(EPICS_HOST_ARCH) when invoking executables, or
some equivalent OS-specific mechanism (such as /etc/ld.so.conf on Linux)
must be used.
Shared libraries are now built by default on all Unix type hosts.</P>
</BLOCKQUOTE>
<H4>Do site-specific build configuration</H4>
<BLOCKQUOTE>
<B>Site configuration</B><BR>
To configure EPICS, you may want to modify the default definitions
in the following files:
<PRE>
configure/CONFIG_SITE Build choices. Specify target archs.
configure/CONFIG_SITE_ENV Environment variable defaults
configure/RELEASE TORNADO2 full path location
</PRE>
<B> Host configuration</B><BR>
To configure each host system, you may override the default
definitions by adding a new file in the configure/os directory with
override definitions. The new file should have the same name as the
distribution file to be overridden except with CONFIG in the name
changed to CONFIG_SITE.
<PRE>
configure/os/CONFIG.&lt;host&gt;.&lt;host&gt; Host build settings
configure/os/CONFIG.&lt;host&gt;.Common Host common build settings
</PRE>
<B>Target configuration</B><BR>
To configure each target system, you may override the default
definitions by adding a new file in the configure/os directory with
override definitions. The new file should have the same name as the
distribution file to be overridden except with CONFIG in the name
replaced by CONFIG_SITE. This step is necessary even if the host system
is the only target system.
<PRE>
configure/os/CONFIG.Common.&lt;target&gt; Target common settings
configure/os/CONFIG.&lt;host&gt;.&lt;target&gt; Host-target settings
</PRE>
</BLOCKQUOTE>
<H4>Build EPICS base</H4>
<BLOCKQUOTE>After configuring the build you should be able to build
EPICS base by issuing the following commands in the distribution's root
directory (base):
<PRE>
gnumake clean uninstall
gnumake
</PRE>
The command &quot;gnumake clean uninstall&quot;
will remove all files and directories generated by a previous build.
The command &quot;gnumake&quot; will build and install everything for the
configured host and targets.
<P> It is recommended that you do a &quot;gnumake clean uninstall&quot; at the
root directory of an EPICS directory structure before each complete
rebuild to ensure that all components will be rebuilt.
</BLOCKQUOTE>
</BLOCKQUOTE>
<H3><A NAME="0_0_13"> Example application and extension</A></H3>
<BLOCKQUOTE>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.
<P>
Instructions for building and executing the 3.15 example application
can be found in the section &quot;Example Application&quot; of Chapter 2,
&quot;Getting Started&quot;, in the &quot;IOC Application Developer's Guide&quot; for this
release. The &quot;Example IOC Application&quot; section briefly explains how to
create and build an example application in a user created &lt;top&gt;
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 application as a host-based IOC, you will be
able to quickly implement a complete EPICS system and be able to run channel
access clients on the host system.
<P>
A perl script,
makeBaseExt.pl, is included in the distribution file. This script will
create a sample extension that can be built and executed. The
makeBaseApp.pl and makeBaseExt.pl scripts are installed into the
install location bin/&lt;hostarch&gt; directory during the base build.
</BLOCKQUOTE>
<H3><A NAME="0_0_14"> Multiple host platforms</A></H3>
<BLOCKQUOTE>You can build using a single EPICS directory structure on
multiple host systems and for multiple cross target systems. The
intermediate and binary files generated by the build will be created in
separate subdirectories and installed into the appropriate separate
host/target install directories. EPICS executables and perl scripts are
installed into the <TT>$(INSTALL_LOCATION)/bin/&lt;arch&gt;</TT> directories.
Libraries are installed into $<TT>(INSTALL_LOCATION)/lib/&lt;arch&gt;</TT>.
The default definition for <TT>$(INSTALL_LOCATION)</TT> is <TT>$(TOP)</TT>
which is the root directory in the distribution directory structure,
base. Created object files are stored in O.&lt;arch&gt; source
subdirectories, This allows objects for multiple cross target
architectures to be maintained at the same time. To build EPICS base
for a specific host/target combination you must have the proper
host/target C/C++ cross compiler and target header files and the
base/configure/os directory must have the appropriate configure files.
</BLOCKQUOTE>
</BODY>
</HTML>

373
documentation/README.md Normal file
View File

@@ -0,0 +1,373 @@
# Installation Instructions
## EPICS Base Release 3.15.7
-----
### Table of Contents
- [What is EPICS base?](#0_0_1)
- [What is new in this release?](#0_0_2)
- [Copyright](#0_0_3)
- [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)
- [Building EPICS base (Unix and Win32)](#0_0_12)
- [Example application and extension](#0_0_13)
- [Multiple host platforms](#0_0_14)
-----
### <span id="0_0_1">What is EPICS base?</span>
The Experimental Physics and Industrial Control Systems (EPICS) is an
extensible set of software components and tools with which application
developers can create a control system. This control system can be
used to control accelerators, detectors, telescopes, or other
scientific experimental equipment. EPICS base is the set of core
software, i.e. the components of EPICS without which EPICS would not
function. EPICS base allows an arbitrary number of target systems,
IOCs (input/output controllers), and host systems, OPIs (operator
interfaces) of various types.
### <span id="0_0_2">What is new in this release?</span>
Please check the `RELEASE_NOTES` file in the distribution for
description of changes and release migration details.
### <span id="0_0_3">Copyright</span>
Please review the LICENSE file included in the distribution for legal
terms of usage.
### <span id="0_0_4">Supported platforms</span>
The list of platforms supported by this version of EPICS base is given
in the `configure/CONFIG_SITE` file. If you are trying to build EPICS
Base on an unlisted host or for a different target machine you must
have the proper host/target cross compiler and header files, and you
will have to create and add the appropriate new configure files to the
base/configure/os/directory. You can start by copying existing
configuration files in the configure/os directory and then make
changes for your new platforms.
### <span id="0_0_5">Supported compilers</span>
This version of EPICS base has been built and tested using the host
vendor's C and C++ compilers, as well as the GNU gcc and g++
compilers. The GNU cross-compilers work for all cross-compiled
targets. You may need the C and C++ compilers to be in your search
path to do EPICS builds; check the definitions of CC and CCC in
base/configure/os/CONFIG.&lt;host>.&lt;host> if you have problems.
### <span id="0_0_6">Software requirements</span>
**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.
**Perl**
You must have Perl version 5.8.1 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.
**Unzip and tar (Winzip on WIN32 systems)**
You must have tools available to unzip and untar the EPICS base
distribution file.
**Target systems**
EPICS supports IOCs running on embedded platforms such as VxWorks and
RTEMS built using a cross-compiler, and also supports soft IOCs
running as processes on the host platform.
**vxWorks**
You must have vxWorks 5.5.x or 6.x installed if any of your target
systems are vxWorks systems; the C++ compiler for vxWorks 5.4 is now
too old to support. The vxWorks installation provides the
cross-compiler and header files needed to build for these targets. The
absolute path to and the version number of the vxWorks installation
must be set in the `base/configure/os/CONFIG_SITE.Common.vxWorksCommon`
file or in one of its target-specific overrides.
Consult the [vxWorks 5.x](https://epics.anl.gov/base/tornado.php) or
[vxWorks 6.x](https://epics.anl.gov/base/vxWorks6.php) EPICS web pages
about and the vxWorks documentation for information about configuring
your vxWorks operating system for use with EPICS.
**RTEMS**
For RTEMS targets, you need RTEMS core and toolset version 4.9.2 or
later.
**GNU readline or Tecla library**
GNU readline and Tecla libraries can be used by the IOC shell to
provide command line editing and command line history recall and edit.
GNU readline (or Tecla library) must be installed on your target
system when `COMMANDLINE_LIBRARY` is set to READLINE (or TECLA) for
that target. EPICS (EPICS shell) is the default specified in
`CONFIG_COMMON`. A READLINE override is defined for linux-x86 in the
EPICS distribution. Comment out `COMMANDLINE_LIBRARY=READLINE` in
`configure/os/CONFIG_SITE.Common.linux-x86` if readline is not
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
website](https://epics.anl.gov/) at Argonne.
Release specific documentation can also be found in the
base/documentation directory of the distribution.
### <span id="0_0_10">Directory Structure</span>
#### Distribution directory structure:
```
base Root directory of the base distribution
base/configure Operating system independent build config files
base/configure/os Operating system dependent build config files
base/documentation Distribution documentation
base/src Source code in various subdirectories
base/startup Scripts for setting up path and environment
```
#### Install directories created by the build:
```
bin Installed scripts and executables in subdirs
cfg Installed build configuration files
db Installed data bases
dbd Installed data base definitions
doc Installed documentation files
html Installed html documentation
include Installed header files
include/os Installed os specific header files in subdirs
include/compiler Installed compiler-specific header files
lib Installed libraries in arch subdirectories
lib/perl Installed perl modules
templates Installed templates
```
### <span id="0_0_11">Build related components</span>
#### base/documentation directory - contains setup, build, and install documents
```
README.md Instructions for setup and building epics base
README.darwin.html Installation notes for Mac OS X (Darwin)
RELEASE_NOTES.html Notes on release changes
KnownProblems.html List of known problems and workarounds
```
#### base/startup directory - contains scripts to set environment and path
```
EpicsHostArch Shell script to set EPICS_HOST_ARCH env variable
unix.csh C shell script to set path and env variables
unix.sh Bourne shell script to set path and env variables
win32.bat Bat file example to configure win32-x86 target
windows.bat Bat file example to configure windows-x64 target
```
#### base/configure directory - contains build definitions and rules
```
CONFIG Includes configure files and allows variable overrides
CONFIG.CrossCommon Cross build definitions
CONFIG.gnuCommon Gnu compiler build definitions for all archs
CONFIG_ADDONS Definitions for &lt;osclass> and DEFAULT options
CONFIG_APP_INCLUDE
CONFIG_BASE EPICS base tool and location definitions
CONFIG_BASE_VERSION Definitions for EPICS base version number
CONFIG_COMMON Definitions common to all builds
CONFIG_ENV Definitions of EPICS environment variables
CONFIG_FILE_TYPE
CONFIG_SITE Site specific make definitions
CONFIG_SITE_ENV Site defaults for EPICS environment variables
MAKEFILE Installs CONFIG* RULES* creates
RELEASE Location of external products
RULES Includes appropriate rules file
RULES.Db Rules for database and database definition files
RULES.ioc Rules for application iocBoot/ioc* directory
RULES_ARCHS Definitions and rules for building architectures
RULES_BUILD Build and install rules and definitions
RULES_DIRS Definitions and rules for building subdirectories
RULES_EXPAND
RULES_FILE_TYPE
RULES_TARGET
RULES_TOP Rules specific to a &lt;top> dir (uninstall and tar)
Sample.Makefile Sample makefile with comments
```
#### base/configure/os directory - contains os-arch specific definitions
```
CONFIG.&lt;host>.&lt;target> Specific host-target build definitions
CONFIG.Common.&lt;target> Specific target definitions for all hosts
CONFIG.&lt;host>.Common Specific host definitions for all targets
CONFIG.UnixCommon.Common Definitions for Unix hosts and all targets
CONFIG.Common.UnixCommon Definitions for Unix targets and all hosts
CONFIG.Common.vxWorksCommon Specific host definitions for all vx targets
CONFIG_SITE.&lt;host>.&lt;target> Site specific host-target definitions
CONFIG_SITE.Common.&lt;target> Site specific target defs for all hosts
CONFIG_SITE.&lt;host>.Common Site specific host defs for all targets
```
### <span id="0_0_12">Building EPICS base (Unix and Win32)</span>
#### Unpack file
Unzip and untar the distribution file. Use WinZip on Windows
systems.
#### Set environment variables
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
`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
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
`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
also must have echo in your search path. For Unix host builds you
also need ln, cpp, cp, rm, mv, and mkdir in your search path and
/bin/chmod must exist. On some Unix systems you may also need ar and
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
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`
must include the full pathname to
`$(INSTALL_LOCATION)/lib/$(EPICS_HOST_ARCH)` when invoking
executables, or some equivalent OS-specific mechanism (such as
/etc/ld.so.conf on Linux) must be used. Shared libraries are now
built by default on all Unix type hosts.
#### Do site-specific build configuration
**Site configuration**
To configure EPICS, you may want to modify the default definitions
in the following files:
```
configure/CONFIG_SITE Build choices. Specify target archs.
configure/CONFIG_SITE_ENV Environment variable defaults
configure/RELEASE TORNADO2 full path location
```
**Host configuration**
To configure each host system, you may override the default
definitions by adding a new file in the configure/os directory with
override definitions. The new file should have the same name as the
distribution file to be overridden except with CONFIG in the name
changed to `CONFIG_SITE`.
```
configure/os/CONFIG.&lt;host>.&lt;host> Host build settings
configure/os/CONFIG.&lt;host>.Common Host common build settings
```
**Target configuration**
To configure each target system, you may override the default
definitions by adding a new file in the configure/os directory with
override definitions. The new file should have the same name as the
distribution file to be overridden except with CONFIG in the name
replaced by `CONFIG_SITE`. This step is necessary even if the host
system is the only target system.
```
configure/os/CONFIG.Common.&lt;target> Target common settings
configure/os/CONFIG.&lt;host>.&lt;target> Host-target settings
```
#### Build EPICS base
After configuring the build you should be able to build EPICS base
by issuing the following commands in the distribution's root
directory (base):
```
gnumake clean uninstall
gnumake
```
The command "gnumake clean uninstall" will remove all files and
directories generated by a previous build. The command "gnumake"
will build and install everything for the configured host and
targets.
It is recommended that you do a "gnumake clean uninstall" at the
root directory of an EPICS directory structure before each complete
rebuild to ensure that all components will be rebuilt.
### <span id="0_0_13">Example application and extension</span>
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
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
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
application as a host-based IOC, you will be able to quickly implement
a complete EPICS system and be able to run channel access clients on
the host system.
A perl script, makeBaseExt.pl, is included in the distribution file.
This script will create a sample extension that can be built and
executed. The makeBaseApp.pl and makeBaseExt.pl scripts are installed
into the install location bin/&lt;hostarch> directory during the base
build.
### <span id="0_0_14">Multiple host platforms</span>
You can build using a single EPICS directory structure on multiple
host systems and for multiple cross target systems. The intermediate
and binary files generated by the build will be created in separate
subdirectories and installed into the appropriate separate host/target
install directories. EPICS executables and perl scripts are installed
into the `$(INSTALL_LOCATION)/bin/<arch>` directories. Libraries are
installed into $`(INSTALL_LOCATION)/lib/<arch>`. The default
definition for `$(INSTALL_LOCATION)` is `$(TOP)` which is the root
directory in the distribution directory structure, base. Created
object files are stored in O.&lt;arch> source subdirectories, This
allows objects for multiple cross target architectures to be
maintained at the same time. To build EPICS base for a specific
host/target combination you must have the proper host/target C/C++
cross compiler and target header files and the base/configure/os
directory must have the appropriate configure files.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -91,7 +91,7 @@ relevent roles unless the Release Manager designates otherwise:</p>
<tr>
<td>&nbsp;</td>
<td>Release Manager</td>
<td>Set the Feature Freeze date, by which time all Bazaar commits for
<td>Set the Feature Freeze date, by which time all Git commits for
enhancements and new functionality should have been completed. After
this date, commits should only be made to fix problems that show up
during testing.</td>
@@ -133,39 +133,36 @@ relevent roles unless the Release Manager designates otherwise:</p>
<tr>
<td>&nbsp;</td>
<td>Release Manager</td>
<td>Tag the module in Bazaar, using these tag conventions:
<td>Tag the module in Git, using these tag conventions:
<ul>
<li>
<tt>R3.15.6-pre1</tt>
<tt>R3.15.7-pre1</tt>
&mdash; pre-release tag
</li>
<li>
<tt>R3.15.6-rc1</tt>
<tt>R3.15.7-rc1</tt>
&mdash; release candidate tag
</li>
</ul>
<blockquote><tt>
cd ~/base/mirror-3.15<br />
bzr tag R3.15.6-rc1
cd base-3.15<br />
git tag -m 'ANJ: Tagged for 3.15.7-rc1' R3.15.7-rc1
</tt></blockquote>
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>Release Manager</td>
<td>Export the tagged version into a tarfile. Note that this command
generates a gzipped tarfile directly from the repository:
<td>Export the tagged version into a tarfile. The <tt>make-tar.sh</tt>
script generates a gzipped tarfile directly from the tag, excluding the
files and directories that are only used for continuous integration:
<blockquote><tt>
cd ~/base<br />
bzr export
--root=base-3.15.6-rc1
-r tag:R3.15.6-rc1
base-3.15.6-rc1.tar.gz
mirror-3.15
cd base-3.15<br />
git archive --prefix=base-3.15.7-rc1/ --output=base-3.15.7-rc1.tar.gz R3.15.7-rc1 configure documentation LICENSE Makefile README src startup
</tt></blockquote>
Create a GPG signature file of the tarfile as follows:
<blockquote><tt>
gpg --armor --sign --detach-sig base-3.15.6-rc1.tar.gz
gpg --armor --sign --detach-sig base-3.15.7-rc1.tar.gz
</tt></blockquote>
</td>
</tr>
@@ -274,10 +271,10 @@ relevent roles unless the Release Manager designates otherwise:</p>
<tr>
<td>&nbsp;</td>
<td>Release Manager</td>
<td>Tag the module in Bazaar:
<td>Tag the module in Git:
<blockquote><tt>
cd ~/base/mirror-3.15<br />
bzr tag R3.15.6</i>
cd base-3.15<br />
git tag -m 'ANJ: Tagged for 3.15.7' R3.15.7
</tt></blockquote>
</td>
</tr>
@@ -287,16 +284,12 @@ relevent roles unless the Release Manager designates otherwise:</p>
<td>Export the tagged version into a tarfile. Note that this command
generates a gzipped tarfile directly from the repository:
<blockquote><tt>
cd ~/base<br />
bzr export
--root=base-3.15.6
-r tag:R3.15.6
base-3.15.6.tar.gz
mirror-3.15
cd base-3.15<br />
git archive --prefix=base-3.15.7/ --output=base-3.15.7.tar.gz R3.15.7 configure documentation LICENSE Makefile README src startup
</tt></blockquote>
Create a GPG signature file of the tarfile as follows:
<blockquote><tt>
gpg --armor --sign --detach-sig base-3.15.6.tar.gz
gpg --armor --sign --detach-sig base-3.15.7.tar.gz
</tt></blockquote>
</td>
</tr>

View File

@@ -1009,7 +1009,7 @@ d:/user/epics/base-3.15/lib/win32-x86/Com.lib</code></p>
<h2><a name="CommandUtils">Command Line Utilities</a></h2>
<h3><a name="acctst">acctst</a></h3>
<pre>acctst &lt;PV name&gt; [progress logging level] [channel duplication count]
<pre>acctst &lt;PV name&gt; [progress logging level] [channel duplication count]
[test repetition count] [enable preemptive callback]</pre>
<h4>Description</h4>
@@ -2079,7 +2079,7 @@ example, be beneficial when tuning an archiver installation.</p>
<p>Significant performance gains can be realized when the CA client library
doesn't wait for a response to return from the server after each request. All
requests which require interaction with a CA server are accumulated (buffered)
and not forwarded to the IOC until one of <code>ca_flush_io()</code>,
and not forwarded to the IOC until one of <code>ca_flush_io()</code>,
<code>ca_pend_io()</code>, <code>ca_pend_event()</code>, or
<code>ca_sg_block()</code> are called allowing several operations to be
efficiently sent over the network together. Any process variable values written
@@ -2103,16 +2103,16 @@ shouldn't test the success of a CA function call by checking to see if the
returned value is zero as is the UNIX convention. Below are several methods to
test CA function returns. See <a href="#ca_signal"><code>ca_signal()</code> and
<code>SEVCHK()</code></a> for more information on this topic.</p>
<pre>status = ca_XXXX();
SEVCHK( status, "ca_XXXX() returned failure status");
<pre>status = ca_XXXX();
SEVCHK( status, "ca_XXXX() returned failure status");
if ( status &amp; CA_M_SUCCESS ) {
printf ( "The requested ca_XXXX() operation didn't complete successfully");
}
if ( status &amp; CA_M_SUCCESS ) {
printf ( "The requested ca_XXXX() operation didn't complete successfully");
}
if ( status != ECA_NORMAL ) {
if ( status != ECA_NORMAL ) {
printf("The requested ca_XXXX() operation didn't complete successfully because \"%s\"\n",
ca_message ( status ) );
ca_message ( status ) );
}</pre>
<h3><a name="Channel">Channel Access Data Types</a></h3>
@@ -2285,7 +2285,7 @@ int main ( int argc, char ** argv )
unsigned nBytes;
unsigned elementCount;
char timeString[32];
unsigned i;
unsigned i;
chid chan;
double sum;
int status;
@@ -2328,7 +2328,7 @@ int main ( int argc, char ** argv )
epicsTimeToStrftime ( timeString, sizeof ( timeString ),
"%a %b %d %Y %H:%M:%S.%f", &amp; pTD-&gt;stamp );
printf ( "The sum of elements in %s at %s was %f\n",
printf ( "The sum of elements in %s at %s was %f\n",
argv[1], timeString, sum );
ca_clear_channel ( chan );
@@ -2359,7 +2359,7 @@ executing within the user's callback function.</p>
<pre>typedef struct event_handler_args {
void *usr; /* user argument supplied with request */
chanId chid; /* channel id */
long type; /* the type of the item returned */
long type; /* the type of the item returned */
long count; /* the element count of the item returned */
const void *dbr; /* a pointer to the item returned */
int status; /* ECA_XXX status of the requested op from the server */
@@ -2382,7 +2382,7 @@ attached to the request, an exception handler is executed in the client. The
default exception handler prints a message on the console and exits if the
exception condition is severe. Certain internal exceptions within the CA client
library, and failures detected by the SEVCHK macro may also cause the exception
handler to be invoked. To modify this behavior see
handler to be invoked. To modify this behavior see
<code><a href="#ca_add_exception_event">ca_add_exception_event</a>()</code>.</p>
<h3><a name="Server">Server and Client Share the Same Address Space on The Same
@@ -2674,6 +2674,14 @@ automatically released by the system when the process exits and
vxWorks or RTEMS no cleanup occurs unless the application calls
<code>ca_context_destroy()</code>.</p>
<p>Note: This operation blocks until any user callbacks for any channel
created in the current context have run to completion. If callbacks take a
lock (mutex) then it is the user's responsibility to ensure that this lock
is not held when <code>ca_clear_context()</code> is called, otherwise a
deadlock may ensue. (See also
<code><a href="#ca_clear_channel">ca_clear_channel</a>()</code> and
<code><a href="#ca_clear_event">ca_clear_subscription</a>()</code>.)</p>
<h4>Returns</h4>
<p>ECA_NORMAL - Normal successful completion</p>
@@ -2819,6 +2827,12 @@ efficiently sent over the network in one message.</p>
clearing a channel does shutdown and reclaim any channel state change event
subscriptions (monitors) registered with the channel.</p>
<p>Note: This operation blocks until any user callbacks for this channel
have run to completion. If callbacks take a lock (mutex) then it is the
user's responsibility to ensure that this lock is not held when
<code>ca_clear_channel()</code> is called, otherwise a deadlock may ensue.
(See also <code><a href="#ca_clear_event">ca_clear_subscription</a>()</code>.)</p>
<h4>Arguments</h4>
<dl>
<dt><code>CHID</code></dt>
@@ -2833,16 +2847,16 @@ subscriptions (monitors) registered with the channel.</p>
<h3><code><a name="ca_put">ca_put()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
int ca_put ( chtype TYPE,
chid CHID, void *PVALUE );
int ca_array_put ( chtype TYPE, unsigned long COUNT,
int ca_put ( chtype TYPE,
chid CHID, void *PVALUE );
int ca_array_put ( chtype TYPE, unsigned long COUNT,
chid CHID, const void *PVALUE);
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
int ca_put_callback ( chtype TYPE,
chid CHID, const void *PVALUE,
caEventCallBackFunc PFUNC, void *USERARG );
int ca_array_put_callback ( chtype TYPE, unsigned long COUNT,
chid CHID, const void *PVALUE,
int ca_put_callback ( chtype TYPE,
chid CHID, const void *PVALUE,
caEventCallBackFunc PFUNC, void *USERARG );
int ca_array_put_callback ( chtype TYPE, unsigned long COUNT,
chid CHID, const void *PVALUE,
caEventCallBackFunc PFUNC, void *USERARG );</pre>
<h4>Description</h4>
@@ -3069,7 +3083,7 @@ when a CA get request is initiated.</p>
typedef void ( caEventCallBackFunc ) (struct event_handler_args);
int ca_create_subscription ( chtype TYPE, unsigned long COUNT,
chid CHID, unsigned long MASK,
caEventCallBackFunc USERFUNC, void *USERARG,
caEventCallBackFunc USERFUNC, void *USERARG,
evid *PEVID );</pre>
<h4>Description</h4>
@@ -3123,7 +3137,8 @@ indicating the current state of the channel.</p>
<dl>
<dt><code>COUNT</code></dt>
<dd>The element count to be read from the specified channel. A count of
zero means use the current element count from the server.</dd>
zero means use the current element count from the server, effectively
resulting in a variable size array subscription.</dd>
</dl>
<dl>
<dt><code>CHID</code></dt>
@@ -3153,7 +3168,7 @@ indicating the current state of the channel.</p>
<dt><code>MASK</code></dt>
<dd>A mask with bits set for each of the event trigger types requested. The
event trigger mask must be a <em>bitwise or</em> of one or more of the
following constants.
following constants.
<ul>
<li>DBE_VALUE - Trigger events when the channel value exceeds the
monitor dead band</li>
@@ -3200,6 +3215,13 @@ and not forwarded to the server until one of <code>ca_flush_io()</code>, <code>c
<code>ca_pend_event()</code>, or <code>ca_sg_block()</code> are called. This allows several requests to be
efficiently sent together in one message.</p>
<p>Note: This operation blocks until any user callbacks for this channel
have run to completion. If callbacks take a lock (mutex) then it is the
user's responsibility to ensure that this lock is not held when
<code>ca_clear_subscription()</code> is called, otherwise a deadlock may
ensue. (See also <code><a
href="#ca_clear_channel">ca_clear_channel</a>()</code>.)</p>
<h4>Arguments</h4>
<dl>
<dt>EVID</dt>
@@ -3364,7 +3386,7 @@ becomes full.</p>
<h3><code><a name="ca_signal">ca_signal()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
int ca_signal ( long CA_STATUS, const char * CONTEXT_STRING );
int ca_signal ( long CA_STATUS, const char * CONTEXT_STRING );
void SEVCHK( CA_STATUS, CONTEXT_STRING );</pre>
<h4>Description</h4>
@@ -3381,7 +3403,7 @@ recommended error handler for simple applications which do not wish to write
code testing the status returned from each channel access call.</p>
<h4>Examples</h4>
<pre>status = ca_context_create (...);
<pre>status = ca_context_create (...);
SEVCHK ( status, "Unable to create a CA client context" );</pre>
<p>If the application only wishes to print the message associated with an error
@@ -3405,7 +3427,7 @@ this purpose.</p>
<h3><code><a
name="ca_add_exception_event">ca_add_exception_event()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
<pre>#include &lt;cadef.h&gt;
typedef void (*pCallback) ( struct exception_handler_args HANDLERARGS );
int ca_add_exception_event ( pCallback USERFUNC, void *USERARG );</pre>
@@ -3614,7 +3636,7 @@ specified channel.</p>
<dt><code>PFUNC</code></dt>
<dd>Pointer to a user supplied callback function. A null pointer uninstalls
the current handler. The following arguments are passed <em>by value</em>
to the supplied callback handler.
to the supplied callback handler.
<pre>typedef struct ca_access_rights {
unsigned read_access:1;
unsigned write_access:1;
@@ -3954,8 +3976,8 @@ type.</p>
prints diagnostics to standard out.</p>
<h4>Examples</h4>
<pre>void ca_test_event ();
status = ca_create_subscription ( type, chid, ca_test_event, NULL, NULL );
<pre>void ca_test_event ();
status = ca_create_subscription ( type, chid, ca_test_event, NULL, NULL );
SEVCHK ( status, .... );</pre>
<h4>See Also</h4>
@@ -3989,8 +4011,8 @@ outstanding within them at any given time.</p>
</dl>
<h4>Examples</h4>
<pre>CA_SYNC_GID gid;
status = ca_sg_create ( &amp;gid );
<pre>CA_SYNC_GID gid;
status = ca_sg_create ( &amp;gid );
SEVCHK ( status, Sync group create failed );</pre>
<h4>Returns</h4>
@@ -4028,8 +4050,8 @@ int ca_sg_delete ( CA_SYNC_GID GID );</pre>
</dl>
<h4>Examples</h4>
<pre>CA_SYNC_GID gid;
status = ca_sg_delete ( gid );
<pre>CA_SYNC_GID gid;
status = ca_sg_delete ( gid );
SEVCHK ( status, Sync group delete failed );</pre>
<h4>Returns</h4>
@@ -4140,7 +4162,7 @@ will not block unless additional subsequent requests are made.</p>
</dl>
<h4>Examples</h4>
<pre>CA_SYNC_GID gid;
<pre>CA_SYNC_GID gid;
status = ca_sg_reset(gid);</pre>
<h4>Returns</h4>
@@ -4153,7 +4175,7 @@ status = ca_sg_reset(gid);</pre>
<pre>#include &lt;cadef.h&gt;
int ca_sg_put ( CA_SYNC_GID GID, chtype TYPE,
chid CHID, void *PVALUE );
int ca_sg_array_put ( CA_SYNC_GID GID, chtype TYPE,
int ca_sg_array_put ( CA_SYNC_GID GID, chtype TYPE,
unsigned long COUNT, chid CHID, void *PVALUE );</pre>
<p>Write a value, or array of values, to a channel and increment the outstanding
@@ -4294,7 +4316,7 @@ reissued.</p>
<h3><code><a name="ca_client_status">ca_client_status()</a></code></h3>
<pre>int ca_client_status ( unsigned level );
int ca_context_status ( struct ca_client_context *CONTEXT,
int ca_context_status ( struct ca_client_context *CONTEXT,
unsigned LEVEL );</pre>
<h4>Description</h4>

View File

@@ -127,21 +127,10 @@ const char * ca_message_text []
static epicsThreadOnceId caClientContextIdOnce = EPICS_THREAD_ONCE_INIT;
extern "C" void ca_client_exit_handler (void *)
{
if ( caClientContextId ) {
epicsThreadPrivateDelete ( caClientContextId );
caClientContextId = 0;
}
}
// runs once only for each process
extern "C" void ca_init_client_context ( void * )
{
caClientContextId = epicsThreadPrivateCreate ();
if ( caClientContextId ) {
epicsAtExit ( ca_client_exit_handler,0 );
}
}
/*

View File

@@ -32,10 +32,12 @@
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
#include "epicsAssert.h"
#include "osiUnistd.h"
#include "udpiiu.h"
int main()
{
chdir ( "/" );
ca_repeater ();
return ( 0 );
}

View File

@@ -45,20 +45,12 @@ static epicsThreadOnceId cacOnce = EPICS_THREAD_ONCE_INIT;
const unsigned ca_client_context :: flushBlockThreshold = 0x58000;
extern "C" void cacExitHandler ( void *)
{
epicsThreadPrivateDelete ( caClientCallbackThreadId );
caClientCallbackThreadId = 0;
delete ca_client_context::pDefaultServiceInstallMutex;
}
// runs once only for each process
extern "C" void cacOnceFunc ( void * )
{
caClientCallbackThreadId = epicsThreadPrivateCreate ();
assert ( caClientCallbackThreadId );
ca_client_context::pDefaultServiceInstallMutex = newEpicsMutex;
epicsAtExit ( cacExitHandler,0 );
}
extern epicsThreadPrivateId caClientContextId;

View File

@@ -288,7 +288,6 @@ private:
};
extern "C" void cacOnceFunc ( void * );
extern "C" void cacExitHandler ( void *);
struct ca_client_context : public cacContextNotify
{
@@ -428,7 +427,6 @@ private:
ca_client_context & operator = ( const ca_client_context & );
friend void cacOnceFunc ( void * );
friend void cacExitHandler ( void *);
static cacService * pDefaultService;
static epicsMutex * pDefaultServiceInstallMutex;
static const unsigned flushBlockThreshold;

View File

@@ -390,7 +390,7 @@ int epicsShareAPI ca_array_get_callback ( chtype type,
{
caStatus = ECA_ALLOCMEM;
}
catch ( cacChannel::msgBodyCacheTooSmall ) {
catch ( cacChannel::msgBodyCacheTooSmall & ) {
caStatus = ECA_TOLARGE;
}
catch ( ... )

View File

@@ -652,7 +652,7 @@ not follow this pattern, but are still printable strings.
=item [1] R3.15 Channel Access Reference Manual by Jeffrey O. Hill
L<http://www.aps.anl.gov/epics/base/R3-15/2-docs/CAref.html>
L<https://epics.anl.gov/base/R3-15/5-docs/CAref.html>
=back

View File

@@ -8,6 +8,18 @@
TOP=../../../..
include $(TOP)/configure/CONFIG
ifdef T_A
PERL_VERSION = $(shell $(PERL) ../perlConfig.pl version)
PERL_ARCHNAME = $(shell $(PERL) ../perlConfig.pl archname)
PERL_ARCHPATH := $(PERL_VERSION)/$(PERL_ARCHNAME)
PERL_ARCHLIB := $(shell $(PERL) ../perlConfig.pl archlib)
PERL_h = $(PERL_ARCHLIB)/CORE/perl.h
EXTUTILS := $(shell $(PERL) ../perlConfig.pl privlib)/ExtUtils
PERLBIN := $(shell $(PERL) ../perlConfig.pl bin)
XSUBPP := $(firstword $(wildcard $(PERLBIN)/xsubpp $(EXTUTILS)/xsubpp))
# Special settings for Darwin:
ifeq ($(OS_CLASS),Darwin)
# Use hdepends command (not GNU compiler flags)
@@ -18,22 +30,23 @@ ifeq ($(OS_CLASS),Darwin)
# Perl loadable libraries on Darwin have funny names
LOADABLE_SHRLIB_PREFIX =
LOADABLE_SHRLIB_SUFFIX = .$(shell $(PERL) ../perlConfig.pl dlext)
ifeq ($(wildcard $(PERL_h)),)
# Perl's headers moved in Mojave
SDK_PATH := $(shell xcodebuild -version -sdk macosx Path)
PERL_ARCHLIB := $(SDK_PATH)/$(PERL_ARCHLIB)
endif
endif
ifdef T_A
PERL_VERSION = $(shell $(PERL) ../perlConfig.pl version)
PERL_ARCHNAME = $(shell $(PERL) ../perlConfig.pl archname)
PERL_ARCHPATH := $(PERL_VERSION)/$(PERL_ARCHNAME)
EXTUTILS := $(shell $(PERL) ../perlConfig.pl privlib)/ExtUtils
PERLBIN := $(shell $(PERL) ../perlConfig.pl bin)
XSUBPP := $(firstword $(wildcard $(PERLBIN)/xsubpp $(EXTUTILS)/xsubpp))
ifeq ($(T_A),$(EPICS_HOST_ARCH)) # No cross-builds (wrong Perl!)
ifeq ($(strip $(XSUBPP)),)
$(warning Perl's xsubpp program was not found.)
$(warning The Perl CA module will not be built.)
else
ifeq ($(T_A),$(EPICS_HOST_ARCH)) # No cross-builds (wrong Perl!)
ifeq ($(wildcard $(PERL_h)),)
$(warning Perl's C header files were not found.)
$(warning The Perl CA module will not be built.)
else
ifeq ($(findstring $(OS_CLASS),WIN32 cygwin32),) # Doesn't build on WIN32
LOADABLE_LIBRARY_HOST = Cap5
@@ -52,13 +65,14 @@ endif
endif
endif
endif
endif
Cap5_SRCS = Cap5.xs
Cap5_LIBS = ca Com
Cap5_INCLUDES = -I$(shell $(PERL) ../perlConfig.pl archlib)/CORE
Cap5_INCLUDES = -I$(PERL_ARCHLIB)/CORE
Cap5_CFLAGS = $(shell $(PERL) ../perlConfig.pl ccflags)
CLEANS += Cap5.c pod2htmd.tmp pod2htmi.tmp
CLEANS += Cap5.c
include $(TOP)/configure/RULES

View File

@@ -140,6 +140,10 @@ sub display {
printf " Lo ctrl limit: %g\n", $data->{lower_ctrl_limit};
printf " Hi ctrl limit: %g\n", $data->{upper_ctrl_limit};
}
if (exists $data->{ackt}) {
printf " Ack transients: %s\n", $data->{ackt} ? 'YES' : 'NO';
printf " Ack severity: %s\n", $data->{acks};
}
} else {
my $value = format_number($data, $type);
if ($opt_t) {

View File

@@ -34,6 +34,7 @@
#include <alarm.h>
#include <cadef.h>
#include <epicsGetopt.h>
#include "epicsVersion.h"
#include "tool_lib.h"
@@ -55,6 +56,7 @@ static void usage (void)
{
fprintf (stderr, "\nUsage: caget [options] <PV name> ...\n\n"
" -h: Help: Print this message\n"
" -V: Version: Show EPICS and CA versions\n"
"Channel Access options:\n"
" -w <sec>: Wait time, specifies CA timeout, default is %f second(s)\n"
" -c: Asynchronous get (use ca_get_callback and wait for completion)\n"
@@ -389,11 +391,14 @@ int main (int argc, char *argv[])
LINE_BUFFER(stdout); /* Configure stdout buffering */
while ((opt = getopt(argc, argv, ":taicnhsSe:f:g:l:#:d:0:w:p:F:")) != -1) {
while ((opt = getopt(argc, argv, ":taicnhsSVe:f:g:l:#:d:0:w:p:F:")) != -1) {
switch (opt) {
case 'h': /* Print usage */
usage();
return 0;
case 'V':
printf( "\nEPICS Version %s, CA Protocol version %s\n", EPICS_VERSION_STRING, ca_version() );
return 0;
case 't': /* Terse output mode */
complainIfNotPlainAndSet(&format, terse);
break;

View File

@@ -23,6 +23,7 @@
#include <stdio.h>
#include <epicsStdlib.h>
#include "epicsVersion.h"
#include <cadef.h>
#include <epicsGetopt.h>
@@ -36,12 +37,14 @@ void usage (void)
{
fprintf (stderr, "\nUsage: cainfo [options] <PV name> ...\n\n"
" -h: Help: Print this message\n"
" -V: Version: Show EPICS and CA versions\n"
"Channel Access options:\n"
" -w <sec>: Wait time, specifies CA timeout, default is %f second(s)\n"
" -s <level>: Call ca_client_status with the specified interest level\n"
" -p <prio>: CA priority (0-%u, default 0=lowest)\n"
"\nExample: cainfo my_channel another_channel\n\n"
, DEFAULT_TIMEOUT, CA_PRIORITY_MAX);
fprintf (stderr, "\nEPICS Version %s, CA Protocol version %s\n", EPICS_VERSION_STRING, ca_version() );
}
@@ -137,11 +140,14 @@ int main (int argc, char *argv[])
LINE_BUFFER(stdout); /* Configure stdout buffering */
while ((opt = getopt(argc, argv, ":nhw:s:p:")) != -1) {
while ((opt = getopt(argc, argv, ":nhVw:s:p:")) != -1) {
switch (opt) {
case 'h': /* Print usage */
usage();
return 0;
case 'V':
printf( "\nEPICS Version %s, CA Protocol version %s\n", EPICS_VERSION_STRING, ca_version() );
return 0;
case 'w': /* Set CA timeout value */
if(epicsScanDouble(optarg, &caTimeout) != 1)
{

View File

@@ -26,6 +26,7 @@
#include <stdio.h>
#include <epicsStdlib.h>
#include <string.h>
#include "epicsVersion.h"
#include <cadef.h>
#include <epicsGetopt.h>
@@ -44,7 +45,8 @@ void usage (void)
{
fprintf (stderr, "\nUsage: camonitor [options] <PV name> ...\n"
"\n"
" -h: Help; Print this message\n"
" -h: Help: Print this message\n"
" -V: Version: Show EPICS and CA versions\n"
"Channel Access options:\n"
" -w <sec>: Wait time, specifies CA timeout, default is %f second(s)\n"
" -m <msk>: Specify CA event mask to use. <msk> is any combination of\n"
@@ -209,11 +211,14 @@ int main (int argc, char *argv[])
LINE_BUFFER(stdout); /* Configure stdout buffering */
while ((opt = getopt(argc, argv, ":nhm:sSe:f:g:l:#:0:w:t:p:F:")) != -1) {
while ((opt = getopt(argc, argv, ":nhVm:sSe:f:g:l:#:0:w:t:p:F:")) != -1) {
switch (opt) {
case 'h': /* Print usage */
usage();
return 0;
case 'V':
printf( "\nEPICS Version %s, CA Protocol version %s\n", EPICS_VERSION_STRING, ca_version() );
return 0;
case 'n': /* Print ENUM as index numbers */
enumAsNr=1;
break;

View File

@@ -8,7 +8,7 @@
* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer
* Synchrotronstrahlung.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
@@ -37,6 +37,7 @@
#include <epicsGetopt.h>
#include <epicsEvent.h>
#include <epicsString.h>
#include "epicsVersion.h"
#include "tool_lib.h"
@@ -59,6 +60,7 @@ void usage (void)
fprintf (stderr, "\nUsage: caput [options] <PV name> <PV value> ...\n"
" caput -a [options] <PV name> <no of values> <PV value> ...\n\n"
" -h: Help: Print this message\n"
" -V: Version: Show EPICS and CA versions\n"
"Channel Access options:\n"
" -w <sec>: Wait time, specifies CA timeout, default is %f second(s)\n"
" -c: Asynchronous put (use ca_put_callback and wait for completion)\n"
@@ -281,11 +283,14 @@ int main (int argc, char *argv[])
LINE_BUFFER(stdout); /* Configure stdout buffering */
putenv("POSIXLY_CORRECT="); /* Behave correct on GNU getopt systems */
while ((opt = getopt(argc, argv, ":cnlhatsS#:w:p:F:")) != -1) {
while ((opt = getopt(argc, argv, ":cnlhatsVS#:w:p:F:")) != -1) {
switch (opt) {
case 'h': /* Print usage */
usage();
return 0;
case 'V':
printf( "\nEPICS Version %s, CA Protocol version %s\n", EPICS_VERSION_STRING, ca_version() );
return 0;
case 'n': /* Force interpret ENUM as index number */
enumAsNr = 1;
enumAsString = 0;
@@ -419,7 +424,7 @@ int main (int argc, char *argv[])
if (argc > optind+1) {
for (i = optind + 1; i < argc; i++) {
strcat(cbuf, " ");
strcat(cbuf, argv[i]);
strcat(cbuf, argv[i]);
}
}
@@ -530,6 +535,11 @@ int main (int argc, char *argv[])
/* Use standard put with defined timeout */
result = ca_array_put (dbrType, count, pvs[0].chid, pbuf);
}
if (result != ECA_NORMAL) {
fprintf(stderr, "Error from put operation: %s\n", ca_message(result));
return 1;
}
result = ca_pend_io(caTimeout);
if (result == ECA_TIMEOUT) {
fprintf(stderr, "Write operation timed out: Data was not written.\n");
@@ -545,7 +555,7 @@ int main (int argc, char *argv[])
}
if (result != ECA_NORMAL) {
fprintf(stderr, "Error occured writing data.\n");
fprintf(stderr, "Error occured writing data: %s\n", ca_message(result));
return 1;
}

View File

@@ -414,6 +414,12 @@ char *dbr2str (const void *value, unsigned type)
ptsNewS = &((struct TYPE *)value)->stamp; \
ptsNewC = &tsNow; \
\
if (!tsInitS) \
{ \
tsFirst = *ptsNewS; \
tsInitS = 1; \
} \
\
switch (tsType) { \
case relative: \
ptsRefC = &tsStart; \
@@ -506,12 +512,6 @@ void print_time_val_sts (pv* pv, unsigned long reqElems)
epicsTimeGetCurrent(&tsNow);
epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, &tsNow);
if (!tsInitS)
{
tsFirst = tsNow;
tsInitS = 1;
}
if (pv->nElems <= 1 && fieldSeparator == ' ') printf("%-30s", pv->name);
else printf("%s", pv->name);
printf("%c", fieldSeparator);

View File

@@ -644,6 +644,11 @@ caStatus casDGClient::processDG ()
if ( status != S_cas_success ) {
break;
}
if ( this->in.bytesPresent () > 0 && dgInBytesConsumed == 0 && status == S_cas_success ) {
this->in.removeMsg ( this->in.bytesPresent() );
}
}
return status;
}

View File

@@ -4,7 +4,7 @@
* 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.
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Author Jeffrey O. Hill
@@ -26,33 +26,39 @@
#include "casAsyncIOI.h"
#include "casMonitor.h"
casPVI::casPVI ( casPV & intf ) :
pCAS ( NULL ), pPV ( & intf ), nMonAttached ( 0u ),
// Use casErrMessage instead of errMessage to show PV name
#define casErrMessage(S, PM) \
errPrintf(S, __FILE__, __LINE__, ", %s, %s", getName(), PM)
casPVI::casPVI ( casPV & intf ) :
pCAS ( NULL ), pPV ( & intf ), nMonAttached ( 0u ),
nIOAttached ( 0u ), deletePending ( false ) {}
casPVI::~casPVI ()
{
//
// all channels should have been destroyed
// (otherwise the server tool is yanking the
//
// all channels should have been destroyed
// (otherwise the server tool is yanking the
// PV out from under the server)
//
casVerify ( this->chanList.count() == 0u );
//
casVerify ( this->chanList.count() == 0u );
//
// all outstanding IO should have been deleted
// when we destroyed the channels
//
casVerify ( this->nIOAttached == 0u );
//
// all outstanding IO should have been deleted
// when we destroyed the channels
//
casVerify ( this->nIOAttached == 0u );
if ( this->nIOAttached ) {
errlogPrintf ( "The number of IO objected attached is %u\n", this->nIOAttached );
errlogPrintf ( "%u IO objects still attached in destructor\n",
this->nIOAttached );
}
//
// all monitors should have been deleted
// when we destroyed the channels
//
casVerify ( this->nMonAttached == 0u );
//
// all monitors should have been deleted
// when we destroyed the channels
//
casVerify ( this->nMonAttached == 0u );
{
epicsGuard < epicsMutex > guard ( this->mutex );
@@ -139,26 +145,26 @@ caStatus casPVI::attachToServer ( caServerI & cas )
caStatus casPVI::updateEnumStringTable ( casCtx & ctxIn )
{
epicsGuard < epicsMutex > guard ( this->mutex );
//
// create a gdd with the "enum string table" application type
//
// gddArray(int app, aitEnum prim, int dimen, ...);
gdd * pTmp = new gddScalar ( gddAppType_enums );
if ( pTmp == NULL ) {
errMessage ( S_cas_noMemory,
casErrMessage ( S_cas_noMemory,
"unable to create gdd for read of application type \"enums\" string"
" conversion table for enumerated PV" );
return S_cas_noMemory;
}
caStatus status = convertContainerMemberToAtomic ( *pTmp,
caStatus status = convertContainerMemberToAtomic ( *pTmp,
gddAppType_enums, MAX_ENUM_STATES );
if ( status != S_cas_success ) {
pTmp->unreference ();
errMessage ( status,
"unable to to config gdd for read of application type \"enums\" string"
" conversion table for enumerated PV");
casErrMessage ( status,
"unable to config gdd for read of application type \"enums\" string"
" conversion table for enumerated PV" );
return status;
}
@@ -169,12 +175,11 @@ caStatus casPVI::updateEnumStringTable ( casCtx & ctxIn )
if ( status == S_cas_success ) {
updateEnumStringTableAsyncCompletion ( *pTmp );
}
else if ( status != S_casApp_asyncCompletion &&
else if ( status != S_casApp_asyncCompletion &&
status != S_casApp_postponeAsyncIO ) {
errPrintf ( status, __FILE__, __LINE__,
"- unable to read application type \"enums\" "
" (string conversion table) from enumerated native type PV \"%s\"",
this->getName() );
casErrMessage ( status,
"unable to read application type \"enums\" "
" (string conversion table) from enumerated native type PV" );
}
pTmp->unreference ();
@@ -185,40 +190,39 @@ caStatus casPVI::updateEnumStringTable ( casCtx & ctxIn )
void casPVI::updateEnumStringTableAsyncCompletion ( const gdd & resp )
{
epicsGuard < epicsMutex > guard ( this->mutex );
if ( resp.isContainer() ) {
errMessage ( S_cas_badType,
"application type \"enums\" string conversion table for"
" enumerated PV was a container (expected vector of strings)" );
casErrMessage ( S_cas_badType,
"Invalid \"enums\" string conversion table for"
" enumerated PV (container instead of vector of strings)" );
return;
}
if ( resp.dimension() == 0 ) {
if ( resp.primitiveType() == aitEnumString ) {
aitString *pStr = (aitString *) resp.dataVoid ();
if ( ! this->enumStrTbl.setString ( 0, pStr->string() ) ) {
errMessage ( S_cas_noMemory,
casErrMessage ( S_cas_noMemory,
"no memory to set enumerated PV string cache" );
}
}
else if ( resp.primitiveType() == aitEnumFixedString ) {
aitFixedString *pStr = (aitFixedString *) resp.dataVoid ();
if ( ! this->enumStrTbl.setString ( 0, pStr->fixed_string ) ) {
errMessage ( S_cas_noMemory,
casErrMessage ( S_cas_noMemory,
"no memory to set enumerated PV string cache" );
}
}
else {
errPrintf ( S_cas_badType, __FILE__, __LINE__,
casErrMessage ( S_cas_badType,
"application type \"enums\" string conversion"
" table for enumerated PV \"%s\" isnt a string type?",
getName() );
" table for enumerated PV isnt a string type?" );
}
}
else if ( resp.dimension() == 1 ) {
gddStatus gdd_status;
aitIndex index, first, count;
gdd_status = resp.getBound ( 0, first, count );
assert ( gdd_status == 0 );
@@ -232,7 +236,7 @@ void casPVI::updateEnumStringTableAsyncCompletion ( const gdd & resp )
aitString *pStr = (aitString *) resp.dataVoid ();
for ( index = 0; index<count; index++ ) {
if ( ! this->enumStrTbl.setString ( index, pStr[index].string() ) ) {
errMessage ( S_cas_noMemory,
casErrMessage ( S_cas_noMemory,
"no memory to set enumerated PV string cache" );
}
}
@@ -241,19 +245,18 @@ void casPVI::updateEnumStringTableAsyncCompletion ( const gdd & resp )
aitFixedString *pStr = (aitFixedString *) resp.dataVoid ();
for ( index = 0; index < count; index++ ) {
if ( ! this->enumStrTbl.setString ( index, pStr[index].fixed_string ) ) {
errMessage ( S_cas_noMemory,
casErrMessage ( S_cas_noMemory,
"no memory to set enumerated PV string cache" );
}
}
}
else {
errMessage ( S_cas_badType,
"application type \"enums\" string conversion"
" table for enumerated PV isnt a string type?" );
casErrMessage( S_cas_badType,
"bad \"enums\" string conversion table for enumerated PV" );
}
}
else {
errMessage ( S_cas_badType,
casErrMessage ( S_cas_badType,
"application type \"enums\" string conversion table"
" for enumerated PV was multi-dimensional"
" (expected vector of strings)" );
@@ -287,7 +290,7 @@ void casPVI::postEvent ( const casEventMask & select, const gdd & event )
}
}
caStatus casPVI::installMonitor (
caStatus casPVI::installMonitor (
casMonitor & mon, tsDLList < casMonitor > & monitorList )
{
epicsGuard < epicsMutex > guard ( this->mutex );
@@ -303,14 +306,14 @@ caStatus casPVI::installMonitor (
}
}
casMonitor * casPVI::removeMonitor (
casMonitor * casPVI::removeMonitor (
tsDLList < casMonitor > & list, ca_uint32_t clientIdIn )
{
epicsGuard < epicsMutex > guard ( this->mutex );
casMonitor * pMon = 0;
//
// (it is reasonable to do a linear search here because
// sane clients will require only one or two monitors
// sane clients will require only one or two monitors
// per channel)
//
tsDLIter < casMonitor > iter = list.firstIter ();
@@ -359,9 +362,9 @@ void casPVI::installChannel ( chanIntfForPV & chan )
epicsGuard < epicsMutex > guard ( this->mutex );
this->chanList.add ( chan );
}
void casPVI::removeChannel (
chanIntfForPV & chan, tsDLList < casMonitor > & src,
void casPVI::removeChannel (
chanIntfForPV & chan, tsDLList < casMonitor > & src,
tsDLList < casMonitor > & dest )
{
epicsGuard < epicsMutex > guard ( this->mutex );
@@ -380,8 +383,8 @@ void casPVI::clearOutstandingReads ( tsDLList < casAsyncIOI > & ioList )
{
epicsGuard < epicsMutex > guard ( this->mutex );
// cancel any pending asynchronous IO
tsDLIter < casAsyncIOI > iterIO =
// cancel any pending asynchronous IO
tsDLIter < casAsyncIOI > iterIO =
ioList.firstIter ();
while ( iterIO.valid () ) {
tsDLIter < casAsyncIOI > tmp = iterIO;
@@ -407,7 +410,7 @@ void casPVI::destroyAllIO ( tsDLList < casAsyncIOI > & ioList )
}
}
void casPVI::installIO (
void casPVI::installIO (
tsDLList < casAsyncIOI > & ioList, casAsyncIOI & io )
{
epicsGuard < epicsMutex > guard ( this->mutex );
@@ -416,7 +419,7 @@ void casPVI::installIO (
this->nIOAttached++;
}
void casPVI::uninstallIO (
void casPVI::uninstallIO (
tsDLList < casAsyncIOI > & ioList, casAsyncIOI & io )
{
{
@@ -517,8 +520,8 @@ aitEnum casPVI::bestExternalType () const
}
}
// CA only does 1D arrays for now
aitIndex casPVI::nativeCount ()
// CA only does 1D arrays for now
aitIndex casPVI::nativeCount ()
{
epicsGuard < epicsMutex > guard ( this->mutex );
if ( this->pPV ) {
@@ -542,4 +545,3 @@ const char * casPVI::getName () const
return "<disconnected>";
}
}

View File

@@ -1373,7 +1373,7 @@ caStatus casStrmClient :: searchAction ( epicsGuard < casClientMutex > & guard )
if ( pChanName[0] == '\0' ) {
caServerI::dumpMsg ( this->pHostName, "?", mp, this->ctx.getData(),
"zero length PV name in UDP search request?\n" );
"zero length PV name in TCP search request?\n" );
return S_cas_success;
}
@@ -1383,7 +1383,7 @@ caStatus casStrmClient :: searchAction ( epicsGuard < casClientMutex > & guard )
for ( unsigned i = mp->m_postsize-1; pChanName[i] != '\0'; i-- ) {
if ( i <= 1 ) {
caServerI::dumpMsg ( pHostName, "?", mp, this->ctx.getData(),
"unterminated PV name in UDP search request?\n" );
"unterminated PV name in TCP search request?\n" );
return S_cas_success;
}
}

View File

@@ -16,7 +16,7 @@
#include "shareLib.h"
typedef struct {
CALLBACK callback;
epicsCallback callback;
long status;
} ASDBCALLBACK;

View File

@@ -58,7 +58,7 @@ DBDINC += menuScan
DBDINC += dbCommon
dbMenusPod = $(notdir $(wildcard ../db/menu*.dbd.pod))
HTMLS += $(patsubst %.dbd.pod,%.html,$(menusPod))
HTMLS += $(patsubst %.dbd.pod,%.html,$(dbMenusPod))
dbCore_SRCS += dbLock.c
dbCore_SRCS += dbAccess.c

View File

@@ -46,6 +46,7 @@
#include "epicsExport.h"
#include "link.h"
#include "recSup.h"
#include "dbUnitTest.h" /* for testSyncCallback() */
static int callbackQueueSize = 2000;
@@ -167,7 +168,7 @@ static void callbackTask(void *arg)
epicsEventMustWait(mySet->semWakeUp);
while ((ptr = epicsRingPointerPop(mySet->queue))) {
CALLBACK *pcallback = (CALLBACK *)ptr;
epicsCallback *pcallback = (epicsCallback *)ptr;
if(!epicsRingPointerIsEmpty(mySet->queue))
epicsEventMustTrigger(mySet->semWakeUp);
mySet->queueOverflow = FALSE;
@@ -267,7 +268,7 @@ void callbackInit(void)
}
/* This routine can be called from interrupt context */
int callbackRequest(CALLBACK *pcallback)
int callbackRequest(epicsCallback *pcallback)
{
int priority;
int pushOK;
@@ -296,7 +297,7 @@ int callbackRequest(CALLBACK *pcallback)
return 0;
}
static void ProcessCallback(CALLBACK *pcallback)
static void ProcessCallback(epicsCallback *pcallback)
{
dbCommon *pRec;
@@ -307,14 +308,14 @@ static void ProcessCallback(CALLBACK *pcallback)
dbScanUnlock(pRec);
}
void callbackSetProcess(CALLBACK *pcallback, int Priority, void *pRec)
void callbackSetProcess(epicsCallback *pcallback, int Priority, void *pRec)
{
callbackSetCallback(ProcessCallback, pcallback);
callbackSetPriority(Priority, pcallback);
callbackSetUser(pRec, pcallback);
}
int callbackRequestProcessCallback(CALLBACK *pcallback,
int callbackRequestProcessCallback(epicsCallback *pcallback,
int Priority, void *pRec)
{
callbackSetProcess(pcallback, Priority, pRec);
@@ -323,11 +324,11 @@ int callbackRequestProcessCallback(CALLBACK *pcallback,
static void notify(void *pPrivate)
{
CALLBACK *pcallback = (CALLBACK *)pPrivate;
epicsCallback *pcallback = (epicsCallback *)pPrivate;
callbackRequest(pcallback);
}
void callbackRequestDelayed(CALLBACK *pcallback, double seconds)
void callbackRequestDelayed(epicsCallback *pcallback, double seconds)
{
epicsTimerId timer = (epicsTimerId)pcallback->timer;
@@ -338,7 +339,7 @@ void callbackRequestDelayed(CALLBACK *pcallback, double seconds)
epicsTimerStartDelay(timer, seconds);
}
void callbackCancelDelayed(CALLBACK *pcallback)
void callbackCancelDelayed(epicsCallback *pcallback)
{
epicsTimerId timer = (epicsTimerId)pcallback->timer;
@@ -347,9 +348,92 @@ void callbackCancelDelayed(CALLBACK *pcallback)
}
}
void callbackRequestProcessCallbackDelayed(CALLBACK *pcallback,
void callbackRequestProcessCallbackDelayed(epicsCallback *pcallback,
int Priority, void *pRec, double seconds)
{
callbackSetProcess(pcallback, Priority, pRec);
callbackRequestDelayed(pcallback, seconds);
}
/* Sync. process of testSyncCallback()
*
* 1. For each priority, make a call to callbackRequest() for each worker.
* 2. Wait until all callbacks are concurrently being executed
* 3. Last worker to begin executing signals success and begins waking up other workers
* 4. Last worker to wake signals testSyncCallback() to complete
*/
typedef struct {
epicsEventId wait_phase2, wait_phase4;
int nphase2, nphase3;
epicsCallback cb;
} sync_helper;
static void sync_callback(epicsCallback *cb)
{
sync_helper *helper;
callbackGetUser(helper, cb);
testGlobalLock();
assert(helper->nphase2 > 0);
if(--helper->nphase2!=0) {
/* we are _not_ the last to start. */
testGlobalUnlock();
epicsEventMustWait(helper->wait_phase2);
testGlobalLock();
}
/* we are either the last to start, or have been
* woken by the same and must pass the wakeup along
*/
epicsEventMustTrigger(helper->wait_phase2);
assert(helper->nphase2 == 0);
assert(helper->nphase3 > 0);
if(--helper->nphase3==0) {
/* we are the last to wake up. wake up testSyncCallback() */
epicsEventMustTrigger(helper->wait_phase4);
}
testGlobalUnlock();
}
void testSyncCallback(void)
{
sync_helper helper[NUM_CALLBACK_PRIORITIES];
unsigned i;
testDiag("Begin testSyncCallback()");
for(i=0; i<NUM_CALLBACK_PRIORITIES; i++) {
helper[i].wait_phase2 = epicsEventMustCreate(epicsEventEmpty);
helper[i].wait_phase4 = epicsEventMustCreate(epicsEventEmpty);
/* no real need to lock here, but do so anyway so that valgrind can establish
* the locking requirements for sync_helper.
*/
testGlobalLock();
helper[i].nphase2 = helper[i].nphase3 = callbackQueue[i].threadsRunning;
testGlobalUnlock();
callbackSetUser(&helper[i], &helper[i].cb);
callbackSetPriority(i, &helper[i].cb);
callbackSetCallback(sync_callback, &helper[i].cb);
callbackRequest(&helper[i].cb);
}
for(i=0; i<NUM_CALLBACK_PRIORITIES; i++) {
epicsEventMustWait(helper[i].wait_phase4);
}
for(i=0; i<NUM_CALLBACK_PRIORITIES; i++) {
testGlobalLock();
epicsEventDestroy(helper[i].wait_phase2);
epicsEventDestroy(helper[i].wait_phase4);
testGlobalUnlock();
}
testDiag("Complete testSyncCallback()");
}

View File

@@ -26,7 +26,7 @@ extern "C" {
/*
* WINDOWS also has a "CALLBACK" type def
*/
#ifdef _WIN32
#if defined(_WIN32) && !defined(EPICS_NO_CALLBACK)
# ifdef CALLBACK
# undef CALLBACK
# endif /*CALLBACK*/
@@ -42,7 +42,11 @@ typedef struct callbackPvt {
int priority;
void *user; /*for use by callback user*/
void *timer; /*for use by callback itself*/
}CALLBACK;
}epicsCallback;
#if !defined(EPICS_NO_CALLBACK)
typedef epicsCallback CALLBACK;
#endif
typedef void (*CALLBACKFUNC)(struct callbackPvt*);
@@ -53,21 +57,21 @@ typedef void (*CALLBACKFUNC)(struct callbackPvt*);
#define callbackSetUser(USER,PCALLBACK)\
( (PCALLBACK)->user = (void *)(USER) )
#define callbackGetUser(USER,PCALLBACK)\
( (USER) = (void *)((CALLBACK *)(PCALLBACK))->user )
( (USER) = (void *)((epicsCallback *)(PCALLBACK))->user )
epicsShareFunc void callbackInit(void);
epicsShareFunc void callbackStop(void);
epicsShareFunc void callbackCleanup(void);
epicsShareFunc int callbackRequest(CALLBACK *pCallback);
epicsShareFunc int callbackRequest(epicsCallback *pCallback);
epicsShareFunc void callbackSetProcess(
CALLBACK *pcallback, int Priority, void *pRec);
epicsCallback *pcallback, int Priority, void *pRec);
epicsShareFunc int callbackRequestProcessCallback(
CALLBACK *pCallback,int Priority, void *pRec);
epicsCallback *pCallback,int Priority, void *pRec);
epicsShareFunc void callbackRequestDelayed(
CALLBACK *pCallback,double seconds);
epicsShareFunc void callbackCancelDelayed(CALLBACK *pcallback);
epicsCallback *pCallback,double seconds);
epicsShareFunc void callbackCancelDelayed(epicsCallback *pcallback);
epicsShareFunc void callbackRequestProcessCallbackDelayed(
CALLBACK *pCallback, int Priority, void *pRec, double seconds);
epicsCallback *pCallback, int Priority, void *pRec, double seconds);
epicsShareFunc int callbackSetQueueSize(int size);
epicsShareFunc int callbackParallelThreads(int count, const char *prio);

View File

@@ -291,10 +291,14 @@ static void get_alarm(DBADDR *paddr, char **ppbuffer,
if (*options & DBR_AL_LONG) {
struct dbr_alLong *pal = (struct dbr_alLong*) pbuffer;
pal->upper_alarm_limit = (epicsInt32) ald.upper_alarm_limit;
pal->upper_warning_limit = (epicsInt32) ald.upper_warning_limit;
pal->lower_warning_limit = (epicsInt32) ald.lower_warning_limit;
pal->lower_alarm_limit = (epicsInt32) ald.lower_alarm_limit;
pal->upper_alarm_limit = finite(ald.upper_alarm_limit) ?
(epicsInt32) ald.upper_alarm_limit : 0;
pal->upper_warning_limit = finite(ald.upper_warning_limit) ?
(epicsInt32) ald.upper_warning_limit : 0;
pal->lower_warning_limit = finite(ald.lower_warning_limit) ?
(epicsInt32) ald.lower_warning_limit : 0;
pal->lower_alarm_limit = finite(ald.lower_alarm_limit) ?
(epicsInt32) ald.lower_alarm_limit : 0;
if (no_data)
*options ^= DBR_AL_LONG; /*Turn off option*/

View File

@@ -410,7 +410,7 @@ long dbd(const char *record_name)
precord = addr.precord;
if (! precord->bkpt & BKPT_ON_MASK) {
if (!(precord->bkpt & BKPT_ON_MASK)) {
printf(" BKPT> No breakpoint set in this record\n");
return(S_db_bkptNotSet);
}

View File

@@ -649,11 +649,16 @@ static void connectionCallback(struct connection_handler_args arg)
if (pca->gotFirstConnection) {
if (pca->nelements != ca_element_count(arg.chid) ||
pca->dbrType != ca_field_type(arg.chid)) {
/* BUG: We have no way to clear any old subscription with the
* originally chosen data type/size. That will continue
* to send us data and will result in an assert() fail.
*/
/* Let next dbCaGetLink and/or dbCaPutLink determine options */
/* Size or type changed, clear everything and let the next call
to dbCaGetLink() and/or dbCaPutLink() reset everything */
if (pca->evidNative) {
ca_clear_event(pca->evidNative);
pca->evidNative = 0;
}
if (pca->evidString) {
ca_clear_event(pca->evidString);
pca->evidString = 0;
}
plink->value.pv_link.pvlMask &=
~(pvlOptInpNative | pvlOptInpString |
pvlOptOutNative | pvlOptOutString);
@@ -701,6 +706,7 @@ static void eventCallback(struct event_handler_args arg)
struct dbr_time_double *pdbr_time_double;
dbCaCallback monitor = 0;
void *userPvt = 0;
int doScan = 1;
assert(pca);
epicsMutexMustLock(pca->lock);
@@ -729,10 +735,13 @@ static void eventCallback(struct event_handler_args arg)
memcpy(pca->pgetString, dbr_value_ptr(arg.dbr, arg.type), size);
pca->gotInString = TRUE;
} else switch (arg.type){
case DBR_TIME_ENUM:
/* Disable the record scan if we also have a string monitor */
doScan = !(plink->value.pv_link.pvlMask & pvlOptInpString);
/* fall through */
case DBR_TIME_STRING:
case DBR_TIME_SHORT:
case DBR_TIME_FLOAT:
case DBR_TIME_ENUM:
case DBR_TIME_CHAR:
case DBR_TIME_LONG:
case DBR_TIME_DOUBLE:
@@ -748,7 +757,7 @@ static void eventCallback(struct event_handler_args arg)
pca->sevr = pdbr_time_double->severity;
pca->stat = pdbr_time_double->status;
memcpy(&pca->timeStamp, &pdbr_time_double->stamp, sizeof(epicsTimeStamp));
if (precord) {
if (doScan && precord) {
struct pv_link *ppv_link = &plink->value.pv_link;
if ((ppv_link->pvlMask & pvlOptCP) ||
@@ -1005,7 +1014,8 @@ static void dbCaTask(void *arg)
status = ca_add_array_event(
ca_field_type(pca->chid)+DBR_TIME_STRING,
ca_element_count(pca->chid),
pca->chid, eventCallback, pca, 0.0, 0.0, 0.0, 0);
pca->chid, eventCallback, pca, 0.0, 0.0, 0.0,
&pca->evidNative);
if (status != ECA_NORMAL) {
errlogPrintf("dbCaTask ca_add_array_event %s\n",
ca_message(status));
@@ -1017,7 +1027,8 @@ static void dbCaTask(void *arg)
pca->pgetString = dbCalloc(1, MAX_STRING_SIZE);
epicsMutexUnlock(pca->lock);
status = ca_add_array_event(DBR_TIME_STRING, 1,
pca->chid, eventCallback, pca, 0.0, 0.0, 0.0, 0);
pca->chid, eventCallback, pca, 0.0, 0.0, 0.0,
&pca->evidString);
if (status != ECA_NORMAL) {
errlogPrintf("dbCaTask ca_add_array_event %s\n",
ca_message(status));

View File

@@ -78,6 +78,8 @@ typedef struct caLink
char *pgetString;
void *pputNative;
char *pputString;
evid evidNative;
evid evidString;
char gotInNative;
char gotInString;
char gotOutNative;

View File

@@ -21,6 +21,7 @@
#include "epicsAssert.h"
#include "epicsExit.h"
#include "epicsString.h"
#include "epicsStdio.h"
#include "errlog.h"
#include "freeList.h"
#include "gpHash.h"

View File

@@ -1165,3 +1165,8 @@ void db_delete_field_log (db_field_log *pfl)
freeListFree(dbevFieldLogFreeList, pfl);
}
}
int db_available_logs(void)
{
return (int) freeListItemsAvail(dbevFieldLogFreeList);
}

View File

@@ -78,6 +78,7 @@ epicsShareFunc void db_event_disable (dbEventSubscription es);
epicsShareFunc struct db_field_log* db_create_event_log (struct evSubscrip *pevent);
epicsShareFunc struct db_field_log* db_create_read_log (struct dbChannel *chan);
epicsShareFunc void db_delete_field_log (struct db_field_log *pfl);
epicsShareFunc int db_available_logs(void);
#define DB_EVENT_OK 0
#define DB_EVENT_ERROR (-1)
@@ -87,4 +88,3 @@ epicsShareFunc void db_delete_field_log (struct db_field_log *pfl);
#endif
#endif /*INCLdbEventh*/

View File

@@ -651,7 +651,7 @@ long dbGetLink(struct link *plink, short dbrType, void *pbuffer,
inherit_severity(&plink->value.pv_link, precord, stat, sevr);
break;
default:
cantProceed("dbGetLinkValue: Illegal link type %d\n", plink->type);
printf("dbGetLinkValue: Illegal link type %d\n", plink->type);
status = -1;
}
if (status) {
@@ -755,7 +755,7 @@ long dbPutLink(struct link *plink, short dbrType, const void *pbuffer,
status = dbCaPutLink(plink, dbrType, pbuffer, nRequest);
break;
default:
cantProceed("dbPutLinkValue: Illegal link type %d\n", plink->type);
printf("dbPutLinkValue: Illegal link type %d\n", plink->type);
status = -1;
}
if (status) {
@@ -836,4 +836,3 @@ long dbPutLinkLS(struct link *plink, char *pbuffer, epicsUInt32 len)
return dbPutLink(plink, DBR_STRING, pbuffer, 1);
}

View File

@@ -552,10 +552,10 @@ long dblsr(char *recordname,int level)
printf(" Not Locked\n");
} else {
printf(" thread %p",plockSet->thread_id);
if(! plockSet->precord || !plockSet->precord->name)
printf(" NULL record or record name\n");
if(! plockSet->precord)
printf(" NULL record\n");
else
printf(" record %s\n",plockSet->precord->name);
printf(" record %s\n",plockSet->precord->name);
}
if(level==0) { if(recordname) break; continue; }
for(plockRecord = (lockRecord *)ellFirst(&plockSet->lockRecordList);

View File

@@ -70,7 +70,7 @@ typedef struct notifyPvt {
ELLNODE node; /*For free list*/
long magic;
short state;
CALLBACK callback;
epicsCallback callback;
ELLLIST waitList; /*list of records for current processNotify*/
short cancelWait;
short userCallbackWait;
@@ -93,7 +93,7 @@ static void notifyCleanup(processNotify *ppn);
static void restartCheck(processNotifyRecord *ppnr);
static void callDone(dbCommon *precord,processNotify *ppn);
static void processNotifyCommon(processNotify *ppn,dbCommon *precord);
static void notifyCallback(CALLBACK *pcallback);
static void notifyCallback(epicsCallback *pcallback);
#define ellSafeAdd(list,listnode) \
{ \
@@ -265,7 +265,7 @@ static void processNotifyCommon(processNotify *ppn,dbCommon *precord)
callDone(precord, ppn);
}
static void notifyCallback(CALLBACK *pcallback)
static void notifyCallback(epicsCallback *pcallback)
{
processNotify *ppn = NULL;
dbCommon *precord;

View File

@@ -6,7 +6,7 @@
* Copyright (c) 2013 Helmholtz-Zentrum Berlin
* für Materialien und Energie GmbH.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* dbScan.c */
/* tasks and subroutines to scan the database */
@@ -109,10 +109,10 @@ static char *priorityName[NUM_CALLBACK_PRIORITIES] = {
/* EVENT */
typedef struct event_list {
CALLBACK callback[NUM_CALLBACK_PRIORITIES];
epicsCallback callback[NUM_CALLBACK_PRIORITIES];
scan_list scan_list[NUM_CALLBACK_PRIORITIES];
struct event_list *next;
char event_name[MAX_STRING_SIZE];
struct event_list *next;
char eventname[1]; /* actually arbitrary size */
} event_list;
static event_list * volatile pevent_list[256];
static epicsMutexId event_lock;
@@ -120,7 +120,7 @@ static epicsMutexId event_lock;
/* IO_EVENT*/
typedef struct io_scan_list {
CALLBACK callback;
epicsCallback callback;
scan_list scan_list;
} io_scan_list;
@@ -141,9 +141,9 @@ static void periodicTask(void *arg);
static void initPeriodic(void);
static void deletePeriodic(void);
static void spawnPeriodic(int ind);
static void eventCallback(CALLBACK *pcallback);
static void eventCallback(epicsCallback *pcallback);
static void ioscanInit(void);
static void ioscanCallback(CALLBACK *pcallback);
static void ioscanCallback(epicsCallback *pcallback);
static void ioscanDestroy(void);
static void printList(scan_list *psl, char *message);
static void scanList(scan_list *psl);
@@ -249,11 +249,6 @@ void scanAdd(struct dbCommon *precord)
event_list *pel;
eventname = precord->evnt;
if (strlen(eventname) >= MAX_STRING_SIZE) {
recGblRecordError(S_db_badField, (void *)precord,
"scanAdd: too long EVNT value");
return;
}
prio = precord->prio;
if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) {
recGblRecordError(-1, (void *)precord,
@@ -317,24 +312,17 @@ void scanDelete(struct dbCommon *precord)
recGblRecordError(-1, (void *)precord,
"scanDelete detected illegal SCAN value");
} else if (scan == menuScanEvent) {
char* eventname;
int prio;
event_list *pel;
scan_list *psl = 0;
eventname = precord->evnt;
prio = precord->prio;
if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) {
recGblRecordError(-1, (void *)precord,
"scanDelete detected illegal PRIO field");
return;
}
do /* multithreading: make sure pel is consistent */
pel = pevent_list[0];
while (pel != pevent_list[0]);
for (; pel; pel=pel->next) {
if (strcmp(pel->event_name, eventname) == 0) break;
}
pel = eventNameToHandle(precord->evnt);
if (pel && (psl = &pel->scan_list[prio]))
deleteFromList(precord, psl);
} else if (scan == menuScanI_O_Intr) {
@@ -422,14 +410,12 @@ int scanpel(const char* eventname) /* print event list */
int prio;
event_list *pel;
do /* multithreading: make sure pel is consistent */
pel = pevent_list[0];
while (pel != pevent_list[0]);
for (; pel; pel = pel->next) {
if (!eventname || strcmp(pel->event_name, eventname) == 0) {
for (pel = pevent_list[0]; pel; pel = pel->next) {
if (!eventname || epicsStrGlobMatch(pel->eventname, eventname)) {
printf("Event \"%s\"\n", pel->eventname);
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
if (ellCount(&pel->scan_list[prio].list) == 0) continue;
sprintf(message, "Event \"%s\" Priority %s", pel->event_name, priorityName[prio]);
sprintf(message, " Priority %s", priorityName[prio]);
printList(&pel->scan_list[prio], message);
}
}
@@ -462,7 +448,7 @@ int scanpiol(void) /* print pioscan_list */
return 0;
}
static void eventCallback(CALLBACK *pcallback)
static void eventCallback(epicsCallback *pcallback)
{
scan_list *psl;
@@ -480,18 +466,52 @@ event_list *eventNameToHandle(const char *eventname)
int prio;
event_list *pel;
static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT;
double eventnumber = 0;
size_t namelength;
if (!eventname || eventname[0] == 0)
return NULL;
if (!eventname) return NULL;
while (isspace((unsigned char)eventname[0])) eventname++;
if (!eventname[0]) return NULL;
namelength = strlen(eventname);
while (isspace((unsigned char)eventname[namelength-1])) namelength--;
/* Backward compatibility with numeric events:
Treat any string that represents a double with an
integer part between 0 and 255 the same as the integer
because it is most probably a conversion from double
like from a calc record.
*/
if (epicsParseDouble(eventname, &eventnumber, NULL) == 0)
{
if (eventnumber >= 0 && eventnumber < 256)
{
if (eventnumber < 1)
return NULL; /* 0 is no event */
if ((pel = pevent_list[(int)eventnumber]) != NULL)
return pel;
}
else
eventnumber = 0; /* not a numeric event between 1 and 255 */
}
epicsThreadOnce(&onceId, eventOnce, NULL);
epicsMutexMustLock(event_lock);
for (pel = pevent_list[0]; pel; pel=pel->next) {
if (strcmp(pel->event_name, eventname) == 0) break;
if (strncmp(pel->eventname, eventname, namelength) == 0
&& pel->eventname[namelength] == 0)
break;
}
if (pel == NULL) {
pel = dbCalloc(1, sizeof(event_list));
strcpy(pel->event_name, eventname);
pel = calloc(1, sizeof(event_list) + namelength);
if (!pel)
goto done;
if (eventnumber > 0) {
/* backward compatibility: make all numeric events look like integers */
sprintf(pel->eventname, "%i", (int)eventnumber);
pevent_list[(int)eventnumber] = pel;
}
else
strncpy(pel->eventname, eventname, namelength);
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
callbackSetUser(&pel->scan_list[prio], &pel->callback[prio]);
callbackSetPriority(prio, &pel->callback[prio]);
@@ -501,13 +521,8 @@ event_list *eventNameToHandle(const char *eventname)
}
pel->next=pevent_list[0];
pevent_list[0]=pel;
{ /* backward compatibility */
char* p;
long e = strtol(eventname, &p, 0);
if (*p == 0 && e > 0 && e <= 255)
pevent_list[e] = pel;
}
}
done:
epicsMutexUnlock(event_lock);
return pel;
}
@@ -527,13 +542,8 @@ void postEvent(event_list *pel)
/* backward compatibility */
void post_event(int event)
{
event_list* pel;
if (event <= 0 || event > 255) return;
do { /* multithreading: make sure pel is consistent */
pel = pevent_list[event];
} while (pel != pevent_list[event]);
postEvent(pel);
postEvent(pevent_list[event]);
}
static void ioscanOnce(void *arg)
@@ -853,7 +863,7 @@ static void spawnPeriodic(int ind)
epicsEventWait(startStopEvent);
}
static void ioscanCallback(CALLBACK *pcallback)
static void ioscanCallback(epicsCallback *pcallback)
{
ioscan_head *piosh = (ioscan_head *) pcallback->user;
int prio = pcallback->priority;

View File

@@ -50,7 +50,7 @@ epicsShareFunc void scanCleanup(void);
epicsShareFunc EVENTPVT eventNameToHandle(const char* event);
epicsShareFunc void postEvent(EVENTPVT epvt);
epicsShareFunc void post_event(int event) EPICS_DEPRECATED;
epicsShareFunc void post_event(int event);
epicsShareFunc void scanAdd(struct dbCommon *);
epicsShareFunc void scanDelete(struct dbCommon *);
epicsShareFunc double scanPeriod(int scan);

View File

@@ -37,6 +37,9 @@ dbStateId dbStateFind(const char *name)
ELLNODE *node;
dbStateId id;
if (!name)
return NULL;
for (node = ellFirst(&states); node; node = ellNext(node)) {
id = CONTAINER(node, dbState, node);
if (strcmp(id->name, name) == 0)
@@ -49,6 +52,9 @@ dbStateId dbStateCreate(const char *name)
{
dbStateId id;
if (!name)
return NULL;
if ((id = dbStateFind(name)))
return id;

View File

@@ -54,7 +54,7 @@ typedef struct msgBuff TAB_BUFFER;
# define MIN(x,y) (((x) < (y)) ? (x) : (y))
#endif
#ifndef MAX
# define MAX(x,y) (((x) < (y)) ? (x) : (y))
# define MAX(x,y) (((x) > (y)) ? (x) : (y))
#endif
/* Local Routines */
@@ -308,6 +308,11 @@ long dbgf(const char *pname)
if (nameToAddr(pname, &addr))
return -1;
if (addr.precord->lset == NULL) {
printf("dbgf only works after iocInit\n");
return -1;
}
no_elements = MIN(addr.no_elements, sizeof(buffer)/addr.field_size);
if (addr.dbr_field_type == DBR_ENUM) {
long status = dbGetField(&addr, DBR_STRING, pbuffer,
@@ -344,6 +349,11 @@ long dbpf(const char *pname,const char *pvalue)
if (nameToAddr(pname, &addr))
return -1;
if (addr.precord->lset == NULL) {
printf("dbpf only works after iocInit\n");
return -1;
}
if (addr.no_elements > 1 &&
(addr.dbr_field_type == DBR_CHAR || addr.dbr_field_type == DBR_UCHAR)) {
dbrType = addr.dbr_field_type;
@@ -398,6 +408,11 @@ long dbtr(const char *pname)
if (nameToAddr(pname, &addr))
return -1;
if (addr.precord->lset == NULL) {
printf("dbtr only works after iocInit\n");
return -1;
}
precord = (struct dbCommon*)addr.precord;
if (precord->pact) {
printf("record active\n");
@@ -437,6 +452,11 @@ long dbtgf(const char *pname)
if (nameToAddr(pname, &addr))
return -1;
if (addr.precord->lset == NULL) {
printf("dbtgf only works after iocInit\n");
return -1;
}
/* try all options first */
req_options = 0xffffffff;
ret_options = req_options;
@@ -534,6 +554,11 @@ long dbtpf(const char *pname, const char *pvalue)
if (nameToAddr(pname, &addr))
return -1;
if (addr.precord->lset == NULL) {
printf("dbtpf only works after iocInit\n");
return -1;
}
val_long = strtol(pvalue, &pend, 10);
validLong = (*pend == 0);
@@ -797,7 +822,7 @@ static void printBuffer(
printf("no_strs = %u:\n",
pdbr_enumStrs->no_str);
for (i = 0; i < pdbr_enumStrs->no_str; i++)
for (i = 0; i < pdbr_enumStrs->no_str; i++)
printf("\t\"%s\"\n", pdbr_enumStrs->strs[i]);
}
else {

View File

@@ -16,6 +16,7 @@
#include "epicsUnitTest.h"
#include "osiFileName.h"
#include "registry.h"
#include "epicsThread.h"
#define epicsExportSharedSymbols
#include "dbAccess.h"
@@ -111,7 +112,7 @@ long testdbVPutField(const char* pv, short dbrType, va_list ap)
return dbPutField(&addr, dbrType, pod.bytes, 1);
}
void testdbPutFieldOk(const char* pv, short dbrType, ...)
void testdbPutFieldOk(const char* pv, int dbrType, ...)
{
long ret;
va_list ap;
@@ -123,7 +124,7 @@ void testdbPutFieldOk(const char* pv, short dbrType, ...)
testOk(ret==0, "dbPutField(%s, %d, ...) == %ld", pv, dbrType, ret);
}
void testdbPutFieldFail(long status, const char* pv, short dbrType, ...)
void testdbPutFieldFail(long status, const char* pv, int dbrType, ...)
{
long ret;
va_list ap;
@@ -138,7 +139,7 @@ void testdbPutFieldFail(long status, const char* pv, short dbrType, ...)
testFail("dbPutField(\"%s\", %d, ...) != %ld (%ld)", pv, dbrType, status, ret);
}
void testdbGetFieldEqual(const char* pv, short dbrType, ...)
void testdbGetFieldEqual(const char* pv, int dbrType, ...)
{
va_list ap;
@@ -268,3 +269,26 @@ dbCommon* testdbRecordPtr(const char* pv)
return addr.precord;
}
static
epicsMutexId test_global;
static
epicsThreadOnceId test_global_once = EPICS_THREAD_ONCE_INIT;
static
void test_global_init(void* ignored)
{
test_global = epicsMutexMustCreate();
}
void testGlobalLock(void)
{
epicsThreadOnce(&test_global_once, &test_global_init, NULL);
epicsMutexMustLock(test_global);
}
void testGlobalUnlock(void)
{
epicsMutexUnlock(test_global);
}

View File

@@ -46,13 +46,13 @@ epicsShareFunc void testdbCleanup(void);
* testdbPutFieldOk("pvname", DBF_FLOAT, (double)4.1);
* testdbPutFieldOk("pvname", DBF_STRING, "hello world");
*/
epicsShareFunc void testdbPutFieldOk(const char* pv, short dbrType, ...);
epicsShareFunc void testdbPutFieldOk(const char* pv, int dbrType, ...);
/* Tests for put failure */
epicsShareFunc void testdbPutFieldFail(long status, const char* pv, short dbrType, ...);
epicsShareFunc void testdbPutFieldFail(long status, const char* pv, int dbrType, ...);
epicsShareFunc long testdbVPutField(const char* pv, short dbrType, va_list ap);
epicsShareFunc void testdbGetFieldEqual(const char* pv, short dbrType, ...);
epicsShareFunc void testdbGetFieldEqual(const char* pv, int dbrType, ...);
epicsShareFunc void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap);
/**
@@ -74,6 +74,65 @@ epicsShareFunc void testdbGetArrFieldEqual(const char* pv, short dbfType, long n
epicsShareFunc dbCommon* testdbRecordPtr(const char* pv);
/** Synchronize the shared callback queues.
*
* Block until all callback queue jobs which were queued, or running,
* have completed.
*/
epicsShareFunc void testSyncCallback(void);
/** Global mutex for use by test code.
*
* This utility mutex is intended to be used to avoid races in situations
* where some other syncronization primitive is being destroyed (epicsEvent,
* epicsMutex, ...).
*
* For example. The following has a subtle race where the event may be
* destroyed (free()'d) before the call to epicsEventMustSignal() has
* returned. On some targets this leads to a use after free() error.
*
@code
epicsEventId evt;
void thread1() {
evt = epicsEventMustCreate(...);
// spawn thread2()
epicsEventMustWait(evt);
epicsEventDestroy(evt);
}
// ...
void thread2() {
epicsEventMustSignal(evt);
}
@endcode
*
* One way to avoid this race is to use a global mutex to ensure
* that epicsEventMustSignal() has returned before destroying
* the event.
*
@code
epicsEventId evt;
void thread1() {
evt = epicsEventMustCreate(...);
// spawn thread2()
epicsEventMustWait(evt);
testGlobalLock(); // <-- added
epicsEventDestroy(evt);
testGlobalUnlock(); // <-- added
}
// ...
void thread2() {
testGlobalLock(); // <-- added
epicsEventMustSignal(evt);
testGlobalUnlock(); // <-- added
}
@endcode
*
* This must be a global mutex to avoid simply shifting the race
* from the event to a locally allocated mutex.
*/
epicsShareFunc void testGlobalLock(void);
epicsShareFunc void testGlobalUnlock(void);
#ifdef __cplusplus
}
#endif

View File

@@ -7,6 +7,17 @@
# and higher are distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
=head1 Menu menuAlarmStat
This menu defines the possible alarm statuses that EPICS records can exhibit
which is used for C<STAT> and C<NSTA> fields of all record types.
See L<Alarm Status> for more information.
=menu menuAlarmStat
=cut
menu(menuAlarmStat) {
choice(menuAlarmStatNO_ALARM,"NO_ALARM")
choice(menuAlarmStatREAD,"READ")

View File

@@ -7,6 +7,15 @@
# and higher are distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
=head1 Menu menuFtype
This menu is used for the C<FTVL> and similar fields of many record types.
=menu menuFtype
=cut
menu(menuFtype) {
choice(menuFtypeSTRING,"STRING")
choice(menuFtypeCHAR,"CHAR")

View File

@@ -3,10 +3,19 @@
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE Versions 3.13.7
# and higher are distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
# EPICS BASE is distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
=head1 Menu menuIvoa
This menu specifies the possibile actions to take when the INVALID alarm is
triggered. See individual record types for more information.
=menu menuIvoa
=cut
menu(menuIvoa) {
choice(menuIvoaContinue_normally,"Continue normally")
choice(menuIvoaDon_t_drive_outputs,"Don't drive outputs")

View File

@@ -1,13 +0,0 @@
#*************************************************************************
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE Versions 3.13.7
# and higher are distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
menu(menuOmsl) {
choice(menuOmslsupervisory,"supervisory")
choice(menuOmslclosed_loop,"closed_loop")
}

View File

@@ -6,19 +6,20 @@
# EPICS BASE is distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
recordtype(state) {
include "dbCommon.dbd"
field(VAL,DBF_STRING) {
prompt("Value")
promptgroup("40 - Input")
asl(ASL0)
pp(TRUE)
size(20)
}
field(OVAL,DBF_STRING) {
prompt("Prev Value")
special(SPC_NOMOD)
interest(3)
size(20)
}
=head1 Menu menuOmsl
This menu is used for the C<OMSL> field of many output record types. It controls
whether the record will fetch an input value from its C<DOL> input link when
processed, which is useful when it is part of a closed loop control algorithm.
The C<supervisory> state means the input link will not be used, C<closed_loop>
enables the input link.
=menu menuOmsl
=cut
menu(menuOmsl) {
choice(menuOmslsupervisory,"supervisory")
choice(menuOmslclosed_loop,"closed_loop")
}

View File

@@ -1,11 +1,48 @@
#*************************************************************************
# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
# Copyright (c) 2018 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 menuScan
This menu is used for the C<SCAN> field of all record types.
The set of periodic scan rates may be modified for an individual IOC by
copying the F<menuScan.dbd> file from Base into the IOC's source
directory and changing it to contain the desired scan rates.
The scan periods are extracted from the choice strings at runtime, which
must be expressed as a number with any of the following units appended:
=over 4
second
seconds
minute
minutes
hour
hours
Hertz
Hz
=back
At IOC start-up a separate scan thread will be created for each period,
with thread priority increasing further down the list, so faster periods
should appear after slower ones.
Scan rates that cannot be achieved will generate a warning message from
the C<iocInit> command.
=menu menuScan
=cut
menu(menuScan) {
choice(menuScanPassive,"Passive")
choice(menuScanEvent,"Event")

View File

@@ -1,13 +0,0 @@
#*************************************************************************
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE Versions 3.13.7
# and higher are distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
menu(menuYesNo) {
choice(menuYesNoNO,"NO")
choice(menuYesNoYES,"YES")
}

View File

@@ -0,0 +1,29 @@
#*************************************************************************
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
# EPICS BASE is distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
=head1 Menu menuYesNo
This menu is used by many record types to specify simple C<NO> or C<YES>
options for record-specific purposes.
Note that no other values for a field that uses menuYesNo are possible, e.g.
C<MAYBE> or C<NO WAY> would not be accepted as choices for the field.
Also, the choices C<yes>, C<No>, and C<Yes> are not valid choices since they
don't match the case of C<NO> or C<YES>.
The integer values C<0> and C<1> may often be used instead however, they are
used as an index into the choices so C<0> becomes C<NO> and C<1> becomes <YES>.
=menu menuYesNo
=cut
menu(menuYesNo) {
choice(menuYesNoNO,"NO")
choice(menuYesNoYES,"YES")
}

View File

@@ -18,6 +18,7 @@
#include <limits.h>
#include "dbDefs.h"
#include "alarm.h"
#include "epicsMath.h"
#include "epicsPrint.h"
#include "epicsStdlib.h"
@@ -181,6 +182,9 @@ unsigned short recGblResetAlarms(void *precord)
epicsEnum16 val_mask = 0;
epicsEnum16 stat_mask = 0;
if (new_sevr > INVALID_ALARM)
new_sevr = INVALID_ALARM;
pdbc->stat = new_stat;
pdbc->sevr = new_sevr;
pdbc->nsta = 0;

View File

@@ -34,6 +34,8 @@
*
* Two time intervals are measured. The time to queue and run each of
* the immediate callbacks, and the actual delay of the delayed callback.
*
* Slow callbacks no longer fail the test, they just emit a diagnostic.
*/
#define NCALLBACKS 169
@@ -42,8 +44,8 @@
#define TEST_DELAY(i) ((i / NUM_CALLBACK_PRIORITIES) * DELAY_QUANTUM)
typedef struct myPvt {
CALLBACK cb1;
CALLBACK cb2;
epicsCallback cb1;
epicsCallback cb2;
epicsTimeStamp pass1Time;
epicsTimeStamp pass2Time;
double delay;
@@ -53,7 +55,7 @@ typedef struct myPvt {
epicsEventId finished;
static void myCallback(CALLBACK *pCallback)
static void myCallback(epicsCallback *pCallback)
{
myPvt *pmyPvt;
@@ -72,7 +74,7 @@ static void myCallback(CALLBACK *pCallback)
}
}
static void finalCallback(CALLBACK *pCallback)
static void finalCallback(epicsCallback *pCallback)
{
myCallback(pCallback);
epicsEventSignal(finished);
@@ -108,7 +110,7 @@ MAIN(callbackParallelTest)
for (j = 0; j < 5; j++)
setupError[i][j] = timeError[i][j] = defaultError[j];
testPlan(4);
testPlan(2);
testDiag("Starting %d parallel callback threads", noCpus);
@@ -165,7 +167,8 @@ MAIN(callbackParallelTest)
}
}
testOk(faults == 0, "%d faults during callback setup", faults);
testOk(slowups <= 1, "%d slowups during callback setup", slowups);
if (slowups)
testDiag("%d slowups during callback setup", slowups);
slowups = 0;
for (i = 0; i < NCALLBACKS ; i++) {
@@ -182,7 +185,8 @@ MAIN(callbackParallelTest)
}
updateStats(timeError[i%NUM_CALLBACK_PRIORITIES], error);
}
testOk(slowups < 5, "%d slowups during callbacks", slowups);
if (slowups)
testDiag("%d slowups during callback setup", slowups);
testDiag("Setup time statistics");
printStats(setupError[0], "LOW");

View File

@@ -34,6 +34,8 @@
*
* Two time intervals are measured. The time to queue and run each of
* the immediate callbacks, and the actual delay of the delayed callback.
*
* Slow callbacks no longer fail the test, they just emit a diagnostic.
*/
#define NCALLBACKS 169
@@ -42,8 +44,8 @@
#define TEST_DELAY(i) ((i / NUM_CALLBACK_PRIORITIES) * DELAY_QUANTUM)
typedef struct myPvt {
CALLBACK cb1;
CALLBACK cb2;
epicsCallback cb1;
epicsCallback cb2;
epicsTimeStamp pass1Time;
epicsTimeStamp pass2Time;
double delay;
@@ -54,7 +56,7 @@ typedef struct myPvt {
epicsEventId finished;
static void myCallback(CALLBACK *pCallback)
static void myCallback(epicsCallback *pCallback)
{
myPvt *pmyPvt;
@@ -73,7 +75,7 @@ static void myCallback(CALLBACK *pCallback)
}
}
static void finalCallback(CALLBACK *pCallback)
static void finalCallback(epicsCallback *pCallback)
{
myCallback(pCallback);
epicsEventSignal(finished);
@@ -108,7 +110,7 @@ MAIN(callbackTest)
for (j = 0; j < 5; j++)
setupError[i][j] = timeError[i][j] = defaultError[j];
testPlan(4);
testPlan(2);
callbackInit();
epicsThreadSleep(1.0);
@@ -162,7 +164,8 @@ MAIN(callbackTest)
}
}
testOk(faults == 0, "%d faults during callback setup", faults);
testOk(slowups <= 1, "%d slowups during callback setup", slowups);
if (slowups)
testDiag("%d slowups during callback setup", slowups);
slowups = 0;
for (i = 0; i < NCALLBACKS ; i++) {
@@ -179,7 +182,8 @@ MAIN(callbackTest)
}
updateStats(timeError[i%NUM_CALLBACK_PRIORITIES], error);
}
testOk(slowups < 5, "%d slowups during callbacks", slowups);
if (slowups)
testDiag("%d slowups during callback setup", slowups);
testDiag("Setup time statistics");
printStats(setupError[0], "LOW");

View File

@@ -428,6 +428,10 @@ static void dbMenuHead(char *name)
dbMenu *pdbMenu;
GPHENTRY *pgphentry;
if (!*name) {
yyerrorAbort("dbMenuHead: Menu name can't be empty");
return;
}
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->menuList);
if(pgphentry) {
duplicate = TRUE;
@@ -441,6 +445,10 @@ static void dbMenuHead(char *name)
static void dbMenuChoice(char *name,char *value)
{
if (!*name) {
yyerror("dbMenuChoice: Menu choice name can't be empty");
return;
}
if(duplicate) return;
allocTemp(epicsStrDup(name));
allocTemp(epicsStrDup(value));
@@ -488,6 +496,10 @@ static void dbRecordtypeHead(char *name)
dbRecordType *pdbRecordType;
GPHENTRY *pgphentry;
if (!*name) {
yyerrorAbort("dbRecordtypeHead: Recordtype name can't be empty");
return;
}
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->recordTypeList);
if(pgphentry) {
duplicate = TRUE;
@@ -505,7 +517,11 @@ static void dbRecordtypeFieldHead(char *name,char *type)
{
dbFldDes *pdbFldDes;
int i;
if (!*name) {
yyerrorAbort("dbRecordtypeFieldHead: Field name can't be empty");
return;
}
if(duplicate) return;
pdbFldDes = dbCalloc(1,sizeof(dbFldDes));
allocTemp(pdbFldDes);
@@ -572,7 +588,7 @@ static void dbRecordtypeFieldItem(char *name,char *value)
if(sscanf(value,"%hd",&pdbFldDes->special)==1) {
return;
}
yyerror("Illegal special value.");
yyerror("Illegal 'special' value.");
return;
}
if(strcmp(name,"pp")==0) {
@@ -581,13 +597,13 @@ static void dbRecordtypeFieldItem(char *name,char *value)
} else if((strcmp(value,"NO")==0) || (strcmp(value,"FALSE")==0)) {
pdbFldDes->process_passive = FALSE;
} else {
yyerror("Illegal value. Must be NO or YES");
yyerror("Illegal 'pp' value, must be YES/NO/TRUE/FALSE");
}
return;
}
if(strcmp(name,"interest")==0) {
if(sscanf(value,"%hd",&pdbFldDes->interest)!=1)
yyerror("Illegal value. Must be integer");
yyerror("Illegal 'interest' value, must be integer");
return;
}
if(strcmp(name,"base")==0) {
@@ -596,13 +612,13 @@ static void dbRecordtypeFieldItem(char *name,char *value)
} else if(strcmp(value,"HEX")==0) {
pdbFldDes->base = CT_HEX;
} else {
yyerror("Illegal value. Must be CT_DECIMAL or CT_HEX");
yyerror("Illegal 'base' value, must be DECIMAL/HEX");
}
return;
}
if(strcmp(name,"size")==0) {
if(sscanf(value,"%hd",&pdbFldDes->size)!=1)
yyerror("Illegal value. Must be integer");
yyerror("Illegal 'size' value, must be integer");
return;
}
if(strcmp(name,"extra")==0) {
@@ -794,6 +810,10 @@ static void dbDriver(char *name)
drvSup *pdrvSup;
GPHENTRY *pgphentry;
if (!*name) {
yyerrorAbort("dbDriver: Driver name can't be empty");
return;
}
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->drvList);
if(pgphentry) {
return;
@@ -813,6 +833,10 @@ static void dbRegistrar(char *name)
dbText *ptext;
GPHENTRY *pgphentry;
if (!*name) {
yyerrorAbort("dbRegistrar: Registrar name can't be empty");
return;
}
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->registrarList);
if(pgphentry) {
return;
@@ -832,6 +856,10 @@ static void dbFunction(char *name)
dbText *ptext;
GPHENTRY *pgphentry;
if (!*name) {
yyerrorAbort("dbFunction: Function name can't be empty");
return;
}
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->functionList);
if(pgphentry) {
return;
@@ -851,6 +879,10 @@ static void dbVariable(char *name, char *type)
dbVariableDef *pvar;
GPHENTRY *pgphentry;
if (!*name) {
yyerrorAbort("dbVariable: Variable name can't be empty");
return;
}
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->variableList);
if(pgphentry) {
return;
@@ -871,6 +903,10 @@ static void dbBreakHead(char *name)
brkTable *pbrkTable;
GPHENTRY *pgphentry;
if (!*name) {
yyerrorAbort("dbBreakHead: Breaktable name can't be empty");
return;
}
pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->bptList);
if(pgphentry) {
duplicate = TRUE;
@@ -973,6 +1009,10 @@ static void dbRecordHead(char *recordType, char *name, int visible)
DBENTRY *pdbentry;
long status;
if (!*name) {
yyerrorAbort("dbRecordHead: Record name can't be empty");
return;
}
badch = strpbrk(name, " \"'.$");
if (badch) {
epicsPrintf("Bad character '%c' in record name \"%s\"\n",
@@ -1036,23 +1076,29 @@ static void dbRecordHead(char *recordType, char *name, int visible)
static void dbRecordField(char *name,char *value)
{
DBENTRY *pdbentry;
tempListNode *ptempListNode;
long status;
DBENTRY *pdbentry;
tempListNode *ptempListNode;
long status;
if(duplicate) return;
if (duplicate) return;
ptempListNode = (tempListNode *)ellFirst(&tempList);
pdbentry = ptempListNode->item;
status = dbFindField(pdbentry,name);
if(status) {
epicsPrintf("Record \"%s\" does not have a field \"%s\"\n",
dbGetRecordName(pdbentry), name);
yyerror(NULL);
return;
if (status) {
epicsPrintf("Record \"%s\" does not have a field \"%s\"\n",
dbGetRecordName(pdbentry), name);
yyerror(NULL);
return;
}
if (pdbentry->indfield == 0) {
epicsPrintf("Can't set \"NAME\" field of record \"%s\"\n",
dbGetRecordName(pdbentry));
yyerror(NULL);
return;
}
dbTranslateEscape(value, value); /* yuck: in-place, but safe */
status = dbPutString(pdbentry,value);
if(status) {
if (status) {
epicsPrintf("Can't set \"%s.%s\" to \"%s\"\n",
dbGetRecordName(pdbentry), name, value);
yyerror(NULL);
@@ -1062,33 +1108,42 @@ static void dbRecordField(char *name,char *value)
static void dbRecordInfo(char *name, char *value)
{
DBENTRY *pdbentry;
tempListNode *ptempListNode;
long status;
DBENTRY *pdbentry;
tempListNode *ptempListNode;
long status;
if(duplicate) return;
if (!*name) {
yyerrorAbort("dbRecordInfo: Info item name can't be empty");
return;
}
if (duplicate) return;
ptempListNode = (tempListNode *)ellFirst(&tempList);
pdbentry = ptempListNode->item;
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",
if (status) {
epicsPrintf("Can't set \"%s\" info \"%s\" to \"%s\"\n",
dbGetRecordName(pdbentry), name, value);
yyerror(NULL);
return;
yyerror(NULL);
return;
}
}
static void dbRecordAlias(char *name)
{
DBENTRY *pdbentry;
tempListNode *ptempListNode;
long status;
DBENTRY *pdbentry;
tempListNode *ptempListNode;
long status;
if(duplicate) return;
if (!*name) {
yyerrorAbort("dbRecordAlias: Alias name can't be empty");
return;
}
if (duplicate) return;
ptempListNode = (tempListNode *)ellFirst(&tempList);
pdbentry = ptempListNode->item;
status = dbCreateAlias(pdbentry, name);
if(status) {
if (status) {
epicsPrintf("Can't create alias \"%s\" for \"%s\"\n",
name, dbGetRecordName(pdbentry));
yyerror(NULL);
@@ -1098,15 +1153,20 @@ static void dbRecordAlias(char *name)
static void dbAlias(char *name, char *alias)
{
DBENTRY dbEntry;
DBENTRY *pdbEntry = &dbEntry;
DBENTRY dbEntry;
DBENTRY *pdbEntry = &dbEntry;
if (!*alias) {
yyerrorAbort("dbAlias: Alias name can't be empty");
return;
}
dbInitEntry(pdbbase, pdbEntry);
if (dbFindRecord(pdbEntry, name)) {
epicsPrintf("Alias \"%s\" refers to unknown record \"%s\"\n",
alias, name);
yyerror(NULL);
} else if (dbCreateAlias(pdbEntry, alias)) {
}
else if (dbCreateAlias(pdbEntry, alias)) {
epicsPrintf("Can't create alias \"%s\" referring to \"%s\"\n",
alias, name);
yyerror(NULL);
@@ -1116,14 +1176,14 @@ static void dbAlias(char *name, char *alias)
static void dbRecordBody(void)
{
DBENTRY *pdbentry;
DBENTRY *pdbentry;
if(duplicate) {
duplicate = FALSE;
return;
if (duplicate) {
duplicate = FALSE;
return;
}
pdbentry = (DBENTRY *)popFirstTemp();
if(ellCount(&tempList))
yyerrorAbort("dbRecordBody: tempList not empty");
if (ellCount(&tempList))
yyerrorAbort("dbRecordBody: tempList not empty");
dbFreeEntry(pdbentry);
}

View File

@@ -851,10 +851,14 @@ long dbWriteRecordFP(
status=dbNextField(pdbentry,dctonly);
}
status = dbFirstInfo(pdbentry);
while(!status) {
fprintf(fp,"\tinfo(\"%s\",\"%s\")\n",
dbGetInfoName(pdbentry), dbGetInfoString(pdbentry));
status=dbNextInfo(pdbentry);
while (!status) {
const char *pinfostr = dbGetInfoString(pdbentry);
fprintf(fp, "\tinfo(\"%s\",\"",
dbGetInfoName(pdbentry));
epicsStrPrintEscaped(fp, pinfostr, strlen(pinfostr));
fprintf(fp, "\")\n");
status = dbNextInfo(pdbentry);
}
fprintf(fp,"}\n");
status = dbNextRecord(pdbentry);
@@ -1631,19 +1635,22 @@ int dbIsVisibleRecord(DBENTRY *pdbentry)
long dbCreateAlias(DBENTRY *pdbentry, const char *alias)
{
dbRecordType *precordType = pdbentry->precordType;
dbRecordNode *precnode = pdbentry->precnode;
dbRecordNode *pnewnode;
PVDENTRY *ppvd;
ELLLIST *preclist = NULL;
dbRecordType *precordType = pdbentry->precordType;
dbRecordNode *precnode = pdbentry->precnode;
dbRecordNode *pnewnode;
DBENTRY tempEntry;
PVDENTRY *ppvd;
if (!precordType)
return S_dbLib_recordTypeNotFound;
if (!precnode)
return S_dbLib_recNotFound;
dbInitEntry(pdbentry->pdbbase, &tempEntry);
if (!dbFindRecord(&tempEntry, alias))
return S_dbLib_recExists;
dbFinishEntry(&tempEntry);
if (!precordType) return S_dbLib_recordTypeNotFound;
if (!precnode) return S_dbLib_recNotFound;
zeroDbentry(pdbentry);
if (!dbFindRecord(pdbentry, alias)) return S_dbLib_recExists;
zeroDbentry(pdbentry);
pdbentry->precordType = precordType;
preclist = &precordType->recList;
pnewnode = dbCalloc(1, sizeof(dbRecordNode));
pnewnode->recordname = epicsStrDup(alias);
pnewnode->precord = precnode->precord;
@@ -1651,11 +1658,16 @@ long dbCreateAlias(DBENTRY *pdbentry, const char *alias)
if (!(precnode->flags & DBRN_FLAGS_ISALIAS))
precnode->flags |= DBRN_FLAGS_HASALIAS;
ellInit(&pnewnode->infoList);
ellAdd(preclist, &pnewnode->node);
ellAdd(&precordType->recList, &pnewnode->node);
precordType->no_aliases++;
pdbentry->precnode = pnewnode;
ppvd = dbPvdAdd(pdbentry->pdbbase, precordType, pnewnode);
if (!ppvd) {errMessage(-1,"Logic Err: Could not add to PVD");return(-1);}
if (!ppvd) {
errMessage(-1, "dbCreateAlias: Add to PVD failed");
return -1;
}
return 0;
}

View File

@@ -13,7 +13,7 @@ SRC_DIRS += $(IOCDIR)/dbtemplate
PROD_HOST += msi
msi_SRCS = msi.c
msi_SRCS = msi.cpp
msi_LIBS += Com
HTMLS += msi.html

View File

@@ -1,895 +0,0 @@
/*************************************************************************\
* Copyright (c) 2010 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 the file LICENSE that is included with this distribution.
\*************************************************************************/
/* msi - macro substitutions and include */
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <dbDefs.h>
#include <macLib.h>
#include <ellLib.h>
#include <errlog.h>
#include <epicsString.h>
#include <osiFileName.h>
#define MAX_BUFFER_SIZE 4096
#define MAX_DEPS 1024
/* Module to read the template files */
typedef struct inputData inputData;
static void inputConstruct(inputData **ppvt);
static void inputDestruct(inputData *pvt);
static void inputAddPath(inputData *pvt, char *pval);
static void inputBegin(inputData *pvt, char *fileName);
static char *inputNextLine(inputData *pvt);
static void inputNewIncludeFile(inputData *pvt, char *name);
static void inputErrPrint(inputData *pvt);
/* Module to read the substitution file */
typedef struct subInfo subInfo;
static void substituteOpen(subInfo **ppvt, char *substitutionName);
static void substituteDestruct(subInfo *pvt);
static int substituteGetNextSet(subInfo *pvt, char **filename);
static int substituteGetGlobalSet(subInfo *pvt);
static char *substituteGetReplacements(subInfo *pvt);
static char *substituteGetGlobalReplacements(subInfo *pvt);
/* Forward references to local routines */
static void usageExit(int status);
static void addMacroReplacements(MAC_HANDLE *macPvt, char *pval);
static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *templateName);
/*Global variables */
static int opt_V = 0;
static int opt_D = 0;
static char *outFile = 0;
static int numDeps = 0, depHashes[MAX_DEPS];
int main(int argc,char **argv)
{
inputData *inputPvt;
MAC_HANDLE *macPvt;
char *pval;
int narg;
char *substitutionName=0;
char *templateName=0;
int i;
int localScope = 1;
inputConstruct(&inputPvt);
macCreateHandle(&macPvt,0);
while((argc>1) && (argv[1][0] == '-')) {
narg = (strlen(argv[1])==2) ? 2 : 1;
pval = (narg==1) ? (argv[1]+2) : argv[2];
if(strncmp(argv[1],"-I",2)==0) {
inputAddPath(inputPvt,pval);
} else if (strcmp(argv[1], "-D") == 0) {
opt_D = 1;
narg = 1; /* no argument for this option */
} else if(strncmp(argv[1],"-o",2)==0) {
outFile = epicsStrDup(pval);
} else if(strncmp(argv[1],"-M",2)==0) {
addMacroReplacements(macPvt,pval);
} else if(strncmp(argv[1],"-S",2)==0) {
substitutionName = epicsStrDup(pval);
} else if (strcmp(argv[1], "-V") == 0) {
opt_V = 1;
narg = 1; /* no argument for this option */
} else if (strcmp(argv[1], "-g") == 0) {
localScope = 0;
narg = 1; /* no argument for this option */
} else if (strcmp(argv[1], "-h") == 0) {
usageExit(0);
} else {
fprintf(stderr, "msi: Bad argument \"%s\"\n", argv[1]);
usageExit(1);
}
argc -= narg;
for(i=1; i<argc; i++) argv[i] = argv[i + narg];
}
if (!opt_V)
macSuppressWarning(macPvt,1);
if(argc>2) {
fprintf(stderr,"msi: Too many arguments\n");
usageExit(1);
}
if (opt_D) {
if (!outFile) {
fprintf(stderr, "msi: Option -D requires -o for Makefile target\n");
exit(1);
}
printf("%s:", outFile);
}
else if (outFile && freopen(outFile, "w", stdout) == NULL) {
fprintf(stderr, "msi: Can't open %s for writing: %s\n",
outFile, strerror(errno));
exit(1);
}
if(argc==2) {
templateName = epicsStrDup(argv[1]);
}
if(!substitutionName) {
makeSubstitutions(inputPvt,macPvt,templateName);
} else {
subInfo *substitutePvt;
char *filename = 0;
int isGlobal, isFile;
substituteOpen(&substitutePvt,substitutionName);
do {
if ((isGlobal = substituteGetGlobalSet(substitutePvt))) {
pval = substituteGetGlobalReplacements(substitutePvt);
if(pval) {
addMacroReplacements(macPvt,pval);
}
} else if ((isFile = substituteGetNextSet(substitutePvt,&filename))) {
if(templateName) filename = templateName;
if(!filename) {
fprintf(stderr,"msi: No template file\n");
usageExit(1);
}
while((pval = substituteGetReplacements(substitutePvt))){
if (localScope) macPushScope(macPvt);
addMacroReplacements(macPvt,pval);
makeSubstitutions(inputPvt,macPvt,filename);
if (localScope) macPopScope(macPvt);
}
}
} while (isGlobal || isFile);
substituteDestruct(substitutePvt);
}
errlogFlush();
macDeleteHandle(macPvt);
inputDestruct(inputPvt);
if (opt_D) {
printf("\n");
}
free(templateName);
free(substitutionName);
return opt_V & 2;
}
void usageExit(int status)
{
fprintf(stderr,
"Usage: msi [options] [template]\n"
" stdin is used if neither template nor substitution file is given\n"
" options:\n"
" -h Print this help message\n"
" -D Output file dependencies, not substitutions\n"
" -V Undefined macros generate an error\n"
" -g All macros have global scope\n"
" -o<FILE> Send output to <FILE>\n"
" -I<DIR> Add <DIR> to include file search path\n"
" -M<SUBST> Add <SUBST> to (global) macro definitions\n"
" (<SUBST> takes the form VAR=VALUE,...)\n"
" -S<FILE> Expand the substitutions in FILE\n");
exit(status);
}
static void addMacroReplacements(MAC_HANDLE *macPvt,char *pval)
{
char **pairs;
long status;
status = macParseDefns(macPvt,pval,&pairs);
if(status==-1) {
fprintf(stderr,"msi: Error from macParseDefns\n");
usageExit(1);
}
if(status) {
status = macInstallMacros(macPvt,pairs);
if(!status) {
fprintf(stderr,"Error from macInstallMacros\n");
usageExit(1);
}
free(pairs);
}
}
typedef enum {cmdInclude,cmdSubstitute} cmdType;
static const char *cmdNames[] = {"include","substitute"};
static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *templateName)
{
char *input;
static char buffer[MAX_BUFFER_SIZE];
int n;
inputBegin(inputPvt,templateName);
while((input = inputNextLine(inputPvt))) {
int expand=1;
char *p;
char *command = 0;
p = input;
/*skip whitespace at beginning of line*/
while(*p && (isspace((int) *p))) ++p;
/*Look for i or s */
if(*p && (*p=='i' || *p=='s')) command = p;
if(command) {
char *pstart;
char *pend;
char *copy;
int cmdind=-1;
int i;
for(i=0; i< NELEMENTS(cmdNames); i++) {
if(strstr(command,cmdNames[i])) {
cmdind = i;
}
}
if(cmdind<0) goto endif;
p = command + strlen(cmdNames[cmdind]);
/*skip whitespace after command*/
while(*p && (isspace((int) *p))) ++p;
/*Next character must be quote*/
if((*p==0) || (*p!='"')) goto endif;
pstart = ++p;
/*Look for end quote*/
while(*p && (*p!='"')) {
/*allow escape for imbeded quote*/
if((*p=='\\') && *(p+1)=='"') {
p += 2; continue;
} else {
if(*p=='"') break;
}
++p;
}
pend = p;
if(*p==0) goto endif;
/*skip quote and any trailing blanks*/
while(*++p==' ') ;
if(*p != '\n' && *p !=0) goto endif;
copy = calloc(pend-pstart+1,sizeof(char));
strncpy(copy,pstart,pend-pstart);
switch(cmdind) {
case cmdInclude:
inputNewIncludeFile(inputPvt,copy);
break;
case cmdSubstitute:
addMacroReplacements(macPvt,copy);
break;
default:
fprintf(stderr,"msi: Logic error in makeSubstitutions\n");
inputErrPrint(inputPvt);
exit(1);
}
free(copy);
expand = 0;
}
endif:
if (expand && !opt_D) {
n = macExpandString(macPvt,input,buffer,MAX_BUFFER_SIZE-1);
fputs(buffer,stdout);
if (opt_V == 1 && n < 0) {
fprintf(stderr,"msi: Error - undefined macros present\n");
opt_V++;
}
}
}
}
typedef struct inputFile{
ELLNODE node;
char *filename;
FILE *fp;
int lineNum;
}inputFile;
typedef struct pathNode {
ELLNODE node;
char *directory;
} pathNode;
struct inputData {
ELLLIST inputFileList;
ELLLIST pathList;
char inputBuffer[MAX_BUFFER_SIZE];
};
static void inputOpenFile(inputData *pinputData,char *filename);
static void inputCloseFile(inputData *pinputData);
static void inputCloseAllFiles(inputData *pinputData);
static void inputConstruct(inputData **ppvt)
{
inputData *pinputData;
pinputData = calloc(1,sizeof(inputData));
ellInit(&pinputData->inputFileList);
ellInit(&pinputData->pathList);
*ppvt = pinputData;
}
static void inputDestruct(inputData *pinputData)
{
pathNode *ppathNode;
inputCloseAllFiles(pinputData);
while((ppathNode = (pathNode *)ellFirst(&pinputData->pathList))) {
ellDelete(&pinputData->pathList,&ppathNode->node);
free(ppathNode->directory);
free(ppathNode);
}
free(pinputData);
}
static void inputAddPath(inputData *pinputData, char *path)
{
ELLLIST *ppathList = &pinputData->pathList;
pathNode *ppathNode;
const char *pcolon;
const char *pdir;
size_t len;
int emptyName;
const char sep = *OSI_PATH_LIST_SEPARATOR;
pdir = path;
/*an empty name at beginning, middle, or end means current directory*/
while(pdir && *pdir) {
emptyName = ((*pdir == sep) ? 1 : 0);
if(emptyName) ++pdir;
ppathNode = (pathNode *)calloc(1,sizeof(pathNode));
ellAdd(ppathList,&ppathNode->node);
if(!emptyName) {
pcolon = strchr(pdir,sep);
len = (pcolon ? (pcolon - pdir) : strlen(pdir));
if(len>0) {
ppathNode->directory = (char *)calloc(len+1,sizeof(char));
strncpy(ppathNode->directory,pdir,len);
pdir = pcolon;
/*unless at end skip past first colon*/
if(pdir && *(pdir+1)!=0) ++pdir;
} else { /*must have been trailing : */
emptyName=1;
}
}
if(emptyName) {
ppathNode->directory = (char *)calloc(2,sizeof(char));
strcpy(ppathNode->directory,".");
}
}
return;
}
static void inputBegin(inputData *pinputData, char *fileName)
{
inputCloseAllFiles(pinputData);
inputOpenFile(pinputData,fileName);
}
static char *inputNextLine(inputData *pinputData)
{
inputFile *pinputFile;
char *pline;
while((pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList))) {
pline = fgets(pinputData->inputBuffer,MAX_BUFFER_SIZE,pinputFile->fp);
if(pline) {
++pinputFile->lineNum;
return(pline);
}
inputCloseFile(pinputData);
}
return(0);
}
static void inputNewIncludeFile(inputData *pinputData, char *name)
{
inputOpenFile(pinputData,name);
}
static void inputErrPrint(inputData *pinputData)
{
inputFile *pinputFile;
fprintf(stderr,"input: '%s' at ",pinputData->inputBuffer);
pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList);
while(pinputFile) {
fprintf(stderr,"line %d of ",pinputFile->lineNum);
if(pinputFile->filename) {
fprintf(stderr," file %s\n",pinputFile->filename);
} else {
fprintf(stderr,"stdin:\n");
}
pinputFile = (inputFile *)ellNext(&pinputFile->node);
if(pinputFile) {
fprintf(stderr," included from ");
} else {
fprintf(stderr,"\n");
}
}
fprintf(stderr,"\n");
}
static void inputOpenFile(inputData *pinputData,char *filename)
{
ELLLIST *ppathList = &pinputData->pathList;
pathNode *ppathNode = 0;
inputFile *pinputFile;
char *fullname = 0;
FILE *fp = 0;
if(!filename) {
fp = stdin;
} else if((ellCount(ppathList)==0) || strchr(filename,'/')){
fp = fopen(filename,"r");
} else {
ppathNode = (pathNode *)ellFirst(ppathList);
while(ppathNode) {
fullname = calloc(strlen(filename)+strlen(ppathNode->directory) +2,
sizeof(char));
strcpy(fullname,ppathNode->directory);
strcat(fullname,"/");
strcat(fullname,filename);
fp = fopen(fullname,"r");
if(fp) break;
free(fullname);
ppathNode = (pathNode *)ellNext(&ppathNode->node);
}
}
if(!fp) {
fprintf(stderr,"msi: Can't open file '%s'\n",filename);
inputErrPrint(pinputData);
exit(1);
}
pinputFile = calloc(1,sizeof(inputFile));
if(ppathNode) {
pinputFile->filename = fullname;
} else if(filename) {
pinputFile->filename = epicsStrDup(filename);
} else {
pinputFile->filename = epicsStrDup("stdin");
}
if (opt_D) {
int hash = epicsStrHash(pinputFile->filename, 12345);
int i = 0;
int match = 0;
while (i < numDeps) {
if (hash == depHashes[i++]) {
match = 1;
break;
}
}
if (!match) {
const char *wrap = numDeps ? " \\\n" : "";
printf("%s %s", wrap, pinputFile->filename);
if (numDeps < MAX_DEPS) {
depHashes[numDeps++] = hash;
}
else {
fprintf(stderr, "msi: More than %d dependencies!\n", MAX_DEPS);
depHashes[0] = hash;
}
}
}
pinputFile->fp = fp;
ellInsert(&pinputData->inputFileList,0,&pinputFile->node);
}
static void inputCloseFile(inputData *pinputData)
{
inputFile *pinputFile;
pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList);
if(!pinputFile) return;
ellDelete(&pinputData->inputFileList,&pinputFile->node);
if(fclose(pinputFile->fp))
fprintf(stderr,"msi: Can't close input file '%s'\n",pinputFile->filename);
free(pinputFile->filename);
free(pinputFile);
}
static void inputCloseAllFiles(inputData *pinputData)
{
inputFile *pinputFile;
while((pinputFile=(inputFile *)ellFirst(&pinputData->inputFileList))){
inputCloseFile(pinputData);
}
}
/*start of code that handles substitution file*/
typedef enum {
tokenLBrace,tokenRBrace,tokenSeparater,tokenString,tokenEOF
}tokenType;
typedef struct subFile {
char *substitutionName;
FILE *fp;
int lineNum;
char inputBuffer[MAX_BUFFER_SIZE];
char *pnextChar;
tokenType token;
char string[MAX_BUFFER_SIZE];
} subFile;
typedef struct patternNode {
ELLNODE node;
char *var;
} patternNode;
struct subInfo {
subFile *psubFile;
int isFile;
char *filename;
int isPattern;
ELLLIST patternList;
size_t size;
size_t curLength;
char *macroReplacements;
};
static char *subGetNextLine(subFile *psubFile);
static tokenType subGetNextToken(subFile *psubFile);
static void subFileErrPrint(subFile *psubFile,char * message);
static void freeSubFile(subInfo *psubInfo);
static void freePattern(subInfo *psubInfo);
static void catMacroReplacements(subInfo *psubInfo,const char *value);
void freeSubFile(subInfo *psubInfo)
{
subFile *psubFile = psubInfo->psubFile;
if(psubFile->fp) {
if(fclose(psubFile->fp))
fprintf(stderr,"msi: Can't close substitution file\n");
}
free(psubFile);
free(psubInfo->filename);
psubInfo->psubFile = 0;
}
void freePattern(subInfo *psubInfo)
{
patternNode *ppatternNode;
while((ppatternNode = (patternNode *)ellFirst(&psubInfo->patternList))) {
ellDelete(&psubInfo->patternList,&ppatternNode->node);
free(ppatternNode->var);
free(ppatternNode);
}
psubInfo->isPattern = 0;
}
static void substituteDestruct(subInfo *psubInfo)
{
freeSubFile(psubInfo);
freePattern(psubInfo);
free(psubInfo);
return;
}
static void substituteOpen(subInfo **ppvt,char *substitutionName)
{
subInfo *psubInfo;
subFile *psubFile;
FILE *fp;
psubInfo = calloc(1,sizeof(subInfo));
*ppvt = psubInfo;
psubFile = calloc(1,sizeof(subFile));
psubInfo->psubFile = psubFile;
ellInit(&psubInfo->patternList);
fp = fopen(substitutionName,"r");
if(!fp) {
fprintf(stderr,"msi: Can't open file '%s'\n",substitutionName);
exit(1);
}
psubFile->substitutionName = substitutionName;
psubFile->fp = fp;
psubFile->lineNum = 1;
psubFile->inputBuffer[0] = 0;
psubFile->pnextChar = &psubFile->inputBuffer[0];
subGetNextToken(psubFile);
return;
}
static int substituteGetGlobalSet(subInfo *psubInfo)
{
subFile *psubFile = psubInfo->psubFile;
while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
if(psubFile->token==tokenString && strcmp(psubFile->string,"global")==0) {
subGetNextToken(psubFile);
return(1);
}
return(0);
}
static int substituteGetNextSet(subInfo *psubInfo,char **filename)
{
subFile *psubFile = psubInfo->psubFile;
patternNode *ppatternNode;
*filename = 0;
while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
if(psubFile->token==tokenEOF) return(0);
if(psubFile->token==tokenString && strcmp(psubFile->string,"file")==0) {
psubInfo->isFile = 1;
if(subGetNextToken(psubFile)!=tokenString) {
subFileErrPrint(psubFile,"Parse error, expecting filename");
exit(1);
}
freePattern(psubInfo);
free(psubInfo->filename);
if(psubFile->string[0]=='"'&&psubFile->string[strlen(psubFile->string)-1]=='"') {
psubFile->string[strlen(psubFile->string)-1]='\0';
psubInfo->filename = macEnvExpand(psubFile->string+1);
}
else {
psubInfo->filename = macEnvExpand(psubFile->string);
}
while(subGetNextToken(psubFile)==tokenSeparater);
if(psubFile->token!=tokenLBrace) {
subFileErrPrint(psubFile,"Parse error, expecting {");
exit(1);
}
subGetNextToken(psubFile);
}
*filename = psubInfo->filename;
while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
if(psubFile->token==tokenLBrace) return(1);
if(psubFile->token==tokenRBrace) return(1);
if(psubFile->token!=tokenString
|| strcmp(psubFile->string,"pattern")!=0) {
subFileErrPrint(psubFile,"Parse error, expecting pattern");
exit(1);
}
freePattern(psubInfo);
psubInfo->isPattern = 1;
while(subGetNextToken(psubFile)==tokenSeparater);
if(psubFile->token!=tokenLBrace) {
subFileErrPrint(psubFile,"Parse error, expecting {");
exit(1);
}
while(1) {
while(subGetNextToken(psubFile)==tokenSeparater);
if(psubFile->token!=tokenString) break;
ppatternNode = calloc(1,sizeof(patternNode));
ellAdd(&psubInfo->patternList,&ppatternNode->node);
ppatternNode->var = epicsStrDup(psubFile->string);
}
if(psubFile->token!=tokenRBrace) {
subFileErrPrint(psubFile,"Parse error, expecting }");
exit(1);
}
subGetNextToken(psubFile);
return(1);
}
static char *substituteGetGlobalReplacements(subInfo *psubInfo)
{
subFile *psubFile = psubInfo->psubFile;
if(psubInfo->macroReplacements) psubInfo->macroReplacements[0] = 0;
psubInfo->curLength = 0;
while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
if(psubFile->token==tokenRBrace && psubInfo->isFile) {
psubInfo->isFile = 0;
free(psubInfo->filename);
psubInfo->filename = 0;
freePattern(psubInfo);
subGetNextToken(psubFile);
return(0);
}
if(psubFile->token==tokenEOF) return(0);
if(psubFile->token!=tokenLBrace) return(0);
while(1) {
switch(subGetNextToken(psubFile)) {
case tokenRBrace:
subGetNextToken(psubFile);
if (!psubInfo->macroReplacements) {
catMacroReplacements(psubInfo,"");
}
return(psubInfo->macroReplacements);
case tokenSeparater:
catMacroReplacements(psubInfo,",");
break;
case tokenString:
catMacroReplacements(psubInfo,psubFile->string);
break;
default:
subFileErrPrint(psubFile,"Parse error, illegal token");
exit(1);
}
}
}
static char *substituteGetReplacements(subInfo *psubInfo)
{
subFile *psubFile = psubInfo->psubFile;
patternNode *ppatternNode;
if(psubInfo->macroReplacements) psubInfo->macroReplacements[0] = 0;
psubInfo->curLength = 0;
while(psubFile->token==tokenSeparater) subGetNextToken(psubFile);
if(psubFile->token==tokenRBrace && psubInfo->isFile) {
psubInfo->isFile = 0;
free(psubInfo->filename);
psubInfo->filename = 0;
freePattern(psubInfo);
subGetNextToken(psubFile);
return(0);
}
if(psubFile->token==tokenEOF) return(0);
if(psubFile->token!=tokenLBrace) return(0);
if(psubInfo->isPattern) {
int gotFirstPattern = 0;
while(subGetNextToken(psubFile)==tokenSeparater);
ppatternNode = (patternNode *)ellFirst(&psubInfo->patternList);
while(1) {
if(psubFile->token==tokenRBrace) {
subGetNextToken(psubFile);
return(psubInfo->macroReplacements);
}
if(psubFile->token!=tokenString) {
subFileErrPrint(psubFile,"Parse error, illegal token");
exit(-1);
}
if(gotFirstPattern) catMacroReplacements(psubInfo,",");
gotFirstPattern = 1;
if(ppatternNode) {
catMacroReplacements(psubInfo,ppatternNode->var);
catMacroReplacements(psubInfo,"=");
catMacroReplacements(psubInfo,psubFile->string);
ppatternNode = (patternNode *)ellNext(&ppatternNode->node);
} else {
subFileErrPrint(psubFile,"Warning, too many values given");
}
while(subGetNextToken(psubFile)==tokenSeparater);
}
} else while(1) {
switch(subGetNextToken(psubFile)) {
case tokenRBrace:
subGetNextToken(psubFile);
if (!psubInfo->macroReplacements) {
catMacroReplacements(psubInfo,"");
}
return(psubInfo->macroReplacements);
case tokenSeparater:
catMacroReplacements(psubInfo,",");
break;
case tokenString:
catMacroReplacements(psubInfo,psubFile->string);
break;
default:
subFileErrPrint(psubFile,"Parse error, illegal token");
exit(1);
}
}
}
static char *subGetNextLine(subFile *psubFile)
{
char *pline;
do {
pline = fgets(psubFile->inputBuffer,MAX_BUFFER_SIZE,psubFile->fp);
++psubFile->lineNum;
} while(pline && psubFile->inputBuffer[0]=='#');
if(!pline) {
psubFile->token = tokenEOF;
psubFile->inputBuffer[0] = 0;
psubFile->pnextChar = 0;
return(0);
}
psubFile->pnextChar = &psubFile->inputBuffer[0];
return(&psubFile->inputBuffer[0]);
}
static void subFileErrPrint(subFile *psubFile,char * message)
{
fprintf(stderr,"msi: %s\n",message);
fprintf(stderr," in substitution file '%s' at line %d:\n %s",
psubFile->substitutionName,
psubFile->lineNum,psubFile->inputBuffer);
}
static tokenType subGetNextToken(subFile *psubFile)
{
char *p;
char *pto;
p = psubFile->pnextChar;
if(!p) { psubFile->token = tokenEOF; return(tokenEOF);}
if(*p==0 || *p=='\n' || *p=='#') {
p = subGetNextLine(psubFile);
if(!p) { psubFile->token = tokenEOF; return(tokenEOF);}
else { psubFile->token = tokenSeparater; return(tokenSeparater);}
}
while(isspace((int) *p)) p++;
if(*p=='{') {
psubFile->token = tokenLBrace;
psubFile->pnextChar = ++p;
return(tokenLBrace);
}
if(*p=='}') {
psubFile->token = tokenRBrace;
psubFile->pnextChar = ++p;
return(tokenRBrace);
}
if(*p==0 || isspace((int) *p) || *p==',') {
while (isspace((int) *p) || *p==',') p++;
psubFile->token = tokenSeparater;
psubFile->pnextChar = p;
return(tokenSeparater);
}
/*now handle quoted strings*/
if(*p=='"') {
pto = &psubFile->string[0];
*pto++ = *p++;
while(*p!='"') {
if(*p==0 || *p=='\n') {
subFileErrPrint(psubFile,"Strings must be on single line\n");
exit(1);
}
/*allow escape for imbeded quote*/
if((*p=='\\') && *(p+1)=='"') {
*pto++ = *p++;
*pto++ = *p++;
continue;
}
*pto++ = *p++;
}
*pto++ = *p++;
psubFile->pnextChar = p;
*pto = 0;
psubFile->token = tokenString;
return(tokenString);
}
/*Now take anything up to next non String token and not space*/
pto = &psubFile->string[0];
while(!isspace((int) *p) && (strspn(p,"\",{}")==0)) *pto++ = *p++;
*pto = 0;
psubFile->pnextChar = p;
psubFile->token = tokenString;
return(tokenString);
}
static void catMacroReplacements(subInfo *psubInfo,const char *value)
{
size_t len = strlen(value);
if(psubInfo->size <= (psubInfo->curLength + len)) {
size_t newsize = psubInfo->size + MAX_BUFFER_SIZE;
char *newbuf;
if(newsize <= psubInfo->curLength + len)
newsize = psubInfo->curLength + len + 1;
newbuf = calloc(1,newsize);
if(!newbuf) {
fprintf(stderr,"calloc failed for size %lu\n",
(unsigned long) newsize);
exit(1);
}
if(psubInfo->macroReplacements) {
memcpy(newbuf,psubInfo->macroReplacements,psubInfo->curLength);
free(psubInfo->macroReplacements);
}
psubInfo->size = newsize;
psubInfo->macroReplacements = newbuf;
}
strcat(psubInfo->macroReplacements,value);
psubInfo->curLength += len;
}

1067
src/ioc/dbtemplate/msi.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -34,10 +34,10 @@ be written to stdout unless the -o option is given.</p>
<dl>
<dt><tt>-V</tt></dt>
<dd>Verbose warnings; if this parameter is specified then any undefined
macro discovered in the template file which does not have an associated
default value is considered an error. An error message is generated, and
when msi terminates it will do so with an exit status of 2.</dd>
<dd>Verbose warnings; if this parameter is specified then any undefined or
recursive macros discovered in the template will be considered an error and
will be marked in the output file. An error message will be shown, and when
msi terminates it will do so with an exit status of 2.</dd>
<dt><tt>-g</tt></dt>
<dd>When this flag is given all macros defined in a substitution file will

View File

@@ -17,8 +17,9 @@ TESTS += msi
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
TARGETS_HOST += msi-copy$(EXE)
TARGETS += $(TARGETS_$(BUILD_CLASS))
ifneq (,$(findstring $(T_A),$(EPICS_HOST_ARCH) $(CROSS_COMPILER_RUNTEST_ARCHS)))
TARGETS += msi-copy$(EXE)
endif
include $(TOP)/configure/RULES

View File

@@ -11,7 +11,7 @@
use strict;
use Test;
BEGIN {plan tests => 9}
BEGIN {plan tests => 12}
# Check include/substitute command model
ok(msi('-I .. ../t1-template.txt'), slurp('../t1-result.txt'));
@@ -31,18 +31,11 @@ ok(msi('-S ../t5-substitute.txt ../t5-template.txt'), slurp('../t5-result.txt'))
# Substitution file, pattern format
ok(msi('-S../t6-substitute.txt ../t6-template.txt'), slurp('../t6-result.txt'));
# Output option -o
# Output option -o and verbose option -V
my $out = 't7-output.txt';
my $count = 5; # Try up to 5 times...
my $result;
do {
unlink $out;
msi("-I.. -o $out ../t1-template.txt");
$result = slurp($out);
print "# msi output file empty, retrying\n"
if $result eq '';
} while ($result eq '') && (--$count > 0);
ok($result, slurp('../t1-result.txt'));
unlink $out;
msi("-I.. -V -o $out ../t1-template.txt");
ok(slurp($out), slurp('../t7-result.txt'));
# Dependency generation, include/substitute model
ok(msi('-I.. -D -o t8.txt ../t1-template.txt'), slurp('../t8-result.txt'));
@@ -50,6 +43,17 @@ ok(msi('-I.. -D -o t8.txt ../t1-template.txt'), slurp('../t8-result.txt'));
# Dependency generation, dbLoadTemplate format
ok(msi('-I.. -D -ot9.txt -S ../t2-substitution.txt'), slurp('../t9-result.txt'));
# Substitution file, variable format, with 0 variable definitions
ok(msi('-I. -I.. -S ../t10-substitute.txt'), slurp('../t10-result.txt'));
# Substitution file, pattern format, with 0 pattern definitions
ok(msi('-I. -I.. -S ../t11-substitute.txt'), slurp('../t11-result.txt'));
# Substitution file, environment variable macros in template filename
my %envs = (TEST_NO => 12, PREFIX => 't');
@ENV{ keys %envs } = values %envs;
ok(msi('-I. -I.. -S ../t12-substitute.txt'), slurp('../t12-result.txt'));
delete @ENV{ keys %envs }; # Not really needed
# Test support routines
@@ -63,21 +67,7 @@ sub slurp {
sub msi {
my ($args) = @_;
my $exe = ($^O eq 'MSWin32') || ($^O eq 'cygwin') ? '.exe' : '';
my $msi = "./msi-copy$exe";
my $result;
if ($args =~ m/-o / && $args !~ m/-D/) {
# An empty result is expected
$result = `$msi $args`;
}
else {
# Try up to 5 times, sometimes msi fails on Windows
my $count = 5;
do {
$result = `$msi $args`;
print "# result of '$msi $args' empty, retrying\n"
if $result eq '';
} while ($result eq '') && (--$count > 0);
}
return $result;
my $nul = ($^O eq 'MSWin32') ? 'NUL' : '/dev/null';
my $msi = ($^O eq 'MSWin32') ? 'msi-copy.exe' : './msi-copy';
return `$msi $args 2>$nul`;
}

View File

@@ -1,6 +1,6 @@
This is t1-template.txt
With $(a,undefined) & $(b,undefined):
With $(a) & $(b):
This is t1-include.txt
a = default value used when a is undefined
b = default value used when b is undefined

View File

@@ -0,0 +1,4 @@
# comment line
a=$(a)
# comment line
a=gbl

View File

@@ -0,0 +1,8 @@
file t10-template.txt {
{}
}
global { a=gbl }
file t10-template.txt {
{}
}

View File

@@ -0,0 +1,2 @@
# comment line
a=$(a)

View File

@@ -0,0 +1,4 @@
# comment line
a=$(a)
# comment line
a=gbl

View File

@@ -0,0 +1,10 @@
file t11-template.txt {
pattern {}
{}
}
global { a=gbl }
file t11-template.txt {
pattern {}
{}
}

View File

@@ -0,0 +1,2 @@
# comment line
a=$(a)

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