#include "error.hpp" #include "charset.hpp" namespace Check { CharSet::CharSet(const char *line, const CharSetSyntax syntax) { switch (syntax) { case PlainText: { for (const char *symbol = line; *symbol != '\0'; ++symbol) insert(*symbol); } break; case ScanSet: { const bool reversed = (*line == '^' && *(line + 1) != '\0'); const char *symbol = line + reversed; while (*symbol != '\0') { if (*(symbol + 1) == '-' && *(symbol + 2) != '\0') { for (char chr = *symbol; chr <= *(symbol + 2); ++chr) insert(chr); symbol += 3; } else { insert(*symbol); ++symbol; } } if (reversed) inverse(); } break; default: { incite(UnhandledError, "Invalid character set syntax"); } break; } } CharSet::CharSet(const char fromChar, const char toChar) { for (char symbol = fromChar; symbol <= toChar; ++symbol) insert(symbol); } std::string CharSet::toString(const CharCategory category) const { std::string result(chars.count(), '\0'); int count = 0; const int length = chars.size(); for (int symbol = 0; symbol < length; ++symbol) if (contains(symbol) && (category == AnyChar || isprint(symbol))) { result[count] = static_cast(symbol); ++count; } return result; } int CharSet::indexIn(const char *line, const size_t length) const { for (size_t count = 0; count < length; ++count) { if (*line == '\0') return NotFound; if (contains(*line)) return count; ++line; } return NotFound; } int CharSet::lastIndexIn(const char *line, const size_t length) const { int result = NotFound; for (size_t count = 0; count < length; ++count) { if (*line == '\0') return result; if (contains(*line)) result = count; ++line; } return result; } int CharSet::indexIn( const std::string &line, const size_t offset, const size_t length) const { const size_t size = line.length(); size_t limit = offset + length; if (size < limit) limit = size; for (size_t count = offset; count < limit; ++count) if (contains(line[count])) return count; return NotFound; } int CharSet::lastIndexIn( const std::string &line, const size_t offset, const size_t length) const { const size_t size = line.length(); size_t limit = offset + length; if (size < limit) limit = size; while (offset < limit) { --limit; if (contains(line[limit])) return limit; } return NotFound; } const CharSet NoneChars; const CharSet AnyChars(~CharSet()); const CharSet NewLineChars("\r\n"); const CharSet BlankChars(" \t"); const CharSet SpaceChars(" \t\v\f\r\n"); const CharSet LetterChars("a-zA-Z", ScanSet); const CharSet DigitChars('0', '9'); }