Index: /CMT/v1r19/ChangeLog
===================================================================
--- /CMT/v1r19/ChangeLog	(revision 15)
+++ /CMT/v1r19/ChangeLog	(revision 16)
@@ -1,2 +1,67 @@
+2005-03-15  Christian Arnault  <arnault@lal.in2p3.fr> 258
+
+	* source/cmt_parser.cxx (clear): Add m_autoconfigure_cmtpath
+	variable to discard autoconfiguration of CMTPATH during initial
+	phases of the configuration.
+	
+	(guess_current_project): Once the current project is known, the
+	CMTPATH is re-generated from the effective knowledge of the
+	project graph.
+
+	(do_setup): Add a check of the configuration when doing cmt setup
+
+	(do_check_configuration): analyze the tags coming from arguments
+	or from CMTSITE to detect mistypings. This is done by checking the
+	effective usage of those tags.
+
+	(configure_cmt_path): Analyze CMTPATH from either the symbol value
+	or from the EV, before asking the project factory to create the
+	projects from it.
+
+	(get_strategy): Add a generic local function to query the strategy elements.
+
+	* source/cmt_project.cxx (add): Manage conflicts between project
+	release requests on a strict basis (no wild card - exact match
+	only)
+
+	* source/cmt_project.h (class ProjectFactory): No longer need m_first and m_previous
+
+	* source/cmt_project.cxx (create_project): Implement a graph of projects.
+	(create_project): Interpret the first top level directory as the project release
+	
+	(create_project): Interpret the second top level directory as the
+	project name when it's not defined in the project file. So we
+	don't create a dummy project name anymore Project<n>.
+
+	* source/cmt_commands.cxx (ArgParser): Suppress obsolete +path option
+	(parse): Initialize the m_action value to none to fix a bad management of unknown commands
+	(do_filter): Implement the cmt filter command
+
+	* source/cmt_error.cxx (class Error): Add unknown_command and project_release_conflict errors
+
+	* source/cmt_syntax.cxx (class KwdBuildStrategy): Apply the restructuration of strategy management to strategy decoding
+	(class KwdSetupStrategy): idem
+	(class KwdUse): Support the use statement for project files
+	(SyntaxParser): Support the use statement for project files
+
+	* source/cmt_project.h (class StrategyDef): Create a class to hold the definition of all strategy elements
+	(class Strategy): Create a class to hold the application of a strategy into a project
+	(class StrategyMgr): Create a singleton to manage the strategy definitions
+	(class ProjectFactory): Add parent argument to create_project to handle the project graph
+	(class IProjectVisitor): Create a class to visit the project graph
+	(class Project): Transport all definitions releated with strategies into Strategy objects
+
+	* source/cmt_system.cxx (class CMTPathManager): Add a class to
+	interact with the ProjectFactory to convert CMTPATH specifications
+	into projects
+
+	(get_cmt_paths): Suppress the setting from $CMTPATH. This is
+	replaced by a selective understanding of the source of CMTPATH
+	either from the symbol (when defined in a requirements file) or
+	from the EV. This selection is performed in
+	Cmt::configure_cmt_path.
+
+	(get_cmt_paths): Suppress the definition of a CMTPATH entry for CMT itself
+
 2005-03-10    <arnault@lal.in2p3.fr> 257
 
@@ -38,15 +103,9 @@
 	* source/cmt_tag.cxx (use_operand): Add way of checking internal structure of a tag
 	* source/cmt_tag.cxx (use_ref): Add way of checking internal structure of a tag
-
 	* source/cmt_tag.h (class Tag): Add way of checking internal structure of a tag
-
 	* source/cmt_symbol.h (class Symbol): Add way of checking if a tag is used by symbols.
-
 	* source/cmt_symbol.cxx (print): Suppress the "export" action after defining an alias in Sh mode
-
 	* source/cmt_project.cxx: Introduce use_action 
-
 	* source/cmt_syntax.cxx (SyntaxParser): Add support to use statements in project files
-
 	* source/cmt_project.cxx (create_project): Add comments
 
@@ -83,5 +142,5 @@
 2004-12-01    <arnault@lal.in2p3.fr> 247
 
-	* source/cmt_version.h (CMTVERSION): Prepare for tagging 20041201
+	* source/cmt_version.h (CMTVERSION): Prepare for tagging v1r18p20041201
 
 	* source/cmt.h (class Cmt): Fix typo
Index: /CMT/v1r19/source/cmt_parser.cxx
===================================================================
--- /CMT/v1r19/source/cmt_parser.cxx	(revision 15)
+++ /CMT/v1r19/source/cmt_parser.cxx	(revision 16)
@@ -536,4 +536,11 @@
   configure_home (0);
   log << "configure_current_dir" << log_endl;
+
+
+  Me.m_autoconfigure_cmtpath = true;
+  configure_cmt_path (0);
+  Me.m_autoconfigure_cmtpath = false;
+
+
   configure_current_dir ();
 
@@ -589,4 +596,8 @@
           Me.m_action = action_show_set;
         }
+    }
+  else
+    {
+      s = CmtSystem::getenv ("CMTPATH");
     }
 
@@ -3559,4 +3570,6 @@
 void Cmt::do_show_strategies (const ArgParser& /*ap*/)
 {
+  Project::show_specified_strategies_for_all ();
+
   Project* p = Project::get_current ();
 
@@ -3832,8 +3845,10 @@
 }
 
-/**
-    if current directory is in one of the CMTPATHs, do nothing.
-
-  Otherwise, we want to guess the current project => perhaps prepend an item to the CMTPATH??
+/**---------------------------------------------------------
+  guess_current_project
+
+   if current directory is in one of the CMTPATHs, do nothing.
+
+  Otherwise, we want to guess the current project
 
   move up in directories until cmt/project.cmt is found
@@ -3850,5 +3865,4 @@
     move up
   }
-
   */
 void Cmt::guess_current_project ()
@@ -3903,5 +3917,6 @@
     }
 
-  cmt_string buffer = "path CMTPATH \n";
+  //cmt_string buffer = "path CMTPATH \n";
+  cmt_string buffer;
   Project::fill_cmtpaths (buffer);
   //cerr << "buffer = " << buffer << endl;
Index: /CMT/v1r19/source/cmt_project.cxx
===================================================================
--- /CMT/v1r19/source/cmt_project.cxx	(revision 15)
+++ /CMT/v1r19/source/cmt_project.cxx	(revision 16)
@@ -93,7 +93,4 @@
 {
   Project::clear_all ();
-  m_first = 0;
-  m_previous = 0;
-  m_id = 0;
 }
 
@@ -112,4 +109,6 @@
   CmtSystem::compress_path (compressed_path);
 
+  //cerr << "Creating project " << path << " with parent " << ((parent==0)? "0" : parent->get_name ()) << endl;
+
   static Project::ProjectVector& Projects = Project::projects ();
   
@@ -125,5 +124,10 @@
 	      p.add_parent (parent);
 	      parent->add_child (&p);
+
+	      // Since p is a new parent, we should propagate the settings UP.
+
+	      parent->update_strategies_from_children ();
 	    }
+
 	  return (&p);
 	}
@@ -168,11 +172,4 @@
 	  CmtSystem::dirname (compressed_path, name);
 	  CmtSystem::basename (name, name);
-
-	  /*
-	  char buffer[20];
-	  m_id++;
-	  sprintf (buffer, "Project%d", m_id);
-	  name = buffer;
-	  */
 	}
     }
@@ -189,6 +186,4 @@
 	  CmtSystem::dirname (compressed_path, name);
 	  CmtSystem::basename (name, name);
-	  //m_id++;
-	  //sprintf (buffer, "Project%d", m_id);
 	}
     }
@@ -200,4 +195,8 @@
       project->add_parent (parent);
       parent->add_child (project);
+
+      // Since p is a new parent, we should propagate the settings UP.
+
+      parent->update_strategies_from_children ();
     }
 
@@ -206,11 +205,4 @@
       cmt = project;
       is_current = false;
-    }
-  else
-    {
-      if (m_first == 0)
-	{
-	  m_first = project;
-	}
     }
 
@@ -399,4 +391,5 @@
 
   Project& project = Projects.add ();
+  project.clear ();
   project.set_name (name);
   project.set_release (release);
@@ -455,4 +448,17 @@
 }
 
+/*----------------------------------------------------------*/
+void Project::show_specified_strategies_for_all ()
+{
+  static ProjectVector& Projects = projects ();
+
+  for (int i = 0; i < Projects.size (); i++)
+    {
+      const Project& project = Projects[i];
+      project.show_specified_strategies ();
+    }
+}
+
+/*----------------------------------------------------------*/
 class VisitorForShowPaths : public IProjectVisitor
 {
@@ -850,4 +856,7 @@
 {
   if (p == 0) return;
+  if (p == this) return;
+
+  //cerr << "Adding parent " << p->get_name () << " to " << m_name << endl;
 
   int i;
@@ -878,8 +887,4 @@
 
   m_parents.push_back (p);
-
-  // Since p is a new parent, we should propagate the settings UP.
-
-  p->update_strategies_from_children ();
 }
 
@@ -888,4 +893,5 @@
 {
   if (p == 0) return;
+  if (p == this) return;
 
   int i;
@@ -954,4 +960,7 @@
   CmtSystem::cmt_string_vector items;
   CmtSystem::split (cmtprojectpath, sep, items);
+
+  bool found = false;
+
   for (int i = 0; i < items.size (); i++)
     {
@@ -967,4 +976,6 @@
 	  //cerr << "Project directory " << p << " exists " << endl;
 
+	  found = true;
+
 	  IProjectFactory& factory = ProjectFactory::instance ();
 
@@ -973,4 +984,24 @@
 	  break;
 	}
+    }
+
+  if (!found)
+    {
+      Project* p = Project::find_by_name (name);
+
+      if (p != 0)
+	{
+	  found = true;
+
+	  p->add_parent (this);
+	  add_child (p);
+
+	  update_strategies_from_children ();
+	}
+    }
+
+  if (!found && (cmtprojectpath != ""))
+    {
+      cerr << "#CMT> Project " << name << " " << release << " requested by " << m_name << " not found in CMTPROJECTPATH" << endl;
     }
 }
@@ -1056,6 +1087,27 @@
 
 //----------------------------------------------------------
-void Project::show_strategies () const
-{
+void Project::show_specified_strategies () const
+{
+  int i;
+
+  for (i = 0; i < m_strategies.size (); i++)
+    {
+      const Strategy& s = m_strategies[i];
+      if (s.m_specified)
+	{
+	  const StrategyDef* def = s.m_definition;
+ 
+	  cout << "# Project " << m_name
+	       << " sets " << def->m_keyword
+	       << " strategy to " << ((s.m_value) ? def->m_on_value : def->m_off_value);
+
+	  if (s.m_context != "")
+	    {
+	      cout << " (from package " << s.m_context << ")";
+	    }
+
+	  cout << endl;
+	}
+    }
 }
 
@@ -1151,5 +1203,5 @@
 
 //----------------------------------------------------------
-void Project::set_strategy (const cmt_string& name, const cmt_string& value)
+void Project::set_strategy (const cmt_string& name, const cmt_string& value, const cmt_string& context)
 {
   static StrategyMgr& mgr = StrategyMgr::instance ();
@@ -1178,9 +1230,9 @@
     }
 
-  set_strategy (def, b_value);
-}
-
-//----------------------------------------------------------
-void Project::set_strategy (StrategyDef* definition, bool b_value)
+  set_strategy (def, b_value, context);
+}
+
+//----------------------------------------------------------
+void Project::set_strategy (StrategyDef* definition, bool b_value, const cmt_string& context)
 {
   bool need_strategy = true;
@@ -1195,4 +1247,9 @@
 	  // This strategy is already applied in this project. Let's change it's value
 	  s.set (definition, b_value, get_name ());
+	  if (context != "")
+	    {
+	      if (s.m_context != "") s.m_context += " ";
+	      s.m_context += context;
+	    }
 	  need_strategy = false;
 	  break;
@@ -1205,5 +1262,7 @@
 
       Strategy& s = m_strategies.add ();
+      s.clear ();
       s.set (definition, b_value, get_name ());
+      s.m_context = context;
     }
   
@@ -1227,4 +1286,5 @@
 {
   bool need_strategy = true;
+  bool specified = false;
 
   int i;
@@ -1235,7 +1295,15 @@
       if (s.m_definition == definition)
 	{
-	  // This strategy is already applied in this project. Let's change it's value
-	  s.update (definition, b_value, get_name ());
 	  need_strategy = false;
+
+	  if (!s.m_specified)
+	    {
+	      // This strategy is already applied in this project. Let's change it's value
+	      s.update (definition, b_value, get_name ());
+	    }
+	  else
+	    {
+	      specified = true;
+	    }
 	  break;
 	}
@@ -1247,13 +1315,14 @@
 
       Strategy& s = m_strategies.add ();
+      s.clear ();
       s.update (definition, b_value, get_name ());
     }
-  
-  for (i = 0; i < m_parents.size (); i++)
-    {
-      Project* project = m_parents[i];
-
-      if (project->has_strategy (definition))
-	{
+
+  if (!specified)
+    {
+      for (i = 0; i < m_parents.size (); i++)
+	{
+	  Project* project = m_parents[i];
+
 	  project->update_strategy (definition, b_value);
 	}
@@ -1271,5 +1340,5 @@
   // If this strategy is specified we don't care what happens from the children
 
-  cerr << "Updating strategy " << definition->m_name << " from children for project " << m_name << endl;
+  //cerr << "Updating strategy " << definition->m_name << " from children for project " << m_name << endl;
 
   int i;
@@ -1286,5 +1355,5 @@
 	      // There will be no impact since the strategy is specified
 
-	      cerr << "This strategy is specified in this project" << endl;
+	      //cerr << "This strategy is specified in this project" << endl;
 	      return;
 	    }
@@ -1305,5 +1374,5 @@
   Project* selected = 0;
   bool selected_is_specified = false;
-  bool selected_value = false;
+  bool selected_value = definition->m_default_value;
 
   for (i = 0; i < m_children.size (); i++)
@@ -1311,5 +1380,5 @@
       Project* p = m_children[i];
 
-      cerr << "Checking strategy for child " << p->get_name () << endl;
+      //cerr << "Checking strategy for child " << p->get_name () << endl;
 
       bool is_specified = p->is_specified (definition);
@@ -1362,5 +1431,5 @@
   StrategyDef::StrategyDefs& defs = StrategyMgr::get_definitions ();
 
-  cerr << "Updating strategies from children for project " << m_name << endl;
+  //cerr << "Updating strategies from children for project " << m_name << endl;
 
   int i;
@@ -1369,6 +1438,12 @@
     {
       StrategyDef* def = defs[i];
-
+      
       update_strategy_from_children (def);
+    }
+
+  for (i = 0; i < m_parents.size (); i++)
+    {
+      Project* p = m_parents[i];
+      p->update_strategies_from_children ();
     }
 }
@@ -1394,4 +1469,5 @@
 
   s = new StrategyDef;
+  s->m_keyword = "build";
   s->m_name = "BuildPrototypes";
   s->m_on_value = "prototypes";
@@ -1403,4 +1479,5 @@
 
   s = new StrategyDef;
+  s->m_keyword = "build";
   s->m_name = "InstallArea";
   s->m_on_value = "with_installarea";
@@ -1412,4 +1489,5 @@
 
   s = new StrategyDef;
+  s->m_keyword = "setup";
   s->m_name = "SetupConfig";
   s->m_on_value = "config";
@@ -1421,4 +1499,5 @@
 
   s = new StrategyDef;
+  s->m_keyword = "setup";
   s->m_name = "SetupRoot";
   s->m_on_value = "root";
@@ -1430,4 +1509,5 @@
 
   s = new StrategyDef;
+  s->m_keyword = "setup";
   s->m_name = "SetupCleanup";
   s->m_on_value = "cleanup";
@@ -1491,4 +1571,21 @@
 }
 
+//-----------------------------------------------------------
+Strategy::Strategy ()
+{
+  clear ();
+}
+
+//-----------------------------------------------------------
+void Strategy::clear ()
+{
+  m_definition = 0;
+  m_specified = false;
+  m_specified_value = false;
+  m_value = false;
+  m_on_tag = 0;
+  m_off_tag = 0;
+}
+
 /**----------------------------------------------------------
    Specify a new value for this strategy.
@@ -1497,4 +1594,6 @@
 void Strategy::set (StrategyDef* definition, bool value, const cmt_string& project_name)
 {
+  //cerr << "Setting strategy " << definition->m_name << " for project " << project_name << " to " << value << endl;
+
   m_definition = definition;
   m_specified = true;
@@ -1511,5 +1610,8 @@
 void Strategy::update (StrategyDef* definition, bool value, const cmt_string& project_name)
 {
+  //cerr << "Updating strategy " << definition->m_name << " for project " << project_name << " to " << value << endl;
+
   m_value = value;
+  m_definition = definition;
 
   cmt_string to_tag_name = project_name;
Index: /CMT/v1r19/source/cmt_project.h
===================================================================
--- /CMT/v1r19/source/cmt_project.h	(revision 15)
+++ /CMT/v1r19/source/cmt_project.h	(revision 16)
@@ -19,4 +19,5 @@
   typedef cmt_vector <StrategyDef*> StrategyDefs;
 
+  cmt_string m_keyword;
   cmt_string m_name;
   cmt_string m_on_value;
@@ -37,5 +38,8 @@
   Tag* m_on_tag;
   Tag* m_off_tag;
+  cmt_string m_context;
 
+  Strategy ();
+  void clear ();
   void set (StrategyDef* definition, bool value, const cmt_string& project_name);
   void update (StrategyDef* definition, bool value, const cmt_string& project_name);
@@ -67,8 +71,4 @@
 			   Project* parent);
 
-private:
-  Project* m_first;
-  Project* m_previous;
-  int m_id;
 };
 
@@ -105,4 +105,5 @@
   static void clear_all ();
   static void show_all ();
+  static void show_specified_strategies_for_all ();
   static void show_paths ();
   static const cmt_string& get_project_file_name ();
@@ -151,5 +152,5 @@
 
   void show ();
-  void show_strategies () const;
+  void show_specified_strategies () const;
 
   bool has_strategy (const StrategyDef* definition) const;
@@ -158,6 +159,6 @@
   bool get_strategy (const cmt_string& name) const;
   void set_default_strategy (const cmt_string& name);
-  void set_strategy (const cmt_string& name, const cmt_string& value);
-  void set_strategy (StrategyDef* definition, bool b_value);
+  void set_strategy (const cmt_string& name, const cmt_string& value, const cmt_string& context);
+  void set_strategy (StrategyDef* definition, bool b_value, const cmt_string& context);
   void update_strategy (StrategyDef* definition, bool b_value);
   void update_strategy_from_children (StrategyDef* definition);
Index: /CMT/v1r19/source/cmt_syntax.cxx
===================================================================
--- /CMT/v1r19/source/cmt_syntax.cxx	(revision 15)
+++ /CMT/v1r19/source/cmt_syntax.cxx	(revision 16)
@@ -173,5 +173,5 @@
 	if (decode (w, strategy, value))
 	  {
-	    if (p != 0) p->set_strategy (strategy, value);
+	    if (p != 0) p->set_strategy (strategy, value, use->get_package_name ());
 	  }
 	else
@@ -181,18 +181,4 @@
 	    CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
 	  }
-
-	if ((Cmt::get_action () == action_show_strategies) && !Cmt::get_quiet ())
-	  {
-	    if (!in_error)
-	      {
-		cerr << "# Package " << use->get_package_name ()
-		     << " adds " << w << " to build strategy" << endl;
-	      }
-	    else
-	      {
-		cerr << "# Error: Package " << use->get_package_name ()
-		     << " uses unknown " << w << " keyword to build strategy" << endl;
-	      }
-	  }
       }
   }
@@ -214,5 +200,5 @@
 	if (decode (w, strategy, value))
 	  {
-	    if (project != 0) project->set_strategy (strategy, value);
+	    if (project != 0) project->set_strategy (strategy, value, "");
 	  }
 	else
@@ -221,18 +207,4 @@
 
 	    CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
-	  }
-
-	if ((Cmt::get_action () == action_show_strategies) && !Cmt::get_quiet ())
-	  {
-	    if (!in_error)
-	      {
-		cerr << "# Project " << project->get_name ()
-		     << " adds " << w << " to build strategy" << endl;
-	      }
-	    else
-	      {
-		cerr << "# Error: Project " << project->get_name ()
-		     << " uses unknown " << w << " keyword to build strategy" << endl;
-	      }
 	  }
       }
@@ -784,5 +756,5 @@
 	if (decode (w, strategy, value))
 	  {
-	    if (p != 0) p->set_strategy (strategy, value);
+	    if (p != 0) p->set_strategy (strategy, value, use->get_package_name ());
 	  }
 	else
@@ -792,18 +764,4 @@
 	    CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
 	  }
-
-	if ((Cmt::get_action () == action_show_strategies) && !Cmt::get_quiet ())
-	  {
-	    if (!in_error)
-	      {
-		cerr << "# Package " << use->get_package_name ()
-		     << " adds " << w << " to setup strategy" << endl;
-	      }
-	    else
-	      {
-		cerr << "# Error: Package " << use->get_package_name ()
-		     << " uses unknown " << w << " keyword to setup strategy" << endl;
-	      }
-	  }
       }
   }
@@ -825,5 +783,5 @@
 	if (decode (w, strategy, value))
 	  {
-	    if (project != 0) project->set_strategy (strategy, value);
+	    if (project != 0) project->set_strategy (strategy, value, "");
 	  }
 	else
@@ -832,18 +790,4 @@
 
 	    CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
-	  }
-
-	if ((Cmt::get_action () == action_show_strategies) && !Cmt::get_quiet ())
-	  {
-	    if (!in_error)
-	      {
-		cerr << "# Project " << project->get_name ()
-		     << " adds " << w << " to setup strategy" << endl;
-	      }
-	    else
-	      {
-		cerr << "# Error: Project " << project->get_name ()
-		     << " uses unknown " << w << " keyword to setup strategy" << endl;
-	      }
 	  }
       }
Index: /CMT/v1r19/source/cmt_system.cxx
===================================================================
--- /CMT/v1r19/source/cmt_system.cxx	(revision 15)
+++ /CMT/v1r19/source/cmt_system.cxx	(revision 16)
@@ -1477,21 +1477,4 @@
   cmt_string rc_name;
 
-  const cmt_string env = CmtSystem::getenv ("CMTPATH");
-
-  if (env != "")
-    {
-      static cmt_string_vector path_vector;
-      int i;
-
-      split (env, path_separator (), path_vector);
-
-      for (i = 0; i < path_vector.size (); i++)
-        {
-          const cmt_string& path = path_vector[i];
-
-          CMTPathManager::add_cmt_path (path, "${CMTPATH}", factory);
-        }
-    }
-
   add_cmt_paths_from_file (".cmtrc", factory);
 
@@ -1516,7 +1499,4 @@
 
   add_cmt_paths_from_file (rc_name, factory);
-
-  // Suppress the definition of a CMTPATH entry for CMT itself
-  //CMTPathManager::add_cmt_path (get_cmt_root (), "default path", factory);
 
   CMTPathManager::add_cmt_path (cmt_user_context, "CMTUSERCONTEXT", factory);
