Commit af360b85 authored by Daniel Elstner's avatar Daniel Elstner
Browse files

:compose_argv): New function with the functionality of compose_impl() but

* src/translation.{cc,h} (Util::compose_argv): New function with
the functionality of compose_impl() but using a format string of
type const char*.  This implementation operates on bytes instead of
Unicode code points, and copies the chunks between placeholders in
one go instead of each character separately.
(Util::compose): Call compose_argv() instead of compose_impl()
and change the type of the format argument to const char* because
the format string really should be a string literal.  Also, inline
all of these overloads since they just forward their arguments to
compose_argv() anyway, so that inlining actually reduces code size.

svn path=/trunk/; revision=636
parent 742206f2
2007-01-14 Daniel Elstner <daniel.kitta@gmail.com>
* src/translation.{cc,h} (Util::compose_argv): New function with
the functionality of compose_impl() but using a format string of
type const char*. This implementation operates on bytes instead of
Unicode code points, and copies the chunks between placeholders in
one go instead of each character separately.
(Util::compose): Call compose_argv() instead of compose_impl()
and change the type of the format argument to const char* because
the format string really should be a string literal. Also, inline
all of these overloads since they just forward their arguments to
compose_argv() anyway, so that inlining actually reduces code size.
2007-01-14 Daniel Elstner <daniel.kitta@gmail.com>
* src/fileshared.h: Replace occurrences of "lhs" and "rhs" with
......
......@@ -27,63 +27,7 @@
#include <glib.h>
#include <glibmm.h>
namespace
{
static
Glib::ustring compose_impl(const Glib::ustring& format,
int argc, const Glib::ustring *const * argv)
{
using Glib::ustring;
ustring result;
ustring::size_type result_size = format.raw().size();
// Guesstimate the final string size.
for (int i = 0; i < argc; ++i)
result_size += argv[i]->raw().size();
result.reserve(result_size);
ustring::const_iterator p = format.begin();
const ustring::const_iterator pend = format.end();
while (p != pend)
{
gunichar uc = *p++;
if (uc == '%' && p != pend)
{
uc = *p++;
if (uc != '%')
{
const int index = Glib::Unicode::digit_value(uc) - 1;
if (index >= 0 && index < argc)
{
result += *argv[index];
continue;
}
const ustring buf (1, uc);
g_warning("Util::compose(): invalid substitution \"%%%s\" in format string \"%s\"",
buf.c_str(), format.c_str());
result += '%'; // print invalid substitutions literally
}
}
result += uc;
}
return result;
}
} // anonymous namespace
#include <cstring>
#if ENABLE_NLS
void Util::initialize_gettext(const char* domain, const char* localedir)
......@@ -108,23 +52,52 @@ const char* Util::translate(const char* msgid)
#endif
}
Glib::ustring Util::compose(const Glib::ustring& format, const Glib::ustring& arg1)
Glib::ustring Util::compose_argv(const char* format, int argc, const Glib::ustring *const * argv)
{
const Glib::ustring *const argv[] = { &arg1 };
return compose_impl(format, G_N_ELEMENTS(argv), argv);
}
const std::string::size_type format_size = std::strlen(format);
std::string::size_type result_size = format_size;
Glib::ustring Util::compose(const Glib::ustring& format, const Glib::ustring& arg1,
const Glib::ustring& arg2)
{
const Glib::ustring *const argv[] = { &arg1, &arg2 };
return compose_impl(format, G_N_ELEMENTS(argv), argv);
}
// Guesstimate the final string size.
for (int i = 0; i < argc; ++i)
result_size += argv[i]->raw().size();
Glib::ustring Util::compose(const Glib::ustring& format, const Glib::ustring& arg1,
const Glib::ustring& arg2,
const Glib::ustring& arg3)
{
const Glib::ustring *const argv[] = { &arg1, &arg2, &arg3 };
return compose_impl(format, G_N_ELEMENTS(argv), argv);
std::string result;
result.reserve(result_size);
const char* start = format;
while (const char* stop = std::strchr(start, '%'))
{
if (stop[1] == '%')
{
result.append(start, stop - start + 1);
start = stop + 2;
}
else
{
const int index = Glib::Ascii::digit_value(stop[1]) - 1;
if (index >= 0 && index < argc)
{
result.append(start, stop - start);
result += argv[index]->raw();
start = stop + 2;
}
else
{
const char *const next = (stop[1] != '\0') ? g_utf8_next_char(stop + 1) : (stop + 1);
// Copy invalid substitutions literally to the output.
result.append(start, next - start);
g_warning("invalid substitution \"%s\" in format string \"%s\"",
result.c_str() + result.size() - (next - stop), format);
start = next;
}
}
}
result.append(start, format + format_size - start);
return result;
}
......@@ -35,14 +35,41 @@ namespace Util
{
void initialize_gettext(const char* domain, const char* localedir);
const char* translate(const char* msgid) G_GNUC_PURE G_GNUC_FORMAT(1);
Glib::ustring compose(const Glib::ustring& format, const Glib::ustring& arg1);
Glib::ustring compose(const Glib::ustring& format, const Glib::ustring& arg1,
const Glib::ustring& arg2);
Glib::ustring compose(const Glib::ustring& format, const Glib::ustring& arg1,
const Glib::ustring& arg2,
const Glib::ustring& arg3);
const char* translate(const char* msgid) G_GNUC_FORMAT(1);
Glib::ustring compose_argv(const char* format, int argc, const Glib::ustring *const * argv);
/*
* The compose functions substitute placeholders in a format string with
* the referenced arguments. The template string should be in qt-format,
* that is "%1", "%2", ..., "%9" are used as placeholders and "%%" denotes
* a literal "%". Substitutions may be reordered.
*
* Note that the format argument is of type const char* because the format
* should generally not be computed. It should be either a literal string
* or the result of a call to Util::translate().
*/
inline
Glib::ustring compose(const char* format, const Glib::ustring& s1)
{
const Glib::ustring *const argv[] = { &s1 };
return compose_argv(format, G_N_ELEMENTS(argv), argv);
}
inline
Glib::ustring compose(const char* format, const Glib::ustring& s1, const Glib::ustring& s2)
{
const Glib::ustring *const argv[] = { &s1, &s2 };
return compose_argv(format, G_N_ELEMENTS(argv), argv);
}
inline
Glib::ustring compose(const char* format, const Glib::ustring& s1, const Glib::ustring& s2,
const Glib::ustring& s3)
{
const Glib::ustring *const argv[] = { &s1, &s2, &s3 };
return compose_argv(format, G_N_ELEMENTS(argv), argv);
}
} // namespace Util
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment