From 8a2d0b417191dcb42ec10abb458e618fcda5d986 Mon Sep 17 00:00:00 2001 From: Matej Sekoranja Date: Wed, 15 Jan 2014 10:59:18 +0100 Subject: [PATCH] eget/pvget/pvput: -f option implemented --- testApp/remote/eget.cpp | 68 ++++++++++++++++++++++++++-------------- testApp/remote/pvget.cpp | 64 +++++++++++++++++++++++++++++++++---- testApp/remote/pvput.cpp | 63 ++++++++++++++++++++++++++++++++----- 3 files changed, 158 insertions(+), 37 deletions(-) diff --git a/testApp/remote/eget.cpp b/testApp/remote/eget.cpp index f76a557..346f0a6 100644 --- a/testApp/remote/eget.cpp +++ b/testApp/remote/eget.cpp @@ -17,7 +17,9 @@ #include #include +#include #include +#include #include #include #include @@ -1021,6 +1023,7 @@ void usage (void) " -q: Quiet mode, print only error messages\n" " -d: Enable debug output\n" " -F : Use as an alternate output field separator\n" + " -f : Use 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\nexamples:\n\n" "#! Get the value of the PV corr:li32:53:bdes\n" @@ -1033,7 +1036,7 @@ void usage (void) "> eget -s archiveService -a entity=quad45:bdes;history -a starttime=2012-02-12T10:04:56 -a endtime=2012-02-01T10:04:56\n" "\n" "#! Get polynomials for bunch of quads using a stdin to give a list of PV names\n" - "> eget -s names -a pattern=QUAD:LTU1:8%%:POLYCOEF | eget -\n" + "> eget -s names -a pattern=QUAD:LTU1:8%%:POLYCOEF | eget -f -\n" "\n" , DEFAULT_REQUEST, DEFAULT_TIMEOUT, DEFAULT_PROVIDER); } @@ -1446,7 +1449,11 @@ int main (int argc, char *argv[]) bool serviceRequest = false; bool pvRequestProvidedByUser = false; bool onlyQuery = false; - bool read_stdin = false; + + istream* inputStream = 0; + ifstream ifs; + bool fromStream = false; + string service; //string urlEncodedRequest; vector< pair > parameters; @@ -1456,7 +1463,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:-")) != -1) { + while ((opt = getopt(argc, argv, ":hr:s:a:w:zntTmxp:qdcF:f:")) != -1) { switch (opt) { case 'h': /* Print usage */ usage(); @@ -1545,9 +1552,28 @@ int main (int argc, char *argv[]) case 'F': /* Store this for output formatting */ fieldSeparator = (char) *optarg; break; - case '-': /* Store this for output formatting */ - read_stdin = true; + case 'f': /* Use input stream as input */ + { + string fileName = optarg; + if (fileName == "-") + inputStream = &cin; + else + { + ifs.open(fileName.c_str(), ifstream::in); + if (!ifs) + { + fprintf(stderr, + "Failed to open file '%s'.\n", + fileName.c_str()); + return 1; + } + else + inputStream = &ifs; + } + + fromStream = true; break; + } case '?': fprintf(stderr, "Unrecognized option: '-%c'. ('eget -h' for help.)\n", @@ -1567,22 +1593,13 @@ int main (int argc, char *argv[]) int nPvs = argc - optind; /* Remaining arg list are PV names */ if (nPvs > 0) { - // do not allow (not supported) reading stdin and command line specified pvs - read_stdin = false; + // do not allow reading file and command line specified pvs + fromStream = false; } - else if (nPvs < 1 && !serviceRequest && !read_stdin) + else if (nPvs < 1 && !serviceRequest && !fromStream) { - // 0 is fd for stdin - // if there is a pipe, automatically set read_stdin - if (!isatty(0)) - { - read_stdin = true; - } - else - { - fprintf(stderr, "No PV name(s) specified. ('eget -h' for help.)\n"); - return 1; - } + fprintf(stderr, "No PV name(s) specified. ('eget -h' for help.)\n"); + return 1; } // only one pv, arguments provided without serviceRequest switch @@ -1716,7 +1733,8 @@ int main (int argc, char *argv[]) } // TODO maybe unify for nPvs == 1?! - bool collectValues = (mode == ValueOnlyMode) && nPvs > 1 && !read_stdin; + // we cannot collect when fromStream is true, since we want to print value immediately + bool collectValues = (mode == ValueOnlyMode) && nPvs > 1 && !fromStream; vector collectedValues; shared_vector collectedNames; @@ -1732,7 +1750,7 @@ int main (int argc, char *argv[]) { Channel::shared_pointer channel; - if (!read_stdin) + if (!fromStream) { if (++n >= nPvs) break; @@ -1742,8 +1760,10 @@ int main (int argc, char *argv[]) { string cn; string cp; - std::cin >> cn; - if (!std::cin) + + // read next channel name from stream + *inputStream >> cn; + if (!(*inputStream)) break; URI uri; @@ -1845,7 +1865,7 @@ int main (int argc, char *argv[]) else { // print immediately - printValue(channel->getChannelName(), getRequesterImpl->getPVStructure()); + printValue(channel->getChannelName(), getRequesterImpl->getPVStructure(), fromStream); } } } diff --git a/testApp/remote/pvget.cpp b/testApp/remote/pvget.cpp index 77b6b2b..3eb8719 100644 --- a/testApp/remote/pvget.cpp +++ b/testApp/remote/pvget.cpp @@ -11,6 +11,8 @@ #include #include +#include +#include #include #include @@ -53,8 +55,9 @@ void usage (void) " -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)" - "\nExample: pvget double01\n\n" + " -f : Use 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" + "\nexample: pvget double01\n\n" , DEFAULT_REQUEST, DEFAULT_TIMEOUT); } @@ -349,9 +352,13 @@ int main (int argc, char *argv[]) bool monitor = false; bool quiet = false; + istream* inputStream = 0; + ifstream ifs; + bool fromStream = false; + setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */ - while ((opt = getopt(argc, argv, ":hr:w:tmqdcF:")) != -1) { + while ((opt = getopt(argc, argv, ":hr:w:tmqdcF:f:")) != -1) { switch (opt) { case 'h': /* Print usage */ usage(); @@ -387,6 +394,28 @@ int main (int argc, char *argv[]) case 'F': /* Store this for output formatting */ fieldSeparator = (char) *optarg; break; + case 'f': /* Use input stream as input */ + { + string fileName = optarg; + if (fileName == "-") + inputStream = &cin; + else + { + ifs.open(fileName.c_str(), ifstream::in); + if (!ifs) + { + fprintf(stderr, + "Failed to open file '%s'.\n", + fileName.c_str()); + return 1; + } + else + inputStream = &ifs; + } + + fromStream = true; + break; + } case '?': fprintf(stderr, "Unrecognized option: '-%c'. ('pvget -h' for help.)\n", @@ -404,15 +433,38 @@ int main (int argc, char *argv[]) } int nPvs = argc - optind; /* Remaining arg list are PV names */ - if (nPvs < 1) + if (nPvs > 0) + { + // do not allow reading file and command line specified pvs + fromStream = false; + } + else if (nPvs < 1 && !fromStream) { fprintf(stderr, "No pv name(s) specified. ('pvget -h' for help.)\n"); return 1; } vector pvs; /* Array of PV structures */ - for (int n = 0; optind < argc; n++, optind++) - pvs.push_back(argv[optind]); /* Copy PV names from command line */ + if (fromStream) + { + string cn; + while (true) + { + *inputStream >> cn; + if (!(*inputStream)) + break; + pvs.push_back(cn); + } + + // set nPvs + nPvs = pvs.size(); + } + else + { + // copy PV names from command line + for (int n = 0; optind < argc; n++, optind++) + pvs.push_back(argv[optind]); + } SET_LOG_LEVEL(debug ? logLevelDebug : logLevelError); diff --git a/testApp/remote/pvput.cpp b/testApp/remote/pvput.cpp index a7f6e80..1c9664a 100644 --- a/testApp/remote/pvput.cpp +++ b/testApp/remote/pvput.cpp @@ -11,6 +11,8 @@ #include #include +#include +#include #include #include @@ -137,8 +139,9 @@ void usage (void) " -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" + " -F : Use as an alternate output field separator\n" + " -f : Use as an input that provides a list PV name(s) to be read, use '-' for stdin\n" + "\nexample: pvput double01 1.234\n\n" , DEFAULT_REQUEST, DEFAULT_TIMEOUT); } @@ -376,10 +379,14 @@ int main (int argc, char *argv[]) bool debug = false; bool quiet = false; + istream* inputStream = 0; + ifstream ifs; + bool fromStream = false; + setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */ putenv(const_cast("POSIXLY_CORRECT=")); /* Behave correct on GNU getopt systems; e.g. handle negative numbers */ - while ((opt = getopt(argc, argv, ":hr:w:tqdF:")) != -1) { + while ((opt = getopt(argc, argv, ":hr:w:tqdF:f:")) != -1) { switch (opt) { case 'h': /* Print usage */ usage(); @@ -409,6 +416,28 @@ int main (int argc, char *argv[]) case 'F': /* Store this for output formatting */ fieldSeparator = (char) *optarg; break; + case 'f': /* Use input stream as input */ + { + string fileName = optarg; + if (fileName == "-") + inputStream = &cin; + else + { + ifs.open(fileName.c_str(), ifstream::in); + if (!ifs) + { + fprintf(stderr, + "Failed to open file '%s'.\n", + fileName.c_str()); + return 1; + } + else + inputStream = &ifs; + } + + fromStream = true; + break; + } case '?': fprintf(stderr, "Unrecognized option: '-%c'. ('pvput -h' for help.)\n", @@ -434,15 +463,35 @@ int main (int argc, char *argv[]) int nVals = argc - optind; /* Remaining arg list are PV names */ - if (nVals < 1) + if (nVals > 0) + { + // do not allow reading file and command line specified pvs + fromStream = false; + } + else if (nVals < 1 && !fromStream) { fprintf(stderr, "No value(s) specified. ('pvput -h' for help.)\n"); return 1; } - vector values; /* Array of values */ - for (int n = 0; optind < argc; n++, optind++) - values.push_back(argv[optind]); /* Copy values from command line */ + vector values; + if (fromStream) + { + string cn; + while (true) + { + *inputStream >> cn; + if (!(*inputStream)) + break; + values.push_back(cn); + } + } + else + { + // copy values from command line + for (int n = 0; optind < argc; n++, optind++) + values.push_back(argv[optind]); + } Requester::shared_pointer requester(new RequesterImpl("pvput"));