//----------------------------------------------------------- // Copyright Christian Arnault LAL-Orsay CNRS // arnault@lal.in2p3.fr // See the complete license in cmt_license.txt "http://www.cecill.info". //----------------------------------------------------------- #include "cmt_database.h" #include "cmt_cmtpath_pattern.h" #include "cmt_syntax.h" //---------------------------------------------------------- // // Operations on CmtPathPatterns // //---------------------------------------------------------- void CmtPathPattern::action (const CmtSystem::cmt_string_vector& words, Use* use) { if (words.size () < 1) return; // // expected syntax is: // // cmtpath_pattern any-cmt-statement // // where any-cmt-statement may contain the "template" // // // // add (words, use); if (Cmt::get_debug ()) { cout << "CmtPathPattern::action> add " << endl; } } void CmtPathPattern::add (const CmtSystem::cmt_string_vector& words, Use* use) { static CmtPathPatternVector& CmtPathPatterns = patterns (); CmtPathPattern& p = CmtPathPatterns.add (); p.clear (); p.use = use; int first_word = 1; // // Install the cmt-statement as a vector of words. // for (int i = first_word; i < words.size (); i++) { bool need_quotes = (i > (first_word + 1)); cmt_string& s = words[i]; if (i > first_word) p.line += " "; if (s == ";") first_word = i+1; if ((s == "\n") | (s == ";")) { p.line += "\n "; } else { cmt_string sep = "\""; if (s.find (sep) != cmt_string::npos) { sep = "\'"; } if (!need_quotes) sep = ""; p.line += sep; p.line += s; p.line += sep; } } } /** * Get the number of registered patterns */ int CmtPathPattern::pattern_number () { static CmtPathPatternVector& CmtPathPatterns = patterns (); return (CmtPathPatterns.size ()); } /** * Get the index'th pattern in the database */ CmtPathPattern& CmtPathPattern::pattern (int index) { static CmtPathPatternVector& CmtPathPatterns = patterns (); return (CmtPathPatterns[index]); } void CmtPathPattern::clear_all () { static CmtPathPatternVector& CmtPathPatterns = patterns (); for (int i = 0; i < CmtPathPatterns.size (); i++) { CmtPathPattern& p = CmtPathPatterns[i]; p.clear (); } CmtPathPatterns.clear (); } CmtPathPattern::CmtPathPatternVector& CmtPathPattern::patterns () { static Database& db = Database::instance (); static CmtPathPatternVector& CmtPathPatterns = db.cmtpath_patterns (); return (CmtPathPatterns); } /** * Applies all patterns to all CMTPATH item */ void CmtPathPattern::apply_all () { static CmtPathPatternVector& CmtPathPatterns = patterns (); int i; for (i = 0; i < CmtPathPatterns.size (); i++) { CmtPathPattern& p = CmtPathPatterns[i]; p.apply (); } } /** * this is the cmt show cmtpath_patterns command * It just shows the cmtpath_pattern declarations. */ void CmtPathPattern::show_all () { static CmtPathPatternVector& CmtPathPatterns = patterns (); int i; for (i = 0; i < CmtPathPatterns.size (); i++) { CmtPathPattern& p = CmtPathPatterns[i]; cout << "# " << p.use->get_package_name () << " " << p.use->version << " adds a cmtpath_pattern as " << endl; cout << " " << p.line << endl; } } //---------------------------------------------------------- CmtPathPattern::CmtPathPattern () { } //---------------------------------------------------------- CmtPathPattern::~CmtPathPattern () { } //---------------------------------------------------------- void CmtPathPattern::clear () { use = 0; line = ""; } class CmtPathPatternProjectAction : public IProjectAction { public: CmtPathPatternProjectAction (const CmtPathPattern& pattern, Use& use) : m_pattern (pattern), m_current (use) { } bool run (const Project& project) { const cmt_string& pname = project.get_name (); const cmt_string& p = project.get_cmtpath (); const cmt_string& s = project.get_cmtpath_source (); if (s == "default path") return (true); m_pattern.expand (m_buffer, p, pname); if (Cmt::get_debug ()) { cout << "CmtPathPattern::apply> text=[" << m_buffer << "]" << endl; } SyntaxParser::parse_requirements_text (m_buffer, "", &m_current); m_buffer = ""; return (true); } private: const CmtPathPattern& m_pattern; Use& m_current; cmt_string m_buffer; }; /** * Applies a pattern to all CMTPATH entries. */ void CmtPathPattern::apply () const { if (Cmt::get_debug ()) { cout << "CmtPathPattern::apply> cmtpath_pattern defined in " << use->get_package_name () << endl; } Use& current_use = Use::current (); bool is_constant = ((line.find ("") == cmt_string::npos) && (line.find ("") == cmt_string::npos)); if (is_constant) { cmt_string buffer; expand (buffer, "", ""); if (Cmt::get_debug ()) { cout << "CmtPathPattern::apply> text=[" << buffer << "]" << endl; } SyntaxParser::parse_requirements_text (buffer, "", ¤t_use); buffer = ""; } else { CmtPathPatternProjectAction pa (*this, current_use); Project::reverse_broadcast (pa); } } void CmtPathPattern::expand (cmt_string& replacement, const cmt_string& path, const cmt_string& project) const { replacement = line; if (replacement != "") { // Substitute template from the cmt statement replacement.replace_all ("", path.c_str ()); replacement.replace_all ("", project.c_str ()); } }