00001
00002 #include "FWCore/ParameterSet/interface/IfExistsDescription.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 IfExistsDescription::
00014 IfExistsDescription(ParameterDescriptionNode const& node_left,
00015 ParameterDescriptionNode const& node_right) :
00016 node_left_(node_left.clone()),
00017 node_right_(node_right.clone()) {
00018 }
00019
00020 IfExistsDescription::
00021 IfExistsDescription(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 IfExistsDescription::
00028 IfExistsDescription(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 IfExistsDescription::
00035 IfExistsDescription(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 IfExistsDescription::
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 IfExistsDescription::
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 return;
00082 }
00083 else if (leftExists && rightExists) {
00084 node_left_->validate(pset, validatedLabels, false);
00085 node_right_->validate(pset, validatedLabels, false);
00086 }
00087 else if (leftExists && !rightExists) {
00088 node_left_->validate(pset, validatedLabels, false);
00089 if (!optional) node_right_->validate(pset, validatedLabels, false);
00090 }
00091 else if (!leftExists && rightExists) {
00092 node_left_->validate(pset, validatedLabels, false);
00093 node_right_->validate(pset, validatedLabels, false);
00094 }
00095 }
00096
00097 void
00098 IfExistsDescription::
00099 writeCfi_(std::ostream & os,
00100 bool & startWithComma,
00101 int indentation,
00102 bool & wroteSomething) const {
00103 node_left_->writeCfi(os, startWithComma, indentation, wroteSomething);
00104 node_right_->writeCfi(os, startWithComma, indentation, wroteSomething);
00105 }
00106
00107 void
00108 IfExistsDescription::
00109 print_(std::ostream & os,
00110 bool optional,
00111 bool writeToCfi,
00112 DocFormatHelper & dfh) {
00113
00114 if (dfh.pass() == 1) {
00115
00116 dfh.indent(os);
00117 os << "IfExists pair:";
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
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 IfExistsDescription::
00155 printNestedContent_(std::ostream & os,
00156 bool optional,
00157 DocFormatHelper & dfh) {
00158
00159 int indentation = dfh.indentation();
00160 if (dfh.parent() != DocFormatHelper::TOP) {
00161 indentation -= DocFormatHelper::offsetSectionContent();
00162 }
00163
00164 std::stringstream ss;
00165 ss << dfh.section() << "." << dfh.counter();
00166 std::string newSection = ss.str();
00167
00168 printSpaces(os, indentation);
00169 os << "Section " << newSection;
00170 if (optional) os << " optional";
00171 os << " IfExists pair description:\n";
00172 printSpaces(os, indentation);
00173 if (optional) {
00174 os << "If the first parameter exists, then the second is allowed to exist\n";
00175 }
00176 else {
00177 os << "If the first parameter exists, then the second is required to exist\n";
00178 }
00179 if (!dfh.brief()) os << "\n";
00180
00181 DocFormatHelper new_dfh(dfh);
00182 new_dfh.init();
00183 new_dfh.setSection(newSection);
00184 new_dfh.setIndentation(indentation + DocFormatHelper::offsetSectionContent());
00185 new_dfh.setParent(DocFormatHelper::OTHER);
00186
00187 node_left_->print(os, false, true, new_dfh);
00188 node_right_->print(os, false, true, new_dfh);
00189
00190 new_dfh.setPass(1);
00191 new_dfh.setCounter(0);
00192
00193 node_left_->print(os, false, true, new_dfh);
00194 node_right_->print(os, false, true, new_dfh);
00195
00196 new_dfh.setPass(2);
00197 new_dfh.setCounter(0);
00198
00199 node_left_->printNestedContent(os, false, new_dfh);
00200 node_right_->printNestedContent(os, false , new_dfh);
00201 }
00202
00203 bool
00204 IfExistsDescription::
00205 exists_(ParameterSet const& pset) const {
00206 bool leftExists = node_left_->exists(pset);
00207 bool rightExists = node_right_->exists(pset);
00208
00209 if (leftExists && rightExists) return true;
00210 else if (!leftExists && !rightExists) return true;
00211 return false;
00212 }
00213
00214 bool
00215 IfExistsDescription::
00216 partiallyExists_(ParameterSet const& pset) const {
00217 return exists(pset);
00218 }
00219
00220 int
00221 IfExistsDescription::
00222 howManyXORSubNodesExist_(ParameterSet const& pset) const {
00223 return exists(pset) ? 1 : 0;
00224 }
00225
00226 void
00227 IfExistsDescription::
00228 throwIfDuplicateLabels(std::set<std::string> const& labelsLeft,
00229 std::set<std::string> const& labelsRight) const {
00230
00231 std::set<std::string> duplicateLabels;
00232 std::insert_iterator<std::set<std::string> > insertIter(duplicateLabels, duplicateLabels.begin());
00233 std::set_intersection(labelsLeft.begin(), labelsLeft.end(),
00234 labelsRight.begin(), labelsRight.end(),
00235 insertIter);
00236 if (!duplicateLabels.empty()) {
00237 std::stringstream ss;
00238 for (std::set<std::string>::const_iterator iter = duplicateLabels.begin(),
00239 iEnd = duplicateLabels.end();
00240 iter != iEnd;
00241 ++iter) {
00242 ss << " \"" << *iter << "\"\n";
00243 }
00244 throw edm::Exception(errors::LogicError)
00245 << "Labels used in a node of a ParameterSetDescription\n"
00246 << "\"ifExists\" expression must be not be the same as labels used\n"
00247 << "in other nodes of the expression. The following duplicate\n"
00248 << "labels were detected:\n"
00249 << ss.str()
00250 << "\n";
00251 }
00252 }
00253
00254 void
00255 IfExistsDescription::
00256 throwIfDuplicateTypes(std::set<ParameterTypes> const& types1,
00257 std::set<ParameterTypes> const& types2) const
00258 {
00259 if (!types1.empty()) {
00260 std::set<ParameterTypes> duplicateTypes;
00261 std::insert_iterator<std::set<ParameterTypes> > insertIter(duplicateTypes, duplicateTypes.begin());
00262 std::set_intersection(types1.begin(), types1.end(),
00263 types2.begin(), types2.end(),
00264 insertIter);
00265 if (!duplicateTypes.empty()) {
00266 std::stringstream ss;
00267 for (std::set<ParameterTypes>::const_iterator iter = duplicateTypes.begin(),
00268 iEnd = duplicateTypes.end();
00269 iter != iEnd;
00270 ++iter) {
00271 ss << " \"" << parameterTypeEnumToString(*iter) << "\"\n";
00272 }
00273 throw edm::Exception(errors::LogicError)
00274 << "Types used for wildcards in a node of a ParameterSetDescription\n"
00275 << "\"ifExists\" expression must be different from types used for other parameters\n"
00276 << "in other nodes. The following duplicate types were detected:\n"
00277 << ss.str()
00278 << "\n";
00279 }
00280 }
00281 }
00282 }