This commit is contained in:
Yevgen Muntyan 2016-10-24 23:35:31 -07:00
parent a48117407f
commit c13468f8ed
14 changed files with 545 additions and 96 deletions

View File

@ -20,6 +20,7 @@
#include "mooutils/mooutils-fs.h" #include "mooutils/mooutils-fs.h"
#include "mooutils/mooutils-misc.h" #include "mooutils/mooutils-misc.h"
#include "mooutils/mootype-macros.h" #include "mooutils/mootype-macros.h"
#include "moocpp/regex.h"
#include "plugins/mooplugin-builtin.h" #include "plugins/mooplugin-builtin.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <stdlib.h> #include <stdlib.h>
@ -50,7 +51,7 @@ static struct MeditOpts {
gboolean log_window; gboolean log_window;
const char *exec_string; const char *exec_string;
const char *exec_file; const char *exec_file;
char **files; std::vector<gstr> files;
const char *geometry; const char *geometry;
gboolean show_version; gboolean show_version;
const char *debug; const char *debug;
@ -59,7 +60,7 @@ static struct MeditOpts {
gboolean ut_list; gboolean ut_list;
char *ut_dir; char *ut_dir;
char *ut_coverage_file; char *ut_coverage_file;
char **ut_tests; std::vector<gstr> ut_tests;
char **run_script; char **run_script;
char **send_script; char **send_script;
gboolean portable; gboolean portable;
@ -107,7 +108,7 @@ parse_use_session (const char *option_name,
else else
{ {
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
/* error message for wrong commmand line */ /* error message for wrong command line */
_("Invalid value '%s' for option %s"), value, option_name); _("Invalid value '%s' for option %s"), value, option_name);
return FALSE; return FALSE;
} }
@ -178,54 +179,34 @@ static GOptionEntry medit_options[] = {
static void static void
check_plus_line_arg (void) check_plus_line_arg (void)
{ {
gboolean done = FALSE; std::shared_ptr<g::Regex> re = g::Regex::compile("^\\+(?P<line>\\d+)", g::Regex::OPTIMIZE | g::Regex::DUPNAMES);
char **p; g_return_if_fail (re != nullptr);
GRegex *re = NULL;
re = g_regex_new ("^\\+(?P<line>\\d+)", GRegexCompileFlags (G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES), GRegexMatchFlags (0), NULL); for (size_t i = 0; i < medit_opts.files.size(); ++i)
g_return_if_fail (re != NULL);
for (p = medit_opts.files; !done && p && *p && **p; ++p)
{ {
GMatchInfo *match_info = NULL; const gstr& file = medit_opts.files[i];
if (std::unique_ptr<g::MatchInfo> match_info = re->match(file))
if (g_regex_match (re, *p, GRegexMatchFlags (0), &match_info))
{ {
int line = 0; int line = 0;
char *line_string = g_match_info_fetch_named (match_info, "line"); gstr line_string = match_info->fetch_named("line");
errno = 0; errno = 0;
line = strtol (line_string, NULL, 10); line = strtol(line_string.get(), NULL, 10);
if (errno != 0) if (errno != 0)
line = 0; line = 0;
// if a file "+10" exists, open it // if a file "+10" exists, open it
if (line > 0 && g_file_test (*p, G_FILE_TEST_EXISTS)) if (line > 0 && g_file_test (file.get(), G_FILE_TEST_EXISTS))
line = 0; line = 0;
if (line > 0) if (line > 0)
{ {
medit_opts.line = line; medit_opts.line = line;
medit_opts.files.erase(medit_opts.files.begin() + i);
g_free (*p); return;
*p = NULL;
if (*(p + 1) != NULL)
{
int n = g_strv_length (p + 1);
memcpy (p, p + 1, n * sizeof(*p));
*(p + n) = NULL;
} }
done = TRUE;
} }
g_free (line_string);
} }
g_match_info_free (match_info);
}
g_regex_unref (re);
} }
static gboolean static gboolean
@ -244,10 +225,7 @@ post_parse_func (void)
} }
if (medit_opts.ut) if (medit_opts.ut)
{ std::swap(medit_opts.ut_tests, medit_opts.files);
medit_opts.ut_tests = medit_opts.files;
medit_opts.files = NULL;
}
if (medit_opts.pid > 0 && medit_opts.instance_name) if (medit_opts.pid > 0 && medit_opts.instance_name)
{ {

View File

@ -206,7 +206,7 @@ parse_files (void)
char *current_dir = NULL; char *current_dir = NULL;
MooOpenInfoArray *files; MooOpenInfoArray *files;
if (!medit_opts.files || !(n_files = g_strv_length (medit_opts.files))) if (medit_opts.files.empty() || !(n_files = medit_opts.files.size()))
return NULL; return NULL;
files = moo_open_info_array_new (); files = moo_open_info_array_new ();
@ -215,7 +215,7 @@ parse_files (void)
{ {
MooOpenInfo *info; MooOpenInfo *info;
info = parse_file (medit_opts.files[i], &current_dir); info = parse_file (medit_opts.files[i].get(), &current_dir);
if (!info) if (!info)
continue; continue;

View File

@ -30,7 +30,7 @@ add_tests (MooTestOptions opts)
} }
static int static int
unit_tests_main (MooTestOptions opts, char **tests, const char *data_dir_arg, const char *coverage_file) unit_tests_main(MooTestOptions opts, const gstrvec& tests, const char *data_dir_arg, const char *coverage_file)
{ {
const char *data_dir = NULL; const char *data_dir = NULL;
gboolean passed; gboolean passed;
@ -56,5 +56,5 @@ unit_tests_main (MooTestOptions opts, char **tests, const char *data_dir_arg, co
static void static void
list_unit_tests (const char *data_dir) list_unit_tests (const char *data_dir)
{ {
unit_tests_main (MOO_TEST_LIST_ONLY, NULL, data_dir, NULL); unit_tests_main(MOO_TEST_LIST_ONLY, gstrvec(), data_dir, NULL);
} }

View File

@ -17,24 +17,9 @@
#include "moocpp/fileutils.h" #include "moocpp/fileutils.h"
gstr g::build_filename(const gstr& comp1, const gstr& comp2) gstr g::build_filename_impl(const char* comp1, const char* comp2, const char* comp3)
{ {
return gstr::take(g_build_filename(comp1.get(), comp2.get(), nullptr)); return gstr::take(g_build_filename(comp1, comp2, comp3, nullptr));
}
gstr g::build_filename(const gstr& comp1, const gstr& comp2, const gstr& comp3)
{
return gstr::take(g_build_filename(comp1.get(), comp2.get(), comp3.get(), nullptr));
}
gstr g::build_filename(const gstr& comp1, const gstr& comp2, const gstr& comp3, const gstr& comp4)
{
return gstr::take(g_build_filename(comp1.get(), comp2.get(), comp3.get(), comp4.get(), nullptr));
}
gstr g::build_filename(const gstr& comp1, const gstr& comp2, const gstr& comp3, const gstr& comp4, const gstr& comp5)
{
return gstr::take(g_build_filename(comp1.get(), comp2.get(), comp3.get(), comp4.get(), comp5.get(), nullptr));
} }
gstr g::build_filenamev(const std::vector<gstr>& components) gstr g::build_filenamev(const std::vector<gstr>& components)

View File

@ -21,10 +21,26 @@
namespace g namespace g
{ {
gstr build_filename(const gstr& comp1, const gstr& comp2); gstr build_filename_impl(const char* comp1, const char* comp2 = nullptr, const char* comp3 = nullptr);
gstr build_filename(const gstr& comp1, const gstr& comp2, const gstr& comp3);
gstr build_filename(const gstr& comp1, const gstr& comp2, const gstr& comp3, const gstr& comp4); template<typename T1>
gstr build_filename(const gstr& comp1, const gstr& comp2, const gstr& comp3, const gstr& comp4, const gstr& comp5); gstr build_filename(const T1& comp1)
{
return build_filename_impl(ConstCharSource<T1>::get(comp1));
}
template<typename T1, typename T2>
gstr build_filename(const T1& comp1, const T2& comp2)
{
return build_filename_impl(ConstCharSource<T1>::get(comp1), ConstCharSource<T2>::get(comp2));
}
template<typename T1, typename T2, typename T3>
gstr build_filename(const T1& comp1, const T2& comp2, const T3& comp3)
{
return build_filename_impl(ConstCharSource<T1>::get(comp1), ConstCharSource<T2>::get(comp2), ConstCharSource<T3>::get(comp3));
}
gstr build_filenamev(const std::vector<gstr>& components); gstr build_filenamev(const std::vector<gstr>& components);
gstr get_current_dir(); gstr get_current_dir();
gstr path_get_basename(const gchar *file_name); gstr path_get_basename(const gchar *file_name);

View File

@ -35,7 +35,7 @@ gstr::~gstr()
gstr::gstr(const char* s) gstr::gstr(const char* s)
: gstr() : gstr()
{ {
*this = s; copy(s);
} }
gstr::gstr(char* s, bool) gstr::gstr(char* s, bool)
@ -74,19 +74,17 @@ gstr gstr::take(char* src)
gstr& gstr::operator=(const gstr& other) gstr& gstr::operator=(const gstr& other)
{ {
if (this != &other) copy(other.m_p);
*this = other.m_p;
return *this; return *this;
} }
gstr& gstr::operator=(const char* other) void gstr::copy(const char* s)
{ {
if (m_p != other) if (m_p != s)
{ {
g_free(m_p); g_free(m_p);
m_p = other ? g_strdup(other) : nullptr; m_p = s ? g_strdup(s) : nullptr;
} }
return *this;
} }
gstr& gstr::operator=(gstr&& other) gstr& gstr::operator=(gstr&& other)
@ -126,17 +124,28 @@ bool gstr::operator<(const gstr& other) const
return strcmp(get(), other.get()) < 0; return strcmp(get(), other.get()) < 0;
} }
std::vector<gstr> gstr::from_strv(char** strv) gstrvec gstr::copy(char** strv)
{ {
size_t len = strv ? g_strv_length(strv) : 0; size_t len = strv ? g_strv_length(strv) : 0;
std::vector<gstr> result; gstrvec result;
result.reserve(len); result.reserve(len);
for (size_t i = 0; i < len; ++i) for (size_t i = 0; i < len; ++i)
result.push_back(strv[i]); result.push_back(gstr(strv[i]));
return result; return result;
} }
std::vector<gstr> gstr::split(const char* separator, int max_pieces) const gstrvec gstr::take(char** strv)
{ {
return from_strv(g_strsplit(get(), separator, max_pieces)); size_t len = strv ? g_strv_length(strv) : 0;
gstrvec result;
result.reserve(len);
for (size_t i = 0; i < len; ++i)
result.push_back(gstr::take(strv[i]));
g_free(strv);
return result;
}
gstrvec gstr::split(const char* separator, int max_pieces) const
{
return take(g_strsplit(get(), separator, max_pieces));
} }

View File

@ -19,12 +19,15 @@
#include <string.h> #include <string.h>
#include <vector> #include <vector>
class gstr;
using gstrvec = std::vector<gstr>;
class gstr class gstr
{ {
public: public:
gstr(); gstr();
gstr(nullptr_t); gstr(nullptr_t);
gstr(const char* s); explicit gstr(const char* s);
gstr(char* s, bool); gstr(char* s, bool);
~gstr(); ~gstr();
@ -33,11 +36,11 @@ public:
const char* get() const; const char* get() const;
void copy(const char* s);
void steal(char* s); void steal(char* s);
static gstr take(char* src); static gstr take(char* src);
gstr& operator=(const gstr& other); gstr& operator=(const gstr& other);
gstr& operator=(const char* other);
gstr& operator=(gstr&& other); gstr& operator=(gstr&& other);
void clear(); void clear();
@ -55,14 +58,20 @@ public:
bool operator<(const gstr& other) const; bool operator<(const gstr& other) const;
static std::vector<gstr> from_strv(char** strv); static gstrvec copy(char** strv);
static gstrvec take(char** strv);
std::vector<gstr> split(const char* separator, int max_pieces) const; gstrvec split(const char* separator, int max_pieces) const;
private: private:
char* m_p; char* m_p;
}; };
class gstrbuilder
{
};
namespace std namespace std
{ {
@ -76,3 +85,24 @@ struct hash<gstr>
}; };
} // namespace std } // namespace std
template<typename T>
struct ConstCharSource;
template<>
struct ConstCharSource<const char*>
{
static const char* get(const char* s) { return s; }
};
template<size_t arr_size>
struct ConstCharSource<const char[arr_size]>
{
static const char* get(const char s[arr_size]) { return s; }
};
template<>
struct ConstCharSource<gstr>
{
static const char* get(const gstr& s) { return s.get(); }
};

View File

@ -6,5 +6,7 @@ SET(moocpp_sources
moocpp/gstr.h moocpp/gstr.h
moocpp/gstr.cpp moocpp/gstr.cpp
moocpp/moocpp.h moocpp/moocpp.h
moocpp/regex.h
moocpp/regex.cpp
moocpp/util.h moocpp/util.h
) )

284
moo/moocpp/regex.cpp Normal file
View File

@ -0,0 +1,284 @@
/*
* regex.cpp
*
* Copyright (C) 2004-2016 by Yevgen Muntyan <emuntyan@users.sourceforge.net>
*
* This file is part of medit. medit is free software; you can
* redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public
* License along with medit. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "moocpp/regex.h"
namespace g
{
Regex::Regex(GRegex* p)
: m_p(p)
{
}
Regex::~Regex()
{
g_regex_unref(m_p);
}
std::shared_ptr<Regex> Regex::compile(const char* pattern, CompileFlags compile_options, MatchFlags match_options, GError** error)
{
GRegex* p = g_regex_new(pattern, GRegexCompileFlags(compile_options), GRegexMatchFlags(match_options), error);
if (!p)
return nullptr;
return std::make_shared<Regex>(p);
}
const char* Regex::get_pattern() const
{
return g_regex_get_pattern(m_p);
}
int Regex::get_max_backref() const
{
return g_regex_get_max_backref(m_p);
}
int Regex::get_capture_count() const
{
return g_regex_get_capture_count(m_p);
}
bool Regex::get_has_cr_or_lf() const
{
return g_regex_get_has_cr_or_lf(m_p);
}
int Regex::get_max_lookbehind() const
{
return g_regex_get_max_lookbehind(m_p);
}
int Regex::get_string_number(const char *name) const
{
return g_regex_get_string_number(m_p, name);
}
gstr Regex::escape_string(const char* string, int length)
{
return gstr::take(g_regex_escape_string(string, length));
}
gstr Regex::escape_nul(const char* string, int length)
{
return gstr::take(g_regex_escape_nul(string, length));
}
Regex::CompileFlags Regex::get_compile_flags() const
{
return CompileFlags(g_regex_get_compile_flags(m_p));
}
Regex::MatchFlags Regex::get_match_flags() const
{
return MatchFlags(g_regex_get_match_flags(m_p));
}
bool Regex::match(const char *pattern, const char *string, CompileFlags compile_options, MatchFlags match_options)
{
return g_regex_match_simple(pattern, string, GRegexCompileFlags(compile_options), GRegexMatchFlags(match_options));
}
std::unique_ptr<MatchInfo> Regex::match(const char* string, MatchFlags match_options) const
{
return match(string, -1, 0, match_options, nullptr);
}
std::unique_ptr<MatchInfo> Regex::match(const gstr& string, MatchFlags match_options) const
{
return match(string.get(), match_options);
}
std::unique_ptr<MatchInfo> Regex::match(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, GError** error) const
{
GMatchInfo* match_info = nullptr;
if (!g_regex_match_full(m_p, string, string_len, start_position, GRegexMatchFlags(match_options), &match_info, error))
return nullptr;
return std::make_unique<MatchInfo>(*this, match_info, true);
}
std::unique_ptr<MatchInfo> Regex::match_all(const char* string, MatchFlags match_options) const
{
return match_all(string, -1, 0, match_options, nullptr);
}
std::unique_ptr<MatchInfo> Regex::match_all(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, GError** error) const
{
GMatchInfo* match_info = nullptr;
if (!g_regex_match_all_full(m_p, string, string_len, start_position, GRegexMatchFlags(match_options), &match_info, error))
return nullptr;
return std::make_unique<MatchInfo>(*this, match_info, true);
}
std::vector<gstr> Regex::split(const char* pattern, const char* string, CompileFlags compile_options, MatchFlags match_options)
{
return gstr::take(g_regex_split_simple(pattern, string, GRegexCompileFlags(compile_options), GRegexMatchFlags(match_options)));
}
std::vector<gstr> Regex::split(const char* string, MatchFlags match_options) const
{
return gstr::take(g_regex_split(m_p, string, GRegexMatchFlags(match_options)));
}
std::vector<gstr> Regex::split(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, int max_tokens, GError** error) const
{
return gstr::take(g_regex_split_full(m_p, string, string_len, start_position, GRegexMatchFlags(match_options), max_tokens, error));
}
gstr Regex::replace(const char* string, const char* replacement, MatchFlags match_options) const
{
return replace(string, -1, 0, replacement, match_options, nullptr);
}
gstr Regex::replace(const char* string, ssize_t string_len, int start_position, const char* replacement, MatchFlags match_options, GError** error) const
{
return gstr::take(g_regex_replace(m_p, string, string_len, start_position, replacement, GRegexMatchFlags(match_options), error));
}
gstr Regex::replace_literal(const char* string, const char* replacement, MatchFlags match_options) const
{
return replace_literal(string, -1, 0, replacement, match_options, nullptr);
}
gstr Regex::replace_literal(const char* string, ssize_t string_len, int start_position, const char* replacement, MatchFlags match_options, GError** error) const
{
return gstr::take(g_regex_replace_literal(m_p, string, string_len, start_position, replacement, GRegexMatchFlags(match_options), error));
}
namespace
{
using EvalFunc = std::function<bool(const MatchInfo&, gstr&)>;
struct EvalFuncData
{
const Regex& regex;
const EvalFunc& func;
EvalFuncData(const Regex& regex, const EvalFunc& func)
: regex(regex)
, func(func)
{
}
EvalFuncData(const EvalFuncData&) = delete;
EvalFuncData& operator=(const EvalFuncData&) = delete;
};
static gboolean eval_func(const GMatchInfo* match_info, GString* result, gpointer user_data)
{
EvalFuncData* data = reinterpret_cast<EvalFuncData*>(user_data);
gstr replacement;
MatchInfo mi(data->regex, const_cast<GMatchInfo*>(match_info), false);
bool retval = data->func(mi, replacement);
if (!replacement.empty())
g_string_append(result, replacement.get());
return retval;
}
}
gstr Regex::replace_eval(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, const std::function<bool(const MatchInfo&, gstr&)>& eval, GError** error) const
{
EvalFuncData data(*this, eval);
return gstr::take(g_regex_replace_eval(m_p, string, string_len, start_position, GRegexMatchFlags(match_options), eval_func, &data, error));
}
bool Regex::check_replacement(const char* replacement, bool& has_references, GError** error)
{
gboolean c_has_references;
bool retval = g_regex_check_replacement(replacement, &c_has_references, error);
has_references = c_has_references;
return retval;
}
MatchInfo::MatchInfo(const Regex& regex, GMatchInfo* p, bool take_ownership)
: m_regex(regex)
, m_p(p)
, m_own(take_ownership)
{
}
MatchInfo::~MatchInfo()
{
if (m_own)
g_match_info_free(m_p);
}
const Regex& MatchInfo::get_regex() const
{
return m_regex;
}
const char* MatchInfo::get_string() const
{
return g_match_info_get_string(m_p);
}
bool MatchInfo::next(GError** error)
{
g_return_val_if_fail(m_own, false);
return g_match_info_next(m_p, error);
}
bool MatchInfo::matches() const
{
return g_match_info_matches(m_p);
}
int MatchInfo::get_match_count() const
{
return g_match_info_get_match_count(m_p);
}
bool MatchInfo::is_partial_match() const
{
return g_match_info_is_partial_match(m_p);
}
gstr MatchInfo::expand_references(const char* string_to_expand, GError** error) const
{
return gstr::take(g_match_info_expand_references(m_p, string_to_expand, error));
}
gstr MatchInfo::fetch(int match_num) const
{
return gstr::take(g_match_info_fetch(m_p, match_num));
}
bool MatchInfo::fetch_pos(int match_num, int& start_pos, int& end_pos) const
{
return g_match_info_fetch_pos(m_p, match_num, &start_pos, &end_pos);
}
gstr MatchInfo::fetch_named(const char* name) const
{
return gstr::take(g_match_info_fetch_named(m_p, name));
}
bool MatchInfo::fetch_named_pos(const char* name, int& start_pos, int& end_pos) const
{
return g_match_info_fetch_named_pos(m_p, name, &start_pos, &end_pos);
}
gstrvec MatchInfo::fetch_all() const
{
return gstr::take(g_match_info_fetch_all(m_p));
}
} // namespace g

148
moo/moocpp/regex.h Normal file
View File

@ -0,0 +1,148 @@
/*
* regex.h
*
* Copyright (C) 2004-2016 by Yevgen Muntyan <emuntyan@users.sourceforge.net>
*
* This file is part of medit. medit is free software; you can
* redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public
* License along with medit. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "moocpp/gstr.h"
#include "mooutils/mooutils-cpp.h"
#include <memory>
#include <functional>
namespace g
{
class MatchInfo;
class Regex
{
public:
enum CompileFlags
{
COMPILE_FLAGS_NONE = 0,
CASELESS = G_REGEX_CASELESS,
MULTILINE = G_REGEX_MULTILINE,
DOTALL = G_REGEX_DOTALL,
EXTENDED = G_REGEX_EXTENDED,
ANCHORED = G_REGEX_ANCHORED,
DOLLAR_ENDONLY = G_REGEX_DOLLAR_ENDONLY,
UNGREEDY = G_REGEX_UNGREEDY,
RAW = G_REGEX_RAW,
NO_AUTO_CAPTURE = G_REGEX_NO_AUTO_CAPTURE,
OPTIMIZE = G_REGEX_OPTIMIZE,
FIRSTLINE = G_REGEX_FIRSTLINE,
DUPNAMES = G_REGEX_DUPNAMES,
NEWLINE_CR = G_REGEX_NEWLINE_CR,
NEWLINE_LF = G_REGEX_NEWLINE_LF,
NEWLINE_CRLF = G_REGEX_NEWLINE_CRLF,
NEWLINE_ANYCRLF = G_REGEX_NEWLINE_ANYCRLF,
BSR_ANYCRLF = G_REGEX_BSR_ANYCRLF,
JAVASCRIPT_COMPAT = G_REGEX_JAVASCRIPT_COMPAT,
};
enum MatchFlags
{
MATCH_FLAGS_NONE = 0,
MATCH_ANCHORED = G_REGEX_MATCH_ANCHORED,
MATCH_NOTBOL = G_REGEX_MATCH_NOTBOL,
MATCH_NOTEOL = G_REGEX_MATCH_NOTEOL,
MATCH_NOTEMPTY = G_REGEX_MATCH_NOTEMPTY,
MATCH_PARTIAL = G_REGEX_MATCH_PARTIAL,
MATCH_NEWLINE_CR = G_REGEX_MATCH_NEWLINE_CR,
MATCH_NEWLINE_LF = G_REGEX_MATCH_NEWLINE_LF,
MATCH_NEWLINE_CRLF = G_REGEX_MATCH_NEWLINE_CRLF,
MATCH_NEWLINE_ANY = G_REGEX_MATCH_NEWLINE_ANY,
MATCH_NEWLINE_ANYCRLF = G_REGEX_MATCH_NEWLINE_ANYCRLF,
MATCH_BSR_ANYCRLF = G_REGEX_MATCH_BSR_ANYCRLF,
MATCH_BSR_ANY = G_REGEX_MATCH_BSR_ANY,
MATCH_PARTIAL_SOFT = G_REGEX_MATCH_PARTIAL_SOFT,
MATCH_PARTIAL_HARD = G_REGEX_MATCH_PARTIAL_HARD,
MATCH_NOTEMPTY_ATSTART = G_REGEX_MATCH_NOTEMPTY_ATSTART,
};
Regex(GRegex*);
~Regex();
Regex(const Regex&) = delete;
Regex& operator=(const Regex&) = delete;
static std::shared_ptr<Regex> compile(const char* pattern, CompileFlags compile_options = COMPILE_FLAGS_NONE, MatchFlags match_options = MATCH_FLAGS_NONE, GError** error = nullptr);
const char* get_pattern() const;
int get_max_backref() const;
int get_capture_count() const;
bool get_has_cr_or_lf() const;
int get_max_lookbehind() const;
int get_string_number(const char *name) const;
static gstr escape_string(const char* string, int length = -1);
static gstr escape_nul(const char* string, int length = -1);
CompileFlags get_compile_flags() const;
MatchFlags get_match_flags() const;
static bool match(const char *pattern, const char *string, CompileFlags compile_options = COMPILE_FLAGS_NONE, MatchFlags match_options = MATCH_FLAGS_NONE);
std::unique_ptr<MatchInfo> match(const char* string, MatchFlags match_options = MATCH_FLAGS_NONE) const;
std::unique_ptr<MatchInfo> match(const gstr& string, MatchFlags match_options = MATCH_FLAGS_NONE) const;
std::unique_ptr<MatchInfo> match(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, GError** error) const;
std::unique_ptr<MatchInfo> match_all(const char* string, MatchFlags match_options = MATCH_FLAGS_NONE) const;
std::unique_ptr<MatchInfo> match_all(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, GError** error) const;
static std::vector<gstr> split(const char* pattern, const char* string, CompileFlags compile_options = COMPILE_FLAGS_NONE, MatchFlags match_options = MATCH_FLAGS_NONE);
std::vector<gstr> split(const char* string, MatchFlags match_options = MATCH_FLAGS_NONE) const;
std::vector<gstr> split(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, int max_tokens, GError** error) const;
gstr replace(const char* string, const char* replacement, MatchFlags match_options = MATCH_FLAGS_NONE) const;
gstr replace(const char* string, ssize_t string_len, int start_position, const char* replacement, MatchFlags match_options, GError** error) const;
gstr replace_literal(const char* string, const char* replacement, MatchFlags match_options = MATCH_FLAGS_NONE) const;
gstr replace_literal(const char* string, ssize_t string_len, int start_position, const char* replacement, MatchFlags match_options, GError** error) const;
gstr replace_eval(const char* string, ssize_t string_len, int start_position, MatchFlags match_options, const std::function<bool(const MatchInfo&, gstr&)>& eval, GError** error) const;
static bool check_replacement(const char* replacement, bool& has_references, GError** error);
private:
GRegex* m_p;
};
class MatchInfo
{
public:
MatchInfo(const Regex& regex, GMatchInfo* p, bool take_ownership);
~MatchInfo();
MatchInfo(const MatchInfo&) = delete;
MatchInfo& operator=(const MatchInfo&) = delete;
const Regex& get_regex() const;
const char* get_string() const;
bool next(GError** error);
bool matches() const;
int get_match_count() const;
bool is_partial_match() const;
gstr expand_references(const char* string_to_expand, GError** error) const;
gstr fetch(int match_num) const;
bool fetch_pos(int match_num, int& start_pos, int& end_pos) const;
gstr fetch_named(const char* name) const;
bool fetch_named_pos(const char* name, int& start_pos, int& end_pos) const;
std::vector<gstr> fetch_all() const;
private:
const Regex& m_regex;
GMatchInfo* m_p;
bool m_own;
};
} // namespace g
MOO_DEFINE_FLAGS(g::Regex::CompileFlags)
MOO_DEFINE_FLAGS(g::Regex::MatchFlags)

View File

@ -143,7 +143,7 @@ test_encodings_1 (const char *name,
if ((dot = strchr(name, '.'))) if ((dot = strchr(name, '.')))
encoding.steal(g_strndup (name, dot - name)); encoding.steal(g_strndup (name, dot - name));
else else
encoding = name; encoding.copy(name);
#ifdef MOO_OS_WIN32 #ifdef MOO_OS_WIN32
if (encoding == "UTF-16" || encoding == "UCS-4") if (encoding == "UTF-16" || encoding == "UCS-4")
@ -151,7 +151,7 @@ test_encodings_1 (const char *name,
#endif #endif
gstr filename = g::build_filename (test_data.encodings_dir, name); gstr filename = g::build_filename (test_data.encodings_dir, name);
gstr filename2 = g_build_filename (working_dir, name, (char*)0); gstr filename2 = g::build_filename (working_dir, name);
editor = moo_editor_instance (); editor = moo_editor_instance ();
doc = moo_editor_open_path (editor, filename.get(), encoding.get(), -1, NULL); doc = moo_editor_open_path (editor, filename.get(), encoding.get(), -1, NULL);
@ -217,10 +217,8 @@ test_suite_init (G_GNUC_UNUSED gpointer data)
{ {
mgw_errno_t err; mgw_errno_t err;
test_data.working_dir = g_build_filename (moo_test_get_working_dir (), test_data.working_dir = g::build_filename (moo_test_get_working_dir (), "editor-work");
"editor-work", (char*)0); test_data.encodings_dir = g::build_filename (moo_test_get_data_dir (), "encodings");
test_data.encodings_dir = g::build_filename (moo_test_get_data_dir (),
"encodings");
if (_moo_mkdir_with_parents (test_data.working_dir.get(), &err) != 0) if (_moo_mkdir_with_parents (test_data.working_dir.get(), &err) != 0)
{ {

View File

@ -83,8 +83,8 @@ moo_test_suite_new(const char *name,
gpointer data) gpointer data)
{ {
MooTestSuite ts; MooTestSuite ts;
ts.name = name; ts.name.copy(name);
ts.description = description; ts.description.copy(description);
ts.init_func = init_func; ts.init_func = init_func;
ts.cleanup_func = cleanup_func; ts.cleanup_func = cleanup_func;
ts.data = data; ts.data = data;
@ -104,8 +104,8 @@ moo_test_suite_add_test(MooTestSuite &ts,
g_return_if_fail(test_func != NULL); g_return_if_fail(test_func != NULL);
MooTest test; MooTest test;
test.name = name; test.name.copy(name);
test.description = description; test.description.copy(description);
test.func = test_func; test.func = test_func;
test.data = data; test.data = data;
@ -240,7 +240,7 @@ find_test (const gstr& name,
} }
gboolean gboolean
moo_test_run_tests (char **tests, moo_test_run_tests (const gstrvec& tests,
const char *coverage_file, const char *coverage_file,
MooTestOptions opts) MooTestOptions opts)
{ {
@ -249,10 +249,9 @@ moo_test_run_tests (char **tests,
fprintf (stdout, "\n"); fprintf (stdout, "\n");
if (tests && *tests) if (!tests.empty())
{ {
char *name; for (const auto& name: tests)
while ((name = *tests++))
{ {
MooTestSuite *single_ts = NULL; MooTestSuite *single_ts = NULL;
MooTest *single_test = NULL; MooTest *single_test = NULL;
@ -407,7 +406,7 @@ moo_test_find_data_file (const char *basename)
if (!_moo_path_is_absolute(basename)) if (!_moo_path_is_absolute(basename))
return gstr::take(g_build_filename(registry.data_dir.get(), basename, NULL)); return gstr::take(g_build_filename(registry.data_dir.get(), basename, NULL));
else else
return basename; return gstr(basename);
} }
char ** char **

View File

@ -50,7 +50,7 @@ void moo_test_suite_add_test (MooTestSuite &ts,
MooTestFunc test_func, MooTestFunc test_func,
gpointer data); gpointer data);
gboolean moo_test_run_tests (char **tests, gboolean moo_test_run_tests (const gstrvec& tests,
const char *coverage_file, const char *coverage_file,
MooTestOptions opts); MooTestOptions opts);
void moo_test_cleanup (void); void moo_test_cleanup (void);

View File

@ -277,7 +277,7 @@ static gstr
file_get_uri (File *file) file_get_uri (File *file)
{ {
if (file->uri) if (file->uri)
return file->uri; return gstr(file->uri);
else else
return gstr::take(moo_edit_get_uri (file->doc)); return gstr::take(moo_edit_get_uri (file->doc));
} }