CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/FWCore/MessageService/src/MessageServicePSetValidation.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Services
00004 // Class  :     MessageServicePSetValidation
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  M. Fischler
00010 //         Created:  Wed May 20 2009
00011 //
00012 // Change log
00013 //
00014 //
00015 
00016 // system include files
00017 
00018 #include <algorithm>
00019 
00020 // user include files
00021 
00022 #include "FWCore/MessageService/interface/MessageServicePSetValidation.h"
00023 
00024 using namespace edm;
00025 using namespace edm::service;
00026 
00027 namespace edm {
00028 namespace service {
00029 
00030 std::string
00031 edm::service::MessageServicePSetValidation::
00032 operator() (ParameterSet const & pset)
00033 {
00034   messageLoggerPSet (pset); 
00035   return flaws.str();  
00036 }  // operator() to validate the PSet passed in
00037 
00038 void
00039 edm::service::MessageServicePSetValidation::
00040 messageLoggerPSet (ParameterSet const & pset) 
00041 {
00042   // Four types of material are allowed at the MessageLogger level:
00043   //   PSet lists (such as destinations or categories
00044   //   Suppression lists, such as SuppressInfo or debugModules
00045   //   General parameters, such as threshold or messageSummaryToJobReport
00046   //   Nested PSets, such as those for each destination
00047 
00048   // PSet lists
00049 
00050   psetLists(pset);
00051 
00052   // Suppression lists
00053 
00054   suppressionLists(pset);
00055 
00056   // No other vstrings
00057   
00058   vStringsCheck(pset, "MessageLogger");
00059   
00060   // General Parameters
00061   
00062   check<bool> 
00063         ( pset, "MessageLogger", "messageSummaryToJobReport" );
00064   std::string dumps = check<std::string> 
00065         ( pset, "MessageLogger", "generate_preconfiguration_message" );
00066   std::string thresh = check<std::string> 
00067         ( pset, "MessageLogger", "threshold" );
00068   if (!thresh.empty()) validateThreshold(thresh, "MessageLogger");
00069   
00070   // Nested PSets
00071 
00072   destinationPSets(pset);
00073   defaultPSet(pset);
00074   statisticsPSets(pset);
00075   fwkJobReportPSets(pset);
00076   categoryPSets(pset, "MessageLogger");  
00077 
00078   // No other PSets -- unless they contain optionalPSet or placeholder=True 
00079 
00080   noOtherPsets (pset); 
00081 
00082   // Nothing else -- look for int, unsigned int, bool, float, double, string
00083 
00084   noneExcept <int> (pset, "MessageLogger", "int");
00085   noneExcept <unsigned int> (pset, "MessageLogger", "unsigned int");
00086   noneExcept <bool> (pset, "MessageLogger","bool","messageSummaryToJobReport");
00087         // Note - at this, the upper MessageLogger PSet level, the use of 
00088         // optionalPSet makes no sense, so we are OK letting that be a flaw
00089   noneExcept <float> (pset, "MessageLogger","float");
00090   noneExcept <double> (pset, "MessageLogger","double");
00091   noneExcept <std::string> (pset, "MessageLogger","string", 
00092                             "threshold", "generate_preconfiguration_message");
00093 
00094   // Append explanatory information if flaws were found
00095   
00096   if (!flaws.str().empty()) {
00097     flaws << "\nThe above are from MessageLogger configuration validation.\n"
00098     << "In most cases, these involve lines that the logger configuration code\n"
00099     << "would not process, but which the cfg creator obviously meant to have "
00100     << "effect.\n";
00101   }
00102      
00103 } // messageLoggerPSet
00104 
00105 void 
00106 edm::service::MessageServicePSetValidation:: 
00107 psetLists ( ParameterSet const & pset ) 
00108 {
00109   destinations = check<vString>
00110         (pset, "MessageLogger", "destinations");
00111   noDuplicates(destinations,"MessageLogger", "destinations");
00112   noKeywords(destinations,"MessageLogger", "destinations");
00113   noNonPSetUsage(pset, destinations,"MessageLogger", "destinations");
00114   // REMOVED: noCoutCerrClash(destinations,"MessageLogger", "destinations");
00115 
00116   statistics = check<vString>
00117         (pset, "MessageLogger", "statistics");
00118   noDuplicates(statistics,"MessageLogger", "statistics");
00119   noKeywords(statistics,"MessageLogger", "statistics");
00120   noNonPSetUsage(pset, statistics,"MessageLogger", "statistics");
00121 
00122   fwkJobReports = check<vString>
00123         (pset, "MessageLogger", "fwkJobReports");
00124   noDuplicates(fwkJobReports,"MessageLogger", "fwkJobReports");
00125   noKeywords(fwkJobReports,"MessageLogger", "fwkJobReports");
00126   noNonPSetUsage(pset, fwkJobReports,"MessageLogger", "fwkJobReports");
00127   noDuplicates(fwkJobReports,destinations,
00128                 "MessageLogger", "fwkJobReports","destinations");
00129   noDuplicates(fwkJobReports,statistics,
00130                 "MessageLogger", "fwkJobReports","statistics");
00131 
00132   categories = check<vString>
00133         (pset, "MessageLogger", "categories");
00134   noDuplicates(categories,"MessageLogger", "categories");
00135   noKeywords(categories,"MessageLogger", "categories");
00136   noNonPSetUsage(pset, categories,"MessageLogger", "categories");
00137   noDuplicates(categories,destinations,
00138                 "MessageLogger", "categories","destinations");
00139   noDuplicates(categories,statistics,
00140                 "MessageLogger", "categories","statistics");
00141   noDuplicates(categories,fwkJobReports,
00142                 "MessageLogger", "categories","fwkJobReports");
00143 
00144   messageIDs = check<vString>
00145         (pset, "MessageLogger", "messageIDs");
00146   noDuplicates(messageIDs,"MessageLogger", "messageIDs");
00147   noKeywords(messageIDs,"MessageLogger", "messageIDs");
00148   noNonPSetUsage(pset, messageIDs,"MessageLogger", "messageIDs");
00149   noDuplicates(messageIDs,destinations,
00150                 "MessageLogger", "messageIDs","destinations");
00151   noDuplicates(messageIDs,statistics,
00152                 "MessageLogger", "messageIDs","statistics");
00153   noDuplicates(messageIDs,fwkJobReports,
00154                 "MessageLogger", "messageIDs","fwkJobReports");
00155   noDuplicates(messageIDs,fwkJobReports,
00156                 "MessageLogger", "messageIDs","categories");
00157 
00158 } // psetLists
00159 
00160 void 
00161 edm::service::MessageServicePSetValidation:: 
00162 suppressionLists ( ParameterSet const & pset ) 
00163 {
00164   debugModules = check<vString>
00165         (pset, "MessageLogger", "debugModules");
00166   bool dmStar = wildcard(debugModules);
00167   if ( dmStar && debugModules.size() != 1) {
00168     flaws << "MessageLogger" << " PSet: \n"
00169           << "debugModules contains wildcard character *" 
00170           << " and also " << debugModules.size()-1 
00171           << " other entries - * must be alone\n";
00172   } 
00173   suppressDebug = check<vString>
00174         (pset, "MessageLogger", "suppressDebug");
00175   if ( (suppressDebug.size() > 0)  && (!dmStar) ) {
00176     flaws << "MessageLogger" << " PSet: \n"
00177           << "suppressDebug contains modules, but debugModules is not *\n"
00178           << "Unless all the debugModules are enabled,\n"
00179           << "suppressing specific modules is meaningless\n";  
00180   }
00181   if (wildcard(suppressDebug)) {
00182     flaws << "MessageLogger" << " PSet: \n"
00183           << "Use of wildcard (*) in suppressDebug is not supported\n"
00184           << "By default, LogDebug is suppressed for all modules\n";
00185   }
00186   suppressInfo = check<vString>
00187         (pset, "MessageLogger", "suppressInfo");
00188   if (wildcard(suppressInfo)) {
00189     flaws << "MessageLogger" << " PSet: \n"
00190           << "Use of wildcard (*) in suppressInfo is not supported\n";
00191   }
00192   suppressWarning = check<vString>
00193         (pset, "MessageLogger", "suppressWarning");
00194   if (wildcard(suppressWarning)) {
00195     flaws << "MessageLogger" << " PSet: \n"
00196           << "Use of wildcard (*) in suppressWarning is not supported\n";
00197   }
00198   suppressError = check<vString>
00199         (pset, "MessageLogger", "suppressError");
00200   if (wildcard(suppressError)) {
00201     flaws << "MessageLogger" << " PSet: \n"
00202           << "Use of wildcard (*) in suppressError is not supported\n";
00203   }
00204 
00205 } // suppressionLists
00206 
00207 
00208 void 
00209 edm::service::MessageServicePSetValidation:: 
00210 vStringsCheck ( ParameterSet const & pset,std::string const & /*psetName*/ ) 
00211 {
00212   vString vStrings = pset.getParameterNamesForType <vString> (false); 
00213   vString::const_iterator end = vStrings.end();
00214   for ( vString::const_iterator i = vStrings.begin(); i != end; ++i ) {
00215     if ( !allowedVstring(*i) ) {
00216       flaws << "MessageLogger" << " PSet: \n"
00217             << (*i) << " is used as a vstring, "
00218             << "but no such vstring is recognized\n"; 
00219     }
00220   }
00221   vStrings = pset.getParameterNamesForType <vString> (true); 
00222   end = vStrings.end();
00223   for ( vString::const_iterator i = vStrings.begin(); i != end; ++i ) {
00224       flaws << "MessageLogger" << " PSet: \n"
00225             << (*i) << " is used as a tracked vstring: "
00226             << "tracked parameters not allowed here\n"; 
00227   }
00228 } // vStringsCheck
00229 
00230 bool 
00231 edm::service::MessageServicePSetValidation:: 
00232 allowedVstring (std::string const & s)
00233 {
00234   if (s == "destinations")      return true;
00235   if (s == "statistics")        return true;
00236   if (s == "destinations")      return true;
00237   if (s == "fwkJobReports")     return true;
00238   if (s == "categories")        return true;
00239   if (s == "messageIDs")        return true;
00240   if (s == "debugModules")      return true;
00241   if (s == "suppressInfo")      return true;
00242   if (s == "suppressDebug")     return true;
00243   if (s == "suppressWarning")   return true;
00244   if (s == "suppressError")     return true;
00245   return false;
00246 }  // allowedVstring
00247 
00248 
00249 
00250 bool 
00251 edm::service::MessageServicePSetValidation::  
00252 validateThreshold (std::string const & thresh, std::string const & psetName)
00253 {
00254   if (checkThreshold(thresh)) return true;
00255   flaws << psetName << " PSet: \n"
00256         << "threshold has value " << thresh 
00257         << " which is not among {DEBUG, INFO, WARNING, ERROR}\n";
00258   return false;
00259 } // validateThreshold
00260 
00261 bool 
00262 edm::service::MessageServicePSetValidation::  
00263 checkThreshold (std::string const & thresh)
00264 {
00265   if (thresh == "WARNING")      return true;
00266   if (thresh == "INFO")         return true;
00267   if (thresh == "ERROR")        return true;
00268   if (thresh == "DEBUG")        return true;
00269   return false;
00270 }  
00271 
00272 void
00273 edm::service::MessageServicePSetValidation::  
00274 noDuplicates(vString const & v, std::string const & psetName,
00275              std::string  const & parameterLabel ) 
00276 {
00277   vString::const_iterator end = v.end();
00278   for (vString::const_iterator i = v.begin(); i != end; ++i) {
00279     for (vString::const_iterator j = i+1; j != end; ++j)       {
00280       if ( *i == *j ) {
00281         flaws << psetName << " PSet: \n"
00282               << "in vString " << parameterLabel
00283               << " duplication of the string " << *i << "\n";
00284       }
00285     }
00286   }
00287 } // noDuplicates(v)
00288 
00289 void
00290 edm::service::MessageServicePSetValidation::  
00291 noDuplicates(vString const & v1, vString const & v2, 
00292              std::string const & psetName,
00293              std::string  const & p1, std::string  const & p2 )
00294 {
00295   vString::const_iterator end1 = v1.end();
00296   vString::const_iterator end2 = v2.end();
00297   for (vString::const_iterator i = v1.begin(); i != end1; ++i) {
00298     for (vString::const_iterator j = v2.begin(); j != end2; ++j) {
00299       if ( *i == *j ) {
00300         flaws << psetName << " PSet: \n"
00301               << "in vStrings " << p1 << " and " << p2
00302               << " duplication of the string " << *i << "\n";
00303       }
00304     }
00305   }
00306 } // noDuplicates(v1,v2)
00307 
00308 void
00309 edm::service::MessageServicePSetValidation::  
00310 noCoutCerrClash(vString const & v, std::string const & psetName,
00311                 std::string  const & parameterLabel ) 
00312 {
00313   vString::const_iterator end = v.end();
00314   bool coutPresent = false;
00315   bool cerrPresent = false;
00316   for (vString::const_iterator i = v.begin(); i != end; ++i) {
00317     if ( *i == "cout" ) coutPresent = true;
00318     if ( *i == "cerr" ) cerrPresent = true;
00319   }
00320   if (coutPresent && cerrPresent) {
00321         flaws << psetName << " PSet: \n"
00322               << "vString " << parameterLabel
00323               << " has both cout and cerr \n";
00324   }
00325 } // noCoutCerrClash(v)
00326 
00327 void
00328 edm::service::MessageServicePSetValidation::  
00329 noKeywords(vString const & v, std::string const & psetName,
00330            std::string  const & parameterLabel ) 
00331 {
00332   vString::const_iterator end = v.end();
00333   for (vString::const_iterator i = v.begin(); i != end; ++i) {
00334      if (!keywordCheck(*i)) {
00335         flaws << psetName << " PSet: \n"
00336               << "vString " << parameterLabel
00337               << " should not contain the keyword " << *i << "\n";
00338      }
00339   }
00340 } // noKeywords(v)
00341 
00342 bool
00343 edm::service::MessageServicePSetValidation::  
00344 keywordCheck(std::string const & word)
00345 {
00346   if (word == "default")        return false;
00347   if (word == "categories")     return false;
00348   if (word == "messageIDs")     return false;
00349   if (word == "fwkJobReports")  return false;
00350   if (word == "destinations")   return false;
00351   if (word == "statistics")     return false;
00352   if (word == "debugModules")   return false;
00353   if (word == "suppressInfo")   return false;
00354   if (word == "suppressDebug")  return false;
00355   if (word == "suppressWarning")return false;
00356   if (word == "suppressError")  return false;
00357   if (word == "threshold")      return false;
00358   if (word == "ERROR")          return false;
00359   if (word == "WARNING")        return false;
00360   if (word == "INFO")           return false;
00361   if (word == "DEBUG")          return false;
00362   if (word == "placeholder")    return false;
00363   if (word == "limit")          return false;
00364   if (word == "reportEvery")    return false;
00365   if (word == "timespan")       return false;
00366   if (word == "noLineBreaks")   return false;
00367   if (word == "lineLength")     return false;
00368   if (word == "noTimeStamps")   return false;
00369   if (word == "output")         return false;
00370   if (word == "filename")       return false;
00371   if (word == "extension")      return false;
00372   if (word == "reset")          return false;
00373   if (word == "optionalPSet")   return false;
00374   return true;
00375 } // keywordCheck
00376 
00377 void
00378 edm::service::MessageServicePSetValidation::  
00379 noNonPSetUsage(ParameterSet const & pset ,
00380                vString const & v, std::string const & psetName,
00381                std::string  const & parameterLabel ) 
00382 {
00383   disallowedParam <int> ( pset, v, psetName, parameterLabel, "int" );
00384   disallowedParam <unsigned int> ( pset, v, psetName, parameterLabel, "uint" );
00385   disallowedParam <bool> ( pset, v, psetName, parameterLabel, "bool" );
00386   disallowedParam <float> ( pset, v, psetName, parameterLabel, "float" );
00387   disallowedParam <double> ( pset, v, psetName, parameterLabel, "double" );
00388   disallowedParam <std::string> ( pset, v, psetName, parameterLabel, "string" );
00389   disallowedParam <std::vector<std::string> > 
00390         ( pset, v, psetName, parameterLabel, "vstring" );
00391 } // noNonPSetUsage
00392 
00393 void 
00394 edm::service::MessageServicePSetValidation::  
00395 noBadParams(vString const & v, vString const & params, 
00396             std::string const & psetName, 
00397             std::string const & parameterLabel, 
00398             std::string const & type)
00399 {
00400   vString::const_iterator end1 = v.end();
00401   vString::const_iterator end2 = params.end();
00402   for (vString::const_iterator i = v.begin(); i != end1; ++i) {
00403     for (vString::const_iterator j = params.begin(); j != end2; ++j) {
00404       if ( *i == *j ) {
00405         flaws << psetName << " PSet: \n"
00406               << *i << " (listed in vstring " << parameterLabel << ")\n"
00407               << "is used as a parameter of type " << type
00408               << " instead of as a PSet \n"; 
00409       }
00410     }
00411   }
00412 
00413 } // noBadParams
00414  
00415 bool
00416 edm::service::MessageServicePSetValidation::  
00417 wildcard(vString const & v) 
00418 {
00419   vString::const_iterator end = v.end();
00420   for (vString::const_iterator i = v.begin(); i != end; ++i) {
00421     if ((*i) == "*") return true;
00422   }
00423   return false;
00424 }
00425 
00426 void
00427 edm::service::MessageServicePSetValidation::  
00428 noOtherPsets(ParameterSet const & pset)
00429 {
00430   vString psnames;
00431   pset.getParameterSetNames(psnames, false);
00432   vString::const_iterator end = psnames.end();
00433   for (vString::const_iterator i = psnames.begin(); i != end; ++i) {
00434     if ( lookForMatch (destinations, *i) )      continue;
00435     if ( lookForMatch (statistics, *i) )        continue;
00436     if ( lookForMatch (fwkJobReports, *i) )     continue;
00437     if ( lookForMatch (categories, *i) )        continue;
00438     if ( lookForMatch (messageIDs, *i) )        continue;
00439     if ( (*i) == "default" )                    continue;
00440     ParameterSet empty_PSet;
00441     bool ok_optionalPSet = false; 
00442     try {
00443       ParameterSet const& culprit = 
00444                     pset.getUntrackedParameterSet((*i),empty_PSet);
00445       ok_optionalPSet = 
00446           culprit.getUntrackedParameter<bool>("placeholder",  ok_optionalPSet);
00447       ok_optionalPSet = 
00448           culprit.getUntrackedParameter<bool>("optionalPSet", ok_optionalPSet);
00449     } catch (cms::Exception& e) { 
00450     }
00451     if (ok_optionalPSet) continue; 
00452     flaws << "MessageLogger " << " PSet: \n"
00453           << *i << " is an unrecognized name for a PSet\n";
00454   }
00455   psnames.clear();
00456   unsigned int n = pset.getParameterSetNames(psnames, true);
00457   if ( n > 0 ) {
00458     end = psnames.end();
00459     for (vString::const_iterator i = psnames.begin(); i != end; ++i) {
00460       flaws << "MessageLogger " << " PSet: \n"
00461             << "PSet " << *i << " is tracked - not allowed\n";
00462     }
00463   }
00464 }
00465 
00466 bool
00467 edm::service::MessageServicePSetValidation::  
00468 lookForMatch(vString const & v, std::string const & s)
00469 {
00470   vString::const_iterator begin = v.begin();
00471   vString::const_iterator end = v.end();
00472   return ( std::find(begin, end, s) != end );
00473 }
00474 
00475 void
00476 edm::service::MessageServicePSetValidation::  
00477 destinationPSets(ParameterSet const & pset)
00478 {
00479   ParameterSet empty_PSet;
00480   std::vector<std::string>::const_iterator end = destinations.end();
00481   for ( std::vector<std::string>::const_iterator i = destinations.begin();
00482                                                              i != end; ++i )  {
00483     ParameterSet const& d = pset.getUntrackedParameterSet(*i,empty_PSet);
00484     destinationPSet(d,*i); 
00485   }
00486 } // destinationPSets
00487 
00488 void
00489 edm::service::MessageServicePSetValidation::  
00490 destinationPSet(ParameterSet const & pset, std::string const & psetName)
00491 {
00492   // Category PSets
00493 
00494   categoryPSets (pset, psetName);
00495      
00496   // No other PSets -- unless they contain optionalPSet or placeholder=True 
00497   
00498   noNoncategoryPsets (pset, psetName);
00499   
00500   // General parameters
00501   
00502   check <bool> ( pset, psetName, "placeholder" );
00503   std::string thresh = check<std::string> ( pset, "psetName", "threshold" );
00504   if (!thresh.empty()) validateThreshold(thresh, psetName);
00505   check <bool> ( pset, psetName, "noLineBreaks" );
00506   check <int>  ( pset, psetName, "lineLength" );
00507   check <bool> ( pset, psetName, "noTimeStamps" );
00508   std::string s = check<std::string> ( pset, "psetName", "filename" );
00509   if ( (s == "cerr") || (s == "cout") ) {
00510     flaws << psetName << " PSet: \n"
00511           << s << " is not allowed as a value of filename \n";
00512   }
00513   s = check<std::string> ( pset, "psetName", "extension" );
00514   if ( (s == "cerr") || (s == "cout") ) {
00515     flaws << psetName << " PSet: \n"
00516          << s << " is not allowed as a value of extension \n";
00517   }
00518   s = check<std::string> ( pset, "psetName", "output" );  
00519   
00520   // No other parameters
00521 
00522   noneExcept <int> (pset, psetName, "int", "lineLength"); 
00523 
00524   vString okbool;
00525   okbool.push_back ("placeholder");
00526   okbool.push_back ("optionalPSet");
00527   okbool.push_back ("noLineBreaks");
00528   okbool.push_back ("noTimeStamps");
00529   noneExcept <bool> (pset, psetName, "bool", okbool);   
00530   vString okstring;
00531   okstring.push_back ("threshold");
00532   okstring.push_back ("output");
00533   okstring.push_back ("filename");
00534   okstring.push_back ("extension");
00535   noneExcept <std::string> (pset, psetName, "string", okstring);   
00536   
00537 } // destinationPSet
00538 
00539 void
00540 edm::service::MessageServicePSetValidation::  
00541 defaultPSet(ParameterSet const & main_pset)
00542 {
00543   ParameterSet empty_PSet;
00544   ParameterSet const& pset = main_pset.getUntrackedParameterSet("default",empty_PSet);
00545   std::string psetName = "default (at MessageLogger main level)";
00546   
00547   // Category PSets
00548 
00549   categoryPSets (pset, psetName);
00550      
00551   // No other PSets -- unless they contain optionalPSet or placeholder=True 
00552   
00553   noNoncategoryPsets (pset, psetName);
00554   
00555   // Parameters applying to the default category
00556   
00557   catInts ( pset, psetName, "default" );
00558 
00559   // General parameters
00560   
00561   check <bool> ( pset, psetName, "placeholder" );
00562   std::string thresh = check<std::string> ( pset, "psetName", "threshold" );
00563   if (!thresh.empty()) validateThreshold(thresh, psetName);
00564   check <bool> ( pset, psetName, "noLineBreaks" );
00565   check <int>  ( pset, psetName, "limit" );   
00566   check <int>  ( pset, psetName, "reportEvery" );   
00567   check <int>  ( pset, psetName, "timespan" );   
00568   check <int>  ( pset, psetName, "lineLength" );   
00569   check <bool> ( pset, psetName, "noTimeStamps" );
00570   
00571   // No other parameters
00572   vString okint;
00573   okint.push_back("limit");
00574   okint.push_back("reportEvery");
00575   okint.push_back("timespan");
00576   okint.push_back("lineLength");
00577   noneExcept <int> (pset, psetName, "int", okint); 
00578   vString okbool;
00579   okbool.push_back ("placeholder");
00580   okbool.push_back ("optionalPSet");
00581   okbool.push_back ("noLineBreaks");
00582   okbool.push_back ("noTimeStamps");
00583   noneExcept <bool> (pset, psetName, "bool", okbool);   
00584   vString okstring;
00585   okstring.push_back ("threshold");
00586   noneExcept <std::string> (pset, psetName, "string", okstring);   
00587   
00588 } // defaultPSet
00589 
00590 void
00591 edm::service::MessageServicePSetValidation::  
00592 statisticsPSets(ParameterSet const & pset)
00593 {
00594   ParameterSet empty_PSet;
00595   std::vector<std::string>::const_iterator end = statistics.end();
00596   for ( std::vector<std::string>::const_iterator i = statistics.begin();
00597                                                              i != end; ++i )  {
00598     if (lookForMatch(destinations, *i)) continue; 
00599     ParameterSet const& d = pset.getUntrackedParameterSet(*i, empty_PSet);
00600     statisticsPSet(d,*i); 
00601   }
00602 } // statisticsPSets
00603 
00604 void
00605 edm::service::MessageServicePSetValidation::  
00606 statisticsPSet(ParameterSet const & pset, std::string const & psetName)
00607 {
00608   // Category PSets
00609   
00610   categoryPSets (pset, psetName);
00611      
00612   // No other PSets -- unless they contain optionalPSet or placeholder=True 
00613   
00614   noNoncategoryPsets (pset, psetName);
00615   
00616   // General parameters
00617   
00618   std::string thresh = check<std::string> ( pset, "psetName", "threshold" );
00619   if (!thresh.empty()) validateThreshold(thresh, psetName);
00620   check <bool> ( pset, psetName, "placeholder" );
00621   check <bool> ( pset, psetName, "reset" );
00622   std::string s = check<std::string> ( pset, "psetName", "filename" );
00623   if ( (s == "cerr") || (s == "cout") ) {
00624     flaws << psetName << " PSet: \n"
00625           << s << " is not allowed as a value of filename \n";
00626   }
00627   s = check<std::string> ( pset, "psetName", "extension" );
00628   if ( (s == "cerr") || (s == "cout") ) {
00629     flaws << psetName << " PSet: \n"
00630          << s << " is not allowed as a value of extension \n";
00631   }
00632   s = check<std::string> ( pset, "psetName", "output" );  
00633   
00634   // No other parameters
00635 
00636   noneExcept <int> (pset, psetName, "int"); 
00637 
00638   vString okbool;
00639   okbool.push_back ("placeholder");
00640   okbool.push_back ("optionalPSet");
00641   okbool.push_back ("reset");
00642   noneExcept <bool> (pset, psetName, "bool", okbool);   
00643   vString okstring;
00644   okstring.push_back ("output");
00645   okstring.push_back ("filename");
00646   okstring.push_back ("extension");
00647   okstring.push_back ("threshold");
00648   noneExcept <std::string> (pset, psetName, "string", okstring);   
00649   
00650 } // statisticsPSet
00651 
00652 void
00653 edm::service::MessageServicePSetValidation::  
00654 fwkJobReportPSets(ParameterSet const & pset)
00655 {
00656   ParameterSet empty_PSet;
00657   std::vector<std::string>::const_iterator end = fwkJobReports.end();
00658   for ( std::vector<std::string>::const_iterator i = fwkJobReports.begin();
00659                                                              i != end; ++i )  {
00660     ParameterSet const& d = pset.getUntrackedParameterSet(*i, empty_PSet);
00661     fwkJobReportPSet(d,*i); 
00662   }
00663 } // fwkJobReportPSets
00664 
00665 void
00666 edm::service::MessageServicePSetValidation::  
00667 fwkJobReportPSet(ParameterSet const & pset, std::string const & psetName)
00668 {
00669   // Category PSets
00670   
00671   categoryPSets (pset, psetName);
00672      
00673   // No other PSets -- unless they contain optionalPSet or placeholder=True 
00674   
00675   noNoncategoryPsets (pset, psetName);
00676   
00677   // General parameters
00678   
00679   check <bool> ( pset, psetName, "placeholder" );
00680   std::string s = check<std::string> ( pset, "psetName", "filename" );
00681   if ( (s == "cerr") || (s == "cout") ) {
00682     flaws << psetName << " PSet: \n"
00683           << s << " is not allowed as a value of filename \n";
00684   }
00685   s = check<std::string> ( pset, "psetName", "extension" );
00686   if ( (s == "cerr") || (s == "cout") ) {
00687     flaws << psetName << " PSet: \n"
00688          << s << " is not allowed as a value of extension \n";
00689   }
00690   s = check<std::string> ( pset, "psetName", "output" );  
00691     
00692   // No other parameters
00693 
00694   noneExcept <int> (pset, psetName, "int"); 
00695 
00696   vString okbool;
00697   okbool.push_back ("placeholder");
00698   okbool.push_back ("optionalPSet");
00699   noneExcept <bool> (pset, psetName, "bool", okbool);   
00700   vString okstring;
00701   okstring.push_back ("output");
00702   okstring.push_back ("filename");
00703   okstring.push_back ("extension");
00704   noneExcept <std::string> (pset, psetName, "string", okstring);   
00705   
00706 } // fwkJobReportPSet
00707 
00708 void
00709 edm::service::MessageServicePSetValidation::  
00710 noNoncategoryPsets(ParameterSet const & pset,std::string const & psetName)
00711 {
00712   vString psnames;
00713   pset.getParameterSetNames(psnames, false);
00714   vString::const_iterator end = psnames.end();
00715   for (vString::const_iterator i = psnames.begin(); i != end; ++i) {
00716     if ( lookForMatch (categories, *i) )        continue;
00717     if ( lookForMatch (messageIDs, *i) )        continue;
00718     if ( (*i) == "default" )                    continue;
00719     if ( (*i) == "ERROR" )                      continue;
00720     if ( (*i) == "WARNING" )                    continue;
00721     if ( (*i) == "INFO" )                       continue;
00722     if ( (*i) == "DEBUG" )                      continue;
00723     ParameterSet empty_PSet;
00724     bool ok_optionalPSet = false; 
00725     try {
00726       ParameterSet const& culprit = 
00727                     pset.getUntrackedParameterSet((*i),empty_PSet);
00728       ok_optionalPSet = 
00729           culprit.getUntrackedParameter<bool>("placeholder",  ok_optionalPSet);
00730       ok_optionalPSet = 
00731           culprit.getUntrackedParameter<bool>("optionalPSet", ok_optionalPSet);
00732     } catch (cms::Exception& e) { 
00733     }
00734     if (ok_optionalPSet) continue; 
00735     flaws << psetName << " PSet: \n"
00736           << *i << " is an unrecognized name for a PSet in this context \n";
00737   }
00738   psnames.clear();
00739   unsigned int n = pset.getParameterSetNames(psnames, true);
00740   if ( n > 0 ) {
00741     end = psnames.end();
00742     for (vString::const_iterator i = psnames.begin(); i != end; ++i) {
00743       flaws << psetName << " PSet: \n"
00744             << "PSet " << *i << " is tracked - not allowed\n";
00745     }
00746   }
00747 } // noNoncategoryPsets
00748 
00749 void
00750 edm::service::MessageServicePSetValidation::  
00751 categoryPSets(ParameterSet const & pset, std::string const & psetName ) 
00752 {
00753   categoryPSet (pset, psetName, "ERROR"  );
00754   categoryPSet (pset, psetName, "WARNING");
00755   categoryPSet (pset, psetName, "INFO"   ) ;
00756   categoryPSet (pset, psetName, "DEBUG"  );
00757   if (psetName != "MessageLogger") categoryPSet (pset, psetName, "default");
00758   // The above conditional is because default in the main level is treated
00759   // as a set of defaults differnt from those of a simple category. 
00760   std::vector<std::string>::const_iterator end = categories.end();
00761   for (std::vector<std::string>::const_iterator i = categories.begin(); 
00762        i != end; ++i) {
00763     categoryPSet(pset, psetName, *i);
00764   }
00765 } // categoryPSets            
00766 
00767 void
00768 edm::service::MessageServicePSetValidation::  
00769 categoryPSet (ParameterSet const & pset,
00770               std::string const & OuterPsetName,
00771               std::string const & categoryName)  {
00772   if (pset.existsAs<ParameterSet> (categoryName, true)) {
00773       flaws << OuterPsetName << " PSet: \n"
00774             << "Category PSet " << categoryName 
00775             << " is tracked - not allowed\n";
00776       return;  
00777   }
00778   ParameterSet empty_PSet;
00779   ParameterSet const& c = pset.getUntrackedParameterSet(categoryName,empty_PSet);
00780   std::string const & psetName(OuterPsetName);
00781   catInts                       ( c, psetName, categoryName );
00782   catNone <unsigned int>        ( c, psetName, categoryName, "unsigned int" );
00783   catBoolRestriction            ( c, psetName, categoryName, "bool" );
00784   catNone <float>               ( c, psetName, categoryName, "float" );
00785   catNone <double>              ( c, psetName, categoryName, "double" );
00786   catNone <std::string>         ( c, psetName, categoryName, "string" );
00787   catNone <vString>             ( c, psetName, categoryName, "vSting" );
00788   catNoPSets                    ( c, psetName, categoryName );
00789 } // categoryPSet             
00790 
00791 void
00792 edm::service::MessageServicePSetValidation::  
00793 catInts (ParameterSet const & pset, 
00794         std::string  const & psetName, 
00795         std::string  const & categoryName)  
00796 {
00797   vString x = pset.getParameterNamesForType <int> (false);
00798   vString::const_iterator end = x.end();
00799   for ( vString::const_iterator i = x.begin(); i != end; ++i ) {
00800     if ( *i == "limit" ) continue;
00801     if ( *i == "reportEvery" ) continue;
00802     if ( *i == "timespan" ) continue;
00803     flaws << categoryName << " category PSet nested in "
00804           << psetName << " PSet: \n"
00805           << (*i) << " is not an allowed parameter within a category PSet \n";
00806   }
00807   x = pset.getParameterNamesForType <int> (true);
00808   end = x.end();
00809   for ( vString::const_iterator i = x.begin(); i != end; ++i ) {
00810     flaws << categoryName << " category PSet nested in "
00811           << psetName << " PSet: \n"
00812           << (*i) << " is used as a tracked int \n"
00813           << "Tracked parameters not allowed here \n";
00814   }
00815 } // catInts()
00816 
00817 void
00818 edm::service::MessageServicePSetValidation::  
00819 catNoPSets (ParameterSet const & pset, 
00820         std::string  const & psetName, 
00821         std::string  const & categoryName)  
00822 {
00823   vString psnames;
00824   pset.getParameterSetNames(psnames, false);
00825   vString::const_iterator end = psnames.end();
00826   for (vString::const_iterator i = psnames.begin(); i != end; ++i) {
00827     flaws << categoryName << " category PSet nested in "
00828           << psetName << " PSet: \n"
00829           << *i << " is used as a  PSet\n"
00830           << "PSets not allowed within a category PSet\n";
00831   }
00832   psnames.clear();
00833   unsigned int n = pset.getParameterSetNames(psnames, true);
00834   if ( n > 0 ) {
00835     end = psnames.end();
00836     for (vString::const_iterator i = psnames.begin(); i != end; ++i) {
00837     flaws << categoryName << " category PSet nested in "
00838           << psetName << " PSet: \n"
00839           << *i << " is used as a tracked PSet\n"
00840           << "tracked parameters not permitted, and "
00841           << "PSets not allowed within a category PSet\n";
00842     }
00843   }
00844 } // catNoPSets
00845 
00846 void
00847 edm::service::MessageServicePSetValidation::  
00848 catBoolRestriction (ParameterSet const & pset, 
00849                     std::string  const & psetName, 
00850                     std::string  const & categoryName,
00851                     std::string  const & type)  
00852 {
00853   vString x = pset.getParameterNamesForType <bool> (false);
00854   vString::const_iterator end = x.end();
00855   for ( vString::const_iterator i = x.begin(); i != end; ++i ) {
00856     if ( ((*i) == "placeholder") || ((*i) == "optionalPSet") ) continue;
00857     flaws << categoryName << " category PSet nested in "
00858           << psetName << " PSet: \n"
00859           << (*i) << " is used as a " << type << "\n"
00860           << "Usage of " << type << " is not recognized here\n"; 
00861   }
00862   x = pset.getParameterNamesForType <bool> (true);
00863   end = x.end();
00864   for ( vString::const_iterator i = x.begin(); i != end; ++i ) {
00865     flaws << categoryName << " category PSet nested in "
00866           << psetName << " PSet: \n"
00867           << (*i) << " is used as a tracked " << type << "\n"
00868           << "Tracked parameters not allowed here, "
00869           <<" and even untracked it would not be recognized\n";
00870   }
00871 } // catBoolRestriction()
00872 
00873 
00874 } // end of namespace service  
00875 } // end of namespace edm