Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:08:23

0001 #include <cstdlib>
0002 #include <exception>
0003 #include <iostream>
0004 #include <string>
0005 #include <utility>
0006 #include <vector>
0007 
0008 #include "DetectorDescription/Core/interface/DDCompactView.h"
0009 #include "DetectorDescription/Core/interface/DDExpandedNode.h"
0010 #include "DetectorDescription/Core/interface/DDExpandedView.h"
0011 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0012 #include "DetectorDescription/Core/interface/DDMaterial.h"
0013 #include "DetectorDescription/Core/interface/DDName.h"
0014 #include "DetectorDescription/Core/interface/DDRoot.h"
0015 #include "DetectorDescription/Core/interface/DDSolid.h"
0016 #include "DetectorDescription/Core/interface/DDTransform.h"
0017 #include "DetectorDescription/RegressionTest/src/DDCheck.h"
0018 #include "DetectorDescription/Parser/interface/DDLDocumentProvider.h"
0019 #include "DetectorDescription/Parser/interface/DDLParser.h"
0020 #include "DetectorDescription/Parser/interface/DDLSAX2ConfigHandler.h"
0021 #include "DetectorDescription/Parser/interface/DDLSAX2Handler.h"
0022 #include "FWCore/PluginManager/interface/PluginManager.h"
0023 #include "FWCore/PluginManager/interface/standard.h"
0024 #include "FWCore/Utilities/interface/Exception.h"
0025 #include "Utilities/Xerces/interface/XercesStrUtils.h"
0026 #include "xercesc/util/XMLException.hpp"
0027 #include "xercesc/util/XercesVersion.hpp"
0028 
0029 using namespace cms::xerces;
0030 
0031 class DDLTestDoc : public DDLDocumentProvider {
0032 public:
0033   DDLTestDoc(void);
0034   ~DDLTestDoc() override;
0035 
0036   /// Return a list of files as a vector of strings.
0037   const std::vector<std::string>& getFileList(void) const override;
0038 
0039   /// Return a list of urls as a vector of strings.
0040   const std::vector<std::string>& getURLList(void) const override;
0041 
0042   /// Print out the list of files.
0043   void dumpFileList(void) const override;
0044 
0045   /// Return whether Validation should be on or off and where the DDL SchemaLocation is.
0046   bool doValidation(void) const override;
0047 
0048   /// Return the designation for where to look for the schema.
0049   std::string getSchemaLocation(void) const override;
0050 
0051   /// ReadConfig
0052   int readConfig(const std::string& filename) override;
0053 
0054   void emplace_back(const std::string& fileName, const std::string& url = std::string("./"));
0055 
0056   void setSchemaLocation(std::string path = std::string("../../DDSchema"));
0057 
0058   void setValidation(bool val);
0059 
0060   void clear(void);
0061 
0062 private:
0063   std::vector<std::string> fnames_;
0064   std::vector<std::string> urls_;
0065   std::string schemaLoc_;
0066   bool validate_;
0067 };
0068 
0069 //--------------------------------------------------------------------------
0070 //  DDLTestDoc:  Default constructor and destructor.
0071 //--------------------------------------------------------------------------
0072 DDLTestDoc::~DDLTestDoc(void) {}
0073 
0074 DDLTestDoc::DDLTestDoc(void) : validate_(true) { schemaLoc_ = "http://www.cern.ch/cms/DDL ../../Schema/DDLSchema.xsd"; }
0075 
0076 const std::vector<std::string>& DDLTestDoc::getFileList(void) const { return fnames_; }
0077 
0078 const std::vector<std::string>& DDLTestDoc::getURLList(void) const { return urls_; }
0079 
0080 void DDLTestDoc::emplace_back(const std::string& fileName, const std::string& url) {
0081   fnames_.emplace_back(fileName);
0082   urls_.emplace_back(url);
0083 }
0084 
0085 void DDLTestDoc::setValidation(bool val) { validate_ = val; }
0086 
0087 bool DDLTestDoc::doValidation(void) const { return validate_; }
0088 
0089 void DDLTestDoc::setSchemaLocation(std::string path) { schemaLoc_ = std::move(path); }
0090 
0091 std::string DDLTestDoc::getSchemaLocation(void) const {
0092   std::cout << schemaLoc_ << std::endl;
0093   return schemaLoc_;
0094 }
0095 
0096 void DDLTestDoc::dumpFileList(void) const {
0097   std::cout << "File List:" << std::endl;
0098   std::vector<std::string> vst = getFileList();
0099   std::cout << "  number of files=" << vst.size() << std::endl;
0100   for (std::vector<std::string>::const_iterator it = vst.begin(); it != vst.end(); ++it)
0101     std::cout << *it << std::endl;
0102 }
0103 
0104 void DDLTestDoc::clear(void) {
0105   fnames_.clear();
0106   urls_.clear();
0107 }
0108 
0109 //-----------------------------------------------------------------------
0110 //  Here the Xerces parser is used to process the content of the
0111 //  configuration file.
0112 //  FIX:  Right now, each config file passed to this will simply increase the
0113 //  size of the list of files.  So if this default DDLDocumentProvider is
0114 //  called repeatedly (i.e. the same instance of it) then the file list MAY
0115 //  repeat files.  It is the Parser which checks for maintains a list of real
0116 //  files.
0117 //-----------------------------------------------------------------------
0118 int DDLTestDoc::readConfig(const std::string& filename) {
0119   std::cout << "readConfig" << std::endl;
0120 
0121   // Set the parser to use the handler for the configuration file.
0122   // This makes sure the Parser is initialized and gets a handle to it.
0123   DDCompactView cpv;
0124   DDLParser parser(cpv);
0125   DDLSAX2Handler* errHandler;
0126   DDLSAX2ConfigHandler* sch;
0127 
0128   sch = new DDLSAX2ConfigHandler(cpv);
0129   errHandler = new DDLSAX2Handler;
0130 
0131   parser.getXMLParser()->setContentHandler(sch);
0132   parser.getXMLParser()->setErrorHandler(errHandler);
0133 
0134   try {
0135     parser.getXMLParser()->parse(filename.c_str());
0136   } catch (const XERCES_CPP_NAMESPACE::XMLException& toCatch) {
0137     std::cout << "\nXMLException: parsing '" << filename << "'\n"
0138               << "Exception message is: \n"
0139               << cStr(toCatch.getMessage()).ptr() << "\n";
0140     return 1;
0141   } catch (...) {
0142     std::cout << "\nUnexpected exception during parsing: '" << filename << "'\n";
0143     return 3;
0144   }
0145 
0146   fnames_ = sch->getFileNames();
0147   urls_ = sch->getURLs();
0148   std::cout << "there are " << fnames_.size() << " files." << std::endl;
0149   for (size_t i = 0; i < fnames_.size(); ++i)
0150     std::cout << "url=" << urls_[i] << " file=" << fnames_[i] << std::endl;
0151   return 0;
0152 }
0153 
0154 void testRotations(void) {
0155   std::cout << "--------------- Parser testing Rotations --------------" << std::endl;
0156   std::cout << "z30 should be a rotation of 30 degrees around the z axis:" << std::endl;
0157   std::cout << DDRotation(DDName("z30", "testRotations")) << std::endl;
0158   std::cout << std::endl;
0159   std::cout << "z30x20 should be a rotation 30 degrees around z, then 20 degrees around x:" << std::endl;
0160   std::cout << DDRotation(DDName("z30x20", "testRotations")) << std::endl;
0161   std::cout << std::endl;
0162   std::cout << "x90y45 should be a rotation 90 degrees around x, then 45 degrees around y:" << std::endl;
0163   std::cout << DDRotation(DDName("x90y45", "testRotations")) << std::endl;
0164   std::cout << std::endl;
0165   std::cout << "x90y90 should be a rotation 90 degrees around x, then 90 degrees around y:" << std::endl;
0166   std::cout << DDRotation(DDName("x90y90", "testRotations")) << std::endl;
0167   std::cout << std::endl;
0168   std::cout << "x90y135 should be a rotation 90 degrees around x, then 135 degrees around y:" << std::endl;
0169   std::cout << DDRotation(DDName("x90y135", "testRotations")) << std::endl;
0170   std::cout << std::endl;
0171   std::cout << "x90y180 should be a rotation 90 degrees around x, then 180 degrees around y:" << std::endl;
0172   std::cout << DDRotation(DDName("x90y180", "testRotations")) << std::endl;
0173   std::cout << std::endl;
0174   std::cout << "x90 should be a rotation of 90 degrees around the x axis:" << std::endl;
0175   std::cout << DDRotation(DDName("x90", "testRotations")) << std::endl;
0176   std::cout << std::endl;
0177   std::cout << "cmsimIdentity makes the identity rotation matrix using the cmsim method (phi and theta of each axis):"
0178             << std::endl;
0179   std::cout << DDRotation(DDName("cmsimIdentity", "testRotations")) << std::endl;
0180   std::cout << std::endl;
0181   std::cout << "newrotIdentity makes the identity rotation matrix by rotating 0 degrees around the z axis:"
0182             << std::endl;
0183   std::cout << DDRotation(DDName("newrotIdentity", "testRotations")) << std::endl;
0184   std::cout << std::endl;
0185   std::cout << "180R should be a REFLECTION rotation.  It is defined using the cmsim way:" << std::endl;
0186   std::cout << DDRotation(DDName("180R", "testRotations")) << std::endl;
0187   std::cout << std::endl;
0188 }
0189 
0190 void testMaterials() {
0191   std::cout << "--------------- Parser testing Materials --------------" << std::endl;
0192   std::cout << "There should be 4 Elementary Materials: Nitrogen," << std::endl;
0193   std::cout << "Oxygen,Argon and Hydrogen.  There should be one composite" << std::endl;
0194   std::cout << " material:Air, made up of those 4 components." << std::endl;
0195   std::cout << DDMaterial(DDName("Nitrogen", "testMaterials")) << std::endl;
0196   std::cout << std::endl;
0197   std::cout << DDMaterial(DDName("Oxygen", "testMaterials")) << std::endl;
0198   std::cout << std::endl;
0199   std::cout << DDMaterial(DDName("Argon", "testMaterials")) << std::endl;
0200   std::cout << std::endl;
0201   std::cout << DDMaterial(DDName("Hydrogen", "testMaterials")) << std::endl;
0202   std::cout << std::endl;
0203   std::cout << DDMaterial(DDName("Air", "testMaterials")) << std::endl;
0204   std::cout << std::endl;
0205 }
0206 
0207 void testSolids(void) {
0208   std::cout << "--------------- Parser testing Solids --------------" << std::endl;
0209   std::cout << "trap1 is a trapezoid:" << std::endl;
0210   std::cout << DDSolid(DDName("trap1", "testSolids")) << std::endl;
0211   std::cout << std::endl;
0212   std::cout << "trap2 is a trapezoid with more symmetry:" << std::endl;
0213   std::cout << DDSolid(DDName("trap2", "testSolids")) << std::endl;
0214   std::cout << std::endl;
0215   std::cout << "ptrap1 is a pseudo Trapezoid with atMinusZ=false:" << std::endl;
0216   std::cout << DDSolid(DDName("ptrap1", "testSolids")) << std::endl;
0217   std::cout << std::endl;
0218   std::cout << "ptrap2 is a psuedo Trapezoid with atMinusZ=true:" << std::endl;
0219   std::cout << DDSolid(DDName("ptrap2", "testSolids")) << std::endl;
0220   std::cout << std::endl;
0221   std::cout << "box1 is a Box:" << std::endl;
0222   std::cout << DDSolid(DDName("box1", "testSolids")) << std::endl;
0223   std::cout << std::endl;
0224   std::cout << "cone1 is a conical section (full 360 degree):" << std::endl;
0225   std::cout << DDSolid(DDName("cone1", "testSolids")) << std::endl;
0226   std::cout << std::endl;
0227   std::cout << "cone2 is a conical section (full 360 degree) which is actually a tube:" << std::endl;
0228   std::cout << DDSolid(DDName("cone2", "testSolids")) << std::endl;
0229   std::cout << std::endl;
0230   std::cout << "cone2hole is a conical section (20 degree):" << std::endl;
0231   std::cout << DDSolid(DDName("cone2hole", "testSolids")) << std::endl;
0232   std::cout << std::endl;
0233   std::cout << "pczsect is a polycone defined using z-sections:" << std::endl;
0234   std::cout << DDSolid(DDName("pczsect", "testSolids")) << std::endl;
0235   std::cout << std::endl;
0236   std::cout << "pcrz is a polycone defined using r & z points:" << std::endl;
0237   std::cout << DDSolid(DDName("pcrz", "testSolids")) << std::endl;
0238   std::cout << std::endl;
0239   std::cout << "phzsect is a polyhedra defined using z-sections:" << std::endl;
0240   std::cout << DDSolid(DDName("phzsect", "testSolids")) << std::endl;
0241   std::cout << std::endl;
0242   std::cout << "phrz is a polyhedra defined using r & z points:" << std::endl;
0243   std::cout << DDSolid(DDName("phrz", "testSolids")) << std::endl;
0244   std::cout << std::endl;
0245   std::cout << "trd1 is a \"special\" trapezoid declaration with fewer";
0246   std::cout << " parameters (Trd1):" << std::endl;
0247   std::cout << DDSolid(DDName("trd1", "testSolids")) << std::endl;
0248   std::cout << std::endl;
0249   std::cout << "trd2 is a \"special\" trapezoid declaration with fewer";
0250   std::cout << " parameters (Trd1):" << std::endl;
0251   std::cout << DDSolid(DDName("trd2", "testSolids")) << std::endl;
0252   std::cout << std::endl;
0253   std::cout << "tube1 is a tube:" << std::endl;
0254   std::cout << DDSolid(DDName("tube1", "testSolids")) << std::endl;
0255   std::cout << std::endl;
0256   std::cout << "tube2 is a tubs(Tube Section):" << std::endl;
0257   std::cout << DDSolid(DDName("tube2", "testSolids")) << std::endl;
0258   std::cout << std::endl;
0259   std::cout << "trunctubs1 is a trunctubs(Cut or truncated Tube Section):" << std::endl;
0260   std::cout << DDSolid(DDName("trunctubs1", "testSolids")) << std::endl;
0261   std::cout << std::endl;
0262   std::cout << "momma is a shapeless solid, a way of \"grouping\" things:" << std::endl;
0263   std::cout << DDSolid(DDName("momma", "testSolids")) << std::endl;
0264   std::cout << std::endl;
0265   std::cout << "MotherOfAllBoxes is a box and is the root's solid:" << std::endl;
0266   std::cout << DDSolid(DDName("MotherOfAllBoxes", "testSolids")) << std::endl;
0267   std::cout << std::endl;
0268   std::cout << "trd2mirror is a ReflectionSolid of trd2:" << std::endl;
0269   std::cout << DDSolid(DDName("trd2mirror", "testSolids")) << std::endl;
0270   std::cout << std::endl;
0271   std::cout << "subsolid is a subtraction solid, cone2-cone2hole:" << std::endl;
0272   std::cout << DDSolid(DDName("subsolid", "testSolids")) << std::endl;
0273   std::cout << std::endl;
0274   std::cout << "unionsolid is a union of pcrz and cone1:" << std::endl;
0275   std::cout << DDSolid(DDName("unionsolid", "testSolids")) << std::endl;
0276   std::cout << std::endl;
0277   std::cout << "intsolid is an Intersection(Solid) of cone1 and cone2:" << std::endl;
0278   std::cout << DDSolid(DDName("intsolid", "testSolids")) << std::endl;
0279   std::cout << std::endl;
0280   std::cout << "cuttubs is a Cut tubs solid:" << std::endl;
0281   std::cout << DDSolid(DDName("cuttubs", "testSolids")) << std::endl;
0282   std::cout << std::endl;
0283   std::cout << "extrudedpgon is an Extruded Polygone solid:" << std::endl;
0284   std::cout << DDSolid(DDName("extrudedpgon", "testSolids")) << std::endl;
0285   std::cout << std::endl;
0286   std::cout << "verify parameters interface\nx: ";
0287   DDExtrudedPolygon extrPgon(DDSolid(DDName("extrudedpgon", "testSolids")));
0288   std::vector<double> x = extrPgon.xVec();
0289   std::vector<double> y = extrPgon.yVec();
0290   std::vector<double> z = extrPgon.zVec();
0291   std::vector<double> zx = extrPgon.zxVec();
0292   std::vector<double> zy = extrPgon.zyVec();
0293   std::vector<double> zs = extrPgon.zscaleVec();
0294   for (auto i : x)
0295     std::cout << i << ", ";
0296   std::cout << "\ny: ";
0297   for (auto i : y)
0298     std::cout << i << ", ";
0299   std::cout << "\nz: ";
0300   for (auto i : z)
0301     std::cout << i << ", ";
0302   std::cout << "\nzx: ";
0303   for (auto i : zx)
0304     std::cout << i << ", ";
0305   std::cout << "\nzy: ";
0306   for (auto i : zy)
0307     std::cout << i << ", ";
0308   std::cout << "\nz scale: ";
0309   for (auto i : zs)
0310     std::cout << i << ", ";
0311 }
0312 
0313 void testLogicalParts(void) {
0314   std::cout << "--------------- Parser testing LogicalParts --------------" << std::endl;
0315   std::cout << "LogicalPart trap1:" << std::endl;
0316   std::cout << DDLogicalPart(DDName("trap1", "testLogicalParts")) << std::endl;
0317   std::cout << std::endl;
0318   std::cout << "LogicalPart trap2:" << std::endl;
0319   std::cout << DDLogicalPart(DDName("trap2", "testLogicalParts")) << std::endl;
0320   std::cout << std::endl;
0321   std::cout << "LogicalPart ptrap1:" << std::endl;
0322   std::cout << DDLogicalPart(DDName("ptrap1", "testLogicalParts")) << std::endl;
0323   std::cout << std::endl;
0324   std::cout << "LogicalPart ptrap2:" << std::endl;
0325   std::cout << DDLogicalPart(DDName("ptrap2", "testLogicalParts")) << std::endl;
0326   std::cout << std::endl;
0327   std::cout << "LogicalPart box1:" << std::endl;
0328   std::cout << DDLogicalPart(DDName("box1", "testLogicalParts")) << std::endl;
0329   std::cout << std::endl;
0330   std::cout << "LogicalPart cone1:" << std::endl;
0331   std::cout << DDLogicalPart(DDName("cone1", "testLogicalParts")) << std::endl;
0332   std::cout << std::endl;
0333   std::cout << "LogicalPart cone2:" << std::endl;
0334   std::cout << DDLogicalPart(DDName("cone2", "testLogicalParts")) << std::endl;
0335   std::cout << std::endl;
0336   std::cout << "LogicalPart cone2hole:" << std::endl;
0337   std::cout << DDLogicalPart(DDName("cone2hole", "testLogicalParts")) << std::endl;
0338   std::cout << std::endl;
0339   std::cout << "LogicalPart pczsect:" << std::endl;
0340   std::cout << DDLogicalPart(DDName("pczsect", "testLogicalParts")) << std::endl;
0341   std::cout << std::endl;
0342   std::cout << "LogicalPart pcrz:" << std::endl;
0343   std::cout << DDLogicalPart(DDName("pcrz", "testLogicalParts")) << std::endl;
0344   std::cout << std::endl;
0345   std::cout << "LogicalPart phzsect:" << std::endl;
0346   std::cout << DDLogicalPart(DDName("phzsect", "testLogicalParts")) << std::endl;
0347   std::cout << std::endl;
0348   std::cout << "LogicalPart phrz:" << std::endl;
0349   std::cout << DDLogicalPart(DDName("phrz", "testLogicalParts")) << std::endl;
0350   std::cout << std::endl;
0351   std::cout << "LogicalPart trd1:";
0352   std::cout << DDLogicalPart(DDName("trd1", "testLogicalParts")) << std::endl;
0353   std::cout << std::endl;
0354   std::cout << "LogicalPart trd2:" << std::endl;
0355   std::cout << DDLogicalPart(DDName("trd2", "testLogicalParts")) << std::endl;
0356   std::cout << std::endl;
0357   std::cout << "LogicalPart tube1:" << std::endl;
0358   std::cout << DDLogicalPart(DDName("tube1", "testLogicalParts")) << std::endl;
0359   std::cout << std::endl;
0360   std::cout << "LogicalPart tube2:" << std::endl;
0361   std::cout << DDLogicalPart(DDName("tube2", "testLogicalParts")) << std::endl;
0362   std::cout << std::endl;
0363   std::cout << "LogicalPart trunctubs1:" << std::endl;
0364   std::cout << DDLogicalPart(DDName("trunctubs1", "testLogicalParts")) << std::endl;
0365   std::cout << std::endl;
0366   std::cout << "LogicalPart momma:" << std::endl;
0367   std::cout << DDLogicalPart(DDName("momma", "testLogicalParts")) << std::endl;
0368   std::cout << std::endl;
0369   std::cout << "LogicalPart MotherOfAllBoxes:" << std::endl;
0370   std::cout << DDLogicalPart(DDName("MotherOfAllBoxes", "testLogicalParts")) << std::endl;
0371   std::cout << std::endl;
0372   std::cout << "LogicalPart torus:" << std::endl;
0373   std::cout << DDLogicalPart(DDName("torus", "testLogicalParts")) << std::endl;
0374   std::cout << std::endl;
0375   std::cout << "LogicalPart trd2mirror:" << std::endl;
0376   std::cout << DDLogicalPart(DDName("trd2mirror", "testLogicalParts")) << std::endl;
0377   std::cout << std::endl;
0378   std::cout << "LogicalPart subsolid:" << std::endl;
0379   std::cout << DDLogicalPart(DDName("subsolid", "testLogicalParts")) << std::endl;
0380   std::cout << std::endl;
0381   std::cout << "LogicalPart unionsolid:" << std::endl;
0382   std::cout << DDLogicalPart(DDName("unionsolid", "testLogicalParts")) << std::endl;
0383   std::cout << std::endl;
0384   std::cout << "LogicalPart intsolid:" << std::endl;
0385   std::cout << DDLogicalPart(DDName("intsolid", "testLogicalParts")) << std::endl;
0386   std::cout << std::endl;
0387 }
0388 
0389 int main(int argc, char* argv[]) {
0390   std::string const kProgramName = argv[0];
0391   int rc = 0;
0392   if (argc < 2 || argc > 2) {
0393     std::cout << "This is a polite exit so that scram b runtests' first run of this program does not give an error"
0394               << std::endl;
0395     exit(0);  // SUCCESS;
0396   }
0397 
0398   try {
0399     edmplugin::PluginManager::configure(edmplugin::standard::config());
0400     std::cout << "Initialize a DDL parser " << std::endl;
0401     DDCompactView cpv;
0402     DDLParser myP(cpv);
0403     if (argc == 2) {
0404       DDLTestDoc dp;
0405 
0406       dp.readConfig(argv[1]);
0407       dp.dumpFileList();
0408 
0409       std::cout << "About to start parsing..." << std::endl;
0410 
0411       myP.parse(dp);
0412 
0413       std::cout << "Completed Parser" << std::endl;
0414 
0415       std::cout << std::endl << std::endl << "Start checking!" << std::endl << std::endl;
0416       std::cout << "Call DDCheckMaterials and other DDChecks." << std::endl;
0417       DDCheckMaterials(std::cout);
0418 
0419       std::cout << "======== Navigate a little bit  ======" << std::endl;
0420       try {
0421         if (!cpv.root().isDefined().second) {
0422           cpv.setRoot(DDRootDef::instance().root());
0423         }
0424         DDExpandedView ev(cpv);
0425         while (ev.next()) {
0426           std::cout << ev.geoHistory() << std::endl;
0427         }
0428       } catch (cms::Exception& e) {
0429         std::cout << e.what() << std::endl;
0430       }
0431       std::cout << "--------------- Parser testing started --------------" << std::endl;
0432       std::cout << std::endl << "Run the XML tests." << std::endl;
0433       testMaterials();
0434       testRotations();
0435       testSolids();
0436       testLogicalParts();
0437     } else if (argc < 3) {
0438       // scram b runtests for now this should not work.
0439       // just to have something!
0440       DDRootDef::instance().set(DDName("LP1", "testNoSections"));
0441 
0442       std::string fname = std::string(argv[1]);
0443       DDLTestDoc dp;
0444       while (fname != "q") {
0445         std::cout << "about to try to process the file " << fname << std::endl;
0446         dp.emplace_back(fname);
0447         myP.parse(dp);
0448         std::cout << "next file name:";
0449         std::cin >> fname;
0450         dp.clear();
0451       }
0452     }
0453   } catch (cms::Exception& e) {
0454     std::cout << "cms::Exception caught in " << kProgramName << "\n" << e.explainSelf();
0455     rc = 1;
0456   } catch (std::exception& e) {
0457     std::cout << "Standard library exception caught in " << kProgramName << "\n" << e.what();
0458     rc = 1;
0459   }
0460 
0461   return rc;
0462 }