Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8633e72026 | ||
|
|
1106ecd818 | ||
|
|
6e6cd59674 | ||
|
|
4cdc2575c5 | ||
|
|
9f52f7282d | ||
|
|
ed882fe82d | ||
|
|
d0e58f9aa7 | ||
|
|
2c13aa03e2 | ||
|
|
3717607892 | ||
|
|
cb72210d45 | ||
|
|
92d01c0e5f | ||
|
|
42506d8c1c | ||
|
|
dfccee739f | ||
|
|
35d07ffbda | ||
|
|
d158974870 | ||
|
|
2e922d7195 | ||
|
|
e405ebbbee | ||
|
|
da15507f8d | ||
|
|
8411adb987 | ||
|
|
c30c884687 | ||
|
|
21fe691d96 | ||
|
|
22e21f268b | ||
|
|
d45e1b13e4 | ||
|
|
8873934c9b | ||
|
|
c0c11c359f | ||
|
|
367e27d5f5 | ||
|
|
35bd1a76d1 | ||
|
|
a887ca44d1 | ||
|
|
dd273da508 | ||
|
|
245cf129ff | ||
|
|
36b1f9e4ff | ||
|
|
24a0197f88 | ||
|
|
e30e1159a2 | ||
|
|
42ea151881 | ||
|
|
ce201c6361 | ||
|
|
0784bbec71 |
@@ -18,7 +18,7 @@
|
||||
|
||||
EPICS_VERSION=3
|
||||
EPICS_REVISION=14
|
||||
EPICS_MODIFICATION=3
|
||||
EPICS_MODIFICATION=4
|
||||
EPICS_UPDATE_NAME=
|
||||
EPICS_UPDATE_LEVEL=0
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ CONFIG ?= $(TOP)/configure
|
||||
|
||||
-include $(CONFIG)/RELEASE
|
||||
-include $(CONFIG)/RELEASE.$(EPICS_HOST_ARCH)
|
||||
-include $(CONFIG)/RELEASE.Common.$(T_A)
|
||||
-include $(CONFIG)/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
include $(CONFIG)/CONFIG_COMMON
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
EPICS_VERSION=3
|
||||
EPICS_REVISION=14
|
||||
EPICS_MODIFICATION=3
|
||||
EPICS_MODIFICATION=4
|
||||
EPICS_UPDATE_NAME=
|
||||
EPICS_UPDATE_LEVEL=0
|
||||
|
||||
@@ -27,3 +27,4 @@ EPICS_VERSION_STRING="EPICS Version ${EPICS_VERSION}.${EPICS_REVISION}.${EPICS_M
|
||||
CVS_DATE="\$$Date$$"
|
||||
CVS_TAG="\$$Name$$"
|
||||
|
||||
BASE_3_14=YES
|
||||
|
||||
@@ -20,7 +20,7 @@ JAVA_INCLUDES += -I$(JAVA_INC) -I$(JAVA_INC)/$(OS_CLASS) -I$(COMMON_DIR)
|
||||
|
||||
JAVACCMD = $(subst \,/,$(JAVA_BIN)/javac$(EXE) $(CLASSPATH) $(SOURCEPATH) $(JAVACFLAGS))
|
||||
JAVAHCMD = $(subst \,/,$(JAVA_BIN)/javah$(EXE) -d $(COMMON_DIR) -force $(CLASSPATH) $(JAVAHFLAGS))
|
||||
JARCMD = $(subst \,/,$(JAVA_BIN)/jar$(EXE) $(JAR_OPTIONS) $(COMMON_JAR) $(JARINPUT))
|
||||
JARCMD = $(subst \,/,$(JAVA_BIN)/jar$(EXE) $(JAR_OPTIONS) $(COMMON_JAR) $(JARINPUT) $(JARPACKAGES))
|
||||
|
||||
#-------------------------------------------------------
|
||||
vpath %.java ..
|
||||
@@ -60,9 +60,11 @@ DEPTESTJAVA += $(subst .class,.java,$(TESTCLASSES))
|
||||
|
||||
COMMON_JAR += $(addprefix $(COMMON_DIR)/,$(JAR))
|
||||
INSTALL_JAR =$(addprefix $(INSTALL_JAVA)/,$(JAR))
|
||||
JARMANIFEST += $(firstword $(trim $(MANIFEST) $(JAR_MANIFEST)))
|
||||
JARMANIFEST += $(firstword $(MANIFEST) $(JAR_MANIFEST))
|
||||
JARINPUT += $(subst .java,.class,$(JAR_INPUT))
|
||||
JARDEPFILES += $(JARINPUT) $(JARMANIFEST)
|
||||
JARDEPFILES += $(addprefix $(INSTALL_JAVA)/,$(subst .java,.class,$(JAVA))) $(JARINPUT)
|
||||
JARPACKAGES += $(foreach pkg,$(JAR_PACKAGES),-C $(INSTALL_JAVA) $(subst .,/,$(pkg)))
|
||||
|
||||
ifneq ($(JARMANIFEST),)
|
||||
JAR_OPTIONS = cvmf $(JARMANIFEST)
|
||||
else
|
||||
|
||||
@@ -76,12 +76,20 @@ $outfile = $ARGV[0];
|
||||
|
||||
# Read the RELEASE file(s)
|
||||
$relfile = "$top/configure/RELEASE";
|
||||
die "Can't find configure/RELEASE file" unless (-f $relfile);
|
||||
die "Can't find configure/RELEASE file" unless (-r $relfile);
|
||||
&readRelease($relfile, \%macros, \@apps);
|
||||
|
||||
if ($hostarch) {
|
||||
$relfile .= ".$hostarch";
|
||||
&readRelease($relfile, \%macros, \@apps) if (-r $relfile);
|
||||
my ($hrelfile) = "$relfile.$hostarch";
|
||||
&readRelease($hrelfile, \%macros, \@apps) if (-r $hrelfile);
|
||||
}
|
||||
if ($arch) {
|
||||
my ($crelfile) = "$relfile.Common.$arch";
|
||||
&readRelease($crelfile, \%macros, \@apps) if (-r $crelfile);
|
||||
if ($hostarch) {
|
||||
my ($arelfile) = "$relfile.$hostarch.$arch";
|
||||
&readRelease($arelfile, \%macros, \@apps) if (-r $arelfile);
|
||||
}
|
||||
}
|
||||
&expandRelease(\%macros, \@apps);
|
||||
|
||||
|
||||
@@ -102,8 +102,8 @@ from the st.cmd files in the iocBoot subdirectories.
|
||||
<p>Remove</p>
|
||||
<pre>ld < iocCore
|
||||
</pre>
|
||||
<p>Immediately after the dbLoadDatabase command add</p>
|
||||
<pre>registerRecordDeviceDriver(pdbbase)
|
||||
<p>Immediately after the dbLoadDatabase(xxx.dbd) command add</p>
|
||||
<pre>xxx_registerRecordDeviceDriver(pdbbase)
|
||||
</pre>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
<body>
|
||||
|
||||
<center>
|
||||
<h2>Converting an EPICS R3.13 application to R3.14.3</h2>
|
||||
<h2>Converting an EPICS R3.13 application to R3.14.4</h2>
|
||||
</center>
|
||||
|
||||
<p><br>
|
||||
This document describes how to convert a R3.13 vxWorks application so that it
|
||||
builds with release R3.14.3. It describes procedures such that:</p>
|
||||
builds with release R3.14.4. It describes procedures such that:</p>
|
||||
<ul>
|
||||
<li>The application uses the configure rules which are new to R3.14.</li>
|
||||
</ul>
|
||||
@@ -50,7 +50,7 @@ If sequence programs (*.st or *.stt files) exist in your application, add the
|
||||
SNCSEQ location definition for the R3.14 seq external module</p>
|
||||
|
||||
<p><tt>SNCSEQ =<full path to seq module top></tt></p>
|
||||
The R3.14 seq module must exist and be built with EPICS base R3.14.3
|
||||
The R3.14 seq module must exist and be built with EPICS base R3.14.4
|
||||
|
||||
<h3>Modify the Makefiles in <top>/*App directories.</h3>
|
||||
|
||||
@@ -167,6 +167,134 @@ example_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
|
||||
<p>After these changes are made the following files are no longer needed:
|
||||
baseLIBOBS, Makefile.Host, and Makefile.Vx</p>
|
||||
|
||||
<h3>File base.dbd no longer needed</h3>
|
||||
|
||||
<blockquote>
|
||||
You now can add the line include "base.dbd" to your
|
||||
<appname>Include.dbd file and remove the file
|
||||
<name>App/src/base.dbd from your src directory. The base.dbd from
|
||||
base/dbd will be included. However, if you only want a subset of
|
||||
record definitions from base you should keep your base.dbd
|
||||
file.</blockquote>
|
||||
|
||||
<h3>Record support</h3>
|
||||
|
||||
<blockquote>
|
||||
Add the following line after all existing #includes
|
||||
|
||||
<blockquote>
|
||||
<pre>#include "epicsExport.h"</pre>
|
||||
</blockquote>
|
||||
The structure rset is now a typedef so change
|
||||
|
||||
<blockquote>
|
||||
<pre>struct rset <recordname>RSET={ ...</pre>
|
||||
</blockquote>
|
||||
to
|
||||
|
||||
<blockquote>
|
||||
<pre>rset <recordname>RSET={ ...</pre>
|
||||
</blockquote>
|
||||
and add the following line after the "rset <recordname>RSET="
|
||||
definition.
|
||||
|
||||
<blockquote>
|
||||
<pre>epicsExportAddress(rset,xxxRSET);</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<h3>Device support</h3>
|
||||
|
||||
<blockquote>
|
||||
Add the following line after all existing #includes
|
||||
|
||||
<blockquote>
|
||||
<pre>#include "epicsExport.h"</pre>
|
||||
</blockquote>
|
||||
and add the following line after the dset dev<devname> definition
|
||||
|
||||
<blockquote>
|
||||
<pre>epicsExportAddress(dset,dev<devname>);</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<h3>Driver support</h3>
|
||||
|
||||
<blockquote>
|
||||
Add the following line after all existing #includes
|
||||
|
||||
<blockquote>
|
||||
<pre>#include "epicsExport.h"</pre>
|
||||
</blockquote>
|
||||
and add the following line after the drvet dev<devname> definition
|
||||
|
||||
<blockquote>
|
||||
<pre>epicsExportAddress(drvet,drv<devname>);</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<h3>Registration code changed</h3>
|
||||
|
||||
<blockquote>
|
||||
Registration code for application specific functions, e.g. subroutine
|
||||
record init and process functions, has been changed as follows
|
||||
|
||||
<p>1) Include the registration support header files:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>#include "dbDefs.h"
|
||||
#include "registryFunction.h"</pre>
|
||||
</blockquote>
|
||||
2) Include the export definitions header file after including all other
|
||||
header files:
|
||||
|
||||
<blockquote>
|
||||
<pre>#include "epicsExport.h"</pre>
|
||||
</blockquote>
|
||||
3) Make the application specific functions static functions, e.g.
|
||||
|
||||
<blockquote>
|
||||
<pre>static long mySubInit(subRecord *precord,processMethod process)
|
||||
static long mySubProcess(subRecord *precord)</pre>
|
||||
</blockquote>
|
||||
4) Define a registryFunctionRef array of the application specific functions
|
||||
to be registered, e.g.
|
||||
|
||||
<blockquote>
|
||||
<pre>static registryFunctionRef mySubRef[] = {
|
||||
{"mySubInit",(REGISTRYFUNCTION)mySubInit},
|
||||
{"mySubProcess",(REGISTRYFUNCTION)mySubProcess}
|
||||
};</pre>
|
||||
</blockquote>
|
||||
5) Add a new function to do the registration of the registryFunctionRef
|
||||
array elements, e.g.
|
||||
|
||||
<blockquote>
|
||||
<pre>void mySub(void)
|
||||
{
|
||||
registryFunctionRefAdd(mySubRef,NELEMENTS(mySubRef));
|
||||
}</pre>
|
||||
</blockquote>
|
||||
6) Call the epicsExportRegistrar with the new registration function: e.g.
|
||||
|
||||
<blockquote>
|
||||
<pre>epicsExportRegistrar(mySub);</pre>
|
||||
</blockquote>
|
||||
7) Remove the existing function lines in <appname>Include.dbd: e.g.
|
||||
remove
|
||||
|
||||
<blockquote>
|
||||
<pre>function("mySubInit")
|
||||
function("mySubProcess")</pre>
|
||||
</blockquote>
|
||||
8) Add a registrar statement to <name>Include.dbd with the new
|
||||
registration function as parameter: e.g. add
|
||||
|
||||
<blockquote>
|
||||
<pre>registrar("mySub")</pre>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
|
||||
<h3>Modify the Makefiles in <top>/iocBoot directory.</h3>
|
||||
|
||||
<p>Change " i<tt>nclude $(TOP)/config/CONFIG_APP" </tt>to "<tt>include
|
||||
@@ -196,7 +324,11 @@ $(TOP)/configure/RULES.ioc"</tt></p>
|
||||
|
||||
<p>If it exists remove the line</p>
|
||||
|
||||
<p><tt>buildInstall: cdCommands</tt></p>
|
||||
<p><tt>buildInstall: cdCommands </tt></p>
|
||||
|
||||
<p>Add the line</p>
|
||||
<p><tt>TARGETS = cdCommands</tt></p>
|
||||
<p>befor the include for RULES.ioc line.</p>
|
||||
|
||||
<h3>Modify st.cmd in <top>/iocBoot/ioc* directories.</h3>
|
||||
|
||||
@@ -207,13 +339,17 @@ ld < iocCore</pre>
|
||||
<p>Change "<tt>ld < <libname>Lib</tt>" to "<tt>ld <
|
||||
<libname>.munch"</tt></p>
|
||||
|
||||
<p>Change "<tt>cd appbin</tt>" to "<tt>cd topbin</tt>"</p>
|
||||
|
||||
<p>Change the statement:</p>
|
||||
|
||||
<p><tt>dbLoadDatabase("../../dbd/exampleApp.dbd")</tt> <br>
|
||||
</p>
|
||||
to
|
||||
<pre>dbLoadDatabase("../../dbd/<name>.dbd")
|
||||
registerRecordDeviceDriver(pdbbase)</pre>
|
||||
<name>_registerRecordDeviceDriver(pdbbase)</pre>
|
||||
|
||||
<p>where <name> is replaced with the name of your dbd file.</p>
|
||||
|
||||
<h3>recGbl calls</h3>
|
||||
|
||||
@@ -230,18 +366,13 @@ base.dbd. If these record types are used at your site, they
|
||||
downloaded and built with base R3.14 by your EPICS administrator. To update
|
||||
the R3.14 location of these record types in your application you must add
|
||||
appropriate module definitions to your application's config/RELEASE file and
|
||||
change the <tt>LIBOBJS</tt> definitions.</p>
|
||||
add <tt>LIBOBJS</tt> definitions to the src Makefile.</p>
|
||||
|
||||
<p>For example add</p>
|
||||
|
||||
<p> <tt>PID=<full path to modules directory>/pid</tt></p>
|
||||
|
||||
<p>to config/RELEASE. <br>
|
||||
Remove</p>
|
||||
|
||||
<p> <tt>LIBOBJS += $(EPICS_BASE_BIN)/pidRecord.o</tt></p>
|
||||
|
||||
<p>from baseLIBOBJS, and add</p>
|
||||
<p>to config/RELEASE and add <br>
|
||||
|
||||
<p></p>
|
||||
|
||||
@@ -298,8 +429,7 @@ administrator. dbLoadTemplate is still supported on iocs.
|
||||
application, db files are created from template and substitution files you
|
||||
should add the definition</p>
|
||||
|
||||
<p><tt>EPICS_EXTENSIONS=<full path name to epics extensions
|
||||
directory></tt></p>
|
||||
<p><tt>MSI=<full path name to msi executable></tt></p>
|
||||
|
||||
<p>to your application config/RELEASE file.</p>
|
||||
<br>
|
||||
|
||||
@@ -6,10 +6,32 @@
|
||||
<body>
|
||||
|
||||
<center>
|
||||
<h2> Converting an EPICS R3.14.2 application to R3.14.3</h2></center>
|
||||
<h2>Converting an EPICS R3.14.2 application to R3.14.3</h2></center>
|
||||
|
||||
<p><br>This document describes how to convert a R3.14.2 application
|
||||
so that it builds with release R3.14.3.
|
||||
<p>This document describes how to convert a R3.14.2 application
|
||||
so that it builds and runs properly with release R3.14.3.</p>
|
||||
|
||||
</p><h3>No changes required.</h3>
|
||||
<h3>registerRecordDeviceDriver Name Change</h3>
|
||||
|
||||
<p>All application iocBoot/iocxxx/st.cmd files must be modified for R3.14.3 as
|
||||
the generated routine that registers record device and driver support has been
|
||||
renamed to incorporate the name of the dbd file it came from. The change to
|
||||
the startup script is straightforward; any pair of lines like this:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>dbLoadDatabase("dbd/<i>something</i>.dbd",0,0)
|
||||
registerRecordDeviceDriver(pdbbase)</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>must have the second line changed so the result looks like this:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>dbLoadDatabase("dbd/<i>something</i>.dbd",0,0)
|
||||
<i>something</i>_registerRecordDeviceDriver(pdbbase)</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>There may be other pathname components in the dbLoadDatabase line which
|
||||
should remain exactly as before.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
17
documentation/ConvertingR3.14.3AppsToR3.14.4.html
Normal file
17
documentation/ConvertingR3.14.3AppsToR3.14.4.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en"><html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="jba">
|
||||
<meta name="GENERATOR" content="Mozilla/4.77 [en] (X11; U; SunOS 5.8 sun4u) [Netscape]"></head>
|
||||
|
||||
<body>
|
||||
|
||||
<center>
|
||||
<h2>Converting an EPICS R3.14.3 application to R3.14.4</h2></center>
|
||||
|
||||
<p>This document describes how to convert a R3.14.3 application
|
||||
so that it builds and runs properly with release R3.14.4.</p>
|
||||
|
||||
</p><h3>No changes required.</h3>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -9,7 +9,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1 style="text-align: center">EPICS base R3.14.3: Known Problems</h1>
|
||||
<h1 style="text-align: center">EPICS base R3.14.4: Known Problems</h1>
|
||||
|
||||
<h3>Known Bugs</h3>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ README.1st
|
||||
|
||||
EPICS base
|
||||
|
||||
Release 3.14.3
|
||||
Release 3.14.4
|
||||
|
||||
What is EPICS base?
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ EPICS base</h2></center>
|
||||
|
||||
<center>
|
||||
<h2>
|
||||
Release 3.14.3</h2></center>
|
||||
Release 3.14.4</h2></center>
|
||||
|
||||
<h3>
|
||||
What is EPICS base?</h3>
|
||||
|
||||
@@ -3,17 +3,64 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<title>EPICS Base Release R3.14.3</title>
|
||||
<title>EPICS Base Release R3.14.4</title>
|
||||
</head>
|
||||
|
||||
<body lang="en">
|
||||
|
||||
<center>
|
||||
<h1>EPICS Base Release 3.14.3</h1>
|
||||
<h1>EPICS Base Release 3.14.4</h1>
|
||||
|
||||
<h1>4 September 2003</h1>
|
||||
<h1>????4 September 2003</h1>
|
||||
</center>
|
||||
|
||||
<center>
|
||||
<h2>Changes since 3.14.3</h2>
|
||||
</center>
|
||||
|
||||
<h4>Format string checking</h4</h4>
|
||||
<p>'printf-style' functions like errlogPrintf have their arguments verified
|
||||
against their format string when compiled with gcc.</p>
|
||||
|
||||
<h4>IOC shell command-line editing on vxWorks</h4>
|
||||
|
||||
<p>The IOC shell now uses the vxWorks ledLib routines so command-line editing
|
||||
is now the same in the IOC shell as it is in the vxWorks shell.</p>
|
||||
|
||||
<h4>CA client library crashes when the same PV name is on multiple
|
||||
servers</h4>
|
||||
|
||||
<p>If the CA client library was searching for a PV name that was hosted on
|
||||
more than one server a segmentation violation occurred when printing a
|
||||
diagnostic message resulting in a failure of the CA client library. The bug
|
||||
was introduced in R3.14.3. The code was tested on WIN32 prior to release, but
|
||||
the problem has so far been reproduced only on Linux.</p>
|
||||
|
||||
<p>Thanks to Ernest Williams at the SNS for discovering and helping to
|
||||
diagnose the problem.</p>
|
||||
|
||||
<h4>Disconnection callback function called when CA channel known to be
|
||||
disconnected</h4>
|
||||
|
||||
<p>If a CA circuit timed out during the connect sequence then the CA client
|
||||
library called the applications's disconnect callback function indicating a
|
||||
disconnect state transition when the channel was already known to be
|
||||
disconnected. This has caused the sequencer to improperly maintain its
|
||||
connected channel count. Other CA client side tools may also be impacted.</p>
|
||||
|
||||
<p>Recent versions of vxWorks appear to experience a connect failure if the
|
||||
vxWorks IP kernel reassigns the same ephemeral TCP port number as was
|
||||
assigned during a previous lifetime. The IP kernel on the vxWorks system
|
||||
hosting the CA server might have a stale entry for this ephemeral port that
|
||||
has not yet timed out which prevents the client from connecting with the
|
||||
ephemeral port assigned by the IP kernel. Eventually, after EPICS_CA_CONN_TMO
|
||||
seconds, the TCP connect sequence is aborted and the client library closes
|
||||
the socket, opens a new socket, receives a new ephemeral port assignment, and
|
||||
successfully connects.</p>
|
||||
|
||||
<p>Thanks to Mark Rivers for initially reporting the bug and energetically
|
||||
assisting with identifying the cause.</p>
|
||||
|
||||
<center>
|
||||
<h2>Changes since 3.14.2</h2>
|
||||
</center>
|
||||
|
||||
@@ -123,7 +123,8 @@ have been responsible for specific tasks in the past:</p>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Janet Anderson</td>
|
||||
<td>Edit and commit changes to the EPICS version number file.</td>
|
||||
<td>Edit and commit changes to the EPICS version number files,
|
||||
config/CONFIG_BASE_VERSION and configure/CONFIG_BASE_VERSION.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
@@ -134,7 +135,8 @@ have been responsible for specific tasks in the past:</p>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Janet Anderson</td>
|
||||
<td>Export the tagged version and create the
|
||||
<td>Export the tagged version, "cvs export -kv -d base-x.y.z
|
||||
-r Rx-y-zepics/base", and create the
|
||||
baseR<i>x.y.z</i>[{alpha,beta}<i>n</i>].tar.gz file of the result</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -1159,7 +1159,7 @@ static ASG *asAsgAdd(char *asgName)
|
||||
&& ellCount(&pnext->ruleList)==0)
|
||||
return(pnext);
|
||||
}
|
||||
errMessage(S_asLib_dupAsg,NULL);
|
||||
errMessage(S_asLib_dupAsg,"asAsgAdd");
|
||||
return(NULL);
|
||||
}
|
||||
pnext = (ASG *)ellNext((ELLNODE *)pnext);
|
||||
|
||||
@@ -118,7 +118,8 @@ const char * ca_message_text []
|
||||
"User destroyed channel",
|
||||
"Invalid channel priority",
|
||||
"Preemptive callback not enabled - additional threads may not join context",
|
||||
"Client's protocol revision does not support transfers exceeding 16k bytes"
|
||||
"Client's protocol revision does not support transfers exceeding 16k bytes",
|
||||
"Virtual circuit connection sequence aborted"
|
||||
};
|
||||
|
||||
static epicsThreadOnceId caClientContextIdOnce = EPICS_THREAD_ONCE_INIT;
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#endif
|
||||
|
||||
#include "tsFreeList.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef autoPtrFreeListh_epicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "tsDLList.h"
|
||||
#include "tsFreeList.h"
|
||||
#include "epicsTime.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef bhehEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
|
||||
@@ -481,6 +481,7 @@ void ca_client_context::blockForEventAndEnableCallbacks (
|
||||
|
||||
void ca_client_context::callbackLock ()
|
||||
{
|
||||
|
||||
// if preemptive callback is enabled then this is a noop
|
||||
if ( this->pCallbackGuard.get() ) {
|
||||
bool sendNeeded = false;
|
||||
|
||||
149
src/ca/cac.cpp
149
src/ca/cac.cpp
@@ -534,15 +534,13 @@ bool cac::transferChanToVirtCircuit (
|
||||
return false;
|
||||
}
|
||||
|
||||
bool v41Ok, v42Ok;
|
||||
nciu *pChan;
|
||||
{
|
||||
epicsGuard < cacMutex > guard ( this->mutex );
|
||||
|
||||
/*
|
||||
* ignore search replies for deleted channels
|
||||
*/
|
||||
pChan = this->chanTable.lookup ( cid );
|
||||
nciu * pChan = this->chanTable.lookup ( cid );
|
||||
if ( ! pChan ) {
|
||||
return false;
|
||||
}
|
||||
@@ -607,36 +605,9 @@ bool cac::transferChanToVirtCircuit (
|
||||
this->pudpiiu->uninstallChan ( guard, *pChan );
|
||||
piiu->installChannel ( guard, *pChan, sid, typeCode, count );
|
||||
|
||||
v41Ok = piiu->ca_v41_ok ();
|
||||
v42Ok = piiu->ca_v42_ok ();
|
||||
|
||||
if ( ! v42Ok ) {
|
||||
if ( ! piiu->ca_v42_ok () ) {
|
||||
// connect to old server with lock applied
|
||||
pChan->connect ();
|
||||
// resubscribe for monitors from this channel
|
||||
this->connectAllIO ( guard, *pChan );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! v42Ok ) {
|
||||
// channel uninstal routine grabs the callback lock so
|
||||
// a channel will not be deleted while a call back is
|
||||
// in progress
|
||||
//
|
||||
// the callback lock is also taken when a channel
|
||||
// disconnects to prevent a race condition with the
|
||||
// code below - ie we hold the callback lock here
|
||||
// so a chanel cant be destroyed out from under us.
|
||||
pChan->connectStateNotify ( cbGuard );
|
||||
|
||||
/*
|
||||
* if less than v4.1 then the server will never
|
||||
* send access rights and we know that there
|
||||
* will always be access and also need to call
|
||||
* their call back here
|
||||
*/
|
||||
if ( ! v41Ok ) {
|
||||
pChan->accessRightsNotify ( cbGuard );
|
||||
pChan->connect ( cbGuard, guard );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1027,7 +998,7 @@ void cac::connectAllIO ( epicsGuard < cacMutex > & guard, nciu & chan )
|
||||
while ( pNetIO.valid () ) {
|
||||
tsDLIter < baseNMIU > next = pNetIO;
|
||||
next++;
|
||||
class netSubscription *pSubscr = pNetIO->isSubscription ();
|
||||
class netSubscription * pSubscr = pNetIO->isSubscription ();
|
||||
// disconnected channels should have only subscription IO attached
|
||||
assert ( pSubscr );
|
||||
try {
|
||||
@@ -1337,26 +1308,14 @@ bool cac::accessRightsRespAction (
|
||||
epicsGuard < callbackMutex > & cbGuard, tcpiiu &, // X aCC 431
|
||||
const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBdy */ )
|
||||
{
|
||||
nciu * pChan;
|
||||
{
|
||||
epicsGuard < cacMutex > guard ( this->mutex );
|
||||
pChan = this->chanTable.lookup ( hdr.m_cid );
|
||||
if ( pChan ) {
|
||||
unsigned ar = hdr.m_available;
|
||||
caAccessRights accessRights (
|
||||
( ar & CA_PROTO_ACCESS_RIGHT_READ ) ? true : false,
|
||||
( ar & CA_PROTO_ACCESS_RIGHT_WRITE ) ? true : false);
|
||||
pChan->accessRightsStateChange ( accessRights );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// the channel delete routine takes the call back lock so
|
||||
// that this will not be called when the channel is being
|
||||
// deleted.
|
||||
//
|
||||
epicsGuard < cacMutex > guard ( this->mutex );
|
||||
nciu * pChan = this->chanTable.lookup ( hdr.m_cid );
|
||||
if ( pChan ) {
|
||||
pChan->accessRightsNotify ( cbGuard );
|
||||
unsigned ar = hdr.m_available;
|
||||
caAccessRights accessRights (
|
||||
( ar & CA_PROTO_ACCESS_RIGHT_READ ) ? true : false,
|
||||
( ar & CA_PROTO_ACCESS_RIGHT_WRITE ) ? true : false);
|
||||
pChan->accessRightsStateChange ( accessRights, cbGuard, guard );
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1366,33 +1325,28 @@ bool cac::claimCIURespAction (
|
||||
epicsGuard < callbackMutex > &cbGuard, tcpiiu & iiu, // X aCC 431
|
||||
const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBdy */ )
|
||||
{
|
||||
nciu * pChan;
|
||||
|
||||
{
|
||||
epicsGuard < cacMutex > guard ( this->mutex );
|
||||
pChan = this->chanTable.lookup ( hdr.m_cid );
|
||||
if ( pChan ) {
|
||||
unsigned sidTmp;
|
||||
if ( iiu.ca_v44_ok() ) {
|
||||
sidTmp = hdr.m_available;
|
||||
}
|
||||
else {
|
||||
sidTmp = pChan->getSID ();
|
||||
}
|
||||
pChan->connect ( hdr.m_dataType, hdr.m_count, sidTmp, iiu.ca_v41_ok() );
|
||||
this->connectAllIO ( guard, *pChan );
|
||||
}
|
||||
else if ( iiu.ca_v44_ok() ) {
|
||||
// this indicates a claim response for a resource that does
|
||||
// not exist in the client - so just remove it from the server
|
||||
iiu.clearChannelRequest ( guard, hdr.m_available, hdr.m_cid );
|
||||
}
|
||||
}
|
||||
// the callback lock is taken when a channel is unistalled or when
|
||||
// is disconnected to prevent race conditions here
|
||||
epicsGuard < cacMutex > guard ( this->mutex );
|
||||
nciu * pChan = this->chanTable.lookup ( hdr.m_cid );
|
||||
if ( pChan ) {
|
||||
pChan->connectStateNotify ( cbGuard );
|
||||
unsigned sidTmp;
|
||||
if ( iiu.ca_v44_ok() ) {
|
||||
sidTmp = hdr.m_available;
|
||||
}
|
||||
else {
|
||||
sidTmp = pChan->getSID ();
|
||||
}
|
||||
|
||||
// the callback lock is taken when a channel is unistalled or when
|
||||
// is disconnected to prevent race conditions here
|
||||
pChan->connect ( hdr.m_dataType, hdr.m_count, sidTmp,
|
||||
cbGuard, guard );
|
||||
}
|
||||
else if ( iiu.ca_v44_ok() ) {
|
||||
// this indicates a claim response for a resource that does
|
||||
// not exist in the client - so just remove it from the server
|
||||
iiu.clearChannelRequest ( guard, hdr.m_available, hdr.m_cid );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1417,11 +1371,8 @@ void cac::disconnectChannel (
|
||||
assert ( this->pudpiiu );
|
||||
this->disconnectAllIO ( guard, chan, true );
|
||||
chan.getPIIU()->uninstallChan ( guard, chan );
|
||||
chan.disconnect ( *this->pudpiiu );
|
||||
chan.disconnect ( *this->pudpiiu, cbGuard, guard );
|
||||
this->pudpiiu->installDisconnectedChannel ( currentTime, chan );
|
||||
epicsGuardRelease < cacMutex > autoMutexRelease ( guard );
|
||||
chan.connectStateNotify ( cbGuard );
|
||||
chan.accessRightsNotify ( cbGuard );
|
||||
}
|
||||
|
||||
bool cac::badTCPRespAction ( epicsGuard < callbackMutex > &, tcpiiu & iiu,
|
||||
@@ -1508,6 +1459,7 @@ void cac::vSignal ( int ca_status, const char *pfilenm,
|
||||
|
||||
void cac::selfTest () const
|
||||
{
|
||||
epicsGuard < cacMutex > guard ( this->mutex );
|
||||
this->chanTable.verify ();
|
||||
this->ioTable.verify ();
|
||||
this->sgTable.verify ();
|
||||
@@ -1522,21 +1474,34 @@ void cac::disconnectNotify ( tcpiiu & iiu )
|
||||
|
||||
void cac::initiateAbortShutdown ( tcpiiu & iiu )
|
||||
{
|
||||
int exception = ECA_DISCONN;
|
||||
char hostNameTmp[64];
|
||||
bool exceptionNeeded = false;
|
||||
epicsGuard < callbackMutex > cbGuard ( this->cbMutex );
|
||||
epicsGuard < cacMutex > guard ( this->mutex );
|
||||
|
||||
iiu.initiateAbortShutdown ( cbGuard, guard );
|
||||
{
|
||||
epicsGuard < cacMutex > guard ( this->mutex );
|
||||
|
||||
// Disconnect all channels immediately from the timer thread
|
||||
// because on certain OS such as HPUX it's difficult to
|
||||
// unblock a blocking send() call, and we need immediate
|
||||
// disconnect notification.
|
||||
if ( iiu.channelCount() ) {
|
||||
char hostNameTmp[64];
|
||||
iiu.hostName ( hostNameTmp, sizeof ( hostNameTmp ) );
|
||||
genLocalExcep ( cbGuard, *this, ECA_DISCONN, hostNameTmp );
|
||||
if ( iiu.channelCount() ) {
|
||||
iiu.hostName ( hostNameTmp, sizeof ( hostNameTmp ) );
|
||||
if ( iiu.connecting () ) {
|
||||
exception = ECA_CONNSEQTMO;
|
||||
}
|
||||
exceptionNeeded = true;
|
||||
}
|
||||
|
||||
iiu.initiateAbortShutdown ( cbGuard, guard );
|
||||
|
||||
// Disconnect all channels immediately from the timer thread
|
||||
// because on certain OS such as HPUX it's difficult to
|
||||
// unblock a blocking send() call, and we need immediate
|
||||
// disconnect notification.
|
||||
iiu.removeAllChannels ( cbGuard, guard, *this );
|
||||
}
|
||||
|
||||
if ( exceptionNeeded ) {
|
||||
genLocalExcep ( cbGuard, *this, exception, hostNameTmp );
|
||||
}
|
||||
iiu.removeAllChannels ( cbGuard, guard, *this );
|
||||
}
|
||||
|
||||
void cac::destroyIIU ( tcpiiu & iiu )
|
||||
|
||||
29
src/ca/cac.h
29
src/ca/cac.h
@@ -31,7 +31,7 @@
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
#include "ipAddrToAsciiAsynchronous.h"
|
||||
#include "msgForMultiplyDefinedPV.h"
|
||||
#include "epicsTimer.h"
|
||||
@@ -72,18 +72,6 @@ struct caHdrLargeArray;
|
||||
|
||||
extern epicsThreadPrivateId caClientCallbackThreadId;
|
||||
|
||||
class callbackMutex {
|
||||
public:
|
||||
callbackMutex ( cacNotify & );
|
||||
~callbackMutex ();
|
||||
void lock ();
|
||||
void unlock ();
|
||||
private:
|
||||
cacNotify & notify;
|
||||
callbackMutex ( callbackMutex & );
|
||||
callbackMutex & operator = ( callbackMutex & );
|
||||
};
|
||||
|
||||
class cacMutex {
|
||||
public:
|
||||
void lock ();
|
||||
@@ -110,6 +98,18 @@ public:
|
||||
epicsGuard < cacMutex > &, nciu & chan ) = 0;
|
||||
};
|
||||
|
||||
class callbackMutex {
|
||||
public:
|
||||
callbackMutex ( cacNotify & );
|
||||
~callbackMutex ();
|
||||
void lock ();
|
||||
void unlock ();
|
||||
private:
|
||||
cacNotify & notify;
|
||||
callbackMutex ( callbackMutex & );
|
||||
callbackMutex & operator = ( callbackMutex & );
|
||||
};
|
||||
|
||||
class cac : private cacRecycle, private cacDisconnectChannelPrivate,
|
||||
private callbackForMultiplyDefinedPV
|
||||
{
|
||||
@@ -134,7 +134,7 @@ public:
|
||||
unsigned cid, unsigned sid,
|
||||
ca_uint16_t typeCode, arrayElementCount count,
|
||||
unsigned minorVersionNumber, const osiSockAddr & );
|
||||
|
||||
void connectAllIO ( epicsGuard < cacMutex > &, nciu & chan );
|
||||
void destroyChannel ( nciu & );
|
||||
cacChannel & createChannel ( const char *name_str,
|
||||
cacChannelNotify &chan, cacChannel::priLev pri );
|
||||
@@ -255,7 +255,6 @@ private:
|
||||
unsigned beaconAnomalyCount;
|
||||
|
||||
void run ();
|
||||
void connectAllIO ( epicsGuard < cacMutex > &, nciu &chan );
|
||||
void disconnectAllIO ( epicsGuard < cacMutex > & locker, nciu & chan, bool enableCallbacks );
|
||||
void flushIfRequired ( epicsGuard < cacMutex > &, netiiu & );
|
||||
void recycleReadNotifyIO ( netReadNotifyIO &io );
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
|
||||
#include "tsDLList.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsSingleton.h"
|
||||
|
||||
#ifdef cacIOh_restore_epicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
@@ -250,6 +251,7 @@ private:
|
||||
};
|
||||
|
||||
template < class T > class epicsSingleton;
|
||||
|
||||
epicsShareExtern epicsSingleton < cacServiceList > globalServiceListCAC;
|
||||
|
||||
epicsShareFunc int epicsShareAPI ca_register_service ( cacService *pService );
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
#define ECA_BADPRIORITY DEFMSG(CA_K_ERROR, 56)
|
||||
#define ECA_NOTTHREADED DEFMSG(CA_K_ERROR, 57)
|
||||
#define ECA_16KARRAYCLIENT DEFMSG(CA_K_WARNING, 58)
|
||||
#define ECA_CONNSEQTMO DEFMSG(CA_K_WARNING, 59)
|
||||
|
||||
#ifdef __STDC__
|
||||
#define CAERR_USE_FUNC_PROTO
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "tsFreeList.h"
|
||||
#include "tsDLList.h"
|
||||
#include "osiWireFormat.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
static const unsigned comBufSize = 0x4000;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "ipAddrToAsciiAsynchronous.h"
|
||||
#include "tsFreeList.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
class callbackForMultiplyDefinedPV { // X aCC 655
|
||||
public:
|
||||
|
||||
@@ -109,7 +109,9 @@ void nciu::initiateConnect ()
|
||||
}
|
||||
|
||||
void nciu::connect ( unsigned nativeType,
|
||||
unsigned nativeCount, unsigned sidIn, bool v41Ok )
|
||||
unsigned nativeCount, unsigned sidIn,
|
||||
epicsGuard < callbackMutex > & cbGuard,
|
||||
epicsGuard < cacMutex > & guard )
|
||||
{
|
||||
if ( ! this->f_claimSent ) {
|
||||
this->cacCtx.printf (
|
||||
@@ -141,14 +143,46 @@ void nciu::connect ( unsigned nativeType,
|
||||
* if less than v4.1 then the server will never
|
||||
* send access rights and there will always be access
|
||||
*/
|
||||
bool v41Ok = this->piiu->ca_v41_ok ();
|
||||
if ( ! v41Ok ) {
|
||||
this->accessRightState.setReadPermit();
|
||||
this->accessRightState.setWritePermit();
|
||||
}
|
||||
|
||||
// this installs any subscriptions that
|
||||
// might still be attached
|
||||
this->cacCtx.connectAllIO ( guard, *this );
|
||||
|
||||
{
|
||||
epicsGuardRelease < cacMutex > unguard ( guard );
|
||||
|
||||
// channel uninstal routine grabs the callback lock so
|
||||
// a channel will not be deleted while a call back is
|
||||
// in progress
|
||||
//
|
||||
// the callback lock is also taken when a channel
|
||||
// disconnects to prevent a race condition with the
|
||||
// code below - ie we hold the callback lock here
|
||||
// so a chanel cant be destroyed out from under us.
|
||||
this->notify().connectNotify ();
|
||||
|
||||
/*
|
||||
* if less than v4.1 then the server will never
|
||||
* send access rights and we know that there
|
||||
* will always be access and also need to call
|
||||
* their call back here
|
||||
*/
|
||||
if ( ! v41Ok ) {
|
||||
this->notify().accessRightsNotify ( this->accessRightState );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::disconnect ( netiiu & newiiu )
|
||||
void nciu::disconnect (
|
||||
netiiu & newiiu, epicsGuard < callbackMutex > & cbGuard,
|
||||
epicsGuard < cacMutex > & guard )
|
||||
{
|
||||
bool currentlyConnected = this->f_connected;
|
||||
this->piiu = & newiiu;
|
||||
this->retry = disconnectRetrySetpoint;
|
||||
this->typeCode = USHRT_MAX;
|
||||
@@ -158,6 +192,26 @@ void nciu::disconnect ( netiiu & newiiu )
|
||||
this->accessRightState.clrWritePermit();
|
||||
this->f_claimSent = false;
|
||||
this->f_connected = false;
|
||||
if ( currentlyConnected ) {
|
||||
epicsGuardRelease < cacMutex > autoMutexRelease ( guard );
|
||||
this->notify().disconnectNotify ();
|
||||
this->notify().accessRightsNotify ( this->accessRightState );
|
||||
}
|
||||
}
|
||||
|
||||
void nciu::accessRightsStateChange (
|
||||
const caAccessRights & arIn, epicsGuard < callbackMutex > &,
|
||||
epicsGuard < cacMutex > & guard )
|
||||
{
|
||||
this->accessRightState = arIn;
|
||||
|
||||
//
|
||||
// the channel delete routine takes the call back lock so
|
||||
// that this will not be called when the channel is being
|
||||
// deleted.
|
||||
//
|
||||
epicsGuardRelease < cacMutex > unguard ( guard );
|
||||
this->notify().accessRightsNotify ( this->accessRightState );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "tsDLList.h"
|
||||
#include "tsFreeList.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef nciuh_restore_epicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
@@ -70,17 +70,19 @@ public:
|
||||
~nciu ();
|
||||
void destroy ();
|
||||
void connect ( unsigned nativeType,
|
||||
unsigned nativeCount, unsigned sid, bool v41Ok );
|
||||
void connect ();
|
||||
void connectStateNotify ( epicsGuard < callbackMutex > & ) const;
|
||||
void accessRightsNotify ( epicsGuard < callbackMutex > & ) const;
|
||||
void disconnect ( netiiu & newiiu );
|
||||
unsigned nativeCount, unsigned sid,
|
||||
epicsGuard < callbackMutex > & cbGuard,
|
||||
epicsGuard < cacMutex > & guard );
|
||||
void connect ( epicsGuard < callbackMutex > & cbGuard,
|
||||
epicsGuard < cacMutex > & guard );
|
||||
void disconnect ( netiiu & newiiu, epicsGuard < callbackMutex > & cbGuard,
|
||||
epicsGuard < cacMutex > & guard );
|
||||
bool searchMsg ( class udpiiu & iiu, unsigned & retryNoForThisChannel );
|
||||
void createChannelRequest ( class tcpiiu & iiu, epicsGuard < cacMutex > & );
|
||||
bool identifierEquivelence ( unsigned idToMatch );
|
||||
void beaconAnomalyNotify ();
|
||||
void serviceShutdownNotify ();
|
||||
void accessRightsStateChange ( const caAccessRights & );
|
||||
void accessRightsStateChange ( const caAccessRights &,
|
||||
epicsGuard < callbackMutex > &, epicsGuard < cacMutex > & );
|
||||
ca_uint32_t getSID () const;
|
||||
ca_uint32_t getCID () const;
|
||||
netiiu * getPIIU ();
|
||||
@@ -88,7 +90,8 @@ public:
|
||||
cac & getClient ();
|
||||
int printf ( const char *pFormat, ... );
|
||||
void searchReplySetUp ( netiiu &iiu, unsigned sidIn,
|
||||
ca_uint16_t typeIn, arrayElementCount countIn );
|
||||
ca_uint16_t typeIn, arrayElementCount countIn,
|
||||
epicsGuard < cacMutex > & );
|
||||
void show ( unsigned level ) const;
|
||||
const char *pName () const;
|
||||
unsigned nameLen () const;
|
||||
@@ -152,16 +155,6 @@ inline void nciu::operator delete ( void * pCadaver,
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool nciu::identifierEquivelence ( unsigned idToMatch )
|
||||
{
|
||||
return idToMatch == this->id;
|
||||
}
|
||||
|
||||
inline void nciu::accessRightsStateChange ( const caAccessRights & arIn )
|
||||
{
|
||||
this->accessRightState = arIn;
|
||||
}
|
||||
|
||||
inline ca_uint32_t nciu::getSID () const
|
||||
{
|
||||
return this->sid;
|
||||
@@ -173,15 +166,18 @@ inline ca_uint32_t nciu::getCID () const
|
||||
}
|
||||
|
||||
// this is to only be used by early protocol revisions
|
||||
inline void nciu::connect ()
|
||||
inline void nciu::connect ( epicsGuard < callbackMutex > & cbGuard,
|
||||
epicsGuard < cacMutex > & guard )
|
||||
{
|
||||
this->connect ( this->typeCode, this->count, this->sid, false );
|
||||
this->connect ( this->typeCode, this->count,
|
||||
this->sid, cbGuard, guard );
|
||||
}
|
||||
|
||||
inline void nciu::searchReplySetUp ( netiiu &iiu, unsigned sidIn,
|
||||
ca_uint16_t typeIn, arrayElementCount countIn )
|
||||
ca_uint16_t typeIn, arrayElementCount countIn,
|
||||
epicsGuard < cacMutex > & )
|
||||
{
|
||||
this->piiu = &iiu;
|
||||
this->piiu = & iiu;
|
||||
this->typeCode = typeIn;
|
||||
this->count = countIn;
|
||||
this->sid = sidIn;
|
||||
@@ -203,21 +199,6 @@ inline void nciu::writeException ( epicsGuard < callbackMutex > &, int status,
|
||||
this->notify().writeException ( status, pContext, typeIn, countIn );
|
||||
}
|
||||
|
||||
inline void nciu::accessRightsNotify ( epicsGuard < callbackMutex > & ) const
|
||||
{
|
||||
this->notify().accessRightsNotify ( this->accessRightState );
|
||||
}
|
||||
|
||||
inline void nciu::connectStateNotify ( epicsGuard < callbackMutex > & ) const
|
||||
{
|
||||
if ( this->f_connected ) {
|
||||
this->notify().connectNotify ();
|
||||
}
|
||||
else {
|
||||
this->notify().disconnectNotify ();
|
||||
}
|
||||
}
|
||||
|
||||
inline const netiiu * nciu::getConstPIIU () const
|
||||
{
|
||||
return this->piiu;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#define netIOh
|
||||
|
||||
#include "nciu.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
// SUN PRO generates multiply defined symbols if the baseNMIU
|
||||
// destructor is virtual (therefore it is protected).
|
||||
|
||||
@@ -37,6 +37,11 @@ bool netiiu::ca_v42_ok () const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool netiiu::ca_v41_ok () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void netiiu::writeRequest ( epicsGuard < cacMutex > &, nciu &,
|
||||
unsigned, unsigned, const void * )
|
||||
{
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
virtual ~netiiu ();
|
||||
virtual void hostName ( char *pBuf, unsigned bufLength ) const = 0;
|
||||
virtual const char * pHostName () const = 0; // deprecated - please do not use
|
||||
virtual bool ca_v41_ok () const = 0;
|
||||
virtual bool ca_v42_ok () const = 0;
|
||||
virtual void writeRequest ( epicsGuard < cacMutex > &, nciu &,
|
||||
unsigned type, unsigned nElem, const void *pValue ) = 0;
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#include "tsFreeList.h"
|
||||
#include "epicsMemory.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
#include "osiSock.h"
|
||||
|
||||
#ifdef oldAccessh_restore_epicsExportSharedSymbols
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#include "tsDLList.h"
|
||||
#include "tsFreeList.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef repeaterClienth_restore_epicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "tsFreeList.h"
|
||||
#include "resourceLib.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef syncGrouph_restore_epicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
|
||||
@@ -638,7 +638,7 @@ void tcpiiu::disconnectNotify ( epicsGuard < cacMutex > & )
|
||||
}
|
||||
|
||||
void tcpiiu::initiateAbortShutdown ( epicsGuard < callbackMutex > &,
|
||||
epicsGuard < cacMutex > & )
|
||||
epicsGuard < cacMutex > & guard )
|
||||
{
|
||||
if ( ! this->discardingPendingData ) {
|
||||
// force abortive shutdown sequence
|
||||
@@ -1306,7 +1306,7 @@ void tcpiiu::installChannel ( epicsGuard < cacMutex > & guard,
|
||||
ca_uint16_t typeIn, arrayElementCount countIn )
|
||||
{
|
||||
this->channelList.add ( chan );
|
||||
chan.searchReplySetUp ( *this, sidIn, typeIn, countIn );
|
||||
chan.searchReplySetUp ( *this, sidIn, typeIn, countIn, guard );
|
||||
chan.createChannelRequest ( *this, guard );
|
||||
this->flushRequest ();
|
||||
}
|
||||
|
||||
@@ -476,7 +476,6 @@ void epicsShareAPI caStartRepeaterIfNotInstalled ( unsigned repeaterPort )
|
||||
struct sockaddr_in ia;
|
||||
struct sockaddr sa;
|
||||
} bd;
|
||||
int flag;
|
||||
|
||||
if ( repeaterPort > 0xffff ) {
|
||||
fprintf ( stderr, "caStartRepeaterIfNotInstalled () : strange repeater port specified\n" );
|
||||
@@ -1094,6 +1093,11 @@ bool udpiiu::ca_v42_ok () const
|
||||
return netiiu::ca_v42_ok ();
|
||||
}
|
||||
|
||||
bool udpiiu::ca_v41_ok () const
|
||||
{
|
||||
return netiiu::ca_v41_ok ();
|
||||
}
|
||||
|
||||
void udpiiu::writeRequest ( epicsGuard < cacMutex > & guard, nciu & chan, unsigned type,
|
||||
unsigned nElem, const void * pValue )
|
||||
{
|
||||
|
||||
@@ -163,6 +163,7 @@ private:
|
||||
void hostName ( char *pBuf, unsigned bufLength ) const;
|
||||
const char * pHostName () const; // deprecated - please do not use
|
||||
bool ca_v42_ok () const;
|
||||
bool ca_v41_ok () const;
|
||||
void writeRequest ( epicsGuard < cacMutex > &, nciu &, unsigned type,
|
||||
unsigned nElem, const void *pValue );
|
||||
void writeNotifyRequest ( epicsGuard < cacMutex > &, nciu &, netWriteNotifyIO &,
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "tcpRecvWatchdog.h"
|
||||
#include "tcpSendWatchdog.h"
|
||||
#include "hostNameCache.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
// a modified ca header with capacity for large arrays
|
||||
struct caHdrLargeArray {
|
||||
@@ -124,6 +124,7 @@ public:
|
||||
|
||||
void hostName ( char *pBuf, unsigned bufLength ) const;
|
||||
bool alive () const;
|
||||
bool connecting () const;
|
||||
osiSockAddr getNetworkAddress () const;
|
||||
int printf ( const char *pformat, ... );
|
||||
unsigned channelCount ();
|
||||
@@ -251,6 +252,11 @@ inline bool tcpiiu::alive () const // X aCC 361
|
||||
this->state == iiucs_connected );
|
||||
}
|
||||
|
||||
inline bool tcpiiu::connecting () const
|
||||
{
|
||||
return ( this->state == iiucs_connecting );
|
||||
}
|
||||
|
||||
inline void tcpiiu::beaconAnomalyNotify ()
|
||||
{
|
||||
this->recvDog.beaconAnomalyNotify ();
|
||||
|
||||
@@ -92,7 +92,7 @@ casEventMask casEventRegistry::registerEvent ( const char *pName )
|
||||
else {
|
||||
mask = this->maskAllocator ();
|
||||
if ( mask.mask == 0u ) {
|
||||
errMessage ( S_cas_tooManyEvents, NULL );
|
||||
errMessage ( S_cas_tooManyEvents, "casEventRegistry::registerEvent" );
|
||||
}
|
||||
else {
|
||||
pEntry = new casEventMaskEntry ( *this, mask, pName );
|
||||
|
||||
@@ -949,7 +949,7 @@ caStatus casStrmClient::writeResponse (
|
||||
caStatus status;
|
||||
|
||||
if ( completionStatus ) {
|
||||
errMessage ( completionStatus, NULL );
|
||||
errMessage ( completionStatus, "write failed" );
|
||||
status = this->sendErrWithEpicsStatus ( guard, & msg,
|
||||
chan.getCID(), completionStatus, ECA_PUTFAIL );
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "tsFreeList.h"
|
||||
#include "osiSock.h"
|
||||
#include "inetAddrID.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef ipIgnoreEntryEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "tsFreeList.h"
|
||||
#include "resourceLib.h"
|
||||
#include "cacIO.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef dbCACh_restore_epicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef dbChannelIOh_restore_epicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
|
||||
@@ -353,7 +353,7 @@ STATIC void dbtpnCallback(putNotify *ppn)
|
||||
if(status==0)
|
||||
printf("dbtpnCallback: success record=%s\n",ppn->paddr->precord->name);
|
||||
else
|
||||
errlogPrintf("%s dbtpnCallback putNotify.status %d\n",(int)status);
|
||||
errlogPrintf("%s dbtpnCallback putNotify.status %d\n",ppn->paddr->precord->name,(int)status);
|
||||
free((void *)ppn->paddr);
|
||||
free(ppn);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#endif
|
||||
|
||||
#include "tsFreeList.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef dbPutNotifyBlockerh_restore_epicsExportSharedSymbols
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
@@ -644,7 +644,7 @@ static void tpnCallback(putNotify *ppn)
|
||||
if(status==0)
|
||||
printf("tpnCallback: success record=%s\n",pname);
|
||||
else
|
||||
errlogPrintf("%s tpnCallback status = %d\n",status);
|
||||
errlogPrintf("%s tpnCallback status = %d\n",pname,status);
|
||||
free((void *)pdbaddr);
|
||||
free(ppn);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "gpHash.h"
|
||||
#include "dbmf.h"
|
||||
#include "postfix.h"
|
||||
#include "sCalcPostfix.h"
|
||||
#include "osiFileName.h"
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
@@ -1995,14 +1994,9 @@ long epicsShareAPI dbPutString(DBENTRY *pdbentry,const char *pstring)
|
||||
strncpy((char *)pfield, pstring,pflddes->size);
|
||||
if((pflddes->special == SPC_CALC) && !stringHasMacro) {
|
||||
char rpcl[RPCL_LEN];
|
||||
char *psCalcrpcl = 0;
|
||||
short error_number;
|
||||
|
||||
status = postfix(pstring,rpcl,&error_number);
|
||||
if(status) {
|
||||
status = sCalcPostfix(pstring,&psCalcrpcl,&error_number);
|
||||
free((void *)psCalcrpcl);
|
||||
}
|
||||
if(status) status = S_dbLib_badField;
|
||||
}
|
||||
if((short)strlen(pstring) >= pflddes->size) status = S_dbLib_strLen;
|
||||
@@ -2375,15 +2369,10 @@ char * epicsShareAPI dbVerify(DBENTRY *pdbentry,const char *pstring)
|
||||
}
|
||||
if((pflddes->special == SPC_CALC) && !stringHasMacro) {
|
||||
char rpcl[RPCL_LEN];
|
||||
char *psCalcrpcl = 0;
|
||||
short error_number;
|
||||
long status;
|
||||
|
||||
status = postfix(pstring,rpcl,&error_number);
|
||||
if(status) {
|
||||
status = sCalcPostfix(pstring,&psCalcrpcl,&error_number);
|
||||
free((void *)psCalcrpcl);
|
||||
}
|
||||
if(status) {
|
||||
sprintf(message,"Illegal Calculation String");
|
||||
return(message);
|
||||
|
||||
@@ -71,6 +71,13 @@ templ: templ_head O_BRACE subst C_BRACE
|
||||
;
|
||||
|
||||
templ_head: DBFILE WORD
|
||||
{
|
||||
var_count=0;
|
||||
if(db_file_name) dbmfFree(db_file_name);
|
||||
db_file_name = dbmfMalloc(strlen($2)+1);
|
||||
strcpy(db_file_name,$2);
|
||||
dbmfFree($2);
|
||||
}
|
||||
| DBFILE QUOTE
|
||||
{
|
||||
var_count=0;
|
||||
|
||||
@@ -31,13 +31,10 @@ SRCS += epicsRingPointer.cpp
|
||||
SRCS += epicsRingBytes.c
|
||||
|
||||
SRC_DIRS += $(LIBCOM)/calc
|
||||
#following needed for locating postfixPvt.h and sCalcPostfixPvt.h
|
||||
#following needed for locating postfixPvt.h
|
||||
INC += postfix.h
|
||||
INC += sCalcPostfix.h
|
||||
SRCS += postfix.c
|
||||
SRCS += calcPerform.c
|
||||
SRCS += sCalcPostfix.c
|
||||
SRCS += sCalcPerform.c
|
||||
|
||||
SRC_DIRS += $(LIBCOM)/cvtFast
|
||||
INC += cvtFast.h
|
||||
@@ -129,7 +126,7 @@ INC += truncateFile.h
|
||||
INC += unixFileName.h
|
||||
INC += locationException.h
|
||||
INC += ipAddrToAsciiAsynchronous.h
|
||||
INC += cxxCompilerDependencies.h
|
||||
INC += compilerDependencies.h
|
||||
SRCS += aToIPAddr.c
|
||||
SRCS += adjustment.c
|
||||
SRCS += cantProceed.c
|
||||
@@ -227,9 +224,7 @@ SRC_DIRS += $(LIBCOM)/tsDefs
|
||||
INC += tsDefs.h
|
||||
SRCS += tsDefs.c
|
||||
|
||||
# For WIN32 we supply getopt as part of libCom:
|
||||
INC_WIN32 := getopt.h
|
||||
SRCS_WIN32 := getopt.c
|
||||
# For WIN32
|
||||
SRCS_WIN32 += dllmain.cpp
|
||||
SRCS_WIN32 += forceBadAllocException.cpp
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,682 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* $Id$
|
||||
* Subroutines used to convert an infix expression to a postfix expression
|
||||
*
|
||||
* Author: Bob Dalesio
|
||||
* Date: 12-12-86
|
||||
*/
|
||||
|
||||
/*
|
||||
* Subroutines
|
||||
*
|
||||
* Public
|
||||
*
|
||||
* sCalcPostfix convert an algebraic expression to symbolic postfix
|
||||
* args
|
||||
* pinfix the algebraic expression
|
||||
* pp_postfix address of the symbolic postfix expression
|
||||
* perror error information
|
||||
* returns
|
||||
* 0 successful
|
||||
* -1 not successful
|
||||
* Private routines for calcPostfix
|
||||
*
|
||||
* find_element finds a symbolic element in the expression element tbl
|
||||
* args
|
||||
* pbuffer pointer to the infix expression element
|
||||
* pelement pointer to the expression element table entry
|
||||
* pno_bytes pointer to the size of this element
|
||||
* parg pointer to arg (used for fetch)
|
||||
* returns
|
||||
* TRUE element found
|
||||
* FALSE element not found
|
||||
*
|
||||
* get_element finds the next expression element in the infix expr
|
||||
* args
|
||||
* pinfix pointer into the infix expression
|
||||
* pelement pointer to the expression element table
|
||||
* pno_bytes size of the element in the infix expression
|
||||
* parg pointer to argument (used for fetch)
|
||||
* returns
|
||||
* FINE found an expression element
|
||||
* VARIABLE found a database reference
|
||||
* UNKNOWN_ELEMENT unknown element found in the infix expression
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "dbDefs.h"
|
||||
#define epicsExportSharedSymbols
|
||||
#include "sCalcPostfix.h"
|
||||
#include "sCalcPostfixPvt.h"
|
||||
|
||||
|
||||
#define OVERRIDESTDCALC 0
|
||||
#define DEBUG 0
|
||||
volatile int sCalcPostfixDebug=0;
|
||||
|
||||
/* declarations for postfix */
|
||||
/* element types */
|
||||
#define OPERAND 0
|
||||
#define UNARY_OPERATOR 1
|
||||
#define BINARY_OPERATOR 2
|
||||
#define EXPR_TERM 3
|
||||
#define COND 4
|
||||
#define CLOSE_PAREN 5
|
||||
#define CONDITIONAL 6
|
||||
#define ELSE 7
|
||||
#define SEPARATOR 8
|
||||
#define TRASH 9
|
||||
#define FLOAT_PT_CONST 10
|
||||
#define MINUS_OPERATOR 11
|
||||
#define STRING_CONST 12
|
||||
#define CLOSE_BRACKET 13
|
||||
#define CLOSE_CURLY 14
|
||||
|
||||
#define UNARY_MINUS_I_S_P 7
|
||||
#define UNARY_MINUS_I_C_P 8
|
||||
#define UNARY_MINUS_CODE UNARY_NEG
|
||||
#define BINARY_MINUS_I_S_P 4
|
||||
#define BINARY_MINUS_I_C_P 4
|
||||
#define BINARY_MINUS_CODE SUB
|
||||
|
||||
/* parsing return values */
|
||||
#define FINE 0
|
||||
#define UNKNOWN_ELEMENT -1
|
||||
#define END -2
|
||||
|
||||
/*
|
||||
* element table
|
||||
*
|
||||
* structure of an element
|
||||
*/
|
||||
struct expression_element{
|
||||
char element[10]; /* character representation of an element */
|
||||
char in_stack_pri; /* priority in translation stack */
|
||||
char in_coming_pri; /* priority when first checking */
|
||||
char type; /* element type */
|
||||
char code; /* postfix representation */
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: DO NOT CHANGE WITHOUT READING THIS NOTICE !!!!!!!!!!!!!!!!!!!!
|
||||
* Because the routine that looks for a match in this table takes the first
|
||||
* match it finds, elements whose designations are contained in other elements
|
||||
* MUST come first in this list. (e.g. ABS will match A if A preceeds ABS and
|
||||
* then try to find BS therefore ABS must be first in this list
|
||||
*/
|
||||
static struct expression_element elements[] = {
|
||||
/*
|
||||
element i_s_p i_c_p type_element internal_rep */
|
||||
{"ABS", 7, 8, UNARY_OPERATOR, ABS_VAL}, /* absolute value */
|
||||
{"NOT", 7, 8, UNARY_OPERATOR, UNARY_NEG}, /* unary negate */
|
||||
{"-", 7, 8, MINUS_OPERATOR, UNARY_NEG}, /* unary negate (or binary op) */
|
||||
{"SQRT", 7, 8, UNARY_OPERATOR, SQU_RT}, /* square root */
|
||||
{"SQR", 7, 8, UNARY_OPERATOR, SQU_RT}, /* square root */
|
||||
{"EXP", 7, 8, UNARY_OPERATOR, EXP}, /* exponential function */
|
||||
{"LOGE", 7, 8, UNARY_OPERATOR, LOG_E}, /* log E */
|
||||
{"LN", 7, 8, UNARY_OPERATOR, LOG_E}, /* log E */
|
||||
{"LOG", 7, 8, UNARY_OPERATOR, LOG_10}, /* log 10 */
|
||||
{"ACOS", 7, 8, UNARY_OPERATOR, ACOS}, /* arc cosine */
|
||||
{"ASIN", 7, 8, UNARY_OPERATOR, ASIN}, /* arc sine */
|
||||
{"ATAN2", 7, 8, UNARY_OPERATOR, ATAN2}, /* arc tangent */
|
||||
{"ATAN", 7, 8, UNARY_OPERATOR, ATAN}, /* arc tangent */
|
||||
{"MAX", 7, 8, UNARY_OPERATOR, MAX_VAL}, /* maximum of 2 args */
|
||||
{"MIN", 7, 8, UNARY_OPERATOR, MIN_VAL}, /* minimum of 2 args */
|
||||
{"CEIL", 7, 8, UNARY_OPERATOR, CEIL}, /* smallest integer >= */
|
||||
{"FLOOR", 7, 8, UNARY_OPERATOR, FLOOR}, /* largest integer <= */
|
||||
{"NINT", 7, 8, UNARY_OPERATOR, NINT}, /* nearest integer */
|
||||
{"INT", 7, 8, UNARY_OPERATOR, NINT}, /* nearest integer */
|
||||
{"COSH", 7, 8, UNARY_OPERATOR, COSH}, /* hyperbolic cosine */
|
||||
{"COS", 7, 8, UNARY_OPERATOR, COS}, /* cosine */
|
||||
{"SINH", 7, 8, UNARY_OPERATOR, SINH}, /* hyperbolic sine */
|
||||
{"SIN", 7, 8, UNARY_OPERATOR, SIN}, /* sine */
|
||||
{"TANH", 7, 8, UNARY_OPERATOR, TANH}, /* hyperbolic tangent*/
|
||||
{"TAN", 7, 8, UNARY_OPERATOR, TAN}, /* tangent */
|
||||
{"!=", 3, 3, BINARY_OPERATOR,NOT_EQ}, /* not equal */
|
||||
{"!", 7, 8, UNARY_OPERATOR, REL_NOT}, /* not */
|
||||
{"~", 7, 8, UNARY_OPERATOR, BIT_NOT}, /* bitwise not */
|
||||
{"DBL", 7, 8, UNARY_OPERATOR, TO_DOUBLE}, /* convert to double */
|
||||
{"STR", 7, 8, UNARY_OPERATOR, TO_STRING}, /* convert to string */
|
||||
{"$P", 7, 8, UNARY_OPERATOR, PRINTF}, /* formatted print to string */
|
||||
{"PRINTF", 7, 8, UNARY_OPERATOR, PRINTF}, /* formatted print to string */
|
||||
{"$S", 7, 8, UNARY_OPERATOR, SSCANF}, /* scan string argument */
|
||||
{"SSCANF", 7, 8, UNARY_OPERATOR, SSCANF}, /* scan string argument */
|
||||
{"RNDM", 0, 0, OPERAND, RANDOM}, /* Random Number */
|
||||
{"OR", 1, 1, BINARY_OPERATOR,BIT_OR}, /* or */
|
||||
{"AND", 2, 2, BINARY_OPERATOR,BIT_AND}, /* and */
|
||||
{"XOR", 1, 1, BINARY_OPERATOR,BIT_EXCL_OR}, /* exclusive or */
|
||||
{"PI", 0, 0, OPERAND, CONST_PI}, /* pi */
|
||||
{"D2R", 0, 0, OPERAND, CONST_D2R}, /* pi/180 */
|
||||
{"R2D", 0, 0, OPERAND, CONST_R2D}, /* 180/pi */
|
||||
{"S2R", 0, 0, OPERAND, CONST_S2R}, /* arc-sec to radians: pi/(180*3600) */
|
||||
{"R2S", 0, 0, OPERAND, CONST_R2S}, /* radians to arc-sec: (180*3600)/pi */
|
||||
{"0", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
|
||||
{"1", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
|
||||
{"2", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
|
||||
{"3", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
|
||||
{"4", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
|
||||
{"5", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
|
||||
{"6", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
|
||||
{"7", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
|
||||
{"8", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
|
||||
{"9", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
|
||||
{".", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
|
||||
{"\"", 0, 0, STRING_CONST, SLITERAL}, /* string constant */
|
||||
{"'", 0, 0, STRING_CONST, SLITERAL}, /* string constant */
|
||||
{"?", 0, 0, CONDITIONAL, COND_IF}, /* conditional */
|
||||
{":", 0, 0, CONDITIONAL, COND_ELSE}, /* else */
|
||||
{"(", 0, 8, UNARY_OPERATOR, PAREN}, /* open paren */
|
||||
{"[", 0, 8, BINARY_OPERATOR,SUBRANGE}, /* string subrange */
|
||||
{"{", 0, 8, BINARY_OPERATOR,REPLACE}, /* string replace */
|
||||
{"^", 6, 6, BINARY_OPERATOR,EXPON}, /* exponentiation */
|
||||
{"**", 6, 6, BINARY_OPERATOR,EXPON}, /* exponentiation */
|
||||
{"+", 4, 4, BINARY_OPERATOR,ADD}, /* addition */
|
||||
#if 0 /* "-" operator is overloaded; may be unary or binary */
|
||||
{"-", 4, 4, BINARY_OPERATOR,SUB}, /* subtraction */
|
||||
#endif
|
||||
{"*", 5, 5, BINARY_OPERATOR,MULT}, /* multiplication */
|
||||
{"/", 5, 5, BINARY_OPERATOR,DIV}, /* division */
|
||||
{"%", 5, 5, BINARY_OPERATOR,MODULO}, /* modulo */
|
||||
{",", 0, 0, SEPARATOR, COMMA}, /* comma */
|
||||
{")", 0, 0, CLOSE_PAREN, PAREN}, /* close paren */
|
||||
{"]", 0, 0, CLOSE_BRACKET, SUBRANGE}, /* close bracket */
|
||||
{"}", 0, 0, CLOSE_CURLY, REPLACE}, /* close curly bracket */
|
||||
{"||", 1, 1, BINARY_OPERATOR,REL_OR}, /* logical or */
|
||||
{"|", 1, 1, BINARY_OPERATOR,BIT_OR}, /* bitwise or */
|
||||
{"&&", 2, 2, BINARY_OPERATOR,REL_AND}, /* logical and */
|
||||
{"&", 2, 2, BINARY_OPERATOR,BIT_AND}, /* bitwise and */
|
||||
{">>", 2, 2, BINARY_OPERATOR,RIGHT_SHIFT}, /* right shift */
|
||||
{">=", 3, 3, BINARY_OPERATOR,GR_OR_EQ}, /* greater or equal*/
|
||||
{">", 3, 3, BINARY_OPERATOR,GR_THAN}, /* greater than */
|
||||
{"<<", 2, 2, BINARY_OPERATOR,LEFT_SHIFT}, /* left shift */
|
||||
{"<=", 3, 3, BINARY_OPERATOR,LESS_OR_EQ}, /* less or equal to*/
|
||||
{"<", 3, 3, BINARY_OPERATOR,LESS_THAN}, /* less than */
|
||||
{"#", 3, 3, BINARY_OPERATOR,NOT_EQ}, /* not equal */
|
||||
{"==", 3, 3, BINARY_OPERATOR,EQUAL}, /* equal */
|
||||
{"=", 3, 3, BINARY_OPERATOR,EQUAL}, /* equal */
|
||||
{""}
|
||||
};
|
||||
|
||||
/*
|
||||
* Element-table entry for "fetch" operation. This element is used for all
|
||||
* named variables. Currently, letters A-Z (double) and AA-ZZ (string) are
|
||||
* allowed. Lower and upper case letters mean the same thing.
|
||||
*/
|
||||
static struct expression_element fetch_element = {
|
||||
"A", 0, 0, OPERAND, FETCH, /* fetch var */
|
||||
};
|
||||
|
||||
static struct expression_element fetch_string_element = {
|
||||
"AA", 0, 0, OPERAND, SFETCH, /* fetch var */
|
||||
};
|
||||
|
||||
static int strncasecmpPrivate(char *s1, char *s2, size_t n)
|
||||
{
|
||||
short i;
|
||||
for (i=0; i<(short)n && (*s1 || *s2); i++, s1++, s2++) {
|
||||
if (toupper((int)*s1) > toupper((int)*s2)) return(1);
|
||||
if (toupper((int)*s1) < toupper((int)*s2)) return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
* FIND_ELEMENT
|
||||
*
|
||||
* find the pointer to an entry in the element table
|
||||
*/
|
||||
static int find_element(pbuffer, pelement, pno_bytes, parg)
|
||||
char *pbuffer;
|
||||
struct expression_element **pelement;
|
||||
short *pno_bytes, *parg;
|
||||
{
|
||||
*parg = 0;
|
||||
|
||||
/* compare the string to each element in the element table */
|
||||
*pelement = &elements[0];
|
||||
while ((*pelement)->element[0] != NULL){
|
||||
if (strncasecmpPrivate(pbuffer,(*pelement)->element, strlen((*pelement)->element)) == 0){
|
||||
*pno_bytes += strlen((*pelement)->element);
|
||||
return(TRUE);
|
||||
}
|
||||
*pelement += 1;
|
||||
}
|
||||
|
||||
/* look for a variable reference */
|
||||
/* double variables: ["a" - "z"], numbered 1-26 */
|
||||
if (isalpha((int)*pbuffer)) {
|
||||
*pelement = &fetch_element; /* fetch means "variable reference" (fetch or store) */
|
||||
*parg = *pbuffer - (isupper((int)*pbuffer) ? 'A' : 'a');
|
||||
*pno_bytes += 1;
|
||||
/* string variables: ["aa" - "zz"], numbered 1-26 */
|
||||
if (pbuffer[1] == pbuffer[0]) {
|
||||
*pelement = &fetch_string_element;
|
||||
*pno_bytes += 1;
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
if (sCalcPostfixDebug) printf("find_element: can't find '%s'\n", pbuffer);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* GET_ELEMENT
|
||||
*
|
||||
* get an expression element
|
||||
*/
|
||||
static int get_element(pinfix, pelement, pno_bytes, parg)
|
||||
char *pinfix;
|
||||
struct expression_element **pelement;
|
||||
short *pno_bytes, *parg;
|
||||
{
|
||||
|
||||
/* get the next expression element from the infix expression */
|
||||
if (*pinfix == NULL) return(END);
|
||||
*pno_bytes = 0;
|
||||
while (*pinfix == 0x20){
|
||||
*pno_bytes += 1;
|
||||
pinfix++;
|
||||
}
|
||||
if (*pinfix == NULL) return(END);
|
||||
if (!find_element(pinfix, pelement, pno_bytes, parg))
|
||||
return(UNKNOWN_ELEMENT);
|
||||
if (sCalcPostfixDebug > 5) printf("get_element: found element '%s', arg=%d\n", (*pelement)->element, *parg);
|
||||
|
||||
return(FINE);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#if OVERRIDESTDCALC
|
||||
/* Override standard EPICS expression evaluator (if we're loaded after it). */
|
||||
long epicsShareAPI postfix(const char *pinfix,char *ppostfix,short *perror)
|
||||
{
|
||||
char *my_ppostfix = NULL, *s, *d;
|
||||
long retval;
|
||||
|
||||
retval = sCalcPostfix(pinfix, &my_ppostfix, perror);
|
||||
if (*my_ppostfix == BAD_EXPRESSION) {
|
||||
*ppostfix = BAD_EXPRESSION;
|
||||
} else {
|
||||
for (s = my_ppostfix, d = ppostfix; *s != END_STACK; ) {
|
||||
*d++=*s++;
|
||||
}
|
||||
*d = *s;
|
||||
}
|
||||
free(my_ppostfix);
|
||||
return(retval);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* sCalcPostFix
|
||||
*
|
||||
* convert an infix expression to a postfix expression
|
||||
*/
|
||||
#define MAX_POSTFIX_SIZE 100
|
||||
long epicsShareAPI sCalcPostfix(const char *pin, char **pp_postfix, short *perror)
|
||||
{
|
||||
short no_bytes;
|
||||
short operand_needed;
|
||||
short new_expression;
|
||||
struct expression_element stack[80];
|
||||
struct expression_element *pelement;
|
||||
struct expression_element *pstacktop;
|
||||
double constant;
|
||||
char c, *pposthold;
|
||||
char in_stack_pri, in_coming_pri, code;
|
||||
char *ppostfix, *ppostfixStart;
|
||||
short arg;
|
||||
char infix[MAX_POSTFIX_SIZE];
|
||||
char *pinfix = &infix[0];
|
||||
int len;
|
||||
|
||||
if (sCalcPostfixDebug) printf("sCalcPostfix: entry\n");
|
||||
len = strlen(pin);
|
||||
if(len>=MAX_POSTFIX_SIZE) return(-1);
|
||||
strcpy(infix,pin);
|
||||
/* Allocate a buffer for the postfix expression. */
|
||||
if (*pp_postfix) free(*pp_postfix); /* Free old buffer. */
|
||||
ppostfix = calloc(5*strlen(pinfix)+7, 1);
|
||||
*pp_postfix = ppostfix;
|
||||
ppostfixStart = ppostfix++;
|
||||
*ppostfixStart = BAD_EXPRESSION;
|
||||
*ppostfix = END_STACK;
|
||||
|
||||
/* place the expression elements into postfix */
|
||||
operand_needed = TRUE;
|
||||
new_expression = TRUE;
|
||||
*perror = 0;
|
||||
if (*pinfix == 0) {
|
||||
return(0);
|
||||
}
|
||||
pstacktop = &stack[0];
|
||||
while (get_element(pinfix, &pelement, &no_bytes, &arg) != END){
|
||||
pinfix += no_bytes;
|
||||
code = pelement->code;
|
||||
if ((*ppostfixStart != USES_STRING) && ((code == TO_STRING) ||
|
||||
(code == PRINTF) || (code == SSCANF) || (code == SLITERAL) ||
|
||||
(code == SUBRANGE) || (code == SFETCH))) {
|
||||
*ppostfixStart = USES_STRING;
|
||||
}
|
||||
|
||||
switch (pelement->type){
|
||||
|
||||
case OPERAND:
|
||||
if (!operand_needed){
|
||||
*perror = 5;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
|
||||
/* add operand to the expression */
|
||||
*ppostfix++ = pelement->code;
|
||||
|
||||
/* if this is a variable reference, append variable number */
|
||||
if ((pelement->code == (char)FETCH) || (pelement->code == (char)SFETCH)) {
|
||||
*ppostfix++ = arg;
|
||||
}
|
||||
|
||||
operand_needed = FALSE;
|
||||
new_expression = FALSE;
|
||||
break;
|
||||
|
||||
case FLOAT_PT_CONST:
|
||||
if (!operand_needed){
|
||||
*perror = 5;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
|
||||
/* add constant to postfix expression */
|
||||
*ppostfix++ = pelement->code;
|
||||
pposthold = ppostfix;
|
||||
|
||||
pinfix-=no_bytes;
|
||||
while (*pinfix == ' ') *ppostfix++ = *pinfix++;
|
||||
while (TRUE) {
|
||||
if ( ( *pinfix >= '0' && *pinfix <= '9' ) || *pinfix == '.' ) {
|
||||
*ppostfix++ = *pinfix;
|
||||
pinfix++;
|
||||
} else if ( *pinfix == 'E' || *pinfix == 'e' ) {
|
||||
*ppostfix++ = *pinfix;
|
||||
pinfix++;
|
||||
if (*pinfix == '+' || *pinfix == '-' ) {
|
||||
*ppostfix++ = *pinfix;
|
||||
pinfix++;
|
||||
}
|
||||
} else break;
|
||||
}
|
||||
*ppostfix++ = '\0';
|
||||
|
||||
ppostfix = pposthold;
|
||||
if ( sscanf(ppostfix,"%lg",&constant) != 1) {
|
||||
*ppostfix = '\0';
|
||||
} else {
|
||||
memcpy(ppostfix,(void *)&constant,8);
|
||||
}
|
||||
ppostfix+=8;
|
||||
|
||||
operand_needed = FALSE;
|
||||
new_expression = FALSE;
|
||||
break;
|
||||
|
||||
case STRING_CONST:
|
||||
if (!operand_needed){
|
||||
*perror = 5;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
|
||||
/* add string literal to the postfix expression */
|
||||
*ppostfix++ = pelement->code;
|
||||
c = pinfix[-1];
|
||||
while (*pinfix != c && *pinfix) *ppostfix++ = *pinfix++;
|
||||
*ppostfix++ = '\0';
|
||||
if (*pinfix) pinfix++;
|
||||
|
||||
operand_needed = FALSE;
|
||||
new_expression = FALSE;
|
||||
break;
|
||||
|
||||
case BINARY_OPERATOR:
|
||||
if (operand_needed){
|
||||
*perror = 4;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
|
||||
/* add operators of higher or equal priority to postfix expression */
|
||||
while ( (pstacktop >= &stack[1]) &&
|
||||
(pstacktop->in_stack_pri >= pelement->in_coming_pri)) {
|
||||
*ppostfix++ = pstacktop->code;
|
||||
pstacktop--;
|
||||
}
|
||||
|
||||
/* add new operator to stack */
|
||||
pstacktop++;
|
||||
*pstacktop = *pelement;
|
||||
|
||||
operand_needed = TRUE;
|
||||
break;
|
||||
|
||||
case UNARY_OPERATOR:
|
||||
if (!operand_needed){
|
||||
*perror = 5;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
|
||||
/* add operators of higher or equal priority to postfix expression */
|
||||
while ( (pstacktop >= &stack[1]) &&
|
||||
(pstacktop->in_stack_pri >= pelement->in_coming_pri)) {
|
||||
*ppostfix++ = pstacktop->code;
|
||||
pstacktop--;
|
||||
}
|
||||
|
||||
/* add new operator to stack */
|
||||
pstacktop++;
|
||||
*pstacktop = *pelement;
|
||||
|
||||
new_expression = FALSE;
|
||||
break;
|
||||
|
||||
case MINUS_OPERATOR:
|
||||
if (operand_needed) {
|
||||
/* then assume minus was intended as a unary operator */
|
||||
in_coming_pri = UNARY_MINUS_I_C_P;
|
||||
in_stack_pri = UNARY_MINUS_I_S_P;
|
||||
code = UNARY_MINUS_CODE;
|
||||
new_expression = FALSE;
|
||||
} else {
|
||||
/* then assume minus was intended as a binary operator */
|
||||
in_coming_pri = BINARY_MINUS_I_C_P;
|
||||
in_stack_pri = BINARY_MINUS_I_S_P;
|
||||
code = BINARY_MINUS_CODE;
|
||||
operand_needed = TRUE;
|
||||
}
|
||||
|
||||
/* add operators of higher or equal priority to postfix expression */
|
||||
while ( (pstacktop >= &stack[1]) &&
|
||||
(pstacktop->in_stack_pri >= in_coming_pri)) {
|
||||
*ppostfix++ = pstacktop->code;
|
||||
pstacktop--;
|
||||
}
|
||||
|
||||
/* add new operator to stack */
|
||||
pstacktop++;
|
||||
*pstacktop = *pelement;
|
||||
pstacktop->in_stack_pri = in_stack_pri;
|
||||
pstacktop->code = code;
|
||||
|
||||
break;
|
||||
|
||||
case SEPARATOR:
|
||||
if (operand_needed){
|
||||
*perror = 4;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
|
||||
/* add operators to postfix until open paren */
|
||||
while ((pstacktop->element[0] != '(') && (pstacktop->element[0] != '[')
|
||||
&& (pstacktop->element[0] != '{')) {
|
||||
if (pstacktop == &stack[1] || pstacktop == &stack[0]){
|
||||
*perror = 6;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
*ppostfix++ = pstacktop->code;
|
||||
pstacktop--;
|
||||
}
|
||||
operand_needed = TRUE;
|
||||
break;
|
||||
|
||||
case CLOSE_PAREN:
|
||||
if (operand_needed){
|
||||
*perror = 4;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
|
||||
/* add operators to postfix until matching paren */
|
||||
while (pstacktop->element[0] != '(') {
|
||||
if (pstacktop == &stack[1] || pstacktop == &stack[0]) {
|
||||
*perror = 6;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
*ppostfix++ = pstacktop->code;
|
||||
pstacktop--;
|
||||
}
|
||||
pstacktop--; /* remove ( from stack */
|
||||
break;
|
||||
|
||||
case CLOSE_BRACKET:
|
||||
if (operand_needed){
|
||||
*perror = 4;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
|
||||
/* add operators to postfix until matching bracket */
|
||||
while (pstacktop->element[0] != '[') {
|
||||
if (pstacktop == &stack[1] || pstacktop == &stack[0]) {
|
||||
*perror = 6;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
*ppostfix++ = pstacktop->code;
|
||||
pstacktop--;
|
||||
}
|
||||
/* add SUBRANGE operator to postfix */
|
||||
if (pstacktop == &stack[0]) {
|
||||
*perror = 6;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
*ppostfix++ = pstacktop->code;
|
||||
pstacktop--;
|
||||
break;
|
||||
|
||||
case CLOSE_CURLY:
|
||||
if (operand_needed){
|
||||
*perror = 4;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
|
||||
/* add operators to postfix until matching bracket */
|
||||
while (pstacktop->element[0] != '{') {
|
||||
if (pstacktop == &stack[1] || pstacktop == &stack[0]) {
|
||||
*perror = 6;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
*ppostfix++ = pstacktop->code;
|
||||
pstacktop--;
|
||||
}
|
||||
/* add REPLACE operator to postfix */
|
||||
if (pstacktop == &stack[0]) {
|
||||
*perror = 6;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
*ppostfix++ = pstacktop->code;
|
||||
pstacktop--;
|
||||
break;
|
||||
|
||||
case CONDITIONAL:
|
||||
if (operand_needed){
|
||||
*perror = 4;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
|
||||
/* add operators of higher priority to postfix expression */
|
||||
while ( (pstacktop >= &stack[1]) &&
|
||||
(pstacktop->in_stack_pri > pelement->in_coming_pri)) {
|
||||
*ppostfix++ = pstacktop->code;
|
||||
pstacktop--;
|
||||
}
|
||||
|
||||
/* add new element to the postfix expression */
|
||||
*ppostfix++ = pelement->code;
|
||||
|
||||
/* add : operator with COND_END code to stack */
|
||||
if (pelement->element[0] == ':'){
|
||||
pstacktop++;
|
||||
*pstacktop = *pelement;
|
||||
pstacktop->code = COND_END;
|
||||
}
|
||||
|
||||
operand_needed = TRUE;
|
||||
break;
|
||||
|
||||
case EXPR_TERM:
|
||||
if (operand_needed && !new_expression){
|
||||
*perror = 4;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
|
||||
/* add all operators on stack to postfix */
|
||||
while (pstacktop >= &stack[1]){
|
||||
if (pstacktop->element[0] == '('){
|
||||
*perror = 6;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
*ppostfix++ = pstacktop->code;
|
||||
pstacktop--;
|
||||
}
|
||||
|
||||
/* add new element to the postfix expression */
|
||||
*ppostfix++ = pelement->code;
|
||||
|
||||
operand_needed = TRUE;
|
||||
new_expression = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
*perror = 8;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
}
|
||||
if (operand_needed){
|
||||
*perror = 4;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
|
||||
/* add all operators on stack to postfix */
|
||||
while (pstacktop >= &stack[1]){
|
||||
if (pstacktop->element[0] == '('){
|
||||
*perror = 6;
|
||||
*ppostfixStart = BAD_EXPRESSION; return(-1);
|
||||
}
|
||||
*ppostfix++ = pstacktop->code;
|
||||
pstacktop--;
|
||||
}
|
||||
*ppostfix++ = END_STACK;
|
||||
*ppostfix = '\0';
|
||||
|
||||
if (ppostfixStart[1] == END_STACK)
|
||||
*ppostfixStart = BAD_EXPRESSION;
|
||||
else if (*ppostfixStart != USES_STRING)
|
||||
*ppostfixStart = NO_STRING;
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* sCalcPostfix.h
|
||||
* Author: Bob Dalesio
|
||||
* Date: 9-21-88
|
||||
*/
|
||||
|
||||
#ifndef INCsCalcPostfixH
|
||||
#define INCsCalcPostfixH
|
||||
|
||||
#include "shareLib.h"
|
||||
|
||||
#define BAD_EXPRESSION 0
|
||||
#define END_STACK 127
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
epicsShareFunc long epicsShareAPI sCalcPostfix (const char *pinfix,
|
||||
char **pp_postfix, short *perror);
|
||||
|
||||
epicsShareFunc long epicsShareAPI
|
||||
sCalcPerform (double *parg, int numArgs,
|
||||
char **psarg, int numSArgs, double *presult,
|
||||
char *psresult, int lenSresult, char *post);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* INCsCalcPostfixH */
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* sCalcPostfixPvt.h
|
||||
* Author: Bob Dalesio
|
||||
* Date: 9-21-88
|
||||
*/
|
||||
|
||||
#ifndef INCpostfixh
|
||||
#include <sCalcPostfix.h>
|
||||
#endif
|
||||
#ifndef INCpostfixPvth
|
||||
#define INCpostfixPvth
|
||||
|
||||
/* #define BAD_EXPRESSION 0 */
|
||||
|
||||
/* defines for element table */
|
||||
/* elements that define a value */
|
||||
#define FETCH 1
|
||||
#define SFETCH 2
|
||||
#define CONST_PI 3
|
||||
#define CONST_D2R 4
|
||||
#define CONST_R2D 5
|
||||
#define CONST_S2R 6
|
||||
#define CONST_R2S 7
|
||||
#define RANDOM 8
|
||||
#define LITERAL 9
|
||||
#define SLITERAL 10
|
||||
#define SSCANF 11
|
||||
|
||||
#define VALUE_ELEMENT 11
|
||||
|
||||
/* elements that operate on a value */
|
||||
#define ACOS 12
|
||||
#define ASIN 13
|
||||
#define ATAN 14
|
||||
#define COS 15
|
||||
#define COSH 16
|
||||
#define SIN 17
|
||||
#define RIGHT_SHIFT 18
|
||||
#define LEFT_SHIFT 19
|
||||
#define SINH 20
|
||||
#define TAN 21
|
||||
#define TANH 22
|
||||
#define LOG_2 23
|
||||
#define COND_ELSE 24
|
||||
#define ABS_VAL 25
|
||||
#define UNARY_NEG 26
|
||||
#define SQU_RT 27
|
||||
#define EXP 28
|
||||
#define CEIL 29
|
||||
#define FLOOR 30
|
||||
#define LOG_10 31
|
||||
#define LOG_E 32
|
||||
#define ADD 33
|
||||
#define SUB 34
|
||||
#define MULT 35
|
||||
#define DIV 36
|
||||
#define EXPON 37
|
||||
#define MODULO 38
|
||||
#define BIT_OR 39
|
||||
#define BIT_AND 40
|
||||
#define BIT_EXCL_OR 41
|
||||
#define GR_OR_EQ 42
|
||||
#define GR_THAN 43
|
||||
#define LESS_OR_EQ 44
|
||||
#define LESS_THAN 45
|
||||
#define NOT_EQ 46
|
||||
#define EQUAL 47
|
||||
#define REL_OR 48
|
||||
#define REL_AND 49
|
||||
#define REL_NOT 50
|
||||
#define BIT_NOT 51
|
||||
#define PAREN 52
|
||||
#define MAX_VAL 53
|
||||
#define MIN_VAL 54
|
||||
#define COMMA 55
|
||||
#define COND_IF 56
|
||||
#define COND_END 57
|
||||
#define NINT 58
|
||||
#define ATAN2 59
|
||||
#define STORE 60
|
||||
#define TO_DOUBLE 61
|
||||
#define PRINTF 62
|
||||
#define SUBRANGE 63
|
||||
#define TO_STRING 64
|
||||
#define REPLACE 65
|
||||
/* #define END_STACK 127 */
|
||||
|
||||
#define USES_STRING 126
|
||||
#define NO_STRING 125
|
||||
#endif /* INCpostfixPvth */
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsGuard.h"
|
||||
#include "epicsThread.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
// This class exists for the purpose of avoiding file scope
|
||||
// object chicken and egg problems. It implements thread safe
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
#include <new>
|
||||
#include "string.h"
|
||||
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
#include "epicsMutex.h"
|
||||
#include "epicsGuard.h"
|
||||
|
||||
|
||||
@@ -40,15 +40,8 @@
|
||||
#define LOCAL static
|
||||
#endif /* LOCAL */
|
||||
|
||||
/* BUFFER_EXTRA_BYTES is set equal to MAX_MESSAGE_SIZE in case
|
||||
an os cant implement vsnprintf. Such an os
|
||||
is subject to buffer overflow. Allocating an additional
|
||||
BUFFER_EXTRA_BYTES bytes will at least make this less likely
|
||||
*/
|
||||
#define BUFFER_SIZE 1280
|
||||
#define MAX_MESSAGE_SIZE 256
|
||||
#define BUFFER_EXTRA_BYTES MAX_MESSAGE_SIZE
|
||||
#define TRUNCATE_SIZE 80
|
||||
#define MAX_ALIGNMENT 8
|
||||
|
||||
/*Declare storage for errVerbose */
|
||||
@@ -57,7 +50,7 @@ epicsShareDef int errVerbose=0;
|
||||
LOCAL void errlogThread(void);
|
||||
|
||||
LOCAL char *msgbufGetFree(int noConsoleMessage);
|
||||
LOCAL void msgbufSetSize(int size);
|
||||
LOCAL void msgbufSetSize(int size); /* Send 'size' chars plus trailing '\0' */
|
||||
LOCAL char * msgbufGetSend(int *noConsoleMessage);
|
||||
LOCAL void msgbufFreeSend(void);
|
||||
|
||||
@@ -94,7 +87,25 @@ LOCAL struct {
|
||||
int missedMessages;
|
||||
void *pbuffer;
|
||||
}pvtData;
|
||||
|
||||
|
||||
/*
|
||||
* vsnprintf with truncation message
|
||||
*/
|
||||
LOCAL int tvsnPrint(char *str, size_t size, const char *format, va_list ap)
|
||||
{
|
||||
int nchar;
|
||||
static const char tmsg[] = "<<TRUNCATED>>\n";
|
||||
|
||||
nchar = epicsVsnprintf(str, size, format?format:"", ap);
|
||||
if(nchar >= size) {
|
||||
if (size > sizeof tmsg)
|
||||
strcpy(str+size-sizeof tmsg, tmsg);
|
||||
nchar = size - 1;
|
||||
}
|
||||
return nchar;
|
||||
}
|
||||
|
||||
epicsShareFunc int errlogPrintf( const char *pFormat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
@@ -126,25 +137,14 @@ epicsShareFunc int errlogVprintf(
|
||||
errlogInit(0);
|
||||
pbuffer = msgbufGetFree(0);
|
||||
if(!pbuffer) return(0);
|
||||
nchar = vsprintf(pbuffer,pFormat,pvar);
|
||||
msgbufSetSize(nchar+1);/*include the \0*/
|
||||
nchar = tvsnPrint(pbuffer,MAX_MESSAGE_SIZE,pFormat?pFormat:"",pvar);
|
||||
msgbufSetSize(nchar);
|
||||
return nchar;
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogMessage(const char *message)
|
||||
{
|
||||
char *pbuffer;
|
||||
|
||||
if(epicsInterruptIsInterruptContext()) {
|
||||
epicsInterruptContextMessage
|
||||
("errlogMessage called from interrupt level\n");
|
||||
return 0;
|
||||
}
|
||||
errlogInit(0);
|
||||
pbuffer = msgbufGetFree(0);
|
||||
if(!pbuffer) return(0);
|
||||
strcpy(pbuffer,message);
|
||||
msgbufSetSize(strlen(message) +1);
|
||||
errlogPrintf("%s", message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -179,8 +179,8 @@ epicsShareFunc int errlogVprintfNoConsole(
|
||||
errlogInit(0);
|
||||
pbuffer = msgbufGetFree(1);
|
||||
if(!pbuffer) return(0);
|
||||
nchar = vsprintf(pbuffer,pFormat,pvar);
|
||||
msgbufSetSize(nchar+1);/*include the \0*/
|
||||
nchar = tvsnPrint(pbuffer,MAX_MESSAGE_SIZE,pFormat?pFormat:"",pvar);
|
||||
msgbufSetSize(nchar);
|
||||
return nchar;
|
||||
}
|
||||
|
||||
@@ -221,10 +221,12 @@ epicsShareFunc int errlogSevVprintf(
|
||||
if(!pnext) return(0);
|
||||
nchar = sprintf(pnext,"sevr=%s ",errlogGetSevEnumString(severity));
|
||||
pnext += nchar; totalChar += nchar;
|
||||
nchar = vsprintf(pnext,pFormat,pvar);
|
||||
nchar = tvsnPrint(pnext,MAX_MESSAGE_SIZE-totalChar-1,pFormat,pvar);
|
||||
pnext += nchar; totalChar += nchar;
|
||||
sprintf(pnext,"\n");
|
||||
totalChar += 2; /*include \n and \0*/
|
||||
if(pnext[-1] != '\n') {
|
||||
strcpy(pnext,"\n");
|
||||
totalChar++;
|
||||
}
|
||||
msgbufSetSize(totalChar);
|
||||
return(nchar);
|
||||
}
|
||||
@@ -322,16 +324,14 @@ epicsShareFunc void errPrintf(long status, const char *pFileName,
|
||||
pnext += nchar; totalChar += nchar;
|
||||
}
|
||||
va_start (pvar, pformat);
|
||||
/* buffer was allocated with an extra BUFFER_EXTRA_BYTES bytes*/
|
||||
/* Thus the following will not overflow buffer */
|
||||
nchar = epicsVsnprintf(pnext,MAX_MESSAGE_SIZE + BUFFER_EXTRA_BYTES,pformat,pvar);
|
||||
nchar = tvsnPrint(pnext,MAX_MESSAGE_SIZE,pformat,pvar);
|
||||
va_end (pvar);
|
||||
if(nchar>0) {
|
||||
pnext += nchar;
|
||||
totalChar += nchar;
|
||||
}
|
||||
sprintf(pnext,"\n");
|
||||
totalChar += 2; /*include the \n and the \0*/
|
||||
strcpy(pnext,"\n");
|
||||
totalChar++ ; /*include the \n */
|
||||
msgbufSetSize(totalChar);
|
||||
}
|
||||
|
||||
@@ -353,8 +353,7 @@ static void errlogInitPvt(void *arg)
|
||||
pvtData.waitForFlush = epicsEventMustCreate(epicsEventEmpty);
|
||||
pvtData.flush = epicsEventMustCreate(epicsEventEmpty);
|
||||
pvtData.flushLock = epicsMutexMustCreate();
|
||||
/*BUFFER_EXTRA_BYTES allows message overflow to be detected*/
|
||||
pbuffer = pvtCalloc(pvtData.buffersize+BUFFER_EXTRA_BYTES,sizeof(char));
|
||||
pbuffer = pvtCalloc(pvtData.buffersize,sizeof(char));
|
||||
pvtData.pbuffer = pbuffer;
|
||||
tid = epicsThreadCreate("errlog",epicsThreadPriorityLow,
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
@@ -479,31 +478,9 @@ LOCAL char *msgbufGetFree(int noConsoleMessage)
|
||||
|
||||
LOCAL void msgbufSetSize(int size)
|
||||
{
|
||||
char *pbuffer = (char *)pvtData.pbuffer;
|
||||
msgNode *pnextSend = pvtData.pnextSend;
|
||||
char *message = pnextSend->message;
|
||||
|
||||
if(size>MAX_MESSAGE_SIZE) {
|
||||
int excess;
|
||||
int nchar;
|
||||
|
||||
excess = size - (pvtData.buffersize -(message - pbuffer));
|
||||
message[TRUNCATE_SIZE] = 0;
|
||||
if(excess> 0) {
|
||||
printf("errlog: A message overran buffer by %d. This is VERY bad\n",
|
||||
excess);
|
||||
nchar = sprintf(&message[TRUNCATE_SIZE],
|
||||
"\nerrlog = previous message overran buffer. It was truncated."
|
||||
" size = %d excess = %d\n", size,excess);
|
||||
} else {
|
||||
nchar = sprintf(&message[TRUNCATE_SIZE],
|
||||
"\nerrlog = previous message too long. It was truncated."
|
||||
" size=%d It was truncated\n",size);
|
||||
}
|
||||
pnextSend->length = TRUNCATE_SIZE + nchar +1;
|
||||
} else {
|
||||
pnextSend->length = size+1;
|
||||
}
|
||||
pnextSend->length = size+1;
|
||||
ellAdd(&pvtData.msgQueue,&pnextSend->node);
|
||||
epicsMutexUnlock(pvtData.msgQueueLock);
|
||||
epicsEventSignal(pvtData.waitForWork);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "shareLib.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -39,11 +40,11 @@ epicsShareExtern char * errlogSevEnumString[];
|
||||
#endif
|
||||
|
||||
epicsShareFunc int errlogPrintf(
|
||||
const char *pformat, ...);
|
||||
const char *pformat, ...) EPICS_PRINTF_STYLE(1,2);
|
||||
epicsShareFunc int errlogVprintf(
|
||||
const char *pformat,va_list pvar);
|
||||
epicsShareFunc int errlogSevPrintf(
|
||||
const errlogSevEnum severity,const char *pformat, ...);
|
||||
const errlogSevEnum severity,const char *pformat, ...) EPICS_PRINTF_STYLE(2,3);
|
||||
epicsShareFunc int errlogSevVprintf(
|
||||
const errlogSevEnum severity,const char *pformat,va_list pvar);
|
||||
epicsShareFunc int epicsShareAPI errlogMessage(
|
||||
@@ -66,7 +67,7 @@ epicsShareFunc void epicsShareAPI errlogFlush(void);
|
||||
|
||||
/*other routines that write to log file*/
|
||||
epicsShareFunc void errPrintf(long status, const char *pFileName,
|
||||
int lineno, const char *pformat, ...);
|
||||
int lineno, const char *pformat, ...) EPICS_PRINTF_STYLE(4,5);
|
||||
|
||||
epicsShareExtern int errVerbose;
|
||||
|
||||
@@ -74,7 +75,7 @@ epicsShareExtern int errVerbose;
|
||||
* the message to appear twice on the console
|
||||
*/
|
||||
epicsShareFunc int errlogPrintfNoConsole(
|
||||
const char *pformat, ...);
|
||||
const char *pformat, ...) EPICS_PRINTF_STYLE(1,2);
|
||||
epicsShareFunc int errlogVprintfNoConsole(
|
||||
const char *pformat,va_list pvar);
|
||||
|
||||
|
||||
@@ -9,27 +9,37 @@
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
// Author:
|
||||
// Jeffrey O. Hill
|
||||
// johill@lanl.gov
|
||||
/*
|
||||
* Author:
|
||||
* Jeffrey O. Hill
|
||||
* johill@lanl.gov
|
||||
*/
|
||||
|
||||
#ifndef cxxCompilerDependencies_h
|
||||
#define cxxCompilerDependencies_h
|
||||
#ifndef compilerDependencies_h
|
||||
#define compilerDependencies_h
|
||||
|
||||
// This tells us what features of standard C++ a compiler supports.
|
||||
// Since this is a compiler, and not os dependent issue, then ifdefs
|
||||
// are used. The ifdefs allow us to assume that these problems will
|
||||
// get fixed by future compiler releases.
|
||||
//
|
||||
// CXX_PLACEMENT_DELETE - defined if compiler supports placement delete
|
||||
// CXX_THROW_SPECIFICATION - defined if compiler supports throw specification
|
||||
//
|
||||
/*
|
||||
* This is an attempt to move all tests identifying what features a
|
||||
* compiler supports into one file.
|
||||
*
|
||||
* Since this is a compiler, and not os dependent, issue then ifdefs
|
||||
* are used. The ifdefs allow us to make the default assumption that
|
||||
* standards incompliance issues will be fixed by future compiler
|
||||
* releases.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/*
|
||||
* CXX_PLACEMENT_DELETE - defined if compiler supports placement delete
|
||||
* CXX_THROW_SPECIFICATION - defined if compiler supports throw specification
|
||||
*/
|
||||
|
||||
#if defined ( _MSC_VER )
|
||||
# if _MSC_VER >= 1200 // visual studio 6.0 or later
|
||||
# if _MSC_VER >= 1200 /* visual studio 6.0 or later */
|
||||
# define CXX_PLACEMENT_DELETE
|
||||
# endif
|
||||
# if _MSC_VER > 1300 // some release after visual studio 7 we hope
|
||||
# if _MSC_VER > 1300 /* some release after visual studio 7 we hope */
|
||||
# define CXX_THROW_SPECIFICATION
|
||||
# endif
|
||||
#elif defined ( __HP_aCC )
|
||||
@@ -54,18 +64,33 @@
|
||||
# define CXX_THROW_SPECIFICATION
|
||||
#endif
|
||||
|
||||
// usage: void func () epicsThrows (( std::bad_alloc, std::logic_error ))
|
||||
/*
|
||||
* usage: void func () epicsThrows (( std::bad_alloc, std::logic_error ))
|
||||
*/
|
||||
#if defined ( CXX_THROW_SPECIFICATION )
|
||||
# define epicsThrows(X) throw X
|
||||
#else
|
||||
# define epicsThrows(X)
|
||||
#endif
|
||||
|
||||
// usage: epicsPlacementDeleteOperator (( void *, myMemoryManager & ))
|
||||
/*
|
||||
* usage: epicsPlacementDeleteOperator (( void *, myMemoryManager & ))
|
||||
*/
|
||||
#if defined ( CXX_PLACEMENT_DELETE )
|
||||
# define epicsPlacementDeleteOperator(X) void operator delete X;
|
||||
#else
|
||||
# define epicsPlacementDeleteOperator(X)
|
||||
#endif
|
||||
|
||||
#endif // ifndef cxxCompilerDependencies_h
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Enable format-string checking if possible
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
# define EPICS_PRINTF_STYLE(f,a) __attribute__((format(printf,f,a)))
|
||||
#else
|
||||
# define EPICS_PRINTF_STYLE(f,a)
|
||||
#endif
|
||||
|
||||
#endif /* ifndef compilerDependencies_h */
|
||||
@@ -273,8 +273,10 @@ void ipAddrToAsciiEnginePrivate::run ()
|
||||
|
||||
this->callbackInProgress = false;
|
||||
|
||||
this->pCurrent->pending = false;
|
||||
this->pCurrent = 0;
|
||||
if ( this->pCurrent ) {
|
||||
this->pCurrent->pending = false;
|
||||
this->pCurrent = 0;
|
||||
}
|
||||
if ( this->cancelPendingCount ) {
|
||||
this->destructorBlockEvent.signal ();
|
||||
}
|
||||
|
||||
@@ -466,7 +466,7 @@ long devUnregisterAddress(
|
||||
devInsertAddress (&addrFree[addrType], pRange);
|
||||
s = devCombineAdjacentBlocks (&addrFree[addrType], pRange);
|
||||
if(s){
|
||||
errMessage (s, NULL);
|
||||
errMessage (s, "devCombineAdjacentBlocks error");
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ typedef enum {
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
class epicsShareClass epicsMutex {
|
||||
public:
|
||||
|
||||
@@ -15,13 +15,14 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "shareLib.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsSnprintf(
|
||||
char *str, size_t size, const char *format, ...);
|
||||
char *str, size_t size, const char *format, ...) EPICS_PRINTF_STYLE(3,4);
|
||||
epicsShareFunc int epicsShareAPI epicsVsnprintf(
|
||||
char *str, size_t size, const char *format, va_list ap);
|
||||
epicsShareFunc FILE * epicsShareAPI epicsTempFile ( void );
|
||||
|
||||
@@ -1,746 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* Getopt for GNU.
|
||||
NOTE: getopt is now part of the C library, so if you don't know what
|
||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* NOTE!!! AIX requires this to be the first thing in the file.
|
||||
Do not put ANYTHING before it! */
|
||||
#if !defined (__GNUC__) && defined (_AIX)
|
||||
#pragma alloca
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#define alloca __builtin_alloca
|
||||
#else /* not __GNUC__ */
|
||||
#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#ifndef _AIX
|
||||
char *alloca ();
|
||||
#endif
|
||||
#endif /* alloca.h */
|
||||
#endif
|
||||
#endif /* not __GNUC__ */
|
||||
|
||||
#if !__STDC__ && !defined(const) && IN_GCC
|
||||
#define const
|
||||
#endif
|
||||
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#undef alloca
|
||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||
contain conflicting prototypes for getopt. */
|
||||
#include <stdlib.h>
|
||||
#else /* Not GNU C library. */
|
||||
#define __alloca alloca
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
|
||||
long-named option. Because this is not POSIX.2 compliant, it is
|
||||
being phased out. */
|
||||
/* #define GETOPT_COMPAT */
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
to intersperse the options with the other arguments.
|
||||
|
||||
As `getopt' works, it permutes the elements of ARGV so that,
|
||||
when it is done, all the options precede everything else. Thus
|
||||
all application programs are extended to handle flexible argument order.
|
||||
|
||||
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
||||
Then the behavior is completely standard.
|
||||
|
||||
GNU application programs can use a third alternative mode in which
|
||||
they can distinguish the relative order of options and other arguments. */
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "getopt.h"
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
epicsShareDef char *optarg = 0;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
/* XXX 1003.2 says this must be 1 before any call. */
|
||||
epicsShareDef int optind = 0;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
in which the last option character we returned was found.
|
||||
This allows us to pick up the scan where we left off.
|
||||
|
||||
If this is zero, or a null string, it means resume the scan
|
||||
by advancing to the next ARGV-element. */
|
||||
|
||||
static char *nextchar;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options. */
|
||||
|
||||
epicsShareDef int opterr = 1;
|
||||
|
||||
/* Set to an option character which was unrecognized.
|
||||
This must be initialized on some systems to avoid linking in the
|
||||
system's own getopt implementation. */
|
||||
|
||||
epicsShareDef int optopt = '?';
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||
so that eventually all the non-options are at the end. This allows options
|
||||
to be given in any order, even with programs that were not written to
|
||||
expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were written
|
||||
to expect options and other ARGV-elements in any order and that care about
|
||||
the ordering of the two. We describe each non-option ARGV-element
|
||||
as if it were the argument of an option with character code 1.
|
||||
Using `-' as the first character of the list of option characters
|
||||
selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
|
||||
|
||||
static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||
because there are many ways it can cause trouble.
|
||||
On some systems, it contains special magic macros that don't work
|
||||
in GCC. */
|
||||
#include <string.h>
|
||||
#define my_index strchr
|
||||
#define my_bcopy(src, dst, n) memcpy ((dst), (src), (n))
|
||||
#else
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
char *getenv ();
|
||||
|
||||
static char *
|
||||
my_index (str, chr)
|
||||
const char *str;
|
||||
int chr;
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
if (*str == chr)
|
||||
return (char *) str;
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
my_bcopy (from, to, size)
|
||||
const char *from;
|
||||
char *to;
|
||||
int size;
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < size; i++)
|
||||
to[i] = from[i];
|
||||
}
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
/* Describe the part of ARGV that contains non-options that have
|
||||
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
||||
`last_nonopt' is the index after the last of them. */
|
||||
|
||||
static int first_nonopt;
|
||||
static int last_nonopt;
|
||||
|
||||
/* Exchange two adjacent subsequences of ARGV.
|
||||
One subsequence is elements [first_nonopt,last_nonopt)
|
||||
which contains all the non-options that have been skipped so far.
|
||||
The other is elements [last_nonopt,optind), which contains all
|
||||
the options processed since those non-options were skipped.
|
||||
|
||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
static void
|
||||
exchange (argv)
|
||||
char **argv;
|
||||
{
|
||||
int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
|
||||
char **temp = (char **) __alloca (nonopts_size);
|
||||
|
||||
/* Interchange the two blocks of data in ARGV. */
|
||||
|
||||
my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
|
||||
my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
|
||||
(optind - last_nonopt) * sizeof (char *));
|
||||
my_bcopy ((char *) temp,
|
||||
(char *) &argv[first_nonopt + optind - last_nonopt],
|
||||
nonopts_size);
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
first_nonopt += (optind - last_nonopt);
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
|
||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||
then it is an option element. The characters of this element
|
||||
(aside from the initial '-') are option characters. If `getopt'
|
||||
is called repeatedly, it returns successively each of the option characters
|
||||
from each of the option elements.
|
||||
|
||||
If `getopt' finds another option character, it returns that character,
|
||||
updating `optind' and `nextchar' so that the next call to `getopt' can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, `getopt' returns `EOF'.
|
||||
Then `optind' is the index in ARGV of the first ARGV-element
|
||||
that is not an option. (The ARGV-elements have been permuted
|
||||
so that those that are not options now come last.)
|
||||
|
||||
OPTSTRING is a string containing the legitimate option characters.
|
||||
If an option character is seen that is not listed in OPTSTRING,
|
||||
return '?' after printing an error message. If you set `opterr' to
|
||||
zero, the error message is suppressed but we still return '?'.
|
||||
|
||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||
so the following text in the same ARGV-element, or the text of the following
|
||||
ARGV-element, is returned in `optarg'. Two colons mean an option that
|
||||
wants an optional arg; if there is text in the current ARGV-element,
|
||||
it is returned in `optarg', otherwise `optarg' is set to zero.
|
||||
|
||||
If OPTSTRING starts with `-' or `+', it requests different methods of
|
||||
handling the non-option ARGV-elements.
|
||||
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||
|
||||
Long-named options begin with `--' instead of `-'.
|
||||
Their names may be abbreviated as long as the abbreviation is unique
|
||||
or is an exact match for some defined option. If they have an
|
||||
argument, it follows the option name in the same ARGV-element, separated
|
||||
from the option name by a `=', or else the in next ARGV-element.
|
||||
When `getopt' finds a long-named option, it returns 0 if that option's
|
||||
`flag' field is nonzero, the value of the option's `val' field
|
||||
if the `flag' field is zero.
|
||||
|
||||
The elements of ARGV aren't really const, because we permute them.
|
||||
But we pretend they're const in the prototype to be compatible
|
||||
with other systems.
|
||||
|
||||
LONGOPTS is a vector of `struct option' terminated by an
|
||||
element containing a name which is zero.
|
||||
|
||||
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||
It is only valid when a long-named option has been found by the most
|
||||
recent call.
|
||||
|
||||
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||
long-named options. */
|
||||
|
||||
int
|
||||
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
const struct option *longopts;
|
||||
int *longind;
|
||||
int long_only;
|
||||
{
|
||||
int option_index;
|
||||
|
||||
optarg = 0;
|
||||
|
||||
/* Initialize the internal data when the first call is made.
|
||||
Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
if (optind == 0)
|
||||
{
|
||||
first_nonopt = last_nonopt = optind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (getenv ("POSIXLY_CORRECT") != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
}
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (last_nonopt != optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
/* Now skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (optind < argc
|
||||
&& (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#ifdef GETOPT_COMPAT
|
||||
&& (longopts == NULL
|
||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||
#endif /* GETOPT_COMPAT */
|
||||
)
|
||||
optind++;
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||
{
|
||||
optind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = optind;
|
||||
last_nonopt = argc;
|
||||
|
||||
optind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (optind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
optind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#ifdef GETOPT_COMPAT
|
||||
&& (longopts == NULL
|
||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||
#endif /* GETOPT_COMPAT */
|
||||
)
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
optarg = argv[optind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Start decoding its characters. */
|
||||
|
||||
nextchar = (argv[optind] + 1
|
||||
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||
}
|
||||
|
||||
if (longopts != NULL
|
||||
&& ((argv[optind][0] == '-'
|
||||
&& (argv[optind][1] == '-' || long_only))
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
))
|
||||
{
|
||||
const struct option *p;
|
||||
char *s = nextchar;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
const struct option *pfound = NULL;
|
||||
int indfound;
|
||||
|
||||
while (*s && *s != '=')
|
||||
s++;
|
||||
|
||||
/* Test all options for either exact match or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name;
|
||||
p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, s - nextchar))
|
||||
{
|
||||
if (s - nextchar == strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
||||
argv[0], argv[optind]);
|
||||
nextchar += strlen (nextchar);
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
optind++;
|
||||
if (*s)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
optarg = s + 1;
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind - 1][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr,
|
||||
"%s: option `--%s' doesn't allow an argument\n",
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr,
|
||||
"%s: option `%c%s' doesn't allow an argument\n",
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (optind < argc)
|
||||
optarg = argv[optind++];
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' requires an argument\n",
|
||||
argv[0], argv[optind - 1]);
|
||||
nextchar += strlen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short
|
||||
option, then it's an error.
|
||||
Otherwise interpret it as a short option. */
|
||||
if (!long_only || argv[optind][1] == '-'
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr, "%s: unrecognized option `--%s'\n",
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
||||
argv[0], argv[optind][0], nextchar);
|
||||
}
|
||||
nextchar = (char *) "";
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
char *temp = my_index (optstring, c);
|
||||
|
||||
/* Increment `optind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++optind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
#if 0
|
||||
if (c < 040 || c >= 0177)
|
||||
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
|
||||
argv[0], c);
|
||||
else
|
||||
fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
|
||||
#else
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
|
||||
#endif
|
||||
}
|
||||
optopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = 0;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
optind++;
|
||||
}
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
#if 0
|
||||
fprintf (stderr, "%s: option `-%c' requires an argument\n",
|
||||
argv[0], c);
|
||||
#else
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: option requires an argument -- %c\n",
|
||||
argv[0], c);
|
||||
#endif
|
||||
}
|
||||
optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `optind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
optarg = argv[optind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int epicsShareAPI
|
||||
getopt (argc, argv, optstring)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
{
|
||||
return _getopt_internal (argc, argv, optstring,
|
||||
(const struct option *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
the above definition of `getopt'. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
|
||||
c = getopt (argc, argv, "abc:d:0123456789");
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
@@ -1,144 +0,0 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
#define _GETOPT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "shareLib.h"
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
epicsShareExtern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
epicsShareExtern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
epicsShareExtern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
epicsShareExtern int optopt;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
#if __STDC__
|
||||
const char *name;
|
||||
#else
|
||||
char *name;
|
||||
#endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
#if __STDC__
|
||||
#if defined(__GNU_LIBRARY__)
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
epicsShareFunc extern int epicsShareAPI
|
||||
getopt (int argc, char *const *argv, const char *shortopts);
|
||||
#else /* not __GNU_LIBRARY__ */
|
||||
epicsShareFunc extern int epicsShareAPI
|
||||
getopt (int argc, char *const *argv, const char *shortopts);
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
epicsShareFunc extern int epicsShareAPI
|
||||
getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
epicsShareFunc extern int
|
||||
epicsShareAPI getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only);
|
||||
#else /* not __STDC__ */
|
||||
epicsShareFunc extern int epicsShareAPI getopt ();
|
||||
epicsShareFunc extern int epicsShareAPI getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
#endif /* not __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GETOPT_H */
|
||||
@@ -185,6 +185,91 @@ epicsReadlineEnd (void *context)
|
||||
|
||||
#elif EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_EPICS
|
||||
|
||||
#if defined(vxWorks)
|
||||
|
||||
#include <ledLib.h>
|
||||
#define LEDLIB_LINESIZE 1000
|
||||
|
||||
struct readlineContext {
|
||||
int ledId;
|
||||
char line[LEDLIB_LINESIZE];
|
||||
FILE *in;
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a command-line context
|
||||
*/
|
||||
void * epicsShareAPI
|
||||
epicsReadlineBegin(FILE *in)
|
||||
{
|
||||
struct readlineContext *readlineContext;
|
||||
|
||||
readlineContext = malloc(sizeof *readlineContext);
|
||||
if (readlineContext != NULL) {
|
||||
readlineContext->ledId = ERROR;
|
||||
readlineContext->in = in;
|
||||
if (in == NULL) {
|
||||
const char *histSize = getenv("IOCSH_HISTSIZE");
|
||||
int i;
|
||||
|
||||
if (histSize == NULL)
|
||||
i = 50;
|
||||
else if ((i = atoi(histSize)) < 0)
|
||||
i = 1;
|
||||
readlineContext->ledId = ledOpen(fileno(stdin), fileno(stdout), i);
|
||||
if (readlineContext->ledId == ERROR) {
|
||||
readlineContext->in = stdin;
|
||||
printf("Warning -- Unabled to allocate space for command-line history.\n");
|
||||
printf("Warning -- Command-line editting disabled.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return readlineContext;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a line of input
|
||||
*/
|
||||
char * epicsShareAPI
|
||||
epicsReadline (const char *prompt, void *context)
|
||||
{
|
||||
struct readlineContext *readlineContext = context;
|
||||
int i;
|
||||
|
||||
if (prompt) {
|
||||
fputs(prompt, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
if (readlineContext->ledId != ERROR) {
|
||||
i = ledRead(readlineContext->ledId, readlineContext->line, LEDLIB_LINESIZE-1);
|
||||
if (i < 0)
|
||||
return NULL;
|
||||
readlineContext->line[i] = '\0';
|
||||
}
|
||||
else {
|
||||
if (fgets(readlineContext->line, LEDLIB_LINESIZE, readlineContext->in) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
return readlineContext->line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a command-line context
|
||||
*/
|
||||
void epicsShareAPI
|
||||
epicsReadlineEnd (void *context)
|
||||
{
|
||||
struct readlineContext *readlineContext = context;
|
||||
|
||||
if (readlineContext) {
|
||||
if (readlineContext->ledId != ERROR)
|
||||
ledClose(readlineContext->ledId);
|
||||
free(readlineContext);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* !vxWorks */
|
||||
|
||||
struct readlineContext {
|
||||
FILE *in;
|
||||
char *line;
|
||||
@@ -234,8 +319,6 @@ epicsReadline (const char *prompt, void *context)
|
||||
printf ("Out of memory!\n");
|
||||
return NULL;
|
||||
}
|
||||
if (prompt) {
|
||||
}
|
||||
while ((c = getc (in)) != '\n') {
|
||||
if (c == EOF) {
|
||||
free (line);
|
||||
@@ -274,6 +357,8 @@ epicsReadlineEnd (void *context)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !vxWorks */
|
||||
|
||||
#else
|
||||
|
||||
# error "Unsupported EPICS_COMMANDLINE_LIBRARY"
|
||||
|
||||
@@ -16,7 +16,13 @@ extern "C" {
|
||||
epicsShareFunc int epicsShareAPI epicsSnprintf(
|
||||
char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
return snprintf ( str, size, format );
|
||||
int nchars;
|
||||
va_list pvar;
|
||||
|
||||
va_start(pvar,format);
|
||||
nchars = epicsVsnprintf(str,size,format,pvar);
|
||||
va_end (pvar);
|
||||
return(nchars);
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsVsnprintf(
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "epicsSingleton.h"
|
||||
#include "tsDLList.h"
|
||||
#include "epicsTimer.h"
|
||||
#include "cxxCompilerDependencies.h"
|
||||
#include "compilerDependencies.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
# define debugPrintf(ARGSINPAREN) printf ARGSINPAREN
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
|
||||
include $(TOP)/configure/RELEASE
|
||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH)
|
||||
-include $(TOP)/configure/RELEASE.Common.$(T_A)
|
||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
CONFIG=$(EPICS_BASE)/configure
|
||||
include $(CONFIG)/CONFIG
|
||||
|
||||
INSTALL_LOCATION = $(TOP)
|
||||
ifdef INSTALL_LOCATION_APP
|
||||
INSTALL_LOCATION = $(INSTALL_LOCATION_APP)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
cd ${TOP}
|
||||
|
||||
## Register all support components
|
||||
dbLoadDatabase("dbd/_APPNAME_.dbd",0,0)
|
||||
dbLoadDatabase("dbd/_APPNAME_.dbd")
|
||||
_APPNAME__registerRecordDeviceDriver(pdbbase)
|
||||
|
||||
## Load record instances
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#< envPaths
|
||||
|
||||
## Register all support components
|
||||
dbLoadDatabase("dbd/_APPNAME_.dbd",0,0)
|
||||
dbLoadDatabase("dbd/_APPNAME_.dbd")
|
||||
_APPNAME__registerRecordDeviceDriver(pdbbase)
|
||||
|
||||
## Load record instances
|
||||
|
||||
@@ -13,6 +13,7 @@ TEMPLATES += top/configure/RELEASE
|
||||
TEMPLATES += top/configure/RULES
|
||||
TEMPLATES += top/configure/RULES_DIRS
|
||||
TEMPLATES += top/configure/RULES_TOP
|
||||
TEMPLATES += top/configure/RULES_PYTHON
|
||||
|
||||
TEMPLATES += $(subst ../,,$(wildcard ../top/configure/os/CONFIG*))
|
||||
|
||||
@@ -27,3 +28,4 @@ TEMPLATES += top/simpleExt/Makefile
|
||||
SCRIPTS_HOST += makeBaseExt.pl
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
|
||||
@@ -4,8 +4,3 @@
|
||||
# Site Specific Configuration Information
|
||||
# Only the local epics system manager should modify this file
|
||||
|
||||
# java jdk definitions
|
||||
CLASSPATH = -classpath .:..:$(INSTALL_JAVA):$(JAVA_DIR)/bin/../classes:$(JAVA_DIR)/bin/../lib/classes.zip
|
||||
JAVACCMD = $(subst \,/,$(JAVA_DIR)/bin/javac$(EXE) $(CLASSPATH) $(JAVAC_FLAGS) )
|
||||
JAVAHCMD = $(subst \,/,$(JAVA_DIR)/bin/javah$(EXE) -jni $(CLASSPATH) $(JAVAH_FLAGS))
|
||||
JARCMD = $(subst \,/,$(JAVA_DIR)/bin/jar$(EXE) $(JAR_OPTIONS) $(MANIFEST) $(JAR) $(JAR_INPUT))
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Site Specific Configuration Information
|
||||
# Only the local epics system manager should modify this file
|
||||
|
||||
# Where to find utilities/libraries
|
||||
# If you do not have a certain product,
|
||||
# leave the line empty.
|
||||
#
|
||||
|
||||
-include $(TOP)/configure/os/CONFIG_SITE.Common.Common
|
||||
|
||||
X11_LIB=/usr/X11R6/lib
|
||||
X11_INC=/usr/X11R6/include
|
||||
MOTIF_LIB=/usr/X11R6/lib
|
||||
MOTIF_INC=/usr/X11R6/Xm/include
|
||||
|
||||
TK_TCL = /sw/lib
|
||||
|
||||
PYTHON_DIR=/usr/lib/python2.2
|
||||
PYTHON_INCLUDE=/usr/include/python2.2
|
||||
|
||||
JAVA_DIR=/System/Library/Frameworks/JavaVM.framework/Home
|
||||
|
||||
@@ -25,5 +25,4 @@ MATHEMATICA = /usr/local/math
|
||||
QUESTWIN = /usr/local/questwin
|
||||
IDL = /usr/csite/idl
|
||||
JAVA_DIR=/usr/local/java
|
||||
JAVA_INC=$(JAVA_DIR)/include
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Site Specific Configuration Information
|
||||
# Only the local epics system manager should modify this file
|
||||
|
||||
# Where to find utilities/libraries
|
||||
# If you do not have a certain product,
|
||||
# leave the line empty.
|
||||
#
|
||||
|
||||
-include $(TOP)/configure/os/CONFIG_SITE.Common.Common
|
||||
|
||||
X11_LIB=/usr/X11R6/lib
|
||||
X11_INC=/usr/X11R6/include/X11
|
||||
MOTIF_LIB=/usr/X11R6/lib
|
||||
MOTIF_INC=/usr/X11R6/include
|
||||
#X11_INC=/local2/X11R6/include/X11
|
||||
#X11_LIB=/local2/X11R6/lib
|
||||
#MOTIF_LIB=/local2/X11R6/lib
|
||||
#MOTIF_INC=/local2/X11R6/include
|
||||
|
||||
OPENWIN =
|
||||
WINGZ =
|
||||
MATHEMATICA =
|
||||
SCIPLOT=YES
|
||||
XRTGRAPH =
|
||||
QUESTWIN =
|
||||
TK_TCL = /usr/lib
|
||||
IDL =
|
||||
|
||||
#JAVA_DIR=/usr/local/java
|
||||
JAVA_DIR=/usr/java/j2sdk1.4.1
|
||||
JAVA_INC = $(JAVA_DIR)/include
|
||||
JAVA_INCLUDES += -I$(JAVA_INC) -I$(JAVA_INC)/linux -I$(COMMON_DIR)
|
||||
|
||||
INTERVIEWS_BIN=/usr/local/interviews/bin/O.Linux
|
||||
|
||||
IV_INC=/usr/local/interviews/include
|
||||
IV_BIN=/usr/local/interviews/bin/O.Linux
|
||||
IV_LIB=/usr/local/interviews/lib/O.Linux
|
||||
|
||||
PYTHON_DIR=/usr/lib/python2.2
|
||||
PYTHON_INCLUDE=/usr/include/python2.2
|
||||
|
||||
@@ -29,8 +29,10 @@ QUESTWIN =
|
||||
TK_TCL = /usr/lib
|
||||
IDL =
|
||||
|
||||
JAVA_DIR=/usr/local/java
|
||||
JAVA_INC=$(JAVA_DIR)/include
|
||||
#JAVA_DIR=/usr/local/java
|
||||
JAVA_DIR=/usr/java/j2sdk1.4.1
|
||||
JAVA_INC = $(JAVA_DIR)/include
|
||||
JAVA_INCLUDES += -I$(JAVA_INC) -I$(JAVA_INC)/linux -I$(COMMON_DIR)
|
||||
|
||||
INTERVIEWS_BIN=/usr/local/interviews/bin/O.Linux
|
||||
|
||||
@@ -38,4 +40,6 @@ IV_INC=/usr/local/interviews/include
|
||||
IV_BIN=/usr/local/interviews/bin/O.Linux
|
||||
IV_LIB=/usr/local/interviews/lib/O.Linux
|
||||
|
||||
PYTHON_DIR=/usr/lib/python2.2
|
||||
PYTHON_INCLUDE=/usr/include/python2.2
|
||||
|
||||
|
||||
@@ -24,6 +24,4 @@ XRTGRAPH = /usr/local/xrtgraph
|
||||
QUESTWIN =
|
||||
IDL =
|
||||
JAVA_DIR=/usr/local/java
|
||||
JAVA_INC=$(JAVA_DIR)/include
|
||||
|
||||
|
||||
|
||||
@@ -57,12 +57,6 @@ IDL = /usr/local/idl
|
||||
# IDL=$(IDL)/external/rpc is the sun4 version
|
||||
IDLRPC = $(IDL)/external/rpc.solaris
|
||||
|
||||
# sun 5.4
|
||||
#JAVA_DIR=/opt/local/java
|
||||
# sun 5.6
|
||||
JAVA_DIR=/usr/java
|
||||
JAVA_INC=$(JAVA_DIR)/include
|
||||
|
||||
ZLIB_PREFIX = /usr/local/oag
|
||||
ZLIB = $(notdir $(wildcard $(ZLIB_PREFIX)/lib/libz.a))
|
||||
ifeq ($(ZLIB) , libz.a)
|
||||
@@ -79,3 +73,7 @@ ZLIB_PROD_LIB =
|
||||
z_DIR=
|
||||
endif
|
||||
|
||||
PYTHON_DIR=/opt/local/lib/python2.2
|
||||
PYTHON_INCLUDE=/opt/local/include/python2.2
|
||||
|
||||
JAVA_DIR=/usr/java
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Site Specific Configuration Information
|
||||
# Only the local epics system manager should modify this file
|
||||
|
||||
# Where to find utilities/libraries
|
||||
# If you do not have a certain product,
|
||||
# leave the line empty.
|
||||
#
|
||||
|
||||
-include $(TOP)/configure/os/CONFIG_SITE.Common.Common
|
||||
|
||||
|
||||
EXCEED = Exceed7.0
|
||||
|
||||
ifeq ($(EXCEED),Exceed5)
|
||||
X11_LIB = c:/exceed5/xdk/lib
|
||||
X11_INC = c:/exceed5/xdk/include
|
||||
EXCEED_XLIBS=xmstatic xt xlibgui xlib xmu
|
||||
xmstatic_DIR=$(X11_LIB)
|
||||
xt_DIR=$(X11_LIB)
|
||||
xlibgui_DIR=$(X11_LIB)
|
||||
xlib_DIR=$(X11_LIB)
|
||||
xmu_DIR=$(X11_LIB)
|
||||
EXCEED_CFLAGS=
|
||||
endif
|
||||
ifeq ($(EXCEED),Exceed6.0)
|
||||
X11_LIB = c:/exceed/xdk/lib
|
||||
X11_INC = c:/exceed/xdk/include
|
||||
EXCEED_XLIBS=xmstatic HCLXt xlibgui xlib HCLXmu
|
||||
xmstatic_DIR=$(X11_LIB)
|
||||
HCLXt_DIR=$(X11_LIB)
|
||||
xlibgui_DIR=$(X11_LIB)
|
||||
xlib_DIR=$(X11_LIB)
|
||||
HCLXmu_DIR=$(X11_LIB)
|
||||
EXCEED_CFLAGS=
|
||||
endif
|
||||
ifeq ($(EXCEED),Exceed6.1)
|
||||
X11_LIB = c:/exceed/xdk/lib
|
||||
X11_INC = c:/exceed/xdk/include
|
||||
EXCEED_XLIBS=XmStatic XmStatXt xlibgui xlib HCLXmu
|
||||
XmStatic_DIR=$(X11_LIB)
|
||||
XmStatXt_DIR=$(X11_LIB)
|
||||
xlibgui_DIR=$(X11_LIB)
|
||||
xlib_DIR=$(X11_LIB)
|
||||
HCLXmu_DIR=$(X11_LIB)
|
||||
EXCEED_CFLAGS=/DXMSTATIC
|
||||
endif
|
||||
ifeq ($(EXCEED),Exceed6.2)
|
||||
X11_LIB = c:/exceed/xdk/lib
|
||||
X11_INC = c:/exceed/xdk/include
|
||||
EXCEED_XLIBS=XmStatic XmStatXt xlibgui Xlib hclXmu
|
||||
XmStatic_DIR=$(X11_LIB)
|
||||
XmStatXt_DIR=$(X11_LIB)
|
||||
xlibgui_DIR=$(X11_LIB)
|
||||
Xlib_DIR=$(X11_LIB)
|
||||
hclXmu_DIR=$(X11_LIB)
|
||||
EXCEED_CFLAGS=/DXMSTATIC
|
||||
endif
|
||||
ifeq ($(EXCEED),Exceed7.0)
|
||||
X11_LIB = c:/Exceed/xdk/lib
|
||||
X11_INC = c:/Exceed/xdk/include
|
||||
EXCEED_XLIBS=XmStatic XmStatXt XlibGui Xlib HCLXmu
|
||||
XmStatic_DIR=$(X11_LIB)
|
||||
XmStatXt_DIR=$(X11_LIB)
|
||||
XlibGui_DIR=$(X11_LIB)
|
||||
Xlib_DIR=$(X11_LIB)
|
||||
HCLXmu_DIR=$(X11_LIB)
|
||||
EXCEED_CFLAGS=/DXMSTATIC /DMOTIFAPP
|
||||
endif
|
||||
|
||||
MOTIF_LIB = $(X11_LIB)
|
||||
MOTIF_INC = $(X11_INC)
|
||||
|
||||
TCL = c:\\Tcl
|
||||
TK_LIB = $(TCL)/lib
|
||||
TK_INC = $(TCL)/include
|
||||
TCL_LIB = $(TCL)/lib
|
||||
TCL_INC = $(TCL)/include
|
||||
DP_LIB = $(TCL)/lib
|
||||
DP_INC = $(TCL)/include
|
||||
BLT_LIB = $(TCL)/lib
|
||||
BLT_INC = $(TCL)/include
|
||||
|
||||
IDL = /usr/local/idl
|
||||
# IDL=$(IDL)/external/rpc is the sun4 version
|
||||
IDLRPC = $(IDL)/external/rpc.solaris
|
||||
|
||||
OPENWIN =
|
||||
INTERVIEWS_BIN =
|
||||
WINGZ_INC =
|
||||
WINGZ_LIB =
|
||||
MATHEMATICA =
|
||||
QUESTWIN =
|
||||
|
||||
# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x
|
||||
# and you want the extensions for MEDM
|
||||
XRTGRAPH_EXTENSIONS = NO
|
||||
XRTGRAPH =
|
||||
|
||||
SCIPLOT = ../../src/medmdev/medm
|
||||
|
||||
# z library created in SDDS extension
|
||||
ZLIB_CFLAG = -DzLib
|
||||
ZLIB_PROD_LIB = z
|
||||
z_DIR = $(EPICS_EXTENSIONS_LIB)
|
||||
|
||||
JAVA_DIR=c:/j2sdk1.4.1_01
|
||||
@@ -73,9 +73,6 @@ endif
|
||||
MOTIF_LIB = $(X11_LIB)
|
||||
MOTIF_INC = $(X11_INC)
|
||||
|
||||
JAVA_DIR = c:\\jdk1.3
|
||||
JAVA_INC = $(JAVA_DIR)/include
|
||||
|
||||
TCL = c:\\Tcl
|
||||
TK_LIB = $(TCL)/lib
|
||||
TK_INC = $(TCL)/include
|
||||
@@ -109,3 +106,4 @@ ZLIB_CFLAG = -DzLib
|
||||
ZLIB_PROD_LIB = z
|
||||
z_DIR = $(EPICS_EXTENSIONS_LIB)
|
||||
|
||||
JAVA_DIR=c:/j2sdk1.4.1_01
|
||||
|
||||
@@ -122,7 +122,7 @@ static long init_record(psub,pass)
|
||||
}
|
||||
|
||||
if(strlen(psub->snam)==0) {
|
||||
epicsPrintf("%s snam not specified\n",psub);
|
||||
epicsPrintf("%s snam not specified\n",psub->name);
|
||||
psub->pact = TRUE;
|
||||
return(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user