CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/FWCore/ParameterSet/src/ORGroupDescription.cc

Go to the documentation of this file.
00001 
00002 #include "FWCore/ParameterSet/interface/ORGroupDescription.h"
00003 #include "FWCore/Utilities/interface/EDMException.h"
00004 #include "FWCore/ParameterSet/interface/DocFormatHelper.h"
00005 
00006 #include <algorithm>
00007 #include <sstream>
00008 #include <ostream>
00009 #include <iomanip>
00010 
00011 namespace edm {
00012 
00013   ORGroupDescription::
00014   ORGroupDescription(ParameterDescriptionNode const& node_left,
00015                      ParameterDescriptionNode const& node_right) :
00016     node_left_(node_left.clone()),
00017     node_right_(node_right.clone()) {
00018   }
00019 
00020   ORGroupDescription::
00021   ORGroupDescription(std::auto_ptr<ParameterDescriptionNode> node_left,
00022                      ParameterDescriptionNode const& node_right) :
00023     node_left_(node_left),
00024     node_right_(node_right.clone()) {
00025   }
00026 
00027   ORGroupDescription::
00028   ORGroupDescription(ParameterDescriptionNode const& node_left,
00029                      std::auto_ptr<ParameterDescriptionNode> node_right) :
00030     node_left_(node_left.clone()),
00031     node_right_(node_right) {
00032   }
00033 
00034   ORGroupDescription::
00035   ORGroupDescription(std::auto_ptr<ParameterDescriptionNode> node_left,
00036                      std::auto_ptr<ParameterDescriptionNode> node_right) :
00037     node_left_(node_left),
00038     node_right_(node_right) {
00039   }
00040 
00041   void
00042   ORGroupDescription::
00043   checkAndGetLabelsAndTypes_(std::set<std::string> & usedLabels,
00044                              std::set<ParameterTypes> & parameterTypes,
00045                              std::set<ParameterTypes> & wildcardTypes) const {
00046 
00047     std::set<std::string> labelsLeft;
00048     std::set<ParameterTypes> parameterTypesLeft;
00049     std::set<ParameterTypes> wildcardTypesLeft;
00050     node_left_->checkAndGetLabelsAndTypes(labelsLeft, parameterTypesLeft, wildcardTypesLeft);
00051 
00052     std::set<std::string> labelsRight;
00053     std::set<ParameterTypes> parameterTypesRight;
00054     std::set<ParameterTypes> wildcardTypesRight;
00055     node_right_->checkAndGetLabelsAndTypes(labelsRight, parameterTypesRight, wildcardTypesRight);
00056 
00057     throwIfDuplicateLabels(labelsLeft, labelsRight);
00058     throwIfDuplicateTypes(wildcardTypesLeft, parameterTypesRight);
00059     throwIfDuplicateTypes(wildcardTypesRight, parameterTypesLeft);
00060 
00061     usedLabels.insert(labelsLeft.begin(), labelsLeft.end());
00062     usedLabels.insert(labelsRight.begin(), labelsRight.end());
00063 
00064     parameterTypes.insert(parameterTypesRight.begin(), parameterTypesRight.end());
00065     parameterTypes.insert(parameterTypesLeft.begin(), parameterTypesLeft.end());
00066 
00067     wildcardTypes.insert(wildcardTypesRight.begin(), wildcardTypesRight.end());
00068     wildcardTypes.insert(wildcardTypesLeft.begin(), wildcardTypesLeft.end());
00069   }
00070 
00071   void
00072   ORGroupDescription::
00073   validate_(ParameterSet & pset,
00074             std::set<std::string> & validatedLabels,
00075             bool optional) const {
00076 
00077     bool leftExists = node_left_->exists(pset);
00078     bool rightExists = node_right_->exists(pset);
00079 
00080     if (leftExists || rightExists) {
00081       if (leftExists) node_left_->validate(pset, validatedLabels, false);
00082       if (rightExists) node_right_->validate(pset, validatedLabels, false);
00083       return;
00084     }
00085 
00086     if (optional) return;
00087 
00088     node_left_->validate(pset, validatedLabels, false);
00089   }
00090 
00091   void
00092   ORGroupDescription::
00093   writeCfi_(std::ostream & os,
00094             bool & startWithComma,
00095             int indentation,
00096             bool & wroteSomething) const {
00097     node_left_->writeCfi(os, startWithComma, indentation, wroteSomething);
00098   }
00099 
00100   void
00101   ORGroupDescription::
00102   print_(std::ostream & os,
00103          bool optional,
00104          bool writeToCfi,
00105          DocFormatHelper & dfh) {
00106 
00107     if (dfh.parent() == DocFormatHelper::OR) {
00108       dfh.decrementCounter();
00109       node_left_->print(os, false, true, dfh);
00110       node_right_->print(os, false, true, dfh);
00111       return;
00112     }
00113 
00114     if (dfh.pass() == 1) {
00115 
00116       dfh.indent(os);
00117       os << "OR group:";
00118 
00119       if (dfh.brief()) {
00120 
00121         if (optional)  os << " optional";
00122 
00123         if (!writeToCfi) os << " (do not write to cfi)";
00124 
00125         os << " see Section " << dfh.section() << "." << dfh.counter() << "\n";
00126       }
00127       // not brief
00128       else {
00129 
00130         os << "\n";
00131         dfh.indent2(os);
00132 
00133         if (optional)  os << "optional";
00134         if (!writeToCfi) os << " (do not write to cfi)";
00135         if (optional || !writeToCfi) {
00136           os << "\n";
00137           dfh.indent2(os);
00138         }
00139 
00140         os << "see Section " << dfh.section() << "." << dfh.counter() << "\n";
00141 
00142         if (!comment().empty()) {
00143           DocFormatHelper::wrapAndPrintText(os,
00144                                             comment(),
00145                                             dfh.startColumn2(),
00146                                             dfh.commentWidth());
00147         }
00148         os << "\n";
00149       }
00150     }
00151   }
00152 
00153   void
00154   ORGroupDescription::
00155   printNestedContent_(std::ostream & os,
00156                       bool optional,
00157                       DocFormatHelper & dfh) {
00158 
00159     if (dfh.parent() == DocFormatHelper::OR) {
00160       dfh.decrementCounter();
00161       node_left_->printNestedContent(os, false, dfh);
00162       node_right_->printNestedContent(os, false, dfh);
00163       return;
00164     }
00165 
00166     int indentation = dfh.indentation();
00167     if (dfh.parent() != DocFormatHelper::TOP) {
00168       indentation -= DocFormatHelper::offsetSectionContent();
00169     }
00170 
00171     std::stringstream ss;
00172     ss << dfh.section() << "." << dfh.counter();
00173     std::string newSection = ss.str();
00174 
00175     printSpaces(os, indentation);
00176     os << "Section " << newSection
00177        << " OR group description:\n";
00178     printSpaces(os, indentation);
00179     if (optional) {
00180       // An optional OR group is kind of pointless, it would be
00181       // easier just make the parameters be independent optional parameters
00182       // I only allow it to make the behavior analogous to the other groups
00183       os << "This optional OR group requires at least one or none of the following to be in the PSet\n";
00184     }
00185     else {
00186       os << "This OR group requires at least one of the following to be in the PSet\n";
00187     }
00188     if (!dfh.brief()) os << "\n";
00189 
00190     DocFormatHelper new_dfh(dfh);
00191     new_dfh.init();
00192     new_dfh.setSection(newSection);
00193     new_dfh.setIndentation(indentation + DocFormatHelper::offsetSectionContent());
00194     new_dfh.setParent(DocFormatHelper::OR);
00195 
00196     node_left_->print(os, false, true, new_dfh);
00197     node_right_->print(os, false, true, new_dfh);
00198 
00199     new_dfh.setPass(1);
00200     new_dfh.setCounter(0);
00201 
00202     node_left_->print(os, false, true, new_dfh);
00203     node_right_->print(os, false, true, new_dfh);
00204 
00205     new_dfh.setPass(2);
00206     new_dfh.setCounter(0);
00207 
00208     node_left_->printNestedContent(os, false, new_dfh);
00209     node_right_->printNestedContent(os, false, new_dfh);
00210   }
00211 
00212   bool
00213   ORGroupDescription::
00214   exists_(ParameterSet const& pset) const {
00215     return node_left_->exists(pset) ||
00216            node_right_->exists(pset);
00217   }
00218 
00219   bool
00220   ORGroupDescription::
00221   partiallyExists_(ParameterSet const& pset) const {
00222     return exists(pset);
00223   }
00224 
00225   int
00226   ORGroupDescription::
00227   howManyXORSubNodesExist_(ParameterSet const& pset) const {
00228     return exists(pset) ? 1 : 0;
00229   }
00230 
00231   void
00232   ORGroupDescription::
00233   throwIfDuplicateLabels(std::set<std::string> const& labelsLeft,
00234                          std::set<std::string> const& labelsRight) const {
00235 
00236     std::set<std::string> duplicateLabels;
00237     std::insert_iterator<std::set<std::string> > insertIter(duplicateLabels, duplicateLabels.begin());
00238     std::set_intersection(labelsLeft.begin(), labelsLeft.end(),
00239                           labelsRight.begin(), labelsRight.end(),
00240                           insertIter);
00241     if (!duplicateLabels.empty()) {
00242       std::stringstream ss;
00243       for (std::set<std::string>::const_iterator iter = duplicateLabels.begin(),
00244                                                  iEnd = duplicateLabels.end();
00245            iter != iEnd;
00246            ++iter) {
00247         ss << " \"" << *iter <<  "\"\n";
00248       }
00249       throw edm::Exception(errors::LogicError)
00250         << "Labels used in a node of a ParameterSetDescription\n"
00251         << "\"or\" expression must be not be the same as labels used\n"
00252         << "in other nodes of the expression.  The following duplicate\n"
00253         << "labels were detected:\n"
00254         << ss.str()
00255         << "\n";
00256     }
00257   }
00258 
00259   void
00260   ORGroupDescription::
00261   throwIfDuplicateTypes(std::set<ParameterTypes> const& types1,
00262                         std::set<ParameterTypes> const& types2) const
00263   {
00264     if (!types1.empty()) {
00265       std::set<ParameterTypes> duplicateTypes;
00266       std::insert_iterator<std::set<ParameterTypes> > insertIter(duplicateTypes, duplicateTypes.begin());
00267       std::set_intersection(types1.begin(), types1.end(),
00268                             types2.begin(), types2.end(),
00269                             insertIter);
00270       if (!duplicateTypes.empty()) {
00271         std::stringstream ss;
00272         for (std::set<ParameterTypes>::const_iterator iter = duplicateTypes.begin(),
00273                                                       iEnd = duplicateTypes.end();
00274              iter != iEnd;
00275              ++iter) {
00276           ss << " \"" << parameterTypeEnumToString(*iter) <<  "\"\n";
00277         }
00278         throw edm::Exception(errors::LogicError)
00279           << "Types used for wildcards in a node of a ParameterSetDescription\n"
00280           << "\"or\" expression must be different from types used for other parameters\n"
00281           << "in other nodes.  The following duplicate types were detected:\n"
00282           << ss.str()
00283           << "\n";
00284       }
00285     }
00286   }
00287 }