// ============================================================================
/*!
//
//  \file TRegularExpression.hh
//  \brief This file contains the TRegularExpression class.
//  \author Go IWAI <goiwai@users.sourceforge.jp>
//
//  $Id: TRegularExpression.hh,v 1.5 2004/03/07 10:30:34 goiwai Exp $
//  $Name: CLDAQ-1-14-06 $
//  $Log: TRegularExpression.hh,v $
//  Revision 1.5  2004/03/07 10:30:34  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.4  2004/01/29 04:16:37  goiwai
//  GetSubMatches->GetSubMatch にして若干仕様変更
//  Splitをオーバーロード
//
//  Revision 1.3  2004/01/19 21:09:43  goiwai
//  プリプロセッサの接頭辞をCLDAQ__に変更しました.
//
//  Revision 1.2  2003/11/03 08:35:15  goiwai
//  Doxygen用のタグとコメントをうちこんでいく試みを開始しました.
//
//  Revision 1.1  2003/10/06 16:33:15  goiwai
//  UNIXの正規表現を扱うための部品です.速度よりも可読性を重視したので遅い
//  です.
//
*/
// ============================================================================
#ifndef CLDAQ__TREGULAREXPRESSION_HH
#define CLDAQ__TREGULAREXPRESSION_HH

#include "Tglobals.h"


/*!
// \example
//
// If example code exists.
//
*/

/*!
// \class TRegularExpression
// \brief This is the TRegularExpression class.
// \author Go IWAI <goiwai@users.sourceforge.jp>
//
// The TRegularExpression class detail description.
// Write it down ASAP!
//
// \todo None?
// \bug None?
// \ingroup SystemCategory
*/
class TRegularExpression
{

  public:
    // REG_EXTENDED
    // 拡張正規表現を使う
    // REG_ICASE
    // 英字の大文字,小文字の区別を無視する
    // REG_NOSUB
    // regexec()でパターンマッチの成功,失敗のみを返す
    // REG_NEWLINE
    // 改行文字の扱いを切り替える
    enum { DEFAULT = REG_EXTENDED|REG_NEWLINE, IOPTION = DEFAULT|REG_ICASE };

  private:
    Tstring thePattern;
    Tint theOption;
    Tint theNumberOfSubMatches;
    Tregex_t* theCompiledPattern;
    Tregmatch_t* theMatch;
    Tregmatch_t* theSubMatch;

  public:
    TRegularExpression( const Tstring& pattern, Tint option = DEFAULT );
    TRegularExpression( Tint option = DEFAULT, const Tstring& pattern = "" );
    TRegularExpression( const TRegularExpression& right );
    ~TRegularExpression();

  public:
    const TRegularExpression& operator=( const TRegularExpression& right );
    const TRegularExpression& operator=( const Tstring& right );
    Tbool operator==( const Tstring& right );
    Tbool operator!=( const Tstring& right );

  public:
    Tvoid Compile();
    Tint Index( const Tstring& source, Tint pos = 0 );
    TintList Indexes( const Tstring& source, Tint pos = 0 );
    Tint Size( const Tstring& source, Tint pos = 0 );
    TintList Sizes( const Tstring& source, Tint pos = 0 );
    Tstring MatchString( const Tstring& source, Tint pos = 0 );
    TstringList MatchStrings( const Tstring& source, Tint pos = 0 );
    Tbool IsMatch( const Tstring& source, Tint pos = 0 );
    Tint GetNumberOfMatches( const Tstring& source, Tint pos = 0 );
    Tstring Substitute( const Tstring& source, const Tstring& substr = "", Tint pos = 0 );
    Tstring SubstituteAll( const Tstring& source, const Tstring& substr = "", Tint pos = 0 );
    TstringList Split( const Tstring& source, Tint pos = 0 );
    TstringList Split( const Tstring& pattern, const Tstring& source, Tint pos = 0 );
    TstringList Split( const TRegularExpression& regex, const Tstring& source, Tint pos = 0 );
    Tstring GetSubMatch( Tint index, const Tstring& source, Tint pos = 0 );
    TstringList GetSubMatch( const Tstring& source, Tint pos = 0 );

  public:
    const Tstring& GetPattern() const;
    Tint GetOption() const;
    Tint GetNumberOfSubMatches() const;
    const Tregex_t* GetCompiledPattern() const;
    const Tregmatch_t* GetMatch() const;
    const Tregmatch_t* GetSubMatch() const;
    Tvoid SetPattern( const Tstring& pattern );
    Tvoid SetOption( Tint option = DEFAULT );
    Tvoid IgnoreCase( Tbool stat = Ttrue );

  private:
    Tvoid free();
    Tint execute( const Tstring& source, Tint pos );

#ifdef __CLDAQ_ROOT_DLL
    ClassDef(TRegularExpression,0)
#endif

};

inline const Tstring& TRegularExpression::GetPattern() const
{
  return thePattern;
}

inline Tint TRegularExpression::GetOption() const
{
  return theOption;
}

inline Tint TRegularExpression::GetNumberOfSubMatches() const
{
  return theNumberOfSubMatches;
}

inline const Tregex_t* TRegularExpression::GetCompiledPattern() const
{
  return theCompiledPattern;
}

inline const Tregmatch_t* TRegularExpression::GetMatch() const
{
  return theMatch;
}

inline const Tregmatch_t* TRegularExpression::GetSubMatch() const
{
  return theSubMatch;
}

inline Tvoid TRegularExpression::SetPattern( const Tstring& pattern )
{
  thePattern = pattern;
  Compile();
  return;
}

inline Tvoid TRegularExpression::SetOption( Tint option )
{
  theOption = option;
  Compile();
  return;
}

inline Tvoid TRegularExpression::IgnoreCase( Tbool stat )
{
  Tint option = theOption;
  if ( stat == Ttrue ) {
    option |= REG_ICASE;
  } else {
    option &= ~REG_ICASE;
  }
  SetOption( option );
  return;
}

#endif
