Exheredludis/paludis/util/simple_parser.cc
Saleem Abdulrasool 64ba7d5be8 modernize: use default method synthesis
Convert a number of destructors to default synthesized functions.  Try to
inline a few instances into the header.  It should be possible to inline all of
them, however, gcc seems to emit a number of warnings.  Furthermore, some of the
destructors are pure-virtualed, but provide an implementation.  Placing the
definition into the header causes ODR violations.
2016-08-06 11:58:04 -07:00

297 lines
8.1 KiB
C++

/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Ciaran McCreesh
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
* Public License version 2, as published by the Free Software Foundation.
*
* Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <paludis/util/simple_parser.hh>
#include <paludis/util/pimp-impl.hh>
#include <strings.h>
using namespace paludis;
using namespace paludis::simple_parser;
SimpleParserExpression::SimpleParserExpression(const SimpleParserMatchFunction & f) :
_match(f)
{
}
std::string::size_type
SimpleParserExpression::match(const std::string & s, const std::string::size_type offset) const
{
return _match(s, offset);
}
namespace
{
std::string::size_type
m_and(const SimpleParserExpression & e1, const SimpleParserExpression & e2, const std::string & text,
const std::string::size_type offset)
{
if (offset >= text.length())
return std::string::npos;
std::string::size_type len_1(e1.match(text, offset));
if (std::string::npos == len_1)
return std::string::npos;
std::string::size_type len_2(e2.match(text, offset + len_1));
if (std::string::npos == len_2)
return std::string::npos;
return len_1 + len_2;
}
std::string::size_type
m_capture(const SimpleParserExpression & e1, std::string & var, const std::string & text,
const std::string::size_type offset)
{
std::string::size_type len_1(e1.match(text, offset));
if (std::string::npos != len_1)
var = text.substr(offset, len_1);
return len_1;
}
std::string::size_type
m_star(const SimpleParserExpression & e1, const std::string & text,
const std::string::size_type offset)
{
std::string::size_type new_offset(offset);
while (true)
{
std::string::size_type len_1(e1.match(text, new_offset));
if (std::string::npos == len_1 || 0 == len_1)
return new_offset - offset;
new_offset += len_1;
}
}
std::string::size_type
m_plus(const SimpleParserExpression & e1, const std::string & text,
const std::string::size_type offset)
{
bool any(false);
std::string::size_type new_offset(offset);
while (true)
{
std::string::size_type len_1(e1.match(text, new_offset));
if (std::string::npos == len_1)
return any ? new_offset - offset : std::string::npos;
else if (0 == len_1)
return new_offset - offset;
new_offset += len_1;
any = true;
}
}
std::string::size_type
m_minus(const SimpleParserExpression & e1, const std::string & text,
const std::string::size_type offset)
{
std::string::size_type len_1(e1.match(text, offset));
return std::string::npos == len_1 ? 0 : len_1;
}
int compare_ignoring_case(const std::string & text, const std::string::size_type offset, const std::string::size_type length,
const std::string & pattern)
{
return strncasecmp(text.c_str() + offset, pattern.c_str(), length);
}
std::string::size_type
m_exact(const std::string & pattern, const std::string & text,
const std::string::size_type offset, const bool ignore_case)
{
if (offset >= text.length())
return std::string::npos;
if (! ignore_case)
return (0 == text.compare(offset, pattern.length(), pattern)) ? pattern.length() : std::string::npos;
else
return (0 == compare_ignoring_case(text, offset, pattern.length(), pattern)) ? pattern.length() : std::string::npos;
}
std::string::size_type
m_any_of(const std::string & allowed, const std::string & text,
const std::string::size_type offset)
{
if (offset >= text.length())
return std::string::npos;
if (std::string::npos != allowed.find(text.at(offset)))
return 1;
else
return std::string::npos;
}
std::string::size_type
m_any_except(const std::string & not_allowed, const std::string & text,
const std::string::size_type offset)
{
if (offset >= text.length())
return std::string::npos;
if (std::string::npos != not_allowed.find(text.at(offset)))
return std::string::npos;
else
return 1;
}
}
SimpleParserExpression
paludis::simple_parser::operator& (const SimpleParserExpression & e1, const SimpleParserExpression & e2)
{
using namespace std::placeholders;
return SimpleParserExpression(std::bind(m_and, e1, e2, _1, _2));
}
SimpleParserExpression
paludis::simple_parser::operator>> (const SimpleParserExpression & e1, std::string & var)
{
using namespace std::placeholders;
return SimpleParserExpression(std::bind(m_capture, e1, std::ref(var), _1, _2));
}
SimpleParserExpression
paludis::simple_parser::operator* (const SimpleParserExpression & e1)
{
using namespace std::placeholders;
return SimpleParserExpression(std::bind(m_star, e1, _1, _2));
}
SimpleParserExpression
paludis::simple_parser::operator+ (const SimpleParserExpression & e1)
{
using namespace std::placeholders;
return SimpleParserExpression(std::bind(m_plus, e1, _1, _2));
}
SimpleParserExpression
paludis::simple_parser::operator- (const SimpleParserExpression & e1)
{
using namespace std::placeholders;
return SimpleParserExpression(std::bind(m_minus, e1, _1, _2));
}
SimpleParserExpression
paludis::simple_parser::exact(const std::string & s)
{
using namespace std::placeholders;
return SimpleParserExpression(std::bind(m_exact, s, _1, _2, false));
}
SimpleParserExpression
paludis::simple_parser::exact_ignoring_case(const std::string & s)
{
using namespace std::placeholders;
return SimpleParserExpression(std::bind(m_exact, s, _1, _2, true));
}
SimpleParserExpression
paludis::simple_parser::any_of(const std::string & s)
{
using namespace std::placeholders;
return SimpleParserExpression(std::bind(m_any_of, s, _1, _2));
}
SimpleParserExpression
paludis::simple_parser::any_except(const std::string & s)
{
using namespace std::placeholders;
return SimpleParserExpression(std::bind(m_any_except, s, _1, _2));
}
namespace paludis
{
template <>
struct Imp<SimpleParser>
{
std::string text;
std::string::size_type offset;
Imp(const std::string & t) :
text(t),
offset(0)
{
}
};
}
SimpleParser::SimpleParser(const std::string & s) :
_imp(s)
{
}
SimpleParser::~SimpleParser() = default;
bool
SimpleParser::consume(const SimpleParserExpression & e1)
{
std::string::size_type len_1(e1.match(_imp->text, _imp->offset));
if (std::string::npos == len_1)
return false;
else
{
_imp->offset += len_1;
return true;
}
}
bool
SimpleParser::lookahead(const SimpleParserExpression & e1) const
{
std::string::size_type len_1(e1.match(_imp->text, _imp->offset));
return std::string::npos != len_1;
}
bool
SimpleParser::eof() const
{
return _imp->offset == _imp->text.length();
}
std::string::size_type
SimpleParser::offset() const
{
return _imp->offset;
}
const std::string
SimpleParser::text() const
{
return _imp->text;
}
unsigned
SimpleParser::current_line_number() const
{
unsigned line_number(1);
for (std::string::size_type p(0) ; p < _imp->offset ; ++p)
if (_imp->text[p] == '\n')
++line_number;
return line_number;
}
namespace paludis
{
template class Pimp<SimpleParser>;
}