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.

294 lines
8.6 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: shwild/shwild.hpp
  3. *
  4. * Purpose: C++ root file for the shwild C-API
  5. *
  6. * Created: 17th June 2005
  7. * Updated: 19th December 2011
  8. *
  9. * Home: http://shwild.org/
  10. *
  11. * Copyright (c) 2005-2011, Matthew Wilson and Sean Kelly
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are
  16. * met:
  17. *
  18. * - Redistributions of source code must retain the above copyright notice,
  19. * this list of conditions and the following disclaimer.
  20. * - Redistributions in binary form must reproduce the above copyright
  21. * notice, this list of conditions and the following disclaimer in the
  22. * documentation and/or other materials provided with the distribution.
  23. * - Neither the names of Matthew Wilson and Sean Kelly nor the names of
  24. * any contributors may be used to endorse or promote products derived
  25. * from this software without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  28. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  29. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  30. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  31. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  32. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  33. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  34. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  35. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  36. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. * ////////////////////////////////////////////////////////////////////// */
  40. /** \file shwild/shwild.hpp [C++] C++ root file for the shwild C-API
  41. */
  42. #ifndef SHWILD_INCL_SHWILD_HPP_SHWILD
  43. #define SHWILD_INCL_SHWILD_HPP_SHWILD
  44. /* /////////////////////////////////////////////////////////////////////////
  45. * Version information
  46. */
  47. #ifndef SHWILD_DOCUMENTATION_SKIP_SECTION
  48. # define SHWILD_VER_SHWILD_HPP_SHWILD_MAJOR 1
  49. # define SHWILD_VER_SHWILD_HPP_SHWILD_MINOR 1
  50. # define SHWILD_VER_SHWILD_HPP_SHWILD_REVISION 4
  51. # define SHWILD_VER_SHWILD_HPP_SHWILD_EDIT 7
  52. #endif /* !SHWILD_DOCUMENTATION_SKIP_SECTION */
  53. /* /////////////////////////////////////////////////////////////////////////
  54. * Includes
  55. */
  56. #ifndef SHWILD_INCL_SHWILD_H_SHWILD
  57. # include <shwild/shwild.h>
  58. #endif /* !SHWILD_INCL_SHWILD_H_SHWILD */
  59. #include <stdexcept>
  60. /* /////////////////////////////////////////////////////////////////////////
  61. * Compiler warnings
  62. */
  63. #ifdef __BORLANDC__
  64. # pragma warn -8026 /* Suppresses "Functions with exception specifications are not expanded inline" */
  65. #endif /* compiler */
  66. /* /////////////////////////////////////////////////////////////////////////
  67. * Namespace
  68. */
  69. #if !defined(SHWILD_NO_NAMESPACE)
  70. namespace shwild
  71. {
  72. #endif /* !SHWILD_NO_NAMESPACE */
  73. /* /////////////////////////////////////////////////////////////////////////
  74. * Classes
  75. */
  76. // TODO: Flesh this out to be a full and complete exception class
  77. /// Exception thrown by the Pattern constructor
  78. /// \ingroup group__shwild_api__cpp_api
  79. class PatternException
  80. : public std::runtime_error
  81. {
  82. /// \name Member Types
  83. /// @{
  84. public:
  85. typedef std::runtime_error parent_class_type;
  86. typedef PatternException class_type;
  87. /// @}
  88. /// \name Construction
  89. /// @{
  90. public:
  91. /// Construct from the given message and error code
  92. PatternException(char const* message, int shwildErrorCode)
  93. : parent_class_type(message)
  94. , m_shwildErrorCode(shwildErrorCode)
  95. {}
  96. /// @}
  97. /// \name Accessors
  98. /// @{
  99. public:
  100. /// nul-terminated C-style string describing the exception
  101. virtual char const* what() const throw()
  102. {
  103. return "Pattern Exception";
  104. }
  105. /// The error code associated with the exception
  106. int errorCode() const throw()
  107. {
  108. return m_shwildErrorCode;
  109. }
  110. /// @}
  111. /// \name Members
  112. /// @{
  113. private:
  114. int m_shwildErrorCode;
  115. /// @}
  116. };
  117. /// Facade for the \ref group__shwild_api__c_api "shwild C API"
  118. /// \ingroup group__shwild_api__cpp_api
  119. class Pattern
  120. {
  121. public:
  122. /// Parses and precompiles the given pattern, according to the behaviour specified by the given flags
  123. ///
  124. /// \note If the parsing fails, an instance of PatternException is thrown
  125. explicit Pattern(char const* pattern, unsigned flags = 0);
  126. /// Parses and precompiles the given pattern, according to the behaviour specified by the given flags
  127. ///
  128. /// \note If the parsing fails, an instance of PatternException is thrown
  129. explicit Pattern(slice_t const* pattern, unsigned flags = 0);
  130. /// Parses and precompiles the given pattern, according to the behaviour specified by the given flags
  131. ///
  132. /// \note If the parsing fails, an instance of PatternException is thrown
  133. explicit Pattern(slice_t const& pattern, unsigned flags = 0);
  134. /// Releases any resources associated with the instance
  135. ~Pattern();
  136. public:
  137. /// Match the given string against the precompiled pattern maintained as member state
  138. bool match(char const* string) const;
  139. /// Match the given string against the precompiled pattern maintained as member state
  140. bool match(slice_t const* string) const;
  141. /// Match the given string against the precompiled pattern maintained as member state
  142. bool match(slice_t const& string) const;
  143. public:
  144. /** The number of potential matches (including the end marker) in
  145. * the compiled pattern.
  146. *
  147. * \note For compilation without exception support, this will be <0 if a
  148. * compilation error occurred
  149. */
  150. int numMatched() const
  151. {
  152. return m_numMatches;
  153. }
  154. private:
  155. static shwild_handle_t init_(char const* pattern, unsigned flags, int &numMatches);
  156. static shwild_handle_t init_(slice_t const* pattern, unsigned flags, int &numMatches);
  157. private:
  158. shwild_handle_t m_hCompiledPattern;
  159. int m_numMatches;
  160. private:
  161. Pattern(Pattern const&);
  162. Pattern &operator =(Pattern const&);
  163. };
  164. /* /////////////////////////////////////////////////////////////////////////
  165. * Implementation
  166. */
  167. #ifndef SHWILD_DOCUMENTATION_SKIP_SECTION
  168. inline /* static */ shwild_handle_t Pattern::init_(char const* pattern, unsigned flags, int &numMatches)
  169. {
  170. shwild_handle_t hCompiledPattern;
  171. numMatches = shwild_compile_pattern(pattern, flags, &hCompiledPattern);
  172. if(numMatches < 0)
  173. {
  174. hCompiledPattern = NULL;
  175. throw PatternException("Failed to compile pattern", numMatches);
  176. }
  177. return hCompiledPattern;
  178. }
  179. inline /* static */ shwild_handle_t Pattern::init_(slice_t const* pattern, unsigned flags, int &numMatches)
  180. {
  181. shwild_handle_t hCompiledPattern;
  182. numMatches = shwild_compile_pattern_s(pattern, flags, &hCompiledPattern);
  183. if(numMatches < 0)
  184. {
  185. hCompiledPattern = NULL;
  186. throw PatternException("Failed to compile pattern", numMatches);
  187. }
  188. return hCompiledPattern;
  189. }
  190. inline Pattern::Pattern(char const* pattern, unsigned flags)
  191. : m_hCompiledPattern(init_(pattern, flags, m_numMatches))
  192. {}
  193. inline Pattern::Pattern(slice_t const* pattern, unsigned flags)
  194. : m_hCompiledPattern(init_(pattern, flags, m_numMatches))
  195. {}
  196. inline Pattern::Pattern(slice_t const& pattern, unsigned flags)
  197. : m_hCompiledPattern(init_(&pattern, flags, m_numMatches))
  198. {}
  199. inline Pattern::~Pattern()
  200. {
  201. shwild_destroy_pattern(m_hCompiledPattern);
  202. }
  203. inline bool Pattern::match(char const* string) const
  204. {
  205. int r = shwild_match_pattern(m_hCompiledPattern, string);
  206. if(r < 0)
  207. {
  208. throw PatternException("Match failed", r);
  209. }
  210. return 0 == r;
  211. }
  212. inline bool Pattern::match(slice_t const* string) const
  213. {
  214. int r = shwild_match_pattern_s(m_hCompiledPattern, string);
  215. if(r < 0)
  216. {
  217. throw PatternException("Match failed", r);
  218. }
  219. return 0 == r;
  220. }
  221. inline bool Pattern::match(slice_t const& string) const
  222. {
  223. int r = shwild_match_pattern_s(m_hCompiledPattern, &string);
  224. if(r < 0)
  225. {
  226. throw PatternException("Match failed", r);
  227. }
  228. return 0 == r;
  229. }
  230. #endif /* !SHWILD_DOCUMENTATION_SKIP_SECTION */
  231. /* /////////////////////////////////////////////////////////////////////////
  232. * Namespace
  233. */
  234. #if !defined(SHWILD_NO_NAMESPACE)
  235. } // namespace shwild
  236. #endif /* !SHWILD_NO_NAMESPACE */
  237. /* ////////////////////////////////////////////////////////////////////// */
  238. #endif /* !SHWILD_INCL_SHWILD_HPP_SHWILD */
  239. /* ///////////////////////////// end of file //////////////////////////// */