Bugfixes plus added support for escaping non-printables and field separator to CA commandline tools.
This commit is contained in:
@@ -12,9 +12,35 @@
|
||||
<h2 align="center">Changes between 3.14.10 and 3.14.11</h2>
|
||||
<!-- Insert new items below here ... -->
|
||||
|
||||
<h4>Channel Access command line tool changes</h4>
|
||||
|
||||
<p>The caget/caput/camonitor programs in src/catools now use '\' escape
|
||||
sequences for non-printable characters.</p>
|
||||
|
||||
<p>They provide a new option <tt>-F</tt> to set an output field separator
|
||||
to be used instead of the default space character.</p>
|
||||
|
||||
<h4>New functions for escaping non-printables in epicsString.h</h4>
|
||||
|
||||
<p>The existing routines used to escape non-printable characters have been replaced
|
||||
by a new set of functions that are prototyped in the epicsString.h header file:</p>
|
||||
|
||||
<pre>int epicsStrnRawFromEscaped(char *outbuf, size_t outsize, const char *inbuf, size_t inlen);
|
||||
epicsShareFunc int epicsStrnEscapedFromRaw(char *outbuf, size_t outsize, const char *inbuf, size_t inlen);
|
||||
epicsShareFunc size_t epicsStrnEscapedFromRawSize(const char *inbuf, size_t inlen);</pre>
|
||||
|
||||
<p>Both conversion functions take the output buffer (and its size), and the input
|
||||
buffer (and its size) as argument. They will convert non-printable characters
|
||||
from/to their '\'-escaped versions. The third function scans a raw input string
|
||||
and returns the number of characters needed for the escaped version.</p>
|
||||
|
||||
<p>The existing function interfaces will be kept for compatibility, but their
|
||||
further use is deprecated.</p>
|
||||
|
||||
<h4>epicsRingBytes</h4>
|
||||
|
||||
<p>Partial puts are not supported. An attempt to put more bytes than currently free will be rejected.</p>
|
||||
<p>Partial puts are not supported.
|
||||
An attempt to put more bytes than currently free will be rejected.</p>
|
||||
|
||||
<h4>Long string support</h4>
|
||||
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
/*************************************************************************\
|
||||
* 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.
|
||||
* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer
|
||||
* Synchrotronstrahlung.
|
||||
* 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.
|
||||
* Copyright (c) 2009 Brookhaven Science Associates, as Operator of
|
||||
* Brookhaven National Laboratory.
|
||||
* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie.
|
||||
* Copyright (c) 2006 Diamond Light Source Ltd.
|
||||
* 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.
|
||||
* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer
|
||||
* Synchrotronstrahlung.
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Author: Ralph Lange (BESSY)
|
||||
*
|
||||
* Modification History
|
||||
@@ -18,12 +22,17 @@
|
||||
* Fixed problem with "-c -w 0" hanging forever
|
||||
* 2008/04/16 Ralph Lange (BESSY)
|
||||
* Updated usage info
|
||||
* 2009/03/31 Larry Hoff (BNL)
|
||||
* Added field separators
|
||||
* 2009/04/01 Ralph Lange (HZB/BESSY)
|
||||
* Added support for long strings (array of char) and quoting of nonprintable characters
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <epicsStdlib.h>
|
||||
#include <string.h>
|
||||
#include <epicsStdlib.h>
|
||||
#include <epicsString.h>
|
||||
|
||||
#include <alarm.h>
|
||||
#include <cadef.h>
|
||||
@@ -45,7 +54,7 @@ static int nRead = 0; /* Number of channels that were read */
|
||||
static int floatAsString = 0; /* Flag: fetch floats as string */
|
||||
|
||||
|
||||
void usage (void)
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, "\nUsage: caget [options] <PV name> ...\n\n"
|
||||
" -h: Help: Print this message\n"
|
||||
@@ -87,6 +96,8 @@ void usage (void)
|
||||
" -0x: Print as hex number\n"
|
||||
" -0o: Print as octal number\n"
|
||||
" -0b: Print as binary number\n"
|
||||
"Alternate output field separator:\n"
|
||||
" -F <ofs>: Use <ofs> as an alternate output field separator\n"
|
||||
"\nExample: caget -a -f8 my_channel another_channel\n"
|
||||
" (uses wide output format, doubles are printed as %%f with precision of 8)\n\n"
|
||||
, DEFAULT_TIMEOUT, CA_PRIORITY_MAX);
|
||||
@@ -105,7 +116,7 @@ void usage (void)
|
||||
*
|
||||
**************************************************************************-*/
|
||||
|
||||
void event_handler (evargs args)
|
||||
static void event_handler (evargs args)
|
||||
{
|
||||
pv* ppv = args.usr;
|
||||
|
||||
@@ -140,7 +151,7 @@ void event_handler (evargs args)
|
||||
*
|
||||
**************************************************************************-*/
|
||||
|
||||
int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
static int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
chtype dbrType, unsigned long reqElems)
|
||||
{
|
||||
unsigned int i;
|
||||
@@ -154,6 +165,7 @@ int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
/* Get natural type and array count */
|
||||
pvs[n].nElems = ca_element_count(pvs[n].chid);
|
||||
pvs[n].dbfType = ca_field_type(pvs[n].chid);
|
||||
pvs[n].dbrType = dbrType;
|
||||
|
||||
/* Set up value structures */
|
||||
if (format != specifiedDbr)
|
||||
@@ -240,8 +252,9 @@ int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
|
||||
switch (format) {
|
||||
case plain: /* Emulate old caget behaviour */
|
||||
if (pvs[n].reqElems <= 1) printf("%-30s ", pvs[n].name);
|
||||
else printf("%s", pvs[n].name);
|
||||
if (pvs[n].reqElems <= 1 && fieldSeparator == ' ') printf("%-30s", pvs[n].name);
|
||||
else printf("%s", pvs[n].name);
|
||||
printf("%c", fieldSeparator);
|
||||
case terse:
|
||||
if (pvs[n].status == ECA_DISCONN)
|
||||
printf("*** not connected\n");
|
||||
@@ -254,11 +267,16 @@ int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
else
|
||||
{
|
||||
if (charArrAsStr && dbr_type_is_CHAR(pvs[n].dbrType) && (reqElems || pvs[n].reqElems > 1)) {
|
||||
printf(" %s", (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType));
|
||||
dbr_char_t *s = (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType);
|
||||
int dlen = epicsStrnEscapedFromRawSize((char*)s, strlen((char*)s));
|
||||
char *d = calloc(dlen+1, sizeof(char));
|
||||
epicsStrnEscapedFromRaw(d, dlen+1, (char*)s, strlen((char*)s));
|
||||
printf("%s", d);
|
||||
free(d);
|
||||
} else {
|
||||
if (reqElems || pvs[n].nElems > 1) printf(" %lu", pvs[n].reqElems);
|
||||
if (reqElems || pvs[n].nElems > 1) printf("%lu%c", pvs[n].reqElems, fieldSeparator);
|
||||
for (i=0; i<pvs[n].reqElems; ++i) {
|
||||
if (i) printf (" ");
|
||||
if (i) printf ("%c", fieldSeparator);
|
||||
printf("%s", val2str(pvs[n].value, pvs[n].dbrType, i));
|
||||
}
|
||||
}
|
||||
@@ -278,8 +296,9 @@ int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
printf(" *** CA error %s\n", ca_message(pvs[n].status));
|
||||
else
|
||||
{
|
||||
printf(" Native data type: %s (CA uses %s)\n",
|
||||
dbf_type_to_text(pvs[n].dbfType),
|
||||
printf(" Native data type: %s\n",
|
||||
dbf_type_to_text(pvs[n].dbfType));
|
||||
printf(" Request type: %s\n",
|
||||
dbr_type_to_text(pvs[n].dbrType));
|
||||
if (pvs[n].dbrType == DBR_CLASS_NAME)
|
||||
printf(" Class Name: %s\n",
|
||||
@@ -290,10 +309,15 @@ int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
" Value: ",
|
||||
pvs[n].reqElems);
|
||||
if (charArrAsStr && dbr_type_is_CHAR(pvs[n].dbrType) && (reqElems || pvs[n].reqElems > 1)) {
|
||||
printf(" %s", (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType));
|
||||
dbr_char_t *s = (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType);
|
||||
int dlen = epicsStrnEscapedFromRawSize((char*)s, strlen((char*)s));
|
||||
char *d = calloc(dlen+1, sizeof(char));
|
||||
epicsStrnEscapedFromRaw(d, dlen+1, (char*)s, strlen((char*)s));
|
||||
printf("%s", d);
|
||||
free(d);
|
||||
} else {
|
||||
for (i=0; i<pvs[n].reqElems; ++i) {
|
||||
if (i) printf (" ");
|
||||
if (i) printf ("%c", fieldSeparator);
|
||||
printf("%s", val2str(pvs[n].value, pvs[n].dbrType, i));
|
||||
}
|
||||
}
|
||||
@@ -328,7 +352,7 @@ int caget (pv *pvs, int nPvs, RequestT request, OutputT format,
|
||||
*
|
||||
**************************************************************************-*/
|
||||
|
||||
void complainIfNotPlainAndSet (OutputT *current, const OutputT requested)
|
||||
static void complainIfNotPlainAndSet (OutputT *current, const OutputT requested)
|
||||
{
|
||||
if (*current != plain)
|
||||
fprintf(stderr,
|
||||
@@ -354,7 +378,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */
|
||||
|
||||
while ((opt = getopt(argc, argv, ":taicnhsSe:f:g:#:d:0:w:p:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, ":taicnhsSe:f:g:#:d:0:w:p:F:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h': /* Print usage */
|
||||
usage();
|
||||
@@ -450,6 +474,9 @@ int main (int argc, char *argv[])
|
||||
"for option '-0' - ignored.\n", optarg);
|
||||
}
|
||||
break;
|
||||
case 'F': /* Store this for output and tool_lib formatting */
|
||||
fieldSeparator = (char) *optarg;
|
||||
break;
|
||||
case '?':
|
||||
fprintf(stderr,
|
||||
"Unrecognized option: '-%c'. ('caget -h' for help.)\n",
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
/*************************************************************************\
|
||||
* 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.
|
||||
* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer
|
||||
* Synchrotronstrahlung.
|
||||
* 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.
|
||||
* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie.
|
||||
* 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.
|
||||
* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer
|
||||
* Synchrotronstrahlung.
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Author: Ralph Lange (BESSY)
|
||||
*
|
||||
* Modification History
|
||||
* 2008/04/16 Ralph Lange (BESSY)
|
||||
* Updated usage info
|
||||
* 2009/04/01 Ralph Lange (HZB/BESSY)
|
||||
* Clarified output for native data type
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -87,7 +90,8 @@ int cainfo (pv *pvs, int nPvs)
|
||||
" State: %s\n"
|
||||
" Host: %s\n"
|
||||
" Access: %sread, %swrite\n"
|
||||
" Native data type: %s (CA uses %s)\n"
|
||||
" Native data type: %s\n"
|
||||
" Request type: %s\n"
|
||||
" Element count: %lu\n"
|
||||
, pvs[n].name,
|
||||
stateStrings[state],
|
||||
@@ -143,7 +147,7 @@ int main (int argc, char *argv[])
|
||||
if(epicsScanDouble(optarg, &caTimeout) != 1)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not a valid timeout value "
|
||||
"- ignored. ('caget -h' for help.)\n", optarg);
|
||||
"- ignored. ('cainfo -h' for help.)\n", optarg);
|
||||
caTimeout = DEFAULT_TIMEOUT;
|
||||
}
|
||||
break;
|
||||
@@ -151,7 +155,7 @@ int main (int argc, char *argv[])
|
||||
if (sscanf(optarg,"%du", &statLevel) != 1)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not a valid interest level "
|
||||
"- ignored. ('caget -h' for help.)\n", optarg);
|
||||
"- ignored. ('cainfo -h' for help.)\n", optarg);
|
||||
statLevel = 0;
|
||||
}
|
||||
break;
|
||||
@@ -159,19 +163,19 @@ int main (int argc, char *argv[])
|
||||
if (sscanf(optarg,"%u", &caPriority) != 1)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not a valid CA priority "
|
||||
"- ignored. ('caget -h' for help.)\n", optarg);
|
||||
"- ignored. ('cainfo -h' for help.)\n", optarg);
|
||||
caPriority = DEFAULT_CA_PRIORITY;
|
||||
}
|
||||
if (caPriority > CA_PRIORITY_MAX) caPriority = CA_PRIORITY_MAX;
|
||||
break;
|
||||
case '?':
|
||||
fprintf(stderr,
|
||||
"Unrecognized option: '-%c'. ('caget -h' for help.)\n",
|
||||
"Unrecognized option: '-%c'. ('cainfo -h' for help.)\n",
|
||||
optopt);
|
||||
return 1;
|
||||
case ':':
|
||||
fprintf(stderr,
|
||||
"Option '-%c' requires an argument. ('caget -h' for help.)\n",
|
||||
"Option '-%c' requires an argument. ('cainfo -h' for help.)\n",
|
||||
optopt);
|
||||
return 1;
|
||||
default :
|
||||
@@ -184,7 +188,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
if (!statLevel && nPvs < 1)
|
||||
{
|
||||
fprintf(stderr, "No pv name specified. ('caget -h' for help.)\n");
|
||||
fprintf(stderr, "No pv name specified. ('cainfo -h' for help.)\n");
|
||||
return 1;
|
||||
}
|
||||
/* Start up Channel Access */
|
||||
|
||||
@@ -1,21 +1,28 @@
|
||||
/*************************************************************************\
|
||||
* 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.
|
||||
* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer
|
||||
* Synchrotronstrahlung.
|
||||
* 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.
|
||||
* Copyright (c) 2009 Brookhaven Science Associates, as Operator of
|
||||
* Brookhaven National Laboratory.
|
||||
* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie.
|
||||
* 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.
|
||||
* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer
|
||||
* Synchrotronstrahlung.
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Author: Ralph Lange (BESSY)
|
||||
*
|
||||
* Modification History
|
||||
* 2008/04/16 Ralph Lange (BESSY)
|
||||
* Updated usage info
|
||||
* 2009/03/31 Larry Hoff (BNL)
|
||||
* Added field separators
|
||||
* 2009/04/01 Ralph Lange (HZB/BESSY)
|
||||
* Added support for long strings (array of char) and quoting of nonprintable characters
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -71,6 +78,8 @@ void usage (void)
|
||||
" -0x: Print as hex number\n"
|
||||
" -0o: Print as octal number\n"
|
||||
" -0b: Print as binary number\n"
|
||||
"Alternate output field separator:\n"
|
||||
" -F <ofs>: Use <ofs> as an alternate output field separator\n"
|
||||
"\nExample: camonitor -f8 my_channel another_channel\n"
|
||||
" (doubles are printed as %%f with precision of 8)\n\n"
|
||||
, DEFAULT_TIMEOUT, CA_PRIORITY_MAX);
|
||||
@@ -89,7 +98,7 @@ void usage (void)
|
||||
*
|
||||
**************************************************************************-*/
|
||||
|
||||
void event_handler (evargs args)
|
||||
static void event_handler (evargs args)
|
||||
{
|
||||
pv* pv = args.usr;
|
||||
|
||||
@@ -115,7 +124,7 @@ void event_handler (evargs args)
|
||||
*
|
||||
**************************************************************************-*/
|
||||
|
||||
void connection_handler ( struct connection_handler_args args )
|
||||
static void connection_handler ( struct connection_handler_args args )
|
||||
{
|
||||
pv *ppv = ( pv * ) ca_puser ( args.chid );
|
||||
if ( args.op == CA_OP_CONN_UP ) {
|
||||
@@ -206,7 +215,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */
|
||||
|
||||
while ((opt = getopt(argc, argv, ":nhm:sSe:f:g:#:d:0:w:t:p:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, ":nhm:sSe:f:g:#:d:0:w:t:p:F:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h': /* Print usage */
|
||||
usage();
|
||||
@@ -238,7 +247,7 @@ int main (int argc, char *argv[])
|
||||
if(epicsScanDouble(optarg, &caTimeout) != 1)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not a valid timeout value "
|
||||
"- ignored. ('caget -h' for help.)\n", optarg);
|
||||
"- ignored. ('camonitor -h' for help.)\n", optarg);
|
||||
caTimeout = DEFAULT_TIMEOUT;
|
||||
}
|
||||
break;
|
||||
@@ -246,7 +255,7 @@ int main (int argc, char *argv[])
|
||||
if (sscanf(optarg,"%ld", &reqElems) != 1)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not a valid array element count "
|
||||
"- ignored. ('caget -h' for help.)\n", optarg);
|
||||
"- ignored. ('camonitor -h' for help.)\n", optarg);
|
||||
reqElems = 0;
|
||||
}
|
||||
break;
|
||||
@@ -254,7 +263,7 @@ int main (int argc, char *argv[])
|
||||
if (sscanf(optarg,"%u", &caPriority) != 1)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not a valid CA priority "
|
||||
"- ignored. ('caget -h' for help.)\n", optarg);
|
||||
"- ignored. ('camonitor -h' for help.)\n", optarg);
|
||||
caPriority = DEFAULT_CA_PRIORITY;
|
||||
}
|
||||
if (caPriority > CA_PRIORITY_MAX) caPriority = CA_PRIORITY_MAX;
|
||||
@@ -309,14 +318,17 @@ int main (int argc, char *argv[])
|
||||
"for option '-0' - ignored.\n", optarg);
|
||||
}
|
||||
break;
|
||||
case 'F': /* Store this for output and tool_lib formatting */
|
||||
fieldSeparator = (char) *optarg;
|
||||
break;
|
||||
case '?':
|
||||
fprintf(stderr,
|
||||
"Unrecognized option: '-%c'. ('caget -h' for help.)\n",
|
||||
"Unrecognized option: '-%c'. ('camonitor -h' for help.)\n",
|
||||
optopt);
|
||||
return 1;
|
||||
case ':':
|
||||
fprintf(stderr,
|
||||
"Option '-%c' requires an argument. ('caget -h' for help.)\n",
|
||||
"Option '-%c' requires an argument. ('camonitor -h' for help.)\n",
|
||||
optopt);
|
||||
return 1;
|
||||
default :
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2006 Diamond Light Source Ltd.
|
||||
* 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.
|
||||
* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer
|
||||
* Synchrotronstrahlung.
|
||||
* 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.
|
||||
* Copyright (c) 2009 Brookhaven Science Associates, as Operator of
|
||||
* Brookhaven National Laboratory.
|
||||
* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie.
|
||||
* Copyright (c) 2006 Diamond Light Source Ltd.
|
||||
* 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.
|
||||
* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer
|
||||
* Synchrotronstrahlung.
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Author: Ralph Lange (BESSY)
|
||||
*
|
||||
* Modification History
|
||||
@@ -22,6 +25,10 @@
|
||||
* (semaphore), i.e. remove ca_pend_event time slicing.
|
||||
* 2008/04/16 Ralph Lange (BESSY)
|
||||
* Updated usage info
|
||||
* 2009/03/31 Larry Hoff (BNL)
|
||||
* Added field separators
|
||||
* 2009/04/01 Ralph Lange (HZB/BESSY)
|
||||
* Added support for long strings (array of char) and quoting of nonprintable characters
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -32,6 +39,7 @@
|
||||
#include <cadef.h>
|
||||
#include <epicsGetopt.h>
|
||||
#include <epicsEvent.h>
|
||||
#include <epicsString.h>
|
||||
|
||||
#include "tool_lib.h"
|
||||
|
||||
@@ -128,6 +136,7 @@ int caget (pv *pvs, int nPvs, OutputT format,
|
||||
/* Get natural type and array count */
|
||||
pvs[n].nElems = ca_element_count(pvs[n].chid);
|
||||
pvs[n].dbfType = ca_field_type(pvs[n].chid);
|
||||
pvs[n].dbrType = dbrType;
|
||||
|
||||
/* Set up value structures */
|
||||
pvs[n].dbrType = dbf_type_to_DBR_TIME(pvs[n].dbfType); /* Use native type */
|
||||
@@ -176,8 +185,9 @@ int caget (pv *pvs, int nPvs, OutputT format,
|
||||
|
||||
switch (format) {
|
||||
case plain: /* Emulate old caput behaviour */
|
||||
if (pvs[n].reqElems <= 1) printf("%-30s ", pvs[n].name);
|
||||
else printf("%s", pvs[n].name);
|
||||
if (pvs[n].reqElems <= 1 && fieldSeparator == ' ') printf("%-30s", pvs[n].name);
|
||||
else printf("%s", pvs[n].name);
|
||||
printf("%c", fieldSeparator);
|
||||
case terse:
|
||||
if (pvs[n].status == ECA_DISCONN)
|
||||
printf("*** not connected\n");
|
||||
@@ -190,11 +200,16 @@ int caget (pv *pvs, int nPvs, OutputT format,
|
||||
else
|
||||
{
|
||||
if (charArrAsStr && dbr_type_is_CHAR(pvs[n].dbrType) && (reqElems || pvs[n].reqElems > 1)) {
|
||||
printf(" %s", (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType));
|
||||
dbr_char_t *s = (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType);
|
||||
int dlen = epicsStrnEscapedFromRawSize((char*)s, strlen((char*)s));
|
||||
char *d = calloc(dlen+1, sizeof(char));
|
||||
epicsStrnEscapedFromRaw(d, dlen+1, (char*)s, strlen((char*)s));
|
||||
printf("%s", d);
|
||||
free(d);
|
||||
} else {
|
||||
if (reqElems || pvs[n].nElems > 1) printf(" %lu", pvs[n].reqElems);
|
||||
if (reqElems || pvs[n].nElems > 1) printf("%lu%c", pvs[n].reqElems, fieldSeparator);
|
||||
for (i=0; i<pvs[n].reqElems; ++i) {
|
||||
if (i) printf (" ");
|
||||
if (i) printf ("%c", fieldSeparator);
|
||||
printf("%s", val2str(pvs[n].value, pvs[n].dbrType, i));
|
||||
}
|
||||
}
|
||||
@@ -246,6 +261,7 @@ int main (int argc, char *argv[])
|
||||
EpicsStr *sbuf;
|
||||
double *dbuf;
|
||||
char *cbuf = 0;
|
||||
char *ebuf = 0;
|
||||
void *pbuf;
|
||||
int len = 0;
|
||||
int waitStatus;
|
||||
@@ -257,7 +273,7 @@ int main (int argc, char *argv[])
|
||||
setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */
|
||||
putenv("POSIXLY_CORRECT="); /* Behave correct on GNU getopt systems */
|
||||
|
||||
while ((opt = getopt(argc, argv, ":cnlhatsS#:w:p:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, ":cnlhatsS#:w:p:F:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h': /* Print usage */
|
||||
usage();
|
||||
@@ -312,6 +328,9 @@ int main (int argc, char *argv[])
|
||||
}
|
||||
if (caPriority > CA_PRIORITY_MAX) caPriority = CA_PRIORITY_MAX;
|
||||
break;
|
||||
case 'F': /* Store this for output and tool_lib formatting */
|
||||
fieldSeparator = (char) *optarg;
|
||||
break;
|
||||
case '?':
|
||||
fprintf(stderr,
|
||||
"Unrecognized option: '-%c'. ('caput -h' for help.)\n",
|
||||
@@ -429,32 +448,27 @@ int main (int argc, char *argv[])
|
||||
} else { /* Interpret values as strings */
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
len = strlen(*(argv+optind+i));
|
||||
if (len >= sizeof(EpicsStr)) /* Too long? Cut at max length */
|
||||
*( *(argv+optind+i)+sizeof(EpicsStr)-1 ) = 0;
|
||||
epicsStrnRawFromEscaped(sbuf[i], sizeof(EpicsStr), *(argv+optind+i), sizeof(EpicsStr));
|
||||
*( sbuf[i]+sizeof(EpicsStr)-1 ) = '\0';
|
||||
dbrType = DBR_STRING;
|
||||
|
||||
/* Compare to ENUM strings */
|
||||
for (len = 0; len < bufGrEnum.no_str; len++)
|
||||
if (!strcmp(*(argv+optind+i), bufGrEnum.strs[len]))
|
||||
if (!strcmp(sbuf[i], bufGrEnum.strs[len]))
|
||||
break;
|
||||
|
||||
if (len >= bufGrEnum.no_str) {
|
||||
/* Not a string? Try as number */
|
||||
dbuf[i] = epicsStrtod(*(argv+optind+i), &pend);
|
||||
if (*(argv+optind+i) == pend || enumAsString) {
|
||||
fprintf(stderr, "Enum string value '%s' invalid.\n",
|
||||
*(argv+optind+i));
|
||||
dbuf[i] = epicsStrtod(sbuf[i], &pend);
|
||||
if (sbuf[i] == pend || enumAsString) {
|
||||
fprintf(stderr, "Enum string value '%s' invalid.\n", sbuf[i]);
|
||||
return 1;
|
||||
}
|
||||
if (dbuf[i] >= bufGrEnum.no_str) {
|
||||
fprintf(stderr, "Enum index value '%s' too large.\n",
|
||||
*(argv+optind+i));
|
||||
fprintf(stderr, "Enum index value '%s' too large.\n", sbuf[i]);
|
||||
return 1;
|
||||
}
|
||||
dbrType = DBR_DOUBLE;
|
||||
} else {
|
||||
strcpy (sbuf[i], *(argv+optind+i));
|
||||
dbrType = DBR_STRING;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -464,12 +478,12 @@ int main (int argc, char *argv[])
|
||||
if (charArrAsStr) {
|
||||
count = len;
|
||||
dbrType = DBR_CHAR;
|
||||
ebuf = calloc(strlen(cbuf), sizeof(char));
|
||||
epicsStrnRawFromEscaped(ebuf, strlen(cbuf), cbuf, strlen(cbuf));
|
||||
} else {
|
||||
for (i = 0; i < count; ++i) {
|
||||
len=strlen(*(argv+optind+i));
|
||||
if (len >= sizeof(EpicsStr)) /* Too long? Cut at max length */
|
||||
*( *(argv+optind+i)+sizeof(EpicsStr)-1 ) = 0;
|
||||
strcpy (sbuf[i], *(argv+optind+i));
|
||||
epicsStrnRawFromEscaped(sbuf[i], sizeof(EpicsStr), *(argv+optind+i), sizeof(EpicsStr));
|
||||
*( sbuf[i]+sizeof(EpicsStr)-1 ) = '\0';
|
||||
}
|
||||
dbrType = DBR_STRING;
|
||||
}
|
||||
@@ -483,7 +497,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
/* Write new data */
|
||||
if (dbrType == DBR_STRING) pbuf = sbuf;
|
||||
else if (dbrType == DBR_CHAR) pbuf = cbuf;
|
||||
else if (dbrType == DBR_CHAR) pbuf = ebuf;
|
||||
else pbuf = dbuf;
|
||||
|
||||
if (request == callback) {
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2009 Brookhaven Science Associates, as Operator of
|
||||
* Brookhaven National Laboratory.
|
||||
* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie.
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
@@ -9,11 +12,18 @@
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Author: Ralph Lange (BESSY)
|
||||
*
|
||||
* Modification History
|
||||
* 2009/03/31 Larry Hoff (BNL)
|
||||
* Added field separators
|
||||
* 2009/04/01 Ralph Lange (HZB/BESSY)
|
||||
* Added support for long strings (array of char) and quoting of nonprintable characters
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -24,6 +34,7 @@
|
||||
#include <alarm.h>
|
||||
#undef epicsAlarmGLOBAL
|
||||
#include <epicsTime.h>
|
||||
#include <epicsString.h>
|
||||
#include <cadef.h>
|
||||
|
||||
#include "tool_lib.h"
|
||||
@@ -43,6 +54,7 @@ IntFormatT outType = dec; /* For -0.. output format option */
|
||||
|
||||
char dblFormatStr[30] = "%g"; /* Format string to print doubles (-efg options) */
|
||||
char timeFormatStr[30] = "%Y-%m-%d %H:%M:%S.%06f"; /* Time format string */
|
||||
char fieldSeparator = ' '; /* OFS default is whitespace */
|
||||
|
||||
int enumAsNr = 0; /* used for -n option - get DBF_ENUM as number */
|
||||
int charArrAsStr = 0; /* used for -S option - treat char array as (long) string */
|
||||
@@ -96,7 +108,8 @@ void sprint_long (char *ret, long val)
|
||||
|
||||
char *val2str (const void *v, unsigned type, int index)
|
||||
{
|
||||
static char str[500];
|
||||
#define STR 500
|
||||
static char str[STR];
|
||||
char ch;
|
||||
void *val_ptr;
|
||||
unsigned base_type;
|
||||
@@ -115,7 +128,7 @@ char *val2str (const void *v, unsigned type, int index)
|
||||
|
||||
switch (base_type) {
|
||||
case DBR_STRING:
|
||||
sprintf(str, "%s", ((dbr_string_t*) val_ptr)[index]);
|
||||
epicsStrnEscapedFromRaw(str, STR, ((dbr_string_t*) val_ptr)[index], strlen(((dbr_string_t*) val_ptr)[index]));
|
||||
break;
|
||||
case DBR_FLOAT:
|
||||
sprintf(str, dblFormatStr, ((dbr_float_t*) val_ptr)[index]);
|
||||
@@ -125,7 +138,7 @@ char *val2str (const void *v, unsigned type, int index)
|
||||
break;
|
||||
case DBR_CHAR:
|
||||
ch = ((dbr_char_t*) val_ptr)[index];
|
||||
sprintf(str, "%d",ch);
|
||||
sprintf(str, "%d", ch);
|
||||
break;
|
||||
case DBR_INT:
|
||||
sprint_long(str, ((dbr_int_t*) val_ptr)[index]);
|
||||
@@ -134,15 +147,15 @@ char *val2str (const void *v, unsigned type, int index)
|
||||
sprint_long(str, ((dbr_long_t*) val_ptr)[index]);
|
||||
break;
|
||||
case DBR_ENUM:
|
||||
{
|
||||
dbr_enum_t *val = (dbr_enum_t *)val_ptr;
|
||||
if (dbr_type_is_GR(type) && !enumAsNr)
|
||||
sprintf(str, "%s", ((struct dbr_gr_enum *)v)->strs[val[index]]);
|
||||
else if (dbr_type_is_CTRL(type) && !enumAsNr)
|
||||
sprintf(str, "%s", ((struct dbr_ctrl_enum *)v)->strs[val[index]]);
|
||||
else
|
||||
sprintf(str, "%d", val[index]);
|
||||
}
|
||||
{
|
||||
dbr_enum_t *val = (dbr_enum_t *)val_ptr;
|
||||
if (dbr_type_is_GR(type) && !enumAsNr)
|
||||
sprintf(str, "%s", ((struct dbr_gr_enum *)v)->strs[val[index]]);
|
||||
else if (dbr_type_is_CTRL(type) && !enumAsNr)
|
||||
sprintf(str, "%s", ((struct dbr_ctrl_enum *)v)->strs[val[index]]);
|
||||
else
|
||||
sprintf(str, "%d", val[index]);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
@@ -393,19 +406,19 @@ char *dbr2str (const void *value, unsigned type)
|
||||
if (printAbs) { \
|
||||
if (tsSrcServer) { \
|
||||
epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, ptsNewS); \
|
||||
printf("%s ", timeText); \
|
||||
printf("%s", timeText); \
|
||||
} \
|
||||
if (tsSrcClient) { \
|
||||
epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, ptsNewC); \
|
||||
printf("(%s) ", timeText); \
|
||||
printf("(%s)", timeText); \
|
||||
} \
|
||||
pv->firstStampPrinted = 1; \
|
||||
} else { \
|
||||
if (tsSrcServer) { \
|
||||
printf(" %+12.6f ", epicsTimeDiffInSeconds(ptsNewS, ptsRefS) ); \
|
||||
printf(" %+12.6f", epicsTimeDiffInSeconds(ptsNewS, ptsRefS) ); \
|
||||
} \
|
||||
if (tsSrcClient) { \
|
||||
printf(" (%+12.6f) ", epicsTimeDiffInSeconds(ptsNewC, ptsRefC) ); \
|
||||
printf(" (%+12.6f)", epicsTimeDiffInSeconds(ptsNewC, ptsRefC) ); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
@@ -418,18 +431,25 @@ char *dbr2str (const void *value, unsigned type)
|
||||
tsPreviousS = *ptsNewS; \
|
||||
\
|
||||
if (charArrAsStr && dbr_type_is_CHAR(TYPE_ENUM) && (reqElems || pv->nElems > 1)) { \
|
||||
printf("%s ", (dbr_char_t*) dbr_value_ptr(value, pv->dbrType)); \
|
||||
dbr_char_t *s = (dbr_char_t*) dbr_value_ptr(pv->value, pv->dbrType); \
|
||||
int dlen = epicsStrnEscapedFromRawSize((char*)s, strlen((char*)s)); \
|
||||
char *d = calloc(dlen+1, sizeof(char)); \
|
||||
epicsStrnEscapedFromRaw(d, dlen+1, (char*)s, strlen((char*)s)); \
|
||||
printf("%c%s", fieldSeparator, d); \
|
||||
free(d); \
|
||||
} else { \
|
||||
if (reqElems || pv->nElems > 1) printf("%lu ", pv->reqElems); \
|
||||
if (reqElems || pv->nElems > 1) printf("%c%lu", fieldSeparator, pv->reqElems); \
|
||||
for (i=0; i<pv->reqElems; ++i) { \
|
||||
printf("%s ", val2str(value, TYPE_ENUM, i)); \
|
||||
printf("%c%s", fieldSeparator, val2str(value, TYPE_ENUM, i)); \
|
||||
} \
|
||||
} \
|
||||
/* Print Status, Severity - if not NO_ALARM */ \
|
||||
if ( ((struct TYPE *)value)->status || ((struct TYPE *)value)->severity ) \
|
||||
{ \
|
||||
printf("%s %s\n", \
|
||||
printf("%c%s%c%s\n", \
|
||||
fieldSeparator, \
|
||||
stat_to_str(((struct TYPE *)value)->status), \
|
||||
fieldSeparator, \
|
||||
sevr_to_str(((struct TYPE *)value)->severity)); \
|
||||
} else { \
|
||||
printf("\n"); \
|
||||
@@ -454,7 +474,9 @@ void print_time_val_sts (pv* pv, unsigned long reqElems)
|
||||
tsInitS = 1;
|
||||
}
|
||||
|
||||
printf("%-30s ", pv->name);
|
||||
if (pv->reqElems <= 1 && fieldSeparator == ' ') printf("%-30s", pv->name);
|
||||
else printf("%s", pv->name);
|
||||
printf("%c", fieldSeparator);
|
||||
if (!pv->onceConnected)
|
||||
printf("*** Not connected (PV not found)\n");
|
||||
else if (pv->status == ECA_DISCONN)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2009 Brookhaven Science Associates, as Operator of
|
||||
* Brookhaven National Laboratory.
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
@@ -9,11 +11,16 @@
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Author: Ralph Lange (BESSY)
|
||||
*
|
||||
* Modification History
|
||||
* 2009/03/31 Larry Hoff (BNL)
|
||||
* Added field separators
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef INCLtool_libh
|
||||
@@ -80,6 +87,7 @@ extern int enumAsNr; /* Used for -n option (get DBF_ENUM as number) */
|
||||
extern int charArrAsStr; /* used for -S option - treat char array as (long) string */
|
||||
extern double caTimeout; /* Wait time default (see -w option) */
|
||||
extern char dblFormatStr[]; /* Format string to print doubles (see -e -f option) */
|
||||
extern char fieldSeparator; /* Output field separator */
|
||||
extern capri caPriority; /* CA priority */
|
||||
|
||||
extern char *val2str (const void *v, unsigned type, int index);
|
||||
|
||||
Reference in New Issue
Block a user