bool DescriptionParser::parse_description(const std::string& description, const std::vector<std::string>& valid_types) { // split by '&', but can be escaped with '\\&' std::regex rgx("[^\\\\]&"); std::sregex_token_iterator iter(description.begin(), description.end(), rgx, -1); for (; iter != std::sregex_token_iterator(); ++iter) { if (static_cast<std::string>(*iter).empty()) continue; if (!parse_branch(*iter, valid_types)) return false; } return true; }
template <typename Traits> inline void detector_impl<Traits>::parse(xmlDocPtr doc) { xmlNodePtr root = xmlDocGetRootElement(doc); if (0 == root) { throw error("got empty browser.xml"); } xml_elems elems(root, "branch"); for (xml_elems::iterator i = elems.begin(), end = elems.end(); i != end; ++i) { root_->add_child(parse_branch(*i)); } }
template <typename Traits> inline shared_ptr<typename detector_impl<Traits>::branch_type> detector_impl<Traits>::parse_branch(xmlNodePtr node) const { shared_ptr<branch_type> result(new branch_type()); for (xmlNodePtr n = xmlFirstElementChild(node); 0 != n; n = xmlNextElementSibling(n)) { if (disabled(n)) { continue; } else if (xmlStrncasecmp(n->name, (xmlChar const*) "match", sizeof("match")) == 0) { xml_elems elems(n, "pattern"); for (xml_elems::iterator i = elems.begin(), end = elems.end(); i != end; ++i) { if (disabled(*i)) { continue; } char const *type = xml_attr_text(*i, "type"); if (strncasecmp(type, "string", sizeof("string")) == 0) { result->add_match(xml_node_text(*i)); } else if (strncasecmp(type, "regex", sizeof("regex")) == 0) { result->add_regex_match(xml_node_text(*i)); } else { resource<xmlChar*, xml_string_traits> path(xmlGetNodePath(*i)); throw error("unknown pattern type %s in [%s]", type, (char const*) path.get()); } } } else if (xmlStrncasecmp(n->name, (xmlChar const*) "branch", sizeof("branch")) == 0) { result->add_child(parse_branch(n)); } else if (xmlStrncasecmp(n->name, (xmlChar const*) "define", sizeof("definition")) == 0) { result->add_definition(parse_definition(n)); } } return result; }