More C++
This commit is contained in:
parent
a48117407f
commit
c13468f8ed
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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], ¤t_dir);
|
info = parse_file (medit_opts.files[i].get(), ¤t_dir);
|
||||||
|
|
||||||
if (!info)
|
if (!info)
|
||||||
continue;
|
continue;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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(); }
|
||||||
|
};
|
||||||
|
@ -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
284
moo/moocpp/regex.cpp
Normal 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
148
moo/moocpp/regex.h
Normal 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)
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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 **
|
||||||
|
@ -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);
|
||||||
|
@ -277,9 +277,9 @@ 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user