You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
5.5 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. /**
  24. * @file eda_pattern_match.h
  25. * @brief Abstract pattern-matching tool and implementations.
  26. */
  27. #ifndef EDA_PATTERN_MATCH_H
  28. #define EDA_PATTERN_MATCH_H
  29. #include <vector>
  30. #include <map>
  31. #include <memory>
  32. #include <wx/string.h>
  33. #include <wx/regex.h>
  34. static const int EDA_PATTERN_NOT_FOUND = wxNOT_FOUND;
  35. /*
  36. * Interface for a pattern matcher, for which there are several implementations
  37. */
  38. class EDA_PATTERN_MATCH
  39. {
  40. public:
  41. struct FIND_RESULT
  42. {
  43. int start = EDA_PATTERN_NOT_FOUND;
  44. int length = 0;
  45. bool valid() const
  46. {
  47. return start != EDA_PATTERN_NOT_FOUND;
  48. }
  49. explicit operator bool() const
  50. {
  51. return valid();
  52. }
  53. };
  54. virtual ~EDA_PATTERN_MATCH() {}
  55. /**
  56. * Set the pattern against which candidates will be matched. If the pattern
  57. * can not be processed, returns false.
  58. */
  59. virtual bool SetPattern( const wxString& aPattern ) = 0;
  60. /**
  61. * Return the pattern passed to SetPattern().
  62. */
  63. virtual wxString const& GetPattern() const = 0;
  64. /**
  65. * Return the location and possibly length of a match iff a given candidate
  66. * string matches the set pattern.
  67. * Otherwise, return an invalid FIND_RESULT.
  68. */
  69. virtual FIND_RESULT Find( const wxString& aCandidate ) const = 0;
  70. };
  71. /*
  72. * Match simple substring
  73. */
  74. class EDA_PATTERN_MATCH_SUBSTR : public EDA_PATTERN_MATCH
  75. {
  76. public:
  77. virtual bool SetPattern( const wxString& aPattern ) override;
  78. virtual wxString const& GetPattern() const override;
  79. virtual FIND_RESULT Find( const wxString& aCandidate ) const override;
  80. protected:
  81. wxString m_pattern;
  82. };
  83. /*
  84. * Match regular expression
  85. */
  86. class EDA_PATTERN_MATCH_REGEX : public EDA_PATTERN_MATCH
  87. {
  88. public:
  89. virtual bool SetPattern( const wxString& aPattern ) override;
  90. virtual wxString const& GetPattern() const override;
  91. virtual FIND_RESULT Find( const wxString& aCandidate ) const override;
  92. protected:
  93. wxString m_pattern;
  94. wxRegEx m_regex;
  95. };
  96. class EDA_PATTERN_MATCH_REGEX_EXPLICIT : public EDA_PATTERN_MATCH_REGEX
  97. {
  98. public:
  99. virtual bool SetPattern( const wxString& aPattern ) override;
  100. };
  101. class EDA_PATTERN_MATCH_WILDCARD : public EDA_PATTERN_MATCH_REGEX
  102. {
  103. public:
  104. virtual bool SetPattern( const wxString& aPattern ) override;
  105. virtual wxString const& GetPattern() const override;
  106. virtual FIND_RESULT Find( const wxString& aCandidate ) const override;
  107. protected:
  108. wxString m_wildcard_pattern;
  109. };
  110. class EDA_PATTERN_MATCH_WILDCARD_EXPLICIT : public EDA_PATTERN_MATCH_WILDCARD
  111. {
  112. public:
  113. virtual bool SetPattern( const wxString& aPattern ) override;
  114. };
  115. /**
  116. * Relational match.
  117. *
  118. * Matches tokens of the format:
  119. *
  120. * key:value or key=value
  121. *
  122. * with search patterns of the format:
  123. *
  124. * key<value, key<=value, key=value, key>=value, key>value
  125. *
  126. * by parsing the value numerically and comparing.
  127. */
  128. class EDA_PATTERN_MATCH_RELATIONAL : public EDA_PATTERN_MATCH
  129. {
  130. public:
  131. virtual bool SetPattern( const wxString& aPattern ) override;
  132. virtual wxString const& GetPattern() const override;
  133. virtual FIND_RESULT Find( const wxString& aCandidate ) const override;
  134. int FindOne( const wxString& aCandidate ) const;
  135. protected:
  136. enum RELATION { LT, LE, EQ, GE, GT, ANY };
  137. wxString m_pattern;
  138. wxString m_key;
  139. RELATION m_relation;
  140. double m_value;
  141. static wxRegEx m_regex_description;
  142. static wxRegEx m_regex_search;
  143. static const std::map<wxString, double> m_units;
  144. };
  145. enum COMBINED_MATCHER_CONTEXT
  146. {
  147. CTX_LIBITEM,
  148. CTX_NETCLASS
  149. };
  150. class EDA_COMBINED_MATCHER
  151. {
  152. public:
  153. EDA_COMBINED_MATCHER( const wxString& aPattern, COMBINED_MATCHER_CONTEXT aContext );
  154. /*
  155. * Look in all existing matchers, return the earliest match of any of
  156. * the existing.
  157. *
  158. * @param aTerm term to look for
  159. * @param aMatchersTriggered out: number of matcher that found the term
  160. * @param aPostion out: where the term was found, or EDA_PATTERN_NOT_FOUND
  161. *
  162. * @return true if any matchers found the term
  163. */
  164. bool Find( const wxString& aTerm, int& aMatchersTriggered, int& aPosition );
  165. const wxString& GetPattern() const;
  166. private:
  167. // Add matcher if it can compile the pattern.
  168. void AddMatcher( const wxString& aPattern, std::unique_ptr<EDA_PATTERN_MATCH> aMatcher );
  169. std::vector<std::unique_ptr<EDA_PATTERN_MATCH>> m_matchers;
  170. wxString m_pattern;
  171. };
  172. #endif // EDA_PATTERN_MATCH_H