From d0915581b4c6fae5b3ff622e940ada526e44c204 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 7 Jun 2017 19:59:56 +0200 Subject: [PATCH] rationalize CLI handling of providers --- pvtoolsSrc/eget.cpp | 142 ++++++++++++++++-------------------------- pvtoolsSrc/pvget.cpp | 41 ++++++------ pvtoolsSrc/pvinfo.cpp | 34 +++++----- pvtoolsSrc/pvput.cpp | 21 +++---- 4 files changed, 95 insertions(+), 143 deletions(-) diff --git a/pvtoolsSrc/eget.cpp b/pvtoolsSrc/eget.cpp index d3a4d0c..cc5a803 100644 --- a/pvtoolsSrc/eget.cpp +++ b/pvtoolsSrc/eget.cpp @@ -1664,8 +1664,6 @@ int main (int argc, char *argv[]) bool allOK = true; - Requester::shared_pointer requester(new RequesterImpl("eget")); - // parse URI // try to parse as URI if only one nPvs URI uri; @@ -1682,14 +1680,16 @@ int main (int argc, char *argv[]) serviceRequest = true; } - static string noAddress; + // register "pva" and "ca" providers + ClientFactory::start(); + epics::pvAccess::ca::CAClientFactory::start(); // PVs mode if (!serviceRequest) { vector pvs; vector pvsAddress; - vector providerNames; + vector providers; vector operations; if (validURI) @@ -1714,26 +1714,38 @@ int main (int argc, char *argv[]) // skip trailing '/' pvs.push_back(uri.path.substr(1)); pvsAddress.push_back(uri.host); - providerNames.push_back(uri.protocol); + providers.push_back(getChannelProviderRegistry()->getProvider(uri.protocol)); + if(!providers.back()) { + std::cerr<<"Unknown provider \""< uris; + + if(!fromStream) { + for (int n = 0; optind < argc; n++, optind++) + { + uris.push_back(argv[optind]); + } + } else { + string cn; + while (true) + { + *inputStream >> cn; + if (!(*inputStream)) + break; + uris.push_back(cn); + } + } + + for (size_t n = 0; ngetProvider(uri.protocol)); } else { - pvs.push_back(argv[optind]); - pvsAddress.push_back(noAddress); - providerNames.push_back(defaultProvider); + uri.protocol = defaultProvider; + pvs.push_back(uris[n]); + pvsAddress.push_back(std::string()); + providers.push_back(getChannelProviderRegistry()->getProvider(defaultProvider)); + } + + if(!providers.back()) { + std::cerr<<"Unknown provider \""<createRequest(request); if(pvRequest.get()==0) { @@ -1762,20 +1782,21 @@ int main (int argc, char *argv[]) return 1; } - // register "pva" and "ca" providers - ClientFactory::start(); - epics::pvAccess::ca::CAClientFactory::start(); - // first connect to all, this allows resource (e.g. TCP connection) sharing vector channels(nPvs); for (int n = 0; n < nPvs; n++) { + if(!providers[n]) continue; TR1::shared_ptr channelRequesterImpl(new ChannelRequesterImpl(quiet)); if (pvsAddress[n].empty()) - channels[n] = getChannelProviderRegistry()->getProvider(providerNames[n])->createChannel(pvs[n], channelRequesterImpl); + channels[n] = providers[n]->createChannel(pvs[n], channelRequesterImpl); else - channels[n] = getChannelProviderRegistry()->getProvider(providerNames[n])->createChannel(pvs[n], channelRequesterImpl, + channels[n] = providers[n]->createChannel(pvs[n], channelRequesterImpl, ChannelProvider::PRIORITY_DEFAULT, pvsAddress[n]); + + if(!channels[n]) { + std::cerr<<"No such channel '"<= nPvs) - break; - channel = channels[n]; - } - else - { - string cn; - string ca; - string cp; - - // read next channel name from stream - *inputStream >> cn; - if (!(*inputStream)) - break; - - URI uri; - bool validURI = URI::parse(cn.c_str(), uri); - if (validURI) - { - // TODO this is copy&pase code from above, clean it up - // for now no only pva/ca schema is supported, without authority - // TODO - if (uri.protocol != "pva" && uri.protocol != "ca") - { - std::cerr << "invalid URI scheme '" << uri.protocol << "', only 'pva' and 'ca' are supported" << std::endl; - // TODO - return 1; - } - - if (uri.path.length() <= 1) - { - std::cerr << "invalid URI, empty path" << std::endl; - // TODO - return 1; - } - - // skip trailing '/' - cn = uri.path.substr(1); - ca = uri.host; - cp = uri.protocol; - } - else - { - // leave cn as it is, use default provider - ca = noAddress; - cp = defaultProvider; - } - - - - TR1::shared_ptr channelRequesterImpl(new ChannelRequesterImpl(quiet)); - if (ca.empty()) - channel = getChannelProviderRegistry()->getProvider(cp)->createChannel(cn, channelRequesterImpl); - else - channel = getChannelProviderRegistry()->getProvider(cp)->createChannel(cn, channelRequesterImpl, - ChannelProvider::PRIORITY_DEFAULT, ca); + if(!channel) { + allOK = false; + continue; } if (monitor) @@ -2101,6 +2066,7 @@ int main (int argc, char *argv[]) ClientFactory::start(); ChannelProvider::shared_pointer provider = getChannelProviderRegistry()->getProvider("pva"); + assert(provider); TR1::shared_ptr channelRequesterImpl(new ChannelRequesterImpl(quiet)); Channel::shared_pointer channel = diff --git a/pvtoolsSrc/pvget.cpp b/pvtoolsSrc/pvget.cpp index 6a322f8..73fc59a 100644 --- a/pvtoolsSrc/pvget.cpp +++ b/pvtoolsSrc/pvget.cpp @@ -516,11 +516,12 @@ int main (int argc, char *argv[]) std::cout << std::boolalpha; terseSeparator(fieldSeparator); + ClientFactory::start(); + epics::pvAccess::ca::CAClientFactory::start(); + bool allOK = true; { - Requester::shared_pointer requester(new RequesterImpl("pvget")); - PVStructure::shared_pointer pvRequest = CreateRequest::create()->createRequest(request); if(pvRequest.get()==NULL) { fprintf(stderr, "failed to parse request string\n"); @@ -529,11 +530,10 @@ int main (int argc, char *argv[]) std::vector pvNames; std::vector pvAddresses; - std::vector providerNames; + std::vector providers; pvNames.reserve(nPvs); pvAddresses.reserve(nPvs); - providerNames.reserve(nPvs); for (int n = 0; n < nPvs; n++) { @@ -543,7 +543,7 @@ int main (int argc, char *argv[]) std::string providerName(defaultProvider); std::string pvName(pvs[n]); std::string address(noAddress); - bool usingDefaultProvider = true; + if (validURI) { if (uri.path.length() <= 1) @@ -554,44 +554,41 @@ int main (int argc, char *argv[]) providerName = uri.protocol; pvName = uri.path.substr(1); address = uri.host; - usingDefaultProvider = false; } - if ((providerName != "pva") && (providerName != "ca")) - { - std::cerr << "invalid " - << (usingDefaultProvider ? "default provider" : "URI scheme") - << " '" << providerName - << "', only 'pva' and 'ca' are supported" << std::endl; - return 1; - } pvNames.push_back(pvName); pvAddresses.push_back(address); - providerNames.push_back(providerName); + providers.push_back(getChannelProviderRegistry()->getProvider(providerName)); + if(!providers.back()) { + std::cerr<<"Unknown provider \""< channels(nPvs); vector operations(nPvs); for (int n = 0; n < nPvs; n++) { + if(!providers[n]) continue; TR1::shared_ptr channelRequesterImpl(new ChannelRequesterImpl(quiet)); if (pvAddresses[n].empty()) - channels[n] = getChannelProviderRegistry()->getProvider( - providerNames[n])->createChannel(pvNames[n], channelRequesterImpl); + channels[n] = providers[n]->createChannel(pvNames[n], channelRequesterImpl); else - channels[n] = getChannelProviderRegistry()->getProvider( - providerNames[n])->createChannel(pvNames[n], channelRequesterImpl, + channels[n] = providers[n]->createChannel(pvNames[n], channelRequesterImpl, ChannelProvider::PRIORITY_DEFAULT, pvAddresses[n]); + if(!channels[n]) { + std::cerr<<"Can't create channel \""<getProviderName()<<"\n"; + allOK = false; + } } // for now a simple iterating sync implementation, guarantees order for (int n = 0; n < nPvs; n++) { Channel::shared_pointer channel = channels[n]; + if(!channel) continue; + TR1::shared_ptr channelRequesterImpl = TR1::dynamic_pointer_cast(channel->getChannelRequester()); if (channelRequesterImpl->waitUntilConnected(timeOut)) diff --git a/pvtoolsSrc/pvinfo.cpp b/pvtoolsSrc/pvinfo.cpp index 2ba35cc..1f6c1c2 100644 --- a/pvtoolsSrc/pvinfo.cpp +++ b/pvtoolsSrc/pvinfo.cpp @@ -137,22 +137,22 @@ int main (int argc, char *argv[]) bool allOK = true; + ClientFactory::start(); + epics::pvAccess::ca::CAClientFactory::start(); + { std::vector pvNames; std::vector pvAddresses; - std::vector providerNames; + std::vector providers; pvNames.reserve(nPvs); pvAddresses.reserve(nPvs); - providerNames.reserve(nPvs); for (int n = 0; n < nPvs; n++) { URI uri; bool validURI = URI::parse(pvs[n], uri); - TR1::shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); - std::string providerName(defaultProvider); std::string pvName(pvs[n]); std::string address(noAddress); @@ -170,33 +170,27 @@ int main (int argc, char *argv[]) usingDefaultProvider = false; } - if ((providerName != "pva") && (providerName != "ca")) - { - std::cerr << "invalid " - << (usingDefaultProvider ? "default provider" : "URI scheme") - << " '" << providerName - << "', only 'pva' and 'ca' are supported" << std::endl; - return 1; - } pvNames.push_back(pvName); pvAddresses.push_back(address); - providerNames.push_back(providerName); + providers.push_back(getChannelProviderRegistry()->getProvider(providerName)); + if(!providers.back()) + { + std::cerr << "unknown provider name '" << providerName + << "', only 'pva' and 'ca' are supported" << std::endl; + allOK = false; + } } - ClientFactory::start(); - epics::pvAccess::ca::CAClientFactory::start(); - // first connect to all, this allows resource (e.g. TCP connection) sharing vector channels(nPvs); for (int n = 0; n < nPvs; n++) { + if(!providers[n]) continue; TR1::shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); if (pvAddresses[n].empty()) - channels[n] = getChannelProviderRegistry()->getProvider( - providerNames[n])->createChannel(pvNames[n], channelRequesterImpl); + channels[n] = providers[n]->createChannel(pvNames[n], channelRequesterImpl); else - channels[n] = getChannelProviderRegistry()->getProvider( - providerNames[n])->createChannel(pvNames[n], channelRequesterImpl, + channels[n] = providers[n]->createChannel(pvNames[n], channelRequesterImpl, ChannelProvider::PRIORITY_DEFAULT, pvAddresses[n]); } diff --git a/pvtoolsSrc/pvput.cpp b/pvtoolsSrc/pvput.cpp index 9eb9e89..5062c19 100644 --- a/pvtoolsSrc/pvput.cpp +++ b/pvtoolsSrc/pvput.cpp @@ -642,12 +642,12 @@ int main (int argc, char *argv[]) usingDefaultProvider = false; } - if ((providerName != "pva") && (providerName != "ca")) - { - std::cerr << "invalid " - << (usingDefaultProvider ? "default provider" : "URI scheme") - << " '" << providerName - << "', only 'pva' and 'ca' are supported" << std::endl; + ClientFactory::start(); + epics::pvAccess::ca::CAClientFactory::start(); + + ChannelProvider::shared_pointer provider(getChannelProviderRegistry()->getProvider(providerName)); + if(!provider) { + std::cerr << "Unknown provider '"<getProvider( - providerName)->createChannel(pvName, channelRequesterImpl); + channel = provider->createChannel(pvName, channelRequesterImpl); else - channel = getChannelProviderRegistry()->getProvider( - providerName)->createChannel(pvName, channelRequesterImpl, + channel = provider->createChannel(pvName, channelRequesterImpl, ChannelProvider::PRIORITY_DEFAULT, address); if (channelRequesterImpl->waitUntilConnected(timeOut))