//----------------------------------------------------------- // Copyright Christian Arnault LAL-Orsay CNRS // arnault@lal.in2p3.fr // Modified by garonne@lal.in2p3.fr // Modified by Grigory Rybkin // See the complete license in cmt_license.txt "http://www.cecill.info". //----------------------------------------------------------- #include "cmt_syntax.h" #include "cmt.h" #include "cmt_symbol.h" #include "cmt_constituent.h" #include "cmt_pattern.h" #include "cmt_error.h" #include "cmt_branch.h" #include "cmt_error.h" #include "cmt_script.h" #include "cmt_language.h" #include "cmt_project.h" #include "cmt_cmtpath_pattern.h" #include "cmt_log.h" class KwdAction : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandAction, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdAlias : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandAlias, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdApplication : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { if (use == &(Use::current ())) { Constituent::action (Application, words); } } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdApplyPattern : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { ApplyPattern::action (words, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdApplyTag : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Tag::action_apply (words, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { action (words, project->get_use(), file_name, line_number); } }; //---------------------------------------------------------- class KwdAuthor : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { use->author_action (words); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { cmt_string author; project->project_author_action (words); } }; //---------------------------------------------------------- class KwdBranches : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { if (use == &(Use::current ())) { Branch::action (words); } } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdBuildStrategy : public Kwd { public: bool decode (const cmt_string& w, cmt_string& strategy, cmt_string& value) { bool result = true; value = w; /*Symbol* symbol = Symbol::find ("use_strategy"); if (symbol != 0) { cmt_string s = symbol->build_macro_value (); Symbol::expand (s); cerr <<"# value s: "<get_cmtpath_and_offset (cmtpath, offset); Project* p = Project::find_by_cmtpath (cmtpath); */ Project* p = const_cast(use->get_project ()); // const Project* p = use->get_project (); for (int i = 1; i < words.size (); i++) { const cmt_string& w = words[i]; cmt_string strategy; cmt_string value; bool in_error = false; if (decode (w, strategy, value)) { if (p != 0) p->set_strategy (strategy, value, use->get_package_name ()); } else { in_error = true; CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword"); } } } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { // action (words, project->get_use(), file_name, line_number); // cerr << project->get_use()->get_strategy ("InstallArea") << endl; for (int i = 1; i < words.size (); i++) { const cmt_string& w = words[i]; cmt_string strategy; cmt_string value; bool in_error = false; if (decode (w, strategy, value)) { if (project != 0) { // project->set_strategy (strategy, value, project->get_use()->get_package_name ()); project->set_strategy (strategy, value, ""); cmt_string s = "build_strategy "; s += words[i]; s += "\n"; bool no_found = true; int size = project->m_extra_lines.size (); for (int n = 0; n < size; n++) { if (s==project->m_extra_lines[n]) no_found = false; } if (no_found) { cmt_string & buffer = project->m_extra_lines.add(); buffer = s; } } } else { in_error = true; char num[32]; sprintf (num, "%d", line_number); CmtError::set (CmtError::syntax_error, project->get_name () + " project file: " + file_name + ": line: " + num + ": " + value + ": Bad strategy value"); //CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword"); } } } }; class KwdCleanupScript : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Script::action (words, CleanupScript, use); Symbol::action (words, CommandCleanupScript, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdCmtPathPattern : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& /*file_name*/, int /*line_number*/) { CmtPathPattern::action (words, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdCmtPathPatternRevert : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& /*file_name*/, int /*line_number*/) { CmtPathPattern::action (words, use, true); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdContainer : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { project->container_action (words); //project->container_action (words[1], words[2]); } }; class KwdDocument : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { if (use == &(Use::current ())) { Constituent::action (Document, words); } } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdEndPrivate : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { if (use != &(Use::current ())) { use->pop_scope_section (); } } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdEndPublic : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { if (use != &(Use::current ())) { use->pop_scope_section (); } } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdIgnorePattern : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { IgnorePattern::action (words, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdIncludeDirs : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Include::action (words, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdIncludePath : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { if (words.size () > 1) { use->set_include_path (words[1]); } } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdLanguage : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Language::action (words, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdLibrary : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { if (use == &(Use::current ())) { Constituent::action (Library, words); } } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdMacro : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandMacro, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { action (words, project->get_use(), file_name, line_number); } }; class KwdMacroPrepend : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandMacroPrepend, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { action (words, project->get_use(), file_name, line_number); } }; class KwdMacroAppend : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandMacroAppend, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { action (words, project->get_use(), file_name, line_number); } }; class KwdMacroRemove : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandMacroRemove, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { action (words, project->get_use(), file_name, line_number); } }; class KwdMacroRemoveRegexp : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandMacroRemoveRegexp, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { action (words, project->get_use(), file_name, line_number); } }; class KwdMacroRemoveAll : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandMacroRemoveAll, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { action (words, project->get_use(), file_name, line_number); } }; class KwdMacroRemoveAllRegexp : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandMacroRemoveAllRegexp, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { action (words, project->get_use(), file_name, line_number); } }; class KwdMakeFragment : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Fragment::action (words, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdManager : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { use->manager_action (words); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdPackage : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { /* if (words.size () > 1) { if (use == &(Use::current())) { m_current_package = words[1]; build_prefix (m_current_package, m_current_prefix); if ((use->get_package_name () != "") && (use->get_package_name () != m_current_package)) { if (!m_quiet) { // cerr << "#CMT> package name mismatch in requirements of " << // use->get_package_name () << " " << // use->version << " line #" << line_number; // cerr << " : " << m_current_package << " versus " << // use->get_package_name () << endl; } } use->set (m_current_package, m_current_version, m_current_path, "", ""); use->change_path (m_current_path); use->style = m_current_style; } } */ } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdPath : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandPath, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdPathAppend : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandPathAppend, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdPathPrepend : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandPathPrepend, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdPathRemove : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandPathRemove, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdPathRemoveRegexp : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandPathRemoveRegexp, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdPattern : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Pattern::action (words, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdPrivate : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { if (use != &(Use::current ())) { use->push_scope_section (ScopePrivate); } } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdProject : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { } }; class KwdPublic : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { if (use != &(Use::current ())) { use->push_scope_section (ScopePublic); } } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdSet : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandSet, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdSetAppend : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandSetAppend, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdSetPrepend : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandSetPrepend, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdSetRemove : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandSetRemove, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdSetRemoveRegexp : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Symbol::action (words, CommandSetRemoveRegexp, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdSetupScript : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Script::action (words, SetupScript, use); Symbol::action (words, CommandSetupScript, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdSetupStrategy : public Kwd { public: bool decode (const cmt_string& w, cmt_string& strategy, cmt_string& value) { bool result = true; value = w; Symbol::expand(value); if (value == "config") { strategy = "SetupConfig"; } else if (value == "no_config") { strategy = "SetupConfig"; } else if (value == "root") { strategy = "SetupRoot"; } else if (value == "no_root") { strategy = "SetupRoot"; } else if (value == "cleanup") { strategy = "SetupCleanup"; } else if (value == "no_cleanup") { strategy = "SetupCleanup"; } else if (value == "scripts") { strategy = "SetupScripts"; } else if (value == "no_scripts") { strategy = "SetupScripts"; } else { result = false; } return (result); } void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { /* cmt_string cmtpath; cmt_string offset; use->get_cmtpath_and_offset (cmtpath, offset); Project* p = Project::find_by_cmtpath (cmtpath); */ Project* p = const_cast(use->get_project ()); // const Project* p = use->get_project (); for (int i = 1; i < words.size (); i++) { const cmt_string& w = words[i]; cmt_string strategy; cmt_string value; bool in_error = false; if (decode (w, strategy, value)) { if (p != 0) p->set_strategy (strategy, value, use->get_package_name ()); } else { in_error = true; CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword"); } } } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { for (int i = 1; i < words.size (); i++) { const cmt_string& w = words[i]; cmt_string strategy; cmt_string value; bool in_error = false; if (decode (w, strategy, value)) { if (project != 0) project->set_strategy (strategy, value, ""); cmt_string s = "setup_strategy "; s += words[i]; s += "\n"; bool no_found = true; int size = project->m_extra_lines.size (); for (int n = 0; n < size; n++) { if (s==project->m_extra_lines[n]) no_found = false; } if (no_found) { cmt_string & buffer = project->m_extra_lines.add(); buffer = s; } } else { in_error = true; char num[32]; sprintf (num, "%d", line_number); CmtError::set (CmtError::syntax_error, project->get_name () + " project file: " + file_name + ": line: " + num + ": " + value + ": Bad strategy value"); //CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword"); } } } }; class KwdStructureStrategy : public Kwd { public: bool decode (const cmt_string& w, cmt_string& strategy, cmt_string& value) { bool result = true; value = w; Symbol::expand(value); if (value == "with_version_directory") { strategy = "VersionDirectory"; } else if (value == "without_version_directory") { strategy = "VersionDirectory"; } else { result = false; } return (result); } void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { /* cmt_string cmtpath; cmt_string offset; use->get_cmtpath_and_offset (cmtpath, offset); Project* p = Project::find_by_cmtpath (cmtpath); */ Project* p = const_cast(use->get_project ()); // const Project* p = use->get_project (); for (int i = 1; i < words.size (); i++) { const cmt_string& w = words[i]; cmt_string strategy; cmt_string value; bool in_error = false; if (decode (w, strategy, value)) { if (p != 0) p->set_strategy (strategy, value, use->get_package_name ()); } else { in_error = true; CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword"); } } } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { for (int i = 1; i < words.size (); i++) { const cmt_string& w = words[i]; cmt_string strategy; cmt_string value; bool in_error = false; if (decode (w, strategy, value)) { if (project != 0) project->set_strategy (strategy, value, ""); cmt_string s = "structure_strategy "; s += words[i]; s += "\n"; bool no_found = true; int size = project->m_extra_lines.size (); for (int n = 0; n < size; n++) { if (s == project->m_extra_lines[n]) no_found = false; } if (no_found) { cmt_string & buffer = project->m_extra_lines.add(); buffer = s; } } else { in_error = true; char num[32]; sprintf (num, "%d", line_number); CmtError::set (CmtError::syntax_error, project->get_name () + " project file: " + file_name + ": line: " + num + ": " + value + ": Bad strategy value"); //CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword"); } } } }; class KwdTag : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Tag::action (words, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { action (words, project->get_use(), file_name, line_number); } }; class KwdTagExclude : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Tag::action_exclude (words, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { action (words, project->get_use(), file_name, line_number); } }; class KwdUse : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { Use::action (words, use); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) { project->use_action (words[1], words[2]); } }; class KwdVersionStrategy : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { CmtMessage::warning ("Package " + use->get_package_name () + " sets obsolescent version strategy"); // cerr << "# Package " << use->get_package_name () << // " sets obsolescent version strategy" << endl; } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdVersion : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {} }; class KwdDefault : public Kwd { public: void action (const CmtSystem::cmt_string_vector& words, Use* use, const cmt_string& file_name, int line_number) { /* Unknown keyword : just ignore the line */ char num[32]; sprintf (num, "%d", line_number); CmtMessage::error ("bad syntax in requirements of " + use->get_package_name () + " " + use->version + " line #" + num + " [" + words[0] + "...]"); /* if (!Cmt::get_quiet ()) { cerr << "#CMT> bad syntax in requirements of " << use->get_package_name () << " " << use->version << " line #" << line_number; cerr << " [" << words[0] << "...]" << endl; } */ CmtError::set (CmtError::syntax_error, "ParseRequirements> "); } void action (const CmtSystem::cmt_string_vector& words, Project* project, const cmt_string& file_name, int line_number) {action (words, project->get_use(), file_name, line_number);} }; SyntaxParser& SyntaxParser::instance () { static SyntaxParser p; return (p); } /** * Parse the input file, rejecting comments and * rebuilding complete lines (from sections separated by * \\ characters. * * Each reformatted line is parsed by filter_line */ void SyntaxParser::parse_requirements (const cmt_string& file_name, Use* use) { SyntaxParser& me = instance (); if (use != 0) { cmt_string buffer; use->fill_standard_macros (buffer); AccessMode saved_current_access = Cmt::get_current_access (); Cmt::set_current_access (UserMode); me.do_parse_text (buffer, "", package_context, use, 0); Cmt::set_current_access (saved_current_access); } me.do_parse_requirements (file_name, use); if (use != 0) { // const Project* p = use->get_project (); if (p != 0) { Use* p_use = p->get_use(); if (p_use != 0 && p_use != use) { //{ // int size = use->sub_uses.size (); // for (int n = 0; n < size; n++) // { // Use* tuse = use->sub_uses[n]; // cerr << "\tpackage file [" << tuse->get_package_name() << "]" <get_package_name()<< endl; // } //} // add the dependency use->add_sub_use (p_use); // add the right extra statements { int size = p->m_extra_lines.size (); for (int n = 0; n < size; n++) { cmt_string& s = p->m_extra_lines[n]; SyntaxParser::parse_requirements_line (s, use); } } // Fill other values use->sub_use_scopes.push_back (use->get_current_scope ()); use->sub_use_auto_imports.push_back (p_use->auto_imports); // cmt_string& request = use->requests.add (); // request = package_name; // request += " "; // request += version; // request += " "; // request += path; // add at the uses level ????? static Use::UsePtrVector& uses = Use::get_ordered_uses (); //const Use& cu = Use::current (); bool found = false; int size = uses.size (); // cerr << "\n size:"<get_package_name() << "]" <get_package_name()<< endl; if (tuse->get_package_name()==p_use->get_package_name()) found=true; } if (! found) { uses.push_back (p_use); p_use->m_index = uses.size () - 1; } } // Apply tag container_package if // the current package is the container package of the project if (use == &(Use::current ()) && use->get_package_name() == p->get_container ().get_package_name () && use->version == p->get_container ().version) { cmt_string name ("container_package"); cmt_string context (p->get_name ()); Tag* tag = Tag::find (name); if (tag == 0) { tag = Tag::add (name, PriorityUserTag, context, use); } tag->mark (use->get_package_name()); } } use->close_scope_sections (); } } /** */ void SyntaxParser::parse_project_file_text (const cmt_string& text, const cmt_string& file_name, Project* project) { SyntaxParser& me = instance (); me.do_parse_text (text, file_name, project_context, 0, project); } /** * Parse a text, rejecting comments and * rebuilding complete lines (from sections separated by * \\ characters. * * Each reformatted line is parsed by filter_line */ void SyntaxParser::parse_requirements_text (const cmt_string& text, const cmt_string& file_name, Use* use) { SyntaxParser& me = instance (); /** * * We have to preserve m_current_access since it reflects whether * the current cmt action is run in the context of the current package. * (the opposite is when the cmt command specifies the current package * in its arguments -use=... therefore the pwd is NOT the directory * of the current package) * * m_current_access is Developer when pwd = current * User when pwd != current * * Therefore, as soon as we reach a used package, this must be switched to User * * On the other hand, Cmt::scope reflects the status of the public/private * statements. By default, we are in public context when entering a new requirements * file. * */ AccessMode saved_current_access; saved_current_access = Cmt::get_current_access (); if (use == 0) use = &(Use::current ()); if (use != &(Use::current ())) { if (Cmt::get_debug ()) { cout << "parse_requirements_text> set UserMode" << endl; } Cmt::set_current_access (UserMode); } else { if (Cmt::get_debug ()) { cout << "parse_requirements_text> set DeveloperMode" << endl; } Cmt::set_current_access (DeveloperMode); } me.do_parse_text (text, file_name, package_context, use, 0); Cmt::set_current_access (saved_current_access); } /** * Apply the basic parser to one single line : * * o Append to global text if previous back_slash * o Split into words * o Apply the generic Select operator */ void SyntaxParser::parse_requirements_line (const cmt_string& line, Use* use, const cmt_string& file_name, int line_number) { SyntaxParser& me = instance (); me.do_parse_line (line, file_name, line_number, package_context, use, 0); } SyntaxParser::SyntaxParser () { m_keywords.add ("action", new KwdAction ()); m_keywords.add ("alias", new KwdAlias ()); m_keywords.add ("application", new KwdApplication ()); m_keywords.add ("apply_pattern", new KwdApplyPattern ()); m_keywords.add ("apply_tag", new KwdApplyTag ()); m_keywords.add ("author", new KwdAuthor ()); m_keywords.add ("branches", new KwdBranches ()); m_keywords.add ("build_strategy", new KwdBuildStrategy ()); m_keywords.add ("cleanup_script", new KwdCleanupScript ()); m_keywords.add ("cmtpath_pattern", new KwdCmtPathPattern ()); m_keywords.add ("cmtpath_pattern_reverse", new KwdCmtPathPatternRevert ()); m_keywords.add ("document", new KwdDocument ()); m_keywords.add ("end_private", new KwdEndPrivate ()); m_keywords.add ("end_public", new KwdEndPublic ()); m_keywords.add ("ignore_pattern", new KwdIgnorePattern ()); m_keywords.add ("include_dirs", new KwdIncludeDirs ()); m_keywords.add ("include_path", new KwdIncludePath ()); m_keywords.add ("language", new KwdLanguage ()); m_keywords.add ("library", new KwdLibrary ()); m_keywords.add ("macro", new KwdMacro ()); m_keywords.add ("macro+", new KwdMacroAppend ()); m_keywords.add ("macro_prepend", new KwdMacroPrepend ()); m_keywords.add ("macro_append", new KwdMacroAppend ()); m_keywords.add ("macro_remove", new KwdMacroRemove ()); m_keywords.add ("macro_remove_regexp", new KwdMacroRemoveRegexp ()); m_keywords.add ("macro_remove_all", new KwdMacroRemoveAll ()); m_keywords.add ("macro_remove_all_regexp", new KwdMacroRemoveAllRegexp ()); m_keywords.add ("make_fragment", new KwdMakeFragment ()); m_keywords.add ("manager", new KwdManager ()); m_keywords.add ("package", new KwdPackage ()); m_keywords.add ("path", new KwdPath ()); m_keywords.add ("path_append", new KwdPathAppend ()); m_keywords.add ("path_prepend", new KwdPathPrepend ()); m_keywords.add ("path_remove", new KwdPathRemove ()); m_keywords.add ("path_remove_regexp", new KwdPathRemoveRegexp ()); m_keywords.add ("pattern", new KwdPattern ()); m_keywords.add ("public", new KwdPublic ()); m_keywords.add ("private", new KwdPrivate ()); m_keywords.add ("project", new KwdProject ()); m_keywords.add ("set", new KwdSet ()); m_keywords.add ("set_append", new KwdSetAppend ()); m_keywords.add ("set_prepend", new KwdSetPrepend ()); m_keywords.add ("set_remove", new KwdSetRemove ()); m_keywords.add ("set_remove_regexp", new KwdSetRemoveRegexp ()); m_keywords.add ("setup_script", new KwdSetupScript ()); m_keywords.add ("setup_strategy", new KwdSetupStrategy ()); m_keywords.add ("structure_strategy", new KwdStructureStrategy ()); m_keywords.add ("tag", new KwdTag ()); m_keywords.add ("tag_exclude", new KwdTagExclude ()); m_keywords.add ("use", new KwdUse ()); m_keywords.add ("version_strategy", new KwdVersionStrategy ()); m_keywords.add ("version", new KwdVersion ()); m_project_keywords.add ("author", new KwdAuthor()); m_project_keywords.add ("apply_tag", new KwdApplyTag ()); m_project_keywords.add ("build_strategy", new KwdBuildStrategy ()); m_project_keywords.add ("container", new KwdContainer ()); m_project_keywords.add ("macro", new KwdMacro ()); // m_project_keywords.add ("macro+", new KwdMacroAppend ()); // m_project_keywords.add ("macro_prepend", new KwdMacroPrepend ()); // m_project_keywords.add ("macro_append", new KwdMacroAppend ()); //m_project_keywords.add ("macro_remove", new KwdMacroRemove ()); //m_project_keywords.add ("macro_remove_regexp", new KwdMacroRemoveRegexp ()); //m_project_keywords.add ("macro_remove_all", new KwdMacroRemoveAll ()); //m_project_keywords.add ("macro_remove_all_regexp", new KwdMacroRemoveAllRegexp ()); m_project_keywords.add ("project", new KwdProject ()); m_project_keywords.add ("setup_strategy", new KwdSetupStrategy ()); m_project_keywords.add ("tag", new KwdTag ()); //m_project_keywords.add ("tag_exclude", new KwdTagExclude ()); m_project_keywords.add ("structure_strategy", new KwdStructureStrategy ()); m_project_keywords.add ("use", new KwdUse ()); } void SyntaxParser::do_parse_requirements (const cmt_string& file_name, Use* use) { cmt_string actual_file_name = file_name; cmt_string text; if (CmtError::get_last_error_code () == CmtError::syntax_error) CmtError::clear (); if (!CmtSystem::test_file (actual_file_name)) { actual_file_name = ".."; actual_file_name += CmtSystem::file_separator (); actual_file_name += "cmt"; actual_file_name += CmtSystem::file_separator (); actual_file_name += file_name; if (!CmtSystem::test_file (actual_file_name)) { actual_file_name = ".."; actual_file_name += CmtSystem::file_separator (); actual_file_name += "mgr"; actual_file_name += CmtSystem::file_separator (); actual_file_name += file_name; if (!CmtSystem::test_file (actual_file_name)) { return; } } } if (!text.read (actual_file_name)) { CmtError::set (CmtError::file_access_error, actual_file_name); return; } SyntaxParser::parse_requirements_text (text, actual_file_name, use); } /** * Parse a text, rejecting comments and * rebuilding complete lines (from sections separated by * \\ characters. * * Each reformatted line is parsed by filter_line */ void SyntaxParser::do_parse_text (const cmt_string& text, const cmt_string& file_name, ContextType context, Use* use, Project* project) { cmt_string line; int line_number = 1; if (context == package_context) { if (use == 0) use = &(Use::current ()); } m_filtered_text.erase (0); int nl; int begin = 0; int end = text.size (); while ((nl = text.find (begin, '\n')) != cmt_string::npos) { if (begin < nl && text[nl - 1] == '\r') { text.substr (begin, nl - 1 - begin, line); } else { text.substr (begin, nl - begin, line); } // cerr << "|do_parse_text> [" << line << "]" << endl; do_parse_line (line, file_name, line_number, context, use, project); line_number++; begin = nl + 1; } // while ((nl = text.find (begin, '\n')) != cmt_string::npos) if (begin < end) { text.substr (begin, end - begin, line); do_parse_line (line, file_name, line_number, context, use, project); } } /* void SyntaxParser::do_parse_text (const cmt_string& text, const cmt_string& file_name, ContextType context, Use* use, Project* project) { cmt_string line; int pos; int max_pos; int line_number = 1; if (context == package_context) { if (use == 0) use = &(Use::current ()); } m_filtered_text.erase (0); pos = 0; max_pos = text.size (); for (pos = 0; pos < max_pos; ) { int cr = text.find (pos, "\r\n"); int nl = text.find (pos, '\n'); int first = nl; int length = 1; if (cr != cmt_string::npos) { if (nl == cmt_string::npos) { first = cr; length = 2; } else { first = (nl < cr) ? nl : cr; length = (nl < cr) ? 1 : 2; } } if (first == cmt_string::npos) { text.substr (pos, line); pos = max_pos; } else if (first > pos) { text.substr (pos, first - pos, line); pos = first + length; } else { line.erase (0); pos += length; } do_parse_line (line, file_name, line_number, context, use, project); if ((Cmt::get_action () == action_check_configuration) && CmtError::has_pending_error ()) { //break; } line_number++; } } */ void SyntaxParser::do_parse_line (const cmt_string& line, const cmt_string& file_name, int line_number, ContextType context, Use* use, Project* project) { int length; int nl; int back_slash; cmt_string temp_line = line; if (temp_line.size () == 0) return; if (temp_line[0] == '#') return; nl = temp_line.find_last_of ('\n'); if (nl != cmt_string::npos) temp_line.erase (nl); length = temp_line.size (); if (length == 0) return; // // We scan the line for handling backslashes. // // o Really terminating backslashes (ie those only followed by spaces/tabs // mean continued line // // bool finished = true; // length = temp_line.size (); back_slash = temp_line.find_last_of ('\\'); if (back_slash != cmt_string::npos) { // // This is the last backslash // check if there are only space chars after it // bool at_end = true; for (int i = (back_slash + 1); i < length; i++) { char c = temp_line[i]; if ((c != ' ') && (c != '\t')) { at_end = false; break; } } if (at_end) { temp_line.erase (back_slash); finished = false; } else { // This was not a trailing backslash. finished = true; } } m_filtered_text += temp_line; if (!finished) { // We still need to accumulate forthcoming lines // before parsing the resulting text. return; } /* Here a full line (possibly accumulating several lines ended by backslashes) is parsed : o Special characters are filtered now : \t \r \n o Split into words (a word is a string not containing spaces or enclosed in quotes) o Parse the word array (function Select) */ m_filtered_text.replace_all ("", "\t"); m_filtered_text.replace_all ("", "\r"); m_filtered_text.replace_all ("", "\n"); if (Cmt::get_debug ()) { cout << "parse_requirements_line [" << m_filtered_text << "]" << endl; } static CmtSystem::cmt_string_vector words; CmtSystem::split (m_filtered_text, " \t", words); if (words.size () != 0) { switch (context) { case project_context: do_parse_words (words, file_name, line_number, project); break; case package_context: do_parse_words (words, file_name, line_number, use); break; } } m_filtered_text.erase (0); } void SyntaxParser::do_parse_words (const CmtSystem::cmt_string_vector& words, const cmt_string& file_name, int line_number, Use* use) { if (CmtError::get_last_error_code () == CmtError::syntax_error) CmtError::clear (); if (words.size () == 0) return; const cmt_string& command = words[0]; if (command.size () == 0) return; // // First analyze the syntax // Kwd* keyword = m_keywords.find (command); if (keyword == 0) { /* When the first word of the line is not a keyword, it may be an implicit pattern application. */ Pattern* p = Pattern::find (command); if (p == 0) { CmtError::set (CmtError::syntax_error, "ParseRequirements> "); } else { keyword = m_keywords.find ("apply_pattern"); } } if (CmtError::get_last_error_code () == CmtError::syntax_error) // if (CmtError::has_pending_error ()) { CmtError::print (); char num[32]; sprintf (num, "%d", line_number); CmtMessage::error ("bad syntax in requirements of " + use->get_package_name () + " " + use->version + " " + use->specified_path + " line #" + num + " [" + command + " ...]"); /* if (!Cmt::get_quiet ()) { cerr << "#CMT> bad syntax in requirements of " << use->get_package_name () << " " << use->version << " " << use->specified_path << " line #" << line_number; cerr << " [" << command << " ...]" << endl; } */ return; } // // Then interpret the action // keyword->action (words, use, file_name, line_number); } void SyntaxParser::do_parse_words (const CmtSystem::cmt_string_vector& words, const cmt_string& file_name, int line_number, Project* project) { if (CmtError::get_last_error_code () == CmtError::syntax_error) CmtError::clear (); if (words.size () == 0) return; const cmt_string& command = words[0]; if (command.size () == 0) return; // // First analyze the syntax // Kwd* keyword = m_project_keywords.find (command); if (keyword == 0) { CmtError::set (CmtError::syntax_error, "ParseRequirements> "); } if (CmtError::get_last_error_code () == CmtError::syntax_error) // if (CmtError::has_pending_error ()) { CmtError::print (); char num[32]; sprintf (num, "%d", line_number); CmtMessage::error ("bad syntax in project file of " + project->get_name () + " line #" + num + " [" + command + " ...]"); /* if (!Cmt::get_quiet ()) { cerr << "#CMT> bad syntax in project file of " << project->get_name () << " line #" << line_number; cerr << " [" << command << " ...]" << endl; } */ return; } // // Then interpret the action // keyword->action (words, project, file_name, line_number); if (CmtError::get_last_error_code () == CmtError::syntax_error) CmtError::print (); }