ROOT logo
// @(#)root/reflex:$Id: Tools.cxx 27468 2009-02-18 04:10:38Z russo $
// Author: Stefan Roiser 2004

// Copyright CERN, CH-1211 Geneva 23, 2004-2006, All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#ifndef REFLEX_BUILD
#define REFLEX_BUILD
#endif

#include "Reflex/Tools.h"

#include "Reflex/Kernel.h"
#include "Reflex/Type.h"
#include "Reflex/internal/OwnedMember.h"
#include <cstring>

#if defined(__GNUC__)
#include <cxxabi.h>
#elif defined(__SUNPRO_CC)
#include <demangle.h>
#endif

using namespace Reflex;

//-------------------------------------------------------------------------------
static std::string splitScopedName(const std::string& nam, bool returnScope, bool startFromLeft = false)
{
   // Split a scoped name. If returnScope is true return the scope part otherwise
   // the base part. If startFromLeft is true, parse from left otherwise from the end.
   size_t pos = 0;
   if (startFromLeft) {
      pos = Tools::GetFirstScopePosition(nam);
   }
   else {
      pos = Tools::GetBasePosition(nam);
   }
   if (pos == 0) { // There is no scope in the name.
      if (returnScope) {
         return "";
      }
      return nam;
   }
   if (returnScope) {
      return nam.substr(0, pos - 2);
   }
   return nam.substr(pos);
}


//-------------------------------------------------------------------------------
std::string Tools::GetScopeName(const std::string& name, bool startFromLeft /*= false*/)
{
   // Get the scope of a name. Start either from the beginning (startfFromLeft=true) or end.
   return splitScopedName(name, true, startFromLeft);
}


//-------------------------------------------------------------------------------
std::string Tools::GetBaseName(const std::string& name, bool startFromLeft /*= false*/)
{
   // Get the base of a name. Start either from the beginning (startFromLeft=true) or end.
   return splitScopedName(name, false, startFromLeft);
}


EFUNDAMENTALTYPE Tools::FundamentalType(const Type& typ) {
   // Return an enum representing the fundamental type passed in.
   static const TypeBase* stb_Char = Type::ByName("char").ToTypeBase();
   static const TypeBase* stb_SigChar = Type::ByName("signed char").ToTypeBase();
   static const TypeBase* stb_ShoInt = Type::ByName("short int").ToTypeBase();
   static const TypeBase* stb_Int = Type::ByName("int").ToTypeBase();
   static const TypeBase* stb_LonInt = Type::ByName("long int").ToTypeBase();
   static const TypeBase* stb_UnsChar = Type::ByName("unsigned char").ToTypeBase();
   static const TypeBase* stb_UnsShoInt = Type::ByName("unsigned short int").ToTypeBase();
   static const TypeBase* stb_UnsInt = Type::ByName("unsigned int").ToTypeBase();
   static const TypeBase* stb_UnsLonInt = Type::ByName("unsigned long int").ToTypeBase();
   static const TypeBase* stb_Bool = Type::ByName("bool").ToTypeBase();
   static const TypeBase* stb_Float = Type::ByName("float").ToTypeBase();
   static const TypeBase* stb_Double = Type::ByName("double").ToTypeBase();
   static const TypeBase* stb_LonDouble = Type::ByName("long double").ToTypeBase();
   static const TypeBase* stb_Void = Type::ByName("void").ToTypeBase();
   static const TypeBase* stb_LonLong = Type::ByName("long long").ToTypeBase();
   static const TypeBase* stb_UnsLonLong = Type::ByName("unsigned long long").ToTypeBase();

   const TypeBase* tbType = typ.FinalType().ToTypeBase();
   if ( tbType == stb_Int)          return kINT; 
   if ( tbType == stb_Float)        return kFLOAT; 
   if ( tbType == stb_Double)       return kDOUBLE; 
   if ( tbType == stb_LonInt)       return kLONG_INT; 
   if ( tbType == stb_Char)         return kCHAR;
   if ( tbType == stb_SigChar)      return kSIGNED_CHAR; 
   if ( tbType == stb_ShoInt)       return kSHORT_INT; 
   if ( tbType == stb_UnsChar)      return kUNSIGNED_CHAR; 
   if ( tbType == stb_UnsShoInt)    return kUNSIGNED_SHORT_INT; 
   if ( tbType == stb_UnsInt)       return kUNSIGNED_INT; 
   if ( tbType == stb_UnsLonInt)    return kUNSIGNED_LONG_INT; 
   if ( tbType == stb_Bool)         return kBOOL; 
   if ( tbType == stb_LonDouble)    return kLONG_DOUBLE; 
   if ( tbType == stb_Void)         return kVOID; 
   if ( tbType == stb_LonLong)      return kLONGLONG; 
   if ( tbType == stb_UnsLonLong)   return kULONGLONG; 
   return kNOTFUNDAMENTAL;
}


//-------------------------------------------------------------------------------
std::string Tools::BuildTypeName( Type & t,
                                  unsigned int /* modifiers */ ) {
//-------------------------------------------------------------------------------
// Build a complete qualified type name.
   std::string mod = "";
   if ( t.IsConstVolatile()) mod = "const volatile";
   else if ( t.IsConst())    mod = "const";
   else if ( t.IsVolatile()) mod = "volatile";

   std::string name = t.Name();

   if (t.IsPointer() || t.IsPointerToMember()) name += " " + mod;
   else                                        name = mod + " " + name;

   if ( t.IsReference()) name += "&";

   return name;
}


//-------------------------------------------------------------------------------
std::vector<std::string> Tools::GenTemplateArgVec( const std::string & Name ) {
//-------------------------------------------------------------------------------
// Return a vector of template arguments from a template type string.

   std::vector<std::string> vec;
   std::string tname;
   GetTemplateComponents( Name, tname, vec);
   return vec;
}


//-------------------------------------------------------------------------------
void Tools::GetTemplateComponents(const std::string& name, std::string& templatename, std::vector<std::string>& args)
{
   // Return the template name and a vector of template arguments.
   //
   // Note:  We must be careful of:
   //
   //       operator<,   operator>,
   //       operator<=,  operator>=,
   //       operator<<,  operator>>,
   //       operator<<=, operator>>=
   //       operator->,  operator->*,
   //       operator()
   //
   int pos = GetBasePosition(name);
   int bracket_depth = 0;
   int paren_depth = 0;
   int args_pos = 0;
   bool have_template = false;
   int len = name.size();
   for (int i = pos; !have_template && (i < len); ++i) {
      char c = name[i];
      if (c == '(') { // check for operator()
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && (name.substr(j - 7, 8) == "operator")) { // possibly found operator()
               j = i + 1;
               while ((j < len) && isspace(name[j])) {
                  ++j;
               }
               if (j < len) {
                  if (name[j] == ')') {
                     i = j;
                     continue; // skip changing depth
                  }
               }
            }
         }
         ++paren_depth;
      }
      else if (c == ')') {
         --paren_depth;
      }
      else if (c == '<') { // check for operator<, operator<=, operator<<, and operator<<=
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && (name.substr(j - 7, 8) == "operator")) { // found at least operator<
               j = i + 1;
               if (j < len) { // check for operator<=, operator<<, or operator<<=
                  if (name[j] == '=') { // operator<=
                     i = j;
                  }
                  else if (name[j] == '<') { // we have operator<<, or operator<<=
                     i = j;
                     ++j;
                     if (j < len) {
                        if (name[j] == '=') { // we have operator<<=
                           i = j;
                        }
                     }
                  }
               }
               continue; // skip changing depth
            }
         }
         if (!paren_depth && !bracket_depth) { // We found the opening '<' of a set of template arguments.
            templatename = name.substr(0, i);
            have_template = true;
            args_pos = i;
            continue;
         }
         ++bracket_depth;
      }
      else if (c == '>') { // check for operator>, operator>=, operator>>, operator>>=, operator->, or operator->*
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            bool have_arrow = false;
            if (name[j] == '-') { // allow for operator->, or operator->*
               have_arrow = true;
               --j;
            }
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && (name.substr(j - 7, 8) == "operator")) { // found at least operator> or operator->
               j = i + 1;
               if (j < len) { // check for operator->*, operator>=, operator>>, or operator>>=
                  if (have_arrow && (name[j] == '*')) { // we have operator->*
                     i = j;
                  }
                  else if (!have_arrow) {
                     if (name[j] == '=') { // we have operator>=
                        i = j;
                     }
                     else if (name[j] == '>') { // we have operator>>, or operator>>=
                        i = j;
                        ++j;
                        if (j < len) {
                           if (name[j] == '=') { // we have operator>>=
                              i = j;
                           }
                        }
                     }
                  }
               }
               continue; // skip changing depth
            }
         }
         --bracket_depth;
      }
   }
   if (!have_template) {
      return;
   }
   int begin_arg = args_pos + 1;
   for (int i = args_pos; i < len; ++i) {
      char c = name[i];
      if (c == '(') { // check for operator()
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && (name.substr(j - 7, 8) == "operator")) { // possibly found operator()
               j = i + 1;
               while ((j < len) && isspace(name[j])) {
                  ++j;
               }
               if (j < len) {
                  if (name[j] == ')') {
                     i = j;
                     continue; // skip changing depth
                  }
               }
            }
         }
         ++paren_depth;
      }
      else if (c == ')') {
         --paren_depth;
      }
      else if (c == '<') { // check for operator<, operator<=, operator<<, and operator<<=
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && (name.substr(j - 7, 8) == "operator")) { // found at least operator<
               j = i + 1;
               if (j < len) { // check for operator<=, operator<<, or operator<<=
                  if (name[j] == '=') { // operator<=
                     i = j;
                  }
                  else if (name[j] == '<') { // we have operator<<, or operator<<=
                     i = j;
                     ++j;
                     if (j < len) {
                        if (name[j] == '=') { // we have operator<<=
                           i = j;
                        }
                     }
                  }
               }
               continue; // skip changing depth
            }
         }
         ++bracket_depth;
      }
      else if (c == '>') { // check for operator>, operator>=, operator>>, operator>>=, operator->, or operator->*
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            bool have_arrow = false;
            if (name[j] == '-') { // allow for operator->, or operator->*
               have_arrow = true;
               --j;
            }
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && (name.substr(j - 7, 8) == "operator")) { // found at least operator> or operator->
               j = i + 1;
               if (j < len) { // check for operator->*, operator>=, operator>>, or operator>>=
                  if (have_arrow && (name[j] == '*')) { // we have operator->*
                     i = j;
                  }
                  else if (!have_arrow) {
                     if (name[j] == '=') { // we have operator>=
                        i = j;
                     }
                     else if (name[j] == '>') { // we have operator>>, or operator>>=
                        i = j;
                        ++j;
                        if (j < len) {
                           if (name[j] == '=') { // we have operator>>=
                              i = j;
                           }
                        }
                     }
                  }
               }
               continue; // skip changing depth
            }
         }
         --bracket_depth;
         if (!bracket_depth) { // We have reached the end of the template arguments;
            if (i - begin_arg) { // Be careful of MyTempl<>
               std::string tmp(name.substr(begin_arg, i - begin_arg));
               StringStrip(tmp);
               args.push_back(tmp);
            }
            return;
         }
      }
      else if (!paren_depth && (bracket_depth == 1) && (c == ',')) { // We have reached the end of an argument
         std::string tmp(name.substr(begin_arg, i - begin_arg));
         StringStrip(tmp);
         args.push_back(tmp);
         begin_arg = i + 1;
      }
   }
   // We cannot get here.
   return;
}


//-------------------------------------------------------------------------------
size_t Tools::GetBasePosition(const std::string& name) {
//-------------------------------------------------------------------------------
// -- Get the position of the base part of a scoped name.
   //
   // Remove the template part of the name <...>,
   // but we must be careful of:
   //
   //       operator<,   operator>,
   //       operator<=,  operator>=,
   //       operator<<,  operator>>,
   //       operator<<=, operator>>=
   //       operator->,  operator->*,
   //       operator()
   //
   int ab = 0; // angle brace depth
   int rb = 0; // right brace depth, actually parenthesis depth
   size_t pos = 0;
   for (int i = name.size() - 1; (i >= 0) && !pos; --i) {
      switch (name[i]) {
         case '>':
            {
               int j = i - 1;
               if (j > -1) {
                  if ((name[j] == '-') || (name[j] == '>')) {
                     --j;
                  }
               }
               for ( ; (j > -1) && (name[j] == ' '); --j) {}
               if ((j > -1) && (name[j] == 'r') && ((j - 7) > -1)) {
                  // -- We may have an operator name.
                  if (name.substr(j - 7, 8) == "operator") {
                     i = j - 7;
                     break;
                  }
               }
               ab++;
            }
            break;
         case '<':
            {
               int j = i - 1;
               if (j > -1) {
                  if (name[j] == '<') {
                     --j;
                  }
               }
               for ( ; (j > -1) && (name[j] == ' '); --j) {}
               if ((j > -1) && (name[j] == 'r') && ((j - 7) > -1)) {
                  // -- We may have an operator name.
                  if (name.substr(j - 7, 8) == "operator") {
                     i = j - 7;
                     break;
                  }
               }
            }
            ab--;
            break;
         case ')':
            {
               int j = i - 1;
               for ( ; (j > -1) && (name[j] == ' '); --j) {}
               if (j > -1) {
                  if (name[j] == '(') {
                     --j;
                     for ( ; (j > -1) && (name[j] == ' '); --j) {}
                     if ((j > -1) && (name[j] == 'r') && ((j - 7) > -1)) {
                        // -- We may have an operator name.
                        if (name.substr(j - 7, 8) == "operator") {
                           i = j - 7;
                           break;
                        }
                     }
                  }
               }
            }
            rb++;
            break;
         case '(':
            {
               int j = i - 1;
               for ( ; (j > -1) && (name[j] == ' '); --j) {}
               if ((j > -1) && (name[j] == 'r') && ((j - 7) > -1)) {
                  // -- We may have an operator name.
                  if (name.substr(j - 7, 8) == "operator") {
                     i = j - 7;
                     break;
                  }
               }
            }
            rb--;
            break;
         case ':':
            if (!ab && !rb && i && (name[i-1] == ':')) {
               pos = i + 1;
            }
            break;
      }
   }
   return pos;
}


//-------------------------------------------------------------------------------
size_t Tools::GetFirstScopePosition(const std::string& name)
{
   // Get the position of the first scope of a scoped name.
   //
   // Note:  We must be careful of:
   //
   //       operator<,   operator>,
   //       operator<=,  operator>=,
   //       operator<<,  operator>>,
   //       operator<<=, operator>>=
   //       operator->,  operator->*,
   //       operator()
   //
   int bracket_depth = 0;
   int paren_depth = 0;
   int len = name.size();
   for (int i = 0; i < len; ++i) {
      char c = name[i];
      if (c == '(') { // check for operator()
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && (name.substr(j - 7, 8) == "operator")) { // possibly found operator()
               j = i + 1;
               while ((j < len) && isspace(name[j])) {
                  ++j;
               }
               if (j < len) {
                  if (name[j] == ')') {
                     i = j;
                     continue; // skip changing depth
                  }
               }
            }
         }
         ++paren_depth;
      }
      else if (c == ')') {
         --paren_depth;
      }
      else if (c == '<') { // check for operator<, operator<=, operator<<, and operator<<=
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && (name.substr(j - 7, 8) == "operator")) { // found at least operator<
               j = i + 1;
               if (j < len) { // check for operator<=, operator<<, or operator<<=
                  if (name[j] == '=') { // operator<=
                     i = j;
                  }
                  else if (name[j] == '<') { // we have operator<<, or operator<<=
                     i = j;
                     ++j;
                     if (j < len) {
                        if (name[j] == '=') { // we have operator<<=
                           i = j;
                        }
                     }
                  }
               }
               continue; // skip changing depth
            }
         }
         ++bracket_depth;
      }
      else if (c == '>') { // check for operator>, operator>=, operator>>, operator>>=, operator->, or operator->*
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            bool have_arrow = false;
            if (name[j] == '-') { // allow for operator->, or operator->*
               have_arrow = true;
               --j;
            }
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && (name.substr(j - 7, 8) == "operator")) { // found at least operator> or operator->
               j = i + 1;
               if (j < len) { // check for operator->*, operator>=, operator>>, or operator>>=
                  if (have_arrow && (name[j] == '*')) { // we have operator->*
                     i = j;
                  }
                  else if (!have_arrow) {
                     if (name[j] == '=') { // we have operator>=
                        i = j;
                     }
                     else if (name[j] == '>') { // we have operator>>, or operator>>=
                        i = j;
                        ++j;
                        if (j < len) {
                           if (name[j] == '=') { // we have operator>>=
                              i = j;
                           }
                        }
                     }
                  }
               }
               continue; // skip changing depth
            }
         }
         --bracket_depth;
      }
      else if (!paren_depth && !bracket_depth && (c == ':') && ((i + 1) < len) && (name[i+1] == ':')) {
         return i + 2;
      }
   }
   return 0;
}


//-------------------------------------------------------------------------------
bool Tools::IsTemplated(const char* name)
{
   // Check if the final component of a qualified-id has template arguments.
   //
   // Note:  We must be careful of:
   //
   //       operator<,   operator>,
   //       operator<=,  operator>=,
   //       operator<<,  operator>>,
   //       operator<<=, operator>>=
   //       operator->,  operator->*,
   //       operator()
   //
   int pos = GetBasePosition(std::string(name));
   int bracket_depth = 0;
   int paren_depth = 0;
   int len = std::strlen(name);
   for (int i = pos; i < len; ++i) {
      char c = name[i];
      if (c == '(') { // check for operator()
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && !strncmp(name + j - 7, "operator", 8)) { // possibly found operator()
               j = i + 1;
               while ((j < len) && isspace(name[j])) {
                  ++j;
               }
               if (j < len) {
                  if (name[j] == ')') {
                     i = j;
                     continue; // skip changing depth
                  }
               }
            }
         }
         ++paren_depth;
      }
      else if (c == ')') {
         --paren_depth;
      }
      else if (c == '<') { // check for operator<, operator<=, operator<<, and operator<<=
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && !strncmp(name + j - 7, "operator", 8)) { // found at least operator<
               j = i + 1;
               if (j < len) { // check for operator<=, operator<<, or operator<<=
                  if (name[j] == '=') { // operator<=
                     i = j;
                  }
                  else if (name[j] == '<') { // we have operator<<, or operator<<=
                     i = j;
                     ++j;
                     if (j < len) {
                        if (name[j] == '=') { // we have operator<<=
                           i = j;
                        }
                     }
                  }
               }
               continue; // skip changing depth
            }
         }
         if (!paren_depth && !bracket_depth) {
            return true; // We found the opening '<' of a set of template arguments.
         }
         ++bracket_depth;
      }
      else if (c == '>') { // check for operator>, operator>=, operator>>, operator>>=, operator->, or operator->*
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            bool have_arrow = false;
            if (name[j] == '-') { // allow for operator->, or operator->*
               have_arrow = true;
               --j;
            }
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && !strncmp(name + j - 7, "operator", 8)) { // found at least operator> or operator->
               j = i + 1;
               if (j < len) { // check for operator->*, operator>=, operator>>, or operator>>=
                  if (have_arrow && (name[j] == '*')) { // we have operator->*
                     i = j;
                  }
                  else if (!have_arrow) {
                     if (name[j] == '=') { // we have operator>=
                        i = j;
                     }
                     else if (name[j] == '>') { // we have operator>>, or operator>>=
                        i = j;
                        ++j;
                        if (j < len) {
                           if (name[j] == '=') { // we have operator>>=
                              i = j;
                           }
                        }
                     }
                  }
               }
               continue; // skip changing depth
            }
         }
         --bracket_depth;
      }
   }
   return false;
}


//-------------------------------------------------------------------------------
void Tools::StringSplit( std::vector < std::string > & splitValues, 
                         const std::string & str,
                         const std::string & delim ) {
//-------------------------------------------------------------------------------
// Split a string by a delimiter and return it's vector of strings.
   if (!str.size()) {
      return;
   }

   std::string str2 = str;
  
   size_t pos = 0;
  
   while (( pos = str2.find_first_of( delim )) != std::string::npos ) {
      std::string s = str2.substr(0, pos);
      StringStrip( s );
      splitValues.push_back( s );
      str2 = str2.substr( pos + delim.length());
   }
  
   StringStrip( str2 );
   splitValues.push_back( str2 );
}


//-------------------------------------------------------------------------------
std::string Tools::StringVec2String( const std::vector<std::string> & vec ) {
//-------------------------------------------------------------------------------
   std::string s = "";
   StdString_Iterator lastbutone = vec.end()-1;
   for( StdString_Iterator it = vec.begin(); it != vec.end(); ++it) {
      s += *it;
      if (it != lastbutone ) s += ", "; 
   }
   return s;
}


//-------------------------------------------------------------------------------
std::string Tools::Demangle( const std::type_info & ti ) { 
//-------------------------------------------------------------------------------
// Demangle a type_info object.
#if defined(_WIN32)
   static std::vector<std::string> keywords;
   if ( 0 == keywords.size() ) {
      keywords.push_back("class ");
      keywords.push_back("struct ");
      keywords.push_back("enum ");
      keywords.push_back("union ");
      keywords.push_back("__cdecl");
   }
   std::string r = ti.name();
   for ( size_t i = 0; i < keywords.size(); i ++ ) {
      while (r.find(keywords[i]) != std::string::npos) 
         r = r.replace(r.find(keywords[i]), keywords[i].size(), "");
      while (r.find(" *") != std::string::npos) 
         r = r.replace(r.find(" *"), 2, "*");
      while (r.find(" &") != std::string::npos) 
         r = r.replace(r.find(" &"), 2, "&");
   }
   return r;

#elif defined(__GNUC__)

   int status = 0;
   bool remove_additional_pointer = false;
   std::string  mangled = ti.name();

   // if the At Name is string return the final string Name 
   // abi::Demangle would return "std::string" instead
   if ( mangled == "Ss" ) return "std::basic_string<char>";

#if __GNUC__ <= 3 && __GNUC_MINOR__ <= 3
   // Function types are not decoded at all. We are an extra 'P' to convert it to a pointer
   // and remove it at the end.
   if ( mangled[0] == 'F' ) {
      mangled.insert(0,"P");
      remove_additional_pointer = true;
   }
#elif __GNUC__ >= 4
   // From gcc 4.0 on the fundamental types are not demangled anymore by the dynamic demangler
   if (mangled.length() == 1) {
      switch ( mangled[0] ) {
      case 'a': return "signed char";        break;
      case 'b': return "bool";               break;
      case 'c': return "char";               break;
      case 'd': return "double";             break;
      case 'e': return "long double";        break;
      case 'f': return "float";              break;
      case 'g': return "__float128";         break;
      case 'h': return "unsigned char";      break;
      case 'i': return "int";                break;
      case 'j': return "unsigned int";       break;
         //case 'k': return "";                   break;
      case 'l': return "long";               break;
      case 'm': return "unsigned long";      break;
      case 'n': return "__int128";           break;
      case 'o': return "unsigned __int128";  break;
         //case 'p': return "";                   break;
         //case 'q': return "";                   break;
         //case 'r': return "";                   break;
      case 's': return "short";              break;
      case 't': return "unsigned short";     break;
         //case 'u': return "";                   break;
      case 'v': return "void";               break;
      case 'w': return "wchar_t";            break;
      case 'x': return "long long";          break;
      case 'y': return "unsigned long long"; break;
      case 'z': return "...";                break;
      default:                               break;
      }
   }
#endif
   char * c_demangled = abi::__cxa_demangle( mangled.c_str(), 0, 0, & status );
   if ( status == -1 ) {
      throw RuntimeError("Memory allocation failure while demangling ");
   }
   else if ( status == -2 ) {
      throw RuntimeError( std::string(mangled) + " is not a valid Name under the C++ ABI");
   }
   else if ( status == -3 ) {
      throw RuntimeError( std::string("Failure while demangling ") + mangled +
                          ". One of the arguments is invalid ");
   }
   else {
      std::string demangled = c_demangled;
      free( c_demangled );
      if ( remove_additional_pointer ) {
         demangled = demangled.replace(demangled.find("(*)"), 3, "");
      }
      while ( demangled.find(", ") != std::string::npos ) {
         demangled = demangled.replace(demangled.find(", "), 2, ",");
      }
      return demangled;
   }

#elif defined(__SUNPRO_CC)

   const char* mangled = ti.name();
   size_t buffer = 1024;
   char * c_demangled = new char[buffer];
   int ret = cplus_demangle( mangled, c_demangled, buffer);
   while ( ret == -1 ) {
      buffer = buffer*2;
      delete[] c_demangled;
      c_demangled = new char[buffer];
      ret = cplus_demangle( mangled, c_demangled, buffer);
   }
   if ( ret == 1 ) {
      throw RuntimeError(std::string("Symbol ") + mangled + " not mangled correctly");
   }
   else {
      std::string demangled = Tools::NormalizeName(c_demangled);
      delete[] c_demangled;
      return demangled;
   }

#elif defined(__IBMCPP__)

   return Tools::NormalizeName(ti.name());

#endif
   return "";
}


//-------------------------------------------------------------------------------
void Tools::StringSplitPair( std::string & val1,
                             std::string & val2,
                             const std::string & str,
                             const std::string & delim ) { 
//-------------------------------------------------------------------------------
// Split a string by a delimiter into a pair and return them as val1 and val2.
   std::string str2 = str;
   size_t pos = str2.rfind( delim );
   if ( pos != std::string::npos ) { 
      val1 = str2.substr( 0, pos ); 
      val2 = str2.substr( pos + delim.length());
   }
   else { 
      val1 = str2; 
   }
   StringStrip( val1 );
   StringStrip( val2 );
}


//-------------------------------------------------------------------------------
void Tools::StringStrip( std::string & str ) {
//-------------------------------------------------------------------------------
// Strip spaces at the beginning and the end from a string.
   if (str.empty()) return;
   size_t sPos = 0;
   size_t ePos = str.length() - 1;
   while ( ePos>=sPos && str[sPos] == ' ' ) { ++sPos; }
   while ( ePos> sPos && str[ePos] == ' ' ) { --ePos; }
   if (ePos >= sPos) {
      str = str.substr( sPos, ePos + 1 - sPos );
   } else {
      str.clear(); // all spaces
   }
}


//-------------------------------------------------------------------------------
std::string Tools::GetTemplateArguments(const char* name)
{
   // Return the template arguments part of a templated type name.
   //
   // Note:  We must be careful of:
   //
   //       operator<,   operator>,
   //       operator<=,  operator>=,
   //       operator<<,  operator>>,
   //       operator<<=, operator>>=
   //       operator->,  operator->*,
   //       operator()
   //
   int pos = GetBasePosition(std::string(name));
   int bracket_depth = 0;
   int paren_depth = 0;
   int len = std::strlen(name);
   for (int i = pos; i < len; ++i) {
      char c = name[i];
      if (c == '(') { // check for operator()
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && !strncmp(name + j - 7, "operator", 8)) { // possibly found operator()
               j = i + 1;
               while ((j < len) && isspace(name[j])) {
                  ++j;
               }
               if (j < len) {
                  if (name[j] == ')') {
                     i = j;
                     continue; // skip changing depth
                  }
               }
            }
         }
         ++paren_depth;
      }
      else if (c == ')') {
         --paren_depth;
      }
      else if (c == '<') { // check for operator<, operator<=, operator<<, and operator<<=
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && !strncmp(name + j - 7, "operator", 8)) { // found at least operator<
               j = i + 1;
               if (j < len) { // check for operator<=, operator<<, or operator<<=
                  if (name[j] == '=') { // operator<=
                     i = j;
                  }
                  else if (name[j] == '<') { // we have operator<<, or operator<<=
                     i = j;
                     ++j;
                     if (j < len) {
                        if (name[j] == '=') { // we have operator<<=
                           i = j;
                        }
                     }
                  }
               }
               continue; // skip changing depth
            }
         }
         if (!paren_depth && !bracket_depth) { // We found the opening '<' of a set of template arguments.
            return name + i;
         }
         ++bracket_depth;
      }
      else if (c == '>') { // check for operator>, operator>=, operator>>, operator>>=, operator->, or operator->*
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            bool have_arrow = false;
            if (name[j] == '-') { // allow for operator->, or operator->*
               have_arrow = true;
               --j;
            }
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && !strncmp(name + j - 7, "operator", 8)) { // found at least operator> or operator->
               j = i + 1;
               if (j < len) { // check for operator->*, operator>=, operator>>, or operator>>=
                  if (have_arrow && (name[j] == '*')) { // we have operator->*
                     i = j;
                  }
                  else if (!have_arrow) {
                     if (name[j] == '=') { // we have operator>=
                        i = j;
                     }
                     else if (name[j] == '>') { // we have operator>>, or operator>>=
                        i = j;
                        ++j;
                        if (j < len) {
                           if (name[j] == '=') { // we have operator>>=
                              i = j;
                           }
                        }
                     }
                  }
               }
               continue; // skip changing depth
            }
         }
         --bracket_depth;
      }
   }
   return std::string();
}


//-------------------------------------------------------------------------------
std::string Tools::GetTemplateName(const char* name)
{
   // Return the fully qualified scope name without template arguments.
   //
   // Note:  We must be careful of:
   //
   //       operator<,   operator>,
   //       operator<=,  operator>=,
   //       operator<<,  operator>>,
   //       operator<<=, operator>>=
   //       operator->,  operator->*,
   //       operator()
   //
   int base_pos = GetBasePosition(std::string(name));
   int bracket_depth = 0;
   int paren_depth = 0;
   int len = std::strlen(name);
   for (int i = base_pos; i < len; ++i) {
      char c = name[i];
      if (c == '(') { // check for operator()
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && !strncmp(name + j - 7, "operator", 8)) { // possibly found operator()
               j = i + 1;
               while ((j < len) && isspace(name[j])) {
                  ++j;
               }
               if (j < len) {
                  if (name[j] == ')') {
                     i = j;
                     continue; // skip changing depth
                  }
               }
            }
         }
         ++paren_depth;
      }
      else if (c == ')') {
         --paren_depth;
      }
      else if (c == '<') { // check for operator<, operator<=, operator<<, and operator<<=
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && !strncmp(name + j - 7, "operator", 8)) { // found at least operator<
               j = i + 1;
               if (j < len) { // check for operator<=, operator<<, or operator<<=
                  if (name[j] == '=') { // operator<=
                     i = j;
                  }
                  else if (name[j] == '<') { // we have operator<<, or operator<<=
                     i = j;
                     ++j;
                     if (j < len) {
                        if (name[j] == '=') { // we have operator<<=
                           i = j;
                        }
                     }
                  }
               }
               continue; // skip changing depth
            }
         }
         if (!paren_depth && !bracket_depth) { // We found the opening '<' of a set of template arguments.
            // Remove any trailing spaces, we might be operator<< <int>
            int j = i - 1;
            while ((j >= base_pos) && isspace(name[j])) {
               --j;
            }
            return std::string(name, j + 1);
         }
         ++bracket_depth;
      }
      else if (c == '>') { // check for operator>, operator>=, operator>>, operator>>=, operator->, or operator->*
         if (i > 7) { // there is room for "operator"
            int j = i - 1;
            bool have_arrow = false;
            if (name[j] == '-') { // allow for operator->, or operator->*
               have_arrow = true;
               --j;
            }
            while (j && isspace(name[j])) {
               --j;
            }
            if ((j > 6) && !strncmp(name + j - 7, "operator", 8)) { // found at least operator> or operator->
               j = i + 1;
               if (j < len) { // check for operator->*, operator>=, operator>>, or operator>>=
                  if (have_arrow && (name[j] == '*')) { // we have operator->*
                     i = j;
                  }
                  else if (!have_arrow) {
                     if (name[j] == '=') { // we have operator>=
                        i = j;
                     }
                     else if (name[j] == '>') { // we have operator>>, or operator>>=
                        i = j;
                        ++j;
                        if (j < len) {
                           if (name[j] == '=') { // we have operator>>=
                              i = j;
                           }
                        }
                     }
                  }
               }
               continue; // skip changing depth
            }
         }
         --bracket_depth;
      }
   }
   return name;
}


//-------------------------------------------------------------------------------
bool isalphanum(int i) {
//-------------------------------------------------------------------------------
// Return true if char is alpha or digit.
   return isalpha(i) || isdigit(i);
}


//-------------------------------------------------------------------------------
std::string Tools::NormalizeName( const char * nam ) {
//-------------------------------------------------------------------------------
// Normalize a type name.
   std::string norm_name;
   char prev = 0;
   for (size_t i = 0; nam[i] != 0; i++) {
      char curr = nam[i];
      if (curr == ' ') {
         char next = 0;
         while (nam[i] != 0 && (next = nam[i + 1]) == ' ') {
            ++i;
         }
         if (!isalphanum(prev) || !isalpha(next)) {
            continue; // continue on non-word boundaries
         }
      } else if ((curr == '>' && prev == '>') || (curr == '(' && prev != ')')) {
         norm_name += ' ';
      }
      norm_name += (prev = curr);
   }

   return norm_name;
}


//-------------------------------------------------------------------------------
std::string Tools::NormalizeName( const std::string & nam ) {
//-------------------------------------------------------------------------------
   return Tools::NormalizeName(nam.c_str());
}
 Tools.cxx:1
 Tools.cxx:2
 Tools.cxx:3
 Tools.cxx:4
 Tools.cxx:5
 Tools.cxx:6
 Tools.cxx:7
 Tools.cxx:8
 Tools.cxx:9
 Tools.cxx:10
 Tools.cxx:11
 Tools.cxx:12
 Tools.cxx:13
 Tools.cxx:14
 Tools.cxx:15
 Tools.cxx:16
 Tools.cxx:17
 Tools.cxx:18
 Tools.cxx:19
 Tools.cxx:20
 Tools.cxx:21
 Tools.cxx:22
 Tools.cxx:23
 Tools.cxx:24
 Tools.cxx:25
 Tools.cxx:26
 Tools.cxx:27
 Tools.cxx:28
 Tools.cxx:29
 Tools.cxx:30
 Tools.cxx:31
 Tools.cxx:32
 Tools.cxx:33
 Tools.cxx:34
 Tools.cxx:35
 Tools.cxx:36
 Tools.cxx:37
 Tools.cxx:38
 Tools.cxx:39
 Tools.cxx:40
 Tools.cxx:41
 Tools.cxx:42
 Tools.cxx:43
 Tools.cxx:44
 Tools.cxx:45
 Tools.cxx:46
 Tools.cxx:47
 Tools.cxx:48
 Tools.cxx:49
 Tools.cxx:50
 Tools.cxx:51
 Tools.cxx:52
 Tools.cxx:53
 Tools.cxx:54
 Tools.cxx:55
 Tools.cxx:56
 Tools.cxx:57
 Tools.cxx:58
 Tools.cxx:59
 Tools.cxx:60
 Tools.cxx:61
 Tools.cxx:62
 Tools.cxx:63
 Tools.cxx:64
 Tools.cxx:65
 Tools.cxx:66
 Tools.cxx:67
 Tools.cxx:68
 Tools.cxx:69
 Tools.cxx:70
 Tools.cxx:71
 Tools.cxx:72
 Tools.cxx:73
 Tools.cxx:74
 Tools.cxx:75
 Tools.cxx:76
 Tools.cxx:77
 Tools.cxx:78
 Tools.cxx:79
 Tools.cxx:80
 Tools.cxx:81
 Tools.cxx:82
 Tools.cxx:83
 Tools.cxx:84
 Tools.cxx:85
 Tools.cxx:86
 Tools.cxx:87
 Tools.cxx:88
 Tools.cxx:89
 Tools.cxx:90
 Tools.cxx:91
 Tools.cxx:92
 Tools.cxx:93
 Tools.cxx:94
 Tools.cxx:95
 Tools.cxx:96
 Tools.cxx:97
 Tools.cxx:98
 Tools.cxx:99
 Tools.cxx:100
 Tools.cxx:101
 Tools.cxx:102
 Tools.cxx:103
 Tools.cxx:104
 Tools.cxx:105
 Tools.cxx:106
 Tools.cxx:107
 Tools.cxx:108
 Tools.cxx:109
 Tools.cxx:110
 Tools.cxx:111
 Tools.cxx:112
 Tools.cxx:113
 Tools.cxx:114
 Tools.cxx:115
 Tools.cxx:116
 Tools.cxx:117
 Tools.cxx:118
 Tools.cxx:119
 Tools.cxx:120
 Tools.cxx:121
 Tools.cxx:122
 Tools.cxx:123
 Tools.cxx:124
 Tools.cxx:125
 Tools.cxx:126
 Tools.cxx:127
 Tools.cxx:128
 Tools.cxx:129
 Tools.cxx:130
 Tools.cxx:131
 Tools.cxx:132
 Tools.cxx:133
 Tools.cxx:134
 Tools.cxx:135
 Tools.cxx:136
 Tools.cxx:137
 Tools.cxx:138
 Tools.cxx:139
 Tools.cxx:140
 Tools.cxx:141
 Tools.cxx:142
 Tools.cxx:143
 Tools.cxx:144
 Tools.cxx:145
 Tools.cxx:146
 Tools.cxx:147
 Tools.cxx:148
 Tools.cxx:149
 Tools.cxx:150
 Tools.cxx:151
 Tools.cxx:152
 Tools.cxx:153
 Tools.cxx:154
 Tools.cxx:155
 Tools.cxx:156
 Tools.cxx:157
 Tools.cxx:158
 Tools.cxx:159
 Tools.cxx:160
 Tools.cxx:161
 Tools.cxx:162
 Tools.cxx:163
 Tools.cxx:164
 Tools.cxx:165
 Tools.cxx:166
 Tools.cxx:167
 Tools.cxx:168
 Tools.cxx:169
 Tools.cxx:170
 Tools.cxx:171
 Tools.cxx:172
 Tools.cxx:173
 Tools.cxx:174
 Tools.cxx:175
 Tools.cxx:176
 Tools.cxx:177
 Tools.cxx:178
 Tools.cxx:179
 Tools.cxx:180
 Tools.cxx:181
 Tools.cxx:182
 Tools.cxx:183
 Tools.cxx:184
 Tools.cxx:185
 Tools.cxx:186
 Tools.cxx:187
 Tools.cxx:188
 Tools.cxx:189
 Tools.cxx:190
 Tools.cxx:191
 Tools.cxx:192
 Tools.cxx:193
 Tools.cxx:194
 Tools.cxx:195
 Tools.cxx:196
 Tools.cxx:197
 Tools.cxx:198
 Tools.cxx:199
 Tools.cxx:200
 Tools.cxx:201
 Tools.cxx:202
 Tools.cxx:203
 Tools.cxx:204
 Tools.cxx:205
 Tools.cxx:206
 Tools.cxx:207
 Tools.cxx:208
 Tools.cxx:209
 Tools.cxx:210
 Tools.cxx:211
 Tools.cxx:212
 Tools.cxx:213
 Tools.cxx:214
 Tools.cxx:215
 Tools.cxx:216
 Tools.cxx:217
 Tools.cxx:218
 Tools.cxx:219
 Tools.cxx:220
 Tools.cxx:221
 Tools.cxx:222
 Tools.cxx:223
 Tools.cxx:224
 Tools.cxx:225
 Tools.cxx:226
 Tools.cxx:227
 Tools.cxx:228
 Tools.cxx:229
 Tools.cxx:230
 Tools.cxx:231
 Tools.cxx:232
 Tools.cxx:233
 Tools.cxx:234
 Tools.cxx:235
 Tools.cxx:236
 Tools.cxx:237
 Tools.cxx:238
 Tools.cxx:239
 Tools.cxx:240
 Tools.cxx:241
 Tools.cxx:242
 Tools.cxx:243
 Tools.cxx:244
 Tools.cxx:245
 Tools.cxx:246
 Tools.cxx:247
 Tools.cxx:248
 Tools.cxx:249
 Tools.cxx:250
 Tools.cxx:251
 Tools.cxx:252
 Tools.cxx:253
 Tools.cxx:254
 Tools.cxx:255
 Tools.cxx:256
 Tools.cxx:257
 Tools.cxx:258
 Tools.cxx:259
 Tools.cxx:260
 Tools.cxx:261
 Tools.cxx:262
 Tools.cxx:263
 Tools.cxx:264
 Tools.cxx:265
 Tools.cxx:266
 Tools.cxx:267
 Tools.cxx:268
 Tools.cxx:269
 Tools.cxx:270
 Tools.cxx:271
 Tools.cxx:272
 Tools.cxx:273
 Tools.cxx:274
 Tools.cxx:275
 Tools.cxx:276
 Tools.cxx:277
 Tools.cxx:278
 Tools.cxx:279
 Tools.cxx:280
 Tools.cxx:281
 Tools.cxx:282
 Tools.cxx:283
 Tools.cxx:284
 Tools.cxx:285
 Tools.cxx:286
 Tools.cxx:287
 Tools.cxx:288
 Tools.cxx:289
 Tools.cxx:290
 Tools.cxx:291
 Tools.cxx:292
 Tools.cxx:293
 Tools.cxx:294
 Tools.cxx:295
 Tools.cxx:296
 Tools.cxx:297
 Tools.cxx:298
 Tools.cxx:299
 Tools.cxx:300
 Tools.cxx:301
 Tools.cxx:302
 Tools.cxx:303
 Tools.cxx:304
 Tools.cxx:305
 Tools.cxx:306
 Tools.cxx:307
 Tools.cxx:308
 Tools.cxx:309
 Tools.cxx:310
 Tools.cxx:311
 Tools.cxx:312
 Tools.cxx:313
 Tools.cxx:314
 Tools.cxx:315
 Tools.cxx:316
 Tools.cxx:317
 Tools.cxx:318
 Tools.cxx:319
 Tools.cxx:320
 Tools.cxx:321
 Tools.cxx:322
 Tools.cxx:323
 Tools.cxx:324
 Tools.cxx:325
 Tools.cxx:326
 Tools.cxx:327
 Tools.cxx:328
 Tools.cxx:329
 Tools.cxx:330
 Tools.cxx:331
 Tools.cxx:332
 Tools.cxx:333
 Tools.cxx:334
 Tools.cxx:335
 Tools.cxx:336
 Tools.cxx:337
 Tools.cxx:338
 Tools.cxx:339
 Tools.cxx:340
 Tools.cxx:341
 Tools.cxx:342
 Tools.cxx:343
 Tools.cxx:344
 Tools.cxx:345
 Tools.cxx:346
 Tools.cxx:347
 Tools.cxx:348
 Tools.cxx:349
 Tools.cxx:350
 Tools.cxx:351
 Tools.cxx:352
 Tools.cxx:353
 Tools.cxx:354
 Tools.cxx:355
 Tools.cxx:356
 Tools.cxx:357
 Tools.cxx:358
 Tools.cxx:359
 Tools.cxx:360
 Tools.cxx:361
 Tools.cxx:362
 Tools.cxx:363
 Tools.cxx:364
 Tools.cxx:365
 Tools.cxx:366
 Tools.cxx:367
 Tools.cxx:368
 Tools.cxx:369
 Tools.cxx:370
 Tools.cxx:371
 Tools.cxx:372
 Tools.cxx:373
 Tools.cxx:374
 Tools.cxx:375
 Tools.cxx:376
 Tools.cxx:377
 Tools.cxx:378
 Tools.cxx:379
 Tools.cxx:380
 Tools.cxx:381
 Tools.cxx:382
 Tools.cxx:383
 Tools.cxx:384
 Tools.cxx:385
 Tools.cxx:386
 Tools.cxx:387
 Tools.cxx:388
 Tools.cxx:389
 Tools.cxx:390
 Tools.cxx:391
 Tools.cxx:392
 Tools.cxx:393
 Tools.cxx:394
 Tools.cxx:395
 Tools.cxx:396
 Tools.cxx:397
 Tools.cxx:398
 Tools.cxx:399
 Tools.cxx:400
 Tools.cxx:401
 Tools.cxx:402
 Tools.cxx:403
 Tools.cxx:404
 Tools.cxx:405
 Tools.cxx:406
 Tools.cxx:407
 Tools.cxx:408
 Tools.cxx:409
 Tools.cxx:410
 Tools.cxx:411
 Tools.cxx:412
 Tools.cxx:413
 Tools.cxx:414
 Tools.cxx:415
 Tools.cxx:416
 Tools.cxx:417
 Tools.cxx:418
 Tools.cxx:419
 Tools.cxx:420
 Tools.cxx:421
 Tools.cxx:422
 Tools.cxx:423
 Tools.cxx:424
 Tools.cxx:425
 Tools.cxx:426
 Tools.cxx:427
 Tools.cxx:428
 Tools.cxx:429
 Tools.cxx:430
 Tools.cxx:431
 Tools.cxx:432
 Tools.cxx:433
 Tools.cxx:434
 Tools.cxx:435
 Tools.cxx:436
 Tools.cxx:437
 Tools.cxx:438
 Tools.cxx:439
 Tools.cxx:440
 Tools.cxx:441
 Tools.cxx:442
 Tools.cxx:443
 Tools.cxx:444
 Tools.cxx:445
 Tools.cxx:446
 Tools.cxx:447
 Tools.cxx:448
 Tools.cxx:449
 Tools.cxx:450
 Tools.cxx:451
 Tools.cxx:452
 Tools.cxx:453
 Tools.cxx:454
 Tools.cxx:455
 Tools.cxx:456
 Tools.cxx:457
 Tools.cxx:458
 Tools.cxx:459
 Tools.cxx:460
 Tools.cxx:461
 Tools.cxx:462
 Tools.cxx:463
 Tools.cxx:464
 Tools.cxx:465
 Tools.cxx:466
 Tools.cxx:467
 Tools.cxx:468
 Tools.cxx:469
 Tools.cxx:470
 Tools.cxx:471
 Tools.cxx:472
 Tools.cxx:473
 Tools.cxx:474
 Tools.cxx:475
 Tools.cxx:476
 Tools.cxx:477
 Tools.cxx:478
 Tools.cxx:479
 Tools.cxx:480
 Tools.cxx:481
 Tools.cxx:482
 Tools.cxx:483
 Tools.cxx:484
 Tools.cxx:485
 Tools.cxx:486
 Tools.cxx:487
 Tools.cxx:488
 Tools.cxx:489
 Tools.cxx:490
 Tools.cxx:491
 Tools.cxx:492
 Tools.cxx:493
 Tools.cxx:494
 Tools.cxx:495
 Tools.cxx:496
 Tools.cxx:497
 Tools.cxx:498
 Tools.cxx:499
 Tools.cxx:500
 Tools.cxx:501
 Tools.cxx:502
 Tools.cxx:503
 Tools.cxx:504
 Tools.cxx:505
 Tools.cxx:506
 Tools.cxx:507
 Tools.cxx:508
 Tools.cxx:509
 Tools.cxx:510
 Tools.cxx:511
 Tools.cxx:512
 Tools.cxx:513
 Tools.cxx:514
 Tools.cxx:515
 Tools.cxx:516
 Tools.cxx:517
 Tools.cxx:518
 Tools.cxx:519
 Tools.cxx:520
 Tools.cxx:521
 Tools.cxx:522
 Tools.cxx:523
 Tools.cxx:524
 Tools.cxx:525
 Tools.cxx:526
 Tools.cxx:527
 Tools.cxx:528
 Tools.cxx:529
 Tools.cxx:530
 Tools.cxx:531
 Tools.cxx:532
 Tools.cxx:533
 Tools.cxx:534
 Tools.cxx:535
 Tools.cxx:536
 Tools.cxx:537
 Tools.cxx:538
 Tools.cxx:539
 Tools.cxx:540
 Tools.cxx:541
 Tools.cxx:542
 Tools.cxx:543
 Tools.cxx:544
 Tools.cxx:545
 Tools.cxx:546
 Tools.cxx:547
 Tools.cxx:548
 Tools.cxx:549
 Tools.cxx:550
 Tools.cxx:551
 Tools.cxx:552
 Tools.cxx:553
 Tools.cxx:554
 Tools.cxx:555
 Tools.cxx:556
 Tools.cxx:557
 Tools.cxx:558
 Tools.cxx:559
 Tools.cxx:560
 Tools.cxx:561
 Tools.cxx:562
 Tools.cxx:563
 Tools.cxx:564
 Tools.cxx:565
 Tools.cxx:566
 Tools.cxx:567
 Tools.cxx:568
 Tools.cxx:569
 Tools.cxx:570
 Tools.cxx:571
 Tools.cxx:572
 Tools.cxx:573
 Tools.cxx:574
 Tools.cxx:575
 Tools.cxx:576
 Tools.cxx:577
 Tools.cxx:578
 Tools.cxx:579
 Tools.cxx:580
 Tools.cxx:581
 Tools.cxx:582
 Tools.cxx:583
 Tools.cxx:584
 Tools.cxx:585
 Tools.cxx:586
 Tools.cxx:587
 Tools.cxx:588
 Tools.cxx:589
 Tools.cxx:590
 Tools.cxx:591
 Tools.cxx:592
 Tools.cxx:593
 Tools.cxx:594
 Tools.cxx:595
 Tools.cxx:596
 Tools.cxx:597
 Tools.cxx:598
 Tools.cxx:599
 Tools.cxx:600
 Tools.cxx:601
 Tools.cxx:602
 Tools.cxx:603
 Tools.cxx:604
 Tools.cxx:605
 Tools.cxx:606
 Tools.cxx:607
 Tools.cxx:608
 Tools.cxx:609
 Tools.cxx:610
 Tools.cxx:611
 Tools.cxx:612
 Tools.cxx:613
 Tools.cxx:614
 Tools.cxx:615
 Tools.cxx:616
 Tools.cxx:617
 Tools.cxx:618
 Tools.cxx:619
 Tools.cxx:620
 Tools.cxx:621
 Tools.cxx:622
 Tools.cxx:623
 Tools.cxx:624
 Tools.cxx:625
 Tools.cxx:626
 Tools.cxx:627
 Tools.cxx:628
 Tools.cxx:629
 Tools.cxx:630
 Tools.cxx:631
 Tools.cxx:632
 Tools.cxx:633
 Tools.cxx:634
 Tools.cxx:635
 Tools.cxx:636
 Tools.cxx:637
 Tools.cxx:638
 Tools.cxx:639
 Tools.cxx:640
 Tools.cxx:641
 Tools.cxx:642
 Tools.cxx:643
 Tools.cxx:644
 Tools.cxx:645
 Tools.cxx:646
 Tools.cxx:647
 Tools.cxx:648
 Tools.cxx:649
 Tools.cxx:650
 Tools.cxx:651
 Tools.cxx:652
 Tools.cxx:653
 Tools.cxx:654
 Tools.cxx:655
 Tools.cxx:656
 Tools.cxx:657
 Tools.cxx:658
 Tools.cxx:659
 Tools.cxx:660
 Tools.cxx:661
 Tools.cxx:662
 Tools.cxx:663
 Tools.cxx:664
 Tools.cxx:665
 Tools.cxx:666
 Tools.cxx:667
 Tools.cxx:668
 Tools.cxx:669
 Tools.cxx:670
 Tools.cxx:671
 Tools.cxx:672
 Tools.cxx:673
 Tools.cxx:674
 Tools.cxx:675
 Tools.cxx:676
 Tools.cxx:677
 Tools.cxx:678
 Tools.cxx:679
 Tools.cxx:680
 Tools.cxx:681
 Tools.cxx:682
 Tools.cxx:683
 Tools.cxx:684
 Tools.cxx:685
 Tools.cxx:686
 Tools.cxx:687
 Tools.cxx:688
 Tools.cxx:689
 Tools.cxx:690
 Tools.cxx:691
 Tools.cxx:692
 Tools.cxx:693
 Tools.cxx:694
 Tools.cxx:695
 Tools.cxx:696
 Tools.cxx:697
 Tools.cxx:698
 Tools.cxx:699
 Tools.cxx:700
 Tools.cxx:701
 Tools.cxx:702
 Tools.cxx:703
 Tools.cxx:704
 Tools.cxx:705
 Tools.cxx:706
 Tools.cxx:707
 Tools.cxx:708
 Tools.cxx:709
 Tools.cxx:710
 Tools.cxx:711
 Tools.cxx:712
 Tools.cxx:713
 Tools.cxx:714
 Tools.cxx:715
 Tools.cxx:716
 Tools.cxx:717
 Tools.cxx:718
 Tools.cxx:719
 Tools.cxx:720
 Tools.cxx:721
 Tools.cxx:722
 Tools.cxx:723
 Tools.cxx:724
 Tools.cxx:725
 Tools.cxx:726
 Tools.cxx:727
 Tools.cxx:728
 Tools.cxx:729
 Tools.cxx:730
 Tools.cxx:731
 Tools.cxx:732
 Tools.cxx:733
 Tools.cxx:734
 Tools.cxx:735
 Tools.cxx:736
 Tools.cxx:737
 Tools.cxx:738
 Tools.cxx:739
 Tools.cxx:740
 Tools.cxx:741
 Tools.cxx:742
 Tools.cxx:743
 Tools.cxx:744
 Tools.cxx:745
 Tools.cxx:746
 Tools.cxx:747
 Tools.cxx:748
 Tools.cxx:749
 Tools.cxx:750
 Tools.cxx:751
 Tools.cxx:752
 Tools.cxx:753
 Tools.cxx:754
 Tools.cxx:755
 Tools.cxx:756
 Tools.cxx:757
 Tools.cxx:758
 Tools.cxx:759
 Tools.cxx:760
 Tools.cxx:761
 Tools.cxx:762
 Tools.cxx:763
 Tools.cxx:764
 Tools.cxx:765
 Tools.cxx:766
 Tools.cxx:767
 Tools.cxx:768
 Tools.cxx:769
 Tools.cxx:770
 Tools.cxx:771
 Tools.cxx:772
 Tools.cxx:773
 Tools.cxx:774
 Tools.cxx:775
 Tools.cxx:776
 Tools.cxx:777
 Tools.cxx:778
 Tools.cxx:779
 Tools.cxx:780
 Tools.cxx:781
 Tools.cxx:782
 Tools.cxx:783
 Tools.cxx:784
 Tools.cxx:785
 Tools.cxx:786
 Tools.cxx:787
 Tools.cxx:788
 Tools.cxx:789
 Tools.cxx:790
 Tools.cxx:791
 Tools.cxx:792
 Tools.cxx:793
 Tools.cxx:794
 Tools.cxx:795
 Tools.cxx:796
 Tools.cxx:797
 Tools.cxx:798
 Tools.cxx:799
 Tools.cxx:800
 Tools.cxx:801
 Tools.cxx:802
 Tools.cxx:803
 Tools.cxx:804
 Tools.cxx:805
 Tools.cxx:806
 Tools.cxx:807
 Tools.cxx:808
 Tools.cxx:809
 Tools.cxx:810
 Tools.cxx:811
 Tools.cxx:812
 Tools.cxx:813
 Tools.cxx:814
 Tools.cxx:815
 Tools.cxx:816
 Tools.cxx:817
 Tools.cxx:818
 Tools.cxx:819
 Tools.cxx:820
 Tools.cxx:821
 Tools.cxx:822
 Tools.cxx:823
 Tools.cxx:824
 Tools.cxx:825
 Tools.cxx:826
 Tools.cxx:827
 Tools.cxx:828
 Tools.cxx:829
 Tools.cxx:830
 Tools.cxx:831
 Tools.cxx:832
 Tools.cxx:833
 Tools.cxx:834
 Tools.cxx:835
 Tools.cxx:836
 Tools.cxx:837
 Tools.cxx:838
 Tools.cxx:839
 Tools.cxx:840
 Tools.cxx:841
 Tools.cxx:842
 Tools.cxx:843
 Tools.cxx:844
 Tools.cxx:845
 Tools.cxx:846
 Tools.cxx:847
 Tools.cxx:848
 Tools.cxx:849
 Tools.cxx:850
 Tools.cxx:851
 Tools.cxx:852
 Tools.cxx:853
 Tools.cxx:854
 Tools.cxx:855
 Tools.cxx:856
 Tools.cxx:857
 Tools.cxx:858
 Tools.cxx:859
 Tools.cxx:860
 Tools.cxx:861
 Tools.cxx:862
 Tools.cxx:863
 Tools.cxx:864
 Tools.cxx:865
 Tools.cxx:866
 Tools.cxx:867
 Tools.cxx:868
 Tools.cxx:869
 Tools.cxx:870
 Tools.cxx:871
 Tools.cxx:872
 Tools.cxx:873
 Tools.cxx:874
 Tools.cxx:875
 Tools.cxx:876
 Tools.cxx:877
 Tools.cxx:878
 Tools.cxx:879
 Tools.cxx:880
 Tools.cxx:881
 Tools.cxx:882
 Tools.cxx:883
 Tools.cxx:884
 Tools.cxx:885
 Tools.cxx:886
 Tools.cxx:887
 Tools.cxx:888
 Tools.cxx:889
 Tools.cxx:890
 Tools.cxx:891
 Tools.cxx:892
 Tools.cxx:893
 Tools.cxx:894
 Tools.cxx:895
 Tools.cxx:896
 Tools.cxx:897
 Tools.cxx:898
 Tools.cxx:899
 Tools.cxx:900
 Tools.cxx:901
 Tools.cxx:902
 Tools.cxx:903
 Tools.cxx:904
 Tools.cxx:905
 Tools.cxx:906
 Tools.cxx:907
 Tools.cxx:908
 Tools.cxx:909
 Tools.cxx:910
 Tools.cxx:911
 Tools.cxx:912
 Tools.cxx:913
 Tools.cxx:914
 Tools.cxx:915
 Tools.cxx:916
 Tools.cxx:917
 Tools.cxx:918
 Tools.cxx:919
 Tools.cxx:920
 Tools.cxx:921
 Tools.cxx:922
 Tools.cxx:923
 Tools.cxx:924
 Tools.cxx:925
 Tools.cxx:926
 Tools.cxx:927
 Tools.cxx:928
 Tools.cxx:929
 Tools.cxx:930
 Tools.cxx:931
 Tools.cxx:932
 Tools.cxx:933
 Tools.cxx:934
 Tools.cxx:935
 Tools.cxx:936
 Tools.cxx:937
 Tools.cxx:938
 Tools.cxx:939
 Tools.cxx:940
 Tools.cxx:941
 Tools.cxx:942
 Tools.cxx:943
 Tools.cxx:944
 Tools.cxx:945
 Tools.cxx:946
 Tools.cxx:947
 Tools.cxx:948
 Tools.cxx:949
 Tools.cxx:950
 Tools.cxx:951
 Tools.cxx:952
 Tools.cxx:953
 Tools.cxx:954
 Tools.cxx:955
 Tools.cxx:956
 Tools.cxx:957
 Tools.cxx:958
 Tools.cxx:959
 Tools.cxx:960
 Tools.cxx:961
 Tools.cxx:962
 Tools.cxx:963
 Tools.cxx:964
 Tools.cxx:965
 Tools.cxx:966
 Tools.cxx:967
 Tools.cxx:968
 Tools.cxx:969
 Tools.cxx:970
 Tools.cxx:971
 Tools.cxx:972
 Tools.cxx:973
 Tools.cxx:974
 Tools.cxx:975
 Tools.cxx:976
 Tools.cxx:977
 Tools.cxx:978
 Tools.cxx:979
 Tools.cxx:980
 Tools.cxx:981
 Tools.cxx:982
 Tools.cxx:983
 Tools.cxx:984
 Tools.cxx:985
 Tools.cxx:986
 Tools.cxx:987
 Tools.cxx:988
 Tools.cxx:989
 Tools.cxx:990
 Tools.cxx:991
 Tools.cxx:992
 Tools.cxx:993
 Tools.cxx:994
 Tools.cxx:995
 Tools.cxx:996
 Tools.cxx:997
 Tools.cxx:998
 Tools.cxx:999
 Tools.cxx:1000
 Tools.cxx:1001
 Tools.cxx:1002
 Tools.cxx:1003
 Tools.cxx:1004
 Tools.cxx:1005
 Tools.cxx:1006
 Tools.cxx:1007
 Tools.cxx:1008
 Tools.cxx:1009
 Tools.cxx:1010
 Tools.cxx:1011
 Tools.cxx:1012
 Tools.cxx:1013
 Tools.cxx:1014
 Tools.cxx:1015
 Tools.cxx:1016
 Tools.cxx:1017
 Tools.cxx:1018
 Tools.cxx:1019
 Tools.cxx:1020
 Tools.cxx:1021
 Tools.cxx:1022
 Tools.cxx:1023
 Tools.cxx:1024
 Tools.cxx:1025
 Tools.cxx:1026
 Tools.cxx:1027
 Tools.cxx:1028
 Tools.cxx:1029
 Tools.cxx:1030
 Tools.cxx:1031
 Tools.cxx:1032
 Tools.cxx:1033
 Tools.cxx:1034
 Tools.cxx:1035
 Tools.cxx:1036
 Tools.cxx:1037
 Tools.cxx:1038
 Tools.cxx:1039
 Tools.cxx:1040
 Tools.cxx:1041
 Tools.cxx:1042
 Tools.cxx:1043
 Tools.cxx:1044
 Tools.cxx:1045
 Tools.cxx:1046
 Tools.cxx:1047
 Tools.cxx:1048
 Tools.cxx:1049
 Tools.cxx:1050
 Tools.cxx:1051
 Tools.cxx:1052
 Tools.cxx:1053
 Tools.cxx:1054
 Tools.cxx:1055
 Tools.cxx:1056
 Tools.cxx:1057
 Tools.cxx:1058
 Tools.cxx:1059
 Tools.cxx:1060
 Tools.cxx:1061
 Tools.cxx:1062
 Tools.cxx:1063
 Tools.cxx:1064
 Tools.cxx:1065
 Tools.cxx:1066
 Tools.cxx:1067
 Tools.cxx:1068
 Tools.cxx:1069
 Tools.cxx:1070
 Tools.cxx:1071
 Tools.cxx:1072
 Tools.cxx:1073
 Tools.cxx:1074
 Tools.cxx:1075
 Tools.cxx:1076
 Tools.cxx:1077
 Tools.cxx:1078
 Tools.cxx:1079
 Tools.cxx:1080
 Tools.cxx:1081
 Tools.cxx:1082
 Tools.cxx:1083
 Tools.cxx:1084
 Tools.cxx:1085
 Tools.cxx:1086
 Tools.cxx:1087
 Tools.cxx:1088
 Tools.cxx:1089
 Tools.cxx:1090
 Tools.cxx:1091
 Tools.cxx:1092
 Tools.cxx:1093
 Tools.cxx:1094
 Tools.cxx:1095
 Tools.cxx:1096
 Tools.cxx:1097
 Tools.cxx:1098
 Tools.cxx:1099
 Tools.cxx:1100
 Tools.cxx:1101
 Tools.cxx:1102
 Tools.cxx:1103
 Tools.cxx:1104
 Tools.cxx:1105
 Tools.cxx:1106
 Tools.cxx:1107
 Tools.cxx:1108
 Tools.cxx:1109
 Tools.cxx:1110
 Tools.cxx:1111
 Tools.cxx:1112
 Tools.cxx:1113
 Tools.cxx:1114
 Tools.cxx:1115
 Tools.cxx:1116
 Tools.cxx:1117
 Tools.cxx:1118
 Tools.cxx:1119
 Tools.cxx:1120
 Tools.cxx:1121
 Tools.cxx:1122
 Tools.cxx:1123
 Tools.cxx:1124
 Tools.cxx:1125
 Tools.cxx:1126
 Tools.cxx:1127
 Tools.cxx:1128
 Tools.cxx:1129
 Tools.cxx:1130
 Tools.cxx:1131
 Tools.cxx:1132
 Tools.cxx:1133
 Tools.cxx:1134
 Tools.cxx:1135
 Tools.cxx:1136
 Tools.cxx:1137
 Tools.cxx:1138
 Tools.cxx:1139
 Tools.cxx:1140
 Tools.cxx:1141
 Tools.cxx:1142
 Tools.cxx:1143
 Tools.cxx:1144
 Tools.cxx:1145
 Tools.cxx:1146
 Tools.cxx:1147
 Tools.cxx:1148
 Tools.cxx:1149
 Tools.cxx:1150
 Tools.cxx:1151
 Tools.cxx:1152
 Tools.cxx:1153
 Tools.cxx:1154
 Tools.cxx:1155
 Tools.cxx:1156
 Tools.cxx:1157
 Tools.cxx:1158
 Tools.cxx:1159
 Tools.cxx:1160
 Tools.cxx:1161
 Tools.cxx:1162
 Tools.cxx:1163
 Tools.cxx:1164
 Tools.cxx:1165
 Tools.cxx:1166
 Tools.cxx:1167
 Tools.cxx:1168
 Tools.cxx:1169
 Tools.cxx:1170
 Tools.cxx:1171
 Tools.cxx:1172
 Tools.cxx:1173
 Tools.cxx:1174
 Tools.cxx:1175
 Tools.cxx:1176
 Tools.cxx:1177
 Tools.cxx:1178
 Tools.cxx:1179
 Tools.cxx:1180
 Tools.cxx:1181
 Tools.cxx:1182
 Tools.cxx:1183
 Tools.cxx:1184
 Tools.cxx:1185
 Tools.cxx:1186
 Tools.cxx:1187
 Tools.cxx:1188
 Tools.cxx:1189
 Tools.cxx:1190