Index: /CMT/HEAD/ChangeLog
===================================================================
--- /CMT/HEAD/ChangeLog	(revision 606)
+++ /CMT/HEAD/ChangeLog	(revision 607)
@@ -1,2 +1,30 @@
+2012-04-03    <rybkin@lal.in2p3.fr> 482
+
+	* source/cmt_syntax.cxx: In class SyntaxParser function
+	do_parse_requirements, check return value of string read function and set
+	error on failure, re-write function do_parse_text in order to optimise
+	* source/cmt_awk.cxx: In class Parser, re-write function parse in order
+	to optimise, in class Awk function run, test CMTTESTAWK environment
+	variable in debug mode only, re-write function run in order to optimise
+	* source/cmt_string.cxx: In class cmt_string, make function resize set size
+	and terminate string with 0, optimise functions substr (int, int),
+	substr (int, int, cmt_string&)
+	* source/cmt_pattern.cxx: In class Pattern functions test CMTTESTPATTERN
+	environment variable in debug mode only
+	* source/cmt_regexp.cxx: In class cmt_and_node function match, class
+	cmt_or_node function match, class cmt_regexp function set, test
+	CMTTESTREGEXP environment variable in debug mode only
+	* source/cmt_parser.cxx: In class Cmt function set_standard_macros, test
+	TAGDEBUG environment variable once
+	* source/cmt_system.cxx: In class CmtSystem, re-write function realpath_
+	making use of system functions realpath (POSIX) and _fullpath (Windows)
+	* source/cmt_use.cxx: In class Use function get_cmtpath_and_offset, check
+	return value of CmtSystem::realpath_ and set error on failure
+	* source/cmt_project.cxx: In class Project function find_in_cmt_paths check
+	return value of CmtSystem::realpath_ and return on failure, do not test
+	existence of project cmt paths as they must exist
+	* source/cmt_symbol.cxx: In find_path_entry helper function, make use of
+	CmtSystem::realpath_ for paths comparison
+
 2012-03-26    <rybkin@lal.in2p3.fr> 481
 
Index: /CMT/HEAD/source/cmt_awk.cxx
===================================================================
--- /CMT/HEAD/source/cmt_awk.cxx	(revision 606)
+++ /CMT/HEAD/source/cmt_awk.cxx	(revision 607)
@@ -40,4 +40,5 @@
 
     cmt_string line;
+    /*
     int pos;
     int max_pos;
@@ -45,7 +46,38 @@
     pos = 0;
     max_pos = text.size ();
-
+    */
     m_accumulator.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 << "|Awk::condition parse> [" << line << "]" << endl;
+	begin = nl + 1;
+	if (m_awk != 0) m_awk->inc_line_number ();
+
+	result = parse_line (line);
+	if (result != Awk::ok) return result;
+      } // while ((nl = text.find (begin, '\n')) != cmt_string::npos)
+    
+    if (begin < end)
+      {
+	text.substr (begin, end - begin, line);
+	if (m_awk != 0) m_awk->inc_line_number ();
+	
+	result = parse_line (line);
+      }
+    
+    /*
     for (pos = 0; pos < max_pos;)
       {
@@ -90,5 +122,5 @@
 	if (result != Awk::ok) break;
       }
-
+    */
     return (result);
   }
@@ -232,5 +264,6 @@
   if (m_condition != ok) return (m_condition);
 
-  if (CmtSystem::testenv ("CMTTESTAWK"))
+  if (Cmt::get_debug () &&
+      CmtSystem::testenv ("CMTTESTAWK"))
     {
       Parser p (this, pattern, 0);
@@ -242,4 +275,49 @@
     {
       cmt_string line;
+      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 << "|Awk::condition run> [" << line << "]" << endl;
+	  begin = nl + 1;
+          m_line_number++;
+	  
+          if (line != "")
+            {
+              if ((pattern == "") ||
+                  (line.find (pattern) != cmt_string::npos))
+                {
+                  filter (line);
+                  if (m_condition != ok) return (m_condition);
+                }
+            }
+	} // while ((nl = text.find (begin, '\n')) != cmt_string::npos)
+      
+      if (begin < end)
+	{
+	  text.substr (begin, end - begin, line);
+          m_line_number++;
+	  
+          if (line != "")
+            {
+              if ((pattern == "") ||
+                  (line.find (pattern) != cmt_string::npos))
+                {
+                  filter (line);
+                  if (m_condition != ok) return (m_condition);
+                }
+            }
+	}
+      /*
       int pos = 0;
       int max_pos;
@@ -315,4 +393,5 @@
             }
         }
+      */
     }
 
Index: /CMT/HEAD/source/cmt_parser.cxx
===================================================================
--- /CMT/HEAD/source/cmt_parser.cxx	(revision 606)
+++ /CMT/HEAD/source/cmt_parser.cxx	(revision 607)
@@ -9684,5 +9684,5 @@
    */
 
-  bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
+  static bool tag_debug = CmtSystem::testenv ("TAGDEBUG");
 
   if (tag_debug) cerr << "set_standard_macro0> current_tag=" << Me.m_current_tag << endl;
Index: /CMT/HEAD/source/cmt_pattern.cxx
===================================================================
--- /CMT/HEAD/source/cmt_pattern.cxx	(revision 606)
+++ /CMT/HEAD/source/cmt_pattern.cxx	(revision 607)
@@ -192,5 +192,6 @@
   add (name, words, start_index, global, use);
 
-  if (CmtSystem::testenv ("CMTTESTPATTERN"))
+  if (Cmt::get_debug () &&
+      CmtSystem::testenv ("CMTTESTPATTERN"))
     {
       cerr << "Pattern::action> add " << name << endl;
@@ -736,5 +737,6 @@
   expand (context_use, templates, replacement);
 
-  if (CmtSystem::testenv ("CMTTESTPATTERN"))
+  if (Cmt::get_debug () &&
+      CmtSystem::testenv ("CMTTESTPATTERN"))
     {
       cerr << "Pattern::apply> replacement=[" << replacement << "]" << endl;
@@ -754,5 +756,6 @@
   if (context_use == 0) context_use = &(Use::current ());
 
-  if (CmtSystem::testenv ("CMTTESTPATTERN"))
+  if (Cmt::get_debug () &&
+      CmtSystem::testenv ("CMTTESTPATTERN"))
     {
       cerr << "Pattern::expand1> line=[" << line << "]" << endl;
@@ -802,5 +805,6 @@
         }
 
-      if (CmtSystem::testenv ("CMTTESTPATTERN"))
+      if (Cmt::get_debug () &&
+	  CmtSystem::testenv ("CMTTESTPATTERN"))
 	{
 	  cerr << "Pattern::expand2> repl=[" << replacement << "]" << endl;
@@ -897,5 +901,6 @@
       cmt_string s = words[i];
 
-      if (CmtSystem::testenv ("CMTTESTPATTERN"))
+      if (Cmt::get_debug () &&
+	  CmtSystem::testenv ("CMTTESTPATTERN"))
 	{
 	  cerr << "ApplyPattern::action> " << name << " s=[" << s << "] state=" << state << endl;
@@ -921,5 +926,6 @@
 	      s.substr (pos + 1, tvalue);
 
-	      if (CmtSystem::testenv ("CMTTESTPATTERN"))
+	      if (Cmt::get_debug () &&
+		  CmtSystem::testenv ("CMTTESTPATTERN"))
 		{
 		  cerr << "ApplyPattern::action-1> n=[" << tname << "] v=[" << tvalue << "]" << endl;
@@ -994,5 +1000,6 @@
 	      s.substr (pos + 1, tvalue);
 
-	      if (CmtSystem::testenv ("CMTTESTPATTERN"))
+	      if (Cmt::get_debug () &&
+		  CmtSystem::testenv ("CMTTESTPATTERN"))
 		{
 		  cerr << "ApplyPattern::action-2> n=[" << tname << "] v=[" << tvalue << "]" << endl;
@@ -1016,5 +1023,6 @@
 	  state = need_template;
 
-	  if (CmtSystem::testenv ("CMTTESTPATTERN"))
+	  if (Cmt::get_debug () &&
+	      CmtSystem::testenv ("CMTTESTPATTERN"))
 	    {
 	      cerr << "ApplyPattern::action-3> n=[" << tname << "] v=[" << tvalue << "]" << endl;
@@ -1109,5 +1117,6 @@
 void ApplyPattern::apply () const
 {
-  if (CmtSystem::testenv ("CMTTESTPATTERN"))
+  if (Cmt::get_debug () &&
+      CmtSystem::testenv ("CMTTESTPATTERN"))
     {
       cerr << "ApplyPattern::apply> " << name << endl;
@@ -1117,5 +1126,6 @@
   if (p == 0) 
     {
-      if (CmtSystem::testenv ("CMTTESTPATTERN"))
+      if (Cmt::get_debug () &&
+	  CmtSystem::testenv ("CMTTESTPATTERN"))
         {
           cerr << "ApplyPattern::apply> " << name << " not found" << endl;
Index: /CMT/HEAD/source/cmt_project.cxx
===================================================================
--- /CMT/HEAD/source/cmt_project.cxx	(revision 606)
+++ /CMT/HEAD/source/cmt_project.cxx	(revision 607)
@@ -1657,5 +1657,6 @@
   cmt_string path_real;
   //cerr << "realpath_: find_in_cmt_paths" << endl;
-  CmtSystem::realpath_ (path, path_real);
+  if (!CmtSystem::realpath_ (path, path_real))
+    return ("");
 
   static ProjectVector& Projects = projects ();
@@ -1672,5 +1673,6 @@
       if (s == "default path") continue;
 
-      if (CmtSystem::test_directory (p))
+      // MUST be directory if project added
+      //      if (CmtSystem::test_directory (p))
 	{
 // 	  if (path.find (p) != cmt_string::npos)
@@ -1693,5 +1695,6 @@
       if (p == w) continue;
 
-      if (CmtSystem::test_directory (w))
+      // MUST be directory if project added
+      //      if (CmtSystem::test_directory (w))
 	{
 	  if (path.find (w) != cmt_string::npos)
Index: /CMT/HEAD/source/cmt_regexp.cxx
===================================================================
--- /CMT/HEAD/source/cmt_regexp.cxx	(revision 606)
+++ /CMT/HEAD/source/cmt_regexp.cxx	(revision 607)
@@ -10,4 +10,5 @@
 #include "cmt_system.h"
 
+#include "cmt.h"
 //----------------------------------------------------------
 //
@@ -987,5 +988,6 @@
   int p = pos;
   
-  bool dbg = CmtSystem::testenv ("CMTTESTREGEXP");
+  bool dbg = false;
+  if (Cmt::get_debug ()) dbg = CmtSystem::testenv ("CMTTESTREGEXP");
 
   if (dbg) {tab (); cerr << "match and (" << this << ") pos=" << pos << endl;}
@@ -1115,5 +1117,6 @@
   if (_nodes.size () == 0) return (cmt_regexp::iterator (pos, 0));
   
-  bool dbg = CmtSystem::testenv ("CMTTESTREGEXP");
+  bool dbg = false;
+  if (Cmt::get_debug ()) dbg = CmtSystem::testenv ("CMTTESTREGEXP");
 
   if (dbg) {tab (); cerr << "match or (" << this << ") pos=" << pos << endl;}
@@ -1562,5 +1565,6 @@
   _root = or_root;
 
-  bool dbg = CmtSystem::testenv ("CMTTESTREGEXP");
+  bool dbg = false;
+  if (Cmt::get_debug ()) dbg = CmtSystem::testenv ("CMTTESTREGEXP");
 
   if (dbg)
Index: /CMT/HEAD/source/cmt_string.cxx
===================================================================
--- /CMT/HEAD/source/cmt_string.cxx	(revision 606)
+++ /CMT/HEAD/source/cmt_string.cxx	(revision 607)
@@ -244,5 +244,7 @@
 void cmt_string::resize (int n)
 {
+  _size = n;
   allocate (n + 1);
+  _data[n] = 0;
 }
 
@@ -544,5 +546,6 @@
   if ((_data == 0) ||
       (pos < 0) ||
-      (pos >= _size))
+      (pos >= _size) ||
+      length == 0)
     {
       return ((cmt_string) "");
@@ -550,7 +553,30 @@
   else
     {
+      //      cerr << "|cmt_string::substr>: `" << *this << "' pos: " << pos << " length: " << length;
+
+      if ((pos + length) >= _size ||
+	  length < 0)
+        {
+	  //	  cmt_string result (&_data[pos]);
+	  //cerr << " |---> `" << result << "'" << endl;
+	  //	  return (result);
+	  return (&_data[pos]);
+        }
+      else
+	{
+	  cmt_string result;
+	  result.resize (length);
+	  for (int i = 0; i < length; i++)
+	    result[i] = _data[pos + i];
+	  //cerr << " |---> `" << result << "'" << endl;
+	  return (result);
+	}
+
+      /*
       cmt_string result (&_data[pos]);
       result.erase (length);
+      cerr << " |---> `" << result << "'" << endl;
       return (result);
+      */
     }
 }
@@ -574,5 +600,6 @@
   if ((_data == 0) ||
       (pos < 0) ||
-      (pos >= _size))
+      (pos >= _size) ||
+      length == 0)
     {
       dest = "";
@@ -580,6 +607,23 @@
   else
     {
+      //      cerr << "|void cmt_string::substr>: `" << *this << "' pos: " << pos << " length: " << length;
+
+      if ((pos + length) >= _size ||
+	  length < 0)
+        {
+	  dest = (const char*) &_data[pos];
+        }
+      else
+	{
+	  dest.resize (length);
+	  for (int i = 0; i < length; i++)
+	    dest[i] = _data[pos + i];
+	}
+
+      /*
       dest = (const char*) &_data[pos];
       dest.erase (length);
+      */
+      //      cerr << " |---> `" << dest << "'" << endl;
     }
 }
Index: /CMT/HEAD/source/cmt_symbol.cxx
===================================================================
--- /CMT/HEAD/source/cmt_symbol.cxx	(revision 606)
+++ /CMT/HEAD/source/cmt_symbol.cxx	(revision 607)
@@ -2224,7 +2224,8 @@
   static const cmt_string path_separator = CmtSystem::path_separator ();
 
-  cmt_string here = CmtSystem::pwd ();
+  //  cmt_string here = CmtSystem::pwd ();
   cmt_string rvalue = value;
 
+  /*
   if (CmtSystem::cd (value))
     {
@@ -2232,4 +2233,6 @@
     }
   else
+  */
+  if (!CmtSystem::realpath_ (value, rvalue))
     {
       CmtSystem::compress_path (rvalue);
@@ -2245,4 +2248,5 @@
       const cmt_string& item = items[i];
       cmt_string ritem = item;
+      /*
       if (CmtSystem::cd (item))
 	{
@@ -2250,4 +2254,6 @@
 	}
       else
+      */
+      if (!CmtSystem::realpath_ (item, ritem))
 	{
 	  CmtSystem::compress_path (ritem);
@@ -2261,5 +2267,5 @@
     }
 
-  CmtSystem::cd (here);
+  //  CmtSystem::cd (here);
   return (found);
 }
Index: /CMT/HEAD/source/cmt_syntax.cxx
===================================================================
--- /CMT/HEAD/source/cmt_syntax.cxx	(revision 606)
+++ /CMT/HEAD/source/cmt_syntax.cxx	(revision 607)
@@ -1682,5 +1682,9 @@
     }
 
-  text.read (actual_file_name);
+  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);
@@ -1694,4 +1698,48 @@
  *  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,
@@ -1762,4 +1810,5 @@
     }
 }
+*/
 
 void SyntaxParser::do_parse_line (const cmt_string& line,
@@ -1794,5 +1843,5 @@
   bool finished = true;
 
-  length = temp_line.size ();
+  //  length = temp_line.size ();
 
   back_slash = temp_line.find_last_of ('\\');
Index: /CMT/HEAD/source/cmt_system.cxx
===================================================================
--- /CMT/HEAD/source/cmt_system.cxx	(revision 606)
+++ /CMT/HEAD/source/cmt_system.cxx	(revision 607)
@@ -334,4 +334,40 @@
 }
 
+//--------------------------------------------------
+bool CmtSystem::realpath_ (const cmt_string& path, cmt_string& result)
+{
+  char buffer[PATH_MAX + 1];
+#ifndef WIN32
+  if (::realpath (path, buffer))
+    {
+      result = buffer;
+      //      cerr << "path: " << path << " result: " << result << endl;
+      return true;
+    }
+  else
+    {
+      //      cerr << "path: " << path << " result: " << result << endl;
+      if (errno != ENOENT
+	  && errno != ENOTDIR
+	  )
+	{
+	  perror ("cmt: realpath failure: " + get_absolute_path (path));
+	}
+      return false;
+    }
+#else
+  if (::_fullpath (buffer, path, PATH_MAX + 1))
+    {
+      result = buffer;
+      return true;
+    }
+  else
+    {
+      return false;
+    }
+#endif
+}
+
+/*
 //--------------------------------------------------
 bool CmtSystem::realpath_ (const cmt_string& path, cmt_string& result)
@@ -359,5 +395,5 @@
   return false;
 }
-
+*/
 //--------------------------------------------------
 bool CmtSystem::absolute_path (const cmt_string& name)
Index: /CMT/HEAD/source/cmt_use.cxx
===================================================================
--- /CMT/HEAD/source/cmt_use.cxx	(revision 606)
+++ /CMT/HEAD/source/cmt_use.cxx	(revision 607)
@@ -3574,5 +3574,11 @@
       //      offset.replace (cmtpath, empty_string);
       //cerr << "realpath_: get_cmtpath_and_offset" << endl;
-      CmtSystem::realpath_ (real_path, offset);
+      if (!CmtSystem::realpath_ (real_path, offset))
+	{
+	  CmtError::set (CmtError::file_access_error, "Cannot compute real path `" +
+			 real_path + "'");
+	  CmtError::print ();
+	  return;
+	}
       offset.replace (p->get_cmtpath_real (), empty_string);
 
