// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- Mode: C++ -*- // // Copyright (C) 2016-2020 Red Hat, Inc. /// @file /// /// Some specialization for shared pointer utility templates. /// #include "config.h" #include #include #include "abg-internal.h" // ABG_BEGIN_EXPORT_DECLARATIONS #include "abg-regex.h" #include "abg-sptr-utils.h" ABG_END_EXPORT_DECLARATIONS // namespace abigail { /// Specialization of sptr_utils::build_sptr for regex_t. /// /// This is used to wrap a pointer to regex_t into a /// shared_ptr. /// /// @param p the bare pointer to regex_t to wrap into a shared_ptr. /// /// @return the shared_ptr that wraps @p p. template<> regex::regex_t_sptr sptr_utils::build_sptr(regex_t *p) {return regex::regex_t_sptr(p, regex::regex_t_deleter());} /// Specialization of sptr_utils::build_sptr for regex_t. /// /// This creates a pointer to regex_t and wraps it into a shared_ptr. /// /// @return the shared_ptr wrapping the newly created regex_t* template<> regex::regex_t_sptr sptr_utils::build_sptr() {return sptr_utils::build_sptr(new regex_t);} namespace regex { /// Escape regex special charaters in input string. /// /// @param os the output stream being written to. /// /// @param esc the regex_escape object holding a reference to the string /// needing to be escaped. /// /// @return the output stream. std::ostream& operator<<(std::ostream& os, const escape& esc) { // ']' and '}' are only conditionally special, so could be removed. static const std::string specials = "^.[]$()|*+?{}\\"; const std::string& str = esc.ref; for (std::string::const_iterator i = str.begin(); i != str.end(); ++i) { if (specials.find(*i) != std::string::npos) os << '\\'; os << *i; } return os; } /// Generate a regex pattern equivalent to testing set membership. /// /// A string will match the resulting pattern regex, if and only if it /// was present in the vector. /// /// @param strs a vector of strings /// /// @return a regex pattern std::string generate_from_strings(const std::vector& strs) { if (strs.empty()) // This cute-looking regex does not match any string. return "^_^"; std::ostringstream os; std::vector::const_iterator i = strs.begin(); os << "^(" << escape(*i++); while (i != strs.end()) os << "|" << escape(*i++); os << ")$"; return os.str(); } /// Compile a regex from a string. /// /// The result is held in a shared pointer. This will be null if regex /// compilation fails. /// /// @param str the string representation of the regex. /// /// @return shared pointer holder of a compiled regex object. regex_t_sptr compile(const std::string& str) { regex_t_sptr r = sptr_utils::build_sptr(new regex_t); if (regcomp(r.get(), str.c_str(), REG_EXTENDED)) r.reset(); return r; } /// See if a string matches a regex. /// /// @param r a shared pointer holder of a compiled regex object. /// /// @param str a string. /// /// @return whether there was a match. bool match(const regex_t_sptr& r, const std::string& str) { return !regexec(r.get(), str.c_str(), 0, NULL, 0); } }//end namespace regex }//end namespace abigail