1+ //
2+ // Licensed under the Apache License v2.0 with LLVM Exceptions.
3+ // See https://llvm.org/LICENSE.txt for license information.
4+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+ //
6+ // Copyright (c) 2024 Alan de Freitas (alandefreitas@gmail.com)
7+ //
8+ // Official repository: https://github.com/cppalliance/mrdocs
9+ //
10+
11+ #ifndef MRDOCS_API_SUPPORT_GLOBPATTERN_HPP
12+ #define MRDOCS_API_SUPPORT_GLOBPATTERN_HPP
13+
14+ #include < mrdocs/Support/Error.hpp>
15+ #include < memory>
16+ #include < optional>
17+ #include < string_view>
18+
19+ namespace clang ::mrdocs {
20+
21+ /* * A glob pattern matcher
22+
23+ @li "*" matches all characters except delimiters.
24+ @li "**" matches all characters
25+ @li "?" matches any single character.
26+ @li "[<chars>]" matches one character in the bracket.
27+ @li "[<char>-<char>]" matches one character in the bracket range.
28+ @li "[^<chars>]" or "[!<chars>]" matches one character not in the bracket.
29+ @li "{<glob>,...}" matches one of the globs in the list.
30+ @li "\" escapes the next character so it is treated as a literal.
31+
32+ Nested brace expansions "{<glob>,"{<glob>,...}",...}" are not supported.
33+ */
34+ class GlobPattern {
35+ struct Impl ;
36+ std::unique_ptr<Impl> impl_;
37+ public:
38+ /* * Constructs a GlobPattern with the given pattern.
39+
40+ @param pattern The glob pattern to use for matching.
41+ */
42+ static
43+ Expected<GlobPattern>
44+ create (std::string_view pattern, std::optional<std::size_t > maxSubGlobs);
45+
46+ static
47+ Expected<GlobPattern>
48+ create (std::string_view pattern)
49+ {
50+ return create (pattern, std::nullopt );
51+ }
52+
53+ /* * Destructor */
54+ ~GlobPattern ();
55+
56+ /* * Construct an empty GlobPattern.
57+
58+ An empty GlobPattern will never match any string.
59+ */
60+ GlobPattern ();
61+
62+ /* * Copy constructor */
63+ GlobPattern (GlobPattern const & other);
64+
65+ /* * Move constructor */
66+ GlobPattern (GlobPattern&& other) noexcept ;
67+
68+ /* * Copy assignment */
69+ GlobPattern&
70+ operator =(GlobPattern const & other);
71+
72+ /* * Move assignment */
73+ GlobPattern&
74+ operator =(GlobPattern&& other) noexcept ;
75+
76+ /* * Matches the given string against the glob pattern.
77+
78+ @param str The string to match against the pattern.
79+ @return true if the string matches the pattern, false otherwise.
80+ */
81+ bool
82+ match (std::string_view str, char delimiter) const ;
83+
84+ /* * Matches the start of a given string against the glob pattern.
85+
86+ This function determines if the given string with
87+ the specified `prefix` can potentially match
88+ the glob pattern.
89+
90+ If the string matches the start of the pattern without failure, even
91+ if there are characters left in the string or the pattern, the
92+ function returns true.
93+
94+ @param prefix The string to match against the pattern.
95+ @return true if the string prefix matches the pattern, false otherwise.
96+ */
97+ bool
98+ matchPatternPrefix (std::string_view prefix, char delimiter) const ;
99+
100+ /* * Returns the glob pattern.
101+
102+ @return The glob pattern as a string view.
103+ */
104+ std::string_view
105+ pattern () const ;
106+ };
107+
108+ /* * A glob pattern matcher for paths
109+
110+ A glob pattern matcher where "*" does not match path separators.
111+ The pattern "**" can be used to match any number of path separators.
112+ */
113+ class PathGlobPattern {
114+ GlobPattern glob_;
115+ public:
116+ /* * Constructs a PathGlobPattern with the given pattern.
117+
118+ @param pattern The glob pattern to use for matching.
119+ @param maxSubGlobs The maximum number of subpatterns allowed.
120+ */
121+ static
122+ Expected<PathGlobPattern>
123+ create (
124+ std::string_view const pattern,
125+ std::optional<std::size_t > maxSubGlobs)
126+ {
127+ MRDOCS_TRY (auto glob, GlobPattern::create (pattern, maxSubGlobs));
128+ return PathGlobPattern{std::move (glob)};
129+ }
130+
131+ /* * Constructs a PathGlobPattern with the given pattern.
132+
133+ @param pattern The glob pattern to use for matching.
134+ */
135+ static
136+ Expected<PathGlobPattern>
137+ create (std::string_view const pattern)
138+ {
139+ MRDOCS_TRY (auto glob, GlobPattern::create (pattern));
140+ return PathGlobPattern{std::move (glob)};
141+ }
142+
143+ /* * Construct an empty PathGlobPattern.
144+
145+ An empty PathGlobPattern will never match any string.
146+ */
147+ PathGlobPattern () = default ;
148+
149+ /* * Construct an empty PathGlobPattern.
150+
151+ An empty PathGlobPattern will never match any string.
152+ */
153+ explicit
154+ PathGlobPattern (GlobPattern glob)
155+ : glob_{std::move (glob)}
156+ {};
157+
158+ /* * Matches the given string against the glob pattern.
159+
160+ @param str The string to match against the pattern.
161+ @return true if the string matches the pattern, false otherwise.
162+ */
163+ bool
164+ match (std::string_view const str) const
165+ {
166+ return glob_.match (str, ' /' );
167+ }
168+
169+ /* * Matches the start of a given string against the glob pattern.
170+
171+ This function determines if the given string with
172+ the specified `prefix` can potentially match
173+ the glob pattern.
174+
175+ If the string matches the start of the pattern without failure, even
176+ if there are characters left in the string or the pattern, the
177+ function returns true.
178+
179+ @param prefix The string to match against the pattern.
180+ @return true if the string prefix matches the pattern, false otherwise.
181+ */
182+ bool
183+ matchPatternPrefix (std::string_view prefix) const
184+ {
185+ return glob_.matchPatternPrefix (prefix, ' /' );
186+ }
187+
188+ /* * Returns the glob pattern.
189+
190+ @return The glob pattern as a string view.
191+ */
192+ std::string_view
193+ pattern () const
194+ {
195+ return glob_.pattern ();
196+ }
197+ };
198+
199+ /* * A glob pattern matcher for C++ symbols
200+
201+ A glob pattern matcher where "*" does not match "::".
202+ The pattern "**" can be used to match any number of "::".
203+ */
204+ class SymbolGlobPattern {
205+ GlobPattern glob_;
206+ public:
207+ /* * Constructs a SymbolGlobPattern with the given pattern.
208+
209+ @param pattern The glob pattern to use for matching.
210+ @param maxSubGlobs The maximum number of subpatterns allowed.
211+ */
212+ static
213+ Expected<SymbolGlobPattern>
214+ create (
215+ std::string_view const pattern,
216+ std::optional<std::size_t > maxSubGlobs)
217+ {
218+ MRDOCS_TRY (auto glob, GlobPattern::create (pattern, maxSubGlobs));
219+ return SymbolGlobPattern{std::move (glob)};
220+ }
221+
222+ /* * Constructs a SymbolGlobPattern with the given pattern.
223+
224+ @param pattern The glob pattern to use for matching.
225+ */
226+ static
227+ Expected<SymbolGlobPattern>
228+ create (std::string_view const pattern)
229+ {
230+ MRDOCS_TRY (auto glob, GlobPattern::create (pattern));
231+ return SymbolGlobPattern{std::move (glob)};
232+ }
233+
234+ /* * Construct an empty SymbolGlobPattern.
235+
236+ An empty SymbolGlobPattern will never match any string.
237+ */
238+ SymbolGlobPattern () = default ;
239+
240+ /* * Construct an empty SymbolGlobPattern.
241+
242+ An empty SymbolGlobPattern will never match any string.
243+ */
244+ explicit
245+ SymbolGlobPattern (GlobPattern glob)
246+ : glob_{std::move (glob)}
247+ {};
248+
249+ /* * Matches the given string against the glob pattern.
250+
251+ @param str The string to match against the pattern.
252+ @return true if the string matches the pattern, false otherwise.
253+ */
254+ bool
255+ match (std::string_view const str) const
256+ {
257+ return glob_.match (str, ' :' );
258+ }
259+
260+ /* * Matches the start of a given string against the glob pattern.
261+
262+ This function determines if the given string with
263+ the specified `prefix` can potentially match
264+ the glob pattern.
265+
266+ If the string matches the start of the pattern without failure, even
267+ if there are characters left in the string or the pattern, the
268+ function returns true.
269+
270+ @param prefix The string to match against the pattern.
271+ @return true if the string prefix matches the pattern, false otherwise.
272+ */
273+ bool
274+ matchPatternPrefix (std::string_view prefix) const
275+ {
276+ return glob_.matchPatternPrefix (prefix, ' :' );
277+ }
278+
279+ /* * Returns the glob pattern.
280+
281+ @return The glob pattern as a string view.
282+ */
283+ std::string_view
284+ pattern () const
285+ {
286+ return glob_.pattern ();
287+ }
288+ };
289+
290+ } // clang::mrdocs
291+
292+ #endif // MRDOCS_API_SUPPORT_GLOBPATTERN_HPP
0 commit comments