#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pvutils.cpp" using namespace std; using namespace std::tr1; using namespace epics::pvData; using namespace epics::pvAccess; #define DEFAULT_TIMEOUT 3.0 double timeOut = DEFAULT_TIMEOUT; void usage (void) { fprintf (stderr, "\nUsage: pvinfo [options] ...\n\n" " -h: Help: Print this message\n" "options:\n" " -w : Wait time, specifies timeout, default is %f second(s)\n" " -d: Enable debug output\n" " -c: Wait for clean shutdown and report used instance count (for expert users)" "\nExample: pvinfo double01\n\n" , DEFAULT_TIMEOUT); } /*+************************************************************************** * * Function: main * * Description: pvinfo main() * Evaluate command line options, set up PVA, connect the * channels, print the data as requested * * Arg(s) In: [options] ... * * Arg(s) Out: none * * Return(s): Standard return code (0=success, 1=error) * **************************************************************************-*/ int main (int argc, char *argv[]) { int opt; /* getopt() current option */ bool debug = false; bool cleanupAndReport = false; setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */ while ((opt = getopt(argc, argv, ":hw:dc")) != -1) { switch (opt) { case 'h': /* Print usage */ usage(); return 0; case 'w': /* Set PVA timeout value */ if(epicsScanDouble(optarg, &timeOut) != 1 || timeOut <= 0.0) { fprintf(stderr, "'%s' is not a valid timeout value " "- ignored. ('pvget -h' for help.)\n", optarg); timeOut = DEFAULT_TIMEOUT; } break; case 'd': /* Debug log level */ debug = true; break; case 'c': /* Clean-up and report used instance count */ cleanupAndReport = true; break; case '?': fprintf(stderr, "Unrecognized option: '-%c'. ('pvinfo -h' for help.)\n", optopt); return 1; case ':': fprintf(stderr, "Option '-%c' requires an argument. ('pvinfo -h' for help.)\n", optopt); return 1; default : usage(); return 1; } } int nPvs = argc - optind; /* Remaining arg list are PV names */ if (nPvs < 1) { fprintf(stderr, "No pv name(s) specified. ('pvinfo -h' for help.)\n"); return 1; } vector pvs; /* Array of PV names */ for (int n = 0; optind < argc; n++, optind++) pvs.push_back(argv[optind]); /* Copy PV names from command line */ SET_LOG_LEVEL(debug ? logLevelDebug : logLevelError); std::cout << std::boolalpha; bool allOK = true; { Requester::shared_pointer requester(new RequesterImpl("pvinfo")); ClientFactory::start(); ChannelProvider::shared_pointer provider = getChannelAccess()->getProvider("pva"); // first connect to all, this allows resource (e.g. TCP connection) sharing vector channels(nPvs); for (int n = 0; n < nPvs; n++) { shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); channels[n] = provider->createChannel(pvs[n], channelRequesterImpl); } // for now a simple iterating sync implementation, guarantees order for (int n = 0; n < nPvs; n++) { Channel::shared_pointer channel = channels[n]; shared_ptr channelRequesterImpl = dynamic_pointer_cast(channel->getChannelRequester()); if (channelRequesterImpl->waitUntilConnected(timeOut)) { shared_ptr getFieldRequesterImpl(new GetFieldRequesterImpl(channel)); channel->getField(getFieldRequesterImpl, ""); if (getFieldRequesterImpl->waitUntilFieldGet(timeOut)) { Structure::const_shared_pointer structure = dynamic_pointer_cast(getFieldRequesterImpl->getField()); channel->printInfo(); if (structure) { String s; structure->toString(&s); std::cout << s << std::endl << std::endl; } else { std::cout << "(null introspection data)" << std::endl << std::endl; } } else { allOK = false; channel->destroy(); std::cerr << "[" << channel->getChannelName() << "] failed to get channel introspection data" << std::endl; } } else { allOK = false; channel->destroy(); std::cerr << "[" << channel->getChannelName() << "] connection timeout" << std::endl; } } ClientFactory::stop(); } if (cleanupAndReport) { // TODO implement wait on context epicsThreadSleep ( 3.0 ); //std::cout << "-----------------------------------------------------------------------" << std::endl; //epicsExitCallAtExits(); } return allOK ? 0 : 1; }