// File:       piscmd02.c++
// Version:    1.00
// Author:     (c) Miles Sabin, 1997
// Purpose:    bool extraction command

// Change log:
//  27/03/97   v. 1.00

#include "piscmds.h"

#include "istream.h"
#include "streambuf.h"


// Implementation of ExtractBoolCommand

ExtractBoolCommand::ExtractBoolCommand(basic_istream_char& is)
  : ExtractIntegralCommand(is, false, true)
  { execute_template(is); }

ExtractBoolCommand::~ExtractBoolCommand()
  {}

ios::iostate ExtractBoolCommand::execute(basic_istream_char& is)
  {
    ios::iostate state = ios::goodbit;

    if((is.flags()&ios::boolalpha) == 0)
    {
      state |= ExtractIntegralCommand::execute(is);
      if(state == ios::goodbit)
      {
        long n = as_signed();
        if(n != 0 && n != 1)
          state |= ios::failbit;
      }
    }
    else
    {
      basic_streambuf_char* sb = is.rdbuf();

      int c = sb->sgetc();
      if(c != 't' && c != 'f')
        state |= ios::failbit;
      else
      {
        bool result = (c =='t');
        char const* name = (result ? "rue" : "alse");
        while(*name != 0 && (c = sb->snextc()) == *name++);

        if(*name != 0)
          state |= ios::failbit;
        else
        {
          n_ = result;
          neg_ = false;
        }
      }

      if(c == basic_istream_char::traits::eof())
        state |= ios::eofbit;
    }

    return state;
  }


// Implementation of basic_istream_char

#ifdef BUILTIN_BOOL

basic_istream_char& basic_istream_char::operator>>(bool& n)
  {
    ExtractBoolCommand cmd(*this);
    if(!fail())
      n = cmd.as_bool();
    return *this;
  }

#endif
