CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/FWCore/Utilities/src/FriendlyName.cc

Go to the documentation of this file.
00001 /*
00002  *  friendlyName.cpp
00003  *  CMSSW
00004  *
00005  *  Created by Chris Jones on 2/24/06.
00006  *
00007  */
00008 #include <string>
00009 #include <boost/regex.hpp>
00010 #include <iostream>
00011 #include <map>
00012 #include "boost/thread/tss.hpp"
00013 
00014 //NOTE:  This should probably be rewritten so that we break the class name into a tree where the template arguments are the node.  On the way down the tree
00015 // we look for '<' or ',' and on the way up (caused by finding a '>') we can apply the transformation to the output string based on the class name for the
00016 // templated class.  Up front we'd register a class name to a transformation function (which would probably take a std::vector<std::string> which holds
00017 // the results of the node transformations)
00018 
00019 namespace edm {
00020   namespace friendlyname {
00021     static boost::regex const reBeginSpace("^ +");
00022     static boost::regex const reEndSpace(" +$");
00023     static boost::regex const reAllSpaces(" +");
00024     static boost::regex const reColons("::");
00025     static boost::regex const reComma(",");
00026     static boost::regex const reTemplateArgs("[^<]*<(.*)>$");
00027     static boost::regex const reTemplateClass("([^<>,]+<[^<>]*>)");
00028     static std::string const emptyString("");
00029 
00030     std::string handleNamespaces(std::string const& iIn) {
00031        return boost::regex_replace(iIn,reColons,emptyString,boost::format_perl);
00032 
00033     }
00034 
00035     std::string removeExtraSpaces(std::string const& iIn) {
00036        return boost::regex_replace(boost::regex_replace(iIn,reBeginSpace,emptyString),
00037                                     reEndSpace, emptyString);
00038     }
00039 
00040     std::string removeAllSpaces(std::string const& iIn) {
00041       return boost::regex_replace(iIn, reAllSpaces,emptyString);
00042     }
00043     static boost::regex const reWrapper("edm::Wrapper<(.*)>");
00044     static boost::regex const reString("std::basic_string<char>");
00045     static boost::regex const reSorted("edm::SortedCollection<(.*), *edm::StrictWeakOrdering<\\1 *> >");
00046     static boost::regex const reUnsigned("unsigned ");
00047     static boost::regex const reLong("long ");
00048     static boost::regex const reVector("std::vector");
00049     static boost::regex const reAIKR(", *edm::helper::AssociationIdenticalKeyReference"); //this is a default so can replaced with empty
00050     //force first argument to also be the argument to edm::ClonePolicy so that if OwnVector is within
00051     // a template it will not eat all the remaining '>'s
00052     static boost::regex const reOwnVector("edm::OwnVector<(.*), *edm::ClonePolicy<\\1 *> >");
00053 
00054     //NOTE: the '?' means make the smallest match. This may lead to problems where the template arguments themselves have commas
00055     // but we are using it in the cases where edm::AssociationMap appears multiple times in template arguments
00056     static boost::regex const reOneToOne("edm::AssociationMap< *edm::OneToOne<(.*?),(.*?), *u[a-z]*> >");
00057     static boost::regex const reOneToMany("edm::AssociationMap< *edm::OneToMany<(.*?),(.*?), *u[a-z]*> >");
00058     static boost::regex const reOneToValue("edm::AssociationMap< *edm::OneToValue<(.*?),(.*?), *u[a-z]*> >");
00059     static boost::regex const reOneToManyWithQuality("edm::AssociationMap<edm::OneToManyWithQuality<(.*?), *(.*?), *(.*?), *u[a-z]*> >");
00060     static boost::regex const reToVector("edm::AssociationVector<(.*), *(.*), *edm::Ref.*,.*>");
00061     //NOTE: if the item within a clone policy is a template, this substitution will probably fail
00062     static boost::regex const reToRangeMap("edm::RangeMap< *(.*), *(.*), *edm::ClonePolicy<([^>]*)> >");
00063     //NOTE: If container is a template with one argument which is its 'type' then can simplify name
00064     static boost::regex const reToRefs1("edm::RefVector< *(.*)< *(.*) *>, *\\2 *, *edm::refhelper::FindUsingAdvance< *\\1< *\\2 *> *, *\\2 *> *>");
00065     static boost::regex const reToRefs2("edm::RefVector< *(.*) *, *(.*) *, *edm::refhelper::FindUsingAdvance< *\\1, *\\2 *> *>");
00066     static boost::regex const reToRefsAssoc("edm::RefVector< *Association(.*) *, *edm::helper(.*), *Association(.*)::Find>");
00067     
00068     std::string standardRenames(std::string const& iIn) {
00069        using boost::regex_replace;
00070        using boost::regex;
00071        std::string name = regex_replace(iIn, reWrapper, "$1");
00072        name = regex_replace(name,reAIKR,"");
00073        name = regex_replace(name,reString,"String");
00074        name = regex_replace(name,reSorted,"sSorted<$1>");
00075        name = regex_replace(name,reUnsigned,"u");
00076        name = regex_replace(name,reLong,"l");
00077        name = regex_replace(name,reVector,"s");
00078        name = regex_replace(name,reOwnVector,"sOwned<$1>");
00079        name = regex_replace(name,reToVector,"AssociationVector<$1,To,$2>");
00080        name = regex_replace(name,reOneToOne,"Association<$1,ToOne,$2>");
00081        name = regex_replace(name,reOneToMany,"Association<$1,ToMany,$2>");
00082        name = regex_replace(name,reOneToValue,"Association<$1,ToValue,$2>");
00083        name = regex_replace(name,reOneToManyWithQuality,"Association<$1,ToMany,$2,WithQuantity,$3>");
00084        name = regex_replace(name,reToRangeMap,"RangeMap<$1,$2>");
00085        name = regex_replace(name,reToRefs1,"Refs<$1<$2>>");
00086        name = regex_replace(name,reToRefs2,"Refs<$1,$2>");
00087        name = regex_replace(name,reToRefsAssoc,"Refs<Association$1>");
00088        //std::cout <<"standardRenames '"<<name<<"'"<<std::endl;
00089        return name;
00090     }
00091 
00092     std::string handleTemplateArguments(std::string const&);
00093     std::string subFriendlyName(std::string const& iFullName) {
00094        using namespace boost;
00095        std::string result = removeExtraSpaces(iFullName);
00096 
00097        smatch theMatch;
00098        if(regex_match(result,theMatch,reTemplateArgs)) {
00099           //std::cout <<"found match \""<<theMatch.str(1) <<"\"" <<std::endl;
00100           //static regex const templateClosing(">$");
00101           //std::string aMatch = regex_replace(theMatch.str(1),templateClosing,"");
00102           std::string aMatch = theMatch.str(1);
00103           std::string theSub = handleTemplateArguments(aMatch);
00104           regex const eMatch(std::string("(^[^<]*)<")+aMatch+">");
00105           result = regex_replace(result,eMatch,theSub+"$1");
00106        }
00107        return result;
00108     }
00109 
00110     std::string handleTemplateArguments(std::string const& iIn) {
00111        using namespace boost;
00112        std::string result = removeExtraSpaces(iIn);
00113        bool shouldStop = false;
00114        while(!shouldStop) {
00115           if(std::string::npos != result.find_first_of("<")) {
00116              smatch theMatch;
00117              if(regex_search(result,theMatch,reTemplateClass)) {
00118                 std::string templateClass = theMatch.str(1);
00119                 std::string friendlierName = removeAllSpaces(subFriendlyName(templateClass));
00120                
00121                 //std::cout <<" t: "<<templateClass <<" f:"<<friendlierName<<std::endl;
00122                 result = regex_replace(result, regex(templateClass),friendlierName);
00123              } else {
00124                 //static regex const eComma(",");
00125                 //result = regex_replace(result,eComma,"");
00126                 std::cout <<" no template match for \""<<result<<"\""<<std::endl;
00127                 assert(0 =="failed to find a match for template class");
00128              }
00129           } else {
00130              shouldStop=true;
00131           }
00132        }
00133        result = regex_replace(result,reComma,"");
00134        return result;
00135     }
00136     std::string friendlyName(std::string const& iFullName) {
00137        typedef std::map<std::string, std::string> Map;
00138        static boost::thread_specific_ptr<Map> s_fillToFriendlyName;
00139        if(0 == s_fillToFriendlyName.get()){
00140           s_fillToFriendlyName.reset(new Map);
00141        }
00142        Map::const_iterator itFound = s_fillToFriendlyName->find(iFullName);
00143        if(s_fillToFriendlyName->end()==itFound) {
00144           itFound = s_fillToFriendlyName->insert(Map::value_type(iFullName, handleNamespaces(subFriendlyName(standardRenames(iFullName))))).first;
00145        }
00146        return itFound->second;
00147     }
00148   }
00149 } // namespace edm
00150