diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 9877a2db9..fc15ddd2c 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -12,9 +12,35 @@
Changes between 3.14.10 and 3.14.11
+Channel Access command line tool changes
+
+The caget/caput/camonitor programs in src/catools now use '\' escape
+sequences for non-printable characters.
+
+They provide a new option -F to set an output field separator
+to be used instead of the default space character.
+
+New functions for escaping non-printables in epicsString.h
+
+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:
+
+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);
+
+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.
+
+The existing function interfaces will be kept for compatibility, but their
+further use is deprecated.
+
epicsRingBytes
-Partial puts are not supported. An attempt to put more bytes than currently free will be rejected.
+Partial puts are not supported.
+An attempt to put more bytes than currently free will be rejected.
Long string support
diff --git a/src/catools/caget.c b/src/catools/caget.c
index 789de7321..82c9301c1 100644
--- a/src/catools/caget.c
+++ b/src/catools/caget.c
@@ -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
-#include
#include
+#include
+#include
#include
#include
@@ -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] ...\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 : Use 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 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 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 */
diff --git a/src/catools/camonitor.c b/src/catools/camonitor.c
index 4cefc3459..24f00e138 100644
--- a/src/catools/camonitor.c
+++ b/src/catools/camonitor.c
@@ -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 : Use 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 :
diff --git a/src/catools/caput.c b/src/catools/caput.c
index a1fde247f..825ba860d 100644
--- a/src/catools/caput.c
+++ b/src/catools/caput.c
@@ -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
#include
#include
+#include
#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 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) {
diff --git a/src/catools/tool_lib.c b/src/catools/tool_lib.c
index d2c314228..4b327de64 100644
--- a/src/catools/tool_lib.c
+++ b/src/catools/tool_lib.c
@@ -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
@@ -24,6 +34,7 @@
#include
#undef epicsAlarmGLOBAL
#include
+#include
#include
#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; ireqElems; ++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)
diff --git a/src/catools/tool_lib.h b/src/catools/tool_lib.h
index a4c98f802..b53e66111 100644
--- a/src/catools/tool_lib.h
+++ b/src/catools/tool_lib.h
@@ -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);