11#include <boost/spirit/include/qi.hpp>
12#include <boost/fusion/adapted.hpp>
13#include <boost/phoenix.hpp>
19 using FieldVal_t = boost::variant<std::string, std::vector<std::string>>;
20 using Lang_t = std::optional<std::string>;
43BOOST_FUSION_ADAPT_STRUCT (LC::Util::XDG::Field,
48BOOST_FUSION_ADAPT_STRUCT (LC::Util::XDG::Group,
52BOOST_FUSION_ADAPT_STRUCT (LC::Util::XDG::File,
59 namespace qi = boost::spirit::qi;
60 namespace phoenix = boost::phoenix;
62 template<
typename Iter>
63 struct Parser : qi::grammar<Iter, File ()>
65 qi::rule<Iter, File ()> Start_;
66 qi::rule<Iter, Group ()> Group_;
67 qi::rule<Iter, std::string ()> GroupName_;
68 qi::rule<Iter, std::string ()>
Lang_;
69 qi::rule<Iter, void ()> KeyValSep_;
70 qi::rule<Iter, std::string ()> LineValSingle_;
71 qi::rule<Iter, FieldVal_t ()> LineVal_;
72 qi::rule<Iter, Field ()> Line_;
73 qi::rule<Iter, void ()> Comment_;
76 : Parser::base_type (Start_)
78 auto eol = qi::lit (
"\n");
79 Comment_ %= qi::lit (
"#") >> *(qi::char_ -
'\r' -
'\n') >> eol;
81 Lang_ %=
'[' >> qi::lexeme [+(qi::char_ (
"a-zA-Z0-9@_-"))] >>
']';
83 KeyValSep_ %= *(qi::lit (
' ')) >>
'=' >> *(qi::lit (
' '));
85 LineValSingle_ %= qi::lexeme [+((qi::lit (
"\\;") | (qi::char_ -
';' -
'\r' -
'\n')))];
86 LineVal_ %= ((LineValSingle_ %
';') >> -qi::lit (
";")) | LineValSingle_;
88 Line_ %= qi::lexeme [+(qi::char_ (
"a-zA-Z0-9-"))] >>
94 GroupName_ %=
'[' >> qi::lexeme [+(qi::char_ (
"a-zA-Z0-9 "))] >>
']';
96 Group_ %= GroupName_ >> eol >>
97 *(Comment_ | Line_ | eol);
99 Start_ %= *eol >> *Comment_ >> +Group_;
101 qi::on_error<qi::fail> (Start_,
102 std::cout << phoenix::val (
"Error! Expecting") << qi::_4
103 << phoenix::val (
" here: \"") << phoenix::construct<std::string> (qi::_3, qi::_2)
104 << phoenix::val (
"\"") << std::endl);
108 template<
typename Iter>
118 return QString::fromUtf8 (
str.c_str ());
121 struct ValGetter :
public boost::static_visitor<QStringList>
123 QStringList operator() (
const std::string& str)
const
125 return QStringList (ToUtf8 (str));
128 QStringList operator() (
const std::vector<std::string>& vec)
const
131 std::transform (vec.begin (), vec.end (), std::back_inserter (result), ToUtf8);
139 const auto&
file =
Parse (data.begin (), data.end ());
UTIL_XDG_API Result_t operator()(const QByteArray &data)
Parses the XDG data.
Container< T > Filter(const Container< T > &c, F f)