/* 
   Copyright 1994-2003 Free Software Foundation, Inc.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 
   USA

   You may contact the author at:

   mailto::camille@bluegrass.net

   or by snail mail at:

   David Lindauer
   850 Washburn Ave Apt 99
   Louisville, KY 40222
*/
#include <typeinfo>
#include <string.h>
#include <stdio.h>
#include "_rtti.h"

extern void _RTL_FUNC __undecorate(char *buf, char *name) ;
namespace std {

static void _internal_name(void *tpp, char *buf)
{
             char extend[64] ;
             CLASSXCEPT *s = (CLASSXCEPT *)tpp ;
             if (s->flags & XD_POINTER) {
               _internal_name(s->destructor,buf) ;
               strcat(buf," *") ;
             } else if (s->flags & XD_REF) {
               _internal_name(s->destructor,buf) ;
               strcat(buf," &") ;
             } else if (s->flags & XD_ARRAY) {
               _internal_name(s->destructor,buf) ;
               sprintf(extend," [%d]", *(int *)(s+1)) ;
               strcat(buf,extend) ;
             } else {
               __undecorate(buf,s->name) ;
             }

}
             _RTL_FUNC type_info::type_info(const type_info &in)
{
}
type_info &  _RTL_FUNC type_info::operator=(const type_info &in)
{
               return *this ;
}

             type_info::~type_info()
{
}

bool         _RTL_FUNC type_info::operator==(const type_info  &in) const
{
             if (this->tpp == in.tpp )
               return true ;
             CLASSXCEPT *s1 = (CLASSXCEPT *)this->tpp ;
             CLASSXCEPT *s2 = (CLASSXCEPT *)in.tpp ;
             if (s1->flags & s2->flags & XD_POINTER)
               if (s1->destructor == s2->destructor)
                  return true ;
             return false ;
}
bool         _RTL_FUNC type_info::operator!=(const type_info  &in) const
{
             return !(*this == in) ;
}

bool         _RTL_FUNC type_info::before(const type_info  &in) const
{
              char nbuf[256],nbuf2[256] ;
              _internal_name(this->tpp,nbuf) ;
              _internal_name(in.tpp,nbuf2) ;
              return( strcmp(nbuf,nbuf2) > 0) ;
}

const char * _RTL_FUNC type_info::name() const
{
			// using a rolling buffer so multiple name() references within
			// the same sequence point will result in valid operation
             static char nbuf[2048] ;
			 static int ofs = 0;
			 int oldoffs = ofs;
			 
             _internal_name(this->tpp,nbuf + ofs) ;
			 ofs += strlen(nbuf + ofs) + 1;
			 if (ofs >= sizeof(nbuf) - 200)
				 ofs = 0;
             return nbuf + oldoffs;
}

} ;
