//----------------------------------------------------------- // Copyright Christian Arnault LAL-Orsay CNRS // arnault@lal.in2p3.fr // See the complete license in cmt_license.txt "http://www.cecill.info". //----------------------------------------------------------- #include #include #include #include #include "cmt_project.h" #include "cmt_database.h" #include "cmt_system.h" #include "cmt_awk.h" #include "cmt_syntax.h" #include "cmt_tag.h" class ProjectReader : public Awk { public: ProjectReader () { } const cmt_string& get_project_name () const { return (m_project); } void filter (const cmt_string& line) { CmtSystem::cmt_string_vector words; CmtSystem::split (line, " \t", words); if (words[0] == "project") { m_project = words[1]; } } private: cmt_string m_project; }; class ProjectPatcher : public Awk { public: ProjectPatcher (const cmt_string& p) : m_project (p) { } void commit () { m_output.write (Project::get_project_file_name ()); } void filter (const cmt_string& line) { if (m_output != "") { m_output += "\n"; } CmtSystem::cmt_string_vector words; CmtSystem::split (line, " \t", words); if (words[0] == "project") { m_output += "project "; m_output += m_project; } else { m_output += line; } } private: cmt_string m_output; const cmt_string& m_project; }; IProjectFactory& ProjectFactory::instance () { static ProjectFactory me; return (me); } void ProjectFactory::reset () { Project::clear_all (); m_first = 0; m_previous = 0; m_id = 0; } void ProjectFactory::create_project (const cmt_string& path, const cmt_string& source) { cmt_string compressed_path = path; CmtSystem::compress_path (compressed_path); static Project::ProjectVector& Projects = Project::projects (); for (int i = 0; i < Projects.size (); i++) { Project& p = Projects[i]; if (p.get_cmtpath () == compressed_path) return; if (p.get_cmtpath_pwd () == compressed_path) return; } Project* project = 0; Project* cmt = 0; bool is_current = false; cmt_string here = CmtSystem::pwd (); if (!CmtSystem::cd (compressed_path)) return; cmt_string pwd = CmtSystem::pwd (); if (here.find (pwd) == 0) is_current = true; cmt_string text; if (CmtSystem::cd ("cmt") && CmtSystem::test_file (Project::get_project_file_name ())) { text.read (Project::get_project_file_name ()); ProjectReader reader; reader.run (text); cmt_string name = reader.get_project_name (); if (name == "") { char buffer[20]; m_id++; sprintf (buffer, "Project%d", m_id); name = buffer; } project = Project::add (name); } else { char buffer[20]; if (source == "default path") { strcpy (buffer, "CMT"); } else { m_id++; sprintf (buffer, "Project%d", m_id); } project = Project::add (buffer); } if (source == "default path") { cmt = project; is_current = false; } else { if (m_first == 0) { m_first = project; } } project->set_cmtpath (compressed_path); project->set_cmtpath_pwd (pwd); project->set_cmtpath_source (source); if (is_current) { Tag* tag; tag = Tag::add (project->get_name (), PriorityConfig, "PROJECT", 0); tag->mark (); } if (m_previous != 0) m_previous->set_predecessor (project); m_previous = project; if (text != "") { SyntaxParser::parse_project_file_text (text, Project::get_project_file_name (), project); } CmtSystem::cd (here); } /*----------------------------------------------------------*/ /* */ /* Operations on Projects */ /* */ /*----------------------------------------------------------*/ //---------------------------------------------------------- void Project::create (const cmt_string& name) { cout << "------------------------------------------" << endl; cout << "Configuring environment for project " << name << endl; cout << "CMT version " << Cmt::get_cmt_version () << "." << endl; cout << "------------------------------------------" << endl; if (!CmtSystem::test_directory ("cmt")) { if (!CmtSystem::mkdir ("cmt")) { cout << "Cannot create the cmt directory" << endl; return; } else { cout << "Installing the cmt directory" << endl; } } CmtSystem::cd ("cmt"); if (!CmtSystem::test_file (get_project_file_name ())) { cout << "Creating a new project file" << endl; ofstream f (get_project_file_name ()); if (f) { f << "project " << name << endl; f << endl; f.close (); } } else { cmt_string text; text.read (get_project_file_name ()); ProjectPatcher p (name); p.run (text); p.commit (); cout << "project file already there" << endl; } } //---------------------------------------------------------- Project* Project::find_by_name (const cmt_string& name) { static ProjectVector& Projects = projects (); for (int i = 0; i < Projects.size (); i++) { Project& p = Projects[i]; if (p.m_name == name) return (&p); } return (0); } //---------------------------------------------------------- Project* Project::find_by_cmtpath (const cmt_string& cmtpath) { cmt_string compressed_path = cmtpath; CmtSystem::compress_path (compressed_path); static ProjectVector& Projects = projects (); for (int i = 0; i < Projects.size (); i++) { Project& p = Projects[i]; if (p.m_cmtpath == compressed_path) return (&p); if (p.m_cmtpath_pwd == compressed_path) return (&p); } return (0); } //---------------------------------------------------------- Project* Project::get_current () { cmt_string here = CmtSystem::pwd (); static ProjectVector& Projects = projects (); Project* result = 0; for (int i = (Projects.size () - 1); i >= 0; i--) { Project& p = Projects[i]; if (here.find (p.m_cmtpath_pwd) == 0) { result = &p; } if (here.find (p.m_cmtpath) == 0) { result = &p; } } return (result); } //---------------------------------------------------------- Project* Project::add (const cmt_string& name) { static ProjectVector& Projects = projects (); //cout << "Project::add> name=" << name << endl; { Project* project; project = find_by_name (name); if (project != 0) { Project& p = Projects.add (); project->set_reference (&p); p.set_name (name); return (&p); } } Project& project = Projects.add (); project.set_name (name); return (&project); } //---------------------------------------------------------- Project::ProjectVector& Project::projects () { static Database& db = Database::instance (); static ProjectVector& Projects = db.projects (); return (Projects); } /*----------------------------------------------------------*/ void Project::clear_all () { static ProjectVector& Projects = projects (); for (int i = 0; i < Projects.size (); i++) { Project& project = Projects[i]; project.clear (); } Projects.clear (); } /*----------------------------------------------------------*/ void Project::show_all () { static ProjectVector& Projects = projects (); for (int i = 0; i < Projects.size (); i++) { const Project& project = Projects[i]; project.show (); } } /*----------------------------------------------------------*/ void Project::show_paths () { static ProjectVector& Projects = projects (); if (!Cmt::get_quiet ()) { for (int i = 0; i < Projects.size (); i++) { const Project& project = Projects[i]; const cmt_string& path = project.get_cmtpath (); const cmt_string& source = project.get_cmtpath_source (); cout << "# Add path " << path << " from " << source << endl; } cout << "#" << endl; } for (int i = 0; i < Projects.size (); i++) { const Project& project = Projects[i]; const cmt_string& path = project.get_cmtpath (); const cmt_string& source = project.get_cmtpath_source (); if (i > 0) cout << CmtSystem::path_separator (); cout << path; } cout << endl; } //---------------------------------------------------------- const cmt_string& Project::get_project_file_name () { static const cmt_string name = "project.cmt"; return (name); } //---------------------------------------------------------- void Project::fill_selection (int depth, CmtSystem::cmt_string_vector& path_selections) { static ProjectVector& Projects = projects (); for (int i = 0; i < Projects.size (); i++) { Project& project = Projects[i]; const cmt_string& p = project.get_cmtpath (); const cmt_string& pwd = project.get_cmtpath_pwd (); const cmt_string& src = project.get_cmtpath_source (); if (src != "default path") { if (depth > 0) { cmt_string& s1 = path_selections.add (); s1 = p; cmt_string& s2 = path_selections.add (); s2 = pwd; depth--; if (depth == 0) break; } } } } //---------------------------------------------------------- void Project::broadcast (IProjectAction& action) { static ProjectVector& Projects = projects (); for (int i = 0; i < Projects.size (); i++) { const Project& project = Projects[i]; if (!action.run (project)) break; } } //---------------------------------------------------------- void Project::reverse_broadcast (IProjectAction& action) { static ProjectVector& Projects = projects (); for (int i = (Projects.size () - 1); i >= 0; i--) { const Project& project = Projects[i]; if (!action.run (project)) break; } } //---------------------------------------------------------- void Project::scan_paths (PathScanner& scanner, PathScanner::actor& a) { static ProjectVector& Projects = projects (); for (int i = 0; i < Projects.size (); i++) { const Project& project = Projects[i]; const cmt_string& p = project.m_cmtpath; scanner.scan_path (p, a); } } //---------------------------------------------------------- void Project::scan_paths_for_package (PathScanner& scanner, const cmt_string& name) { static ProjectVector& Projects = projects (); for (int i = 0; i < Projects.size (); i++) { const Project& project = Projects[i]; const cmt_string& p = project.m_cmtpath; scanner.scan_package (p, name); } } //---------------------------------------------------------- cmt_string Project::find_in_cmt_paths (const cmt_string& path) { const cmt_string pwd = CmtSystem::pwd (); static ProjectVector& Projects = projects (); for (int i = 0; i < Projects.size (); i++) { const Project& project = Projects[i]; const cmt_string& p = project.m_cmtpath; const cmt_string& w = project.m_cmtpath_pwd; const cmt_string& s = project.m_cmtpath_source; if (s == "default path") continue; if (CmtSystem::test_directory (p)) { if (path.find (p) != cmt_string::npos) { return (p); } // To become the current area, a path must correspond to the current package if (path.find (w) != cmt_string::npos) { return (p); } } if (p == w) continue; if (CmtSystem::test_directory (w)) { if (path.find (w) != cmt_string::npos) { return (w); } } } return (""); } //---------------------------------------------------------- Project::Project () : m_name (""), m_reference (0), m_predecessor (0) { clear (); } //---------------------------------------------------------- const cmt_string& Project::get_name () const { return (m_name); } //---------------------------------------------------------- const cmt_string& Project::get_cmtpath () const { return (m_cmtpath); } //---------------------------------------------------------- const cmt_string& Project::get_cmtpath_pwd () const { return (m_cmtpath_pwd); } //---------------------------------------------------------- const cmt_string& Project::get_cmtpath_source () const { return (m_cmtpath_source); } //---------------------------------------------------------- void Project::set_name (const cmt_string& name) { m_name = name; configure (); } //---------------------------------------------------------- void Project::set_cmtpath (const cmt_string& path) { m_cmtpath = path; } //---------------------------------------------------------- void Project::set_cmtpath_pwd (const cmt_string& path) { m_cmtpath_pwd = path; } //---------------------------------------------------------- void Project::set_cmtpath_source (const cmt_string& source) { m_cmtpath_source = source; } //---------------------------------------------------------- void Project::set_predecessor (Project* predecessor) { m_predecessor = predecessor; } //---------------------------------------------------------- void Project::set_reference (Project* reference) { m_reference = reference; } //---------------------------------------------------------- void Project::clear () { m_name = ""; m_cmtpath = ""; m_cmtpath_pwd = ""; m_cmtpath_source = ""; m_build_strategy_mask = 0; m_build_strategy = DefaultBuildStrategy; m_setup_strategy_mask = 0; m_setup_strategy = DefaultSetupStrategy; m_configured = false; m_prototypes_tag = 0; m_no_prototypes_tag = 0; m_with_installarea_tag = 0; m_without_installarea_tag = 0; m_setup_config_tag = 0; m_setup_no_config_tag = 0; m_setup_root_tag = 0; m_setup_no_root_tag = 0; m_setup_cleanup_tag = 0; m_setup_no_cleanup_tag = 0; } //---------------------------------------------------------- void Project::configure () { /* _prototypes _no_prototypes _rebuild_makefile _keep_makefile _with_installarea _without_installarea _setup_config _setup_no_config _setup_root _setup_no_root _setup_cleanup _setup_no_cleanup */ if (m_configured) return; m_configured = true; cmt_string tag_name; tag_name = m_name; tag_name += "_prototypes"; m_prototypes_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0); tag_name = m_name; tag_name += "_no_prototypes"; m_no_prototypes_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0); m_prototypes_tag->add_tag_exclude (m_no_prototypes_tag); m_no_prototypes_tag->add_tag_exclude (m_prototypes_tag); m_prototypes_tag->mark (); tag_name = m_name; tag_name += "_with_installarea"; m_with_installarea_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0); tag_name = m_name; tag_name += "_without_installarea"; m_without_installarea_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0); m_with_installarea_tag->add_tag_exclude (m_without_installarea_tag); m_without_installarea_tag->add_tag_exclude (m_with_installarea_tag); m_without_installarea_tag->mark (); tag_name = m_name; tag_name += "_setup_config"; m_setup_config_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0); tag_name = m_name; tag_name += "_setup_no_config"; m_setup_no_config_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0); m_setup_config_tag->add_tag_exclude (m_setup_no_config_tag); m_setup_no_config_tag->add_tag_exclude (m_setup_config_tag); m_setup_config_tag->mark (); tag_name = m_name; tag_name += "_setup_root"; m_setup_root_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0); tag_name = m_name; tag_name += "_setup_no_root"; m_setup_no_root_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0); m_setup_root_tag->add_tag_exclude (m_setup_no_root_tag); m_setup_no_root_tag->add_tag_exclude (m_setup_root_tag); m_setup_root_tag->mark (); tag_name = m_name; tag_name += "_setup_cleanup"; m_setup_cleanup_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0); tag_name = m_name; tag_name += "_setup_no_cleanup"; m_setup_no_cleanup_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0); m_setup_cleanup_tag->add_tag_exclude (m_setup_no_cleanup_tag); m_setup_no_cleanup_tag->add_tag_exclude (m_setup_cleanup_tag); m_setup_cleanup_tag->mark (); if (Cmt::get_debug ()) { cout << "Project::configure> " << m_name << " " << m_prototypes_tag << " " << m_no_prototypes_tag << " " << m_with_installarea_tag << " " << m_without_installarea_tag << " " << m_setup_config_tag << " " << m_setup_no_config_tag << " " << m_setup_root_tag << " " << m_setup_no_root_tag << " " << m_setup_cleanup_tag << " " << m_setup_no_cleanup_tag << endl; } } //---------------------------------------------------------- Project& Project::operator = (const Project& other) { m_name = other.m_name; m_cmtpath = other.m_cmtpath; m_cmtpath_pwd = other.m_cmtpath_pwd; m_cmtpath_source = other.m_cmtpath_source; return (*this); } //---------------------------------------------------------- bool Project::operator == (const cmt_string& name) const { return ((m_name == name)); } //---------------------------------------------------------- bool Project::operator != (const cmt_string& name) const { return ((m_name != name)); } //---------------------------------------------------------- void Project::show () const { bool is_current = false; cmt_string here = CmtSystem::pwd (); if (here.find (m_cmtpath) == 0) { if (m_cmtpath_source != "default path") { is_current = true; } } cout << m_name << " (in " << m_cmtpath << ")"; if (is_current) cout << " (current)"; cout << endl; } //---------------------------------------------------------- void Project::show_strategies () const { } //---------------------------------------------------------- int Project::get_build_strategy () const { int result = 0; if (m_reference != 0) result = m_reference->get_build_strategy (); else if (m_predecessor != 0) result = m_predecessor->get_build_strategy (); else result = Cmt::get_current_build_strategy (); if (m_build_strategy_mask != 0) { result &= ~m_build_strategy_mask; result |= m_build_strategy; } return (result); } //---------------------------------------------------------- int Project::get_setup_strategy () const { int result = 0; if (m_reference != 0) result = m_reference->get_setup_strategy (); else if (m_predecessor != 0) result = m_predecessor->get_setup_strategy (); else result = Cmt::get_current_setup_strategy (); if (m_setup_strategy_mask != 0) { result &= ~m_setup_strategy_mask; result |= m_setup_strategy; } return (result); } //---------------------------------------------------------- void Project::set_build_strategy (int mask, int strategy) { m_build_strategy_mask |= mask; m_build_strategy &= ~mask; m_build_strategy |= strategy; cmt_string to_tag_name = m_name; cmt_string to_untag_name = m_name; Tag* to_tag = 0; Tag* to_untag = 0; switch (strategy) { case Prototypes: to_tag_name += "_prototypes"; to_untag_name += "_no_prototypes"; break; case NoPrototypes: to_tag_name += "_no_prototypes"; to_untag_name += "_prototypes"; break; case WithInstallArea: to_tag_name += "_with_installarea"; to_untag_name += "_without_installarea"; break; case WithoutInstallArea: to_tag_name += "_without_installarea"; to_untag_name += "_with_installarea"; break; } to_tag = Tag::find (to_tag_name); to_untag = Tag::find (to_untag_name); if (to_untag != 0) { to_untag->unmark (); } if (to_tag != 0) { to_tag->mark (); } static ProjectVector& Projects = projects (); for (int i = 0; i < Projects.size (); i++) { Project& project = Projects[i]; if ((project.m_predecessor == this) || (project.m_reference == this)) { if ((project.m_build_strategy_mask & mask) == 0) { project.set_build_strategy (mask, strategy); } } } } //---------------------------------------------------------- void Project::set_setup_strategy (int mask, int strategy) { m_setup_strategy_mask |= mask; m_setup_strategy &= ~mask; m_setup_strategy |= strategy; cmt_string to_tag_name = m_name; cmt_string to_untag_name = m_name; Tag* to_tag = 0; Tag* to_untag = 0; switch (strategy) { case SetupConfig: to_tag_name += "_setup_config"; to_untag_name += "_setup_no_config"; break; case SetupNoConfig: to_tag_name += "_setup_no_config"; to_untag_name += "_setup_config"; break; case SetupRoot: to_tag_name += "_setup_root"; to_untag_name += "_setup_no_root"; break; case SetupNoRoot: to_tag_name += "_setup_no_root"; to_untag_name += "_setup_root"; break; case SetupCleanup: to_tag_name += "_setup_cleanup"; to_untag_name += "_setup_no_cleanup"; break; case SetupNoCleanup: to_tag_name += "_setup_no_cleanup"; to_untag_name += "_setup_cleanup"; break; } to_tag = Tag::find (to_tag_name); to_untag = Tag::find (to_untag_name); if (to_untag != 0) { to_untag->unmark (); } if (to_tag != 0) { to_tag->mark (); } static ProjectVector& Projects = projects (); for (int i = 0; i < Projects.size (); i++) { Project& project = Projects[i]; if ((project.m_predecessor == this) || (project.m_reference == this)) { if ((project.m_setup_strategy_mask & mask) == 0) { project.set_setup_strategy (mask, strategy); } } } }