Esempio n. 1
0
int main (int argc, char **argv)
try {
  // Process the command line arguments
  std::string descString(argv[0]);
  descString += " option [options]\n\n";
  descString += "Prints descriptions of the allowed/required parameters used to\n";
  descString += "configure plugins. Output is ordered by plugin name. Within a\n";
  descString += "plugin, the labels and parameters are ordered based on the order\n";
  descString += "declared by the plugin. Formatted as follows:\n\n";
  descString += "PluginName (PluginType) Library\n";
  descString += "  ModuleLabel\n";
  descString += "    Details of parameters corresponding to this module label\n\n";
  descString += "For more information about the output format see:\n";
  descString += "https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideConfigurationValidationAndHelp\n\n";

  descString += "At least one of the following options must be used: -p, -l, -a, or -q\n\n";
  descString += "Allowed options:";
  boost::program_options::options_description desc(descString);   
  desc.add_options()
                  (kHelpCommandOpt, "produce help message")
                  (kPluginCommandOpt,
                   boost::program_options::value<std::string>(),
                   "only print descriptions for this plugin")
                  (kLibraryCommandOpt,
                   boost::program_options::value<std::string>(),
                   "only print descriptions for plugins in this library")
                  (kAllLibrariesCommandOpt,
                   "allows the program to run without selecting a plugin or library. "
                   "This will take a significant amount of time.")
                  (kModuleLabelCommandOpt,
                   boost::program_options::value<std::string>(),
                   "only print descriptions for this module label")
                  (kBriefCommandOpt,
                   "do not print comments, more compact format, suppress text"
                   " added to help the user understand what the output means")
                  (kPrintOnlyLabelsCommandOpt,
                   "do not print parameter descriptions, just list module labels matching selection criteria")
                  (kPrintOnlyPluginsCommandOpt,
                   "do not print parameter descriptions or module labels, just list plugins matching selection criteria")
                  (kLineWidthCommandOpt,
                   boost::program_options::value<unsigned>(),
                   "try to limit lines to this length by inserting newlines between words in comments. Long words or names can cause the line length to exceed this limit. Defaults to terminal screen width or 80");

  boost::program_options::variables_map vm;
  try {
    store(boost::program_options::command_line_parser(argc,argv).options(desc).run(),vm);
    notify(vm);
  } catch(boost::program_options::error const& iException) {
    std::cerr << "Exception from command line processing: "
              << iException.what() << "\n";
    std::cerr << desc << std::endl;
    return 1;
  }     

  if(vm.count(kHelpOpt)) {
    std::cout << desc << std::endl;
    return 0;
  }

  std::string plugin;
  std::string library;
  std::string moduleLabel;
  bool brief = false;
  bool printOnlyLabels = false;
  bool printOnlyPlugins = false;

  if (vm.count(kPluginOpt)) {
    plugin = vm[kPluginOpt].as<std::string>();
  }
  if (vm.count(kLibraryOpt)) {
    library = vm[kLibraryOpt].as<std::string>();
  }
  if (!vm.count(kAllLibrariesOpt)) {
    if (!vm.count(kPluginOpt) &&
        !vm.count(kLibraryOpt) &&
        !vm.count(kPrintOnlyPluginsOpt)) {
      std::cerr << "\nERROR: At least one of the following options must be used: -p, -l, -a, or -q\n\n";
      std::cerr << desc << std::endl;
      return 1;
    }
  }
  if (vm.count(kModuleLabelOpt)) {
    moduleLabel = vm[kModuleLabelOpt].as<std::string>();
  }
  if (vm.count(kBriefOpt)) {
    brief = true;
  }
  if (vm.count(kPrintOnlyLabelsOpt)) {
    printOnlyLabels = true;
  }
  if (vm.count(kPrintOnlyPluginsOpt)) {
    printOnlyPlugins = true;
  }

  unsigned lineWidth = 80U;

  // This next little bit of code was sent to me.  It gets the number
  // of characters per line that show up on the display terminal in
  // use.  It is not standard C++ code and I do not understand sys/ioctl.h
  // very well.  From what I got via google, it should work on any UNIX platform,
  // which as far as I know is all we need to support.  If this code causes
  // problems, then deleting it and just having the default be 80 should
  // work fine.  Or someone could add the appropriate #ifdef for the
  // OS/platform/compiler where this fails.

  if (isatty(2)) {
#ifdef TIOCGWINSZ
    {
      struct winsize w;
      if (ioctl(2, TIOCGWINSZ, &w) == 0)
      {
        if (w.ws_col > 0)
        lineWidth = w.ws_col;
      }
    }
#else
#ifdef WIOCGETD
    {
      struct uwdata w;
      if (ioctl(2, WIOCGETD, &w) == 0)
      {
        if (w.uw_width > 0)
        lineWidth = w.uw_width / w.uw_hs;
      }
    }
#endif
#endif
  }

  if (vm.count(kLineWidthOpt)) {
    lineWidth = vm[kLineWidthOpt].as<unsigned>();
  }

  // Get the list of plugins from the plugin cache

  edm::ParameterSetDescriptionFillerPluginFactory* factory;
  std::vector<edmplugin::PluginInfo> infos;

  try {

    edmplugin::PluginManager::configure(edmplugin::standard::config());
    typedef edmplugin::PluginManager::CategoryToInfos CatToInfos;
    CatToInfos const& catToInfos = edmplugin::PluginManager::get()->categoryToInfos();
    factory = edm::ParameterSetDescriptionFillerPluginFactory::get();

    CatToInfos::const_iterator itPlugins = catToInfos.find(factory->category());
    if(itPlugins == catToInfos.end() ) {
      return 0;
    }
    infos = itPlugins->second;

  } catch(cms::Exception& e) {
    std::cerr << "The executable \"edmPluginHelp\" failed while retrieving the list of parameter description plugins from the cache.\n"
              << "The following problem occurred:\n" 
              << e.what() << std::endl;
    return 1;
  } catch(const std::exception& e) {
    std::cerr << "The executable \"edmPluginHelp\" failed while retrieving the list of parameter description plugins from the cache.\n"
              << "The following problem occurred:\n" 
              << e.what() << std::endl;
    return 1;
  }

  // Select the plugins that match the library and plugin names if
  // any are specified in the command line arguments

  std::vector<edmplugin::PluginInfo> matchingInfos;

  try {

    std::string previousName;

    edm::for_all(infos, std::bind(&getMatchingPlugins,
                                    std::placeholders::_1,
                                    std::ref(matchingInfos),
                                    std::ref(previousName),
                                    std::cref(library),
                                    std::cref(plugin)));
  }
  catch(cms::Exception& e) {
    std::cerr << "The executable \"edmPluginHelp\" failed while selecting plugins.\n"
              << "The following problem occurred:\n" 
              << e.what() << std::endl;
    return 1;
  }
  catch(const std::exception& e) {
    std::cerr << "The executable \"edmPluginHelp\" failed while selecting plugins.\n"
              << "The following problem occurred:\n" 
              << e.what() << std::endl;
    return 1;
  }

  // For each selected plugin, fill the ParameterSetDescription for all defined
  // module labels and then print out the details of the description.
  try {

    int iPlugin = 0;
 
    edm::for_all(matchingInfos, std::bind(&writeDocForPlugin,
                                            std::placeholders::_1,
                                            factory,
                                            std::cref(moduleLabel),
                                            brief,
                                            printOnlyLabels,
                                            printOnlyPlugins,
                                            lineWidth,
                                            std::ref(iPlugin)));
  } catch(cms::Exception& e) {
    std::cerr << "\nThe executable \"edmPluginHelp\" failed. The following problem occurred:\n" 
              << e.what() << std::endl;
    return 1;
  } catch(const std::exception& e) {
    std::cerr << "\nThe executable \"edmPluginHelp\" failed. The following problem occurred:\n" 
              << e.what() << std::endl;
    return 1;
  }

  return 0;
} catch(cms::Exception const& e) {
  std::cerr << e.explainSelf() << std::endl;
  return 1;
} catch(std::exception const& e) {
  std::cerr << e.what() << std::endl;
  return 1;
}
Esempio n. 2
0
int main(int argc, char* argv[]) {

  int returnCode = 0;
  std::string context;
  bool alwaysAddContext = true;
  boost::shared_ptr<edm::Presence> theMessageServicePresence;
  std::auto_ptr<std::ofstream> jobReportStreamPtr;
  boost::shared_ptr<edm::serviceregistry::ServiceWrapper<edm::JobReport> > jobRep;
  EventProcessorWithSentry proc;

  try {
    try {

      // NOTE: MacOs X has a lower rlimit for opened file descriptor than Linux (256
      // in Snow Leopard vs 512 in SLC5). This is a problem for some of the workflows
      // that open many small root datafiles.  Notice that this is safe to do also
      // for Linux, but we agreed not to change the behavior there for the moment.
      // Also the limits imposed by ulimit are not affected and still apply, if
      // there.
#ifdef __APPLE__
      context = "Setting file descriptor limit";
      struct rlimit limits;
      getrlimit(RLIMIT_NOFILE, &limits);
      limits.rlim_cur = (OPEN_MAX < limits.rlim_max) ? OPEN_MAX : limits.rlim_max;
      setrlimit(RLIMIT_NOFILE, &limits);
#endif

      context = "Initializing plug-in manager";
      edmplugin::PluginManager::configure(edmplugin::standard::config());

      // Decide whether to use the multi-thread or single-thread message logger
      //    (Just walk the command-line arguments, since the boost parser will
      //    be run below and can lead to error messages which should be sent via
      //    the message logger)
      context = "Initializing either multi-threaded or single-threaded message logger";
      bool multiThreadML = false;
      for(int i = 0; i < argc; ++i) {
        if((std::strncmp (argv[i], "-t", 20) == 0) ||
           (std::strncmp (argv[i], "--multithreadML", 20) == 0)) {
          multiThreadML = true;
          break;
        }
      }

      // Load the message service plug-in

      if(multiThreadML) {
        theMessageServicePresence = boost::shared_ptr<edm::Presence>(edm::PresenceFactory::get()->
          makePresence("MessageServicePresence").release());
      }
      else {
        theMessageServicePresence = boost::shared_ptr<edm::Presence>(edm::PresenceFactory::get()->
          makePresence("SingleThreadMSPresence").release());
      }

      context = "Processing command line arguments";
      std::string descString(argv[0]);
      descString += " [options] [--";
      descString += kParameterSetOpt;
      descString += "] config_file \nAllowed options";
      boost::program_options::options_description desc(descString);

      desc.add_options()
        (kHelpCommandOpt, "produce help message")
        (kParameterSetCommandOpt, boost::program_options::value<std::string>(), "configuration file")
        (kJobreportCommandOpt, boost::program_options::value<std::string>(),
                "file name to use for a job report file: default extension is .xml")
        (kEnableJobreportCommandOpt,
                "enable job report files (if any) specified in configuration file")
        (kJobModeCommandOpt, boost::program_options::value<std::string>(),
                "Job Mode for MessageLogger defaults - default mode is grid")
        (kMultiThreadMessageLoggerOpt,
                "MessageLogger handles multiple threads - default is single-thread")
        (kStrictOpt, "strict parsing");

      // anything at the end will be ignored, and sent to python
      boost::program_options::positional_options_description p;
      p.add(kParameterSetOpt, 1).add(kPythonOpt, -1);

      // This --fwk option is not used anymore, but I'm leaving it around as
      // it might be useful again in the future for code development
      // purposes.  We originally used it when implementing the boost
      // state machine code.
      boost::program_options::options_description hidden("hidden options");
      hidden.add_options()("fwk", "For use only by Framework Developers")
        (kPythonOpt, boost::program_options::value< std::vector<std::string> >(),
         "options at the end to be passed to python");

      boost::program_options::options_description all_options("All Options");
      all_options.add(desc).add(hidden);

      boost::program_options::variables_map vm;
      try {
        store(boost::program_options::command_line_parser(argc, argv).options(all_options).positional(p).run(), vm);
        notify(vm);
      }
      catch (boost::program_options::error const& iException) {
        edm::LogAbsolute("CommandLineProcessing") << "cmsRun: Error while trying to process command line arguments:\n"
          << iException.what()
	  << "\nFor usage and an options list, please do 'cmsRun --help'.";
        return edm::errors::CommandLineProcessing;
      }

      if (vm.count(kHelpOpt)) {
        std::cout << desc << std::endl;
        if (!vm.count(kParameterSetOpt)) edm::HaltMessageLogging();
        return 0;
      }

      if (!vm.count(kParameterSetOpt)) {
        edm::LogAbsolute("ConfigFileNotFound") << "cmsRun: No configuration file given.\n"
          << "For usage and an options list, please do 'cmsRun --help'.";
        edm::HaltMessageLogging();
        return edm::errors::ConfigFileNotFound;
      }
      std::string fileName(vm[kParameterSetOpt].as<std::string>());

      if (vm.count(kStrictOpt)) {
        //edm::setStrictParsing(true);
        edm::LogSystem("CommandLineProcessing") << "Strict configuration processing is now done from python";
      }

      context = "Creating the JobReport Service";
      // Decide whether to enable creation of job report xml file
      //  We do this first so any errors will be reported
      std::string jobReportFile;
      if (vm.count("jobreport")) {
        jobReportFile = vm["jobreport"].as<std::string>();
      } else if(vm.count("enablejobreport")) {
        jobReportFile = "FrameworkJobReport.xml";
      }
      jobReportStreamPtr = std::auto_ptr<std::ofstream>(jobReportFile.empty() ? 0 : new std::ofstream(jobReportFile.c_str()));

      //NOTE: JobReport must have a lifetime shorter than jobReportStreamPtr so that when the JobReport destructor
      // is called jobReportStreamPtr is still valid
      std::auto_ptr<edm::JobReport> jobRepPtr(new edm::JobReport(jobReportStreamPtr.get()));
      jobRep.reset(new edm::serviceregistry::ServiceWrapper<edm::JobReport>(jobRepPtr));
      edm::ServiceToken jobReportToken =
        edm::ServiceRegistry::createContaining(jobRep);

      context = "Processing the python configuration file named ";
      context += fileName;
      boost::shared_ptr<edm::ProcessDesc> processDesc;
      try {
        boost::shared_ptr<edm::ParameterSet> parameterSet = edm::readConfig(fileName, argc, argv);
        processDesc.reset(new edm::ProcessDesc(parameterSet));
      }
      catch(cms::Exception& iException) {
        edm::Exception e(edm::errors::ConfigFileReadError, "", iException);
        throw e;
      }

      context = "Initializing default service configurations";
      std::vector<std::string> defaultServices;
      defaultServices.reserve(6);
      defaultServices.push_back("MessageLogger");
      defaultServices.push_back("InitRootHandlers");
#ifdef linux
      defaultServices.push_back("EnableFloatingPointExceptions");
#endif
      defaultServices.push_back("UnixSignalService");
      defaultServices.push_back("AdaptorConfig");
      defaultServices.push_back("SiteLocalConfigService");

      // Default parameters will be used for the default services
      // if they are not overridden from the configuration files.
      processDesc->addServices(defaultServices);

      context = "Setting MessageLogger defaults";
      // Decide what mode of hardcoded MessageLogger defaults to use
      if (vm.count("mode")) {
        std::string jobMode = vm["mode"].as<std::string>();
        edm::MessageDrop::instance()->jobMode = jobMode;
      }

      context = "Constructing the EventProcessor";
      std::auto_ptr<edm::EventProcessor>
          procP(new
                edm::EventProcessor(processDesc, jobReportToken,
                                    edm::serviceregistry::kTokenOverrides));
      EventProcessorWithSentry procTmp(procP);
      proc = procTmp;

      alwaysAddContext = false;
      context = "Calling beginJob";
      proc->beginJob();

      alwaysAddContext = true;
      context = "Calling EventProcessor::forkProcess";
      if (!proc->forkProcess(jobReportFile)) {
        return 0;
      }

      alwaysAddContext = false;
      context = "Calling EventProcessor::runToCompletion (which does almost everything after beginJob and before endJob)";
      proc.on();
      bool onlineStateTransitions = false;
      edm::EventProcessor::StatusCode status = proc->runToCompletion(onlineStateTransitions);
      if (status == edm::EventProcessor::epSignal) {
        returnCode = edm::errors::CaughtSignal;
      }
      proc.off();

      context = "Calling endJob";
      proc->endJob();
    }
    catch (cms::Exception& e) {
      throw;
    }
    // The functions in the following catch blocks throw an edm::Exception
    catch(std::bad_alloc& bda) {
      edm::convertException::badAllocToEDM();
    }
    catch (std::exception& e) {
      edm::convertException::stdToEDM(e);
    }
    catch(std::string& s) {
      edm::convertException::stringToEDM(s);
    }
    catch(char const* c) {
      edm::convertException::charPtrToEDM(c);
    }
    catch (...) {
      edm::convertException::unknownToEDM();
    }
  }
  // All exceptions which are not handled before propagating
  // into main will get caught here.
  catch (cms::Exception& ex) {
    returnCode = ex.returnCode();
    if (!context.empty()) {
      if (alwaysAddContext) {
        ex.addContext(context);
      }
      else if (ex.context().empty()) {
        ex.addContext(context);
      }
    }
    if (!ex.alreadyPrinted()) {
      if (jobRep.get() != 0) {
        edm::printCmsException(ex, &(jobRep->get()), returnCode);
      }
      else {
        edm::printCmsException(ex);
      }
    }
  }
  // Disable Root Error Handler.
  SetErrorHandler(DefaultErrorHandler);
  return returnCode;
}
Esempio n. 3
0
int main(int argc, char *argv[])
{
  try
  {
    edmplugin::PluginManager::configure(edmplugin::standard::config());
  }
  catch (cms::Exception& e)
  {
    edm::LogInfo("DDCompareCPV") << "Attempting to configure the plugin manager. Exception message: " << e.what();
    return 1;
  }
  
    // Process the command line arguments
    std::string descString("DDCompareCPV");
    descString += " [options] configurationFileName1 configurationFileName2 Compares two DDCompactViews\n";
    descString += "Allowed options";
    boost::program_options::options_description desc(descString);   
    desc.add_options()
      ("help,h", "Print this help message")
      ("file1,f", boost::program_options::value<std::string>(), "XML configuration file name. "
       "Default is DetectorDescription/RegressionTest/test/configuration.xml")
      ("file2,g", boost::program_options::value<std::string>(), "XML configuration file name. "
       "Default is DetectorDescription/RegressionTest/test/configuration.xml")
      ("dist-tolerance,t", boost::program_options::value<std::string>(), "Value tolerance for distances (in mm). "
       "Default value 0.0004 (anything larger is an error)")
      ("rot-tolerance,r", boost::program_options::value<std::string>(), "Value tolerance for rotation matrix elements. "
       "Default value is 0.0004 (anything larger is an error)")
      ("spec-tolerance,s", boost::program_options::value<std::string>(), "Value tolerance for rotation matrix elements. "
       "Default value is 0.0004 (anything larger is an error) NOT USED YET")
      ("user-ns,u", "Use the namespaces in each file and do NOT use the filename as namespace. "
       "Default is to use the filename of each file in the configuration.xml file as a filename")
      ("comp-rot,c", "Use the rotation name when comparing rotations. "
       "Default is to use the matrix only and not the name when comparing DDRotations")
      ("continue-on-error,e", "Continue after an error in values. "
       "Default is to stop at the first error. NOT IMPLEMENTED")
      ("attempt-resync,a", "Continue after an error in graph position, attempt to resync. "
       "Default is to stop at the first mis-match of the graph. NOT IMPLEMENTED");
    
    boost::program_options::positional_options_description p;
    p.add("file1", 1);
    p.add("file2", 2);
    
    boost::program_options::variables_map vm;
    try {
      store(boost::program_options::command_line_parser(argc,argv).options(desc).positional(p).run(),vm);
      notify(vm);
    } catch(boost::program_options::error const& iException) {
      std::cerr << "Exception from command line processing: "
                << iException.what() << "\n";
      std::cerr << desc << std::endl;
      return 1;
    }
    if(vm.count("help")) {
      std::cout << desc << std::endl;
      return 0;
    }

    bool fullPath = false;
    std::string configfile("DetectorDescription/RegressionTest/test/configuration.xml");
    std::string configfile2("DetectorDescription/RegressionTest/test/configuration.xml");
    DDCompOptions ddco;
    //    double dtol(0.0004), rottol(0.0004);
    // bool usrns(false), comprot(false);
    bool usrns(false);
    try {
      if (vm.count("file1")) {
	configfile = vm["file1"].as<std::string>();
	if (vm.count("file2")) {
	  configfile2 = vm["file2"].as<std::string>();
	}
      }
      if (vm.count("dist-tolerance"))
	ddco.distTol_ = vm["dist-tolerance"].as<double>();
      if (vm.count("rot-tolerance"))
	ddco.rotTol_ = vm["rot-tolerance"].as<double>();
      if (vm.count("spec-tolerance"))
	ddco.rotTol_ = vm["spec-tolerance"].as<double>();
      if (vm.count("user-ns")) 
	usrns = true;
      if (vm.count("comp-rot")) 
	ddco.compRotName_ = true;
      if (vm.count("continue-on-error")) 
	ddco.contOnError_ = true;
      if (vm.count("attempt-resync"))
	ddco.attResync_ = true;
    }
    catch(boost::exception& e)
    {
      edm::LogInfo("DDCompareCPV") << "Attempting to parse the options. Exception message: " << boost::diagnostic_information(e);
      return 1;
    }

    std::ios_base::fmtflags originalFlags = std::cout.flags();
    
    std::cout << "Settings are: " << std::endl;
    std::cout << "Configuration file 1: " << configfile << std::endl;
    std::cout << "Configuration file 2: " << configfile2 << std::endl;
    std::cout << "Length/distance tolerance: " << ddco.distTol_ << std::endl;
    std::cout << "Rotation matrix element tolerance: " << ddco.rotTol_ << std::endl;
    std::cout << "SpecPar tolerance: " << ddco.specTol_ << std::endl;
    std::cout << "User controlled namespace (both file sets)? " << std::boolalpha << usrns << std::endl;
    std::cout << "Compare Rotation names? " << ddco.compRotName_ << std::endl;
    std::cout << "Continue on error (data mismatch)? " << ddco.contOnError_ << std::endl;
    std::cout << "Attempt resyncronization of disparate graphs? " << ddco.attResync_ << std::endl;

    DDCompactView cpv1;
    DDLParser myP(cpv1);
    myP.getDDLSAX2FileHandler()->setUserNS(usrns);

    /* The configuration file tells the parser what to parse.
       The sequence of files to be parsed does not matter but for one exception:
       XML containing SpecPar-tags must be parsed AFTER all corresponding
       PosPart-tags were parsed. (Simply put all SpecPars-tags into seperate
       files and mention them at end of configuration.xml. Functional SW 
       will not suffer from this restriction).
    */  

    // Use the File-In-Path configuration document provider.
    FIPConfiguration fp(cpv1);
    try
    {
      fp.readConfig(configfile, fullPath);
    }
    catch (cms::Exception& e)
    {
      edm::LogInfo("DDCompareCPV") << "Attempting to read config. Exception message: " << e.what();
      return 1;
    }
    
    std::cout << "FILE 1: " << configfile << std::endl;
    if ( fp.getFileList().size() == 0 ) {
      std::cout << "FILE 1: configuration file has no DDD xml files in it!" << std::endl;
      exit(1);
    }
    int parserResult = myP.parse(fp);
    if (parserResult != 0) {
      std::cout << "FILE 1: problem encountered during parsing. exiting ... " << std::endl;
      exit(1);
    }
    cpv1.lockdown();

    DDCompactView cpv2;
    DDLParser myP2(cpv2);
    myP2.getDDLSAX2FileHandler()->setUserNS(usrns);

    /* The configuration file tells the parser what to parse.
       The sequence of files to be parsed does not matter but for one exception:
       XML containing SpecPar-tags must be parsed AFTER all corresponding
       PosPart-tags were parsed. (Simply put all SpecPars-tags into seperate
       files and mention them at end of configuration.xml. Functional SW 
       will not suffer from this restriction).
    */  

    // Use the File-In-Path configuration document provider.
    FIPConfiguration fp2(cpv2);
    fp2.readConfig(configfile2, fullPath);
    std::cout << "FILE 2: " << configfile2 << std::endl;
    if ( fp2.getFileList().size() == 0 ) {
      std::cout << "FILE 2: configuration file has no DDD xml files in it!" << std::endl;
      exit(1);
    }
    int parserResult2 = myP2.parse(fp2);
    if (parserResult2 != 0) {
      std::cout << "FILE 2: problem encountered during parsing. exiting ... " << std::endl;
      exit(1);
    }
    cpv2.lockdown();

    std::cout << "Parsing completed. Start comparing." << std::endl;

//      DDErrorDetection ed(cpv1);

//      bool noErrors = ed.noErrorsInTheReport(cpv1);
//      if (noErrors && fullPath) {
//        std::cout << "DDCompareCPV did not find any errors and is finished." << std::endl;
//      }
//     else {
//       ed.report(cpv1, std::cout);
//       if (!noErrors) {
//         return 1;
//       }
//     }

    DDCompareCPV ddccpv(ddco);
    bool graphmatch = ddccpv(cpv1, cpv2);

    if (graphmatch) {
      std::cout << "DDCompactView graphs match" << std::endl;
    } else {
      std::cout << "DDCompactView graphs do NOT match" << std::endl;
    }

    // Now set everything back to defaults
    std::cout.flags( originalFlags );

    return 0;
}
Esempio n. 4
0
int main(int argc, char* argv[])
{
// NOTE: MacOs X has a lower rlimit for opened file descriptor than Linux (256
// in Snow Leopard vs 512 in SLC5). This is a problem for some of the workflows
// that open many small root datafiles.  Notice that this is safe to do also
// for Linux, but we agreed not to change the behavior there for the moment.
// Also the limits imposed by ulimit are not affected and still apply, if
// there.
#ifdef __APPLE__
  struct rlimit limits;
  getrlimit(RLIMIT_NOFILE, &limits);
  limits.rlim_cur = (OPEN_MAX < limits.rlim_max) ? OPEN_MAX : limits.rlim_max;
  setrlimit(RLIMIT_NOFILE, &limits);
#endif

  // We must initialize the plug-in manager first
  try {
    edmplugin::PluginManager::configure(edmplugin::standard::config());
  } catch(const std::exception& e) {
    std::cerr << e.what() << std::endl;
    return 1;
  }
  
  // Decide whether to use the multi-thread or single-thread message logger
  //    (Just walk the command-line arguments, since the boost parser will
  //    be run below and can lead to error messages which should be sent via
  //    the message logger)
  bool multiThreadML = false;
  for (int i=0; i<argc; ++i) {
    if ( (std::strncmp (argv[i],"-t", 20) == 0) ||
         (std::strncmp (argv[i],"--multithreadML", 20) == 0) )
    { multiThreadML = true; 
      break; 
    }
  } 
 
  // TEMPORARY -- REMOVE AT ONCE!!!!!
  // if ( multiThreadML ) std::cerr << "\n\n multiThreadML \n\n";
  
  // Load the message service plug-in
  boost::shared_ptr<edm::Presence> theMessageServicePresence;

  if (multiThreadML)
  {
    try {
      theMessageServicePresence = boost::shared_ptr<edm::Presence>(edm::PresenceFactory::get()->
          makePresence("MessageServicePresence").release());
    } catch(cms::Exception& e) {
      std::cerr << e.what() << std::endl;
      return 1;
    }
  } else {
    try {
      theMessageServicePresence = boost::shared_ptr<edm::Presence>(edm::PresenceFactory::get()->
          makePresence("SingleThreadMSPresence").release());
    } catch(cms::Exception& e) {
      std::cerr << e.what() << std::endl;
      return 1;
    }
  }
  
  //
  // Specify default services to be enabled with their default parameters.
  // 
  // The parameters for these can be overridden from the configuration files.
  std::vector<std::string> defaultServices;
  defaultServices.reserve(6);
  defaultServices.push_back("MessageLogger");
  defaultServices.push_back("InitRootHandlers");
#ifdef linux
  defaultServices.push_back("EnableFloatingPointExceptions");
#endif
  defaultServices.push_back("UnixSignalService");
  defaultServices.push_back("AdaptorConfig");
  defaultServices.push_back("SiteLocalConfigService");

  // These cannot be overridden from the configuration files.
  // An exception will be thrown if any of these is specified there.
  std::vector<std::string> forcedServices;
  forcedServices.reserve(1);
  forcedServices.push_back("JobReportService");

  std::string descString(argv[0]);
  descString += " [options] [--";
  descString += kParameterSetOpt;
  descString += "] config_file \nAllowed options";
  boost::program_options::options_description desc(descString);
  
  desc.add_options()
    (kHelpCommandOpt, "produce help message")
    (kParameterSetCommandOpt, boost::program_options::value<std::string>(), "configuration file")
    (kJobreportCommandOpt, boost::program_options::value<std::string>(),
    	"file name to use for a job report file: default extension is .xml")
    (kEnableJobreportCommandOpt, 
    	"enable job report files (if any) specified in configuration file")
    (kJobModeCommandOpt, boost::program_options::value<std::string>(),
    	"Job Mode for MessageLogger defaults - default mode is grid")
    (kMultiThreadMessageLoggerOpt,
    	"MessageLogger handles multiple threads - default is single-thread")
    (kStrictOpt, "strict parsing");

  // anything at the end will be ignored, and sent to python
  boost::program_options::positional_options_description p;
  p.add(kParameterSetOpt, 1).add(kPythonOpt, -1);

  // This --fwk option is not used anymore, but I'm leaving it around as
  // it might be useful again in the future for code development
  // purposes.  We originally used it when implementing the boost
  // state machine code.
  boost::program_options::options_description hidden("hidden options");
  hidden.add_options()("fwk", "For use only by Framework Developers")
    (kPythonOpt, boost::program_options::value< std::vector<std::string> >(), 
     "options at the end to be passed to python");
  
  boost::program_options::options_description all_options("All Options");
  all_options.add(desc).add(hidden);

  boost::program_options::variables_map vm;
  try {
    store(boost::program_options::command_line_parser(argc,argv).options(all_options).positional(p).run(),vm);
    notify(vm);
  } catch(boost::program_options::error const& iException) {
    edm::LogError("FwkJob") << "Exception from command line processing: " << iException.what();
    edm::LogSystem("CommandLineProcessing") << "Exception from command line processing: " << iException.what() << "\n";
    return 7000;
  }
    
  if(vm.count(kHelpOpt)) {
    std::cout << desc <<std::endl;
    if(!vm.count(kParameterSetOpt)) edm::HaltMessageLogging();
    return 0;
  }
  
  if(!vm.count(kParameterSetOpt)) {
    std::string shortDesc("ConfigFileNotFound");
    std::ostringstream longDesc;
    longDesc << "cmsRun: No configuration file given.\n"
	     << "For usage and an options list, please do '"
	     << argv[0]
	     <<  " --"
	     << kHelpOpt
	     << "'.";
    int exitCode = 7001;
    edm::LogAbsolute(shortDesc) << longDesc.str() << "\n";
    edm::HaltMessageLogging();
    return exitCode;
  }

#ifdef CHANGED_FROM
  if(!vm.count(kParameterSetOpt)) {
    std::string shortDesc("ConfigFileNotFound");
    std::ostringstream longDesc;
    longDesc << "No configuration file given \n"
	     <<" please do '"
	     << argv[0]
	     <<  " --"
	     << kHelpOpt
	     << "'.";
    int exitCode = 7001;
    jobRep->reportError(shortDesc, longDesc.str(), exitCode);
    edm::LogSystem(shortDesc) << longDesc.str() << "\n";
    return exitCode;
  }
#endif

  //
  // Decide whether to enable creation of job report xml file 
  //  We do this first so any errors will be reported
  // 
  std::string jobReportFile;
  if (vm.count("jobreport")) {
    jobReportFile = vm["jobreport"].as<std::string>();
  } else if (vm.count("enablejobreport")) {
    jobReportFile = "FrameworkJobReport.xml";
  } 
  std::auto_ptr<std::ofstream> jobReportStreamPtr = std::auto_ptr<std::ofstream>(jobReportFile.empty() ? 0 : new std::ofstream(jobReportFile.c_str()));
  //
  // Make JobReport Service up front
  // 
  //NOTE: JobReport must have a lifetime shorter than jobReportStreamPtr so that when the JobReport destructor
  // is called jobReportStreamPtr is still valid
  std::auto_ptr<edm::JobReport> jobRepPtr(new edm::JobReport(jobReportStreamPtr.get()));  
  boost::shared_ptr<edm::serviceregistry::ServiceWrapper<edm::JobReport> > jobRep( new edm::serviceregistry::ServiceWrapper<edm::JobReport>(jobRepPtr) );
  edm::ServiceToken jobReportToken = 
    edm::ServiceRegistry::createContaining(jobRep);
  
  std::string fileName(vm[kParameterSetOpt].as<std::string>());
  boost::shared_ptr<edm::ProcessDesc> processDesc;
  try {
    processDesc = edm::readConfig(fileName, argc, argv);
  }
  catch(cms::Exception& iException) {
    std::string shortDesc("ConfigFileReadError");
    std::ostringstream longDesc;
    longDesc << "Problem with configuration file " << fileName
             <<  "\n" << iException.what();
    int exitCode = 7002;
    jobRep->get().reportError(shortDesc, longDesc.str(), exitCode);
    edm::LogSystem(shortDesc) << longDesc.str() << "\n";
    return exitCode;
  }

  processDesc->addServices(defaultServices, forcedServices);
  //
  // Decide what mode of hardcoded MessageLogger defaults to use 
  // 
  if (vm.count("mode")) {
    std::string jobMode = vm["mode"].as<std::string>();
    edm::MessageDrop::instance()->jobMode = jobMode;
  }  

  if(vm.count(kStrictOpt))
  {
    //edm::setStrictParsing(true);
    edm::LogSystem("CommandLineProcessing") << "Strict configuration processing is now done from python";
  }
 
  // Now create and configure the services
  //
  EventProcessorWithSentry proc;
  int rc = -1; // we should never return this value!
  try {
    std::auto_ptr<edm::EventProcessor> 
	procP(new 
	      edm::EventProcessor(processDesc, jobReportToken, 
			     edm::serviceregistry::kTokenOverrides));
    EventProcessorWithSentry procTmp(procP);
    proc = procTmp;
    proc->beginJob();
    if(!proc->forkProcess(jobReportFile)) {
      return 0;
    }
    proc.on();
    bool onlineStateTransitions = false;
    proc->runToCompletion(onlineStateTransitions);
    proc.off();
    proc->endJob();
    rc = 0;
    // Disable Root Error Handler so we do not throw because of ROOT errors.
    edm::ServiceToken token = proc->getToken();
    edm::ServiceRegistry::Operate operate(token);
    edm::Service<edm::RootHandlers> rootHandler;
    rootHandler->disableErrorHandler();
  }
  catch (edm::Exception& e) {
    rc = e.returnCode();
    edm::printCmsException(e, kProgramName, &(jobRep->get()), rc);
  }
  catch (cms::Exception& e) {
    rc = 8001;
    edm::printCmsException(e, kProgramName, &(jobRep->get()), rc);
  }
  catch(std::bad_alloc& bda) {
    rc = 8004;
    edm::printBadAllocException(kProgramName, &(jobRep->get()), rc);
  }
  catch (std::exception& e) {
    rc = 8002;
    edm::printStdException(e, kProgramName, &(jobRep->get()), rc);
  }
  catch (...) {
    rc = 8003;
    edm::printUnknownException(kProgramName, &(jobRep->get()), rc);
  }
  // Disable Root Error Handler again, just in case an exception
  // caused the above disabling of the handler to be bypassed.
  SetErrorHandler(DefaultErrorHandler);
  return rc;
}