1/* Copyright (C) 2007 The glibmm Development Team
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <glibmm/utility.h>
18
19namespace Glib
20{
21
22Glib::RefPtr<Glib::Regex>
23Regex::create(
24  const Glib::ustring& pattern, RegexCompileFlags compile_options, RegexMatchFlags match_options)
25{
26  GError* gerror = nullptr;
27  auto regex = g_regex_new(
28    pattern.c_str(), (GRegexCompileFlags)compile_options, (GRegexMatchFlags)match_options, &gerror);
29
30  if (gerror)
31    Glib::Error::throw_exception(gerror);
32  return Glib::wrap(regex);
33}
34
35// static
36Glib::ustring
37Regex::escape_string(const Glib::ustring& string)
38{
39  const auto buf =
40    make_unique_ptr_gfree(g_regex_escape_string(string.raw().c_str(), string.raw().size()));
41  return Glib::ustring(buf.get());
42}
43
44bool
45Regex::match(
46  const Glib::ustring& string, Glib::MatchInfo& match_info, RegexMatchFlags match_options)
47{
48  GMatchInfo* ginfo = nullptr;
49  bool const result = static_cast<bool>(
50    g_regex_match(gobj(), string.c_str(), static_cast<GRegexMatchFlags>(match_options), &ginfo));
51  match_info.set_gobject(ginfo);
52  return result;
53}
54
55bool
56Regex::match(const Glib::ustring& string, RegexMatchFlags match_options)
57{
58  return g_regex_match(gobj(), string.c_str(), (GRegexMatchFlags)(match_options), nullptr);
59}
60
61bool
62Regex::match(const Glib::ustring& string, int start_position, Glib::MatchInfo& match_info,
63  RegexMatchFlags match_options)
64{
65  GError* gerror = nullptr;
66  GMatchInfo* ginfo = nullptr;
67
68  bool const result = static_cast<bool>(g_regex_match_full(gobj(), string.c_str(), -1,
69    start_position, static_cast<GRegexMatchFlags>(match_options), &ginfo, &gerror));
70
71  if (gerror)
72    ::Glib::Error::throw_exception(gerror);
73
74  match_info.set_gobject(ginfo);
75  return result;
76}
77
78bool
79Regex::match(const Glib::ustring& string, gssize string_len, int start_position,
80  Glib::MatchInfo& match_info, RegexMatchFlags match_options)
81{
82  GError* gerror = nullptr;
83  GMatchInfo* ginfo = nullptr;
84
85  bool const result = static_cast<bool>(g_regex_match_full(gobj(), string.c_str(), string_len,
86    start_position, static_cast<GRegexMatchFlags>(match_options), &ginfo, &gerror));
87
88  if (gerror)
89    ::Glib::Error::throw_exception(gerror);
90
91  match_info.set_gobject(ginfo);
92  return result;
93}
94
95bool
96Regex::match(const Glib::ustring& string, int start_position, RegexMatchFlags match_options)
97{
98  GError* gerror = nullptr;
99  bool retvalue = g_regex_match_full(gobj(), string.c_str(), -1, start_position,
100    ((GRegexMatchFlags)(match_options)), nullptr, &(gerror));
101  if (gerror)
102    ::Glib::Error::throw_exception(gerror);
103
104  return retvalue;
105}
106
107bool
108Regex::match(
109  const Glib::ustring& string, gssize string_len, int start_position, RegexMatchFlags match_options)
110{
111  GError* gerror = nullptr;
112  bool retvalue = g_regex_match_full(gobj(), string.c_str(), string_len, start_position,
113    ((GRegexMatchFlags)(match_options)), nullptr, &(gerror));
114  if (gerror)
115    ::Glib::Error::throw_exception(gerror);
116
117  return retvalue;
118}
119
120bool
121Regex::match_all(
122  const Glib::ustring& string, Glib::MatchInfo& match_info, RegexMatchFlags match_options)
123{
124  GMatchInfo* ginfo = nullptr;
125  bool const result = static_cast<bool>(g_regex_match_all(
126    gobj(), string.c_str(), static_cast<GRegexMatchFlags>(match_options), &ginfo));
127  match_info.set_gobject(ginfo);
128  return result;
129}
130
131bool
132Regex::match_all(const Glib::ustring& string, RegexMatchFlags match_options)
133{
134  return g_regex_match_all(gobj(), string.c_str(), ((GRegexMatchFlags)(match_options)), nullptr);
135}
136
137bool
138Regex::match_all(const Glib::ustring& string, int start_position, Glib::MatchInfo& match_info,
139  RegexMatchFlags match_options)
140{
141  GError* gerror = nullptr;
142  GMatchInfo* ginfo = nullptr;
143
144  bool const retvalue = static_cast<bool>(g_regex_match_all_full(gobj(), string.c_str(), -1,
145    start_position, static_cast<GRegexMatchFlags>(match_options), &ginfo, &gerror));
146
147  if (gerror)
148    ::Glib::Error::throw_exception(gerror);
149
150  match_info.set_gobject(ginfo);
151  return retvalue;
152}
153
154bool
155Regex::match_all(const Glib::ustring& string, gssize string_len, int start_position,
156  Glib::MatchInfo& match_info, RegexMatchFlags match_options)
157{
158  GError* gerror = nullptr;
159  GMatchInfo* ginfo = nullptr;
160
161  bool const retvalue = static_cast<bool>(g_regex_match_all_full(gobj(), string.c_str(), string_len,
162    start_position, static_cast<GRegexMatchFlags>(match_options), &ginfo, &gerror));
163
164  if (gerror)
165    ::Glib::Error::throw_exception(gerror);
166
167  match_info.set_gobject(ginfo);
168  return retvalue;
169}
170
171bool
172Regex::match_all(const Glib::ustring& string, int start_position, RegexMatchFlags match_options)
173{
174  GError* gerror = nullptr;
175  bool retvalue = g_regex_match_all_full(gobj(), string.c_str(), -1, start_position,
176    ((GRegexMatchFlags)(match_options)), nullptr, &(gerror));
177  if (gerror)
178    ::Glib::Error::throw_exception(gerror);
179
180  return retvalue;
181}
182
183bool
184Regex::match_all(
185  const Glib::ustring& string, gssize string_len, int start_position, RegexMatchFlags match_options)
186{
187  GError* gerror = nullptr;
188  bool retvalue = g_regex_match_all_full(gobj(), string.c_str(), string_len, start_position,
189    ((GRegexMatchFlags)(match_options)), nullptr, &(gerror));
190  if (gerror)
191    ::Glib::Error::throw_exception(gerror);
192
193  return retvalue;
194}
195
196Glib::ustring
197Regex::replace(const Glib::ustring& string, int start_position, const Glib::ustring& replacement,
198  RegexMatchFlags match_options)
199{
200  GError* gerror = nullptr;
201  auto retvalue = Glib::convert_return_gchar_ptr_to_ustring(g_regex_replace(gobj(), string.c_str(),
202    -1, start_position, replacement.c_str(), ((GRegexMatchFlags)(match_options)), &(gerror)));
203  if (gerror)
204    ::Glib::Error::throw_exception(gerror);
205
206  return retvalue;
207}
208
209Glib::ustring
210Regex::replace_literal(const Glib::ustring& string, int start_position,
211  const Glib::ustring& replacement, RegexMatchFlags match_options)
212{
213  GError* gerror = nullptr;
214  auto retvalue =
215    Glib::convert_return_gchar_ptr_to_ustring(g_regex_replace_literal(gobj(), string.c_str(), -1,
216      start_position, replacement.c_str(), ((GRegexMatchFlags)(match_options)), &(gerror)));
217  if (gerror)
218    ::Glib::Error::throw_exception(gerror);
219
220  return retvalue;
221}
222
223Glib::StringArrayHandle
224Regex::split(const Glib::ustring& string, int start_position, RegexMatchFlags match_options,
225  int max_tokens) const
226{
227  GError* gerror = nullptr;
228  auto retvalue = Glib::StringArrayHandle(
229    g_regex_split_full(const_cast<GRegex*>(gobj()), string.c_str(), -1, start_position,
230      ((GRegexMatchFlags)(match_options)), max_tokens, &(gerror)),
231    Glib::OWNERSHIP_DEEP);
232  if (gerror)
233    ::Glib::Error::throw_exception(gerror);
234
235  return retvalue;
236}
237
238MatchInfo::MatchInfo() : gobject_(nullptr), take_ownership(false)
239{
240}
241
242MatchInfo::MatchInfo(GMatchInfo* castitem, bool take_the_ownership)
243: gobject_(castitem), take_ownership(take_the_ownership)
244{
245}
246
247MatchInfo::MatchInfo(MatchInfo&& other) noexcept : gobject_(std::move(other.gobject_)),
248                                                   take_ownership(std::move(other.take_ownership))
249{
250  other.gobject_ = nullptr;
251  other.take_ownership = false;
252}
253
254MatchInfo&
255MatchInfo::operator=(MatchInfo&& other) noexcept
256{
257  if (take_ownership && gobject_)
258    g_match_info_free(gobject_);
259
260  gobject_ = std::move(other.gobject_);
261  take_ownership = std::move(other.take_ownership);
262
263  other.gobject_ = nullptr;
264  other.take_ownership = false;
265
266  return *this;
267}
268
269void
270MatchInfo::set_gobject(GMatchInfo* castitem, bool take_the_ownership)
271{
272  if (gobject_ && this->take_ownership)
273    g_match_info_free(gobject_);
274
275  gobject_ = castitem;
276  this->take_ownership = take_the_ownership;
277}
278
279MatchInfo::~MatchInfo()
280{
281  if (take_ownership && gobject_)
282    g_match_info_free(gobject_);
283}
284
285} // namespace Glib
286