Skip to content

Commit

Permalink
Update Spirit Po sources from source repo
Browse files Browse the repository at this point in the history
This incorporates changes from cbeck88/spirit-po as of 111402d716b48486b7952bfe58b49fddbdcd9969 and
covers a period of approximately 16 months since the addition of this code to the Wesnoth repo in
June 2016. This also bumps our included Spirit Po version from 1.0.1 to 1.1.2.

I've retained our own changes from:
* fd671b1

The following changes have been discarded in favor of changes made in the source repo:
* 69b070a
* 65dacf6
* ae60ff8
* b4dc11c
  • Loading branch information
Vultraz authored and GregoryLundberg committed Nov 30, 2017
1 parent 75f046a commit e59dec9
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 45 deletions.
104 changes: 75 additions & 29 deletions src/spirit_po/catalog.hpp
Expand Up @@ -6,10 +6,19 @@
#ifndef SPIRIT_PO_CATALOG_HPP_INCLUDED
#define SPIRIT_PO_CATALOG_HPP_INCLUDED

// This isn't necessary after boost 1.57 I think but we'll leave it here for compat

#ifndef BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_USE_PHOENIX_V3
#endif

// SPIRIT_PO_NO_EXCEPTIONS used to be named SPIRIT_PO_NOEXCEPT, but we leave this
// here to avoid breakage.

#if (!defined SPIRIT_PO_NO_EXCEPTIONS) && (defined SPIRIT_PO_NOEXCEPT)
#define SPIRIT_PO_NO_EXCEPTIONS
#endif

#include <spirit_po/catalog_metadata.hpp>
#include <spirit_po/default_plural_forms_compiler.hpp>
#include <spirit_po/exceptions.hpp>
Expand Down Expand Up @@ -39,23 +48,23 @@ class catalog {
typename pf_compiler::result_type pf_function_object_;
uint singular_index_; // cached result of pf_function_object(1)

#ifdef SPIRIT_PO_NOEXCEPT
#ifdef SPIRIT_PO_NO_EXCEPTIONS
boost::optional<std::string> error_message_;
// if loading failed, error_message_ contains an error
// (rather than throwing an exception)
#endif // SPIRIT_PO_NOEXCEPT
#endif // SPIRIT_PO_NO_EXCEPTIONS
warning_channel_type warning_channel_;

hashmap_type hashmap_;

public:
static const char EOT = '\x4';
// ASCII 4 is EOT character
// Used to separate msg context from msgid in the hashmap, in MO files
// We use the same formatting system, just for consistency.
// c.f. https://www.gnu.org/software/gettext/manual/html_node/MO-Files.html

static std::string form_context_index(const std::string & msgctxt, const std::string & id) {
const char EOT = static_cast<char>(4);
// ASCII 4 is EOT character
// Used to separate msg context from msgid in the hashmap, in MO files
// We use the same formatting system, just for consistency.
// c.f. https://www.gnu.org/software/gettext/manual/html_node/MO-Files.html

return msgctxt + EOT + id;
}

Expand All @@ -76,6 +85,7 @@ class catalog {

const std::string & get(const po_message & msg, uint plural) const {
uint idx = (plural == 1 ? singular_index_ : pf_function_object_(plural));
if (idx >= msg.strings().size()) { idx = 0; }
return msg.strings()[idx];
}

Expand Down Expand Up @@ -114,7 +124,7 @@ class catalog {
}

public:
#ifdef SPIRIT_PO_NOEXCEPT
#ifdef SPIRIT_PO_NO_EXCEPTIONS
/***
* Error checking (this is done so we don't have to throw exceptions from the ctor.
*/
Expand All @@ -125,7 +135,7 @@ class catalog {
std::string error() const {
return *error_message_; // UB if there there is not an error message
}
#endif // SPIRIT_PO_NOEXCEPT
#endif // SPIRIT_PO_NO_EXCEPTIONS

/***
* Ctors
Expand All @@ -134,6 +144,7 @@ class catalog {
catalog(spirit::line_pos_iterator<Iterator> & it, spirit::line_pos_iterator<Iterator> & end, warning_channel_type warn_channel = warning_channel_type(), pf_compiler compiler = pf_compiler())
: metadata_()
, pf_function_object_()
, singular_index_(0)
, warning_channel_(warn_channel)
, hashmap_()
{
Expand Down Expand Up @@ -186,7 +197,7 @@ class catalog {
}

msg.line_no = line_no;
insert_message(std::move(msg)); // for compatibility, need to insert the header message at msgid ""
this->insert_message(std::move(msg)); // for compatibility, need to insert the header message at msgid ""
}

// Now parse non-fuzzy messages
Expand Down Expand Up @@ -219,7 +230,7 @@ class catalog {
}
msg.line_no = line_no;
// only insert it if it wasn't marked fuzzy
if (!fuzzy) { insert_message(std::move(msg)); }
if (!fuzzy) { this->insert_message(std::move(msg)); }
}
}

Expand Down Expand Up @@ -280,7 +291,7 @@ class catalog {
const char * gettext(const char * msgid) const {
auto it = hashmap_.find(msgid);
if (it != hashmap_.end()) {
return get(it->second).c_str();
return this->get(it->second).c_str();
} else {
return msgid;
}
Expand All @@ -289,7 +300,7 @@ class catalog {
const char * ngettext(const char * msgid, const char * msgid_plural, uint plural) const {
auto it = hashmap_.find(msgid);
if (it != hashmap_.end() && it->second.is_plural()) {
return get(it->second, plural).c_str();
return this->get(it->second, plural).c_str();
} else {
return (plural == 1 ? msgid : msgid_plural);
}
Expand All @@ -298,7 +309,7 @@ class catalog {
const char * pgettext(const char * context, const char * msgid) const {
auto it = hashmap_.find(form_context_index(context, msgid));
if (it != hashmap_.end()) {
return get(it->second).c_str();
return this->get(it->second).c_str();
} else {
return msgid;
}
Expand All @@ -307,7 +318,7 @@ class catalog {
const char * npgettext(const char * context, const char * msgid, const char * msgid_plural, uint plural) const {
auto it = hashmap_.find(form_context_index(context, msgid));
if (it != hashmap_.end() && it->second.is_plural()) {
return get(it->second, plural).c_str();
return this->get(it->second, plural).c_str();
} else {
return (plural == 1 ? msgid : msgid_plural);
}
Expand All @@ -317,43 +328,78 @@ class catalog {
* Lookup strings from catalog, return std::string.
*
* When, for whatever reason, it is more comfortable to use idiomatic C++.
*
* Template arguments here should always be `std::string &&` or `const std::string &`
*/
std::string gettext_str(const std::string & msgid) const {

private:
template <typename S>
std::string gettext_str_impl(S && msgid) const {
auto it = hashmap_.find(msgid);
if (it != hashmap_.end()) {
return get(it->second);
return this->get(it->second);
} else {
return msgid;
return std::forward<S>(msgid);
}
}

std::string ngettext_str(const std::string & msgid, const std::string & msgid_plural, uint plural) const {
template <typename S1, typename S2>
std::string ngettext_str_impl(S1 && msgid, S2 && msgid_plural, uint plural) const {
auto it = hashmap_.find(msgid);
if (it != hashmap_.end() && it->second.is_plural()) {
return get(it->second, plural);
return this->get(it->second, plural);
} else {
return (plural == 1 ? msgid : msgid_plural);
if (plural == 1) {
return std::forward<S1>(msgid);
} else {
return std::forward<S2>(msgid_plural);
}
}
}

std::string pgettext_str(const std::string & context, const std::string & msgid) const {
template <typename S>
std::string pgettext_str_impl(const std::string & context, S && msgid) const {
auto it = hashmap_.find(form_context_index(context, msgid));
if (it != hashmap_.end()) {
return get(it->second);
return this->get(it->second);
} else {
return msgid;
return std::forward<S>(msgid);
}
}

std::string npgettext_str(const std::string & context, const std::string & msgid, const std::string & msgid_plural, uint plural) const {
template <typename S1, typename S2>
std::string npgettext_str_impl(const std::string & context, S1 && msgid, S2 && msgid_plural, uint plural) const {
auto it = hashmap_.find(form_context_index(context, msgid));
if (it != hashmap_.end() && it->second.is_plural()) {
return get(it->second, plural);
return this->get(it->second, plural);
} else {
return (plural == 1 ? msgid : msgid_plural);
if (plural == 1) {
return std::forward<S1>(msgid);
} else {
return std::forward<S2>(msgid_plural);
}
}
}

public:
// Interface to implementations above, enforcing that arguments are `std::string`.

std::string gettext_str(const std::string & msgid) const { return this->gettext_str_impl(msgid); }
std::string gettext_str(std::string && msgid) const { return this->gettext_str_impl(std::move(msgid)); }

std::string ngettext_str(const std::string & msgid, const std::string & msgid_plural, uint plural) const { return this->ngettext_str_impl(msgid, msgid_plural, plural); }
std::string ngettext_str(std::string && msgid, const std::string & msgid_plural, uint plural) const { return this->ngettext_str_impl(std::move(msgid), msgid_plural, plural); }
std::string ngettext_str(const std::string & msgid, std::string && msgid_plural, uint plural) const { return this->ngettext_str_impl(msgid, std::move(msgid_plural), plural); }
std::string ngettext_str(std::string && msgid, std::string && msgid_plural, uint plural) const { return this->ngettext_str_impl(std::move(msgid), std::move(msgid_plural), plural); }

std::string pgettext_str(const std::string & context, const std::string & msgid) const { return this->pgettext_str_impl(context, msgid); }
std::string pgettext_str(const std::string & context, std::string && msgid) const { return this->pgettext_str_impl(context, std::move(msgid)); }

std::string npgettext_str(const std::string & context, const std::string & msgid, const std::string & msgid_plural, uint plural) const { return this->npgettext_str_impl(context, msgid, msgid_plural, plural); }
std::string npgettext_str(const std::string & context, std::string && msgid, const std::string & msgid_plural, uint plural) const { return this->npgettext_str_impl(context, std::move(msgid), msgid_plural, plural); }
std::string npgettext_str(const std::string & context, const std::string & msgid, std::string && msgid_plural, uint plural) const { return this->npgettext_str_impl(context, msgid, std::move(msgid_plural), plural); }
std::string npgettext_str(const std::string & context, std::string && msgid, std::string && msgid_plural, uint plural) const { return this->npgettext_str_impl(context, std::move(msgid), std::move(msgid_plural), plural); }

/***
* Get line numbers of messages
*/
Expand Down Expand Up @@ -409,7 +455,7 @@ class catalog {
}
for (auto & p : other.hashmap_) {
if (p.first.size()) { // don't copy over the header, keep our original header
insert_message(std::move(p.second));
this->insert_message(std::move(p.second));
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/spirit_po/catalog_metadata.hpp
Expand Up @@ -66,7 +66,7 @@ struct catalog_metadata {
}
};

#define DEFAULT_CHARSET "UTF-8"
#define SPIRIT_PO_DEFAULT_CHARSET "UTF-8"

template <typename Iterator>
struct content_type_grammar : qi::grammar<Iterator, std::string()> {
Expand All @@ -75,15 +75,15 @@ struct catalog_metadata {
using qi::lit;
using qi::omit;
using qi::skip;
main = skip(' ')[ omit[ *(qi::char_ - ';') >> lit(';') ] >> ((lit("charset=") >> *(qi::char_)) | qi::attr(DEFAULT_CHARSET)) ];
main = skip(' ')[ omit[ *(qi::char_ - ';') >> lit(';') ] >> ((lit("charset=") >> *(qi::char_)) | qi::attr(SPIRIT_PO_DEFAULT_CHARSET)) ];
}
};

public:
// nonempty return is an error mesage
std::string parse_header(const std::string & header) {
const char * default_charset = DEFAULT_CHARSET;
#undef DEFAULT_CHARSET
const char * const default_charset = SPIRIT_PO_DEFAULT_CHARSET;
#undef SPIRIT_PO_DEFAULT_CHARSET

project_id = find_header_line(header, "Project-Id-Version:");
language = find_header_line(header, "Language:");
Expand Down
6 changes: 3 additions & 3 deletions src/spirit_po/default_plural_forms_compiler.hpp
Expand Up @@ -83,8 +83,8 @@ class function_object {
boost::optional<std::string> parse_error_;

public:
function_object(const expr & _e) : machine_(_e), parse_error_() {}
function_object(const std::string & s) : machine_(n_var()), parse_error_(s) {}
explicit function_object(const expr & _e) : machine_(_e), parse_error_() {}
explicit function_object(const std::string & s) : machine_(constant{0}), parse_error_(s) {}
function_object() : function_object(std::string{"uninitialized"}) {}

uint operator()(uint n) const {
Expand Down Expand Up @@ -113,7 +113,7 @@ struct compiler {
}
};

} // end namespace default_plura_forms
} // end namespace default_plural_forms

} // end namespace spirit_po

Expand Down
2 changes: 1 addition & 1 deletion src/spirit_po/default_plural_forms_expressions.hpp
Expand Up @@ -126,7 +126,7 @@ FOREACH_SPIRIT_PO_CONJUNCTION(EVAL_OP_)
*/

BOOST_FUSION_ADAPT_STRUCT(spirit_po::default_plural_forms::constant,
(spirit_po::uint, value))
(unsigned int, value))
BOOST_FUSION_ADAPT_STRUCT(spirit_po::default_plural_forms::not_op,
(spirit_po::default_plural_forms::expr, e1))
BOOST_FUSION_ADAPT_STRUCT(spirit_po::default_plural_forms::ternary_op,
Expand Down
11 changes: 5 additions & 6 deletions src/spirit_po/exceptions.hpp
Expand Up @@ -6,7 +6,6 @@
#ifndef SPIRIT_PO_EXCEPTIONS_HPP_INCLUDED
#define SPIRIT_PO_EXCEPTIONS_HPP_INCLUDED

#include <spirit_po/default_plural_forms_expressions.hpp>
#include <boost/spirit/include/support_line_pos_iterator.hpp>
#include <string>

Expand Down Expand Up @@ -48,23 +47,23 @@ inline std::string string_iterator_context(const std::string & str,
} // end namespace spirit_po


#ifdef SPIRIT_PO_NOEXCEPT
#ifdef SPIRIT_PO_NO_EXCEPTIONS

#define SPIRIT_PO_CATALOG_FAIL(Message) \
do { \
error_message_ = (Message); \
return ; \
} while(0)

#else // SPIRIT_PO_NOEXCEPT
#else // SPIRIT_PO_NO_EXCEPTIONS

#include <stdexcept>

namespace spirit_po {

struct catalog_exception : std::runtime_error {
catalog_exception(const char * what) : runtime_error(what) {}
catalog_exception(const std::string & what) : runtime_error(what) {}
explicit catalog_exception(const char * what) : runtime_error(what) {}
explicit catalog_exception(const std::string & what) : runtime_error(what) {}
};

} // end namespace spirit_po
Expand All @@ -75,6 +74,6 @@ do { \
} while(0)


#endif // SPIRIT_PO_NOEXCEPT
#endif // SPIRIT_PO_NO_EXCEPTIONS

#endif // SPIRIT_PO_EXCEPTIONS_HPP_INCLUDED
4 changes: 2 additions & 2 deletions src/spirit_po/version.hpp
Expand Up @@ -7,7 +7,7 @@
#define SPIRIT_PO_VERSION_HPP_INCLUDED

#define SPIRIT_PO_VERSION_MAJOR 1
#define SPIRIT_PO_VERSION_MINOR 0
#define SPIRIT_PO_VERSION_PATCH 1
#define SPIRIT_PO_VERSION_MINOR 1
#define SPIRIT_PO_VERSION_PATCH 2

#endif // SPIRIT_PO_VERSION_HPP_INCLUDED

0 comments on commit e59dec9

Please sign in to comment.