/* * Copyright information and license terms for this software can be * found in the file LICENSE that is included with the distribution */ #include #include #include #include #include #include #include "pvutils.h" #ifndef EXECNAME # define EXECNAME "pvcall" #endif namespace { void callusage (void) { fprintf (stderr, "\nUsage: " EXECNAME " [options] [=]...\n" "\n" COMMON_OPTIONS " -s : legacy form of PV name\n" " -a : legacy form of argument\n" " deprecated options:\n" " -q, -t, -i, -n, -F: ignored\n" " -f : errors\n" "\nexample: " EXECNAME " pv:name:add lhs=1 rhs=2\n\n" , request.c_str(), timeout, defaultProvider.c_str()); } typedef std::pair arg_t; typedef std::vector args_t; arg_t parseArg(const std::string& raw) { size_t equal = raw.find_first_of('='); if(equal==raw.npos) throw std::runtime_error("Argument missing '='"); std::string sval(raw.substr(equal+1)); pvd::PVFieldPtr value; if(sval.size()>=2 && sval[0]=='[' && sval[sval.size()-1]==']') { pvd::shared_vector sarr; jarray(sarr, sval.c_str()); pvd::PVStringArrayPtr V(pvd::getPVDataCreate()->createPVScalarArray()); V->replace(pvd::freeze(sarr)); value = V; } else if(sval.size()>=2 && sval[0]=='{' && sval[sval.size()-1]=='}') { std::istringstream strm(sval); value = pvd::parseJSON(strm); } else { pvd::PVStringPtr V(pvd::getPVDataCreate()->createPVScalar()); V->put(sval); value = V; } assert(!!value); return std::make_pair(raw.substr(0, equal), value); } } //namespace #ifndef MAIN # define MAIN main #endif int MAIN (int argc, char *argv[]) { try { int opt; /* getopt() current option */ std::string pv; 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 */ { fprintf(stdout, "pvAccess %u.%u.%u%s\n", EPICS_PVA_MAJOR_VERSION, EPICS_PVA_MINOR_VERSION, EPICS_PVA_MAINTENANCE_VERSION, (EPICS_PVA_DEVELOPMENT_FLAG)?"-SNAPSHOT":""); fprintf(stdout, "pvData %u.%u.%u%s\n", EPICS_PVD_MAJOR_VERSION, EPICS_PVD_MINOR_VERSION, EPICS_PVD_MAINTENANCE_VERSION, (EPICS_PVD_DEVELOPMENT_FLAG)?"-SNAPSHOT":""); fprintf(stdout, "Base %s\n", EPICS_VERSION_FULL); 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"); 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); } } if(verbosity>=1) std::cout<<"# Argument\n"<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) { std::cerr<<"Error: "<=1) std::cout<<"# Result\n"; if(ret) std::cout<stream().format(outmode); return 0; } catch(std::exception& e) { std::cerr<<"Error: "<