// @(#)root/core/utils:$Id: BaseSelectionRule.cxx 41697 2011-11-01 21:03:41Z pcanal $ // Author: Velislava Spasova September 2010 /************************************************************************* * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ ////////////////////////////////////////////////////////////////////////// // // // BaseSelectionRule // // // // Base selection class from which all // // selection classes should be derived // // // ////////////////////////////////////////////////////////////////////////// #include "BaseSelectionRule.h" #include #include #include "clang/AST/DeclCXX.h" const clang::CXXRecordDecl *R__SlowRawTypeSearch(const char *input_name, const clang::DeclContext *ctxt = 0); BaseSelectionRule::BaseSelectionRule(long index, BaseSelectionRule::ESelect sel, const std::string& attributeName, const std::string& attributeValue) : fIndex(index), fIsSelected(sel),fMatchFound(false),fCXXRecordDecl(0) { fAttributes.insert(AttributesMap_t::value_type(attributeName, attributeValue)); } void BaseSelectionRule::SetSelected(BaseSelectionRule::ESelect sel) { fIsSelected = sel; } BaseSelectionRule::ESelect BaseSelectionRule::GetSelected() const { return fIsSelected; } bool BaseSelectionRule::HasAttributeWithName(const std::string& attributeName) const { AttributesMap_t::const_iterator iter = fAttributes.find(attributeName); if(iter!=fAttributes.end()) return true; else return false; } bool BaseSelectionRule::GetAttributeValue(const std::string& attributeName, std::string& returnValue) const { AttributesMap_t::const_iterator iter = fAttributes.find(attributeName); if(iter!=fAttributes.end()) { returnValue = iter->second; return true; } else { returnValue = "No such attribute"; return false; } } void BaseSelectionRule::SetAttributeValue(const std::string& attributeName, const std::string& attributeValue) { fAttributes.insert(AttributesMap_t::value_type(attributeName, attributeValue)); int pos = attributeName.find("pattern"); int pos_file = attributeName.find("file_pattern"); if (pos > -1) { if (pos_file > -1) // if we have file_pattern ProcessPattern(attributeValue, fFileSubPatterns); else ProcessPattern(attributeValue, fSubPatterns); // if we have pattern and proto_pattern } } const BaseSelectionRule::AttributesMap_t& BaseSelectionRule::GetAttributes() const { return fAttributes; } void BaseSelectionRule::PrintAttributes(int level) const { std::string tabs; for (int i = 0; i < level; ++i) { tabs+='\t'; } if (!fAttributes.empty()) { for (AttributesMap_t::const_iterator iter = fAttributes.begin(); iter!=fAttributes.end(); ++iter) { std::cout<first<<" = "<second<(decl); if ( target && D && target == llvm::dyn_cast( D ) ) { // fprintf(stderr,"DECL MATCH: %s %s\n",name_value.c_str(),name.c_str()); has_name_rule = true; } } else if (HasAttributeWithName("name")) { if (name_value == name) { has_name_rule = true; } else { // Try a real match! const clang::CXXRecordDecl *D = llvm::dyn_cast(decl); const clang::CXXRecordDecl *target = R__SlowRawTypeSearch(name_value.c_str()); if ( target && D && target == llvm::dyn_cast( D ) ) { // fprintf(stderr,"DECL MATCH: %s %s\n",name_value.c_str(),name.c_str()); has_name_rule = true; } // if (strstr(name.c_str(),"std::vector") && name_value == "vv") { //// if (D) D->dump(); //// if (target) target->dump(); // fprintf(stderr,"\n vector %p %p %p\n",decl,D,target); // } } } if (HasAttributeWithName("pattern") && CheckPattern(name, pattern_value, fSubPatterns, isLinkdef)) { has_name_rule = true; } std::string proto_name_value; GetAttributeValue("proto_name", proto_name_value); std::string proto_pattern_value; GetAttributeValue("proto_pattern", proto_pattern_value); // do we have matching against the proto_name (or proto_pattern) attribute and if yes - select or veto bool has_proto_rule = false; if (!prototype.empty()) has_proto_rule = (HasAttributeWithName("proto_name") && (proto_name_value==prototype)) || (HasAttributeWithName("proto_pattern") && CheckPattern(prototype, proto_pattern_value, fSubPatterns, isLinkdef)); // do we have matching against the file_name (or file_pattern) attribute and if yes - select or veto std::string file_name_value; GetAttributeValue("file_name", file_name_value); std::string file_pattern_value; GetAttributeValue("file_pattern", file_pattern_value); bool has_file_rule; if (file_name.empty()) has_file_rule = false; else { has_file_rule = (HasAttributeWithName("file_name") && (file_name_value==file_name)) || (HasAttributeWithName("file_pattern") && CheckPattern(file_name, file_pattern_value, fFileSubPatterns, isLinkdef)); } if (has_file_rule) { // Reject utility class defined in ClassImp // when using a file based rule if (!strncmp(name.c_str(), "R__Init", 7) || strstr(name.c_str(), "::R__Init")) { noName = false; dontCare = false; file = true; return false; } } bool otherSourceFile = false; // if file_name is passed and we have file_name or file_pattern attribute but the // passed file_name is different than that in the selection rule than return false (=kNo) if (!file_name.empty() && (HasAttributeWithName("file_name")||HasAttributeWithName("file_pattern")) && !has_file_rule) otherSourceFile = true; if (otherSourceFile) { noName = false; dontCare = false; file = true; return false; } /* DEBUG if (has_name_rule) { if (HasAttributeWithName("name")) std::cout<<"\n\tname rule found: "<(this)->SetMatchFound(true); noName = false; switch(fIsSelected){ case kYes: return true; case kNo: dontCare = false; return false; case kDontCare: dontCare = true; return false; default: return false; } } else { // has_rule = false means that this selection rule isn't valid for our Decl noName = true; dontCare = false; return false; } } /* * This method processes the pattern - which means that it splits it in a list of fSubPatterns. * The idea is the following - if we have a pattern = "this*pat*rn", it will be split in the * following list of subpatterns: "this", "pat", "rn". If we have "this*pat\*rn", it will be * split in "this", "pat*rn", i.e. the star could be escaped. */ void BaseSelectionRule::ProcessPattern(const std::string& pattern, std::list& out) { std::string temp = pattern; std::string split; int pos; bool escape = false; if (pattern == "*"){ out.push_back(""); return; } while (!temp.empty()){ pos = temp.find("*"); if (pos == -1) { if (!escape){ // if we don't find a '*', push_back temp (contains the last sub-pattern) out.push_back(temp); std::cout<<"1. pushed = "< -1) { #ifdef SELECTION_DEBUG std::cout<<"\tNested - don't generate dict (ret false to isSelected)"< 1) { if ((int)((*it).length())+pos1 > pos_end) { // std::cout<<"\tNo match"; return false; // end is contained in begin -> test = "A::B" sub-patterns = "A::", "::" will return false } } ++it; for (; it != patterns_list.end(); ++it) { // std::cout<<"sub-pattern = "<<*it<