static CharT decode_octal (state &state_) { std::size_t accumulator_ = 0; CharT ch_ = *state_._curr; unsigned short count_ = 3; bool eos_ = false; for (;;) { accumulator_ *= 8; accumulator_ += ch_ - '0'; --count_; state_.increment (); eos_ = state_.eos (); if (!count_ || eos_) break; ch_ = *state_._curr; // Don't consume invalid chars! if (ch_ < '0' || ch_ > '7') { break; } } return static_cast<CharT> (accumulator_); }
static CharT decode_control_char (state &state_) { // Skip over 'c' state_.increment (); CharT ch_ = 0; bool eos_ = state_.next (ch_); if (eos_) { // Pointless returning index if at end of string throw runtime_error ("Unexpected end of regex following \\c."); } else { if (ch_ >= 'a' && ch_ <= 'z') { ch_ -= 'a' - 1; } else if (ch_ >= 'A' && ch_ <= 'Z') { ch_ -= 'A' - 1; } else if (ch_ == '@') { // Apparently... ch_ = 0; } else { std::ostringstream ss_; ss_ << "Invalid control char at index " << state_.index () - 1 << '.'; throw runtime_error (ss_.str ().c_str ()); } } return ch_; }
static CharT decode_hex (state &state_) { // Skip over 'x' state_.increment (); CharT ch_ = 0; bool eos_ = state_.next (ch_); if (eos_) { // Pointless returning index if at end of string throw runtime_error ("Unexpected end of regex following \\x."); } if (!((ch_ >= '0' && ch_ <= '9') || (ch_ >= 'a' && ch_ <= 'f') || (ch_ >= 'A' && ch_ <= 'F'))) { std::ostringstream ss_; ss_ << "Illegal char following \\x at index " << state_.index () - 1 << '.'; throw runtime_error (ss_.str ().c_str ()); } std::size_t hex_ = 0; do { hex_ *= 16; if (ch_ >= '0' && ch_ <= '9') { hex_ += ch_ - '0'; } else if (ch_ >= 'a' && ch_ <= 'f') { hex_ += 10 + (ch_ - 'a'); } else { hex_ += 10 + (ch_ - 'A'); } eos_ = state_.eos (); if (!eos_) { ch_ = *state_._curr; // Don't consume invalid chars! if (((ch_ >= '0' && ch_ <= '9') || (ch_ >= 'a' && ch_ <= 'f') || (ch_ >= 'A' && ch_ <= 'F'))) { state_.increment (); } else { eos_ = true; } } } while (!eos_); return static_cast<CharT> (hex_); }
static CharT chr (state &state_) { CharT ch_ = 0; // eos_ has already been checked for. switch (*state_._curr) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': ch_ = decode_octal (state_); break; case 'a': ch_ = '\a'; state_.increment (); break; case 'b': ch_ = '\b'; state_.increment (); break; case 'c': ch_ = decode_control_char (state_); break; case 'e': ch_ = 27; // '\e' not recognised by compiler state_.increment (); break; case 'f': ch_ = '\f'; state_.increment (); break; case 'n': ch_ = '\n'; state_.increment (); break; case 'r': ch_ = '\r'; state_.increment (); break; case 't': ch_ = '\t'; state_.increment (); break; case 'v': ch_ = '\v'; state_.increment (); break; case 'x': ch_ = decode_hex (state_); break; default: ch_ = *state_._curr; state_.increment (); break; } return ch_; }