// =====================================================================
//  $Id: TMacroFileParser.cc,v 1.6 2004/03/07 10:30:34 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: TMacroFileParser.cc,v $
//  Revision 1.6  2004/03/07 10:30:34  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.5  2003/10/06 16:38:26  goiwai
//  *** empty log message ***
//
//  Revision 1.4  2003/07/30 16:21:21  goiwai
//  ファイルにコミットログをつけることにしました.
//
// =====================================================================
#include "TMacroFileParser.hh"

TMacroFileParser::TMacroFileParser()
  : theMacroFileName(), theCommentStringList(), theMacroFileStream()
{
  theCommentStringList.clear();
  theCommentStringList.push_back( Tsharp );
  theCommentStringList.push_back( Twslash );
}

TMacroFileParser::TMacroFileParser( const Tstring& input )
  : theMacroFileName( input ), theCommentStringList(), theMacroFileStream()
{
  theCommentStringList.clear();
  theCommentStringList.push_back( Tsharp );
  theCommentStringList.push_back( Twslash );
  Open();
}

TMacroFileParser::TMacroFileParser( const Tstring& input, const TstringList& comment )
  : theMacroFileName( input ), theCommentStringList( comment ),
    theMacroFileStream()
{
  Open();
}

TMacroFileParser::TMacroFileParser( const TMacroFileParser& right )
  : theMacroFileName( right.theMacroFileName ),
    theCommentStringList( right.theCommentStringList )
{
  Open();
}

TMacroFileParser::~TMacroFileParser()
{
  Close();
}

Tvoid TMacroFileParser::Open()
{
  if ( IsOpen() ) {
    Close();
  }
  if ( !theMacroFileName.empty() ) {
    theMacroFileStream.open( theMacroFileName.c_str() );
    checkFileStream();
  }
  return;
}

Tvoid TMacroFileParser::Open( const Tstring& filename )
{
  theMacroFileName = filename;
  Open();
  return;
}

Tbool TMacroFileParser::IsOpen()
{
  if ( theMacroFileStream.is_open() == Ttrue ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

Tbool TMacroFileParser::IsFail() const
{
  if ( theMacroFileStream.fail() == Ttrue ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

Tbool TMacroFileParser::IsGood() const
{
  if ( theMacroFileStream.good() == Ttrue ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

Tbool TMacroFileParser::IsEndOfFile() const
{
  if ( theMacroFileStream.eof() == Ttrue ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

Tbool TMacroFileParser::IsSuccess()
{
  if ( IsOpen() && !IsFail() && !IsEndOfFile() ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

Tbool TMacroFileParser::IsExecutable( const TstringList& readbuf ) const
{
  if ( readbuf.empty() ) {
    return Tfalse;
  } else {
    return Ttrue;
  }
}

Tvoid TMacroFileParser::Close()
{
  if ( IsOpen() ) {
    theMacroFileStream.close();
  }
  return;
}

TstringList TMacroFileParser::ReadLine()
{
  static const Tsize_t bufflen = 1024;
  static Tchar linebuf[ bufflen ];

  TstringList listbuf;
  listbuf.clear();
  Tstring strbuf;
  theMacroFileStream.getline( linebuf, bufflen );
  strbuf = linebuf;
  if ( !( strbuf.empty() ) ) {
    eraseComment( strbuf );
  }
  listbuf = divideLine( strbuf );

  return listbuf;
}

Tstring TMacroFileParser::GetCommand( const TstringList& readbuf ) const
{
  Tstring command;
  if ( !readbuf.empty() ) {
    command = readbuf[ 0 ];
  }
  return command;
}

TstringList TMacroFileParser::GetArguments( const TstringList& readbuf ) const
{
  TstringList arguments = readbuf;

  if ( arguments.size() > 0 ) {
    arguments.erase( arguments.begin() );
  } else {
    arguments.clear();
  }

  return arguments;
}

Tvoid TMacroFileParser::checkFileStream()
{
  if ( !( IsGood() ) || !( IsOpen() ) ) {
    Tstring head = "TMacroFileParser::checkFileStream: ";
    Tcerr << head << "fail to open a file " << theMacroFileName << Tendl;
  }
  return;
}

const Tstring& TMacroFileParser::eraseComment( Tstring& readline ) const
{
  for ( Tsize_t i = 0; i < theCommentStringList.size(); i ++ ) {
    Tsize_t pos = readline.find( theCommentStringList[ i ] );
    Tsize_t bufsize = readline.size();
    if ( pos >= 0 && pos <= bufsize - theCommentStringList[ i ].size() ) {
      readline.erase( pos, bufsize - pos );
    }
  }

  while ( !( readline.empty() ) && readline.rfind( Tspace ) == readline.size() - 1 ) {
    readline.erase( readline.end() - 1 );
  }

  while ( !( readline.empty() ) && readline.find( Tspace ) == 0 ) {
    readline.erase( readline.begin() );
  }

  return readline;
}

TstringList TMacroFileParser::divideLine( Tstring& readline ) const
{
  Tsize_t begin = 0;
  Tsize_t end = 0;
  Tstring strbuf;
  TstringList listbuf;
  listbuf.clear();

  if ( !( readline.empty() ) ) {
    Tsize_t lastpos = readline.rfind( Tspace ) + 1;
    do {
      begin = readline.find_first_not_of( Tspace, end );
      end = readline.find( Tspace, begin );
      if ( end > readline.size() ) {
	end = readline.size();
      }
      strbuf = readline.substr( begin, end - begin );
      listbuf.push_back( strbuf );
    } while ( begin != lastpos );
  }

  return listbuf;
}

#ifdef __CLDAQ_ROOT_DLL
    ClassImp(TMacroFileParser)
#endif
