CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 
00002 #include "FWCore/ParameterSet/interface/ANDGroupDescription.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   ANDGroupDescription::
00014   ANDGroupDescription(ParameterDescriptionNode const& node_left,
00015                       ParameterDescriptionNode const& node_right) :
00016     node_left_(node_left.clone()),
00017     node_right_(node_right.clone()) {
00018   }
00019 
00020   ANDGroupDescription::
00021   ANDGroupDescription(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   ANDGroupDescription::
00028   ANDGroupDescription(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   ANDGroupDescription::
00035   ANDGroupDescription(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   ANDGroupDescription::
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   ANDGroupDescription::
00073   validate_(ParameterSet & pset,
00074             std::set<std::string> & validatedLabels,
00075             bool optional) const {
00076     if (partiallyExists(pset) || !optional) {
00077       node_left_->validate(pset, validatedLabels, false);
00078       node_right_->validate(pset, validatedLabels, false);
00079     }
00080   }
00081 
00082   void
00083   ANDGroupDescription::
00084   writeCfi_(std::ostream & os,
00085             bool & startWithComma,
00086             int indentation,
00087             bool & wroteSomething) const {
00088     node_left_->writeCfi(os, startWithComma, indentation, wroteSomething);
00089     node_right_->writeCfi(os, startWithComma, indentation, wroteSomething);
00090   }
00091 
00092   void
00093   ANDGroupDescription::
00094   print_(std::ostream & os,
00095          bool optional,
00096          bool writeToCfi,
00097          DocFormatHelper & dfh) {
00098 
00099     if (dfh.parent() == DocFormatHelper::AND) {
00100       dfh.decrementCounter();
00101       node_left_->print(os, false, true, dfh);
00102       node_right_->print(os, false, true, dfh);
00103       return;
00104     }
00105 
00106     if (dfh.pass() == 1) {
00107 
00108       dfh.indent(os);
00109       os << "AND group:";
00110 
00111       if (dfh.brief()) {
00112 
00113         if (optional)  os << " optional";
00114 
00115         if (!writeToCfi) os << " (do not write to cfi)";
00116 
00117         os << " see Section " << dfh.section() << "." << dfh.counter() << "\n";
00118       }
00119       // not brief
00120       else {
00121 
00122         os << "\n";
00123         dfh.indent2(os);
00124 
00125         if (optional)  os << "optional";
00126         if (!writeToCfi) os << " (do not write to cfi)";
00127         if (optional || !writeToCfi) {
00128           os << "\n";
00129           dfh.indent2(os);
00130         }
00131 
00132         os << "see Section " << dfh.section() << "." << dfh.counter() << "\n";
00133 
00134         if (!comment().empty()) {
00135           DocFormatHelper::wrapAndPrintText(os,
00136                                             comment(),
00137                                             dfh.startColumn2(),
00138                                             dfh.commentWidth());
00139         }
00140         os << "\n";
00141       }
00142     }
00143   }
00144 
00145   void
00146   ANDGroupDescription::
00147   printNestedContent_(std::ostream & os,
00148                       bool optional,
00149                       DocFormatHelper & dfh) {
00150 
00151     if (dfh.parent() == DocFormatHelper::AND) {
00152       dfh.decrementCounter();
00153       node_left_->printNestedContent(os, false, dfh);
00154       node_right_->printNestedContent(os, false, dfh);
00155       return;
00156     }
00157 
00158     int indentation = dfh.indentation();
00159     if (dfh.parent() != DocFormatHelper::TOP) {
00160       indentation -= DocFormatHelper::offsetSectionContent();
00161     }
00162 
00163     std::stringstream ss;
00164     ss << dfh.section() << "." << dfh.counter();
00165     std::string newSection = ss.str();
00166 
00167     printSpaces(os, indentation);
00168     os << "Section " << newSection
00169        << " AND group description:\n";
00170     printSpaces(os, indentation);
00171     if (optional) {
00172       os << "This optional AND group requires all or none of the following to be in the PSet\n";
00173     }
00174     else {
00175       os << "This AND group requires all of the following to be in the PSet\n";
00176     }
00177     if (!dfh.brief()) os << "\n";
00178 
00179     DocFormatHelper new_dfh(dfh);
00180     new_dfh.init();
00181     new_dfh.setSection(newSection);
00182     new_dfh.setIndentation(indentation + DocFormatHelper::offsetSectionContent());
00183     new_dfh.setParent(DocFormatHelper::AND);
00184 
00185     node_left_->print(os, false, true, new_dfh);
00186     node_right_->print(os, false, true, new_dfh);
00187 
00188     new_dfh.setPass(1);
00189     new_dfh.setCounter(0);
00190 
00191     node_left_->print(os, false, true, new_dfh);
00192     node_right_->print(os, false, true, new_dfh);
00193 
00194     new_dfh.setPass(2);
00195     new_dfh.setCounter(0);
00196 
00197     node_left_->printNestedContent(os, false, new_dfh);
00198     node_right_->printNestedContent(os, false, new_dfh);
00199   }
00200 
00201   bool
00202   ANDGroupDescription::
00203   exists_(ParameterSet const& pset) const {
00204     return node_left_->exists(pset) && node_right_->exists(pset);
00205   }
00206 
00207   bool
00208   ANDGroupDescription::
00209   partiallyExists_(ParameterSet const& pset) const {
00210     return node_left_->partiallyExists(pset) || node_right_->partiallyExists(pset);
00211   }
00212 
00213   int
00214   ANDGroupDescription::
00215   howManyXORSubNodesExist_(ParameterSet const& pset) const {
00216     return exists(pset) ? 1 : 0; 
00217   }
00218 
00219   void
00220   ANDGroupDescription::
00221   throwIfDuplicateLabels(std::set<std::string> const& labelsLeft,
00222                          std::set<std::string> const& labelsRight) const {
00223 
00224     std::set<std::string> duplicateLabels;
00225     std::insert_iterator<std::set<std::string> > insertIter(duplicateLabels, duplicateLabels.begin());
00226     std::set_intersection(labelsLeft.begin(), labelsLeft.end(),
00227                           labelsRight.begin(), labelsRight.end(),
00228                           insertIter);
00229     if (!duplicateLabels.empty()) {
00230       std::stringstream ss;
00231       for (std::set<std::string>::const_iterator iter = duplicateLabels.begin(),
00232                                                  iEnd = duplicateLabels.end();
00233            iter != iEnd;
00234            ++iter) {
00235         ss << " \"" << *iter <<  "\"\n";
00236       }
00237       throw edm::Exception(errors::LogicError)
00238         << "Labels used in different nodes of a ParameterSetDescription\n"
00239         << "\"and\" expression must be unique.  The following duplicate\n"
00240         << "labels were detected:\n"
00241         << ss.str()
00242         << "\n";
00243     }
00244   }
00245 
00246   void
00247   ANDGroupDescription::
00248   throwIfDuplicateTypes(std::set<ParameterTypes> const& types1,
00249                         std::set<ParameterTypes> const& types2) const
00250   {
00251     if (!types1.empty()) {
00252       std::set<ParameterTypes> duplicateTypes;
00253       std::insert_iterator<std::set<ParameterTypes> > insertIter(duplicateTypes, duplicateTypes.begin());
00254       std::set_intersection(types1.begin(), types1.end(),
00255                             types2.begin(), types2.end(),
00256                             insertIter);
00257       if (!duplicateTypes.empty()) {
00258         std::stringstream ss;
00259         for (std::set<ParameterTypes>::const_iterator iter = duplicateTypes.begin(),
00260                                                       iEnd = duplicateTypes.end();
00261              iter != iEnd;
00262              ++iter) {
00263           ss << " \"" << parameterTypeEnumToString(*iter) <<  "\"\n";
00264         }
00265         throw edm::Exception(errors::LogicError)
00266           << "Types used for wildcards in different nodes of a ParameterSetDescription\n"
00267           << "\"and\" expression must be different from types used for other parameters.\n"
00268           << "The following duplicate types were detected:\n"
00269           << ss.str()
00270           << "\n";
00271       }
00272     }
00273   }
00274 }