/** * Copyright (C) 2016 Charybdis Development Team * Copyright (C) 2016 Jason Volk * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #pragma once #define HAVE_IRCD_RFC1459_PARSE_H #ifdef __cplusplus #include BOOST_FUSION_ADAPT_STRUCT ( ircd::rfc1459::pfx, ( ircd::rfc1459::nick, nick ) ( ircd::rfc1459::user, user ) ( ircd::rfc1459::host, host ) ) BOOST_FUSION_ADAPT_STRUCT ( ircd::rfc1459::line, ( ircd::rfc1459::pfx, pfx ) ( ircd::rfc1459::cmd, cmd ) ( ircd::rfc1459::parv, parv ) ) namespace ircd { namespace rfc1459 { namespace parse { namespace qi = boost::spirit::qi; using qi::lit; using qi::char_; using qi::repeat; using qi::attr; using qi::eps; /* The grammar template class. * This aggregates all the rules under one template to make composing them easier. * * The grammar template is instantiated by individual parsers depending on the goal * for the specific parse, or the "top level." The first top-level was an IRC line, so * a class was created `struct head` specifying grammar::line as the top rule, and * rfc1459::line as the top output target to parse into. */ template struct grammar :qi::grammar { qi::rule space; qi::rule colon; qi::rule nulcrlf; qi::rule spnulcrlf; qi::rule terminator; qi::rule hostname; qi::rule user; qi::rule server; qi::rule nick; qi::rule prefix; qi::rule trailing; qi::rule middle; qi::rule params; qi::rule numeric; qi::rule command; qi::rule line; qi::rule tape; grammar(qi::rule &top_rule); }; template grammar::grammar(qi::rule &top_rule) :grammar::base_type { top_rule } ,space // A single space character { /* TODO: RFC says: * 1) is consists only of SPACE character(s) (0x20). * Specially notice that TABULATION, and all other control * characters are considered NON-WHITE-SPACE. * But our table in this namespace has control characters labeled as SPACE. * This needs to be fixed. */ //char_(charset(character::SPACE)) lit(' ') ,"space" } ,colon // A single colon character { lit(':') ,"colon" } ,nulcrlf // Match on NUL or CR or LF { lit('\0') | lit('\r') | lit('\n') ,"nulcrlf" } ,spnulcrlf // Match on space or nulcrlf { space | nulcrlf ,"spnulcrlf" } ,terminator // The message terminator { lit('\r') >> lit('\n') ,"terminator" } ,hostname // A valid hostname { +char_(charset(character::HOST)) // TODO: https://tools.ietf.org/html/rfc952 ,"hostname" } ,user // A valid username { +char_(charset(character::USER)) ,"user" } ,server // A valid servername { hostname ,"server" } ,nick // A valid nickname, leading letter followed by any NICK chars { char_(charset(character::ALPHA)) >> *char_(charset(character::NICK)) ,"nick" } ,prefix // A valid prefix, required name, optional user and host (or empty placeholders) { colon >> (nick | server) >> -(lit('!') >> user) >> -(lit('@') >> hostname) ,"prefix" } ,trailing // Trailing string pinch { colon >> +(char_ - nulcrlf) ,"trailing" } ,middle // Spaced parameters { !colon >> +(char_ - spnulcrlf) ,"middle" } ,params // Parameter vector { *(+space >> middle) >> -(+space >> trailing) ,"params" } ,numeric // \d\d\d numeric { repeat(3)[char_(charset(character::DIGIT))] ,"numeric" } ,command // A command or numeric { +char_(charset(character::ALPHA)) | numeric ,"command" } ,line { -(prefix >> +space) >> command >> params ,"line" } ,tape { +(-line >> +terminator) ,"tape" } { } } // namespace parse } // namespace rfc1459 } // namespace ircd #endif // __cplusplus