enum_t/time_t print in terse mode
This commit is contained in:
@ -157,29 +157,7 @@ void formatNTEnum(std::ostream& o, PVStructurePtr const & pvStruct)
|
||||
return;
|
||||
}
|
||||
|
||||
PVIntPtr index = dynamic_pointer_cast<PVInt>(enumt->getSubField("index"));
|
||||
if (index.get() == 0)
|
||||
{
|
||||
std::cerr << "no int 'value.index' field in NTEnum" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
PVStringArrayPtr choices = dynamic_pointer_cast<PVStringArray>(enumt->getSubField("choices"));
|
||||
if (choices.get() == 0)
|
||||
{
|
||||
std::cerr << "no string[] 'value.choices' field in NTEnum" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
int32 ix = index->get();
|
||||
if (ix < 0 || ix > static_cast<int32>(choices->getLength()))
|
||||
{
|
||||
o << ix;
|
||||
}
|
||||
else
|
||||
{
|
||||
choices->dumpValue(o, ix);
|
||||
}
|
||||
printEnumT(o, enumt);
|
||||
}
|
||||
|
||||
size_t getLongestString(shared_vector<const string> const & array)
|
||||
@ -1045,7 +1023,7 @@ void usage (void)
|
||||
" -r <pv request>: Get request string, specifies what fields to return and options, default is '%s'\n"
|
||||
" -w <sec>: Wait time, specifies timeout, default is %f second(s)\n"
|
||||
" -z: Pure pvAccess RPC based service (send NTURI.query as request argument)\n"
|
||||
" -n: Do not format NT types, dump structure instead\n"
|
||||
" -N: Do not format NT types, dump structure instead\n"
|
||||
" -t: Terse mode\n"
|
||||
" -T: Transpose vector, table, matrix\n"
|
||||
" -m: Monitor mode\n"
|
||||
@ -1056,6 +1034,8 @@ void usage (void)
|
||||
" -F <ofs>: Use <ofs> as an alternate output field separator\n"
|
||||
" -f <input file>: Use <input file> as an input that provides a list PV name(s) to be read, use '-' for stdin\n"
|
||||
" -c: Wait for clean shutdown and report used instance count (for expert users)"
|
||||
" enum format:\n"
|
||||
" -n: Force enum interpretation of values as numbers (default is enum string)\n"
|
||||
"\n\nexamples:\n\n"
|
||||
"#! Get the value of the PV corr:li32:53:bdes\n"
|
||||
"> eget corr:li32:53:bdes\n"
|
||||
@ -1472,7 +1452,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */
|
||||
|
||||
while ((opt = getopt(argc, argv, ":hr:s:a:w:zntTmxp:qdcF:f:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, ":hr:s:a:w:zNtTmxp:qdcF:f:n")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h': /* Print usage */
|
||||
usage();
|
||||
@ -1539,7 +1519,7 @@ int main (int argc, char *argv[])
|
||||
case 'z': /* pvAccess RPC mode */
|
||||
onlyQuery = true;
|
||||
break;
|
||||
case 'n': /* Do not format NT types */
|
||||
case 'N': /* Do not format NT types */
|
||||
dumpStructure = true;
|
||||
break;
|
||||
case 't': /* Terse mode */
|
||||
@ -1601,6 +1581,9 @@ int main (int argc, char *argv[])
|
||||
fromStream = true;
|
||||
break;
|
||||
}
|
||||
case 'n':
|
||||
setEnumPrintMode(NumberEnum);
|
||||
break;
|
||||
case '?':
|
||||
fprintf(stderr,
|
||||
"Unrecognized option: '-%c'. ('eget -h' for help.)\n",
|
||||
|
@ -57,6 +57,8 @@ void usage (void)
|
||||
" -F <ofs>: Use <ofs> as an alternate output field separator\n"
|
||||
" -f <input file>: Use <input file> as an input that provides a list PV name(s) to be read, use '-' for stdin\n"
|
||||
" -c: Wait for clean shutdown and report used instance count (for expert users)\n"
|
||||
" enum format:\n"
|
||||
" -n: Force enum interpretation of values as numbers (default is enum string)\n"
|
||||
"\nexample: pvget double01\n\n"
|
||||
, DEFAULT_REQUEST, DEFAULT_TIMEOUT);
|
||||
}
|
||||
@ -95,7 +97,12 @@ void printValue(std::string const & channelName, PVStructure::shared_pointer con
|
||||
else if (mode == TerseMode)
|
||||
terseStructure(std::cout, pv) << std::endl;
|
||||
else
|
||||
{
|
||||
std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl;
|
||||
|
||||
//pvutil_ostream myos(std::cout.rdbuf());
|
||||
//myos << channelName << std::endl << *(pv.get()) << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -339,7 +346,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */
|
||||
|
||||
while ((opt = getopt(argc, argv, ":hr:w:tmqdcF:f:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, ":hr:w:tmqdcF:f:n")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h': /* Print usage */
|
||||
usage();
|
||||
@ -397,6 +404,9 @@ int main (int argc, char *argv[])
|
||||
fromStream = true;
|
||||
break;
|
||||
}
|
||||
case 'n':
|
||||
setEnumPrintMode(NumberEnum);
|
||||
break;
|
||||
case '?':
|
||||
fprintf(stderr,
|
||||
"Unrecognized option: '-%c'. ('pvget -h' for help.)\n",
|
||||
|
@ -604,7 +604,7 @@ int main (int argc, char *argv[])
|
||||
if (quiet)
|
||||
cmd += 'q';
|
||||
if (printInfo)
|
||||
cmd += 'n';
|
||||
cmd += 'N';
|
||||
cmd += "s pva://" + serverAddress + "/server?op=";
|
||||
if (printInfo)
|
||||
cmd += "info";
|
||||
|
@ -28,8 +28,9 @@ using namespace std::tr1;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
|
||||
enum EnumMode { AutoEnum, NumberEnum, StringEnum };
|
||||
EnumMode enumMode = AutoEnum;
|
||||
//EnumMode enumMode = AutoEnum;
|
||||
|
||||
size_t fromString(PVFieldPtr const & pv, StringArray const & from, size_t fromStartIndex);
|
||||
|
||||
size_t fromString(PVScalarArrayPtr const &pv, StringArray const & from, size_t fromStartIndex = 0)
|
||||
{
|
||||
@ -114,64 +115,12 @@ size_t fromString(PVUnionPtr const & pvUnion, StringArray const & from, size_t f
|
||||
throw std::runtime_error("not enough of values");
|
||||
|
||||
string selector = from[fromStartIndex++];
|
||||
PVFieldPtr fieldField = pvUnion->select(selector);
|
||||
if (!fieldField)
|
||||
PVFieldPtr pv = pvUnion->select(selector);
|
||||
if (!pv)
|
||||
throw std::runtime_error("invalid union selector value '" + selector + "'");
|
||||
|
||||
size_t processed = 1;
|
||||
|
||||
try
|
||||
{
|
||||
Type type = fieldField->getField()->getType();
|
||||
if(type==structure) {
|
||||
PVStructurePtr pv = static_pointer_cast<PVStructure>(fieldField);
|
||||
size_t count = fromString(pv, from, fromStartIndex);
|
||||
processed += count;
|
||||
}
|
||||
else if(type==scalarArray) {
|
||||
PVScalarArrayPtr pv = static_pointer_cast<PVScalarArray>(fieldField);
|
||||
size_t count = fromString(pv, from, fromStartIndex);
|
||||
processed += count;
|
||||
}
|
||||
else if(type==scalar) {
|
||||
|
||||
if (fromStartIndex >= fromValueCount)
|
||||
throw std::runtime_error("not enough of values");
|
||||
|
||||
PVScalarPtr pv = static_pointer_cast<PVScalar>(fieldField);
|
||||
getConvert()->fromString(pv, from[fromStartIndex]);
|
||||
processed++;
|
||||
}
|
||||
else if(type==structureArray) {
|
||||
PVStructureArrayPtr pv = static_pointer_cast<PVStructureArray>(fieldField);
|
||||
size_t count = fromString(pv, from, fromStartIndex);
|
||||
processed += count;
|
||||
}
|
||||
else if(type==union_) {
|
||||
PVUnionPtr pv = static_pointer_cast<PVUnion>(fieldField);
|
||||
size_t count = fromString(pv, from, fromStartIndex);
|
||||
processed += count;
|
||||
}
|
||||
else if(type==unionArray) {
|
||||
PVUnionArrayPtr pv = static_pointer_cast<PVUnionArray>(fieldField);
|
||||
size_t count = fromString(pv, from, fromStartIndex);
|
||||
processed += count;
|
||||
}
|
||||
else {
|
||||
std::ostringstream oss;
|
||||
oss << "fromString unsupported fieldType " << type;
|
||||
throw std::logic_error(oss.str());
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "failed to parse '" << fieldField->getField()->getID() << ' ' << fieldField->getFieldName() << "'";
|
||||
os << ": " << ex.what();
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
|
||||
return processed;
|
||||
size_t processed = fromString(pv, from, fromStartIndex);
|
||||
return processed + 1;
|
||||
}
|
||||
|
||||
size_t fromString(PVUnionArrayPtr const &pv, StringArray const & from, size_t fromStartIndex = 0)
|
||||
@ -251,76 +200,68 @@ size_t fromString(PVStructurePtr const & pvStructure, StringArray const & from,
|
||||
}
|
||||
|
||||
size_t processed = 0;
|
||||
size_t fromValueCount = from.size();
|
||||
|
||||
PVFieldPtrArray const & fieldsData = pvStructure->getPVFields();
|
||||
if (fieldsData.size() != 0) {
|
||||
size_t length = pvStructure->getStructure()->getNumberFields();
|
||||
for(size_t i = 0; i < length; i++) {
|
||||
PVFieldPtr fieldField = fieldsData[i];
|
||||
|
||||
try
|
||||
{
|
||||
Type type = fieldField->getField()->getType();
|
||||
if(type==structure) {
|
||||
PVStructurePtr pv = static_pointer_cast<PVStructure>(fieldField);
|
||||
size_t count = fromString(pv, from, fromStartIndex);
|
||||
processed += count;
|
||||
fromStartIndex += count;
|
||||
}
|
||||
else if(type==scalarArray) {
|
||||
PVScalarArrayPtr pv = static_pointer_cast<PVScalarArray>(fieldField);
|
||||
size_t count = fromString(pv, from, fromStartIndex);
|
||||
processed += count;
|
||||
fromStartIndex += count;
|
||||
}
|
||||
else if(type==scalar) {
|
||||
|
||||
if (fromStartIndex >= fromValueCount)
|
||||
throw std::runtime_error("not enough of values");
|
||||
|
||||
PVScalarPtr pv = static_pointer_cast<PVScalar>(fieldField);
|
||||
getConvert()->fromString(pv, from[fromStartIndex]);
|
||||
processed++;
|
||||
fromStartIndex++;
|
||||
}
|
||||
else if(type==structureArray) {
|
||||
PVStructureArrayPtr pv = static_pointer_cast<PVStructureArray>(fieldField);
|
||||
size_t count = fromString(pv, from, fromStartIndex);
|
||||
processed += count;
|
||||
fromStartIndex += count;
|
||||
}
|
||||
else if(type==union_) {
|
||||
PVUnionPtr pv = static_pointer_cast<PVUnion>(fieldField);
|
||||
size_t count = fromString(pv, from, fromStartIndex);
|
||||
processed += count;
|
||||
fromStartIndex += count;
|
||||
}
|
||||
else if(type==unionArray) {
|
||||
PVUnionArrayPtr pv = static_pointer_cast<PVUnionArray>(fieldField);
|
||||
size_t count = fromString(pv, from, fromStartIndex);
|
||||
processed += count;
|
||||
fromStartIndex += count;
|
||||
}
|
||||
else {
|
||||
std::ostringstream oss;
|
||||
oss << "fromString unsupported fieldType " << type;
|
||||
throw std::logic_error(oss.str());
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "failed to parse '" << fieldField->getField()->getID() << ' ' << fieldField->getFieldName() << "'";
|
||||
os << ": " << ex.what();
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
size_t count = fromString(fieldsData[i], from, fromStartIndex);
|
||||
processed += count;
|
||||
fromStartIndex += count;
|
||||
}
|
||||
}
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
size_t fromString(PVFieldPtr const & fieldField, StringArray const & from, size_t fromStartIndex)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (fieldField->getField()->getType())
|
||||
{
|
||||
case scalar:
|
||||
{
|
||||
if (fromStartIndex >= from.size())
|
||||
throw std::runtime_error("not enough of values");
|
||||
|
||||
PVScalarPtr pv = static_pointer_cast<PVScalar>(fieldField);
|
||||
getConvert()->fromString(pv, from[fromStartIndex]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case scalarArray:
|
||||
return fromString(static_pointer_cast<PVScalarArray>(fieldField), from, fromStartIndex);
|
||||
|
||||
case structure:
|
||||
return fromString(static_pointer_cast<PVStructure>(fieldField), from, fromStartIndex);
|
||||
|
||||
case structureArray:
|
||||
return fromString(static_pointer_cast<PVStructureArray>(fieldField), from, fromStartIndex);
|
||||
|
||||
case union_:
|
||||
return fromString(static_pointer_cast<PVUnion>(fieldField), from, fromStartIndex);
|
||||
|
||||
case unionArray:
|
||||
return fromString(static_pointer_cast<PVUnionArray>(fieldField), from, fromStartIndex);
|
||||
|
||||
default:
|
||||
std::ostringstream oss;
|
||||
oss << "fromString unsupported fieldType " << fieldField->getField()->getType();
|
||||
throw std::logic_error(oss.str());
|
||||
}
|
||||
}
|
||||
catch (std::exception &ex)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "failed to parse '" << fieldField->getField()->getID() << ' '
|
||||
<< fieldField->getFieldName() << "'";
|
||||
os << ": " << ex.what();
|
||||
throw std::runtime_error(os.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define DEFAULT_TIMEOUT 3.0
|
||||
#define DEFAULT_REQUEST "field(value)"
|
||||
|
||||
@ -368,6 +309,27 @@ void printValue(std::string const & channelName, PVStructure::shared_pointer con
|
||||
Type valueType = value->getField()->getType();
|
||||
if (valueType != scalar && valueType != scalarArray)
|
||||
{
|
||||
// special case for enum
|
||||
if (valueType == structure)
|
||||
{
|
||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(value);
|
||||
if (pvStructure->getStructure()->getID() == "enum_t")
|
||||
{
|
||||
if (fieldSeparator == ' ')
|
||||
std::cout << std::setw(30) << std::left << channelName;
|
||||
else
|
||||
std::cout << channelName;
|
||||
|
||||
std::cout << fieldSeparator;
|
||||
|
||||
printEnumT(std::cout, pvStructure);
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// switch to structure mode
|
||||
std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl;
|
||||
}
|
||||
@ -705,6 +667,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
std::cout << std::boolalpha;
|
||||
terseSeparator(fieldSeparator);
|
||||
setEnumPrintMode(enumMode);
|
||||
|
||||
ClientFactory::start();
|
||||
ChannelProvider::shared_pointer provider = getChannelProviderRegistry()->getProvider("pva");
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include <pv/logger.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace std::tr1;
|
||||
@ -68,6 +69,18 @@ void terseArrayCount(bool flag)
|
||||
arrayCountFlag = flag;
|
||||
}
|
||||
|
||||
EnumMode enumMode = AutoEnum;
|
||||
void setEnumPrintMode(EnumMode mode)
|
||||
{
|
||||
enumMode = mode;
|
||||
}
|
||||
|
||||
bool formatTTypesFlag = true;
|
||||
void formatTTypes(bool flag)
|
||||
{
|
||||
formatTTypesFlag = flag;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& terse(std::ostream& o, PVField::shared_pointer const & pv)
|
||||
{
|
||||
@ -99,6 +112,54 @@ std::ostream& terse(std::ostream& o, PVField::shared_pointer const & pv)
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& printEnumT(std::ostream& o, epics::pvData::PVStructure::shared_pointer const & pvEnumT)
|
||||
{
|
||||
PVInt::shared_pointer pvIndex = pvEnumT->getSubField<PVInt>("index");
|
||||
if (!pvIndex)
|
||||
throw std::runtime_error("enum_t structure does not have 'int index' field");
|
||||
|
||||
PVStringArray::shared_pointer pvChoices = pvEnumT->getSubField<PVStringArray>("choices");
|
||||
if (!pvChoices)
|
||||
throw std::runtime_error("enum_t structure does not have 'string choices[]' field");
|
||||
|
||||
if (enumMode == AutoEnum || enumMode == StringEnum)
|
||||
{
|
||||
int32 ix = pvIndex->get();
|
||||
if (ix < 0 || ix > static_cast<int32>(pvChoices->getLength()))
|
||||
o << ix;
|
||||
else
|
||||
pvChoices->dumpValue(o, ix);
|
||||
}
|
||||
else
|
||||
o << pvIndex->get();
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
std::ostream& printTimeT(std::ostream& o, epics::pvData::PVStructure::shared_pointer const & pvTimeT)
|
||||
{
|
||||
#define TIMETEXTLEN 32
|
||||
char timeText[TIMETEXTLEN];
|
||||
epicsTimeStamp epicsTS;
|
||||
|
||||
PVTimeStamp pvTimeStamp;
|
||||
if (pvTimeStamp.attach(pvTimeT))
|
||||
{
|
||||
TimeStamp ts;
|
||||
pvTimeStamp.get(ts);
|
||||
|
||||
epicsTS.secPastEpoch = ts.getEpicsSecondsPastEpoch();
|
||||
epicsTS.nsec = ts.getNanoseconds();
|
||||
}
|
||||
else
|
||||
throw std::runtime_error("invalid time_t structure");
|
||||
|
||||
epicsTimeToStrftime(timeText, TIMETEXTLEN, "%Y-%m-%dT%H:%M:%S.%03f", &epicsTS);
|
||||
o << timeText;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
std::ostream& terseStructure(std::ostream& o, PVStructure::shared_pointer const & pvStructure)
|
||||
{
|
||||
if (!pvStructure)
|
||||
@ -107,6 +168,22 @@ std::ostream& terseStructure(std::ostream& o, PVStructure::shared_pointer const
|
||||
return o;
|
||||
}
|
||||
|
||||
// special t-types support (enum_t and time_t, etc.)
|
||||
if (formatTTypesFlag)
|
||||
{
|
||||
string id = pvStructure->getStructure()->getID();
|
||||
if (id == "enum_t")
|
||||
{
|
||||
printEnumT(o, pvStructure);
|
||||
return o;
|
||||
}
|
||||
else if (id == "time_t")
|
||||
{
|
||||
printTimeT(o, pvStructure);
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
PVFieldPtrArray fieldsData = pvStructure->getPVFields();
|
||||
size_t length = pvStructure->getStructure()->getNumberFields();
|
||||
bool first = true;
|
||||
|
@ -16,6 +16,13 @@ std::ostream& terseScalarArray(std::ostream& o, epics::pvData::PVScalarArray::sh
|
||||
std::ostream& terseStructureArray(std::ostream& o, epics::pvData::PVStructureArray::shared_pointer const & pvArray);
|
||||
std::ostream& terseUnionArray(std::ostream& o, epics::pvData::PVUnionArray::shared_pointer const & pvArray);
|
||||
|
||||
enum EnumMode { AutoEnum, NumberEnum, StringEnum };
|
||||
void setEnumPrintMode(EnumMode mode);
|
||||
|
||||
void formatTTypes(bool flag);
|
||||
|
||||
std::ostream& printEnumT(std::ostream& o, epics::pvData::PVStructure::shared_pointer const & pvEnumT);
|
||||
std::ostream& printTimeT(std::ostream& o, epics::pvData::PVStructure::shared_pointer const & pvTimeT);
|
||||
|
||||
/* Converts a hex character to its integer value */
|
||||
char from_hex(char ch);
|
||||
@ -103,3 +110,69 @@ struct dump_stack_only_on_debug
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const dump_stack_only_on_debug& d);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
#include <ostream>
|
||||
#include <iostream>
|
||||
|
||||
// usage: pvutil_ostream myos(std::cout.rdbuf());
|
||||
|
||||
class pvutil_ostream : private std::ostream
|
||||
{
|
||||
public:
|
||||
pvutil_ostream(std::streambuf* sb)
|
||||
: std::ostream(sb)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
friend pvutil_ostream& operator<<(pvutil_ostream&, const T&);
|
||||
|
||||
// Additional overload to handle ostream specific io manipulators
|
||||
friend pvutil_ostream& operator<<(pvutil_ostream&, std::ostream& (*)(std::ostream&));
|
||||
|
||||
// Accessor function to get a reference to the ostream
|
||||
std::ostream& get_ostream() { return *this; }
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline pvutil_ostream&
|
||||
operator<<(pvutil_ostream& out, const T& value)
|
||||
{
|
||||
static_cast<std::ostream&>(out) << '.';
|
||||
static_cast<std::ostream&>(out) << value;
|
||||
return out;
|
||||
}
|
||||
|
||||
// overload for std::ostream specific io manipulators
|
||||
inline pvutil_ostream&
|
||||
operator<<(pvutil_ostream& out, std::ostream& (*func)(std::ostream&))
|
||||
{
|
||||
static_cast<std::ostream&>(out) << '#';
|
||||
static_cast<std::ostream&>(out) << func;
|
||||
return out;
|
||||
}
|
||||
|
||||
// overload for PVField
|
||||
template <>
|
||||
inline pvutil_ostream&
|
||||
operator<<(pvutil_ostream& out, const epics::pvData::PVField& value)
|
||||
{
|
||||
static_cast<std::ostream&>(out) << '?';
|
||||
// static_cast<std::ostream&>(out) << value;
|
||||
value.dumpValue(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline pvutil_ostream&
|
||||
operator<<(pvutil_ostream& out, const epics::pvData::PVStructure& value)
|
||||
{
|
||||
static_cast<std::ostream&>(out) << '!';
|
||||
// static_cast<std::ostream&>(out) << value;
|
||||
value.dumpValue(out);
|
||||
return out;
|
||||
}
|
||||
*/
|
||||
|
Reference in New Issue
Block a user