diff --git a/testApp/remote/eget.cpp b/testApp/remote/eget.cpp index 7190fdf..713b7aa 100644 --- a/testApp/remote/eget.cpp +++ b/testApp/remote/eget.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -35,6 +36,8 @@ char fieldSeparator = ' '; bool columnMajor = false; +bool transpose = false; + void formatNTAny(std::ostream& o, PVStructurePtr const & pvStruct) { PVFieldPtr value = pvStruct->getSubField("value"); @@ -125,7 +128,7 @@ void formatNTScalarArray(std::ostream& o, PVStructurePtr const & pvStruct) //o << *value; //formatScalarArray(o, value); - formatVector(o, "", value, mode == TerseMode); + formatVector(o, "", value, mode == TerseMode || transpose); } void formatNTEnum(std::ostream& o, PVStructurePtr const & pvStruct) @@ -197,14 +200,14 @@ size_t getLongestString(PVScalarArrayPtr const & array) void formatTable(std::ostream& o, vector const & labels, vector const & columnData, - bool transpose) + bool showHeader, bool transpose) { // array with maximum number of elements size_t maxValues = 0; // value with longest string form - size_t maxColumnLength = labels.size() ? getLongestString(labels) : 0; - + size_t maxLabelColumnLength = (showHeader && labels.size()) ? getLongestString(labels) : 0; + size_t maxColumnLength = 0; // // get maxValue and maxColumnLength // @@ -228,6 +231,13 @@ void formatTable(std::ostream& o, if (!transpose) { + /* non-compact + maxLabelColumnLength += padding; + + // increase maxColumnLength to maxLabelColumnLength + if (maxLabelColumnLength > maxColumnLength) + maxColumnLength = maxLabelColumnLength; + */ // // , , ... @@ -235,11 +245,13 @@ void formatTable(std::ostream& o, // // first print labels - if (labels.size()) + if (showHeader && labels.size()) { for (size_t i = 0; i < numColumns; i++) { - o << std::setw(maxColumnLength) << std::right << labels[i]; + int width = std::max(labels[i].size()+padding, maxColumnLength); + o << std::setw(width) << std::right << labels[i]; + // non-compact o << std::setw(maxColumnLength) << std::right << labels[i]; } o << std::endl; } @@ -249,7 +261,9 @@ void formatTable(std::ostream& o, { for (size_t i = 0; i < numColumns; i++) { - o << std::setw(maxColumnLength) << std::right; + int width = std::max(labels[i].size()+padding, maxColumnLength); + o << setw(width) << std::right; + // non-compact o << std::setw(maxColumnLength) << std::right; PVScalarArrayPtr array = columnData[i]; if (array.get() && r < array->getLength()) array->dumpValue(o, r); @@ -271,8 +285,8 @@ void formatTable(std::ostream& o, for (size_t i = 0; i < numColumns; i++) { - if (labels.size()) - o << std::setw(maxColumnLength) << std::left << labels[i]; + if (showHeader && labels.size()) + o << std::setw(maxLabelColumnLength) << std::left << labels[i]; for (size_t r = 0; r < maxValues; r++) { @@ -331,7 +345,8 @@ void formatNTTable(std::ostream& o, PVStructurePtr const & pvStruct) StringArrayData labelsData; labels->get(0, numColumns, labelsData); - formatTable(o, labelsData.data, columnData, mode == TerseMode); + bool showHeader = (mode != TerseMode); + formatTable(o, labelsData.data, columnData, showHeader, transpose); } @@ -388,8 +403,7 @@ void formatNTMatrix(std::ostream& o, PVStructurePtr const & pvStruct) size_t padding = 2; size_t maxColumnLength = getLongestString(value) + padding; - // TerseMode as Transpose - if (mode != TerseMode) + if (!transpose) { // @@ -471,19 +485,25 @@ void formatNTNameValue(std::ostream& o, PVStructurePtr const & pvStruct) StringArrayData nameData; name->get(0, name->getLength(), nameData); - // get max column size - size_t maxColumnLength = getLongestString(nameData.data); + // get max column name size + bool showHeader = (mode != TerseMode); + size_t maxLabelColumnLength = showHeader ? getLongestString(nameData.data) : 0; - size_t valueLen = getLongestString(array); - if (valueLen > maxColumnLength) maxColumnLength = valueLen; + size_t maxColumnLength = getLongestString(array); // add some space size_t padding = 2; maxColumnLength += padding; - bool transpose = (mode == TerseMode); if (transpose) { + /* non-compact + maxLabelColumnLength += padding; + + // increase maxColumnLength to maxLabelColumnLength + if (maxLabelColumnLength > maxColumnLength) + maxColumnLength = maxLabelColumnLength; + */ // // , , ... @@ -491,16 +511,23 @@ void formatNTNameValue(std::ostream& o, PVStructurePtr const & pvStruct) // // first print names - for (size_t i = 0; i < numColumns; i++) + if (showHeader) { - o << std::setw(maxColumnLength) << std::right << nameData.data[i]; + for (size_t i = 0; i < numColumns; i++) + { + int width = std::max(nameData.data[i].size()+padding, maxColumnLength); + o << std::setw(width) << std::right << nameData.data[i]; + // non-compact o << std::setw(maxColumnLength) << std::right << nameData.data[i]; + } + o << std::endl; } - o << std::endl; // then values for (size_t i = 0; i < numColumns; i++) { - o << std::setw(maxColumnLength) << std::right; + int width = std::max(nameData.data[i].size()+padding, maxColumnLength); + o << std::setw(width) << std::right; + // non-compact o << std::setw(maxColumnLength) << std::right; array->dumpValue(o, i); } o << std::endl; @@ -516,7 +543,8 @@ void formatNTNameValue(std::ostream& o, PVStructurePtr const & pvStruct) for (size_t i = 0; i < numColumns; i++) { - o << std::setw(maxColumnLength) << std::left << nameData.data[i]; + if (showHeader) + o << std::setw(maxLabelColumnLength) << std::left << nameData.data[i]; o << std::setw(maxColumnLength) << std::right; array->dumpValue(o, i); o << std::endl; @@ -760,17 +788,28 @@ void formatNT(std::ostream& o, PVFieldPtr const & pv) o << *(pv.get()) << std::endl; } - - -void printValue(String const & channelName, PVStructure::shared_pointer const & pv) +void dumpValue(String const & channelName, PVField::shared_pointer const & pv) { - if (mode == ValueOnlyMode) + if (!channelName.empty()) + std::cout << channelName << std::endl; + std::cout << *(pv.get()) << std::endl << std::endl; +} + +void printValue(String const & channelName, PVStructure::shared_pointer const & pv, bool forceTerseWithName = false) +{ + if (forceTerseWithName) + { + if (!channelName.empty()) + std::cout << channelName << separator; + terseStructure(std::cout, pv) << std::endl; + } + else if (mode == ValueOnlyMode) { PVField::shared_pointer value = pv->getSubField("value"); if (value.get() == 0) { std::cerr << "no 'value' field" << std::endl; - std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; + dumpValue(channelName, pv); } else { @@ -791,17 +830,20 @@ void printValue(String const & channelName, PVStructure::shared_pointer const & std::cout << std::endl; } else - std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; + dumpValue(channelName, pv); } } } else if (mode == TerseMode) terseStructure(std::cout, pv) << std::endl; else - std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; + dumpValue(channelName, pv); } +static String emptyString; + // only in ValueOnlyMode +// NOTE: names might be empty void printValues(vector const & names, vector const & values) { size_t len = values.size(); @@ -819,11 +861,24 @@ void printValues(vector const & names, vector(value)); else if (type == scalar) { - scalars.push_back(dynamic_pointer_cast(value)); + PVScalar::shared_pointer scalar = dynamic_pointer_cast(value); + scalars.push_back(scalar); - // TODO also try to make an PVStringArray out of a scalar + // make an array, i.e. PVStringArray, out of a scalar (since scalar is an array w/ element count == 1) + PVStringArray::shared_pointer stringArray = + dynamic_pointer_cast(getPVDataCreate()->createPVScalarArray(pvString)); + StringArray values; + values.reserve(1); + values.push_back(getConvert()->toString(scalar)); + stringArray->put(0, values.size(), values, 0); + scalarArrays.push_back(stringArray); } } + else + { + // a structure detected, break + break; + } } if (scalars.size() == len) @@ -841,14 +896,15 @@ void printValues(vector const & names, vector: Service argument in form 'name[=value]'\n" " -r : Get request string, specifies what fields to return and options, default is '%s'\n" " -w : Wait time, specifies timeout, default is %f second(s)\n" - " -q: Pure pvAccess RPC based service (send NTURI.query as request argument)\n" + " -z: Pure pvAccess RPC based service (send NTURI.query as request argument)\n" " -n: Do not format NT types, dump structure instead.\n" - " -t: Terse mode / transpose vector, table, matrix.\n" + " -t: Terse mode.\n" + " -T: Transpose vector, table, matrix.\n" " -x: Use column-major order to decode matrix.\n" + " -q: Quiet mode, print only error messages\n" " -d: Enable debug output\n" " -F : Use as an alternate output field separator\n" " -c: Wait for clean shutdown and report used instance count (for expert users)" @@ -1177,10 +1235,11 @@ int main (int argc, char *argv[]) string service; //string urlEncodedRequest; vector< pair > parameters; + bool quiet = false; setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */ - while ((opt = getopt(argc, argv, ":hr:s:a:w:qntxdcF:")) != -1) { + while ((opt = getopt(argc, argv, ":hr:s:a:w:zntTxqdcF:")) != -1) { switch (opt) { case 'h': /* Print usage */ usage(); @@ -1225,7 +1284,7 @@ int main (int argc, char *argv[]) service = optarg; serviceRequest = true; break; - case 'q': /* pvAccess RPC mode */ + case 'z': /* pvAccess RPC mode */ onlyQuery = true; break; case 'n': /* Do not format NT types */ @@ -1234,9 +1293,15 @@ int main (int argc, char *argv[]) case 't': /* Terse mode */ mode = TerseMode; break; + case 'T': /* Terse mode */ + transpose = true; + break; case 'x': /* Column-major order mode */ columnMajor = true; break; + case 'q': /* Quiet mode */ + quiet = true; + break; case 'd': /* Debug log level */ debug = true; break; @@ -1396,7 +1461,7 @@ int main (int argc, char *argv[]) vector channels(nPvs); for (int n = 0; n < nPvs; n++) { - shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); + shared_ptr channelRequesterImpl(new ChannelRequesterImpl(quiet)); // TODO to be removed String providerName = providerNames[n]; @@ -1466,7 +1531,7 @@ int main (int argc, char *argv[]) if (collectValues) { collectedValues.push_back(getRequesterImpl->getPVStructure()); - // no labels collectedNames.push_back(channel->getChannelName()); + collectedNames.push_back(channel->getChannelName()); } else { @@ -1634,7 +1699,7 @@ int main (int argc, char *argv[]) ClientFactory::start(); ChannelProvider::shared_pointer provider = getChannelAccess()->getProvider("pvAccess"); - shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); + shared_ptr channelRequesterImpl(new ChannelRequesterImpl(quiet)); Channel::shared_pointer channel = authority.empty() ? provider->createChannel(service, channelRequesterImpl) : diff --git a/testApp/remote/pvget.cpp b/testApp/remote/pvget.cpp index 289c5bb..46b181c 100644 --- a/testApp/remote/pvget.cpp +++ b/testApp/remote/pvget.cpp @@ -50,6 +50,7 @@ void usage (void) " -w : Wait time, specifies timeout, default is %f second(s)\n" " -t: Terse mode - print only value, without names\n" " -m: Monitor mode\n" + " -q: Quiet mode, print only error messages\n" " -d: Enable debug output\n" " -F : Use as an alternate output field separator\n" " -c: Wait for clean shutdown and report used instance count (for expert users)" @@ -346,10 +347,11 @@ int main (int argc, char *argv[]) bool debug = false; bool cleanupAndReport = false; bool monitor = false; + bool quiet = false; setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */ - while ((opt = getopt(argc, argv, ":hr:w:tmdcF:")) != -1) { + while ((opt = getopt(argc, argv, ":hr:w:tmqdcF:")) != -1) { switch (opt) { case 'h': /* Print usage */ usage(); @@ -373,6 +375,9 @@ int main (int argc, char *argv[]) case 'm': /* Monitor mode */ monitor = true; break; + case 'q': /* Quiet mode */ + quiet = true; + break; case 'd': /* Debug log level */ debug = true; break; @@ -436,7 +441,7 @@ int main (int argc, char *argv[]) vector channels(nPvs); for (int n = 0; n < nPvs; n++) { - shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); + shared_ptr channelRequesterImpl(new ChannelRequesterImpl(quiet)); channels[n] = provider->createChannel(pvs[n], channelRequesterImpl); } diff --git a/testApp/remote/pvput.cpp b/testApp/remote/pvput.cpp index 8eb0cfc..48e62ec 100644 --- a/testApp/remote/pvput.cpp +++ b/testApp/remote/pvput.cpp @@ -537,6 +537,7 @@ void usage (void) " -r : Request, specifies what fields to return and options, default is '%s'\n" " -w : Wait time, specifies timeout, default is %f second(s)\n" " -t: Terse mode - print only successfully written value, without names\n" + " -q: Quiet mode, print only error messages\n" " -d: Enable debug output\n" " -F : Use as an alternate output field separator" "\nExample: pvput double01 1.234\n\n" @@ -775,10 +776,11 @@ int main (int argc, char *argv[]) { int opt; /* getopt() current option */ bool debug = false; + bool quiet = false; setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */ - while ((opt = getopt(argc, argv, ":hr:w:tdF:")) != -1) { + while ((opt = getopt(argc, argv, ":hr:w:tqdF:")) != -1) { switch (opt) { case 'h': /* Print usage */ usage(); @@ -802,6 +804,9 @@ int main (int argc, char *argv[]) case 'd': /* Debug log level */ debug = true; break; + case 'q': /* Quiet mode */ + quiet = true; + break; case 'F': /* Store this for output formatting */ fieldSeparator = (char) *optarg; break; @@ -866,19 +871,19 @@ int main (int argc, char *argv[]) do { // first connect - shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); + shared_ptr channelRequesterImpl(new ChannelRequesterImpl(quiet)); Channel::shared_pointer channel = provider->createChannel(pvName, channelRequesterImpl); if (channelRequesterImpl->waitUntilConnected(timeOut)) { shared_ptr putRequesterImpl(new ChannelPutRequesterImpl(channel->getChannelName())); - if (mode != TerseMode) + if (mode != TerseMode && !quiet) std::cout << "Old : "; ChannelPut::shared_pointer channelPut = channel->createChannelPut(putRequesterImpl, pvRequest); allOK &= putRequesterImpl->waitUntilDone(timeOut); if (allOK) { - if (mode != TerseMode) + if (mode != TerseMode && !quiet) printValue(pvName, putRequesterImpl->getStructure()); // convert value from string @@ -896,11 +901,11 @@ int main (int argc, char *argv[]) if (allOK) { // and than a get again to verify put - if (mode != TerseMode) std::cout << "New : "; + if (mode != TerseMode && !quiet) std::cout << "New : "; putRequesterImpl->resetEvent(); channelPut->get(); allOK &= putRequesterImpl->waitUntilDone(timeOut); - if (allOK) + if (allOK && !quiet) printValue(pvName, putRequesterImpl->getStructure()); } } diff --git a/testApp/remote/pvutils.cpp b/testApp/remote/pvutils.cpp index e0c2a37..e2861aa 100644 --- a/testApp/remote/pvutils.cpp +++ b/testApp/remote/pvutils.cpp @@ -211,6 +211,11 @@ char *url_encode(const char *str) { +ChannelRequesterImpl::ChannelRequesterImpl(bool _printOnlyErrors) : + printOnlyErrors(_printOnlyErrors) +{ +} + String ChannelRequesterImpl::getRequesterName() { return "ChannelRequesterImpl"; @@ -218,7 +223,8 @@ String ChannelRequesterImpl::getRequesterName() void ChannelRequesterImpl::message(String const & message, MessageType messageType) { - std::cerr << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl; + if (!printOnlyErrors || messageType > warningMessage) + std::cerr << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl; } void ChannelRequesterImpl::channelCreated(const epics::pvData::Status& status, Channel::shared_pointer const & channel) diff --git a/testApp/remote/pvutils.h b/testApp/remote/pvutils.h index 4931478..3f71179 100644 --- a/testApp/remote/pvutils.h +++ b/testApp/remote/pvutils.h @@ -52,8 +52,12 @@ class ChannelRequesterImpl : { private: epics::pvData::Event m_event; + bool printOnlyErrors; public: + + ChannelRequesterImpl(bool printOnlyErrors = false); + virtual epics::pvData::String getRequesterName(); virtual void message(epics::pvData::String const & message, epics::pvData::MessageType messageType);