Merge lp:~bhill/epics-base/pcas-vararray-3.15 into lp:~epics-core/epics-base/3.16

Proposed by Bruce Hill
Status: Superseded
Proposed branch: lp:~bhill/epics-base/pcas-vararray-3.15
Merge into: lp:~epics-core/epics-base/3.16
Diff against target: 3345 lines (+2228/-203) (has conflicts)
41 files modified
configure/CONFIG_BASE_VERSION (+4/-0)
configure/RULES_BUILD (+12/-0)
configure/os/CONFIG.linux-x86.windows-x64-mingw (+0/-28)
configure/os/CONFIG.linux-x86_64.windows-x64-mingw (+0/-9)
configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw (+7/-4)
configure/os/CONFIG_SITE.linux-x86.windows-x64-mingw (+0/-20)
configure/os/CONFIG_SITE.linux-x86_64.windows-x64-mingw (+0/-8)
documentation/RELEASE_NOTES.html (+1311/-0)
src/ca/legacy/gdd/gddAppTable.cc (+2/-0)
src/ca/legacy/pcas/generic/caHdrLargeArray.h (+1/-1)
src/ca/legacy/pcas/generic/casDGClient.cc (+4/-1)
src/ca/legacy/pcas/generic/casStrmClient.cc (+43/-26)
src/ca/legacy/pcas/generic/casStrmClient.h (+1/-1)
src/ioc/db/dbScan.c (+4/-4)
src/ioc/db/templateInstances.cpp.OTHER (+36/-0)
src/ioc/dbStatic/dbBase.h (+19/-19)
src/ioc/dbStatic/dbLexRoutines.c (+22/-1)
src/ioc/dbStatic/dbStaticLib.c (+3/-73)
src/ioc/dbStatic/dbStaticLib.h (+0/-2)
src/ioc/misc/dbCore.dbd (+1/-0)
src/libCom/cxxTemplates/epicsOnce.cpp.OTHER (+103/-0)
src/libCom/cxxTemplates/epicsOnce.h.OTHER (+36/-0)
src/libCom/ellLib/Makefile (+1/-0)
src/libCom/ellLib/ellLib.h (+2/-0)
src/libCom/ellLib/ellSort.c (+83/-0)
src/libCom/env/RULES (+7/-0)
src/libCom/env/bldEnvData.pl (+5/-0)
src/libCom/freeList/freeList.html.OTHER (+76/-0)
src/libCom/gpHash/gpHash.html.OTHER (+130/-0)
src/libCom/osi/epicsGeneralTime.c (+70/-0)
src/libCom/osi/os/RTEMS/osdThread.c (+1/-0)
src/libCom/osi/os/WIN32/osdNetIntf.c (+124/-0)
src/libCom/test/epicsEllTest.c (+74/-3)
src/std/rec/compressRecord.dbd.pod (+4/-0)
src/template/base/top/exampleApp/src/Makefile (+4/-0)
src/tools/DBD/Base.pm (+12/-0)
src/tools/DBD/Output.pm (+1/-1)
src/tools/DBD/Recfield.pm (+8/-2)
src/tools/EPICS/Path.pm (+8/-0)
src/tools/dbdExpand.pl (+3/-0)
src/tools/munch.pl (+6/-0)
Text conflict in configure/CONFIG_BASE_VERSION
Text conflict in configure/RULES_BUILD
Text conflict in documentation/RELEASE_NOTES.html
Text conflict in src/ca/legacy/pcas/generic/casDGClient.cc
Contents conflict in src/ioc/db/templateInstances.cpp
Contents conflict in src/libCom/cxxTemplates/epicsOnce.cpp
Contents conflict in src/libCom/cxxTemplates/epicsOnce.h
Text conflict in src/libCom/env/RULES
Text conflict in src/libCom/env/bldEnvData.pl
Contents conflict in src/libCom/freeList/freeList.html
Contents conflict in src/libCom/gpHash/gpHash.html
Text conflict in src/libCom/osi/epicsGeneralTime.c
Text conflict in src/libCom/osi/os/WIN32/osdNetIntf.c
Text conflict in src/std/rec/compressRecord.dbd.pod
Text conflict in src/template/base/top/exampleApp/src/Makefile
Text conflict in src/tools/DBD/Base.pm
Text conflict in src/tools/DBD/Recfield.pm
Text conflict in src/tools/EPICS/Path.pm
Text conflict in src/tools/dbdExpand.pl
Text conflict in src/tools/munch.pl
To merge this branch: bzr merge lp:~bhill/epics-base/pcas-vararray-3.15
Reviewer Review Type Date Requested Status
EPICS Core Developers Pending
Review via email: mp+308224@code.launchpad.net

Description of the change

This branch adds variable length array support to pcas.
A flag fAllowZeroCount is added to casStrmClient::verifyRequest and set for CA_V413 to
allow zero counts in the msg.m_count.

In casStrmClient::read(), since we don't know how big the array is yet, the GDD
is created using the full array size.

Finally, in casStrmClient::readResponse() we use the actual number of elements
to set the payloadSize that we read from the CA header.

Changes were made vs the epics-base/3.15 branch as the 3.14 branch still has
the pcas-fake-dynamic branch changes which conflict w/ this patch.

To post a comment you must log in.
Revision history for this message
Ralph Lange (ralph-lange) wrote :

Hi Bruce,

This has many unrelated changes that are artifacts of the rebase.

Actually, what I would prefer - since the merged pcas-fake changes and Matej's/your original changes are very similar - would be a rebase against the current 3.14 with the pcas-fake merged.

That would minimize the patch (making the difference very obvious) and be the easiest to integrate.

Revision history for this message
Ralph Lange (ralph-lange) wrote :

Given your time zone ... I can try to do that. Should I?

Revision history for this message
Bruce Hill (bhill) wrote :

If you wouldn't mind helping out, I was about ready to call it a night.

I'm not that familiar w/ bzr so was surprised to see my minimal change

set expand into all those conflicts even though I made the changes against

a fresh copy of epics-base/3.15.

Thanks!

- Bruce

On 10/12/2016 02:15 AM, Ralph Lange wrote:
> Given your time zone ... I can try to do that. Should I?

--
Bruce Hill
Member Technical Staff
SLAC National Accelerator Lab
2575 Sand Hill Road M/S 10
Menlo Park, CA 94025

Revision history for this message
Ralph Lange (ralph-lange) wrote :

Sure, call it a night.
There will be something for you to check out when you wake up....

Revision history for this message
Bruce Hill (bhill) wrote :

Here's the patch files that I used.

When are we moving base to git?

I've been working a lot w/ git lately and could have done this much faster w/ git.

Cheers,

- Bruce

On 10/12/2016 02:15 AM, Ralph Lange wrote:
> Given your time zone ... I can try to do that. Should I?

--
Bruce Hill
Member Technical Staff
SLAC National Accelerator Lab
2575 Sand Hill Road M/S 10
Menlo Park, CA 94025

1Index: src/cas/generic/caHdrLargeArray.h
2===================================================================
3--- src/cas/generic/caHdrLargeArray.h (revision 26175)
4+++ src/cas/generic/caHdrLargeArray.h (working copy)
5@@ -32,7 +32,7 @@
6 # include "shareLib.h"
7 #endif
8
9-static const unsigned char CA_MINOR_PROTOCOL_REVISION = 12;
10+static const unsigned char CA_MINOR_PROTOCOL_REVISION = 13;
11
12 typedef ca_uint32_t caResId;
13
14Index: src/cas/generic/casStrmClient.cc
15===================================================================
16--- src/cas/generic/casStrmClient.cc (revision 26175)
17+++ src/cas/generic/casStrmClient.cc (working copy)
18@@ -390,7 +390,7 @@
19 //
20 // casStrmClient::verifyRequest()
21 //
22-caStatus casStrmClient::verifyRequest ( casChannelI * & pChan )
23+caStatus casStrmClient::verifyRequest ( casChannelI * & pChan, bool allowZeroCount )
24 {
25 const caHdrLargeArray * mp = this->ctx.getMsg();
26
27@@ -413,7 +413,8 @@
28 //
29 // element count out of range ?
30 //
31- if ( mp->m_count > pChan->getPVI().nativeCount() || mp->m_count == 0u ) {
32+ if ( mp->m_count > pChan->getPVI().nativeCount() ||
33+ ( !allowZeroCount && mp->m_count == 0u ) ) {
34 return ECA_BADCOUNT;
35 }
36
37@@ -446,7 +447,7 @@
38 casChannelI * pChan;
39
40 {
41- caStatus status = this->verifyRequest ( pChan );
42+ caStatus status = this->verifyRequest ( pChan, CA_V413 ( this->minor_version_number ) );
43 if ( status != ECA_NORMAL ) {
44 if ( pChan ) {
45 return this->sendErr ( guard, mp, pChan->getCID(),
46@@ -533,11 +534,15 @@
47 pChan->getCID(), status, ECA_GETFAIL );
48 }
49
50+ ca_uint32_t count = (msg.m_count == 0) ?
51+ (ca_uint32_t)desc.getDataSizeElements() :
52+ msg.m_count;
53+
54 void * pPayload;
55 {
56- unsigned payloadSize = dbr_size_n ( msg.m_dataType, msg.m_count );
57+ unsigned payloadSize = dbr_size_n ( msg.m_dataType, count );
58 caStatus localStatus = this->out.copyInHeader ( msg.m_cmmd, payloadSize,
59- msg.m_dataType, msg.m_count, pChan->getCID (),
60+ msg.m_dataType, count, pChan->getCID (),
61 msg.m_available, & pPayload );
62 if ( localStatus ) {
63 if ( localStatus==S_cas_hugeRequest ) {
64@@ -553,21 +558,21 @@
65 // (places the data in network format)
66 //
67 int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr(
68- pPayload, msg.m_count, desc, pChan->enumStringTable() );
69+ pPayload, count, desc, pChan->enumStringTable() );
70 if ( mapDBRStatus < 0 ) {
71 desc.dump ();
72 errPrintf ( S_cas_badBounds, __FILE__, __LINE__, "- get with PV=%s type=%u count=%u",
73- pChan->getPVI().getName(), msg.m_dataType, msg.m_count );
74+ pChan->getPVI().getName(), msg.m_dataType, count );
75 return this->sendErrWithEpicsStatus (
76 guard, & msg, pChan->getCID(), S_cas_badBounds, ECA_GETFAIL );
77 }
78 int cacStatus = caNetConvert (
79- msg.m_dataType, pPayload, pPayload, true, msg.m_count );
80+ msg.m_dataType, pPayload, pPayload, true, count );
81 if ( cacStatus != ECA_NORMAL ) {
82 return this->sendErrWithEpicsStatus (
83 guard, & msg, pChan->getCID(), S_cas_internal, cacStatus );
84 }
85- if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) {
86+ if ( msg.m_dataType == DBR_STRING && count == 1u ) {
87 unsigned reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u;
88 this->out.commitMsg ( reducedPayloadSize );
89 }
90@@ -587,7 +592,7 @@
91 casChannelI * pChan;
92
93 {
94- caStatus status = this->verifyRequest ( pChan );
95+ caStatus status = this->verifyRequest ( pChan, CA_V413 ( this->minor_version_number ) );
96 if ( status != ECA_NORMAL ) {
97 return this->readNotifyFailureResponse ( guard, * mp, status );
98 }
99@@ -657,12 +662,16 @@
100 guard, msg, ECA_GETFAIL );
101 return ecaStatus;
102 }
103+
104+ ca_uint32_t count = (msg.m_count == 0) ?
105+ (ca_uint32_t)desc.getDataSizeElements() :
106+ msg.m_count;
107
108 void *pPayload;
109 {
110- unsigned size = dbr_size_n ( msg.m_dataType, msg.m_count );
111+ unsigned size = dbr_size_n ( msg.m_dataType, count );
112 caStatus status = this->out.copyInHeader ( msg.m_cmmd, size,
113- msg.m_dataType, msg.m_count, ECA_NORMAL,
114+ msg.m_dataType, count, ECA_NORMAL,
115 msg.m_available, & pPayload );
116 if ( status ) {
117 if ( status == S_cas_hugeRequest ) {
118@@ -677,23 +686,23 @@
119 // convert gdd to db_access type
120 //
121 int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr ( pPayload,
122- msg.m_count, desc, pChan->enumStringTable() );
123+ count, desc, pChan->enumStringTable() );
124 if ( mapDBRStatus < 0 ) {
125 desc.dump();
126 errPrintf ( S_cas_badBounds, __FILE__, __LINE__,
127 "- get notify with PV=%s type=%u count=%u",
128- pChan->getPVI().getName(), msg.m_dataType, msg.m_count );
129+ pChan->getPVI().getName(), msg.m_dataType, count );
130 return this->readNotifyFailureResponse ( guard, msg, ECA_NOCONVERT );
131 }
132
133 int cacStatus = caNetConvert (
134- msg.m_dataType, pPayload, pPayload, true, msg.m_count );
135+ msg.m_dataType, pPayload, pPayload, true, count );
136 if ( cacStatus != ECA_NORMAL ) {
137 return this->sendErrWithEpicsStatus (
138 guard, & msg, pChan->getCID(), S_cas_internal, cacStatus );
139 }
140
141- if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) {
142+ if ( msg.m_dataType == DBR_STRING && count == 1u ) {
143 unsigned reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u;
144 this->out.commitMsg ( reducedPayloadSize );
145 }
146@@ -851,11 +860,15 @@
147 casChannelI & chan, const caHdrLargeArray & msg,
148 const gdd & desc, const caStatus completionStatus )
149 {
150+ ca_uint32_t count = (msg.m_count == 0) ?
151+ (ca_uint32_t)desc.getDataSizeElements() :
152+ msg.m_count;
153+
154 void * pPayload = 0;
155 {
156- ca_uint32_t size = dbr_size_n ( msg.m_dataType, msg.m_count );
157+ ca_uint32_t size = dbr_size_n ( msg.m_dataType, count );
158 caStatus status = out.copyInHeader ( msg.m_cmmd, size,
159- msg.m_dataType, msg.m_count, ECA_NORMAL,
160+ msg.m_dataType, count, ECA_NORMAL,
161 msg.m_available, & pPayload );
162 if ( status ) {
163 if ( status == S_cas_hugeRequest ) {
164@@ -873,7 +886,7 @@
165
166 gdd * pDBRDD = 0;
167 if ( completionStatus == S_cas_success ) {
168- caStatus status = createDBRDD ( msg.m_dataType, msg.m_count, pDBRDD );
169+ caStatus status = createDBRDD ( msg.m_dataType, count, pDBRDD );
170 if ( status != S_cas_success ) {
171 caStatus ecaStatus;
172 if ( status == S_cas_badType ) {
173@@ -894,7 +907,7 @@
174 pDBRDD->unreference ();
175 errPrintf ( S_cas_noConvert, __FILE__, __LINE__,
176 "no conversion between event app type=%d and DBR type=%d Element count=%d",
177- desc.applicationType (), msg.m_dataType, msg.m_count);
178+ desc.applicationType (), msg.m_dataType, count);
179 return monitorFailureResponse ( guard, msg, ECA_NOCONVERT );
180 }
181 }
182@@ -917,7 +930,7 @@
183 }
184
185 int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr (
186- pPayload, msg.m_count, *pDBRDD, chan.enumStringTable() );
187+ pPayload, count, *pDBRDD, chan.enumStringTable() );
188 if ( mapDBRStatus < 0 ) {
189 pDBRDD->unreference ();
190 return monitorFailureResponse ( guard, msg, ECA_NOCONVERT );
191@@ -924,7 +937,7 @@
192 }
193
194 int cacStatus = caNetConvert (
195- msg.m_dataType, pPayload, pPayload, true, msg.m_count );
196+ msg.m_dataType, pPayload, pPayload, true, count );
197 if ( cacStatus != ECA_NORMAL ) {
198 pDBRDD->unreference ();
199 return this->sendErrWithEpicsStatus (
200@@ -934,7 +947,7 @@
201 //
202 // force string message size to be the true size
203 //
204- if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) {
205+ if ( msg.m_dataType == DBR_STRING && count == 1u ) {
206 ca_uint32_t reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u;
207 this->out.commitMsg ( reducedPayloadSize );
208 }
209@@ -1942,7 +1955,7 @@
210
211 casChannelI *pciu;
212 {
213- caStatus status = casStrmClient::verifyRequest ( pciu );
214+ caStatus status = casStrmClient::verifyRequest ( pciu, CA_V413 ( this->minor_version_number ) );
215 if ( status != ECA_NORMAL ) {
216 if ( pciu ) {
217 return this->sendErr ( guard, mp,
218Index: src/cas/generic/casStrmClient.h
219===================================================================
220--- src/cas/generic/casStrmClient.h (revision 26175)
221+++ src/cas/generic/casStrmClient.h (working copy)
222@@ -69,7 +69,7 @@
223 bool responseIsPending;
224
225 caStatus createChannel ( const char * pName );
226- caStatus verifyRequest ( casChannelI * & pChan );
227+ caStatus verifyRequest ( casChannelI * & pChan, bool allowZeroCount = false );
228 typedef caStatus ( casStrmClient :: * pCASMsgHandler )
229 ( epicsGuard < casClientMutex > & );
230 static pCASMsgHandler const msgHandlers[CA_PROTO_LAST_CMMD+1u];
1=== modified file 'src/ca/legacy/pcas/generic/caHdrLargeArray.h'
2--- src/ca/legacy/pcas/generic/caHdrLargeArray.h 2010-10-05 19:27:37 +0000
3+++ src/ca/legacy/pcas/generic/caHdrLargeArray.h 2015-04-01 07:29:16 +0000
4@@ -32,7 +32,7 @@
5 # include "shareLib.h"
6 #endif
7
8-static const unsigned char CA_MINOR_PROTOCOL_REVISION = 12;
9+static const unsigned char CA_MINOR_PROTOCOL_REVISION = 13;
10
11 typedef ca_uint32_t caResId;
12
13
14=== modified file 'src/ca/legacy/pcas/generic/casStrmClient.cc'
15--- src/ca/legacy/pcas/generic/casStrmClient.cc 2014-05-30 17:36:50 +0000
16+++ src/ca/legacy/pcas/generic/casStrmClient.cc 2015-04-01 07:29:16 +0000
17@@ -388,7 +388,7 @@
18 //
19 // casStrmClient::verifyRequest()
20 //
21-caStatus casStrmClient::verifyRequest ( casChannelI * & pChan )
22+caStatus casStrmClient::verifyRequest ( casChannelI * & pChan, bool allowZeroCount )
23 {
24 const caHdrLargeArray * mp = this->ctx.getMsg();
25
26@@ -411,7 +411,8 @@
27 //
28 // element count out of range ?
29 //
30- if ( mp->m_count > pChan->getPVI().nativeCount() || mp->m_count == 0u ) {
31+ if ( mp->m_count > pChan->getPVI().nativeCount() ||
32+ ( !allowZeroCount && mp->m_count == 0u ) ) {
33 return ECA_BADCOUNT;
34 }
35
36@@ -444,7 +445,7 @@
37 casChannelI * pChan;
38
39 {
40- caStatus status = this->verifyRequest ( pChan );
41+ caStatus status = this->verifyRequest ( pChan, CA_V413 ( this->minor_version_number ) );
42 if ( status != ECA_NORMAL ) {
43 if ( pChan ) {
44 return this->sendErr ( guard, mp, pChan->getCID(),
45@@ -531,11 +532,15 @@
46 pChan->getCID(), status, ECA_GETFAIL );
47 }
48
49+ ca_uint32_t count = (msg.m_count == 0) ?
50+ (ca_uint32_t)desc.getDataSizeElements() :
51+ msg.m_count;
52+
53 void * pPayload;
54 {
55- unsigned payloadSize = dbr_size_n ( msg.m_dataType, msg.m_count );
56+ unsigned payloadSize = dbr_size_n ( msg.m_dataType, count );
57 caStatus localStatus = this->out.copyInHeader ( msg.m_cmmd, payloadSize,
58- msg.m_dataType, msg.m_count, pChan->getCID (),
59+ msg.m_dataType, count, pChan->getCID (),
60 msg.m_available, & pPayload );
61 if ( localStatus ) {
62 if ( localStatus==S_cas_hugeRequest ) {
63@@ -551,21 +556,21 @@
64 // (places the data in network format)
65 //
66 int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr(
67- pPayload, msg.m_count, desc, pChan->enumStringTable() );
68+ pPayload, count, desc, pChan->enumStringTable() );
69 if ( mapDBRStatus < 0 ) {
70 desc.dump ();
71 errPrintf ( S_cas_badBounds, __FILE__, __LINE__, "- get with PV=%s type=%u count=%u",
72- pChan->getPVI().getName(), msg.m_dataType, msg.m_count );
73+ pChan->getPVI().getName(), msg.m_dataType, count );
74 return this->sendErrWithEpicsStatus (
75 guard, & msg, pChan->getCID(), S_cas_badBounds, ECA_GETFAIL );
76 }
77 int cacStatus = caNetConvert (
78- msg.m_dataType, pPayload, pPayload, true, msg.m_count );
79+ msg.m_dataType, pPayload, pPayload, true, count );
80 if ( cacStatus != ECA_NORMAL ) {
81 return this->sendErrWithEpicsStatus (
82 guard, & msg, pChan->getCID(), S_cas_internal, cacStatus );
83 }
84- if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) {
85+ if ( msg.m_dataType == DBR_STRING && count == 1u ) {
86 unsigned reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u;
87 this->out.commitMsg ( reducedPayloadSize );
88 }
89@@ -585,7 +590,7 @@
90 casChannelI * pChan;
91
92 {
93- caStatus status = this->verifyRequest ( pChan );
94+ caStatus status = this->verifyRequest ( pChan, CA_V413 ( this->minor_version_number ) );
95 if ( status != ECA_NORMAL ) {
96 return this->readNotifyFailureResponse ( guard, * mp, status );
97 }
98@@ -655,12 +660,16 @@
99 guard, msg, ECA_GETFAIL );
100 return ecaStatus;
101 }
102+
103+ ca_uint32_t count = (msg.m_count == 0) ?
104+ (ca_uint32_t)desc.getDataSizeElements() :
105+ msg.m_count;
106
107 void *pPayload;
108 {
109- unsigned size = dbr_size_n ( msg.m_dataType, msg.m_count );
110+ unsigned size = dbr_size_n ( msg.m_dataType, count );
111 caStatus status = this->out.copyInHeader ( msg.m_cmmd, size,
112- msg.m_dataType, msg.m_count, ECA_NORMAL,
113+ msg.m_dataType, count, ECA_NORMAL,
114 msg.m_available, & pPayload );
115 if ( status ) {
116 if ( status == S_cas_hugeRequest ) {
117@@ -675,23 +684,23 @@
118 // convert gdd to db_access type
119 //
120 int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr ( pPayload,
121- msg.m_count, desc, pChan->enumStringTable() );
122+ count, desc, pChan->enumStringTable() );
123 if ( mapDBRStatus < 0 ) {
124 desc.dump();
125 errPrintf ( S_cas_badBounds, __FILE__, __LINE__,
126 "- get notify with PV=%s type=%u count=%u",
127- pChan->getPVI().getName(), msg.m_dataType, msg.m_count );
128+ pChan->getPVI().getName(), msg.m_dataType, count );
129 return this->readNotifyFailureResponse ( guard, msg, ECA_NOCONVERT );
130 }
131
132 int cacStatus = caNetConvert (
133- msg.m_dataType, pPayload, pPayload, true, msg.m_count );
134+ msg.m_dataType, pPayload, pPayload, true, count );
135 if ( cacStatus != ECA_NORMAL ) {
136 return this->sendErrWithEpicsStatus (
137 guard, & msg, pChan->getCID(), S_cas_internal, cacStatus );
138 }
139
140- if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) {
141+ if ( msg.m_dataType == DBR_STRING && count == 1u ) {
142 unsigned reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u;
143 this->out.commitMsg ( reducedPayloadSize );
144 }
145@@ -849,11 +858,15 @@
146 casChannelI & chan, const caHdrLargeArray & msg,
147 const gdd & desc, const caStatus completionStatus )
148 {
149+ ca_uint32_t count = (msg.m_count == 0) ?
150+ (ca_uint32_t)desc.getDataSizeElements() :
151+ msg.m_count;
152+
153 void * pPayload = 0;
154 {
155- ca_uint32_t size = dbr_size_n ( msg.m_dataType, msg.m_count );
156+ ca_uint32_t size = dbr_size_n ( msg.m_dataType, count );
157 caStatus status = out.copyInHeader ( msg.m_cmmd, size,
158- msg.m_dataType, msg.m_count, ECA_NORMAL,
159+ msg.m_dataType, count, ECA_NORMAL,
160 msg.m_available, & pPayload );
161 if ( status ) {
162 if ( status == S_cas_hugeRequest ) {
163@@ -871,7 +884,7 @@
164
165 gdd * pDBRDD = 0;
166 if ( completionStatus == S_cas_success ) {
167- caStatus status = createDBRDD ( msg.m_dataType, msg.m_count, pDBRDD );
168+ caStatus status = createDBRDD ( msg.m_dataType, count, pDBRDD );
169 if ( status != S_cas_success ) {
170 caStatus ecaStatus;
171 if ( status == S_cas_badType ) {
172@@ -892,7 +905,7 @@
173 pDBRDD->unreference ();
174 errPrintf ( S_cas_noConvert, __FILE__, __LINE__,
175 "no conversion between event app type=%d and DBR type=%d Element count=%d",
176- desc.applicationType (), msg.m_dataType, msg.m_count);
177+ desc.applicationType (), msg.m_dataType, count);
178 return monitorFailureResponse ( guard, msg, ECA_NOCONVERT );
179 }
180 }
181@@ -915,14 +928,14 @@
182 }
183
184 int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr (
185- pPayload, msg.m_count, *pDBRDD, chan.enumStringTable() );
186+ pPayload, count, *pDBRDD, chan.enumStringTable() );
187 if ( mapDBRStatus < 0 ) {
188 pDBRDD->unreference ();
189 return monitorFailureResponse ( guard, msg, ECA_NOCONVERT );
190 }
191
192 int cacStatus = caNetConvert (
193- msg.m_dataType, pPayload, pPayload, true, msg.m_count );
194+ msg.m_dataType, pPayload, pPayload, true, count );
195 if ( cacStatus != ECA_NORMAL ) {
196 pDBRDD->unreference ();
197 return this->sendErrWithEpicsStatus (
198@@ -932,7 +945,7 @@
199 //
200 // force string message size to be the true size
201 //
202- if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) {
203+ if ( msg.m_dataType == DBR_STRING && count == 1u ) {
204 ca_uint32_t reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u;
205 this->out.commitMsg ( reducedPayloadSize );
206 }
207@@ -1940,7 +1953,7 @@
208
209 casChannelI *pciu;
210 {
211- caStatus status = casStrmClient::verifyRequest ( pciu );
212+ caStatus status = casStrmClient::verifyRequest ( pciu, CA_V413 ( this->minor_version_number ) );
213 if ( status != ECA_NORMAL ) {
214 if ( pciu ) {
215 return this->sendErr ( guard, mp,
216
217=== modified file 'src/ca/legacy/pcas/generic/casStrmClient.h'
218--- src/ca/legacy/pcas/generic/casStrmClient.h 2010-08-10 21:05:46 +0000
219+++ src/ca/legacy/pcas/generic/casStrmClient.h 2015-04-01 07:29:16 +0000
220@@ -69,7 +69,7 @@
221 bool responseIsPending;
222
223 caStatus createChannel ( const char * pName );
224- caStatus verifyRequest ( casChannelI * & pChan );
225+ caStatus verifyRequest ( casChannelI * & pChan, bool allowZeroCount = false );
226 typedef caStatus ( casStrmClient :: * pCASMsgHandler )
227 ( epicsGuard < casClientMutex > & );
228 static pCASMsgHandler const msgHandlers[CA_PROTO_LAST_CMMD+1u];
Revision history for this message
Ralph Lange (ralph-lange) wrote :

Thanks a lot!

We will be moving to git once the releases of the 3.14, 3.15 and 3.16 branches are done, which are all targeted for the end of this month. That's behind the schedule pressure.

(You see: it's all part of a big - if not great - plan.)

Unmerged revisions

12785. By Bruce Hill

Implemented variable array sizing in pcas

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'configure/CONFIG_BASE_VERSION'
2--- configure/CONFIG_BASE_VERSION 2016-09-07 15:04:54 +0000
3+++ configure/CONFIG_BASE_VERSION 2016-10-12 09:08:28 +0000
4@@ -38,7 +38,11 @@
5 EPICS_REVISION = 16
6
7 # EPICS_MODIFICATION must be a number >=0 and <256
8+<<<<<<< TREE
9 EPICS_MODIFICATION = 0
10+=======
11+EPICS_MODIFICATION = 4
12+>>>>>>> MERGE-SOURCE
13
14 # EPICS_PATCH_LEVEL must be a number (win32 resource file requirement)
15 # Not included if zero
16
17=== modified file 'configure/CONFIG_COMMON'
18=== modified file 'configure/CONFIG_SITE_ENV'
19=== modified file 'configure/RULES_BUILD'
20--- configure/RULES_BUILD 2016-09-07 15:04:54 +0000
21+++ configure/RULES_BUILD 2016-10-12 09:08:28 +0000
22@@ -167,6 +167,7 @@
23 endif
24
25 $(DIRECTORY_TARGETS) :
26+<<<<<<< TREE
27 $(MKDIR) $@
28
29 # Install LIB_INSTALLS libraries before linking executables
30@@ -176,6 +177,17 @@
31 ifneq ($(DELAY_INSTALL_LIBS),YES)
32 $(TESTPRODNAME) $(PRODNAME): | $(INSTALL_LIBS) $(INSTALL_DLLSTUB_LIBS)
33 endif
34+=======
35+ $(MKDIR) -p $@
36+
37+# Install LIB_INSTALLS libraries before linking executables
38+$(TESTPRODNAME) $(PRODNAME): | $(INSTALL_LIB_INSTALLS)
39+
40+# Install built libraries too, unless Makefile says to wait
41+ifneq ($(DELAY_INSTALL_LIBS),YES)
42+$(TESTPRODNAME) $(PRODNAME): | $(INSTALL_LIBS) $(INSTALL_DLLSTUB_LIBS)
43+endif
44+>>>>>>> MERGE-SOURCE
45
46 # RELEASE file consistency checking
47 checkRelease:
48
49=== modified file 'configure/os/CONFIG.Common.vxWorksCommon'
50=== modified file 'configure/os/CONFIG.UnixCommon.Common'
51=== modified file 'configure/os/CONFIG.linux-386.Common'
52=== modified file 'configure/os/CONFIG.linux-486.Common'
53=== modified file 'configure/os/CONFIG.linux-586.Common'
54=== modified file 'configure/os/CONFIG.linux-686.Common'
55=== modified file 'configure/os/CONFIG.linux-x86.Common'
56=== added file 'configure/os/CONFIG.linux-x86.windows-x64-mingw'
57--- configure/os/CONFIG.linux-x86.windows-x64-mingw 1970-01-01 00:00:00 +0000
58+++ configure/os/CONFIG.linux-x86.windows-x64-mingw 2016-10-12 09:08:28 +0000
59@@ -0,0 +1,24 @@
60+# CONFIG.linux-x86.windows-x64-mingw
61+#
62+# Definitions for linux-x86 host windows-x64-mingw target builds
63+# Override these definitions in CONFIG_SITE.linux-x86.windows-x64-mingw
64+#-------------------------------------------------------
65+
66+# Include common gnu compiler definitions
67+include $(CONFIG)/CONFIG.gnuCommon
68+
69+# Add resource compiler
70+RCCMD = $(GNU_BIN)/$(CMPLR_PREFIX)windres$(CMPLR_SUFFIX) $(INCLUDES) $< $@
71+
72+# Remove -fPIC flags, add out-implib
73+SHRLIB_CFLAGS =
74+SHRLIB_LDFLAGS = -shared \
75+ -Wl,--out-implib,$(DLLSTUB_PREFIX)$*$(DLLSTUB_SUFFIX)
76+LOADABLE_SHRLIB_LDFLAGS = -shared \
77+ -Wl,--out-implib,$(DLLSTUB_PREFIX)$*$(DLLSTUB_SUFFIX)
78+
79+# No need to explicitly link with gcc library
80+GNU_LDLIBS_YES =
81+
82+# Link with winsock2
83+OP_SYS_LDLIBS = -lws2_32
84
85=== removed file 'configure/os/CONFIG.linux-x86.windows-x64-mingw'
86--- configure/os/CONFIG.linux-x86.windows-x64-mingw 2016-02-04 21:57:23 +0000
87+++ configure/os/CONFIG.linux-x86.windows-x64-mingw 1970-01-01 00:00:00 +0000
88@@ -1,28 +0,0 @@
89-# CONFIG.linux-x86.windows-x64-mingw
90-#
91-# Definitions for linux-x86 host windows-x64-mingw target builds
92-# Override these definitions in CONFIG_SITE.linux-x86.windows-x64-mingw
93-#-------------------------------------------------------
94-
95-# Include common gnu compiler definitions
96-include $(CONFIG)/CONFIG.gnuCommon
97-
98-# Add resource compiler
99-RCCMD = $(GNU_BIN)/$(CMPLR_PREFIX)windres$(CMPLR_SUFFIX) $(INCLUDES) $< $@
100-
101-# Remove -fPIC flags, add out-implib
102-SHRLIB_CFLAGS =
103-SHRLIB_LDFLAGS = -shared \
104- -Wl,--out-implib,$(DLLSTUB_PREFIX)$*$(DLLSTUB_SUFFIX)
105-LOADABLE_SHRLIB_LDFLAGS = -shared \
106- -Wl,--out-implib,$(DLLSTUB_PREFIX)$*$(DLLSTUB_SUFFIX)
107-
108-# No need to explicitly link with gcc library
109-GNU_LDLIBS_YES =
110-
111-# Link with winsock2
112-OP_SYS_LDLIBS = -lws2_32
113-
114-# Use static compiler-support libraries
115-OP_SYS_LDFLAGS += -static-libgcc -static-libstdc++
116-# There is no compiler flag for static libwinpthread
117
118=== modified file 'configure/os/CONFIG.linux-x86_64.Common'
119=== added file 'configure/os/CONFIG.linux-x86_64.windows-x64-mingw'
120--- configure/os/CONFIG.linux-x86_64.windows-x64-mingw 1970-01-01 00:00:00 +0000
121+++ configure/os/CONFIG.linux-x86_64.windows-x64-mingw 2016-10-12 09:08:28 +0000
122@@ -0,0 +1,9 @@
123+# CONFIG.linux-x86_64.windows-x64-mingw
124+#
125+# Definitions for linux-x86_64 host windows-x64-mingw target builds
126+# Override these definitions in CONFIG_SITE.linux-x86_64.windows-x64-mingw
127+#-------------------------------------------------------
128+
129+# Settings as for the linux-x86 host architecture
130+include $(CONFIG)/os/CONFIG.linux-x86.windows-x64-mingw
131+
132
133=== removed file 'configure/os/CONFIG.linux-x86_64.windows-x64-mingw'
134--- configure/os/CONFIG.linux-x86_64.windows-x64-mingw 2016-02-04 21:57:23 +0000
135+++ configure/os/CONFIG.linux-x86_64.windows-x64-mingw 1970-01-01 00:00:00 +0000
136@@ -1,9 +0,0 @@
137-# CONFIG.linux-x86_64.windows-x64-mingw
138-#
139-# Definitions for linux-x86_64 host windows-x64-mingw target builds
140-# Override these definitions in CONFIG_SITE.linux-x86_64.windows-x64-mingw
141-#-------------------------------------------------------
142-
143-# Settings as for the linux-x86 host architecture
144-include $(CONFIG)/os/CONFIG.linux-x86.windows-x64-mingw
145-
146
147=== modified file 'configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw'
148--- configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw 2015-03-03 17:21:09 +0000
149+++ configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw 2016-10-12 09:08:28 +0000
150@@ -4,10 +4,10 @@
151 #-------------------------------------------------------
152
153 # Early versions of the MinGW cross-build tools can only build
154-# static (non-DLL) libraries. For example RHEL's cross-gcc 4.4.6
155-# needs these uncommented, cross-gcc 4.6.3 for Ubuntu does not:
156-SHARED_LIBRARIES = NO
157-STATIC_BUILD = YES
158+# static (non-DLL) libraries. RHEL's cross-build of gcc 4.4.6
159+# needs these uncommented, cross-gcc 4.6.3 from Ubuntu does not:
160+#SHARED_LIBRARIES = NO
161+#STATIC_BUILD = YES
162
163 # The cross-build tools are in $(GNU_DIR)/bin
164 # Default is /usr
165@@ -20,3 +20,6 @@
166 CMPLR_PREFIX = i686-pc-mingw32-
167 # Debian?
168 #CMPLR_PREFIX = i586-mingw32msvc-
169+
170+# Use static compiler-support libraries
171+OP_SYS_LDFLAGS += -static-libgcc -static-libstdc++
172
173=== added file 'configure/os/CONFIG_SITE.linux-x86.windows-x64-mingw'
174--- configure/os/CONFIG_SITE.linux-x86.windows-x64-mingw 1970-01-01 00:00:00 +0000
175+++ configure/os/CONFIG_SITE.linux-x86.windows-x64-mingw 2016-10-12 09:08:28 +0000
176@@ -0,0 +1,23 @@
177+# CONFIG_SITE.linux-x86.windows-x64-mingw
178+#
179+# Configuration for linux-x86 host windows-x64-mingw target builds
180+#-------------------------------------------------------
181+
182+# Early versions of the MinGW cross-build tools can only build
183+# static (non-DLL) libraries. For example RHEL's cross-gcc 4.4.6
184+# needs these uncommented, cross-gcc 4.6.3 for Ubuntu does not:
185+#SHARED_LIBRARIES = NO
186+#STATIC_BUILD = YES
187+
188+# The cross-build tools are in $(GNU_DIR)/bin
189+# Default is /usr
190+#GNU_DIR = /usr/local
191+
192+# Different distribution cross-build packages use different prefixes:
193+# Ubuntu:
194+#CMPLR_PREFIX = i686-w64-mingw32-
195+# RHEL:
196+CMPLR_PREFIX = x86_64-w64-mingw32-
197+
198+# Use static compiler-support libraries
199+OP_SYS_LDFLAGS += -static-libgcc -static-libstdc++
200
201=== removed file 'configure/os/CONFIG_SITE.linux-x86.windows-x64-mingw'
202--- configure/os/CONFIG_SITE.linux-x86.windows-x64-mingw 2016-02-04 21:57:23 +0000
203+++ configure/os/CONFIG_SITE.linux-x86.windows-x64-mingw 1970-01-01 00:00:00 +0000
204@@ -1,20 +0,0 @@
205-# CONFIG_SITE.linux-x86.windows-x64-mingw
206-#
207-# Configuration for linux-x86 host windows-x64-mingw target builds
208-#-------------------------------------------------------
209-
210-# Early versions of the MinGW cross-build tools can only build
211-# static (non-DLL) libraries. For example RHEL's cross-gcc 4.4.6
212-# needs these uncommented, cross-gcc 4.6.3 for Ubuntu does not:
213-#SHARED_LIBRARIES = NO
214-#STATIC_BUILD = YES
215-
216-# The cross-build tools are in $(GNU_DIR)/bin
217-# Default is /usr
218-#GNU_DIR = /usr/local
219-
220-# Different distribution cross-build packages use different prefixes:
221-# Ubuntu:
222-#CMPLR_PREFIX = i686-w64-mingw32-
223-# RHEL:
224-CMPLR_PREFIX = x86_64-w64-mingw32-
225
226=== added file 'configure/os/CONFIG_SITE.linux-x86_64.windows-x64-mingw'
227--- configure/os/CONFIG_SITE.linux-x86_64.windows-x64-mingw 1970-01-01 00:00:00 +0000
228+++ configure/os/CONFIG_SITE.linux-x86_64.windows-x64-mingw 2016-10-12 09:08:28 +0000
229@@ -0,0 +1,8 @@
230+# CONFIG_SITE.linux-x86_64.windows-x64-mingw
231+#
232+# Configuration for linux-x86_64 host windows-x64-mingw target builds
233+#-------------------------------------------------------
234+
235+# Inherit from the linux-x86 host architecture
236+include $(CONFIG)/os/CONFIG_SITE.linux-x86.windows-x64-mingw
237+
238
239=== removed file 'configure/os/CONFIG_SITE.linux-x86_64.windows-x64-mingw'
240--- configure/os/CONFIG_SITE.linux-x86_64.windows-x64-mingw 2016-02-04 21:57:23 +0000
241+++ configure/os/CONFIG_SITE.linux-x86_64.windows-x64-mingw 1970-01-01 00:00:00 +0000
242@@ -1,8 +0,0 @@
243-# CONFIG_SITE.linux-x86_64.windows-x64-mingw
244-#
245-# Configuration for linux-x86_64 host windows-x64-mingw target builds
246-#-------------------------------------------------------
247-
248-# Inherit from the linux-x86 host architecture
249-include $(CONFIG)/os/CONFIG_SITE.linux-x86.windows-x64-mingw
250-
251
252=== modified file 'documentation/RELEASE_NOTES.html'
253--- documentation/RELEASE_NOTES.html 2016-09-07 15:04:54 +0000
254+++ documentation/RELEASE_NOTES.html 2016-10-12 09:08:28 +0000
255@@ -3,14 +3,23 @@
256 <html>
257 <head>
258 <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
259+<<<<<<< TREE
260 <title>EPICS Base R3.16.0.2 Release Notes</title>
261+=======
262+ <title>EPICS Base R3.15.5 Release Notes</title>
263+>>>>>>> MERGE-SOURCE
264 </head>
265
266 <body lang="en">
267+<<<<<<< TREE
268 <h1 align="center">EPICS Base Release 3.16.0.2</h1>
269+=======
270+<h1 align="center">EPICS Base Release 3.15.5</h1>
271+>>>>>>> MERGE-SOURCE
272
273 <p style="color:red">This version of EPICS Base has not been released yet.</p>
274
275+<<<<<<< TREE
276 <h2 align="center">Changes made on the 3.16 branch since 3.16.0.1</h2>
277 <!-- Insert new items immediately below this template ...
278
279@@ -250,6 +259,144 @@
280 string for use by the IOC. This permits an older record type to be used with
281 the 3.15.4 release, although eventually record types should be converted by
282 hand with better group names used.</p>
283+=======
284+
285+<h2 align="center">Changes made on the 3.15 branch since 3.15.4</h2>
286+<!-- Insert new items immediately below here ... -->
287+>>>>>>> MERGE-SOURCE
288+
289+<h3>dbStatic Library Speedup and Cleanup</h3>
290+
291+<p>Loading of database files has been optimized to avoid overproportionally
292+long loading times for large databases. As a part of this, the alphabetical
293+ordering of records instances (within a record type) has been dropped. In the
294+unexpected case that applications were relying on the alphabetic order, setting
295+<tt>dbRecordsAbcSorted = 1</tt> before loading the databases will retain the
296+old behavior.</p>
297+
298+<p>The routine <tt>dbRenameRecord()</tt> has been removed, as it was intended
299+to be used by database configuration tools linked against a host side version
300+of the dbStatic library that is not being built anymore.</p>
301+
302+
303+<h2 align="center">Changes from the 3.14 branch since 3.15.4</h2>
304+<!-- Insert inherited items immediately below here ... -->
305+
306+<h3>MinGW Cross-builds from Linux</h3>
307+
308+<p>The build configuration files that allow cross-building of the 32-bit
309+win32-x86-mingw cross-target have been adjusted to default to building shared
310+libraries (DLLs) as this is now supported by recent MinGW compilers. The 64-bit
311+windows-x64-mingw cross-target was already being built that way by default. The
312+configuration options to tell the minGW cross-compiler to link programs with
313+static versions of the compiler support libraries have now been moved into the
314+CONFIG_SITE.linux-x86.<i>target</i> files.</p>
315+
316+<h3>General Time updates</h3>
317+
318+<p>The <tt>iocInit</tt> code now performs a sanity check of the current time
319+returned by the generalTime subsystem and will print a warning if the wall-clock
320+time returned has not been initialized yet. This is just a warning message; when
321+a time provider does synchonize the IOC will subsequently pick up and use the
322+correct time. This check code also primes the registered event system provider
323+if there is one so the <tt>epicsTimeGetEventInt()</tt> routine will work on IOCs
324+that ask for event time within an interrupt service routine.</p>
325+
326+<p>The osiClockTime provider's synchronization thread (which is only used on
327+some embedded targets) will now poll the other time providers at 1Hz until the
328+first time it manages to get a successful timestamp, after which it will poll
329+for updates every 60 seconds as before.</p>
330+
331+<p>The routine <tt>generalTimeGetExceptPriority()</tt> was designed for use by
332+backup (lower priority) time providers like the osiClockTime provider which do
333+not have their own absolute time reference and rely on other providers for an
334+absolute time source. This routine no longer implements the ratchet mechanism
335+that prevented the time it returned from going backwards. If the backup clock's
336+tick-timer runs fast the synchronization of the backup time provider would never
337+allow it to be corrected backwards when the ratchet was in place. The regular
338+<tt>epicsTimeGetCurrent()</tt> API still uses the ratchet mechanism, so this
339+change will not cause the IOC to see time going backwards.</p>
340+
341+<h3>Microsoft Visual Studio builds</h3>
342+
343+<p>The build configuration files for builds using the Microsoft compilers have
344+been updated, although there should be no noticable difference at most sites.
345+One extra compiler warning is now being suppressed for C++ code, <tt>C4344:
346+behavior change: use of explicit template arguments results in ...</tt> which is
347+gratuitous and was appearing frequently in builds of the EPICS V4 modules.</p>
348+
349+<p>Cross-builds of the windows-x64 target from a win32-x86 host have been
350+removed as they don't actually work within the context of a single <tt>make</tt>
351+run. Significant changes to the build configuration files would be necessary for
352+these kinds of cross-builds to work properly, which could be done if someone
353+needs them (email Andrew Johnson before working on this, and see
354+<a href="http://stackoverflow.com/questions/5807647/how-do-you-compile-32-bit-and-64-bit-applications-at-the-same-time-in-visual-stu">
355+this stack-overflow answer</a> for a starting point).</p>
356+
357+<h3>Bazaar keywords such as 'Revision-Id' removed</h3>
358+
359+<p>In preparation for moving to git in place of the Bazaar revision control
360+system we have removed all the keywords from the Base source code.</p>
361+
362+<h3>Linux systemd service file for CA Repeater</h3>
363+
364+<p>Building this version of Base on a Linux system creates a systemd service
365+file suitable for starting the Channel Access Repeater under systemd. The file
366+will be installed into the target bin directory, from where it can be copied
367+into the appropriate systemd location and modified as necessary. Installation
368+instructions are included as comments in the file.</p>
369+
370+
371+<h2 align="center">Changes made between 3.15.3 and 3.15.4</h2>
372+
373+<h3>New string input device support "getenv"</h3>
374+
375+<p>A new "getenv" device support for both the stringin and lsi (long string
376+input) record types can be used to read the value of an environment variable
377+from the IOC at runtime. See base/db/softIocExit.db for sample usage.</p>
378+
379+<h3>Build rules and DELAY_INSTALL_LIBS</h3>
380+
381+<p>A new order-only prerequisite build rule has been added to ensure that
382+library files (and DLL stubs on Windows) get installed before linking any
383+executables, which resolves parallel build problems on high-powered CPUs. There
384+are some (rare) cases though where a Makefile has to build an executable and run
385+it to be able to compile code for a library built by the same Makefile. With
386+this new build rule GNUmake will complain about a circular dependency and the
387+build will probably fail in those cases. To avoid this problem the failing
388+Makefile should set <tt>DELAY_INSTALL_LIBS = YES</tt> before including the
389+<tt>$(TOP)/configure/RULES</tt> file, disabling the new build rule.</p>
390+
391+<h3>IOC environment variables and build parameters</h3>
392+
393+<p>The IOC now sets a number of environment variables at startup that provide
394+the version of EPICS Base it was built against (EPICS_VERSION_...) and its build
395+architecture (ARCH). In some cases this allows a single iocBoot/ioc directory to
396+be used to run the same IOC on several different architectures without any
397+changes.</p>
398+
399+<p>There are also 3 new environment parameters (EPICS_BUILD_...) available that
400+C/C++ code can use to find out the target architecture, OS class and compiler
401+class it was built with. These may be useful when writing interfaces to other
402+languages.</p>
403+
404+<h3>New implementation of promptgroup/gui_group field property</h3>
405+
406+<p>The mechanism behind the "promptgroup()" field property inside a record type
407+definition has been changed. Instead of using a fixed set of choices,
408+the static database access library now collects the used gui group names
409+while parsing DBD information. Group names should start with a two-digit number
410+plus space-dash-space to allow proper sorting of groups.</p>
411+
412+<p>The include file <tt>guigroup.h</tt> that defined the fixed set of choices
413+has been deprecated. Instead, use the conversion functions between index number
414+and group string that have been added to dbStaticLib.</p>
415+
416+<p>When a DBD file containing record-type descriptions is expanded, any
417+old-style <tt>GUI_xxx</tt> group names will be replaced by a new-style
418+string for use by the IOC. This permits an older record type to be used with
419+the 3.15.4 release, although eventually record types should be converted by
420+hand with better group names used.</p>
421
422 <h3>CA server configuration changes</h3>
423
424@@ -422,5 +569,1169 @@
425 <a href="https://bugs.launchpad.net/bugs/1528284">Launchpad bug 1528284</a>.</p>
426
427
428+<<<<<<< TREE
429+=======
430+<h2 align="center">Changes made between 3.15.2 and 3.15.3</h2>
431+
432+<h3>Make the NTP Time provider optional on VxWorks</h3>
433+
434+<p>Recent versions of VxWorks (sometime after VxWorks 6) provide facilities for
435+automatically synchronizing the OS clock time with an NTP server. The EPICS time
436+system used to assume that it had to provide time synchronization on VxWorks,
437+but now it tests for the existance of either of the two OS synchronization
438+threads before starting the NTP time provider. It is still possible to force the
439+NTP provider to be started even if the OS synchronization is running by defining
440+the environment variable <tt>EPICS_TS_FORCE_NTPTIME</tt> in the startup script
441+before loading the IOC's .munch file. Forcing may be necessary if the VxWorks
442+image is not correctly configured with the IP address of a local NTP server.</p>
443+
444+<h3>Assembling files from numbered snippets</h3>
445+
446+<p>A tool has been added that assembles file snippets specified on the
447+command line into a single output file, with sorting and replacing/adding of
448+snippets done based on their file names. The build system integration requires
449+the output file to be specified setting COMMON_ASSEMBLIES (arch independent)
450+or ASSEMBLIES (created by arch), then defining the snippets for each assembly
451+setting *_SNIPPETS (explicitly) or *_PATTERN (searched relative to all source
452+directories).
453+</p>
454+
455+<h3>Clean up after GNU readline()</h3>
456+
457+<p>If EPICS Base is built with readline support, any IOC that calls epicsExit()
458+from a thread other than the main thread is likely to leave the user's terminal
459+in a weird state, requiring the user to run something like 'stty sane' to clean
460+it up. This release patches the readline support code to clean up automatically
461+by registering an epicsAtExit() routine.</p>
462+
463+<h3>Removed the last vestiges of RSET::get_value()</h3>
464+
465+<p>The IOC has not called the get_value() routine in the RSET for a very long
466+time, but there was still one implementation left in the event record support
467+code, and a structure definition for one of the original arguments to that
468+routine was defined in recGbl.h. Both of these have now been removed.</p>
469+
470+
471+<h2 align="center">Changes made between 3.15.1 and 3.15.2</h2>
472+
473+<h3>Raised limit on link field length in database files</h3>
474+
475+<p>The length of INP/OUT link fields in database files was limited to 79 chars
476+by an internal buffer size in the db file parser. This limitation will go away
477+completely in 3.16, and has been statically raised to 255 chars for the 3.15
478+series.</p>
479+
480+<h3>aoRecord raw conversion overflows</h3>
481+
482+<p>The ao record type now checks converted raw values and limits them to the
483+32-bit integer range before writing them to the RVAL field. Previously value
484+overflows relied on Undefined Behaviour which could give different results on
485+different platforms. The ROFF fields of the ao and ai record types are now
486+DBF_ULONG to allow an ROFF setting of 0x80000000 to work properly.</p>
487+
488+<h3>Changes to &lt;top&gt;/cfg/* files</h3>
489+
490+<p>The order in which cfg/CONFIG* and cfg/RULES* files are included from support
491+applications listed in the configure/RELEASE* files has been changed. Previously
492+these files were included in the order in which the top areas are listed in the
493+RELEASE file, but it makes more sense to load them in reverse order since later
494+entries override earlier ones in Makefiles but the release file order is
495+supposed to allow earlier entries to take precedence over later ones. The same
496+change has been made to the inclusion of the &lt;top&gt;/configure/RULES_BUILD
497+files.</p>
498+
499+<p>Two new file types can also be provided in a module's cfg directory. Files
500+named TOP_RULES* will be included by the top-level Makefile of other modules
501+that refer to this module; files name DIR_RULES* will be included by all
502+Makefiles that merely descend into lower-level directories. The cfg/RULES* files
503+are only included when make is building code inside the O.&lt;arch&gt;
504+directories.</p>
505+
506+<p>The new cfg/DIR_RULES* file inclusion was designed to permit new recursive
507+make actions to be implemented by appending the name of the new action to the
508+ACTIONS variable. There must be a matching rule in one of the cfg/RULES* files
509+when doing this. Similar rules may also be defined in the cfg/TOP_RULES* and/or
510+cfg/DIR_RULES* files, but these should only state prerequisites and not directly
511+provide commands to be executed.</p>
512+
513+<h3>Build rules for RTEMS GESYS modules</h3>
514+
515+<p>RTEMS target builds can now be configured to make GESYS modules by changing
516+the <CODE>USE_GESYS=NO</code> setting in the file
517+configure/os/CONFIG_SITE.Common.RTEMS to <code>YES</code>.</p>
518+
519+<h3>Added Make variables for command-line use</h3>
520+
521+<p>The following variables are now used during the build process, reserved for
522+setting on the command-line only (Makefiles should continue to use the
523+<code>USR_</code> equivalents):</p>
524+
525+<ul>
526+<li>CMD_INCLUDES</li>
527+<li>CMD_CPPFLAGS</li>
528+<li>CMD_CFLAGS</li>
529+<li>CMD_CXXFLAGS</li>
530+<li>CMD_LDFLAGS</li>
531+<li>CMD_DBFLAGS</li>
532+<li>CMD_DBDFLAGS</li>
533+<li>CMD_REGRDDFLAGS</li>
534+<li>CMD_ARFLAGS</li>
535+</ul>
536+
537+<p>For example:</p>
538+
539+<blockquote><pre>
540+make CMD_INCLUDES=/opt/local/include CMD_LDFLAGS=-L/opt/local/lib
541+</pre></blockquote>
542+
543+<h3>Enhanced API for asTrapWrite listeners</h3>
544+
545+<p>External software such as the CA Put Logging module that registers a listener
546+with the asTrapWrite subsystem was not previously given access to the actual
547+data being sent by the CA client. In most cases this was not a problem as the
548+listener can look at the field being modified both before and after the
549+operation, but if the put processes the record which immediately overwrites the
550+new value, the client's value cannot be observed.</p>
551+
552+<p>This release adds three fields to the asTrapWriteMessage structure that is
553+passed to the listener routines. These new fields provide the CA data type, the
554+number of array elements, and a pointer to the source data buffer. This change
555+is completely backwards compatible with listener code written against the
556+original API. The new API can be detected at compile-time as follows:</p>
557+
558+<blockquote><pre>
559+#include "asLib.h"
560+
561+/* ... */
562+
563+#ifdef asTrapWriteWithData
564+ /* Enhanced API */
565+#endif
566+</pre></blockquote>
567+
568+<h3>Use of PATH_FILTER in Makefiles deprecated</h3>
569+
570+<p>The PATH_FILTER variable was being called to convert forward shashes
571+<tt><b>/</b></tt> in file paths into pairs of backward slashes
572+<tt><b>\\</b></tt> on Windows architectures. This has never been strictly
573+necessary, and was added about 10 years ago to get around some short-comings in
574+Windows tools at the time. All uses of PATH_FILTER in Base have now been
575+removed; the definition is still present, but will result in a warning being
576+printed if it is ever used.</p>
577+
578+<h3>Using msi for dependencies</h3>
579+
580+<p>To reduce confusion the msi program has been modified to allow the generation
581+of dependency rules by adding support for a <tt>-D</tt> option, and changing the
582+commands in RULES.Db to use this option instead of the mkmf.pl script. The new
583+build rules will not work with old versions of the msi program, so the command
584+variable name used in the rules has been changed from MSI to MSI3_15. Sites that
585+use a modified version of msi must provide support for both the <tt>-D</tt> and
586+<tt>-o&nbsp;outfile</tt> options, and should then point the MSI3_15 variable in
587+their applications' CONFIG_SITE files to that updated executable.</p>
588+
589+
590+<h2 align="center">Changes made between 3.15.0.2 and 3.15.1</h2>
591+
592+<h3>epicsStrnEscapedFromRaw() and epicsStrnRawFromEscaped()</h3>
593+
594+<p>These routines have been rewritten; the previous implementations did not
595+always behave exactly as specified.</p>
596+
597+<h3>Shared Library Versions</h3>
598+
599+<p>On architectures that can support it, the shared library version number for
600+libraries provided with Base has had the third component of the EPICS version
601+number added to it, thus libCom.so.3.15.1 instead of libCom.so.3.15. Windows
602+can only support two components to its internal product version number, and the
603+Darwin bug that external shared libraries were being built using the EPICS
604+version number has been fixed.</p>
605+
606+<h3>Hooking into dbLoadRecords</h3>
607+
608+<p>A function pointer hook has been added to the dbLoadRecords() routine, to
609+allow external modules such as autosave to be notified when new records have
610+been loaded during IOC initialization. The hook is called dbLoadRecordsHook and
611+follows the model of the recGblAlarmHook pointer in that modules that wish to
612+use it must save the current value of the pointer before installing their own
613+function pointer, and must call the original function from their own
614+routine.</p>
615+
616+<p>The hook is activiated from the dbLoadRecords() routine and gets called only
617+after a database instance file has been read in without error. Note that the
618+dbLoadTemplates() routine directly calls dbLoadRecords() so this hook also
619+provides information about instantiated database templates. It is still possible
620+to load record instances using dbLoadDatabase() though, and doing this will not
621+result in the hook routines being called.</p>
622+
623+<p>Code to use this hook should look something like this:</p>
624+
625+<blockquote><pre>
626+#include "dbAccessDefs.h"
627+
628+static DB_LOAD_RECORDS_HOOK_ROUTINE previousHook;
629+
630+static void myRoutine(const char* file, const char* subs) {
631+ if (previousHook)
632+ previousHook(file, subs);
633+
634+ /* Do whatever ... */
635+}
636+
637+void myInit(void) {
638+ static int done = 0;
639+
640+ if (!done) {
641+ previousHook = dbLoadRecordsHook;
642+ dbLoadRecordsHook = myRoutine;
643+ done = 1;
644+ }
645+}
646+</pre></blockquote>
647+
648+<p>As with many other parts of the static database access library there is no
649+mutex to protect the function pointer. Initialization is expected to take place
650+in the context of the IOC's main thread, from either a static C++ constructor or
651+an EPICS registrar routine.</p>
652+
653+
654+<h2 align="center">Changes made between 3.15.0.1 and 3.15.0.2</h2>
655+
656+<h3>New iocshLoad command</h3>
657+
658+<p>A new command <tt>iocshLoad</tt> has been added to iocsh which executes a
659+named iocsh script and can also set one or more shell macro variables at the
660+same time, the values of which will be forgotten immediately after the named
661+script finishes executing. The following example shows the syntax:</p>
662+
663+<blockquote><pre>
664+iocshLoad "serial.cmd", "DEV=/dev/ttyS0,PORT=com1,TYPE=RS485"
665+iocshLoad "radmon.cmd", "PORT=com1,ADDR=0"
666+</pre></blockquote>
667+
668+<h3>Support routines for 64-bit integers</h3>
669+
670+<p>The libCom library now provides support for 64-bit integer types on all
671+supported architectures. The epicsTypes.h header file defines epicsInt64 and
672+epicsUInt64 type definitions for both C and C++ code. The epicsStdlib.h header
673+also declares the following for parsing strings into the relevent sized integer
674+variables: Functions epicsParseLLong(), epicsParseULLong() with related macros
675+epicsScanLLong() and epicsScanULLong(), and the functions epicsParseInt64()
676+and epicsParseUInt64(). Use the first two functions and the macros for long long
677+and unsigned long long integer types, and the last two functions for the
678+epicsInt64 and epicsUInt64 types. Note that the latter can map to the types long
679+and unsigned long on some 64-bit architectures such as linux-x86_64, not to the
680+two long long types.</p>
681+
682+<p>This version does not provide the ability to define 64-bit record fields, the
683+use of the 64-bit types in the IOC database will come in a later release of
684+EPICS Base.</p>
685+
686+<h3>Full support for loadable support modules</h3>
687+
688+<p>Apparently later versions of Base 3.14 permitted support modules to be loaded
689+from a shared library at runtime without the IOC having been linked against that
690+shared library; the registerRecordDeviceDriver.pl program would accept a partial
691+DBD file containing just the entries needed for the library and generate the
692+appropriate registration code. In 3.15 however the registerRecordDeviceDriver.pl
693+program was replaced by one using the new DBD file parser, and in this a device
694+support entry would only be accepted after first loading the record type that it
695+depended on.</p>
696+
697+<p>The parser has been modified to accept device entries without having seen the
698+record type first, although a warning is given when that happens. To remove the
699+warning the DBD file can provide a record type declaration instead (no fields
700+can be defined, so the braces must be empty), before the device() entry. The
701+result will generate the correct registration code for the device entry without
702+including anything for any merely declared record types. The generated code can
703+be linked into a shared library and loaded by an IOC at runtime using dlload.
704+</p>
705+
706+<h3>Parallel callback threads</h3>
707+
708+<p>The general purpose callback facility can run multiple parallel callback
709+threads per priority level. This makes better use of SMP architectures (e.g.
710+processors with multiple cores), as callback work - which includes second
711+stage processing of records with asynchronuous device support and I/O
712+scanned processing - can be distributed over the available CPUs.</p>
713+
714+<p>Note that by using parallel callback threads the order of scan callback
715+requests in the queue is not retained. If a device support needs to be
716+informed when scanIoRequest processing has finished, it should use the new
717+scanIoSetComplete() feature to add a user function that will be called after
718+the scanIoRequest record processing has finished.</p>
719+
720+<p>Parallel callback threads have to be explicitly configured, by default
721+the IOC keeps the old behavior of running one callback thread per priority.</p>
722+
723+<h3>Merge MMIO API from devLib2</h3>
724+
725+<p>Added calls to handle 8, 16, and 32 bit Memory Mapped I/O reads and writes.
726+The calls added include <tt><i>X</i>_iowrite<i>Y</i>()</tt> and
727+<tt><i>X</i>_ioread<i>Y</i>()</tt>
728+where <tt><i>X</i></tt> is <tt>nat</tt> (native), <tt>be</tt> or <tt>le</tt>,
729+and <tt><i>Y</i></tt> is <tt>16</tt> or <tt>32</tt>.
730+Also added are <tt>ioread8()</tt> and <tt>iowrite8()</tt>.</p>
731+
732+<h3>Added optional dbServer API to database</h3>
733+
734+<p>A server layer that sits on top of the IOC database may now register itself
735+as such by calling <tt>dbRegisterServer()</tt> and providing optional routines
736+that other components can use. The initial purpose of this API allows the Trace
737+Processing implementation in <tt>dbProcess()</tt> to identify a client that
738+causes a record to process when TPRO is set.</p>
739+
740+<p>To support the client idenfication, the server provides a routine that
741+returns that identity string when called by one of its own processing
742+threads.</p>
743+
744+<h3>Concatenated database definition files</h3>
745+
746+<p>A series of database definition (dbd) files can now be concatenated during
747+the build process into a newly-created dbd file with result being installed into
748+$(INSTALL_LOCATION)/dbd without expanding it.</p>
749+
750+<p>The following lines in an EPICS Makefile will create a file name.dbd in the
751+O.Common build directory containing the contents of file1.dbd followed by
752+file2.dbd then file3.dbd. The new file will then be installed into
753+$(INSTALL_LOCATION)/dbd without expanding any of its include statements.</p>
754+
755+<blockquote><pre>
756+DBDCAT += name.dbd
757+name_DBD += file1.dbd file2.dbd file3.dbd
758+</pre></blockquote>
759+
760+<p>The source files file1.dbd, file2.dbd and file3.dbd may be created by the
761+current Makefile, be located in the parent directory or any other directory in
762+the SRC_DIRS list, be specified by their full pathname, exist in the install dbd
763+directory, or be found in any dbd directory linked from the application's
764+RELEASE files.</p>
765+
766+<h3>Posix: Drop SCHED_FIFO before exec() in child process</h3>
767+
768+<p>If Base is compiled with <tt>USE_POSIX_THREAD_PRIORITY_SCHEDULING = YES</tt>
769+in configure/CONFIG_SITE or related files, the Posix implementation of the
770+libCom <tt>osiSpawnDetachedProcess()</tt> routine will switch the child process
771+to use the normal SCHED_OTHER (non real-time) scheduler before executing the
772+named executable program. If it needs to use the real-time scheduler the new
773+program can request that for itself.</p>
774+
775+<h3>Posix: Lock all memory when running with FIFO scheduler</h3>
776+
777+<p>On Posix systems, an IOC application's ability to meet timing deadlines is
778+often dependent on its ability to lock part or all of the process's virtual
779+address space into RAM, preventing that memory from being paged to the swap
780+area. This change will attempt to lock the process's virtual address space into
781+RAM if the process has the ability to run threads with different priorities. If
782+unsuccessful, it prints an message to stderr and continues.</p>
783+
784+<p>On Linux, one can grant a process the ability to run threads with different
785+priorities by using the command <code>ulimit -r unlimited</code>. To use the
786+FIFO scheduler for an IOC, use a command like this:</p>
787+
788+<blockquote><pre>chrt -f 1 softIoc -d test.db</pre></blockquote>
789+
790+<p>On Linux, one can grant a process the ability to lock itself into memory
791+using the command <code>ulimit -l unlimited</code>. These limits can also be
792+configured on a per user/per group basis by changing /etc/security/limits.conf
793+or its equivalent.</p>
794+
795+<p>A child process created via fork() normally inherits its parent's resource
796+limits, so a child of a real-time soft-IOC will get its parent's real-time
797+priority and memlock limits. The memory locks themselves however are not
798+inherited by child processes.</p>
799+
800+<h3>Implement EPICS_CAS_INTF_ADDR_LIST in rsrv</h3>
801+
802+<p>The IOC server can now bind to a single IP address (and optional port number)
803+read from the standard environment parameter EPICS_CAS_INTF_ADDR_LIST.
804+Additional addresses included in that parameter after the first will be ignored
805+and a warning message displayed at iocInit time.</p>
806+
807+<h3>alarmString.h deprecated again</h3>
808+
809+<p>The string arrays that provide string versions of the alarm status and
810+severity values have been moved into libCom and the header file that used to
811+instanciate them is no longer required, although a copy is still provided for
812+backwards compatibility reasons. Only the alarm.h header needs to be included
813+now to declare the epicsAlarmSeverityStrings and epicsAlarmConditionStrings
814+arrays.</p>
815+
816+<h3>General purpose thread pool</h3>
817+
818+<p>
819+A general purpose threaded work queue API epicsThreadPool is added.
820+Multiple pools can be created with controlable priority and number
821+of worker threads. Lazy worker startup is supported.</p>
822+
823+<h3>Database field setting updates</h3>
824+
825+<p>A database (.db) file loaded by an IOC does not have to repeat the record
826+type of a record that has already been loaded. It may replace the first
827+parameter of the <tt>record(type, name)</tt> statement with an asterisk
828+character inside double-quotes, <tt>"*"</tt> instead. Thus the following is a
829+legal database file:</p>
830+
831+<blockquote><pre>record(ao, "ao1") {}
832+record("*", "ao1") {
833+ field(VAL, 10)
834+}</pre></blockquote>
835+
836+<p>Note that database configuration tools will not be expected to have to
837+understand this syntax, which is provided for scripted and hand-coded database
838+and template instantiation only. Setting the IOC's <tt>dbRecordsOnceOnly</tt>
839+flag also makes this syntax illegal, since its purpose is to prevent
840+multiply-defined records from being collapsed into a single instance.</p>
841+
842+<h3>Added echo command to iocsh</h3>
843+
844+<p>The single argument string may contain escaped characters, which will be
845+translated to their raw form before being printed (enclose the string in quotes
846+to avoid double-translation). A newline is always appended to the output, and
847+output stream redirection is supported.</p>
848+
849+<h3>Added macro EPICS_UNUSED to compilerDependencies.h</h3>
850+
851+<p>To prevent the compiler from warning about a known-unused variable, mark it
852+with the macro EPICS_UNUSED. On gcc and clang this will expand to
853+<tt>__attribute__((unused))</tt> to prevent the warning.</p>
854+
855+<h3>User specified db substitution file suffix</h3>
856+
857+<p>Per Dirk Zimoch's suggestion, a user specified db substitution file suffix is
858+now allowed by setting the variable SUBST_SUFFIX in a configuration directory
859+CONFIG_SITE file or in a Makefile before the include $(TOP)/configure/RULES
860+line. The default for SUBST_SUFFIX is <tt>.substitutions</tt></p>
861+
862+<h3>NTP Time Provider adjusts to OS tick rate changes</h3>
863+
864+<p>Dirk Zimoch provided code that allows the NTP Time provider (used on VxWorks
865+and RTEMS only) to adapt to changes in the OS clock tick rate after the provider
866+has been initialized. Note that changing the tick rate after iocInit() is not
867+advisable, and that other software might still misbehave if initialized before
868+an OS tick rate change.</p>
869+
870+<h3>Added newEpicsMutex macro</h3>
871+
872+<p>Internal C++ uses of <tt>new epicsMutex()</tt> have been replaced with a new
873+macro which calls a new constructor, passing it the file name and line number of
874+the mutex creation code. C code that creates mutexes has been using a similar
875+macro for a long time, but there was no equivalent constructor for the C++
876+wrapper class, so identifying a specific mutex was much harder to do.</p>
877+
878+<h3>Post DBE_PROPERTY events automatically</h3>
879+
880+<p>A new record field attribute "prop(YES)" has been added to identify fields
881+holding meta-data. External changes to these fields will cause a CA monitor
882+event to be sent to all record subscribers who have asked for DBE_PROPERTY
883+updates. Meta-data fields have been marked for all Base record types.</p>
884+
885+<h3>errlogRemoveListener() routine changed</h3>
886+
887+<p>Code that calls <tt>errlogRemoveListener(myfunc)</tt> must be modified to use
888+the new, safer routine <tt>errlogRemoveListeners(myfunc, &amp;pvt)</tt> instead.
889+The replacement routine takes a second argument which must be the same private
890+pointer that was passed to <tt>errlogAddListener()</tt> when adding that
891+listener. It also deletes all matching listeners (hence the new plural name) and
892+returns how many were actually deleted, whereas the previous routine only
893+removed the first listener that matched.</p>
894+
895+<h3>Simplified generation of .dbd files</h3>
896+
897+<p>The Perl script <tt>makeIncludeDbd.pl</tt> has been removed and the rules
898+that created an intermediate <tt><i>xxx</i>Include.dbd</tt> file from the
899+Makefile variable <tt>xxx_DBD</tt> have been modified to generate the target
900+<tt><i>xxx</i>.dbd</tt> file directly. This should simplify applications that
901+might have had to provide dependency rules for the intermediate files in 3.15.
902+Applications which provide their own <tt><i>xxx</i>Include.dbd</tt> source file
903+will continue to have it expanded as before.</p>
904+
905+<h3>New Undefined Severity field UDFS</h3>
906+
907+<p>A new field has been added to dbCommon which configures the alarm severity
908+associated with the record being undefined (when UDF=TRUE). The default value is
909+INVALID so old databases will not be affected, but now individual records can be
910+configured to have a lower severity or even no alarm when undefined. Be careful
911+when changing this on applications where the IVOA field of output records is
912+used, IVOA still requires an INVALID severity to trigger value replacement.</p>
913+
914+<h3>New build target <q>tapfiles</q></h3>
915+
916+<p>This new make target runs the same tests as the <q>runtests</q> target, but
917+instead of summarizing or displaying the output for each test script it creates
918+a <q>.tap</q> file inside the architecture build directory which contains the
919+detailed test output. The output file can be parsed by continuous integration
920+packages such as <a href="http://www.jenkins-ci.org/">Jenkins</a> to show the
921+test results.</p>
922+
923+<h3>Array field double-buffering</h3>
924+
925+<p>Array data can now be moved, without copying, into and out of the VAL field
926+of the waveform, aai, and aao record types by replacing the pointer in BPTR.
927+The basic rules which device support must follow are:</p>
928+
929+<ol>
930+ <li>BPTR, and the memory it is currently pointing to, can only be accessed
931+ while the record is locked.</li>
932+ <li>NELM may not be changed; NORD should be updated whenever the number of
933+ valid data elements changes.</li>
934+ <li>When BPTR is replaced it must always point to a block of memory large
935+ enough to hold the maximum number of elements, as given by the NELM and
936+ FTVL fields.</li>
937+</ol>
938+
939+<h3>Spin-locks API added</h3>
940+
941+<p>The new header file epicsSpin.h adds a portable spin-locks API which is
942+intended for locking very short sections of code (typically one or two lines of
943+C or C++) to provide a critical section that protects against race conditions.
944+On Posix platforms this uses the pthread_spinlock_t type if it's available and
945+the build is not configured to use Posix thread priorities, but otherwise it
946+falls back to a pthread_mutex_t. On the UP VxWorks and RTEMS platforms the
947+implementations lock out CPU interrupts and disable task preemption while a
948+spin-lock is held. The default implementation (used when no other implementation
949+is provided) uses an epicsMutex. Spin-locks may not be taken recursively, and
950+the code inside the critical section should be short and deterministic.</p>
951+
952+<h3>Improvements to aToIPAddr()</h3>
953+
954+<p>The libCom routine aToIPAddr() and the vxWorks implementation of the
955+associated hostToIPAddr() function have been modified to be able to look up
956+hostnames that begin with one or more digits. The epicsSockResolveTest program
957+was added to check this functionality.</p>
958+
959+<h3>mbboDirect and mbbiDirect records</h3>
960+
961+<p>These record types have undergone some significant rework, and will behave
962+slightly differently than they did in their 3.14 versions. The externally
963+visible changes are as follows:</p>
964+
965+<h5>mbbiDirect</h5>
966+
967+<ul>
968+ <li>If the MASK field is set in a database file, it will not be over-written
969+ when the record is initialized. This allows non-contiguous masks to be set,
970+ although only the device support actually uses the MASK field.</li>
971+ <li>If process() finds the UDF field to be set, the record will raise a
972+ UDF/INVALID alarm.</li>
973+</ul>
974+
975+<h5>mbboDirect</h5>
976+
977+<ul>
978+ <li>If the MASK field is set in a database file, it will not be over-written
979+ when the record is initialized. This allows non-contiguous masks to be set,
980+ although only the device support actually uses the MASK field.</li>
981+ <li>After the device support's init_record() routine returns during record
982+ initialization, if OMSL is <q>supervisory</q> and UDF is clear the fields
983+ B0-BF will be set from the current VAL field.</li>
984+ <li>When a put to the OMSL field sets it to <q>supervisory</q>, the fields
985+ B0-BF will be set from the current VAL field. This did not used to happen,
986+ the individual bit fields were previously never modified by the record.
987+ Note that this change may require some databases to be modified, if they
988+ were designed to take advantage of the previous behavior.</li>
989+</ul>
990+
991+<h3>Redirection of the errlog console stream</h3>
992+
993+<p>A new routine has been added to the errlog facility which allows the console
994+error message stream to be redirected from stderr to some other already open
995+file stream:</p>
996+
997+<blockquote><pre>int errlogSetConsole(FILE *stream);
998+</pre></blockquote>
999+
1000+<p>The stream argument must be a FILE* pointer as returned by fopen() that is
1001+open for output. If NULL is passed in, the errlog thread's stderr output stream
1002+will be used instead. Note that messages to the console can be disabled and
1003+re-enabled using the eltc routine which is also an iocsh command, but there is
1004+no iocsh command currently provided for calling errlogSetConsole.</p>
1005+
1006+<h3>Add cleanup subroutine to aSub record</h3>
1007+
1008+<p>An aSub routine may set the CADR field with a function pointer which will be
1009+run before a new routine in the event that a change to the SNAM field changes
1010+the record's process subroutine.</p>
1011+
1012+<p>This can be used to free any resources the routine needs to allocate. It can
1013+also be used to determine if this is the first time this routine has been called
1014+by this record instance. The CADR field is set to NULL immediately after the
1015+routine it points to is called.</p>
1016+
1017+<p>Example:</p>
1018+
1019+<blockquote><pre>void cleanup(aSubRecord* prec) {
1020+ free(prec-&gt;dpvt);
1021+ prec-&gt;dpvt = NULL;
1022+}
1023+
1024+long myAsubRoutine(aSubRecord* prec) {
1025+ if (!prec-&gt;cadr) {
1026+ /* check types of inputs and outputs */
1027+ if (prec-&gt;ftva != menuFtypeDOUBLE)
1028+ return 1; /* oops */
1029+
1030+ dpvt = malloc(42);
1031+ prec-&gt;cadr = &amp;cleanup;
1032+ }
1033+
1034+ /* normal processing */
1035+}
1036+epicsRegisterFunction(myAsubRoutine);
1037+</pre></blockquote>
1038+
1039+<h3>Sequence record enhancements</h3>
1040+
1041+<p>The sequence record type now has 16 link groups numbered 0 through 9 and A
1042+through F, instead of the previous 10 groups numbered 1 through 9 and A. The
1043+changes to this record are directly equivalent to those described below for the
1044+fanout record. The fields OFFS and SHFT have been added and operate on the SELN
1045+value exactly the same way. The result is backwards compatible with the 3.14
1046+version of the sequence record as long as none of the new fields are modified
1047+and the application does not rely on the SOFT/INVALID alarm that was generated
1048+when the selection number exceeded 10. The record also now posts monitors on the
1049+SELN field at the end of the sequence if its value changed when read through the
1050+SELL link.
1051+
1052+<h3>Fanout record enhancements</h3>
1053+
1054+<p>The fanout record type now has 16 output links LNK0-LNK9 and LNKA-LNKF, plus
1055+two additional fields which make the result backwards compatible with 3.14
1056+databases, but also allow the link selection to be shifted without having to
1057+process the SELN value through a calc or calcout record first.</p>
1058+
1059+<p>Previously there was no LNK0 field, so when SELM is <q>Mask</q> bit 0 of SELN
1060+controls whether the LNK1 link field was activated; bit 1 controls LNK2 and so
1061+on. When SELM is <q>Specified</q> and SELN is zero no output link would be
1062+activated at all; LNK1 gets activated when SELN is 1 and so on. Only 6 links
1063+were provided, LNK1 through LNK6. The updated record type maintains the original
1064+behavior when the new fields are not configured, except that the SOFT/INVALID
1065+alarm is not generated when SELN is 7 through 15.</p>
1066+
1067+<p>The update involved adding a LNK0 field, as well as fields LNK7 through LNK9
1068+and LNKA through LNKF. To add flexibility and maintain backwards compatibility,
1069+two additional fields have been added:</p>
1070+
1071+<dl>
1072+<dt><b>OFFS</b></dt>
1073+
1074+<dd>This field holds a signed offset which is added to SELN to select which link
1075+to activate when SELM is <q>Specified</q>. If the resulting value is outside the
1076+range 0 .. 15 the record will go into a SOFT/INVALID alarm state. The default
1077+value of OFFS is zero, so if it is not explicitly set and SELN is 1 the LNK1
1078+link will be activated.</dd>
1079+
1080+<dt><b>SHFT</b></dt>
1081+
1082+<dd>When SELM is <q>Mask</q> the signed field SHFT is used to shift the SELN
1083+value by SHFT bits (positive means right-wards, values outside the range -15 ..
1084+15 will result in a SOFT/INVALID alarm), before using the resulting bit-pattern
1085+to control which links to activate. The default value is -1, so if SHFT is not
1086+explicitly set bit 0 of SELN will be used to control whether LNK1 gets
1087+activated.</dd>
1088+
1089+</dl>
1090+
1091+<p>The record also now posts monitors on the SELN field if it changes as a
1092+result of record processing (i.e. when read through the SELL link).</p>
1093+
1094+<h3>Deleted Java build rules</h3>
1095+
1096+<p>Java has its own build systems now, so we've deleted the rules and associated
1097+variables from Base, although they might get added to the Extensions build rules
1098+for a while in case anyone still needs them.</p>
1099+
1100+<h2 align="center">Changes made between 3.14.x and 3.15.0.1</h2>
1101+
1102+<h3>Application clean rules</h3>
1103+
1104+<p>The <tt>clean</tt> Makefile target has changed between a single-colon rule
1105+and a double-colon rule more than once in the life of the EPICS build rules, and
1106+it just changed back to a single-colon rule, but now we recommend that
1107+applications that wish to provide a Makefile that is backwards compatible with
1108+the 3.14 build rules use the construct shown below. The 3.15 rules now support
1109+a variable called <tt>CLEANS</tt> to which a Makefile can add a list of files to
1110+be deleted when the user does a <tt>make clean</tt> like this:</p>
1111+
1112+<blockquote><pre>CLEANS += &lt;list of files to be cleaned&gt;
1113+
1114+ifndef BASE_3_15
1115+clean::
1116+ $(RM) $(CLEANS)
1117+endif</pre></blockquote>
1118+
1119+<p>The conditional rule provides compatibility for use with the 3.14 build
1120+system.</p>
1121+
1122+<h3>MSI included with Base</h3>
1123+
1124+<p>An enhanced version of the Macro Substitution and Include program <q>msi</q>
1125+has been included with Base. Both this new version of msi and the IOC's
1126+<tt>dbLoadTemplates</tt> command now support setting global macros in
1127+substitution files, and <tt>dbLoadTemplates</tt> can now take a list of global
1128+macro settings as the second argument on its command line. The substitution file
1129+syntax is documented in the Application Developers Guide.</p>
1130+
1131+<h3>Cross-builds targeting win32-x86-mingw</h3>
1132+
1133+<p>Some Linux distributions now package the MinGW cross-compiler which makes it
1134+possible to cross-build the win32-x86-mingw target from a linux-x86 host. Build
1135+configuration files for this combination are now included; adjust the settings
1136+in configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw and add win32-x86-mingw to
1137+the CROSS_COMPILER_TARGET_ARCHS variable in configure/CONFIG_SITE or in
1138+configure/os/CONFIG_SITE.linux-x86.Common.</p>
1139+
1140+<h3>Architecture win32-x86-cygwin Removed</h3>
1141+
1142+<p>The ability to compile non-cygwin binaries using the Cygwin build tools is no
1143+longer supported by current versions of Cygwin, so this architecture has been
1144+removed. Use the MinWG tools and the win32-x86-mingw architecture instead.</p>
1145+
1146+<h3>RTEMS and VxWorks Test Harnesses</h3>
1147+
1148+<p>The original libCom test harness has been renamed <tt>libComTestHarness</tt>,
1149+and two additional test harnesses have been created <tt>dbTestHarness</tt> and
1150+<tt>filterTestHarness</tt> which are all built for RTEMS and vxWorks targets.
1151+The new ones include tests in src/ioc/db/test and src/std/filters/test.</p>
1152+
1153+<p>Running the new tests requires additional .db and .dbd files to be loaded at
1154+runtime, which can be found in the relevant source directory or its O.Common
1155+subdirectory. If the target can access the Base source tree directly it may be
1156+simplest to cd to the relevant source directory before running the test. If not,
1157+the files needed are listed in the generated 'testspec' file found in the
1158+associated build (O.<i>arch</i>) directory.</p>
1159+
1160+<p>For RTEMS users the current directory is determined in a BSP specific way.
1161+See rtems_init.c and setBootConfigFromNVRAM.c in src/libCom/RTEMS.</p>
1162+
1163+<h3>New API to hook into thread creation</h3>
1164+
1165+<p>A hook API has been added allowing user-supplied functions to be called
1166+whenever a thread starts. The calls are made from the thread's context,
1167+and can be used to control additional thread properties not handled inside
1168+EPICS base, e.g. setting the scheduling policy or CPU affinity (on SMP
1169+systems).</p>
1170+
1171+<p>The API also supports a mapping operation, calling a user-supplied function
1172+for every thread that is currently running.</p>
1173+
1174+<h3>New scan rate units</h3>
1175+
1176+<p>Scan rates defined in the menuScan.dbd file may now be specified in seconds,
1177+minutes, hours or Hertz, and plural time units will also be accepted (seconds
1178+are used if no unit is mentioned in the choice string). At <tt>iocInit</tt> each
1179+scan rate is compared with the OS's clock tick and a warning printed if the
1180+rate is too fast or likely to be more than 10% different to the requested rate.
1181+For example the rates given below are all valid, although non-standard (the
1182+default menuScan choices that come with Base have not been changed):</p>
1183+
1184+<blockquote>
1185+<pre>menu(menuScan) {
1186+ choice(menuScanPassive, "Passive")
1187+ choice(menuScanEvent, "Event")
1188+ choice(menuScanI_O_Intr, "I/O Intr")
1189+ choice(menuScan1_hour, "1 hour")
1190+ choice(menuScan0_5_hours, "0.5 hours")
1191+ choice(menuScan15_minutes, "15 minutes")
1192+ choice(menuScan5_minutes, "5 minutes")
1193+ choice(menuScan1_minute, "1 minute")
1194+ choice(menuScan10_seconds, "10 seconds")
1195+ choice(menuScan5_seconds, "5 seconds")
1196+ choice(menuScan2_seconds, "2 seconds")
1197+ choice(menuScan1_second, "1 second")
1198+ choice(menuScan2_Hertz, "2 Hertz")
1199+ choice(menuScan5_Hertz, "5 Hertz")
1200+ choice(menuScan10_Hertz, "10 Hz")
1201+}</pre></blockquote>
1202+
1203+<h3>Alarm filtering added to input record types</h3>
1204+
1205+<p>The record types ai, calc, longin and mbbi have a new alarm filter added to
1206+them. This provides a low-pass filter that can be used to delay the reporting of
1207+alarms caused by the input level passing the HIGH, HIHI, LOW or LOLO values. The
1208+filter is controlled with a new AFTC field that sets the filter's time constant.
1209+The default value for this field is zero, which keeps the record's original
1210+alarm behaviour.</p>
1211+
1212+<p>The record must be scanned often enough for the filtering action to work
1213+effectively and the alarm severity can only change when the record is processed,
1214+but that processing does not have to be regular; the filter uses the time since
1215+the record last processed in its calculation. Setting AFTC to a positive number
1216+of seconds will delay the record going into or out of a minor alarm severity or
1217+from minor to major severity until the input signal has been in that range for
1218+that number of seconds.</p>
1219+
1220+<h3>Post events on Waveform record's NORD field</h3>
1221+
1222+<p>When the record type or device support modify the NORD field of a waveform
1223+record, the record support code now posts DBE_VALUE and DBE_LOG events for that
1224+field, signalling the array length change to any client monitoring the NORD
1225+field.</p>
1226+
1227+<h3>Attributes of Non-VAL Fields</h3>
1228+
1229+<p>Non-VAL fields now report meaningful information for precision, units,
1230+graphic limits, control limits, and alarm limits instead of simply using
1231+PREC, EGU, HOPR, LOPR, DRVL, DRVH, HIHI, HIGH, LOW, and LOLO. All delay
1232+fields have a default precision of 2 digits, units "s" and control limits
1233+of 0 to 100,000 seconds (these precision and limit values can be changed
1234+for each record type as a whole at runtime by updating a registered global
1235+variable). Input fields like A-L of the calc record read their metadata
1236+from the corresponding INPn link if possible.</p>
1237+<h4>epicsStdioRedirect.h merged into epicsStdio.h</h4>
1238+
1239+<p>The definitions from the header file epicsStdioRedirect.h have been moved
1240+into epicsStdio.h so all calls to printf(), puts() and putchar() in files that
1241+include that OSI header will now be subject to stdout redirection. In past
1242+releases (3.14.7 and later) it was necessary to request the redirection support
1243+by including the epicsStdioRedirect.h header file. The header file is still
1244+provided, but now it just includes epicsStdio.h.</p>
1245+
1246+<h4>Named Soft Events</h4>
1247+
1248+<p>Soft events can now be given meaningful names instead of just using the
1249+numbers 1-255. The EVNT field is now a DBF_STRING. The <tt>post_event()</tt> API
1250+is now deprecated but still works. It should be replaced by code that in advance
1251+looks up the <tt>EVNTPVT</tt> event handle associated with the named event by
1252+calling <tt>eventNameToHandle(char *)</tt>, and when that event occurs passes
1253+that handle to the new <tt>postEvent(EVNTPVT)</tt> routine (which may be called
1254+from interrupt level). A new iocsh command <tt>postEvent <i>name</i></tt> will
1255+trigger a named event from the command-line or a startup script (on vxWorks the
1256+expression <tt>postEvent(eventNameToHandle("<i>name</i>"))</tt> must be used
1257+instead though).</p>
1258+
1259+<h4>Parallel Builds</h4>
1260+
1261+<p>
1262+As EPICS sites get computers with more CPUs they report additional bugs in our
1263+parallel build rules. Various issues have been fixed by separating out the build
1264+rules that generate dependency (.d) files, ensuring that they are constructed at
1265+the appropriate time in the build.</p>
1266+
1267+<p>
1268+These rule changes can cause additional warning messages to appear when building
1269+support modules. Where an application provides its own Makefile rules it may now
1270+have to add rules to construct an associated dependency file. In many cases
1271+though the change needed is just to replace a dependency for a
1272+<tt>target$(OBJ)</tt> with the <tt>target$(DEP)</tt> so this</p>
1273+
1274+<pre>
1275+ myLib$(OBJ): myLib_lex.c</pre>
1276+
1277+<p>
1278+becomes</p>
1279+
1280+<pre>
1281+ myLib$(DEP): myLib_lex.c</pre>
1282+
1283+<p>
1284+To debug build issues assocated with dependency files, use the command <tt>make
1285+--debug=m</tt> which tells GNUmake to display information about what it is doing
1286+during the first pass when it updates its makefiles.</p>
1287+
1288+<h3>
1289+Removed tsDefs.h</h3>
1290+
1291+<p>
1292+The deprecated tsDefs API was provided for 3.13 compatibility only, and has now
1293+been removed. Convert any remaining code that used it to call the epicsTime API
1294+instead.</p>
1295+
1296+<h3>
1297+Changes to epicsVersion.h</h3>
1298+
1299+<p>
1300+The two macros <tt>EPICS_UPDATE_LEVEL</tt> and <tt>EPICS_CVS_SNAPSHOT</tt> have
1301+been deleted from the epicsVersion.h file; they were deprecated in R3.14 and can
1302+be replaced with <tt>EPICS_PATCH_LEVEL</tt> and <tt>EPICS_DEV_SNAPSHOT</tt>
1303+respectively.</p>
1304+
1305+<p>
1306+A new pair of macros has been added to make version number comparisons easier.
1307+Code that will not work with a version of Base before 3.15.0 can now be
1308+written like this to prevent it from compiling:</p>
1309+
1310+<pre style="margin: 0 2em;">
1311+#if defined(VERSION_INT) &amp;&amp; EPICS_VERSION_INT &lt; VERSION_INT(3,15,0,0)
1312+# error EPICS Base R3.15.0 or later is required
1313+#endif
1314+</pre>
1315+
1316+<h3>
1317+Added support for iocLogPrefix</h3>
1318+
1319+<p>
1320+Added a <code>iocLogPrefix</code> command to <code>iocsh</code>. This adds a
1321+prefix to all messages from this IOC (or other log client) as they get sent to the
1322+iocLogServer. This lets sites use the "fac=&lt;<i>facility</i>&gt;" syntax for
1323+displaying the facility, process name etc. in log viewers like the
1324+<code>cmlogviewer</code>.</p>
1325+
1326+<h3>
1327+Reworked the epicsEvent C &amp; C++ APIs</h3>
1328+
1329+<ul>
1330+ <li>Renamed the enum epicsEventWaitStatus to epicsEventStatus</li>
1331+ <li>Defined epicsEventWaitStatus as a macro for epicsEventStatus</li>
1332+ <li>Renamed epicsEventWaitOk to epicsEventOk</li>
1333+ <li>Renamed epicsEventWaitError to epicsEventError</li>
1334+ <li>Defined epicsEventWaitOK and epicsEventWaitError as macros</li>
1335+ <li>Added epicsEventTrigger(id) which triggers an event and returns OK or an
1336+ error status if the underlying OS primitives report an error</li>
1337+ <li>Added epicsEventMustTrigger(id) which halts on error</li>
1338+ <li>Defined epicsEventSignal(id) as a macro for epicsEventMustTrigger(id)</li>
1339+ <li>Added a new C++ method epicsEvent::trigger() which throws an
1340+ epicsEvent::invalidSemaphore in the event of an error</li>
1341+ <li>epicsEvent::signal() makes an inline call to epicsEvent::trigger()</li>
1342+ <li>epicsEventWait() and epicsEventWaitWithTimeout() now return an error
1343+ status if the underlying OS primitives report an error</li>
1344+ <li>All the epicsEventMust...() routines are now implemented in the common
1345+ libCom/osi/epicsEvent.cpp source file, and call cantProceed() instead of
1346+ mis-using assert()</li>
1347+ <li>Implemented epicsEventShow() on Posix</li>
1348+ <li>Win32: Removed all epicsShareAPI decorations</li>
1349+</ul>
1350+
1351+<h3>
1352+Enabled histogram record type</h3>
1353+
1354+<p>
1355+The histogram record was not included in the base.dbd file in any 3.14 release,
1356+but has now been added along with its associated soft device support. The build
1357+system now generates the list of all the record.dbd files in base automatically
1358+in src/std/rec/Makefile.</p>
1359+
1360+<h3>
1361+Reorganization of src/</h3>
1362+
1363+<p>Reorganization of subdirectories of src/ to better represent the relation
1364+between different parts as described in the following table.</p>
1365+
1366+<p>This change also allows the number of libraries built to be reduced to:
1367+libCap5.so, libca.so, libdbCore.so, libdbStaticHost.so,
1368+libCom.so, libcas.so, libdbRecStd.so, and libgdd.so</p>
1369+
1370+<table border="1"><tbody>
1371+<tr>
1372+ <th>Component</th>
1373+ <th>Dependency</th>
1374+ <th>Library name</th>
1375+ <th>Description</th>
1376+</tr>
1377+<tr>
1378+ <td>src/tools</td>
1379+ <td></td>
1380+ <td></td>
1381+ <td>Build system scripts</td>
1382+</tr>
1383+<tr>
1384+ <td>src/libCom</td>
1385+ <td>src/tools</td>
1386+ <td>Com</td>
1387+ <td>Utility routines and OS-independant API</td>
1388+</tr>
1389+<tr>
1390+ <td>src/template</td>
1391+ <td>src/tools</td>
1392+ <td></td>
1393+ <td>User application templates (e.g. makeBaseApp)</td>
1394+</tr>
1395+<tr>
1396+ <td>src/ca/client</td>
1397+ <td>src/libCom</td>
1398+ <td>ca</td>
1399+ <td>Channel Access client</td>
1400+</tr>
1401+<tr>
1402+ <td>src/ca/legacy/gdd</td>
1403+ <td>src/ca/client</td>
1404+ <td>gdd</td>
1405+ <td>Generic data layer for PCAS</td>
1406+</tr>
1407+<tr>
1408+ <td>src/ca/legacy/pcas</td>
1409+ <td>src/ca/legacy/gdd</td>
1410+ <td>cas</td>
1411+ <td>Portable Channel Access Server</td>
1412+</tr>
1413+<tr>
1414+ <td>src/ioc</td>
1415+ <td>src/ca</td>
1416+ <td>dbCore</td>
1417+ <td>Core database processing functions</td>
1418+</tr>
1419+<tr>
1420+ <td>src/std</td>
1421+ <td>src/ioc</td>
1422+ <td>dbRecStd</td>
1423+ <td>Standard records, soft device support and the softIoc </td>
1424+</tr>
1425+</tbody></table>
1426+
1427+<p>
1428+In order to better reflect these relations the following
1429+directories and files were moved as described:</p>
1430+
1431+<table border="1"><tbody>
1432+<tr>
1433+ <th colspan="2">Relocations</th>
1434+</tr>
1435+<tr>
1436+ <th>Previous</th><th>New</th>
1437+</tr>
1438+<tr>
1439+ <th colspan="2">libCom</th>
1440+</tr>
1441+<tr>
1442+ <td>src/RTEMS</td>
1443+ <td>src/libCom/RTEMS</td>
1444+</tr>
1445+<tr>
1446+ <td>src/toolsComm/flex</td>
1447+ <td>src/libCom/flex</td>
1448+</tr>
1449+<tr>
1450+ <td>src/toolsComm/antelope</td>
1451+ <td>src/libCom/yacc</td>
1452+</tr>
1453+<tr>
1454+ <td align="right">src/dbStatic/alarm.h<br>.../alarmString.h</td>
1455+ <td>src/libCom/misc/</td>
1456+</tr>
1457+<tr>
1458+ <th colspan="2">IOC Core Components</th>
1459+</tr>
1460+<tr>
1461+ <td>src/bpt</td>
1462+ <td>src/ioc/bpt</td>
1463+</tr>
1464+<tr>
1465+ <td>src/db</td>
1466+ <td>src/ioc/db</td>
1467+</tr>
1468+<tr>
1469+ <td>src/dbStatic</td>
1470+ <td>src/ioc/dbStatic</td>
1471+</tr>
1472+<tr>
1473+ <td>src/dbtools</td>
1474+ <td>src/ioc/dbtemplate</td>
1475+</tr>
1476+<tr>
1477+ <td>src/misc</td>
1478+ <td>src/ioc/misc</td>
1479+</tr>
1480+<tr>
1481+ <td>src/registry</td>
1482+ <td>src/ioc/registry</td>
1483+</tr>
1484+<tr>
1485+ <td>src/rsrv</td>
1486+ <td>src/ioc/rsrv <a href="#rsrv">1</a></td>
1487+</tr>
1488+<tr>
1489+ <th colspan="2">Standard Record Definitions</th>
1490+</tr>
1491+<tr>
1492+ <td>src/dev/softDev</td>
1493+ <td>src/std/dev</td>
1494+</tr>
1495+<tr>
1496+ <td>src/rec</td>
1497+ <td>src/std/rec</td>
1498+</tr>
1499+<tr>
1500+ <td>src/softIoc</td>
1501+ <td>src/std/softIoc</td>
1502+</tr>
1503+<tr>
1504+ <th colspan="2">Channel Access</th>
1505+</tr>
1506+<tr>
1507+ <td>src/ca</td>
1508+ <td>src/ca/client</td>
1509+</tr>
1510+<tr>
1511+ <td>src/catools</td>
1512+ <td>src/ca/client/tools</td>
1513+</tr>
1514+<tr>
1515+ <td>src/cap5</td>
1516+ <td>src/ca/client/perl</td>
1517+</tr>
1518+<tr>
1519+ <td>src/gdd</td>
1520+ <td>src/ca/legacy/gdd</td>
1521+</tr>
1522+<tr>
1523+ <td>src/cas</td>
1524+ <td>src/ca/legacy/pcas</td>
1525+</tr>
1526+<tr>
1527+ <td>src/excas</td>
1528+ <td>src/ca/legacy/pcas/ex</td>
1529+</tr>
1530+<tr>
1531+ <th colspan="2">User Templates</th>
1532+</tr>
1533+<tr>
1534+ <td>src/makeBaseApp</td>
1535+ <td>src/template/base</td>
1536+</tr>
1537+<tr>
1538+ <td>src/makeBaseExt</td>
1539+ <td>src/template/ext</td>
1540+</tr>
1541+<tr>
1542+ <th colspan="2">Dispersed</th>
1543+</tr>
1544+<tr>
1545+ <td rowspan="3">src/util <a href="#util">2</a></td>
1546+ <td>src/ca/client</td>
1547+</tr>
1548+<tr>
1549+ <td>src/ca/client/test</td>
1550+</tr>
1551+<tr>
1552+ <td>src/libCom/log</td>
1553+</tr>
1554+<tr>
1555+ <td rowspan="2">src/as <a href="#as">3</a></td>
1556+ <td>src/libCom/as</td>
1557+</tr>
1558+<tr>
1559+ <td>src/ioc/as</td>
1560+</tr>
1561+</tbody></table>
1562+
1563+<p><a name="rsrv">1</a>
1564+RSRV is built as part of dbCore due to its tight (bidirectional) coupling
1565+with the other database code.</p>
1566+
1567+<p><a name="util">2</a>
1568+The contents for src/util/ moved to three locations. The caRepeater init script
1569+was moved to src/ca/client/. ca_test is now in src/ca/client/test/.
1570+The iocLogServer was moved into the same directory (src/libCom/log) as
1571+the log client code.</p>
1572+
1573+<p><a name="as">3</a>
1574+The Access Security code has been divided, with the parts not related to the
1575+database (lexer/parser and trap registration) becoming part of libCom.
1576+The remaining components are included in the dbCore library</p>
1577+
1578+<h3>
1579+Moved src/RTEMS/base directory</h3>
1580+
1581+<p>
1582+These files are now found under src/RTEMS.</p>
1583+
1584+<h3>
1585+Removed 3.13 compatibility</h3>
1586+
1587+<p>
1588+Removed the 3.13 &lt;top&gt;/config directory and build compatibility rules and
1589+variables, and various conversion documents.</p>
1590+
1591+>>>>>>> MERGE-SOURCE
1592 </body>
1593 </html>
1594
1595=== modified file 'documentation/ReleaseChecklist.html'
1596=== modified file 'src/ca/client/Makefile'
1597=== modified file 'src/ca/legacy/gdd/gddAppTable.cc'
1598--- src/ca/legacy/gdd/gddAppTable.cc 2016-05-22 12:38:18 +0000
1599+++ src/ca/legacy/gdd/gddAppTable.cc 2016-10-12 09:08:28 +0000
1600@@ -418,8 +418,10 @@
1601 }
1602
1603 // fprintf(stderr,"Adding DD to free_list %d\n",app);
1604+ attr_table[group][app].sem.lock ();
1605 dd->setNext(attr_table[group][app].free_list);
1606 attr_table[group][app].free_list=dd;
1607+ attr_table[group][app].sem.unlock ();
1608 }
1609 else if (attr_table[group][app].type==gddApplicationTypeNormal)
1610 {
1611
1612=== modified file 'src/ca/legacy/pcas/generic/caHdrLargeArray.h'
1613--- src/ca/legacy/pcas/generic/caHdrLargeArray.h 2016-05-22 03:43:09 +0000
1614+++ src/ca/legacy/pcas/generic/caHdrLargeArray.h 2016-10-12 09:08:28 +0000
1615@@ -30,7 +30,7 @@
1616 # include "shareLib.h"
1617 #endif
1618
1619-static const unsigned char CA_MINOR_PROTOCOL_REVISION = 12;
1620+static const unsigned char CA_MINOR_PROTOCOL_REVISION = 13;
1621
1622 typedef ca_uint32_t caResId;
1623
1624
1625=== modified file 'src/ca/legacy/pcas/generic/casDGClient.cc'
1626--- src/ca/legacy/pcas/generic/casDGClient.cc 2016-09-07 15:04:54 +0000
1627+++ src/ca/legacy/pcas/generic/casDGClient.cc 2016-10-12 09:08:28 +0000
1628@@ -346,10 +346,13 @@
1629 //
1630 caStatus casDGClient::searchFailResponse ( const caHdrLargeArray * mp )
1631 {
1632+<<<<<<< TREE
1633 caStatus status;
1634
1635+=======
1636+>>>>>>> MERGE-SOURCE
1637 epicsGuard < epicsMutex > guard ( this->mutex );
1638- status = this->out.copyInHeader ( CA_PROTO_NOT_FOUND, 0,
1639+ this->out.copyInHeader ( CA_PROTO_NOT_FOUND, 0,
1640 mp->m_dataType, mp->m_count, mp->m_cid, mp->m_available, 0 );
1641
1642 if ( status == S_cas_success ) {
1643
1644=== modified file 'src/ca/legacy/pcas/generic/casStrmClient.cc'
1645--- src/ca/legacy/pcas/generic/casStrmClient.cc 2014-05-30 17:36:50 +0000
1646+++ src/ca/legacy/pcas/generic/casStrmClient.cc 2016-10-12 09:08:28 +0000
1647@@ -388,7 +388,7 @@
1648 //
1649 // casStrmClient::verifyRequest()
1650 //
1651-caStatus casStrmClient::verifyRequest ( casChannelI * & pChan )
1652+caStatus casStrmClient::verifyRequest ( casChannelI * & pChan, bool allowZeroCount )
1653 {
1654 const caHdrLargeArray * mp = this->ctx.getMsg();
1655
1656@@ -411,7 +411,8 @@
1657 //
1658 // element count out of range ?
1659 //
1660- if ( mp->m_count > pChan->getPVI().nativeCount() || mp->m_count == 0u ) {
1661+ if ( mp->m_count > pChan->getPVI().nativeCount() ||
1662+ ( !allowZeroCount && mp->m_count == 0u ) ) {
1663 return ECA_BADCOUNT;
1664 }
1665
1666@@ -444,7 +445,7 @@
1667 casChannelI * pChan;
1668
1669 {
1670- caStatus status = this->verifyRequest ( pChan );
1671+ caStatus status = this->verifyRequest ( pChan, CA_V413 ( this->minor_version_number ) );
1672 if ( status != ECA_NORMAL ) {
1673 if ( pChan ) {
1674 return this->sendErr ( guard, mp, pChan->getCID(),
1675@@ -531,11 +532,15 @@
1676 pChan->getCID(), status, ECA_GETFAIL );
1677 }
1678
1679+ ca_uint32_t count = (msg.m_count == 0) ?
1680+ (ca_uint32_t)desc.getDataSizeElements() :
1681+ msg.m_count;
1682+
1683 void * pPayload;
1684 {
1685- unsigned payloadSize = dbr_size_n ( msg.m_dataType, msg.m_count );
1686+ unsigned payloadSize = dbr_size_n ( msg.m_dataType, count );
1687 caStatus localStatus = this->out.copyInHeader ( msg.m_cmmd, payloadSize,
1688- msg.m_dataType, msg.m_count, pChan->getCID (),
1689+ msg.m_dataType, count, pChan->getCID (),
1690 msg.m_available, & pPayload );
1691 if ( localStatus ) {
1692 if ( localStatus==S_cas_hugeRequest ) {
1693@@ -551,21 +556,21 @@
1694 // (places the data in network format)
1695 //
1696 int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr(
1697- pPayload, msg.m_count, desc, pChan->enumStringTable() );
1698+ pPayload, count, desc, pChan->enumStringTable() );
1699 if ( mapDBRStatus < 0 ) {
1700 desc.dump ();
1701 errPrintf ( S_cas_badBounds, __FILE__, __LINE__, "- get with PV=%s type=%u count=%u",
1702- pChan->getPVI().getName(), msg.m_dataType, msg.m_count );
1703+ pChan->getPVI().getName(), msg.m_dataType, count );
1704 return this->sendErrWithEpicsStatus (
1705 guard, & msg, pChan->getCID(), S_cas_badBounds, ECA_GETFAIL );
1706 }
1707 int cacStatus = caNetConvert (
1708- msg.m_dataType, pPayload, pPayload, true, msg.m_count );
1709+ msg.m_dataType, pPayload, pPayload, true, count );
1710 if ( cacStatus != ECA_NORMAL ) {
1711 return this->sendErrWithEpicsStatus (
1712 guard, & msg, pChan->getCID(), S_cas_internal, cacStatus );
1713 }
1714- if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) {
1715+ if ( msg.m_dataType == DBR_STRING && count == 1u ) {
1716 unsigned reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u;
1717 this->out.commitMsg ( reducedPayloadSize );
1718 }
1719@@ -585,7 +590,7 @@
1720 casChannelI * pChan;
1721
1722 {
1723- caStatus status = this->verifyRequest ( pChan );
1724+ caStatus status = this->verifyRequest ( pChan, CA_V413 ( this->minor_version_number ) );
1725 if ( status != ECA_NORMAL ) {
1726 return this->readNotifyFailureResponse ( guard, * mp, status );
1727 }
1728@@ -655,12 +660,16 @@
1729 guard, msg, ECA_GETFAIL );
1730 return ecaStatus;
1731 }
1732+
1733+ ca_uint32_t count = (msg.m_count == 0) ?
1734+ (ca_uint32_t)desc.getDataSizeElements() :
1735+ msg.m_count;
1736
1737 void *pPayload;
1738 {
1739- unsigned size = dbr_size_n ( msg.m_dataType, msg.m_count );
1740+ unsigned size = dbr_size_n ( msg.m_dataType, count );
1741 caStatus status = this->out.copyInHeader ( msg.m_cmmd, size,
1742- msg.m_dataType, msg.m_count, ECA_NORMAL,
1743+ msg.m_dataType, count, ECA_NORMAL,
1744 msg.m_available, & pPayload );
1745 if ( status ) {
1746 if ( status == S_cas_hugeRequest ) {
1747@@ -675,23 +684,23 @@
1748 // convert gdd to db_access type
1749 //
1750 int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr ( pPayload,
1751- msg.m_count, desc, pChan->enumStringTable() );
1752+ count, desc, pChan->enumStringTable() );
1753 if ( mapDBRStatus < 0 ) {
1754 desc.dump();
1755 errPrintf ( S_cas_badBounds, __FILE__, __LINE__,
1756 "- get notify with PV=%s type=%u count=%u",
1757- pChan->getPVI().getName(), msg.m_dataType, msg.m_count );
1758+ pChan->getPVI().getName(), msg.m_dataType, count );
1759 return this->readNotifyFailureResponse ( guard, msg, ECA_NOCONVERT );
1760 }
1761
1762 int cacStatus = caNetConvert (
1763- msg.m_dataType, pPayload, pPayload, true, msg.m_count );
1764+ msg.m_dataType, pPayload, pPayload, true, count );
1765 if ( cacStatus != ECA_NORMAL ) {
1766 return this->sendErrWithEpicsStatus (
1767 guard, & msg, pChan->getCID(), S_cas_internal, cacStatus );
1768 }
1769
1770- if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) {
1771+ if ( msg.m_dataType == DBR_STRING && count == 1u ) {
1772 unsigned reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u;
1773 this->out.commitMsg ( reducedPayloadSize );
1774 }
1775@@ -849,11 +858,15 @@
1776 casChannelI & chan, const caHdrLargeArray & msg,
1777 const gdd & desc, const caStatus completionStatus )
1778 {
1779+ ca_uint32_t count = (msg.m_count == 0) ?
1780+ (ca_uint32_t)desc.getDataSizeElements() :
1781+ msg.m_count;
1782+
1783 void * pPayload = 0;
1784 {
1785- ca_uint32_t size = dbr_size_n ( msg.m_dataType, msg.m_count );
1786+ ca_uint32_t size = dbr_size_n ( msg.m_dataType, count );
1787 caStatus status = out.copyInHeader ( msg.m_cmmd, size,
1788- msg.m_dataType, msg.m_count, ECA_NORMAL,
1789+ msg.m_dataType, count, ECA_NORMAL,
1790 msg.m_available, & pPayload );
1791 if ( status ) {
1792 if ( status == S_cas_hugeRequest ) {
1793@@ -871,7 +884,7 @@
1794
1795 gdd * pDBRDD = 0;
1796 if ( completionStatus == S_cas_success ) {
1797- caStatus status = createDBRDD ( msg.m_dataType, msg.m_count, pDBRDD );
1798+ caStatus status = createDBRDD ( msg.m_dataType, count, pDBRDD );
1799 if ( status != S_cas_success ) {
1800 caStatus ecaStatus;
1801 if ( status == S_cas_badType ) {
1802@@ -892,7 +905,7 @@
1803 pDBRDD->unreference ();
1804 errPrintf ( S_cas_noConvert, __FILE__, __LINE__,
1805 "no conversion between event app type=%d and DBR type=%d Element count=%d",
1806- desc.applicationType (), msg.m_dataType, msg.m_count);
1807+ desc.applicationType (), msg.m_dataType, count);
1808 return monitorFailureResponse ( guard, msg, ECA_NOCONVERT );
1809 }
1810 }
1811@@ -915,14 +928,14 @@
1812 }
1813
1814 int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr (
1815- pPayload, msg.m_count, *pDBRDD, chan.enumStringTable() );
1816+ pPayload, count, *pDBRDD, chan.enumStringTable() );
1817 if ( mapDBRStatus < 0 ) {
1818 pDBRDD->unreference ();
1819 return monitorFailureResponse ( guard, msg, ECA_NOCONVERT );
1820 }
1821
1822 int cacStatus = caNetConvert (
1823- msg.m_dataType, pPayload, pPayload, true, msg.m_count );
1824+ msg.m_dataType, pPayload, pPayload, true, count );
1825 if ( cacStatus != ECA_NORMAL ) {
1826 pDBRDD->unreference ();
1827 return this->sendErrWithEpicsStatus (
1828@@ -932,7 +945,7 @@
1829 //
1830 // force string message size to be the true size
1831 //
1832- if ( msg.m_dataType == DBR_STRING && msg.m_count == 1u ) {
1833+ if ( msg.m_dataType == DBR_STRING && count == 1u ) {
1834 ca_uint32_t reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u;
1835 this->out.commitMsg ( reducedPayloadSize );
1836 }
1837@@ -1940,7 +1953,7 @@
1838
1839 casChannelI *pciu;
1840 {
1841- caStatus status = casStrmClient::verifyRequest ( pciu );
1842+ caStatus status = casStrmClient::verifyRequest ( pciu, CA_V413 ( this->minor_version_number ) );
1843 if ( status != ECA_NORMAL ) {
1844 if ( pciu ) {
1845 return this->sendErr ( guard, mp,
1846@@ -2599,10 +2612,14 @@
1847 {
1848 const caHdrLargeArray * pHdr = this->ctx.getMsg();
1849
1850+ ca_uint32_t count = pHdr->m_count;
1851+ if ( count == 0 ) {
1852+ count = this->ctx.getChannel()->getPVI().nativeCount();
1853+ }
1854+
1855 {
1856 gdd * pDD = 0;
1857- caStatus status = createDBRDD ( pHdr->m_dataType,
1858- pHdr->m_count, pDD );
1859+ caStatus status = createDBRDD ( pHdr->m_dataType, count, pDD );
1860 if ( status != S_cas_success ) {
1861 return status;
1862 }
1863
1864=== modified file 'src/ca/legacy/pcas/generic/casStrmClient.h'
1865--- src/ca/legacy/pcas/generic/casStrmClient.h 2010-08-10 21:05:46 +0000
1866+++ src/ca/legacy/pcas/generic/casStrmClient.h 2016-10-12 09:08:28 +0000
1867@@ -69,7 +69,7 @@
1868 bool responseIsPending;
1869
1870 caStatus createChannel ( const char * pName );
1871- caStatus verifyRequest ( casChannelI * & pChan );
1872+ caStatus verifyRequest ( casChannelI * & pChan, bool allowZeroCount = false );
1873 typedef caStatus ( casStrmClient :: * pCASMsgHandler )
1874 ( epicsGuard < casClientMutex > & );
1875 static pCASMsgHandler const msgHandlers[CA_PROTO_LAST_CMMD+1u];
1876
1877=== modified file 'src/ioc/db/callback.h'
1878=== modified file 'src/ioc/db/dbAccess.c'
1879=== modified file 'src/ioc/db/dbCAC.h'
1880=== modified file 'src/ioc/db/dbCa.c'
1881=== modified file 'src/ioc/db/dbChannelIO.h'
1882=== modified file 'src/ioc/db/dbCommon.dbd'
1883=== modified file 'src/ioc/db/dbContext.cpp'
1884=== modified file 'src/ioc/db/dbContextReadNotifyCache.cpp'
1885=== modified file 'src/ioc/db/dbLink.c'
1886=== modified file 'src/ioc/db/dbNotify.c'
1887=== modified file 'src/ioc/db/dbScan.c'
1888--- src/ioc/db/dbScan.c 2015-09-07 04:15:21 +0000
1889+++ src/ioc/db/dbScan.c 2016-10-12 09:08:28 +0000
1890@@ -989,13 +989,13 @@
1891 pse->precord = precord;
1892 }
1893 pse->pscan_list = psl;
1894- ptemp = (scan_element *)ellFirst(&psl->list);
1895+ ptemp = (scan_element *)ellLast(&psl->list);
1896 while (ptemp) {
1897- if (ptemp->precord->phas > precord->phas) {
1898- ellInsert(&psl->list, ellPrevious(&ptemp->node), &pse->node);
1899+ if (ptemp->precord->phas <= precord->phas) {
1900+ ellInsert(&psl->list, &ptemp->node, &pse->node);
1901 break;
1902 }
1903- ptemp = (scan_element *)ellNext(&ptemp->node);
1904+ ptemp = (scan_element *)ellPrevious(&ptemp->node);
1905 }
1906 if (ptemp == NULL) ellAdd(&psl->list, (void *)pse);
1907 psl->modified = TRUE;
1908
1909=== modified file 'src/ioc/db/dbScan.h'
1910=== modified file 'src/ioc/db/recGbl.c'
1911=== added file 'src/ioc/db/templateInstances.cpp.OTHER'
1912--- src/ioc/db/templateInstances.cpp.OTHER 1970-01-01 00:00:00 +0000
1913+++ src/ioc/db/templateInstances.cpp.OTHER 2016-10-12 09:08:28 +0000
1914@@ -0,0 +1,36 @@
1915+/*************************************************************************\
1916+* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
1917+* National Laboratory.
1918+* Copyright (c) 2002 The Regents of the University of California, as
1919+* Operator of Los Alamos National Laboratory.
1920+* EPICS BASE Versions 3.13.7
1921+* and higher are distributed subject to a Software License Agreement found
1922+* in file LICENSE that is included with this distribution.
1923+\*************************************************************************/
1924+
1925+/*
1926+ * Author Jeffrey O. Hill
1927+ * johill@lanl.gov
1928+ * 505 665 1831
1929+ */
1930+
1931+#define epicsExportSharedSymbols
1932+
1933+#include "dbCAC.h"
1934+#include "dbChannelIO.h"
1935+#include "dbPutNotifyBlocker.h"
1936+
1937+#ifdef _MSC_VER
1938+# pragma warning ( push )
1939+# pragma warning ( disable:4660 )
1940+#endif
1941+
1942+template class tsFreeList < dbChannelIO, 256, epicsMutexNOOP >;
1943+template class tsFreeList < dbPutNotifyBlocker, 64, epicsMutexNOOP >;
1944+template class tsFreeList < dbSubscriptionIO, 256, epicsMutexNOOP >;
1945+template class resTable < dbBaseIO, chronIntId >;
1946+template class chronIntIdResTable < dbBaseIO >;
1947+
1948+#ifdef _MSC_VER
1949+# pragma warning ( pop )
1950+#endif
1951
1952=== modified file 'src/ioc/dbStatic/dbBase.h'
1953--- src/ioc/dbStatic/dbBase.h 2016-09-07 15:04:54 +0000
1954+++ src/ioc/dbStatic/dbBase.h 2016-10-12 09:08:28 +0000
1955@@ -133,25 +133,25 @@
1956 }dbVariableDef;
1957
1958 typedef struct dbRecordType {
1959- ELLNODE node;
1960- ELLLIST attributeList; /*LIST head of attributes*/
1961- ELLLIST recList; /*LIST head of sorted dbRecordNodes*/
1962- ELLLIST devList; /*List of associated device support*/
1963- ELLLIST cdefList; /*LIST of Cdef text items*/
1964- char *name;
1965- short no_fields; /* number of fields defined */
1966- short no_prompt; /* number of fields to configure*/
1967- short no_links; /* number of links */
1968- short no_aliases; /* number of aliases in recList */
1969- short *link_ind; /* addr of array of ind in papFldDes*/
1970- char **papsortFldName;/* ptr to array of ptr to fld names*/
1971- short *sortFldInd; /* addr of array of ind in papFldDes*/
1972- dbFldDes *pvalFldDes; /*pointer dbFldDes for VAL field*/
1973- short indvalFlddes; /*ind in papFldDes*/
1974- dbFldDes **papFldDes; /* ptr to array of ptr to fldDes*/
1975- /*The following are only available on run time system*/
1976- struct rset *prset;
1977- int rec_size; /*record size in bytes */
1978+ ELLNODE node;
1979+ ELLLIST attributeList; /*LIST head of attributes*/
1980+ ELLLIST recList; /*LIST head of sorted dbRecordNodes*/
1981+ ELLLIST devList; /*List of associated device support*/
1982+ ELLLIST cdefList; /*LIST of Cdef text items*/
1983+ char *name;
1984+ short no_fields; /* number of fields defined */
1985+ short no_prompt; /* number of fields to configure*/
1986+ short no_links; /* number of links */
1987+ short no_aliases; /* number of aliases in recList */
1988+ short *link_ind; /* addr of array of ind in papFldDes*/
1989+ char **papsortFldName;/* ptr to array of ptr to fld names*/
1990+ short *sortFldInd; /* addr of array of ind in papFldDes*/
1991+ dbFldDes *pvalFldDes; /*pointer dbFldDes for VAL field*/
1992+ short indvalFlddes; /*ind in papFldDes*/
1993+ dbFldDes **papFldDes; /* ptr to array of ptr to fldDes*/
1994+ /*The following are only available on run time system*/
1995+ struct rset *prset;
1996+ int rec_size; /*record size in bytes */
1997 }dbRecordType;
1998
1999 struct dbPvd; /* Contents private to dbPvdLib code */
2000
2001=== modified file 'src/ioc/dbStatic/dbLexRoutines.c'
2002--- src/ioc/dbStatic/dbLexRoutines.c 2016-09-07 15:04:54 +0000
2003+++ src/ioc/dbStatic/dbLexRoutines.c 2016-10-12 09:08:28 +0000
2004@@ -50,6 +50,9 @@
2005 epicsShareDef int dbQuietMacroWarnings=0;
2006 epicsExportAddress(int,dbQuietMacroWarnings);
2007
2008+epicsShareDef int dbRecordsAbcSorted=0;
2009+epicsExportAddress(int,dbRecordsAbcSorted);
2010+
2011 /*private routines */
2012 static void yyerrorAbort(char *str);
2013 static void allocTemp(void *pvoid);
2014@@ -194,7 +197,16 @@
2015 free((void *)pinputFileNow);
2016 }
2017 }
2018-
2019
2020+
2021+static
2022+int cmp_dbRecordNode(const ELLNODE *lhs, const ELLNODE *rhs)
2023+{
2024+ dbRecordNode *LHS = (dbRecordNode*)lhs,
2025+ *RHS = (dbRecordNode*)rhs;
2026+
2027+ return strcmp(LHS->recordname, RHS->recordname);
2028+}
2029+
2030 static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
2031 const char *path,const char *substitutions)
2032 {
2033@@ -294,6 +306,15 @@
2034 dbFinishEntry(pdbEntry);
2035 }
2036 cleanup:
2037+ if(dbRecordsAbcSorted) {
2038+ ELLNODE *cur;
2039+ for(cur = ellFirst(&pdbbase->recordTypeList); cur; cur=ellNext(cur))
2040+ {
2041+ dbRecordType *rtype = CONTAINER(cur, dbRecordType, node);
2042+
2043+ ellSortStable(&rtype->recList, &cmp_dbRecordNode);
2044+ }
2045+ }
2046 if(macHandle) macDeleteHandle(macHandle);
2047 macHandle = NULL;
2048 if(mac_input_buffer) free((void *)mac_input_buffer);
2049
2050=== modified file 'src/ioc/dbStatic/dbStaticLib.c'
2051--- src/ioc/dbStatic/dbStaticLib.c 2016-09-07 15:04:54 +0000
2052+++ src/ioc/dbStatic/dbStaticLib.c 2016-10-12 09:08:28 +0000
2053@@ -1418,7 +1418,6 @@
2054 dbFldDes *pdbFldDes;
2055 PVDENTRY *ppvd;
2056 ELLLIST *preclist = NULL;
2057- dbRecordNode *precnode = NULL;
2058 dbRecordNode *pNewRecNode = NULL;
2059 long status = 0;
2060
2061@@ -1426,7 +1425,7 @@
2062 /*Get size of NAME field*/
2063 pdbFldDes = precordType->papFldDes[0];
2064 if(!pdbFldDes || (strcmp(pdbFldDes->name,"NAME")!=0))
2065- return(S_dbLib_nameLength);
2066+ return(S_dbLib_nameLength);
2067 if((int)strlen(precordName)>=pdbFldDes->size) return(S_dbLib_nameLength);
2068 /* clear callers entry */
2069 zeroDbentry(pdbentry);
2070@@ -1441,18 +1440,7 @@
2071 if((status = dbAllocRecord(pdbentry,precordName))) return(status);
2072 pNewRecNode->recordname = dbRecordName(pdbentry);
2073 ellInit(&pNewRecNode->infoList);
2074- /* install record node in list in sorted postion */
2075- status = dbFirstRecord(pdbentry);
2076- while(status==0) {
2077- if(strcmp(precordName,dbGetRecordName(pdbentry)) < 0) break;
2078- status = dbNextRecord(pdbentry);
2079- }
2080- if(status==0) {
2081- precnode = pdbentry->precnode;
2082- ellInsert(preclist,ellPrevious(&precnode->node),&pNewRecNode->node);
2083- } else {
2084- ellAdd(preclist,&pNewRecNode->node);
2085- }
2086+ ellAdd(preclist, &pNewRecNode->node);
2087 pdbentry->precnode = pNewRecNode;
2088 ppvd = dbPvdAdd(pdbentry->pdbbase,precordType,pNewRecNode);
2089 if(!ppvd) {errMessage(-1,"Logic Err: Could not add to PVD");return(-1);}
2090@@ -1630,52 +1618,6 @@
2091 return precnode->recordname;
2092 }
2093
2094-long dbRenameRecord(DBENTRY *pdbentry,const char *newName)
2095-{
2096- dbBase *pdbbase = pdbentry->pdbbase;
2097- dbRecordType *precordType = pdbentry->precordType;
2098- dbFldDes *pdbFldDes;
2099- dbRecordNode *precnode = pdbentry->precnode;
2100- PVDENTRY *ppvd;
2101- ELLLIST *preclist;
2102- dbRecordNode *plistnode;
2103- long status;
2104- DBENTRY dbentry;
2105-
2106- if(!precordType) return(S_dbLib_recordTypeNotFound);
2107- /*Get size of NAME field*/
2108- pdbFldDes = precordType->papFldDes[0];
2109- if(!pdbFldDes || (strcmp(pdbFldDes->name,"NAME")!=0))
2110- return(S_dbLib_nameLength);
2111- if((int)strlen(newName)>=pdbFldDes->size) return(S_dbLib_nameLength);
2112- if (!precnode || dbIsAlias(pdbentry)) return S_dbLib_recNotFound;
2113- dbInitEntry(pdbentry->pdbbase,&dbentry);
2114- status = dbFindRecord(&dbentry,newName);
2115- dbFinishEntry(&dbentry);
2116- if(!status) return(S_dbLib_recExists);
2117- dbPvdDelete(pdbbase,precnode);
2118- pdbentry->pflddes = precordType->papFldDes[0];
2119- if((status = dbGetFieldAddress(pdbentry))) return(status);
2120- strcpy(pdbentry->pfield,newName);
2121- ppvd = dbPvdAdd(pdbbase,precordType,precnode);
2122- if(!ppvd) {errMessage(-1,"Logic Err: Could not add to PVD");return(-1);}
2123- /*remove from record list and reinstall in sorted order*/
2124- preclist = &precordType->recList;
2125- ellDelete(preclist,&precnode->node);
2126- plistnode = (dbRecordNode *)ellFirst(preclist);
2127- while(plistnode) {
2128- pdbentry->precnode = plistnode;
2129- if(strcmp(newName,dbGetRecordName(pdbentry)) >=0) break;
2130- plistnode = (dbRecordNode *)ellNext(&plistnode->node);
2131- }
2132- if(plistnode)
2133- ellInsert(preclist,ellPrevious(&plistnode->node),&precnode->node);
2134- else
2135- ellAdd(preclist,&precnode->node);
2136- /*Leave pdbentry pointing to newly renamed record*/
2137- return(dbFindRecord(pdbentry,newName));
2138-}
2139-
2140 long dbVisibleRecord(DBENTRY *pdbentry)
2141 {
2142 dbRecordNode *precnode = pdbentry->precnode;
2143@@ -1709,7 +1651,6 @@
2144 dbRecordNode *pnewnode;
2145 PVDENTRY *ppvd;
2146 ELLLIST *preclist = NULL;
2147- long status;
2148
2149 if (!precordType) return S_dbLib_recordTypeNotFound;
2150 if (!precnode) return S_dbLib_recNotFound;
2151@@ -1725,18 +1666,7 @@
2152 if (!(precnode->flags & DBRN_FLAGS_ISALIAS))
2153 precnode->flags |= DBRN_FLAGS_HASALIAS;
2154 ellInit(&pnewnode->infoList);
2155- /* install record node in list in sorted postion */
2156- status = dbFirstRecord(pdbentry);
2157- while (!status) {
2158- if (strcmp(alias, dbGetRecordName(pdbentry)) < 0) break;
2159- status = dbNextRecord(pdbentry);
2160- }
2161- if (!status) {
2162- precnode = pdbentry->precnode;
2163- ellInsert(preclist, ellPrevious(&precnode->node), &pnewnode->node);
2164- } else {
2165- ellAdd(preclist, &pnewnode->node);
2166- }
2167+ ellAdd(preclist, &pnewnode->node);
2168 precordType->no_aliases++;
2169 pdbentry->precnode = pnewnode;
2170 ppvd = dbPvdAdd(pdbentry->pdbbase, precordType, pnewnode);
2171
2172=== modified file 'src/ioc/dbStatic/dbStaticLib.h'
2173--- src/ioc/dbStatic/dbStaticLib.h 2016-05-22 12:38:18 +0000
2174+++ src/ioc/dbStatic/dbStaticLib.h 2016-10-12 09:08:28 +0000
2175@@ -146,8 +146,6 @@
2176 epicsShareFunc int dbGetNRecords(DBENTRY *pdbentry);
2177 epicsShareFunc int dbGetNAliases(DBENTRY *pdbentry);
2178 epicsShareFunc char * dbGetRecordName(DBENTRY *pdbentry);
2179-epicsShareFunc long dbRenameRecord(DBENTRY *pdbentry,
2180- const char *newName);
2181 epicsShareFunc long dbCopyRecord(DBENTRY *pdbentry,
2182 const char *newRecordName, int overWriteOK);
2183
2184
2185=== modified file 'src/ioc/dbStatic/dbStaticPvt.h'
2186=== modified file 'src/ioc/dbStatic/link.h'
2187=== modified file 'src/ioc/misc/dbCore.dbd'
2188--- src/ioc/misc/dbCore.dbd 2016-05-22 12:38:18 +0000
2189+++ src/ioc/misc/dbCore.dbd 2016-10-12 09:08:28 +0000
2190@@ -11,6 +11,7 @@
2191
2192 # Static database access variables
2193 variable(dbRecordsOnceOnly,int)
2194+variable(dbRecordsAbcSorted,int)
2195 variable(dbBptNotMonotonic,int)
2196 variable(dbQuietMacroWarnings,int)
2197
2198
2199=== modified file 'src/ioc/misc/iocInit.c'
2200=== modified file 'src/libCom/Makefile'
2201=== modified file 'src/libCom/RTEMS/rtems_init.c'
2202=== modified file 'src/libCom/cxxTemplates/epicsGuard.h'
2203=== added file 'src/libCom/cxxTemplates/epicsOnce.cpp.OTHER'
2204--- src/libCom/cxxTemplates/epicsOnce.cpp.OTHER 1970-01-01 00:00:00 +0000
2205+++ src/libCom/cxxTemplates/epicsOnce.cpp.OTHER 2016-10-12 09:08:28 +0000
2206@@ -0,0 +1,103 @@
2207+/*************************************************************************\
2208+* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
2209+* National Laboratory.
2210+* Copyright (c) 2002 The Regents of the University of California, as
2211+* Operator of Los Alamos National Laboratory.
2212+* EPICS BASE Versions 3.13.7
2213+* and higher are distributed subject to a Software License Agreement found
2214+* in file LICENSE that is included with this distribution.
2215+\*************************************************************************/
2216+
2217+/*
2218+ * Author Jeff Hill
2219+ * johill@lanl.gov
2220+ * 505 665 1831
2221+ */
2222+
2223+#define epicsExportSharedSymbols
2224+#include "epicsMutex.h"
2225+#include "epicsSingleton.h"
2226+#include "epicsGuard.h"
2227+#include "epicsOnce.h"
2228+#include "tsFreeList.h"
2229+
2230+class epicsOnceImpl : public epicsOnce {
2231+public:
2232+ epicsOnceImpl ( epicsOnceNotify & notifyIn );
2233+ void * operator new ( size_t size );
2234+ void operator delete ( void * pCadaver, size_t size );
2235+private:
2236+ epicsSingleton < epicsMutex > :: reference mutexRef;
2237+ epicsOnceNotify & notify;
2238+ bool onceFlag;
2239+ void destroy ();
2240+ void once ();
2241+ epicsOnceImpl ( epicsOnceImpl & ); // disabled
2242+ epicsOnceImpl & operator = ( epicsOnceImpl & ); // disabled
2243+ static epicsSingleton < epicsMutex > mutex;
2244+ static epicsSingleton < tsFreeList < class epicsOnceImpl, 16 > > freeList;
2245+};
2246+
2247+#ifdef _MSC_VER
2248+# pragma warning ( push )
2249+# pragma warning ( disable:4660 )
2250+#endif
2251+
2252+template class epicsSingleton < epicsMutex >;
2253+template class tsFreeList < class epicsOnceImpl, 16 >;
2254+template class epicsSingleton < tsFreeList < class epicsOnceImpl, 16 > >;
2255+
2256+#ifdef _MSC_VER
2257+# pragma warning ( pop )
2258+#endif
2259+
2260+epicsSingleton < epicsMutex > epicsOnceImpl::mutex;
2261+epicsSingleton < tsFreeList < class epicsOnceImpl, 16 > > epicsOnceImpl::freeList;
2262+
2263+inline void * epicsOnceImpl::operator new ( size_t size )
2264+{
2265+ epicsSingleton < tsFreeList < class epicsOnceImpl, 16 > > :: reference ref =
2266+ epicsOnceImpl::freeList.getReference ();
2267+ return ref->allocate ( size );
2268+}
2269+
2270+inline void epicsOnceImpl::operator delete ( void *pCadaver, size_t size )
2271+{
2272+ epicsSingleton < tsFreeList < class epicsOnceImpl, 16 > > :: reference ref =
2273+ epicsOnceImpl::freeList.getReference ();
2274+ ref->release ( pCadaver, size );
2275+}
2276+
2277+inline epicsOnceImpl::epicsOnceImpl ( epicsOnceNotify & notifyIn ) :
2278+mutexRef ( epicsOnceImpl::mutex.getReference() ), notify ( notifyIn ), onceFlag ( false )
2279+{
2280+}
2281+
2282+void epicsOnceImpl::once ()
2283+{
2284+ epicsGuard < epicsMutex > guard ( *this->mutexRef );
2285+ if ( ! this->onceFlag ) {
2286+ this->notify.initialize ();
2287+ this->onceFlag = true;
2288+ }
2289+}
2290+
2291+void epicsOnceImpl::destroy ()
2292+{
2293+ delete this;
2294+}
2295+
2296+epicsOnce & epicsOnce::create ( epicsOnceNotify & notifyIn )
2297+{
2298+ // free list throws exception in no memory situation
2299+ return * new epicsOnceImpl ( notifyIn );
2300+}
2301+
2302+epicsOnce::~epicsOnce ()
2303+{
2304+}
2305+
2306+epicsOnceNotify::~epicsOnceNotify ()
2307+{
2308+}
2309+
2310
2311=== added file 'src/libCom/cxxTemplates/epicsOnce.h.OTHER'
2312--- src/libCom/cxxTemplates/epicsOnce.h.OTHER 1970-01-01 00:00:00 +0000
2313+++ src/libCom/cxxTemplates/epicsOnce.h.OTHER 2016-10-12 09:08:28 +0000
2314@@ -0,0 +1,36 @@
2315+/*************************************************************************\
2316+* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
2317+* National Laboratory.
2318+* Copyright (c) 2002 The Regents of the University of California, as
2319+* Operator of Los Alamos National Laboratory.
2320+* EPICS BASE Versions 3.13.7
2321+* and higher are distributed subject to a Software License Agreement found
2322+* in file LICENSE that is included with this distribution.
2323+\*************************************************************************/
2324+/*
2325+ * Author Jeff Hill
2326+ * johill@lanl.gov
2327+ * 505 665 1831
2328+ */
2329+
2330+#ifndef epicsOnceh
2331+#define epicsOnceh
2332+
2333+#include "shareLib.h"
2334+
2335+class epicsOnceNotify {
2336+public:
2337+ epicsShareFunc virtual ~epicsOnceNotify ();
2338+ virtual void initialize () = 0;
2339+};
2340+
2341+class epicsOnce {
2342+public:
2343+ epicsShareFunc static epicsOnce & create ( epicsOnceNotify & notifyIn );
2344+ virtual ~epicsOnce (); // use destroy
2345+ virtual void once () = 0; // run notifyIn.initialize() once only
2346+ virtual void destroy () = 0; // destroy this object
2347+};
2348+
2349+#endif // epicsOnceh
2350+
2351
2352=== modified file 'src/libCom/ellLib/Makefile'
2353--- src/libCom/ellLib/Makefile 2011-02-25 21:39:44 +0000
2354+++ src/libCom/ellLib/Makefile 2016-10-12 09:08:28 +0000
2355@@ -10,3 +10,4 @@
2356 SRC_DIRS += $(LIBCOM)/ellLib
2357 INC += ellLib.h
2358 Com_SRCS += ellLib.c
2359+Com_SRCS += ellSort.c
2360
2361=== modified file 'src/libCom/ellLib/ellLib.h'
2362--- src/libCom/ellLib/ellLib.h 2016-05-22 12:38:18 +0000
2363+++ src/libCom/ellLib/ellLib.h 2016-10-12 09:08:28 +0000
2364@@ -56,6 +56,8 @@
2365 epicsShareFunc ELLNODE * ellNth (ELLLIST *pList, int nodeNum);
2366 epicsShareFunc ELLNODE * ellNStep (ELLNODE *pNode, int nStep);
2367 epicsShareFunc int ellFind (ELLLIST *pList, ELLNODE *pNode);
2368+typedef int (*pListCmp)(const ELLNODE* A, const ELLNODE* B);
2369+epicsShareFunc void ellSortStable(ELLLIST *pList, pListCmp);
2370 epicsShareFunc void ellFree2 (ELLLIST *pList, FREEFUNC freeFunc);
2371 epicsShareFunc void ellVerify (ELLLIST *pList);
2372
2373
2374=== added file 'src/libCom/ellLib/ellSort.c'
2375--- src/libCom/ellLib/ellSort.c 1970-01-01 00:00:00 +0000
2376+++ src/libCom/ellLib/ellSort.c 2016-10-12 09:08:28 +0000
2377@@ -0,0 +1,83 @@
2378+/*************************************************************************\
2379+* Copyright (c) 2014 Brookhaven Science Assoc., as Operator of Argonne
2380+* National Laboratory.
2381+* Copyright (c) 2016 Michael Davidsaver
2382+* EPICS BASE is distributed subject to a Software License Agreement found
2383+* in file LICENSE that is included with this distribution.
2384+\*************************************************************************/
2385+
2386+/*
2387+ * Use of mergesort algorithm based on analysis by
2388+ * http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
2389+ */
2390+#include <stdlib.h>
2391+
2392+#define epicsExportSharedSymbols
2393+#include "epicsAssert.h"
2394+#include "ellLib.h"
2395+
2396+static void ellMoveN(ELLLIST* pTo, ELLLIST* pFrom, int count )
2397+{
2398+ for(;count && ellCount(pFrom); count--) {
2399+ ELLNODE *node = ellGet(pFrom);
2400+ ellAdd(pTo, node);
2401+ }
2402+}
2403+
2404+/* Stable (MergeSort) to given list.
2405+ * The comparison function cmp(A,B) is expected
2406+ * to return -1 for A<B, 0 for A==B, and 1 for A>B.
2407+ */
2408+void ellSortStable(ELLLIST *pList, pListCmp cmp)
2409+{
2410+ ELLLIST INP, P, Q;
2411+ size_t insize = 1; /* initial sub-list size */
2412+ if(ellCount(pList)<=1)
2413+ return;
2414+
2415+ ellInit(&INP);
2416+ ellInit(&P);
2417+ ellInit(&Q);
2418+
2419+ /* Process is to iteratively sort
2420+ * a sequence of sub-lists of size 'insize'
2421+ */
2422+
2423+ while(insize < ellCount(pList)) {
2424+
2425+ assert(ellCount(&INP)==0);
2426+
2427+ /* shift previous results to inputs */
2428+ ellConcat(&INP, pList);
2429+
2430+ while(ellCount(&INP))
2431+ {
2432+ ELLNODE *p, *q;
2433+
2434+ /* Pull out the next pair of sub-lists */
2435+ ellMoveN(&Q, &INP, insize);
2436+ ellMoveN(&P, &INP, insize);
2437+
2438+ /* merge these sub-lists */
2439+ while((p=ellFirst(&P)) && (q=ellFirst(&Q)))
2440+ {
2441+ if((*cmp)(p,q) < 0) {
2442+ ellAdd(pList, ellGet(&P));
2443+ } else {
2444+ ellAdd(pList, ellGet(&Q));
2445+ }
2446+ }
2447+
2448+ /* concatenate any remaining to result */
2449+ if(ellFirst(&P))
2450+ ellConcat(pList, &P);
2451+ else if(ellFirst(&Q))
2452+ ellConcat(pList, &Q);
2453+
2454+ assert(!ellFirst(&P) && !ellFirst(&Q));
2455+ }
2456+
2457+ insize *= 2;
2458+ }
2459+
2460+}
2461
2462=== modified file 'src/libCom/env/RULES'
2463--- src/libCom/env/RULES 2016-09-07 15:04:54 +0000
2464+++ src/libCom/env/RULES 2016-10-12 09:08:28 +0000
2465@@ -8,7 +8,14 @@
2466 # This is a Makefile fragment, see src/libCom/Makefile.
2467
2468 envData.c: $(LIBCOM)/env/envDefs.h $(LIBCOM)/env/bldEnvData.pl \
2469+<<<<<<< TREE
2470 $(CONFIG)/CONFIG_ENV $(CONFIG)/CONFIG_SITE_ENV \
2471 $(wildcard $(CONFIG)/os/CONFIG_SITE_ENV.$(T_A))
2472 $(PERL) $(LIBCOM)/env/bldEnvData.pl $(QUIET_FLAG) -t $(T_A) \
2473 -c $(CMPLR_CLASS) -s $(OS_CLASS) $(CONFIG)
2474+=======
2475+ $(CONFIG)/CONFIG_ENV $(CONFIG)/CONFIG_SITE_ENV \
2476+ $(wildcard $(CONFIG)/os/CONFIG_SITE_ENV.$(T_A))
2477+ $(PERL) $(LIBCOM)/env/bldEnvData.pl $(INSTALL_QUIETLY) -t $(T_A) \
2478+ -c $(CMPLR_CLASS) -s $(OS_CLASS) $(CONFIG)
2479+>>>>>>> MERGE-SOURCE
2480
2481=== modified file 'src/libCom/env/bldEnvData.pl'
2482--- src/libCom/env/bldEnvData.pl 2016-09-07 15:04:54 +0000
2483+++ src/libCom/env/bldEnvData.pl 2016-10-12 09:08:28 +0000
2484@@ -32,8 +32,13 @@
2485 $Getopt::Std::OUTPUT_HELP_VERSION = 1;
2486 $Text::Wrap::columns = 75;
2487
2488+<<<<<<< TREE
2489 HELP_MESSAGE() unless getopts('ho:qt:s:c:') && @ARGV == 1;
2490 HELP_MESSAGE() if $opt_h;
2491+=======
2492+&HELP_MESSAGE unless getopts('ho:qt:s:c:') && @ARGV == 1;
2493+&HELP_MESSAGE if $opt_h;
2494+>>>>>>> MERGE-SOURCE
2495
2496 my $config = AbsPath(shift);
2497 my $env_defs = AbsPath('../env/envDefs.h');
2498
2499=== modified file 'src/libCom/env/envDefs.h'
2500=== modified file 'src/libCom/error/errMdef.h'
2501=== added file 'src/libCom/freeList/freeList.html.OTHER'
2502--- src/libCom/freeList/freeList.html.OTHER 1970-01-01 00:00:00 +0000
2503+++ src/libCom/freeList/freeList.html.OTHER 2016-10-12 09:08:28 +0000
2504@@ -0,0 +1,76 @@
2505+<HTML>
2506+<BODY>
2507+<PRE>
2508+<!-- Manpage converted by man2html 3.0.1 -->
2509+
2510+</PRE>
2511+<H2>VERSION $Id: freeList.3,v 1.2 1997/04/10 19:47:35</H2><PRE>
2512+
2513+</PRE>
2514+<H2>NAME</H2><PRE>
2515+ freeList.c - General Purpose memory free list library
2516+
2517+
2518+</PRE>
2519+<H2>SYNOPSIS</H2><PRE>
2520+ freeListInitPvt - Initialize a free list
2521+ freeListCalloc - Allocate and initialize to zero a new element
2522+ freeListMalloc - Allocate a new element
2523+ freeListFree - Free an element,i.e. put on free list
2524+
2525+
2526+ void freeListInitPvt(void **ppvt,int size,int nmalloc);
2527+ void *freeListCalloc(void *pvt);
2528+ void *freeListMalloc(void *pvt);
2529+ size_t freeListItemsAvail(void *pvt);
2530+ void freeListFree(void *pvt,void*pmem);
2531+
2532+ where :
2533+
2534+ pvt - For private use by library. Caller must provide a "void *pvt"
2535+ size - Size in butes of each element. Note that all elements must be same size
2536+ nmalloc - Number of elements top allocate when regular malloc must be called.
2537+
2538+
2539+
2540+</PRE>
2541+<H2>DESCRIPTION</H2><PRE>
2542+ This library can be used to allocate and free fixed size
2543+ memory elements. Free elements are maintained on a free
2544+ list rather then being returned to the heap via calls to
2545+ free. When it is necessary to call malloc, memory can be
2546+ allocated in multiples of the element size.
2547+
2548+
2549+</PRE>
2550+<H2>RETURNS</H2><PRE>
2551+ freeListCalloc and freeListMalloc return address of element allocated
2552+ or NULL if no more memory could be obtained via call to malloc
2553+
2554+
2555+</PRE>
2556+<H2>INCLUDES</H2><PRE>
2557+ freeLib.h
2558+
2559+
2560+
2561+
2562+
2563+
2564+
2565+
2566+
2567+
2568+
2569+
2570+
2571+
2572+
2573+</PRE>
2574+<HR>
2575+<ADDRESS>
2576+Man(1) output converted with
2577+<a href="http://www.oac.uci.edu/indiv/ehood/man2html.html">man2html</a>
2578+</ADDRESS>
2579+</BODY>
2580+</HTML>
2581
2582=== modified file 'src/libCom/freeList/freeListLib.c'
2583=== added file 'src/libCom/gpHash/gpHash.html.OTHER'
2584--- src/libCom/gpHash/gpHash.html.OTHER 1970-01-01 00:00:00 +0000
2585+++ src/libCom/gpHash/gpHash.html.OTHER 2016-10-12 09:08:28 +0000
2586@@ -0,0 +1,130 @@
2587+<HTML>
2588+<BODY>
2589+<PRE>
2590+<!-- Manpage converted by man2html 3.0.1 -->
2591+
2592+</PRE>
2593+<H2>VERSION $Id: gpHash.3,v 1.2 1999/09/13 19:18:04</H2><PRE>
2594+
2595+</PRE>
2596+<H2>NAME</H2><PRE>
2597+ gpHash.c - General Purpose Hash Library
2598+
2599+
2600+</PRE>
2601+<H2>SYNOPSIS</H2><PRE>
2602+ gphInitPvt - Initialize
2603+ gphFind - Find an element taht has been hashed
2604+ gphAdd - Add a new entry
2605+ gphDelete - Delete an entry
2606+ gphFreeMem - Free all memory allocated by gpHash
2607+ gphDump - Dump current members
2608+
2609+
2610+ typedef struct{
2611+ ELLNODE node;
2612+ char *name; /*address of name placed in directory*/
2613+ void *pvtid; /*private name for subsystem user*/
2614+ void *userPvt; /*private for user*/
2615+ } GPHENTRY;
2616+
2617+ void gphInitPvt(void **ppvt);
2618+ GPHENTRY *gphFind(void *pvt,const char *name,void *pvtid);
2619+ GPHENTRY *gphAdd(void *pvt,const char *name,void *pvtid);
2620+ void gphDelete(void *pvt,const char *name,void *pvtid);
2621+ void gphFreeMem(void *pvt);
2622+ void gphDump(void *pvt);
2623+
2624+
2625+ where :
2626+
2627+ pvt - For private use by library. Caller must provide a "void *pvt"
2628+ name - The character string that will be hashed and added to table
2629+ pvtid - The name plus value of this pointer constitute unique entry
2630+
2631+
2632+
2633+</PRE>
2634+<H2>DESCRIPTION</H2><PRE>
2635+ This library provides a general purpose directory of names
2636+ that is accessed via a hash table. The hash table contains
2637+ 256 entries. Each entry is a list of members that hash to
2638+ the same value. The user can maintain seperate directories
2639+ via the same table by having a different pvtid for each
2640+ directory.
2641+
2642+
2643+</PRE>
2644+<H2>RETURNS</H2><PRE>
2645+ gphFind returns the address of the GPHENTRY describing the entry or NULL if name was not found.
2646+ gphAdd returns the address of the new GPHENTRY describing the entry or NULL if name was already
2647+ present.
2648+
2649+
2650+</PRE>
2651+<H2>INCLUDES</H2><PRE>
2652+ gpHash.h
2653+
2654+
2655+
2656+</PRE>
2657+<H2>REFERENCE</H2><PRE>
2658+ Fast Hashing of Variable Length Text Strings, Peter K. Pear-
2659+ son, Communications of the ACM, June 1990
2660+
2661+
2662+
2663+
2664+
2665+
2666+
2667+
2668+
2669+
2670+
2671+
2672+
2673+
2674+
2675+
2676+
2677+
2678+
2679+
2680+
2681+
2682+
2683+
2684+
2685+
2686+
2687+
2688+
2689+
2690+
2691+
2692+
2693+
2694+
2695+
2696+
2697+
2698+
2699+
2700+
2701+
2702+
2703+
2704+
2705+
2706+
2707+
2708+
2709+</PRE>
2710+<HR>
2711+<ADDRESS>
2712+Man(1) output converted with
2713+<a href="http://www.oac.uci.edu/indiv/ehood/man2html.html">man2html</a>
2714+</ADDRESS>
2715+</BODY>
2716+</HTML>
2717
2718=== modified file 'src/libCom/misc/makeEpicsVersion.pl'
2719=== modified file 'src/libCom/osi/epicsGeneralTime.c'
2720--- src/libCom/osi/epicsGeneralTime.c 2016-09-07 15:04:54 +0000
2721+++ src/libCom/osi/epicsGeneralTime.c 2016-10-12 09:08:28 +0000
2722@@ -117,6 +117,7 @@
2723
2724 status = ptp->get.Time(pDest);
2725 if (status == epicsTimeOK) {
2726+<<<<<<< TREE
2727 /* No ratchet, time from this routine may go backwards */
2728 if (pPrio)
2729 *pPrio = ptp->priority;
2730@@ -159,6 +160,50 @@
2731
2732 status = ptp->get.Time(&ts);
2733 if (status == epicsTimeOK) {
2734+=======
2735+ /* No ratchet, time from this routine may go backwards */
2736+ if (pPrio)
2737+ *pPrio = ptp->priority;
2738+ break;
2739+ }
2740+ else IFDEBUG(2)
2741+ printf("gTGExP provider '%s' returned error\n", ptp->name);
2742+ }
2743+ epicsMutexUnlock(gtPvt.timeListLock);
2744+
2745+ IFDEBUG(2) {
2746+ if (ptp && status == epicsTimeOK) {
2747+ char buff[40];
2748+
2749+ epicsTimeToStrftime(buff, sizeof(buff), tsfmt, pDest);
2750+ printf("gTGExP returning %s from provider '%s'\n",
2751+ buff, ptp->name);
2752+ }
2753+ else
2754+ printf("gTGExP returning error\n");
2755+ }
2756+
2757+ return status;
2758+}
2759+
2760+int epicsShareAPI epicsTimeGetCurrent(epicsTimeStamp *pDest)
2761+{
2762+ gtProvider *ptp;
2763+ int status = epicsTimeERROR;
2764+ epicsTimeStamp ts;
2765+
2766+ generalTime_Init();
2767+
2768+ IFDEBUG(20)
2769+ printf("epicsTimeGetCurrent()\n");
2770+
2771+ epicsMutexMustLock(gtPvt.timeListLock);
2772+ for (ptp = (gtProvider *)ellFirst(&gtPvt.timeProviders);
2773+ ptp; ptp = (gtProvider *)ellNext(&ptp->node)) {
2774+
2775+ status = ptp->get.Time(&ts);
2776+ if (status == epicsTimeOK) {
2777+>>>>>>> MERGE-SOURCE
2778 /* check time is monotonic */
2779 if (epicsTimeGreaterThanEqual(&ts, &gtPvt.lastProvidedTime)) {
2780 *pDest = ts;
2781@@ -185,7 +230,11 @@
2782 break;
2783 }
2784 }
2785+<<<<<<< TREE
2786 if (status)
2787+=======
2788+ if (status == epicsTimeERROR)
2789+>>>>>>> MERGE-SOURCE
2790 gtPvt.lastTimeProvider = NULL;
2791 epicsMutexUnlock(gtPvt.timeListLock);
2792
2793@@ -209,11 +258,19 @@
2794 gtProvider *ptp = gtPvt.lastTimeProvider;
2795
2796 if (ptp == NULL ||
2797+<<<<<<< TREE
2798 ptp->getInt.Time == NULL) {
2799 IFDEBUG(20)
2800 epicsInterruptContextMessage("eTGCInt: No support\n");
2801 return S_time_noProvider;
2802 }
2803+=======
2804+ ptp->getInt.Time == NULL) {
2805+ IFDEBUG(20)
2806+ epicsInterruptContextMessage("eTGCInt: No support\n");
2807+ return epicsTimeERROR;
2808+ }
2809+>>>>>>> MERGE-SOURCE
2810
2811 return ptp->getInt.Time(pDest);
2812 }
2813@@ -223,8 +280,13 @@
2814 int *pPrio)
2815 {
2816 gtProvider *ptp;
2817+<<<<<<< TREE
2818 int status = S_time_noProvider;
2819 epicsTimeStamp ts;
2820+=======
2821+ int status = epicsTimeERROR;
2822+ epicsTimeStamp ts;
2823+>>>>>>> MERGE-SOURCE
2824
2825 generalTime_Init();
2826
2827@@ -335,11 +397,19 @@
2828 gtProvider *ptp = gtPvt.lastEventProvider;
2829
2830 if (ptp == NULL ||
2831+<<<<<<< TREE
2832 ptp->getInt.Event == NULL) {
2833 IFDEBUG(20)
2834 epicsInterruptContextMessage("eTGEvInt: No support\n");
2835 return S_time_noProvider;
2836 }
2837+=======
2838+ ptp->getInt.Event == NULL) {
2839+ IFDEBUG(20)
2840+ epicsInterruptContextMessage("eTGEvInt: No support\n");
2841+ return epicsTimeERROR;
2842+ }
2843+>>>>>>> MERGE-SOURCE
2844
2845 return ptp->getInt.Event(pDest, eventNumber);
2846 }
2847
2848=== modified file 'src/libCom/osi/epicsMessageQueue.h'
2849=== modified file 'src/libCom/osi/epicsMutex.cpp'
2850=== modified file 'src/libCom/osi/epicsReadline.c'
2851=== modified file 'src/libCom/osi/os/RTEMS/osdThread.c'
2852--- src/libCom/osi/os/RTEMS/osdThread.c 2016-09-07 15:04:54 +0000
2853+++ src/libCom/osi/os/RTEMS/osdThread.c 2016-10-12 09:08:28 +0000
2854@@ -690,6 +690,7 @@
2855 for (v = taskVarHead ; v != NULL ; v = v->forw) {
2856 if ((rtems_id)id == v->id) {
2857 epicsThreadShowInfo (v, level);
2858+ taskVarUnlock ();
2859 return;
2860 }
2861 }
2862
2863=== modified file 'src/libCom/osi/os/RTEMS/osdTime.cpp'
2864=== modified file 'src/libCom/osi/os/WIN32/osdNetIntf.c'
2865--- src/libCom/osi/os/WIN32/osdNetIntf.c 2016-09-07 15:04:54 +0000
2866+++ src/libCom/osi/os/WIN32/osdNetIntf.c 2016-10-12 09:08:28 +0000
2867@@ -48,6 +48,7 @@
2868 */
2869 static void osiLocalAddrOnce ( void *raw )
2870 {
2871+<<<<<<< TREE
2872 SOCKET *psocket = raw;
2873 osiSockAddr addr;
2874 int status;
2875@@ -58,8 +59,25 @@
2876 DWORD cbBytesReturned;
2877
2878 memset ( (void *) &addr, '\0', sizeof ( addr ) );
2879+=======
2880+ static osiSockAddr addr;
2881+ static char init;
2882+ int status;
2883+ INTERFACE_INFO *pIfinfo;
2884+ INTERFACE_INFO *pIfinfoList;
2885+ unsigned nelem;
2886+ DWORD numifs;
2887+ DWORD cbBytesReturned;
2888+
2889+ if (init) {
2890+ return addr;
2891+ }
2892+
2893+ init = 1;
2894+>>>>>>> MERGE-SOURCE
2895 addr.sa.sa_family = AF_UNSPEC;
2896
2897+<<<<<<< TREE
2898 /* only valid for winsock 2 and above */
2899 if ( wsaMajorVersion() < 2 ) {
2900 goto fail;
2901@@ -101,10 +119,55 @@
2902 addr.sa = pIfinfo->iiAddress.Address;
2903
2904 /* Work around MS Winsock2 bugs */
2905+=======
2906+ /* only valid for winsock 2 and above */
2907+ if ( wsaMajorVersion() < 2 ) {
2908+ return addr;
2909+ }
2910+
2911+ nelem = 100;
2912+ pIfinfoList = (INTERFACE_INFO *) calloc ( nelem, sizeof (INTERFACE_INFO) );
2913+ if (!pIfinfoList) {
2914+ errlogPrintf ("calloc failed\n");
2915+ return addr;
2916+ }
2917+
2918+ status = WSAIoctl (socket, SIO_GET_INTERFACE_LIST, NULL, 0,
2919+ (LPVOID) pIfinfoList, nelem * sizeof(INTERFACE_INFO),
2920+ &cbBytesReturned, NULL, NULL);
2921+
2922+ if (status != 0 || cbBytesReturned == 0) {
2923+ errlogPrintf ("WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError());
2924+ free (pIfinfoList);
2925+ return addr;
2926+ }
2927+
2928+ numifs = cbBytesReturned / sizeof(INTERFACE_INFO);
2929+ for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++){
2930+
2931+ /*
2932+ * dont use interfaces that have been disabled
2933+ */
2934+ if (!(pIfinfo->iiFlags & IFF_UP)) {
2935+ continue;
2936+ }
2937+
2938+ /*
2939+ * dont use the loop back interface
2940+ */
2941+ if (pIfinfo->iiFlags & IFF_LOOPBACK) {
2942+ continue;
2943+ }
2944+
2945+ addr.sa = pIfinfo->iiAddress.Address;
2946+
2947+ /* Work around MS Winsock2 bugs */
2948+>>>>>>> MERGE-SOURCE
2949 if (addr.sa.sa_family == 0) {
2950 addr.sa.sa_family = AF_INET;
2951 }
2952
2953+<<<<<<< TREE
2954 osiLocalAddrResult = addr;
2955 free ( pIfinfoList );
2956 return;
2957@@ -126,6 +189,14 @@
2958 {
2959 epicsThreadOnce(&osiLocalAddrId, osiLocalAddrOnce, (void*)&socket);
2960 return osiLocalAddrResult;
2961+=======
2962+ free (pIfinfoList);
2963+ return addr;
2964+ }
2965+
2966+ free (pIfinfoList);
2967+ return addr;
2968+>>>>>>> MERGE-SOURCE
2969 }
2970
2971 /*
2972@@ -156,6 +227,7 @@
2973 }
2974 }
2975
2976+<<<<<<< TREE
2977 /* only valid for winsock 2 and above */
2978 if (wsaMajorVersion() < 2 ) {
2979 fprintf(stderr, "Need to set EPICS_CA_AUTO_ADDR_LIST=NO for winsock 1\n");
2980@@ -206,6 +278,58 @@
2981 * if it isnt a wildcarded interface then look for
2982 * an exact match
2983 */
2984+=======
2985+ /* only valid for winsock 2 and above */
2986+ if (wsaMajorVersion() < 2 ) {
2987+ fprintf(stderr, "Need to set EPICS_CA_AUTO_ADDR_LIST=NO for winsock 1\n");
2988+ return;
2989+ }
2990+
2991+ nelem = 100;
2992+ pIfinfoList = (INTERFACE_INFO *) calloc(nelem, sizeof(INTERFACE_INFO));
2993+ if(!pIfinfoList){
2994+ return;
2995+ }
2996+
2997+ status = WSAIoctl (socket, SIO_GET_INTERFACE_LIST,
2998+ NULL, 0,
2999+ (LPVOID)pIfinfoList, nelem*sizeof(INTERFACE_INFO),
3000+ &cbBytesReturned, NULL, NULL);
3001+
3002+ if (status != 0 || cbBytesReturned == 0) {
3003+ fprintf(stderr, "WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError());
3004+ free(pIfinfoList);
3005+ return;
3006+ }
3007+
3008+ numifs = cbBytesReturned/sizeof(INTERFACE_INFO);
3009+ for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++){
3010+
3011+ /*
3012+ * dont bother with interfaces that have been disabled
3013+ */
3014+ if (!(pIfinfo->iiFlags & IFF_UP)) {
3015+ continue;
3016+ }
3017+
3018+ if (pIfinfo->iiFlags & IFF_LOOPBACK) {
3019+ continue;
3020+ }
3021+
3022+ /*
3023+ * work around WS2 bug
3024+ */
3025+ if (pIfinfo->iiAddress.Address.sa_family != AF_INET) {
3026+ if (pIfinfo->iiAddress.Address.sa_family == 0) {
3027+ pIfinfo->iiAddress.Address.sa_family = AF_INET;
3028+ }
3029+ }
3030+
3031+ /*
3032+ * if it isnt a wildcarded interface then look for
3033+ * an exact match
3034+ */
3035+>>>>>>> MERGE-SOURCE
3036 if (pMatchAddr->sa.sa_family != AF_UNSPEC) {
3037 if (pIfinfo->iiAddress.Address.sa_family != pMatchAddr->sa.sa_family) {
3038 continue;
3039
3040=== modified file 'src/libCom/osi/os/default/osdMessageQueue.cpp'
3041=== modified file 'src/libCom/osi/os/default/osdNetIntf.c'
3042=== modified file 'src/libCom/osi/osiClockTime.c'
3043=== modified file 'src/libCom/test/epicsEllTest.c'
3044--- src/libCom/test/epicsEllTest.c 2009-08-28 18:34:38 +0000
3045+++ src/libCom/test/epicsEllTest.c 2016-10-12 09:08:28 +0000
3046@@ -1,4 +1,5 @@
3047 /*************************************************************************\
3048+* Copyright (c) 2016 Michael Davidsaver
3049 * Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
3050 * National Laboratory.
3051 * Copyright (c) 2002 The Regents of the University of California, as
3052@@ -11,6 +12,7 @@
3053 #include <stdlib.h>
3054
3055 #include "ellLib.h"
3056+#include "dbDefs.h"
3057 #include "epicsUnitTest.h"
3058 #include "testMain.h"
3059
3060@@ -20,15 +22,13 @@
3061 int num;
3062 };
3063
3064-MAIN(epicsEllTest)
3065+static void testList(void)
3066 {
3067 ELLLIST list1;
3068 ELLLIST list2 = ELLLIST_INIT;
3069 int i1 = 1;
3070 struct myItem *pitem, *pfirst, *pick;
3071
3072- testPlan(70);
3073-
3074 list1.count = 27;
3075 list1.node.next = (ELLNODE *) 0x01010101;
3076 list1.node.previous = (ELLNODE *) 0x10101010;
3077@@ -192,6 +192,77 @@
3078
3079 ellFree2(&list1, free);
3080 testOk1(ellCount(&list1) == 0);
3081+}
3082+
3083+typedef struct { int A, B; } input_t;
3084+
3085+static int myItemCmp(const ELLNODE *a, const ELLNODE *b)
3086+{
3087+ struct myItem *A = CONTAINER(a, struct myItem, node),
3088+ *B = CONTAINER(b, struct myItem, node);
3089+
3090+ if (A->num < B->num) return -1;
3091+ else if(A->num > B->num) return 1;
3092+ else if(A->list < B->list) return -1;
3093+ else if(A->list > B->list) return 1;
3094+ else return 0;
3095+}
3096+
3097+static const input_t input[] = {
3098+ {-4, 0},
3099+ {-5, 0},
3100+ {0,0},
3101+ {50,0},
3102+ {0,1},
3103+ {5,0},
3104+ {5,1}
3105+};
3106+
3107+static
3108+void testSort(const input_t *inp, size_t ninp)
3109+{
3110+ unsigned i;
3111+ ELLLIST list = ELLLIST_INIT;
3112+ struct myItem *alloc = calloc(ninp, sizeof(*alloc));
3113+
3114+ if(!alloc) testAbort("testSort allocation fails");
3115+
3116+ for(i=0; i<ninp; i++) {
3117+ struct myItem *it = &alloc[i];
3118+
3119+ it->num = inp[i].A;
3120+ it->list= inp[i].B;
3121+
3122+ ellAdd(&list, &it->node);
3123+ }
3124+
3125+ ellSortStable(&list, &myItemCmp);
3126+
3127+ testOk(ellCount(&list)==ninp, "output length %u == %u", (unsigned)ellCount(&list), (unsigned)ninp);
3128+ if(ellCount(&list)==0) {
3129+ testSkip(ninp-1, "all items lost");
3130+ }
3131+
3132+ {
3133+ struct myItem *prev = CONTAINER(ellFirst(&list), struct myItem, node),
3134+ *next;
3135+
3136+ for(next = CONTAINER(ellNext(&prev->node), struct myItem, node);
3137+ next;
3138+ prev = next, next = CONTAINER(ellNext(&next->node), struct myItem, node))
3139+ {
3140+ int cond = (prev->num<next->num) || (prev->num==next->num && prev->list<next->list);
3141+ testOk(cond, "%d:%d < %d:%d", prev->num, prev->list, next->num, next->list);
3142+ }
3143+ }
3144+}
3145+
3146+MAIN(epicsEllTest)
3147+{
3148+ testPlan(77);
3149+
3150+ testList();
3151+ testSort(input, NELEMENTS(input));
3152
3153 return testDone();
3154 }
3155
3156=== modified file 'src/std/dev/devGeneralTime.c'
3157=== modified file 'src/std/rec/compressRecord.c'
3158=== modified file 'src/std/rec/compressRecord.dbd.pod'
3159--- src/std/rec/compressRecord.dbd.pod 2016-09-07 15:04:54 +0000
3160+++ src/std/rec/compressRecord.dbd.pod 2016-10-12 09:08:28 +0000
3161@@ -90,6 +90,7 @@
3162 }
3163 field(ALG,DBF_MENU) {
3164 prompt("Compression Algorithm")
3165+<<<<<<< TREE
3166 promptgroup("30 - Action")
3167 special(SPC_RESET)
3168 interest(1)
3169@@ -98,6 +99,9 @@
3170 field(BALG,DBF_MENU) {
3171 prompt("Buffering Algorithm")
3172 promptgroup(GUI_ALARMS)
3173+=======
3174+ promptgroup("30 - Action")
3175+>>>>>>> MERGE-SOURCE
3176 special(SPC_RESET)
3177 interest(1)
3178 menu(bufferingALG)
3179
3180=== modified file 'src/std/rec/test/Makefile'
3181=== modified file 'src/template/base/makeBaseApp.pl'
3182=== modified file 'src/template/base/top/exampleApp/src/Makefile'
3183--- src/template/base/top/exampleApp/src/Makefile 2016-09-07 15:04:54 +0000
3184+++ src/template/base/top/exampleApp/src/Makefile 2016-10-12 09:08:28 +0000
3185@@ -27,12 +27,16 @@
3186
3187 _APPNAME_Support_LIBS += $(EPICS_BASE_IOC_LIBS)
3188
3189+<<<<<<< TREE
3190 # Auto-generate a header file containing a version string.
3191 # Version comes from the VCS if available, else date+time.
3192 GENVERSION = _APPNAME_Version.h
3193 # Macro name
3194 GENVERSIONMACRO = _APPNAME_VERSION
3195
3196+=======
3197+
3198+>>>>>>> MERGE-SOURCE
3199 # Build the IOC application
3200 PROD_IOC = _APPNAME_
3201
3202
3203=== modified file 'src/template/ext/makeBaseExt.pl'
3204=== modified file 'src/template/ext/top/configure/RULES_JAVA'
3205=== modified file 'src/tools/DBD/Base.pm'
3206--- src/tools/DBD/Base.pm 2016-09-07 15:04:54 +0000
3207+++ src/tools/DBD/Base.pm 2016-10-12 09:08:28 +0000
3208@@ -8,11 +8,18 @@
3209 use Carp;
3210 require Exporter;
3211
3212+<<<<<<< TREE
3213 our @ISA = qw(Exporter);
3214
3215 our @EXPORT = qw(&pushContext &popContext &dieContext &warnContext &is_reserved
3216 &escapeCcomment &escapeCstring $RXident $RXname $RXuint $RXint $RXhex $RXoct
3217 $RXuintx $RXintx $RXnum $RXdqs $RXstr);
3218+=======
3219+@ISA = qw(Exporter);
3220+@EXPORT = qw(&pushContext &popContext &dieContext &warnContext &is_reserved
3221+ &identifier &unquote &escapeCcomment &escapeCstring $RXident $RXname
3222+ $RXuint $RXint $RXhex $RXoct $RXuintx $RXintx $RXnum $RXdqs $RXstr);
3223+>>>>>>> MERGE-SOURCE
3224
3225
3226 our $RXident = qr/ [a-zA-Z] [a-zA-Z0-9_]* /x;
3227@@ -24,8 +31,13 @@
3228 our $RXuintx = qr/ ( $RXhex | $RXoct | $RXuint ) /ox;
3229 our $RXintx = qr/ ( $RXhex | $RXoct | $RXint ) /ox;
3230 our $RXnum = qr/ -? (?: \d+ | \d* \. \d+ ) (?: [eE] [-+]? \d+ )? /x;
3231+<<<<<<< TREE
3232 our $RXdqs = qr/ " (?: [^"] | \\" )* " /x;
3233 our $RXstr = qr/ ( $RXname | $RXnum | $RXdqs ) /ox;
3234+=======
3235+our $RXdqs = qr/" (?: [^"] | \\" )* " /x;
3236+our $RXstr = qr/ ( $RXname | $RXnum | $RXdqs ) /ox;
3237+>>>>>>> MERGE-SOURCE
3238
3239 our @context;
3240
3241
3242=== modified file 'src/tools/DBD/Menu.pm'
3243=== modified file 'src/tools/DBD/Output.pm'
3244--- src/tools/DBD/Output.pm 2015-07-06 16:26:35 +0000
3245+++ src/tools/DBD/Output.pm 2016-10-12 09:08:28 +0000
3246@@ -101,7 +101,7 @@
3247 my ($out, $breaktables) = @_;
3248 while (my ($name, $breaktable) = each %{$breaktables}) {
3249 printf $out "breaktable(\"%s\") {\n", $name;
3250- printf $out " point(%s, %s)\n", @{$_}
3251+ printf $out " %s, %s\n", @{$_}
3252 foreach $breaktable->points;
3253 print $out "}\n";
3254 }
3255
3256=== modified file 'src/tools/DBD/Recfield.pm'
3257--- src/tools/DBD/Recfield.pm 2016-09-07 15:04:54 +0000
3258+++ src/tools/DBD/Recfield.pm 2016-10-12 09:08:28 +0000
3259@@ -103,8 +103,14 @@
3260
3261 sub add_attribute {
3262 my ($this, $attr, $value) = @_;
3263- $value = $promptgroupMap{$value}
3264- if $attr eq 'promptgroup' && exists $promptgroupMap{$value};
3265+<<<<<<< TREE
3266+ $value = $promptgroupMap{$value}
3267+ if $attr eq 'promptgroup' && exists $promptgroupMap{$value};
3268+=======
3269+ unquote $value;
3270+ $value = $promptgroupMap{$value}
3271+ if $attr eq 'promptgroup' && exists $promptgroupMap{$value};
3272+>>>>>>> MERGE-SOURCE
3273 my $match = $field_attrs{$attr};
3274 if (defined $match) {
3275 dieContext("Bad value '$value' for field attribute '$attr'")
3276
3277=== modified file 'src/tools/EPICS/Path.pm'
3278--- src/tools/EPICS/Path.pm 2016-09-07 15:04:54 +0000
3279+++ src/tools/EPICS/Path.pm 2016-10-12 09:08:28 +0000
3280@@ -5,11 +5,19 @@
3281 # in file LICENSE that is included with this distribution.
3282 #*************************************************************************
3283
3284+<<<<<<< TREE
3285 package EPICS::Path;
3286 require 5.000;
3287 require Exporter;
3288
3289 =head1 NAME
3290+=======
3291+use Carp;
3292+use Cwd qw(getcwd abs_path);
3293+use File::Spec;
3294+
3295+=head1 EPICS::Path
3296+>>>>>>> MERGE-SOURCE
3297
3298 EPICS::Path - Path-handling utilities for EPICS tools
3299
3300
3301=== modified file 'src/tools/EPICS/Readfile.pm'
3302=== modified file 'src/tools/EPICS/Release.pm'
3303=== modified file 'src/tools/EPICS/macLib.pm'
3304=== modified file 'src/tools/convertRelease.pl'
3305=== modified file 'src/tools/dbdExpand.pl'
3306--- src/tools/dbdExpand.pl 2016-09-07 15:04:54 +0000
3307+++ src/tools/dbdExpand.pl 2016-10-12 09:08:28 +0000
3308@@ -7,8 +7,11 @@
3309 # in file LICENSE that is included with this distribution.
3310 #*************************************************************************
3311
3312+<<<<<<< TREE
3313 use strict;
3314
3315+=======
3316+>>>>>>> MERGE-SOURCE
3317 use FindBin qw($Bin);
3318 use lib "$Bin/../../lib/perl";
3319
3320
3321=== modified file 'src/tools/dbdReport.pl'
3322=== modified file 'src/tools/dbdToHtml.pl'
3323=== modified file 'src/tools/dbdToMenuH.pl'
3324=== modified file 'src/tools/dbdToRecordtypeH.pl'
3325=== modified file 'src/tools/expandVars.pl'
3326=== modified file 'src/tools/fullPathName.pl'
3327=== modified file 'src/tools/munch.pl'
3328--- src/tools/munch.pl 2016-09-07 15:04:54 +0000
3329+++ src/tools/munch.pl 2016-10-12 09:08:28 +0000
3330@@ -7,6 +7,12 @@
3331 # EPICS BASE is distributed subject to a Software License Agreement found
3332 # in the file LICENSE that is included with this distribution.
3333 #*************************************************************************
3334+<<<<<<< TREE
3335+=======
3336+#
3337+# Creates a ctdt.c file of C++ static constructors and destructors,
3338+# as required for all vxWorks binaries containing C++ code.
3339+>>>>>>> MERGE-SOURCE
3340
3341 use strict;
3342 use warnings;
3343
3344=== modified file 'src/tools/podRemove.pl'
3345=== modified file 'src/tools/podToHtml.pl'
3346=== modified file 'src/tools/test/Menu.plt'

Subscribers

People subscribed via source and target branches