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.

255 lines
6.7 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright The 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 <kicommon.h>
  30. #include <vector>
  31. #include <map>
  32. #include <memory>
  33. #include <wx/string.h>
  34. #include <wx/regex.h>
  35. static const int EDA_PATTERN_NOT_FOUND = wxNOT_FOUND;
  36. /**
  37. * A structure for storing weighted search terms.
  38. *
  39. * @note An exact match is scored at 8 * Score while a match at the start of the text is scored
  40. * at 2 * Score.
  41. */
  42. struct KICOMMON_API SEARCH_TERM
  43. {
  44. SEARCH_TERM( const wxString& aText, int aScore ) :
  45. Text( aText ),
  46. Score( aScore ),
  47. Normalized( false )
  48. {}
  49. wxString Text;
  50. int Score;
  51. bool Normalized;
  52. };
  53. /**
  54. * Interface for a pattern matcher for which there are several implementations.
  55. */
  56. class KICOMMON_API EDA_PATTERN_MATCH
  57. {
  58. public:
  59. struct FIND_RESULT
  60. {
  61. int start = EDA_PATTERN_NOT_FOUND;
  62. int length = 0;
  63. bool valid() const
  64. {
  65. return start != EDA_PATTERN_NOT_FOUND;
  66. }
  67. explicit operator bool() const
  68. {
  69. return valid();
  70. }
  71. };
  72. virtual ~EDA_PATTERN_MATCH() {}
  73. /**
  74. * Set the pattern against which candidates will be matched.
  75. *
  76. * @return false if the pattern not be processed.
  77. */
  78. virtual bool SetPattern( const wxString& aPattern ) = 0;
  79. /**
  80. * Return the pattern passed to SetPattern().
  81. */
  82. virtual wxString const& GetPattern() const = 0;
  83. /**
  84. * Return the location and possibly length of a match if a given candidate
  85. * string matches the set pattern.
  86. *
  87. * Otherwise, return an invalid #FIND_RESULT.
  88. */
  89. virtual FIND_RESULT Find( const wxString& aCandidate ) const = 0;
  90. };
  91. /**
  92. * Match simple substring.
  93. */
  94. class KICOMMON_API EDA_PATTERN_MATCH_SUBSTR : public EDA_PATTERN_MATCH
  95. {
  96. public:
  97. virtual bool SetPattern( const wxString& aPattern ) override;
  98. virtual wxString const& GetPattern() const override;
  99. virtual FIND_RESULT Find( const wxString& aCandidate ) const override;
  100. protected:
  101. wxString m_pattern;
  102. };
  103. /**
  104. * Match regular expression.
  105. */
  106. class KICOMMON_API EDA_PATTERN_MATCH_REGEX : public EDA_PATTERN_MATCH
  107. {
  108. public:
  109. virtual bool SetPattern( const wxString& aPattern ) override;
  110. virtual wxString const& GetPattern() const override;
  111. virtual FIND_RESULT Find( const wxString& aCandidate ) const override;
  112. protected:
  113. wxString m_pattern;
  114. wxRegEx m_regex;
  115. };
  116. class KICOMMON_API EDA_PATTERN_MATCH_REGEX_ANCHORED : public EDA_PATTERN_MATCH_REGEX
  117. {
  118. public:
  119. virtual bool SetPattern( const wxString& aPattern ) override;
  120. };
  121. class KICOMMON_API EDA_PATTERN_MATCH_WILDCARD : public EDA_PATTERN_MATCH_REGEX
  122. {
  123. public:
  124. virtual bool SetPattern( const wxString& aPattern ) override;
  125. virtual wxString const& GetPattern() const override;
  126. virtual FIND_RESULT Find( const wxString& aCandidate ) const override;
  127. protected:
  128. wxString m_wildcard_pattern;
  129. };
  130. class KICOMMON_API EDA_PATTERN_MATCH_WILDCARD_ANCHORED : public EDA_PATTERN_MATCH_WILDCARD
  131. {
  132. public:
  133. virtual bool SetPattern( const wxString& aPattern ) override;
  134. };
  135. /**
  136. * Relational match.
  137. *
  138. * Matches tokens of the format:
  139. *
  140. * key:value or key=value
  141. *
  142. * with search patterns of the format:
  143. *
  144. * key<value, key<=value, key=value, key>=value, key>value
  145. *
  146. * by parsing the value numerically and comparing.
  147. */
  148. class KICOMMON_API EDA_PATTERN_MATCH_RELATIONAL : public EDA_PATTERN_MATCH
  149. {
  150. public:
  151. virtual bool SetPattern( const wxString& aPattern ) override;
  152. virtual wxString const& GetPattern() const override;
  153. virtual FIND_RESULT Find( const wxString& aCandidate ) const override;
  154. int FindOne( const wxString& aCandidate ) const;
  155. protected:
  156. enum RELATION { LT, LE, EQ, GE, GT, ANY };
  157. wxString m_pattern;
  158. wxString m_key;
  159. RELATION m_relation;
  160. double m_value;
  161. static const std::map<wxString, double> m_units;
  162. };
  163. enum COMBINED_MATCHER_CONTEXT
  164. {
  165. CTX_LIBITEM,
  166. CTX_NET,
  167. CTX_NETCLASS,
  168. CTX_SIGNAL,
  169. CTX_SEARCH
  170. };
  171. class KICOMMON_API EDA_COMBINED_MATCHER
  172. {
  173. public:
  174. EDA_COMBINED_MATCHER( const wxString& aPattern, COMBINED_MATCHER_CONTEXT aContext );
  175. /**
  176. * Deleted copy or else we have to implement copy constructors for all EDA_PATTERN_MATCH classes
  177. * due to this class' m_matchers member being copied.
  178. */
  179. EDA_COMBINED_MATCHER( EDA_COMBINED_MATCHER const& ) = delete;
  180. /**
  181. * Deleted copy or else we have to implement copy constructors for all EDA_PATTERN_MATCH classes
  182. * due to this class' m_matchers member being copied
  183. */
  184. EDA_COMBINED_MATCHER& operator=( EDA_COMBINED_MATCHER const& ) = delete;
  185. /**
  186. * Look in all existing matchers, return the earliest match of any of the existing.
  187. *
  188. * @param aTerm term to look for.
  189. * @param aMatchersTriggered out: number of matcher that found the term.
  190. * @param aPostion out: where the term was found, or #EDA_PATTERN_NOT_FOUND.
  191. *
  192. * @return true if any matchers found the term
  193. */
  194. bool Find( const wxString& aTerm, int& aMatchersTriggered, int& aPosition );
  195. bool Find( const wxString& aTerm );
  196. bool StartsWith( const wxString& aTerm );
  197. const wxString& GetPattern() const;
  198. int ScoreTerms( std::vector<SEARCH_TERM>& aWeightedTerms );
  199. private:
  200. /// Add matcher if it can compile the pattern.
  201. void AddMatcher( const wxString& aPattern, std::unique_ptr<EDA_PATTERN_MATCH> aMatcher );
  202. std::vector<std::unique_ptr<EDA_PATTERN_MATCH>> m_matchers;
  203. wxString m_pattern;
  204. };
  205. #endif // EDA_PATTERN_MATCH_H