//----------------------------------------------------------- // 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_include.h" #include "cmt_use.h" #include "cmt_symbol.h" #include "cmt_log.h" /*----------------------------------------------------------*/ /* */ /* Operations on Include */ /* */ /*----------------------------------------------------------*/ /** Executed to parse an include_dirs statement It postpones the macro expansion to the post-processing stage (during set_standard_macros) */ void Include::action (const CmtSystem::cmt_string_vector& words, Use* use) { cmt_string name; if (use == 0) use = &(Use::current()); if (Cmt::get_current_access () == UserMode) { if (use->get_current_scope () == ScopePrivate) return; } for (int i = 1; i < words.size (); i++) { /* statement words may contain macro references at that level they are stored as they are. They will be expanded later on using the parse_all method (called from set_standard_macros) */ name = words[i]; if (name == "") return; add (name, use); } } /** Search a database entry for this include_dirs matching the duet {name, use} */ Include* Include::find (const cmt_string& name, Use* use) { int include_index; if (use == 0) use = &(Use::current()); if (use->includes.size () == 0) return (0); for (include_index = 0; include_index < use->includes.size (); include_index++) { Include& incl = use->includes[include_index]; if (incl.use != use) continue; if (incl.name == name) { return (&incl); } } return (0); } /** Add a unique entry for this include_dirs specification given by the duet {name, use} */ Include* Include::add (const cmt_string& name, Use* use) { if (name == "") return (0); if (use == 0) use = &(Use::current()); { Include* incl; incl = find (name, use); if (incl != 0) return (incl); } Include& incl = use->includes.add (); incl.name = name; incl.use = use; return (&incl); } /*----------------------------------------------------------*/ void Include::clear_all () { for (int include_number = 0; include_number < (Use::current()).includes.size (); include_number++) { Include& incl = (Use::current()).includes[include_number]; incl.clear (); } } /** Post processing of the include_dirs statements of a Use object. This is meant to expand all macro references used in the include_dirs statements Note that this may create new Include objects. Thus the loop is only performed onto the existing objects before the post-processing step */ void Include::parse_all (Use* use) { int size; int i; size = use->includes.size (); for (i = 0; i < size; i++) { Include& incl = use->includes[i]; incl.parse (); } } /*----------------------------------------------------------*/ void Include::clear () { use = 0; } /** Post processing of an include_dirs statement. The name field is expanded for its macro references and split into individual words. Each word in turn generates a new Include object The old Include object is inactivated by setting an empty name */ void Include::parse () { cmt_string new_name = name; Symbol::expand (new_name); if (new_name == name) return; CmtSystem::cmt_string_vector ws; ws.clear (); CmtSystem::split (new_name, " ", ws); name = ""; for (int j = 0; j < ws.size (); j++) { const cmt_string& w = ws[j]; add (w, use); } use = 0; } /*----------------------------------------------------------*/ Include::Include () { clear (); } /*----------------------------------------------------------*/ Include::~Include () { use = 0; }