From 754a1d2b0848f400e366346270bfe1079f638bb5 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 21 Feb 2019 19:38:50 -0800 Subject: [PATCH] pvtools main() catch --- pvtoolsSrc/pvcall.cpp | 269 +++++++++++++++--------------- pvtoolsSrc/pvget.cpp | 315 +++++++++++++++++------------------ pvtoolsSrc/pvput.cpp | 371 +++++++++++++++++++++--------------------- 3 files changed, 485 insertions(+), 470 deletions(-) diff --git a/pvtoolsSrc/pvcall.cpp b/pvtoolsSrc/pvcall.cpp index bf1ab84..fdd331d 100644 --- a/pvtoolsSrc/pvcall.cpp +++ b/pvtoolsSrc/pvcall.cpp @@ -85,165 +85,170 @@ arg_t parseArg(const std::string& raw) { int MAIN (int argc, char *argv[]) { - int opt; /* getopt() current option */ - std::string pv; + try { + int opt; /* getopt() current option */ + std::string pv; - args_t args; + args_t args; - while ((opt = getopt(argc, argv, ":hvVM:r:w:p:ds:a:")) != -1) { - switch (opt) { - case 'h': /* Print usage */ - callusage(); - return 0; - case 'v': - verbosity++; - break; - case 'V': /* Print version */ - { - pva::Version version(EXECNAME, "cpp", - EPICS_PVA_MAJOR_VERSION, - EPICS_PVA_MINOR_VERSION, - EPICS_PVA_MAINTENANCE_VERSION, - EPICS_PVA_DEVELOPMENT_FLAG); - fprintf(stdout, "%s\n", version.getVersionString().c_str()); - return 0; - } - break; - case 'M': - if(strcmp(optarg, "raw")==0) { - outmode = pvd::PVStructure::Formatter::Raw; - } else if(strcmp(optarg, "nt")==0) { - outmode = pvd::PVStructure::Formatter::NT; - } else if(strcmp(optarg, "json")==0) { - outmode = pvd::PVStructure::Formatter::JSON; - } else { - fprintf(stderr, "Unknown output mode '%s'\n", optarg); - outmode = pvd::PVStructure::Formatter::Raw; - } - break; - case 'w': /* Set PVA timeout value */ - { - double temp; - if((epicsScanDouble(optarg, &temp)) != 1) + while ((opt = getopt(argc, argv, ":hvVM:r:w:p:ds:a:")) != -1) { + switch (opt) { + case 'h': /* Print usage */ + callusage(); + return 0; + case 'v': + verbosity++; + break; + case 'V': /* Print version */ { - fprintf(stderr, "'%s' is not a valid timeout value " - "- ignored. ('" EXECNAME " -h' for help.)\n", optarg); - } else { - timeout = temp; + pva::Version version(EXECNAME, "cpp", + EPICS_PVA_MAJOR_VERSION, + EPICS_PVA_MINOR_VERSION, + EPICS_PVA_MAINTENANCE_VERSION, + EPICS_PVA_DEVELOPMENT_FLAG); + fprintf(stdout, "%s\n", version.getVersionString().c_str()); + return 0; + } + break; + case 'M': + if(strcmp(optarg, "raw")==0) { + outmode = pvd::PVStructure::Formatter::Raw; + } else if(strcmp(optarg, "nt")==0) { + outmode = pvd::PVStructure::Formatter::NT; + } else if(strcmp(optarg, "json")==0) { + outmode = pvd::PVStructure::Formatter::JSON; + } else { + fprintf(stderr, "Unknown output mode '%s'\n", optarg); + outmode = pvd::PVStructure::Formatter::Raw; + } + break; + case 'w': /* Set PVA timeout value */ + { + double temp; + if((epicsScanDouble(optarg, &temp)) != 1) + { + fprintf(stderr, "'%s' is not a valid timeout value " + "- ignored. ('" EXECNAME " -h' for help.)\n", optarg); + } else { + timeout = temp; + } + } + break; + case 'r': /* Set PVA timeout value */ + request = optarg; + break; + case 'p': /* Set default provider */ + defaultProvider = optarg; + break; + case 'd': /* Debug log level */ + debugFlag = true; + break; + case 's': + pv = optarg; + break; + case 'a': + try { + args.push_back(parseArg(optarg)); + } catch(std::exception& e){ + std::cerr<<"Error parsing argument '"<createFieldBuilder()); + builder = builder->setId("epics:nt/NTURI:1.0") + ->add("scheme", pvd::pvString) + ->add("authority", pvd::pvString) + ->add("path", pvd::pvString) + ->addNestedStructure("query"); - pvd::PVStructurePtr argument; - { - pvd::FieldBuilderPtr builder(pvd::getFieldCreate()->createFieldBuilder()); - builder = builder->setId("epics:nt/NTURI:1.0") - ->add("scheme", pvd::pvString) - ->add("authority", pvd::pvString) - ->add("path", pvd::pvString) - ->addNestedStructure("query"); + for(args_t::const_iterator it(args.begin()), end(args.end()); it!=end; ++it) { + builder = builder->add(it->first, it->second->getField()); + } - for(args_t::const_iterator it(args.begin()), end(args.end()); it!=end; ++it) { - builder = builder->add(it->first, it->second->getField()); + pvd::StructureConstPtr type(builder->endNested() + ->createStructure()); + argument = pvd::getPVDataCreate()->createPVStructure(type); + + argument->getSubFieldT("scheme")->put(defaultProvider); + argument->getSubFieldT("path")->put(pv); + pvd::PVStructurePtr query(argument->getSubFieldT("query")); + + for(args_t::const_iterator it(args.begin()), end(args.end()); it!=end; ++it) { + query->getSubFieldT(it->first)->copy(*it->second); + } } - pvd::StructureConstPtr type(builder->endNested() - ->createStructure()); - argument = pvd::getPVDataCreate()->createPVStructure(type); + if(verbosity>=1) + std::cout<<"# Argument\n"<stream().format(outmode); - argument->getSubFieldT("scheme")->put(defaultProvider); - argument->getSubFieldT("path")->put(pv); - pvd::PVStructurePtr query(argument->getSubFieldT("query")); + pvac::ClientProvider prov(defaultProvider); - for(args_t::const_iterator it(args.begin()), end(args.end()); it!=end; ++it) { - query->getSubFieldT(it->first)->copy(*it->second); + pvac::ClientChannel chan(prov.connect(pv)); + + pvd::PVStructure::const_shared_pointer ret; + try { + ret = chan.rpc(timeout, argument, pvRequest); + }catch(pvac::Timeout&){ + std::cerr<<"Timeout\n"; + return 1; + }catch(std::exception& e) { + std::cerr<<"Error: "<=1) - std::cout<<"# Argument\n"<stream().format(outmode); + if(verbosity>=1) + std::cout<<"# Result\n"; + std::cout<stream().format(outmode); - pvac::ClientProvider prov(defaultProvider); - - pvac::ClientChannel chan(prov.connect(pv)); - - pvd::PVStructure::const_shared_pointer ret; - try { - ret = chan.rpc(timeout, argument, pvRequest); - }catch(pvac::Timeout&){ - std::cerr<<"Timeout\n"; - return 1; - }catch(std::exception& e) { + return 0; + } catch(std::exception& e) { std::cerr<<"Error: "<=1) - std::cout<<"# Result\n"; - std::cout<stream().format(outmode); - - return 0; } diff --git a/pvtoolsSrc/pvget.cpp b/pvtoolsSrc/pvget.cpp index 2b475d5..141ec19 100644 --- a/pvtoolsSrc/pvget.cpp +++ b/pvtoolsSrc/pvget.cpp @@ -264,180 +264,185 @@ struct MonTracker : public pvac::ClientChannel::MonitorCallback, int MAIN (int argc, char *argv[]) { - int opt; /* getopt() current option */ + try { + int opt; /* getopt() current option */ #ifdef PVMONITOR - bool monitor = true; + bool monitor = true; #else - bool monitor = false; + bool monitor = false; #endif - epics::RefMonitor refmon; + epics::RefMonitor refmon; - // ================ Parse Arguments + // ================ Parse Arguments - while ((opt = getopt(argc, argv, ":hvVRM:r:w:tmp:qdcF:f:ni")) != -1) { - switch (opt) { - case 'h': /* Print usage */ - usage(); - return 0; - case 'v': - verbosity++; - break; - case 'V': /* Print version */ - { - pva::Version version(EXECNAME, "cpp", - EPICS_PVA_MAJOR_VERSION, - EPICS_PVA_MINOR_VERSION, - EPICS_PVA_MAINTENANCE_VERSION, - EPICS_PVA_DEVELOPMENT_FLAG); - fprintf(stdout, "%s\n", version.getVersionString().c_str()); - return 0; - } - case 'R': - refmon.start(5.0); - break; - case 'M': - if(strcmp(optarg, "raw")==0) { - outmode = pvd::PVStructure::Formatter::Raw; - } else if(strcmp(optarg, "nt")==0) { - outmode = pvd::PVStructure::Formatter::NT; - } else if(strcmp(optarg, "json")==0) { - outmode = pvd::PVStructure::Formatter::JSON; - } else { - fprintf(stderr, "Unknown output mode '%s'\n", optarg); - outmode = pvd::PVStructure::Formatter::Raw; - } - break; - case 'w': /* Set PVA timeout value */ - { - double temp; - if((epicsScanDouble(optarg, &temp)) != 1) + while ((opt = getopt(argc, argv, ":hvVRM:r:w:tmp:qdcF:f:ni")) != -1) { + switch (opt) { + case 'h': /* Print usage */ + usage(); + return 0; + case 'v': + verbosity++; + break; + case 'V': /* Print version */ { - fprintf(stderr, "'%s' is not a valid timeout value " - "- ignored. ('" EXECNAME " -h' for help.)\n", optarg); - } else { - timeout = temp; + pva::Version version(EXECNAME, "cpp", + EPICS_PVA_MAJOR_VERSION, + EPICS_PVA_MINOR_VERSION, + EPICS_PVA_MAINTENANCE_VERSION, + EPICS_PVA_DEVELOPMENT_FLAG); + fprintf(stdout, "%s\n", version.getVersionString().c_str()); + return 0; } - } - break; - case 'r': /* Set PVA timeout value */ + case 'R': + refmon.start(5.0); + break; + case 'M': + if(strcmp(optarg, "raw")==0) { + outmode = pvd::PVStructure::Formatter::Raw; + } else if(strcmp(optarg, "nt")==0) { + outmode = pvd::PVStructure::Formatter::NT; + } else if(strcmp(optarg, "json")==0) { + outmode = pvd::PVStructure::Formatter::JSON; + } else { + fprintf(stderr, "Unknown output mode '%s'\n", optarg); + outmode = pvd::PVStructure::Formatter::Raw; + } + break; + case 'w': /* Set PVA timeout value */ + { + double temp; + if((epicsScanDouble(optarg, &temp)) != 1) + { + fprintf(stderr, "'%s' is not a valid timeout value " + "- ignored. ('" EXECNAME " -h' for help.)\n", optarg); + } else { + timeout = temp; + } + } + break; + case 'r': /* Set PVA timeout value */ request = optarg; break; - case 't': /* Terse mode */ - case 'i': /* T-types format mode */ - case 'F': /* Store this for output formatting */ - case 'n': - case 'q': /* Quiet mode */ - // deprecate - break; - case 'f': /* Use input stream as input */ - fprintf(stderr, "Unsupported option -f\n"); - return 1; - case 'm': /* Monitor mode */ - monitor = true; - break; - case 'p': /* Set default provider */ - defaultProvider = optarg; - break; - case 'd': /* Debug log level */ - debugFlag = true; - break; - case 'c': /* Clean-up and report used instance count */ - break; - case '?': - fprintf(stderr, - "Unrecognized option: '-%c'. ('" EXECNAME " -h' for help.)\n", - optopt); - return 1; - case ':': - fprintf(stderr, - "Option '-%c' requires an argument. ('" EXECNAME " -h' for help.)\n", - optopt); - return 1; - default : - usage(); - return 1; - } - } - - if(monitor) - timeout = -1; - - if(verbosity>0 && outmode==pvd::PVStructure::Formatter::NT) - outmode = pvd::PVStructure::Formatter::Raw; - - pvd::PVStructure::shared_pointer pvRequest; - try { - pvRequest = pvd::createRequest(request); - } catch(std::exception& e){ - fprintf(stderr, "failed to parse request string: %s\n", e.what()); - return 1; - } - - for(int i = optind; i < argc; i++) { - pvnamewidth = std::max(pvnamewidth, strlen(argv[i])); - } - - SET_LOG_LEVEL(debugFlag ? pva::logLevelDebug : pva::logLevelError); - - epics::pvAccess::ca::CAClientFactory::start(); - - { - pvac::ClientProvider provider(defaultProvider); - - std::vector > tracked; - - epics::auto_ptr Q; - if(monitor) - Q.reset(new WorkQueue); - - for(int i = optind; i < argc; i++) { - pvac::ClientChannel chan(provider.connect(argv[i])); - - if(monitor) { - std::tr1::shared_ptr mon(new MonTracker(*Q, chan, pvRequest)); - - tracked.push_back(mon); - - } else { // Get - std::tr1::shared_ptr get(new Getter(chan, pvRequest)); - - tracked.push_back(get); + case 't': /* Terse mode */ + case 'i': /* T-types format mode */ + case 'F': /* Store this for output formatting */ + case 'n': + case 'q': /* Quiet mode */ + // deprecate + break; + case 'f': /* Use input stream as input */ + fprintf(stderr, "Unsupported option -f\n"); + return 1; + case 'm': /* Monitor mode */ + monitor = true; + break; + case 'p': /* Set default provider */ + defaultProvider = optarg; + break; + case 'd': /* Debug log level */ + debugFlag = true; + break; + case 'c': /* Clean-up and report used instance count */ + break; + case '?': + fprintf(stderr, + "Unrecognized option: '-%c'. ('" EXECNAME " -h' for help.)\n", + optopt); + return 1; + case ':': + fprintf(stderr, + "Option '-%c' requires an argument. ('" EXECNAME " -h' for help.)\n", + optopt); + return 1; + default : + usage(); + return 1; } } - // ========================== Wait for operations to complete, or timeout + if(monitor) + timeout = -1; - Tracker::prepare(); // install signal handler + if(verbosity>0 && outmode==pvd::PVStructure::Formatter::NT) + outmode = pvd::PVStructure::Formatter::Raw; - if(debugFlag) - std::cerr<<"Waiting...\n"; + pvd::PVStructure::shared_pointer pvRequest; + try { + pvRequest = pvd::createRequest(request); + } catch(std::exception& e){ + fprintf(stderr, "failed to parse request string: %s\n", e.what()); + return 1; + } + + for(int i = optind; i < argc; i++) { + pvnamewidth = std::max(pvnamewidth, strlen(argv[i])); + } + + SET_LOG_LEVEL(debugFlag ? pva::logLevelDebug : pva::logLevelError); + + epics::pvAccess::ca::CAClientFactory::start(); { - Guard G(Tracker::doneLock); - while(Tracker::inprog.size() && !Tracker::abort) { - UnGuard U(G); - if(timeout<=0) - Tracker::doneEvt.wait(); - else if(!Tracker::doneEvt.wait(timeout)) { - haderror = 1; - std::cerr<<"Timeout\n"; - break; + pvac::ClientProvider provider(defaultProvider); + + std::vector > tracked; + + epics::auto_ptr Q; + if(monitor) + Q.reset(new WorkQueue); + + for(int i = optind; i < argc; i++) { + pvac::ClientChannel chan(provider.connect(argv[i])); + + if(monitor) { + std::tr1::shared_ptr mon(new MonTracker(*Q, chan, pvRequest)); + + tracked.push_back(mon); + + } else { // Get + std::tr1::shared_ptr get(new Getter(chan, pvRequest)); + + tracked.push_back(get); + } + } + + // ========================== Wait for operations to complete, or timeout + + Tracker::prepare(); // install signal handler + + if(debugFlag) + std::cerr<<"Waiting...\n"; + + { + Guard G(Tracker::doneLock); + while(Tracker::inprog.size() && !Tracker::abort) { + UnGuard U(G); + if(timeout<=0) + Tracker::doneEvt.wait(); + else if(!Tracker::doneEvt.wait(timeout)) { + haderror = 1; + std::cerr<<"Timeout\n"; + break; + } } } } + + if(refmon.running()) { + refmon.stop(); + // show final counts + refmon.current(); + } + + // ========================== All done now + + if(debugFlag) + std::cerr<<"Done\n"; + + return haderror ? 1 : 0; + } catch(std::exception& e) { + std::cerr<<"Error: "<("POSIXLY_CORRECT=")); /* Behave correct on GNU getopt systems; e.g. handle negative numbers */ - - while ((opt = getopt(argc, argv, ":hvVM:r:w:tp:qdF:f:ns")) != -1) { - switch (opt) { - case 'h': /* Print usage */ - usage(true); - return 0; - case 'v': - outmode = pvd::PVStructure::Formatter::Raw; - break; - case 'V': /* Print version */ - { - pva::Version version("pvput", "cpp", - EPICS_PVA_MAJOR_VERSION, - EPICS_PVA_MINOR_VERSION, - EPICS_PVA_MAINTENANCE_VERSION, - EPICS_PVA_DEVELOPMENT_FLAG); - fprintf(stdout, "%s\n", version.getVersionString().c_str()); - return 0; - } - case 'M': - if(strcmp(optarg, "raw")==0) { - outmode = pvd::PVStructure::Formatter::Raw; - } else if(strcmp(optarg, "nt")==0) { - outmode = pvd::PVStructure::Formatter::NT; - } else if(strcmp(optarg, "json")==0) { - outmode = pvd::PVStructure::Formatter::JSON; - } else { - fprintf(stderr, "Unknown output mode '%s'\n", optarg); - outmode = pvd::PVStructure::Formatter::Raw; - } - break; - case 'w': /* Set PVA timeout value */ - { - double temp; - if((epicsScanDouble(optarg, &temp)) != 1) - { - fprintf(stderr, "'%s' is not a valid timeout value " - "- ignored. ('pvput -h' for help.)\n", optarg); - } else { - timeout = temp; - } - } - break; - case 'r': /* Set PVA timeout value */ - request = optarg; - break; - case 't': /* Terse mode */ - // deprecated - break; - case 'd': /* Debug log level */ - debugFlag = true; - break; - case 'p': /* Set default provider */ - defaultProvider = optarg; - break; - case 'q': /* Quiet mode */ - quiet = true; - break; - case 'F': /* Store this for output formatting */ - break; - case 'f': /* Use input stream as input */ - fprintf(stderr, "Unsupported option -f\n"); - return 1; - case 'n': - break; - case 's': - break; - case '?': - fprintf(stderr, - "Unrecognized option: '-%c'. ('pvput -h' for help.)\n", - optopt); - return 1; - case ':': - fprintf(stderr, - "Option '-%c' requires an argument. ('pvput -h' for help.)\n", - optopt); - return 1; - default : - usage(); - return 1; - } - } - - if (argc <= optind) - { - fprintf(stderr, "No pv name specified. ('pvput -h' for help.)\n"); - return 1; - } - std::string pv = argv[optind++]; - - std::string providerName(defaultProvider); - std::string pvName(pv); - - int nVals = argc - optind; /* Remaining arg list are PV names */ - if (nVals < 1) - { - fprintf(stderr, "No value(s) specified. ('pvput -h' for help.)\n"); - return 1; - } - - std::vector values; - // copy values from command line - for (int n = 0; optind < argc; n++, optind++) - values.push_back(argv[optind]); - - Putter thework; - - for(size_t i=0, N=values.size(); i("POSIXLY_CORRECT=")); /* Behave correct on GNU getopt systems; e.g. handle negative numbers */ - std::cout << std::boolalpha; - - epics::pvAccess::ca::CAClientFactory::start(); - - pvac::ClientProvider ctxt(providerName); - - pvac::ClientChannel chan(ctxt.connect(pvName)); - - if (!quiet) { - std::cout << "Old : "; - printValue(pvName, chan.get(timeout, pvRequest)); - } - - { - pvac::Operation op(chan.put(&thework, pvRequest, true)); - - epicsGuard G(thework.lock); - while(!thework.done) { - epicsGuardRelease U(G); - if(!thework.wait.wait(timeout)) { - fprintf(stderr, "Put timeout\n"); + while ((opt = getopt(argc, argv, ":hvVM:r:w:tp:qdF:f:ns")) != -1) { + switch (opt) { + case 'h': /* Print usage */ + usage(true); + return 0; + case 'v': + outmode = pvd::PVStructure::Formatter::Raw; + break; + case 'V': /* Print version */ + { + pva::Version version("pvput", "cpp", + EPICS_PVA_MAJOR_VERSION, + EPICS_PVA_MINOR_VERSION, + EPICS_PVA_MAINTENANCE_VERSION, + EPICS_PVA_DEVELOPMENT_FLAG); + fprintf(stdout, "%s\n", version.getVersionString().c_str()); + return 0; + } + case 'M': + if(strcmp(optarg, "raw")==0) { + outmode = pvd::PVStructure::Formatter::Raw; + } else if(strcmp(optarg, "nt")==0) { + outmode = pvd::PVStructure::Formatter::NT; + } else if(strcmp(optarg, "json")==0) { + outmode = pvd::PVStructure::Formatter::JSON; + } else { + fprintf(stderr, "Unknown output mode '%s'\n", optarg); + outmode = pvd::PVStructure::Formatter::Raw; + } + break; + case 'w': /* Set PVA timeout value */ + { + double temp; + if((epicsScanDouble(optarg, &temp)) != 1) + { + fprintf(stderr, "'%s' is not a valid timeout value " + "- ignored. ('pvput -h' for help.)\n", optarg); + } else { + timeout = temp; + } + } + break; + case 'r': /* Set PVA timeout value */ + request = optarg; + break; + case 't': /* Terse mode */ + // deprecated + break; + case 'd': /* Debug log level */ + debugFlag = true; + break; + case 'p': /* Set default provider */ + defaultProvider = optarg; + break; + case 'q': /* Quiet mode */ + quiet = true; + break; + case 'F': /* Store this for output formatting */ + break; + case 'f': /* Use input stream as input */ + fprintf(stderr, "Unsupported option -f\n"); + return 1; + case 'n': + break; + case 's': + break; + case '?': + fprintf(stderr, + "Unrecognized option: '-%c'. ('pvput -h' for help.)\n", + optopt); + return 1; + case ':': + fprintf(stderr, + "Option '-%c' requires an argument. ('pvput -h' for help.)\n", + optopt); + return 1; + default : + usage(); return 1; } } - } - if(thework.result==pvac::PutEvent::Fail) { - fprintf(stderr, "Error: %s\n", thework.message.c_str()); - } + if (argc <= optind) + { + fprintf(stderr, "No pv name specified. ('pvput -h' for help.)\n"); + return 1; + } + std::string pv = argv[optind++]; - if (!quiet) { - std::cout << "New : "; - } - printValue(pvName, chan.get(timeout, pvRequest)); + std::string providerName(defaultProvider); + std::string pvName(pv); - return thework.result!=pvac::PutEvent::Success; + int nVals = argc - optind; /* Remaining arg list are PV names */ + if (nVals < 1) + { + fprintf(stderr, "No value(s) specified. ('pvput -h' for help.)\n"); + return 1; + } + + std::vector values; + // copy values from command line + for (int n = 0; optind < argc; n++, optind++) + values.push_back(argv[optind]); + + Putter thework; + + for(size_t i=0, N=values.size(); i G(thework.lock); + while(!thework.done) { + epicsGuardRelease U(G); + if(!thework.wait.wait(timeout)) { + fprintf(stderr, "Put timeout\n"); + return 1; + } + } + } + + if(thework.result==pvac::PutEvent::Fail) { + fprintf(stderr, "Error: %s\n", thework.message.c_str()); + } + + if (!quiet) { + std::cout << "New : "; + } + printValue(pvName, chan.get(timeout, pvRequest)); + + return thework.result!=pvac::PutEvent::Success; + } catch(std::exception& e) { + std::cerr<<"Error: "<