Update bundled tinygettext
Remove unneeded files like gitignore and test and keep a simplified CMakeLists.txt
This commit is contained in:
parent
b84f8dcbd3
commit
842278ffd9
@ -261,6 +261,8 @@ endif()
|
||||
if(NOT SERVER_ONLY)
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/graphics_utils")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/graphics_utils")
|
||||
add_subdirectory("${PROJECT_SOURCE_DIR}/lib/tinygettext")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/tinygettext/include")
|
||||
endif()
|
||||
|
||||
# Libmcpp
|
||||
@ -646,7 +648,8 @@ if(NOT SERVER_ONLY)
|
||||
${HARFBUZZ_LIBRARY}
|
||||
${SDL2_LIBRARY}
|
||||
${SHEENBIDI_LIBRARY}
|
||||
graphics_utils)
|
||||
graphics_utils
|
||||
tinygettext)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
|
@ -157,6 +157,16 @@ include $(BUILD_STATIC_LIBRARY)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
|
||||
# tinygettext
|
||||
LOCAL_MODULE := tinygettext
|
||||
LOCAL_PATH := .
|
||||
LOCAL_CPP_FEATURES += rtti exceptions
|
||||
LOCAL_SRC_FILES := $(wildcard ../lib/tinygettext/src/*.cpp)
|
||||
LOCAL_CFLAGS := -I../lib/tinygettext/include
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
|
||||
# Irrlicht
|
||||
LOCAL_MODULE := irrlicht
|
||||
LOCAL_PATH := .
|
||||
@ -242,6 +252,7 @@ LOCAL_CFLAGS := -I../lib/angelscript/include \
|
||||
-I../lib/graphics_utils \
|
||||
-I../lib/mcpp \
|
||||
-I../lib/sdl2/include \
|
||||
-I../lib/tinygettext/include \
|
||||
-I../src \
|
||||
-Iobj/curl/include \
|
||||
-Iobj/freetype/include \
|
||||
@ -264,7 +275,8 @@ LOCAL_CPPFLAGS := -std=gnu++0x
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := irrlicht bullet enet ifaddrs angelscript mcpp SDL2 \
|
||||
vorbisfile vorbis ogg openal curl libssl libcrypto \
|
||||
c++_static sheenbidi harfbuzz freetype graphics_utils
|
||||
c++_static sheenbidi harfbuzz freetype \
|
||||
tinygettext graphics_utils
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
include $(CLEAR_VARS)
|
||||
|
95
lib/tinygettext/CMakeLists.txt
Normal file
95
lib/tinygettext/CMakeLists.txt
Normal file
@ -0,0 +1,95 @@
|
||||
# tinygettext - A gettext replacement that works directly on .po files
|
||||
# Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
|
||||
#
|
||||
# This software is provided 'as-is', without any express or implied
|
||||
# warranty. In no event will the authors be held liable for any damages
|
||||
# arising from the use of this software.
|
||||
#
|
||||
# Permission is granted to anyone to use this software for any purpose,
|
||||
# including commercial applications, and to alter it and redistribute it
|
||||
# freely, subject to the following restrictions:
|
||||
#
|
||||
# 1. The origin of this software must not be misrepresented; you must not
|
||||
# claim that you wrote the original software. If you use this software
|
||||
# in a product, an acknowledgement in the product documentation would be
|
||||
# appreciated but is not required.
|
||||
# 2. Altered source versions must be plainly marked as such, and must not be
|
||||
# misrepresented as being the original software.
|
||||
# 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#
|
||||
# INSTRUCTIONS:
|
||||
# -------------
|
||||
#
|
||||
# Create a directory build/ and change to it. Run
|
||||
#
|
||||
# cmake ..
|
||||
#
|
||||
# This creates a set of Makefiles to build the project. Run
|
||||
#
|
||||
# make
|
||||
#
|
||||
|
||||
cmake_policy(SET CMP0005 NEW)
|
||||
|
||||
## Project name to use as command prefix
|
||||
|
||||
project(tinygettext)
|
||||
set(VERSION "0.1.0")
|
||||
|
||||
### CMake configuration
|
||||
|
||||
cmake_minimum_required(VERSION 2.4)
|
||||
if(COMMAND cmake_policy)
|
||||
CMAKE_POLICY(SET CMP0003 NEW)
|
||||
endif(COMMAND cmake_policy)
|
||||
|
||||
## Reveal library type choice to users
|
||||
option(BUILD_SHARED_LIBS "Produce dynamic library instead of static archive" OFF)
|
||||
|
||||
## Add iconv to include directories
|
||||
|
||||
find_package(ICONV REQUIRED)
|
||||
include_directories(${ICONV_INCLUDE_DIR})
|
||||
|
||||
## Check iconv_const
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${ICONV_INCLUDE_DIR})
|
||||
check_cxx_source_compiles(
|
||||
"
|
||||
#include <iconv.h>
|
||||
// this declaration will fail when there already exists a non const char** version which returns size_t
|
||||
double iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
|
||||
int main() { return 0; }
|
||||
"
|
||||
HAVE_ICONV_CONST
|
||||
)
|
||||
|
||||
# TODO: better way of config
|
||||
|
||||
if(HAVE_ICONV_CONST)
|
||||
add_definitions(-DHAVE_ICONV_CONST)
|
||||
else(HAVE_ICONV_CONST)
|
||||
remove_definitions(-DHAVE_ICONV_CONST)
|
||||
endif(HAVE_ICONV_CONST)
|
||||
|
||||
## TinyGetText library compilation
|
||||
|
||||
## build list of source files
|
||||
|
||||
file(GLOB TINYGETTEXT_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/*.cpp)
|
||||
file(GLOB TINYGETTEXT_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} include/tinygettext/*.hpp)
|
||||
|
||||
## define a target for building the library
|
||||
|
||||
add_library(tinygettext ${TINYGETTEXT_SOURCES})
|
||||
|
||||
## Add tinygettext dir to search path
|
||||
|
||||
include_directories(include/)
|
||||
|
||||
add_definitions(-DVERSION=${VERSION})
|
||||
|
||||
# EOF #
|
34
lib/tinygettext/LICENSE.md
Normal file
34
lib/tinygettext/LICENSE.md
Normal file
@ -0,0 +1,34 @@
|
||||
tinygettext - A gettext replacement that works directly on .po files
|
||||
|
||||
Copyright (c) 2004-2016
|
||||
|
||||
* Bastiaan Zapf <bzapf@example.org>
|
||||
* Christoph Sommer <mail@christoph-sommer.de>
|
||||
* Georg Kilzer (leper) <leper@wildfiregames.com>
|
||||
* Ingo Ruhnke <grumbel@gmail.com>
|
||||
* Mathnerd314 <mathnerd314.gph@gmail.com>
|
||||
* Matt McCutchen <matt@mattmccutchen.net>
|
||||
* Matthias Braun <matze@braunis.de>
|
||||
* Nathan Phillip Brink <ohnobinki@ohnopublishing.net>
|
||||
* Poren Chiang <ren.chiang@gmail.com>
|
||||
* Ravu al Hemio <ondra.hosek@gmail.com>
|
||||
* Ryan Flegel <rflegel@gmail.com>
|
||||
* Tim Goya <tuxdev103@gmail.com>
|
||||
* Tobias Markus <tobbi.bugs@gmail.com>
|
||||
* Wolfgang Becker <uafr@gmx.de>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgement in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
@ -1,29 +1,29 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2006-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_DICTIONARY_HPP
|
||||
#define HEADER_TINYGETTEXT_DICTIONARY_HPP
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "plural_forms.hpp"
|
||||
|
||||
namespace tinygettext {
|
||||
@ -34,17 +34,17 @@ namespace tinygettext {
|
||||
class Dictionary
|
||||
{
|
||||
private:
|
||||
typedef std::map<std::string, std::vector<std::string> > Entries;
|
||||
typedef std::unordered_map<std::string, std::vector<std::string> > Entries;
|
||||
Entries entries;
|
||||
|
||||
typedef std::map<std::string, Entries> CtxtEntries;
|
||||
typedef std::unordered_map<std::string, Entries> CtxtEntries;
|
||||
CtxtEntries ctxt_entries;
|
||||
|
||||
std::string charset;
|
||||
PluralForms plural_forms;
|
||||
|
||||
std::string translate(const Entries& dict, const std::string& msgid);
|
||||
std::string translate_plural(const Entries& dict, const std::string& msgid, const std::string& msgidplural, int num);
|
||||
std::string translate(const Entries& dict, const std::string& msgid) const;
|
||||
std::string translate_plural(const Entries& dict, const std::string& msgid, const std::string& msgidplural, int num) const;
|
||||
|
||||
bool m_has_fallback;
|
||||
Dictionary* m_fallback;
|
||||
@ -62,21 +62,21 @@ public:
|
||||
|
||||
|
||||
/** Translate the string \a msgid. */
|
||||
std::string translate(const std::string& msgid);
|
||||
std::string translate(const std::string& msgid) const;
|
||||
|
||||
/** Translate the string \a msgid to its correct plural form, based
|
||||
on the number of items given by \a num. \a msgid_plural is \a msgid in
|
||||
plural form. */
|
||||
std::string translate_plural(const std::string& msgid, const std::string& msgidplural, int num);
|
||||
std::string translate_plural(const std::string& msgid, const std::string& msgidplural, int num) const;
|
||||
|
||||
/** Translate the string \a msgid that is in context \a msgctx. A
|
||||
context is a way to disambiguate msgids that contain the same
|
||||
letters, but different meaning. For example "exit" might mean to
|
||||
quit doing something or it might refer to a door that leads
|
||||
outside (i.e. 'Ausgang' vs 'Beenden' in german) */
|
||||
std::string translate_ctxt(const std::string& msgctxt, const std::string& msgid);
|
||||
std::string translate_ctxt(const std::string& msgctxt, const std::string& msgid) const;
|
||||
|
||||
std::string translate_ctxt_plural(const std::string& msgctxt, const std::string& msgid, const std::string& msgidplural, int num);
|
||||
std::string translate_ctxt_plural(const std::string& msgctxt, const std::string& msgid, const std::string& msgidplural, int num) const;
|
||||
|
||||
/** Add a translation from \a msgid to \a msgstr to the dictionary,
|
||||
where \a msgid is the singular form of the message, msgid_plural the
|
||||
@ -94,10 +94,6 @@ public:
|
||||
void add_translation(const std::string& msgid, const std::string& msgstr);
|
||||
void add_translation(const std::string& msgctxt, const std::string& msgid, const std::string& msgstr);
|
||||
|
||||
/** Write all unique character from current dictionary using in a c++ set which is useful for
|
||||
specific character loading. */
|
||||
std::set<wchar_t> get_all_used_chars();
|
||||
|
||||
/** Iterate over all messages, Func is of type:
|
||||
void func(const std::string& msgid, const std::vector<std::string>& msgstrs) */
|
||||
template<class Func>
|
||||
@ -130,6 +126,10 @@ public:
|
||||
}
|
||||
return func;
|
||||
}
|
||||
|
||||
private:
|
||||
Dictionary(const Dictionary&) = delete;
|
||||
Dictionary& operator=(const Dictionary&) = delete;
|
||||
};
|
||||
|
||||
} // namespace tinygettext
|
||||
@ -137,4 +137,3 @@ public:
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
#endif
|
@ -1,30 +1,30 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2006-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_DICTIONARY_MANAGER_HPP
|
||||
#define HEADER_TINYGETTEXT_DICTIONARY_MANAGER_HPP
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include <map>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "dictionary.hpp"
|
||||
#include "language.hpp"
|
||||
@ -39,11 +39,11 @@ class FileSystem;
|
||||
class DictionaryManager
|
||||
{
|
||||
private:
|
||||
typedef std::map<Language, Dictionary*> Dictionaries;
|
||||
typedef std::unordered_map<Language, Dictionary*, Language_hash> Dictionaries;
|
||||
Dictionaries dictionaries;
|
||||
|
||||
typedef std::vector<std::string> Search_Path;
|
||||
Search_Path search_path;
|
||||
typedef std::deque<std::string> SearchPath;
|
||||
SearchPath search_path;
|
||||
|
||||
std::string charset;
|
||||
bool use_fuzzy;
|
||||
@ -57,10 +57,6 @@ private:
|
||||
|
||||
void clear_cache();
|
||||
|
||||
#ifdef DEBUG
|
||||
unsigned int m_magic_number;
|
||||
#endif
|
||||
|
||||
public:
|
||||
DictionaryManager(const std::string& charset_ = "UTF-8");
|
||||
~DictionaryManager();
|
||||
@ -85,8 +81,12 @@ public:
|
||||
void set_charset(const std::string& charset);
|
||||
|
||||
/** Add a directory to the search path for dictionaries, earlier
|
||||
added directories have higher priority then later added ones */
|
||||
void add_directory(const std::string& pathname);
|
||||
added directories have higher priority then later added ones.
|
||||
Set @p precedence to true to invert this for a single addition. */
|
||||
void add_directory(const std::string& pathname, bool precedence = false);
|
||||
|
||||
/** Remove a directory from the search path */
|
||||
void remove_directory(const std::string& pathname);
|
||||
|
||||
/** Return a set of the available languages in their country code */
|
||||
std::set<Language> get_languages();
|
||||
@ -94,7 +94,6 @@ public:
|
||||
void set_filesystem(std::unique_ptr<FileSystem> filesystem);
|
||||
std::string convertFilename2Language(const std::string &s_in) const;
|
||||
|
||||
|
||||
private:
|
||||
DictionaryManager (const DictionaryManager&);
|
||||
DictionaryManager& operator= (const DictionaryManager&);
|
||||
@ -105,4 +104,3 @@ private:
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
#endif
|
44
lib/tinygettext/include/tinygettext/file_system.hpp
Normal file
44
lib/tinygettext/include/tinygettext/file_system.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2009 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_FILE_SYSTEM_HPP
|
||||
#define HEADER_TINYGETTEXT_FILE_SYSTEM_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
class FileSystem
|
||||
{
|
||||
public:
|
||||
virtual ~FileSystem() {}
|
||||
|
||||
virtual std::vector<std::string> open_directory(const std::string& pathname) =0;
|
||||
virtual std::unique_ptr<std::istream> open_file(const std::string& filename) =0;
|
||||
};
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
74
lib/tinygettext/include/tinygettext/iconv.hpp
Normal file
74
lib/tinygettext/include/tinygettext/iconv.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_ICONV_HPP
|
||||
#define HEADER_TINYGETTEXT_ICONV_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef HAVE_SDL
|
||||
# include "SDL.h"
|
||||
|
||||
# define tinygettext_ICONV_CONST const
|
||||
# define tinygettext_iconv_t SDL_iconv_t
|
||||
# define tinygettext_iconv SDL_iconv
|
||||
# define tinygettext_iconv_open SDL_iconv_open
|
||||
# define tinygettext_iconv_close SDL_iconv_close
|
||||
#else
|
||||
# include <iconv.h>
|
||||
|
||||
# ifdef HAVE_ICONV_CONST
|
||||
# define tinygettext_ICONV_CONST ICONV_CONST
|
||||
# else
|
||||
# define tinygettext_ICONV_CONST
|
||||
# endif
|
||||
|
||||
# define tinygettext_iconv_t iconv_t
|
||||
# define tinygettext_iconv iconv
|
||||
# define tinygettext_iconv_open iconv_open
|
||||
# define tinygettext_iconv_close iconv_close
|
||||
#endif
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
class IConv
|
||||
{
|
||||
private:
|
||||
std::string to_charset;
|
||||
std::string from_charset;
|
||||
tinygettext_iconv_t cd;
|
||||
|
||||
public:
|
||||
IConv();
|
||||
IConv(const std::string& fromcode, const std::string& tocode);
|
||||
~IConv();
|
||||
|
||||
void set_charsets(const std::string& fromcode, const std::string& tocode);
|
||||
std::string convert(const std::string& text);
|
||||
|
||||
private:
|
||||
IConv (const IConv&);
|
||||
IConv& operator= (const IConv&);
|
||||
};
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
@ -1,26 +1,27 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2006-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_LANGUAGE_HPP
|
||||
#define HEADER_TINYGETTEXT_LANGUAGE_HPP
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
@ -49,7 +50,7 @@ public:
|
||||
/** Create a language from an environment variable style string (e.g de_DE.UTF-8@modifier) */
|
||||
static Language from_env(const std::string& env);
|
||||
|
||||
/** Compares two Languages, returns 0 on mismatch and a score
|
||||
/** Compares two Languages, returns 0 on missmatch and a score
|
||||
between 1 and 9 on match, the higher the score the better the
|
||||
match */
|
||||
static int match(const Language& lhs, const Language& rhs);
|
||||
@ -57,7 +58,7 @@ public:
|
||||
/** Create an undefined Language object */
|
||||
Language();
|
||||
|
||||
operator bool() const { return language_spec!=NULL; }
|
||||
explicit operator bool() const { return language_spec != NULL; }
|
||||
|
||||
/** Returns the language code (i.e. de, en, fr) */
|
||||
std::string get_language() const;
|
||||
@ -76,20 +77,27 @@ public:
|
||||
variable: {language}_{country}@{modifier} */
|
||||
std::string str() const;
|
||||
|
||||
bool operator==(const Language& rhs);
|
||||
bool operator!=(const Language& rhs);
|
||||
bool operator==(const Language& rhs) const;
|
||||
bool operator!=(const Language& rhs) const;
|
||||
|
||||
friend bool operator<(const Language& lhs, const Language& rhs);
|
||||
friend struct Language_hash;
|
||||
};
|
||||
|
||||
inline bool operator<(const Language& lhs, const Language& rhs) {
|
||||
return lhs.language_spec < rhs.language_spec;
|
||||
}
|
||||
|
||||
struct Language_hash
|
||||
{
|
||||
size_t operator()(const Language& v) const
|
||||
{
|
||||
return reinterpret_cast<size_t>(v.language_spec);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
||||
#endif
|
58
lib/tinygettext/include/tinygettext/log.hpp
Normal file
58
lib/tinygettext/include/tinygettext/log.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2009 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_LOG_HPP
|
||||
#define HEADER_TINYGETTEXT_LOG_HPP
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
class Log
|
||||
{
|
||||
public:
|
||||
typedef void (*log_callback_t)(const std::string&);
|
||||
|
||||
static log_callback_t log_info_callback;
|
||||
static log_callback_t log_warning_callback;
|
||||
static log_callback_t log_error_callback;
|
||||
|
||||
|
||||
static void default_log_callback(const std::string& str);
|
||||
|
||||
static void set_log_info_callback(log_callback_t callback);
|
||||
static void set_log_warning_callback(log_callback_t callback);
|
||||
static void set_log_error_callback(log_callback_t callback);
|
||||
|
||||
private:
|
||||
log_callback_t callback;
|
||||
std::ostringstream out;
|
||||
|
||||
public:
|
||||
Log(log_callback_t callback);
|
||||
~Log();
|
||||
|
||||
std::ostream& get();
|
||||
};
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
36
lib/tinygettext/include/tinygettext/log_stream.hpp
Normal file
36
lib/tinygettext/include/tinygettext/log_stream.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2009 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_LOG_STREAM_HPP
|
||||
#define HEADER_TINYGETTEXT_LOG_STREAM_HPP
|
||||
|
||||
#include "log.hpp"
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
// FIXME: very bad to have such things in the API
|
||||
#define log_error if (!Log::log_error_callback); else (Log(Log::log_error_callback)).get()
|
||||
#define log_warning if (!Log::log_warning_callback); else (Log(Log::log_warning_callback)).get()
|
||||
#define log_info if (!Log::log_info_callback); else (Log(Log::log_warning_callback)).get()
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
63
lib/tinygettext/include/tinygettext/plural_forms.hpp
Normal file
63
lib/tinygettext/include/tinygettext/plural_forms.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_PLURAL_FORMS_HPP
|
||||
#define HEADER_TINYGETTEXT_PLURAL_FORMS_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
typedef unsigned int (*PluralFunc)(int n);
|
||||
|
||||
class PluralForms
|
||||
{
|
||||
private:
|
||||
unsigned int nplural;
|
||||
PluralFunc plural;
|
||||
|
||||
public:
|
||||
static PluralForms from_string(const std::string& str);
|
||||
|
||||
PluralForms()
|
||||
: nplural(0),
|
||||
plural(0)
|
||||
{}
|
||||
|
||||
PluralForms(unsigned int nplural_, PluralFunc plural_)
|
||||
: nplural(nplural_),
|
||||
plural(plural_)
|
||||
{}
|
||||
|
||||
unsigned int get_nplural() const { return nplural; }
|
||||
unsigned int get_plural(int n) const { if (plural) return plural(n); else return 0; }
|
||||
|
||||
bool operator==(const PluralForms& other) const { return nplural == other.nplural && plural == other.plural; }
|
||||
bool operator!=(const PluralForms& other) const { return !(*this == other); }
|
||||
|
||||
explicit operator bool() const {
|
||||
return plural != NULL;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
@ -1,27 +1,28 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2009-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2009 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_PO_PARSER_HPP
|
||||
#define HEADER_TINYGETTEXT_PO_PARSER_HPP
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#include "iconv.hpp"
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
@ -42,7 +43,7 @@ private:
|
||||
int line_number;
|
||||
std::string current_line;
|
||||
|
||||
//IConv conv;
|
||||
IConv conv;
|
||||
|
||||
POParser(const std::string& filename, std::istream& in_, Dictionary& dict_, bool use_fuzzy = true);
|
||||
~POParser();
|
||||
@ -51,10 +52,10 @@ private:
|
||||
void parse();
|
||||
void next_line();
|
||||
std::string get_string(unsigned int skip);
|
||||
void get_string_line(std::ostringstream& str,unsigned int skip);
|
||||
void get_string_line(std::ostringstream& str, size_t skip);
|
||||
bool is_empty_line();
|
||||
bool prefix(const char* );
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
void error(const std::string& msg);
|
||||
#else
|
||||
void error(const std::string& msg) __attribute__((__noreturn__));
|
||||
@ -78,4 +79,3 @@ private:
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
#endif
|
29
lib/tinygettext/include/tinygettext/tinygettext.hpp
Normal file
29
lib/tinygettext/include/tinygettext/tinygettext.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_TINYGETTEXT_HPP
|
||||
#define HEADER_TINYGETTEXT_TINYGETTEXT_HPP
|
||||
|
||||
#include "dictionary.hpp"
|
||||
#include "dictionary_manager.hpp"
|
||||
#include "language.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
40
lib/tinygettext/include/tinygettext/unix_file_system.hpp
Normal file
40
lib/tinygettext/include/tinygettext/unix_file_system.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2009 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_UNIX_FILE_SYSTEM_HPP
|
||||
#define HEADER_TINYGETTEXT_UNIX_FILE_SYSTEM_HPP
|
||||
|
||||
#include "file_system.hpp"
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
class UnixFileSystem : public FileSystem
|
||||
{
|
||||
public:
|
||||
UnixFileSystem();
|
||||
|
||||
std::vector<std::string> open_directory(const std::string& pathname);
|
||||
std::unique_ptr<std::istream> open_file(const std::string& filename);
|
||||
};
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
246
lib/tinygettext/src/dictionary.cpp
Normal file
246
lib/tinygettext/src/dictionary.cpp
Normal file
@ -0,0 +1,246 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "tinygettext/log_stream.hpp"
|
||||
#include "tinygettext/dictionary.hpp"
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
namespace {
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const std::vector<std::string>& v)
|
||||
{
|
||||
for (std::vector<std::string>::const_iterator it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
if (it != v.begin())
|
||||
o << ", ";
|
||||
o << "'" << *it << "'";
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Dictionary::Dictionary(const std::string& charset_) :
|
||||
entries(),
|
||||
ctxt_entries(),
|
||||
charset(charset_),
|
||||
plural_forms(),
|
||||
m_has_fallback(false),
|
||||
m_fallback()
|
||||
{
|
||||
}
|
||||
|
||||
Dictionary::~Dictionary()
|
||||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::get_charset() const
|
||||
{
|
||||
return charset;
|
||||
}
|
||||
|
||||
void
|
||||
Dictionary::set_plural_forms(const PluralForms& plural_forms_)
|
||||
{
|
||||
plural_forms = plural_forms_;
|
||||
}
|
||||
|
||||
PluralForms
|
||||
Dictionary::get_plural_forms() const
|
||||
{
|
||||
return plural_forms;
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::translate_plural(const std::string& msgid, const std::string& msgid_plural, int num) const
|
||||
{
|
||||
return translate_plural(entries, msgid, msgid_plural, num);
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::translate_plural(const Entries& dict, const std::string& msgid, const std::string& msgid_plural, int count) const
|
||||
{
|
||||
Entries::const_iterator it = dict.find(msgid);
|
||||
if (it != dict.end())
|
||||
{
|
||||
unsigned int n = plural_forms.get_plural(count);
|
||||
const std::vector<std::string>& msgstrs = it->second;
|
||||
if (n >= msgstrs.size())
|
||||
{
|
||||
log_error << "Plural translation not available (and not set to empty): '" << msgid << "'" << std::endl;
|
||||
log_error << "Missing plural form: " << n << std::endl;
|
||||
return msgid;
|
||||
}
|
||||
|
||||
if (!msgstrs[n].empty())
|
||||
return msgstrs[n];
|
||||
else
|
||||
if (count == 1) // default to english rules
|
||||
return msgid;
|
||||
else
|
||||
return msgid_plural;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info << "Couldn't translate: " << msgid << std::endl;
|
||||
log_info << "Candidates: " << std::endl;
|
||||
for (it = dict.begin(); it != dict.end(); ++it)
|
||||
log_info << "'" << it->first << "'" << std::endl;
|
||||
|
||||
if (count == 1) // default to english rules
|
||||
return msgid;
|
||||
else
|
||||
return msgid_plural;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::translate(const std::string& msgid) const
|
||||
{
|
||||
return translate(entries, msgid);
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::translate(const Entries& dict, const std::string& msgid) const
|
||||
{
|
||||
Entries::const_iterator i = dict.find(msgid);
|
||||
if (i != dict.end() && !i->second.empty())
|
||||
{
|
||||
return i->second[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info << "Couldn't translate: " << msgid << std::endl;
|
||||
|
||||
if (m_has_fallback) return m_fallback->translate(msgid);
|
||||
else return msgid;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::translate_ctxt(const std::string& msgctxt, const std::string& msgid) const
|
||||
{
|
||||
CtxtEntries::const_iterator i = ctxt_entries.find(msgctxt);
|
||||
if (i != ctxt_entries.end())
|
||||
{
|
||||
return translate(i->second, msgid);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info << "Couldn't translate: " << msgid << std::endl;
|
||||
return msgid;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::translate_ctxt_plural(const std::string& msgctxt,
|
||||
const std::string& msgid, const std::string& msgidplural, int num) const
|
||||
{
|
||||
CtxtEntries::const_iterator i = ctxt_entries.find(msgctxt);
|
||||
if (i != ctxt_entries.end())
|
||||
{
|
||||
return translate_plural(i->second, msgid, msgidplural, num);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info << "Couldn't translate: " << msgid << std::endl;
|
||||
if (num != 1) // default to english
|
||||
return msgidplural;
|
||||
else
|
||||
return msgid;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Dictionary::add_translation(const std::string& msgid, const std::string& msgid_plural,
|
||||
const std::vector<std::string>& msgstrs)
|
||||
{
|
||||
std::vector<std::string>& vec = entries[msgid];
|
||||
if (vec.empty())
|
||||
{
|
||||
vec = msgstrs;
|
||||
}
|
||||
else if (vec != msgstrs)
|
||||
{
|
||||
log_warning << "collision in add_translation: '"
|
||||
<< msgid << "', '" << msgid_plural
|
||||
<< "' -> [" << vec << "] vs [" << msgstrs << "]" << std::endl;
|
||||
vec = msgstrs;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Dictionary::add_translation(const std::string& msgid, const std::string& msgstr)
|
||||
{
|
||||
std::vector<std::string>& vec = entries[msgid];
|
||||
if (vec.empty())
|
||||
{
|
||||
vec.push_back(msgstr);
|
||||
}
|
||||
else if (vec[0] != msgstr)
|
||||
{
|
||||
log_warning << "collision in add_translation: '"
|
||||
<< msgid << "' -> '" << msgstr << "' vs '" << vec[0] << "'" << std::endl;
|
||||
vec[0] = msgstr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Dictionary::add_translation(const std::string& msgctxt,
|
||||
const std::string& msgid, const std::string& msgid_plural,
|
||||
const std::vector<std::string>& msgstrs)
|
||||
{
|
||||
std::vector<std::string>& vec = ctxt_entries[msgctxt][msgid];
|
||||
if (vec.empty())
|
||||
{
|
||||
vec = msgstrs;
|
||||
}
|
||||
else if (vec != msgstrs)
|
||||
{
|
||||
log_warning << "collision in add_translation: '"
|
||||
<< msgctxt << "', '" << msgid << "', '" << msgid_plural
|
||||
<< "' -> [" << vec << "] vs [" << msgstrs << "]" << std::endl;
|
||||
vec = msgstrs;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Dictionary::add_translation(const std::string& msgctxt, const std::string& msgid, const std::string& msgstr)
|
||||
{
|
||||
std::vector<std::string>& vec = ctxt_entries[msgctxt][msgid];
|
||||
if (vec.empty())
|
||||
{
|
||||
vec.push_back(msgstr);
|
||||
}
|
||||
else if (vec[0] != msgstr)
|
||||
{
|
||||
log_warning << "collision in add_translation: '"
|
||||
<< msgctxt << "', '" << msgid
|
||||
<< "' -> '" << vec[0] << "' vs '" << msgstr << "'" << std::endl;
|
||||
vec[0] = msgstr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
/* EOF */
|
@ -1,25 +1,23 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2006-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include "dictionary_manager.hpp"
|
||||
|
||||
#include "utils/log.hpp"
|
||||
#include "tinygettext/dictionary_manager.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <assert.h>
|
||||
@ -28,12 +26,13 @@
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "po_parser.hpp"
|
||||
#include "stk_file_system.hpp"
|
||||
#include "tinygettext/log_stream.hpp"
|
||||
#include "tinygettext/po_parser.hpp"
|
||||
#include "tinygettext/unix_file_system.hpp"
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
static bool has_suffix(const std::string& lhs, const std::string &rhs)
|
||||
static bool has_suffix(const std::string& lhs, const std::string& rhs)
|
||||
{
|
||||
if (lhs.length() < rhs.length())
|
||||
return false;
|
||||
@ -49,19 +48,12 @@ DictionaryManager::DictionaryManager(const std::string& charset_) :
|
||||
current_language(),
|
||||
current_dict(0),
|
||||
empty_dict(),
|
||||
filesystem(new StkFileSystem)
|
||||
filesystem(new UnixFileSystem)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
m_magic_number = 0xD1C70471;
|
||||
#endif
|
||||
}
|
||||
|
||||
DictionaryManager::~DictionaryManager()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
assert(m_magic_number == 0xD1C70471);
|
||||
m_magic_number = 0xDEADBEEF;
|
||||
#endif
|
||||
for(Dictionaries::iterator i = dictionaries.begin(); i != dictionaries.end(); ++i)
|
||||
{
|
||||
delete i->second;
|
||||
@ -120,14 +112,14 @@ DictionaryManager::get_dictionary(const Language& language)
|
||||
|
||||
dictionaries[language] = dict;
|
||||
|
||||
for (Search_Path::reverse_iterator p = search_path.rbegin(); p != search_path.rend(); ++p)
|
||||
for (SearchPath::reverse_iterator p = search_path.rbegin(); p != search_path.rend(); ++p)
|
||||
{
|
||||
std::vector<std::string> files = filesystem->open_directory(*p);
|
||||
|
||||
std::string best_filename = "";
|
||||
std::string best_filename;
|
||||
int best_score = 0;
|
||||
|
||||
for(std::vector<std::string>::iterator filename = files.begin(); filename != files.end(); filename++)
|
||||
for (std::vector<std::string>::iterator filename = files.begin(); filename != files.end(); ++filename)
|
||||
{
|
||||
// check if filename matches requested language
|
||||
if (has_suffix(*filename, ".po"))
|
||||
@ -137,8 +129,7 @@ DictionaryManager::get_dictionary(const Language& language)
|
||||
|
||||
if (!po_language)
|
||||
{
|
||||
Log::warn("tinygettext", "%s: warning: ignoring, unknown language",
|
||||
filename->c_str());
|
||||
log_warning << *filename << ": warning: ignoring, unknown language" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -161,8 +152,7 @@ DictionaryManager::get_dictionary(const Language& language)
|
||||
std::unique_ptr<std::istream> in = filesystem->open_file(pofile);
|
||||
if (!in.get())
|
||||
{
|
||||
Log::error("tinygettext", "error: failure opening: '%s'.",
|
||||
pofile.c_str());
|
||||
log_error << "error: failure opening: " << pofile << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -171,15 +161,15 @@ DictionaryManager::get_dictionary(const Language& language)
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
Log::error("tinygettext", "error: failure parsing: '%s'.", pofile.c_str());
|
||||
Log::error("tinygettext", "%s", e.what());
|
||||
log_error << "error: failure parsing: " << pofile << std::endl;
|
||||
log_error << e.what() << "" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (language.get_country().size() > 0)
|
||||
if (!language.get_country().empty())
|
||||
{
|
||||
Log::info("tinygettext", "Adding language fallback %s\n", language.get_language().c_str());
|
||||
// printf("Adding language fallback %s\n", language.get_language().c_str());
|
||||
dict->addFallback( &get_dictionary(Language::from_spec(language.get_language())) );
|
||||
}
|
||||
return *dict;
|
||||
@ -191,7 +181,7 @@ DictionaryManager::get_languages()
|
||||
{
|
||||
std::set<Language> languages;
|
||||
|
||||
for (Search_Path::iterator p = search_path.begin(); p != search_path.end(); ++p)
|
||||
for (SearchPath::iterator p = search_path.begin(); p != search_path.end(); ++p)
|
||||
{
|
||||
std::vector<std::string> files = filesystem->open_directory(*p);
|
||||
|
||||
@ -199,12 +189,7 @@ DictionaryManager::get_languages()
|
||||
{
|
||||
if (has_suffix(*file, ".po"))
|
||||
{
|
||||
Language po_language = Language::from_env(file->substr(0, file->size()-3));
|
||||
|
||||
if (po_language)
|
||||
{
|
||||
languages.insert(po_language);
|
||||
}
|
||||
languages.insert(Language::from_env(file->substr(0, file->size()-3)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -248,10 +233,24 @@ DictionaryManager::get_use_fuzzy() const
|
||||
}
|
||||
|
||||
void
|
||||
DictionaryManager::add_directory(const std::string& pathname)
|
||||
DictionaryManager::add_directory(const std::string& pathname, bool precedence /* = false */)
|
||||
{
|
||||
clear_cache(); // adding directories invalidates cache
|
||||
search_path.push_back(pathname);
|
||||
if (precedence)
|
||||
search_path.push_front(pathname);
|
||||
else
|
||||
search_path.push_back(pathname);
|
||||
}
|
||||
|
||||
void
|
||||
DictionaryManager::remove_directory(const std::string& pathname)
|
||||
{
|
||||
SearchPath::iterator it = std::find(search_path.begin(), search_path.end(), pathname);
|
||||
if (it != search_path.end())
|
||||
{
|
||||
clear_cache(); // removing directories invalidates cache
|
||||
search_path.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -286,7 +285,7 @@ std::string DictionaryManager::convertFilename2Language(const std::string &s_in)
|
||||
// of filename.
|
||||
if(!::isalpha(s[i]))
|
||||
break;
|
||||
s[i]=::toupper(s[i]);
|
||||
s[i] = static_cast<char>(::toupper(s[i]));
|
||||
}
|
||||
else
|
||||
underscore_found = s[i]=='_';
|
||||
@ -299,4 +298,3 @@ std::string DictionaryManager::convertFilename2Language(const std::string &s_in)
|
||||
|
||||
|
||||
/* EOF */
|
||||
#endif
|
150
lib/tinygettext/src/iconv.cpp
Normal file
150
lib/tinygettext/src/iconv.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2009 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <sstream>
|
||||
#include <errno.h>
|
||||
#include <stdexcept>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "tinygettext/iconv.hpp"
|
||||
#include "tinygettext/log_stream.hpp"
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
#ifndef tinygettext_ICONV_CONST
|
||||
# define tinygettext_ICONV_CONST
|
||||
#endif
|
||||
|
||||
IConv::IConv()
|
||||
: to_charset(),
|
||||
from_charset(),
|
||||
cd(0)
|
||||
{}
|
||||
|
||||
IConv::IConv(const std::string& from_charset_, const std::string& to_charset_)
|
||||
: to_charset(),
|
||||
from_charset(),
|
||||
cd(0)
|
||||
{
|
||||
set_charsets(from_charset_, to_charset_);
|
||||
}
|
||||
|
||||
IConv::~IConv()
|
||||
{
|
||||
if (cd)
|
||||
tinygettext_iconv_close(cd);
|
||||
}
|
||||
|
||||
void
|
||||
IConv::set_charsets(const std::string& from_charset_, const std::string& to_charset_)
|
||||
{
|
||||
if (cd)
|
||||
tinygettext_iconv_close(cd);
|
||||
|
||||
from_charset = from_charset_;
|
||||
to_charset = to_charset_;
|
||||
|
||||
for(std::string::iterator i = to_charset.begin(); i != to_charset.end(); ++i)
|
||||
*i = static_cast<char>(toupper(*i));
|
||||
|
||||
for(std::string::iterator i = from_charset.begin(); i != from_charset.end(); ++i)
|
||||
*i = static_cast<char>(toupper(*i));
|
||||
|
||||
if (to_charset == from_charset)
|
||||
{
|
||||
cd = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cd = tinygettext_iconv_open(to_charset.c_str(), from_charset.c_str());
|
||||
if (cd == reinterpret_cast<tinygettext_iconv_t>(-1))
|
||||
{
|
||||
if(errno == EINVAL)
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << "IConv construction failed: conversion from '" << from_charset
|
||||
<< "' to '" << to_charset << "' not available";
|
||||
throw std::runtime_error(str.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << "IConv: construction failed: " << strerror(errno);
|
||||
throw std::runtime_error(str.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a string from encoding to another.
|
||||
std::string
|
||||
IConv::convert(const std::string& text)
|
||||
{
|
||||
if (!cd)
|
||||
{
|
||||
return text;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inbytesleft = text.size();
|
||||
size_t outbytesleft = 4*inbytesleft; // Worst case scenario: ASCII -> UTF-32?
|
||||
|
||||
// We try to avoid to much copying around, so we write directly into
|
||||
// a std::string
|
||||
tinygettext_ICONV_CONST char* inbuf = const_cast<char*>(&text[0]);
|
||||
std::string result(outbytesleft, 'X');
|
||||
char* outbuf = &result[0];
|
||||
|
||||
// Try to convert the text.
|
||||
size_t ret = tinygettext_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
|
||||
if (ret == static_cast<size_t>(-1))
|
||||
{
|
||||
if (errno == EILSEQ || errno == EINVAL)
|
||||
{ // invalid multibyte sequence
|
||||
tinygettext_iconv(cd, NULL, NULL, NULL, NULL); // reset state
|
||||
|
||||
// FIXME: Could try to skip the invalid byte and continue
|
||||
log_error << "error: tinygettext:iconv: invalid multibyte sequence in: \"" << text << "\"" << std::endl;
|
||||
}
|
||||
else if (errno == E2BIG)
|
||||
{ // output buffer to small
|
||||
assert(false && "tinygettext/iconv.cpp: E2BIG: This should never be reached");
|
||||
}
|
||||
else if (errno == EBADF)
|
||||
{
|
||||
assert(false && "tinygettext/iconv.cpp: EBADF: This should never be reached");
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false && "tinygettext/iconv.cpp: <unknown>: This should never be reached");
|
||||
}
|
||||
}
|
||||
|
||||
result.resize(4*text.size() - outbytesleft);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
/* EOF */
|
@ -1,28 +1,26 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2006-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
#include "tinygettext/language.hpp"
|
||||
|
||||
#include "language.hpp"
|
||||
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <assert.h>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
@ -76,6 +74,7 @@ static const LanguageSpec languages[] = {
|
||||
{ "ca", "ES", 0, "Catalan (Spain)" },
|
||||
{ "ca", 0, "valencia", "Catalan (valencia)" },
|
||||
{ "ca", 0, 0, "Catalan" },
|
||||
{ "cmn", 0, 0, "Mandarin" },
|
||||
{ "co", 0, 0, "Corsican" },
|
||||
{ "cs", 0, 0, "Czech" },
|
||||
{ "cs", "CZ", 0, "Czech (Czech Republic)" },
|
||||
@ -166,7 +165,6 @@ static const LanguageSpec languages[] = {
|
||||
{ "iu", 0, 0, "Inuktitut" },
|
||||
{ "ja", 0, 0, "Japanese" },
|
||||
{ "ja", "JP", 0, "Japanese (Japan)" },
|
||||
{ "jbo",0, 0, "Lojban" },
|
||||
{ "ka", 0, 0, "Georgian" },
|
||||
{ "kk", 0, 0, "Kazakh" },
|
||||
{ "kl", 0, 0, "Kalaallisut" },
|
||||
@ -175,7 +173,6 @@ static const LanguageSpec languages[] = {
|
||||
{ "kn", 0, 0, "Kannada" },
|
||||
{ "ko", 0, 0, "Korean" },
|
||||
{ "ko", "KR", 0, "Korean (Korea)" },
|
||||
{ "krl",0, 0, "Karelian" },
|
||||
{ "ku", 0, 0, "Kurdish" },
|
||||
{ "kw", 0, 0, "Cornish" },
|
||||
{ "ky", 0, 0, "Kirghiz" },
|
||||
@ -185,13 +182,13 @@ static const LanguageSpec languages[] = {
|
||||
{ "lt", "LT", 0, "Lithuanian (Lithuania)" },
|
||||
{ "lv", 0, 0, "Latvian" },
|
||||
{ "lv", "LV", 0, "Latvian (Latvia)" },
|
||||
{ "jbo", 0, 0, "Lojban" },
|
||||
{ "mg", 0, 0, "Malagasy" },
|
||||
{ "mi", 0, 0, "Maori" },
|
||||
{ "mk", 0, 0, "Macedonian" },
|
||||
{ "mk", "MK", 0, "Macedonian (Macedonia)" },
|
||||
{ "ml", 0, 0, "Malayalam" },
|
||||
{ "mn", 0, 0, "Mongolian" },
|
||||
{ "mn", "MN", 0, "Mongolian (Mongolia)" },
|
||||
{ "mr", 0, 0, "Marathi" },
|
||||
{ "ms", 0, 0, "Malay" },
|
||||
{ "ms", "MY", 0, "Malay (Malaysia)" },
|
||||
@ -206,19 +203,16 @@ static const LanguageSpec languages[] = {
|
||||
{ "nl", "NL", 0, "Dutch (Netherlands)" },
|
||||
{ "nn", 0, 0, "Norwegian Nynorsk" },
|
||||
{ "nn", "NO", 0, "Norwegian Nynorsk (Norway)" },
|
||||
// DEPRECATED
|
||||
//{ "no", 0, 0, "Norwegian" },
|
||||
//{ "no", "NO", 0, "Norwegian (Norway)" },
|
||||
//{ "no", "NY", 0, "Norwegian (NY)" },
|
||||
{ "no", 0, 0, "Norwegian" },
|
||||
{ "no", "NO", 0, "Norwegian (Norway)" },
|
||||
{ "no", "NY", 0, "Norwegian (NY)" },
|
||||
{ "nr", 0, 0, "Ndebele, South" },
|
||||
{ "oc", 0, 0, "Occitan post 1500" },
|
||||
{ "om", 0, 0, "Oromo" },
|
||||
{ "or", 0, 0, "Oriya" },
|
||||
{ "os", 0, 0, "Ossetian" },
|
||||
{ "pa", 0, 0, "Punjabi" },
|
||||
{ "pl", 0, 0, "Polish" },
|
||||
{ "pl", "PL", 0, "Polish (Poland)" },
|
||||
{ "pms",0, 0, "Piedmontese" },
|
||||
{ "ps", 0, 0, "Pashto" },
|
||||
{ "pt", 0, 0, "Portuguese" },
|
||||
{ "pt", "BR", 0, "Portuguese (Brazil)" },
|
||||
@ -231,8 +225,6 @@ static const LanguageSpec languages[] = {
|
||||
{ "ru", "RU", 0, "Russian (Russia" },
|
||||
{ "rw", 0, 0, "Kinyarwanda" },
|
||||
{ "sa", 0, 0, "Sanskrit" },
|
||||
{ "sc", 0, 0, "Sardinian" },
|
||||
{ "sco",0, 0, "Scots" },
|
||||
{ "sd", 0, 0, "Sindhi" },
|
||||
{ "se", 0, 0, "Sami" },
|
||||
{ "se", "NO", 0, "Sami (Norway)" },
|
||||
@ -258,7 +250,6 @@ static const LanguageSpec languages[] = {
|
||||
{ "sv", "SE", 0, "Swedish (Sweden)" },
|
||||
{ "sv", "SV", 0, "Swedish (El Salvador)" },
|
||||
{ "sw", 0, 0, "Swahili" },
|
||||
{ "szl", 0, 0, "Silesian" },
|
||||
{ "ta", 0, 0, "Tamil" },
|
||||
{ "te", 0, 0, "Telugu" },
|
||||
{ "tg", 0, 0, "Tajik" },
|
||||
@ -295,10 +286,12 @@ static const LanguageSpec languages[] = {
|
||||
};
|
||||
//*}
|
||||
|
||||
namespace {
|
||||
|
||||
std::string
|
||||
resolve_language_alias(const std::string& name)
|
||||
{
|
||||
typedef std::map<std::string, std::string> Aliases;
|
||||
typedef std::unordered_map<std::string, std::string> Aliases;
|
||||
static Aliases language_aliases;
|
||||
if (language_aliases.empty())
|
||||
{
|
||||
@ -373,10 +366,13 @@ resolve_language_alias(const std::string& name)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Language
|
||||
Language::from_spec(const std::string& language, const std::string& country, const std::string& modifier)
|
||||
{
|
||||
static std::map<std::string, std::vector<const LanguageSpec*> > language_map;
|
||||
typedef std::unordered_map<std::string, std::vector<const LanguageSpec*> > LanguageSpecMap;
|
||||
static LanguageSpecMap language_map;
|
||||
|
||||
if (language_map.empty())
|
||||
{ // Init language_map
|
||||
@ -384,7 +380,7 @@ Language::from_spec(const std::string& language, const std::string& country, con
|
||||
language_map[languages[i].language].push_back(&languages[i]);
|
||||
}
|
||||
|
||||
std::map<std::string, std::vector<const LanguageSpec*> >::iterator i = language_map.find(language);
|
||||
LanguageSpecMap::iterator i = language_map.find(language);
|
||||
if (i != language_map.end())
|
||||
{
|
||||
std::vector<const LanguageSpec*>& lst = i->second;
|
||||
@ -441,9 +437,7 @@ Language::from_env(const std::string& env)
|
||||
|
||||
if (ln != std::string::npos && ln+1 < env.size()) // _
|
||||
{
|
||||
country = env.substr(ln+1, (std::min(dt, at) == std::string::npos)
|
||||
? std::string::npos : std::min(dt, at) - (ln+1));
|
||||
country = StringUtils::toUpperCase(country);
|
||||
country = env.substr(ln+1, (std::min(dt, at) == std::string::npos) ? std::string::npos : std::min(dt, at) - (ln+1));
|
||||
}
|
||||
|
||||
if (dt != std::string::npos && dt+1 < env.size()) // .
|
||||
@ -568,13 +562,13 @@ Language::str() const
|
||||
}
|
||||
|
||||
bool
|
||||
Language::operator==(const Language& rhs)
|
||||
Language::operator==(const Language& rhs) const
|
||||
{
|
||||
return language_spec == rhs.language_spec;
|
||||
}
|
||||
|
||||
bool
|
||||
Language::operator!=(const Language& rhs)
|
||||
Language::operator!=(const Language& rhs) const
|
||||
{
|
||||
return language_spec != rhs.language_spec;
|
||||
}
|
||||
@ -582,5 +576,3 @@ Language::operator!=(const Language& rhs)
|
||||
} // namespace tinygettext
|
||||
|
||||
/* EOF */
|
||||
|
||||
#endif
|
72
lib/tinygettext/src/log.cpp
Normal file
72
lib/tinygettext/src/log.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2009 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#include <iostream>
|
||||
#include "tinygettext/log.hpp"
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
Log::log_callback_t Log::log_info_callback = &Log::default_log_callback;
|
||||
Log::log_callback_t Log::log_warning_callback = &Log::default_log_callback;
|
||||
Log::log_callback_t Log::log_error_callback = &Log::default_log_callback;
|
||||
|
||||
void
|
||||
Log::default_log_callback(const std::string& str)
|
||||
{
|
||||
std::cerr << "tinygettext: " << str;
|
||||
}
|
||||
|
||||
void
|
||||
Log::set_log_info_callback(log_callback_t callback)
|
||||
{
|
||||
log_info_callback = callback;
|
||||
}
|
||||
|
||||
void
|
||||
Log::set_log_warning_callback(log_callback_t callback)
|
||||
{
|
||||
log_warning_callback = callback;
|
||||
}
|
||||
|
||||
void
|
||||
Log::set_log_error_callback(log_callback_t callback)
|
||||
{
|
||||
log_error_callback = callback;
|
||||
}
|
||||
|
||||
Log::Log(log_callback_t callback_) :
|
||||
callback(callback_),
|
||||
out()
|
||||
{
|
||||
}
|
||||
|
||||
Log::~Log()
|
||||
{
|
||||
callback(out.str());
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
Log::get()
|
||||
{
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
/* EOF */
|
98
lib/tinygettext/src/plural_forms.cpp
Normal file
98
lib/tinygettext/src/plural_forms.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#include "tinygettext/plural_forms.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Plural functions are used to select a string that matches a given
|
||||
* count. \a n is the count and the return value is the string index
|
||||
* used in the .po file, for example:
|
||||
*
|
||||
* msgstr[0] = "You got %d error";
|
||||
* msgstr[1] = "You got %d errors";
|
||||
* ^-- return value of plural function
|
||||
*/
|
||||
unsigned int plural1(int ) { return 0; }
|
||||
unsigned int plural2_1(int n) { return (n != 1); }
|
||||
unsigned int plural2_2(int n) { return (n > 1); }
|
||||
unsigned int plural2_mk(int n) { return n==1 || n%10==1 ? 0 : 1; }
|
||||
unsigned int plural3_lv(int n) { return static_cast<unsigned int>(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2); }
|
||||
unsigned int plural3_ga(int n) { return static_cast<unsigned int>(n==1 ? 0 : n==2 ? 1 : 2); }
|
||||
unsigned int plural3_lt(int n) { return static_cast<unsigned int>(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2); }
|
||||
unsigned int plural3_1(int n) { return static_cast<unsigned int>(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); }
|
||||
unsigned int plural3_sk(int n) { return static_cast<unsigned int>( (n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2 ); }
|
||||
unsigned int plural3_pl(int n) { return static_cast<unsigned int>(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); }
|
||||
unsigned int plural3_sl(int n) { return static_cast<unsigned int>(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3); }
|
||||
unsigned int plural4_gd(int n) { return static_cast<unsigned int>( n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3; }
|
||||
unsigned int plural6_ar(int n) { return static_cast<unsigned int>( n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5); }
|
||||
|
||||
} // namespace
|
||||
|
||||
PluralForms
|
||||
PluralForms::from_string(const std::string& str)
|
||||
{
|
||||
typedef std::unordered_map<std::string, PluralForms> PluralFormsMap;
|
||||
static PluralFormsMap plural_forms;
|
||||
|
||||
if (plural_forms.empty())
|
||||
{
|
||||
// Note that the plural forms here shouldn't contain any spaces
|
||||
plural_forms["Plural-Forms:nplurals=1;plural=0;"] = PluralForms(1, plural1);
|
||||
plural_forms["Plural-Forms:nplurals=2;plural=(n!=1);"] = PluralForms(2, plural2_1);
|
||||
plural_forms["Plural-Forms:nplurals=2;plural=n!=1;"] = PluralForms(2, plural2_1);
|
||||
plural_forms["Plural-Forms:nplurals=2;plural=(n>1);"] = PluralForms(2, plural2_2);
|
||||
plural_forms["Plural-Forms:nplurals=2;plural=n==1||n%10==1?0:1;"] = PluralForms(2, plural2_mk);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=n%10==1&&n%100!=11?0:n!=0?1:2);"] = PluralForms(2, plural3_lv);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=n==1?0:n==2?1:2;"] = PluralForms(3, plural3_ga);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=(n%10==1&&n%100!=11?0:n%10>=2&&(n%100<10||n%100>=20)?1:2);"] = PluralForms(3, plural3_lt);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=(n%10==1&&n%100!=11?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2);"] = PluralForms(3, plural3_1);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=(n==1)?0:(n>=2&&n<=4)?1:2;"] = PluralForms(3, plural3_sk);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=(n==1?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2);"] = PluralForms(3, plural3_pl);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=(n%100==1?0:n%100==2?1:n%100==3||n%100==4?2:3);"] = PluralForms(3, plural3_sl);
|
||||
|
||||
plural_forms["Plural-Forms:nplurals=4;plural=(n==1||n==11)?0:(n==2||n==12)?1:(n>2&&n<20)?2:3;"]=PluralForms(4, plural4_gd);
|
||||
plural_forms["Plural-Forms:nplurals=6;plural=n==0?0:n==1?1:n==2?2:n%100>=3&&n%100<=10?3:n%100>=11?4:5"]=PluralForms(6, plural6_ar);
|
||||
}
|
||||
|
||||
// Remove spaces from string before lookup
|
||||
std::string space_less_str;
|
||||
for(std::string::size_type i = 0; i < str.size(); ++i)
|
||||
if (!isspace(str[i]))
|
||||
space_less_str += str[i];
|
||||
|
||||
PluralFormsMap::const_iterator it= plural_forms.find(space_less_str);
|
||||
if (it != plural_forms.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PluralForms();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
/* EOF */
|
@ -1,38 +1,37 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2009-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2009 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include "po_parser.hpp"
|
||||
#include "tinygettext/po_parser.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <ctype.h>
|
||||
#include <string>
|
||||
#include <istream>
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "language.hpp"
|
||||
#include "dictionary.hpp"
|
||||
#include "plural_forms.hpp"
|
||||
|
||||
#include "utils/log.hpp"
|
||||
#include "tinygettext/language.hpp"
|
||||
#include "tinygettext/log_stream.hpp"
|
||||
#include "tinygettext/iconv.hpp"
|
||||
#include "tinygettext/dictionary.hpp"
|
||||
#include "tinygettext/plural_forms.hpp"
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
@ -56,8 +55,8 @@ POParser::POParser(const std::string& filename_, std::istream& in_, Dictionary&
|
||||
eof(false),
|
||||
big5(false),
|
||||
line_number(0),
|
||||
current_line()//,
|
||||
//conv()
|
||||
current_line(),
|
||||
conv()
|
||||
{
|
||||
}
|
||||
|
||||
@ -68,15 +67,14 @@ POParser::~POParser()
|
||||
void
|
||||
POParser::warning(const std::string& msg)
|
||||
{
|
||||
Log::warn("tinygettext", "%s line %d %s: \"%s\"",
|
||||
filename.c_str(), line_number, msg.c_str(), current_line.c_str());
|
||||
log_warning << filename << ":" << line_number << ": warning: " << msg << ": " << current_line << std::endl;
|
||||
//log_warning << "Line: " << current_line << std::endl;
|
||||
}
|
||||
|
||||
void
|
||||
POParser::error(const std::string& msg)
|
||||
{
|
||||
Log::error("tinygettext", "%s line %d %s: \"%s\"",
|
||||
filename.c_str(), line_number, msg.c_str(), current_line.c_str());
|
||||
log_error << filename << ":" << line_number << ": error: " << msg << ": " << current_line << std::endl;
|
||||
|
||||
// Try to recover from an error by searching for start of another entry
|
||||
do
|
||||
@ -95,7 +93,7 @@ POParser::next_line()
|
||||
}
|
||||
|
||||
void
|
||||
POParser::get_string_line(std::ostringstream& out,unsigned int skip)
|
||||
POParser::get_string_line(std::ostringstream& out, size_t skip)
|
||||
{
|
||||
if (skip+1 >= static_cast<unsigned int>(current_line.size()))
|
||||
error("unexpected end of line");
|
||||
@ -177,7 +175,7 @@ POParser::get_string(unsigned int skip)
|
||||
else
|
||||
{
|
||||
if (pedantic)
|
||||
warning("keyword and string must be separated by a single space");
|
||||
warning("keyword and string must be seperated by a single space");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
@ -211,7 +209,7 @@ next:
|
||||
if (pedantic)
|
||||
warning("leading whitespace before string");
|
||||
|
||||
get_string_line(out, (unsigned int) i);
|
||||
get_string_line(out, i);
|
||||
goto next;
|
||||
}
|
||||
else if (isspace(current_line[i]))
|
||||
@ -227,7 +225,7 @@ next:
|
||||
return out.str();
|
||||
}
|
||||
|
||||
static bool has_prefix(const std::string& lhs, const std::string &rhs)
|
||||
static bool has_prefix(const std::string& lhs, const std::string& rhs)
|
||||
{
|
||||
if (lhs.length() < rhs.length())
|
||||
return false;
|
||||
@ -249,7 +247,7 @@ POParser::parse_header(const std::string& header)
|
||||
if (has_prefix(line, "Content-Type:"))
|
||||
{
|
||||
// from_charset = line.substr(len);
|
||||
unsigned int len = (unsigned int) strlen("Content-Type: text/plain; charset=");
|
||||
size_t len = strlen("Content-Type: text/plain; charset=");
|
||||
if (line.compare(0, len, "Content-Type: text/plain; charset=") == 0)
|
||||
{
|
||||
from_charset = line.substr(len);
|
||||
@ -279,7 +277,7 @@ POParser::parse_header(const std::string& header)
|
||||
{
|
||||
if (dict.get_plural_forms() != plural_forms)
|
||||
{
|
||||
warning("Plural-Forms mismatch between .po file and dictionary");
|
||||
warning("Plural-Forms missmatch between .po file and dictionary");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -298,7 +296,7 @@ POParser::parse_header(const std::string& header)
|
||||
big5 = true;
|
||||
}
|
||||
|
||||
//conv.set_charsets(from_charset, dict.get_charset());
|
||||
conv.set_charsets(from_charset, dict.get_charset());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -340,9 +338,9 @@ POParser::parse()
|
||||
// skip UTF-8 intro that some text editors produce
|
||||
// see http://en.wikipedia.org/wiki/Byte-order_mark
|
||||
if (current_line.size() >= 3 &&
|
||||
current_line[0] == static_cast<unsigned char>(0xef) &&
|
||||
current_line[1] == static_cast<unsigned char>(0xbb) &&
|
||||
current_line[2] == static_cast<unsigned char>(0xbf))
|
||||
current_line[0] == static_cast<char>(0xef) &&
|
||||
current_line[1] == static_cast<char>(0xbb) &&
|
||||
current_line[2] == static_cast<char>(0xbf))
|
||||
{
|
||||
current_line = current_line.substr(3);
|
||||
}
|
||||
@ -386,7 +384,7 @@ POParser::parse()
|
||||
{
|
||||
std::string msgid_plural = get_string(12);
|
||||
std::vector<std::string> msgstr_num;
|
||||
bool saw_nonempty_msgstr = false;
|
||||
bool saw_nonempty_msgstr = false;
|
||||
|
||||
next:
|
||||
if (is_empty_line())
|
||||
@ -399,15 +397,15 @@ POParser::parse()
|
||||
isdigit(current_line[7]) && current_line[8] == ']')
|
||||
{
|
||||
unsigned int number = static_cast<unsigned int>(current_line[7] - '0');
|
||||
std::string msgstr = get_string(9);
|
||||
std::string msgstr = get_string(9);
|
||||
|
||||
if(!msgstr.empty())
|
||||
saw_nonempty_msgstr = true;
|
||||
if(!msgstr.empty())
|
||||
saw_nonempty_msgstr = true;
|
||||
|
||||
if (number >= msgstr_num.size())
|
||||
msgstr_num.resize(number+1);
|
||||
|
||||
msgstr_num[number] = msgstr; //conv.convert(msgstr);
|
||||
msgstr_num[number] = conv.convert(msgstr);
|
||||
goto next;
|
||||
}
|
||||
else
|
||||
@ -418,38 +416,38 @@ POParser::parse()
|
||||
if (!is_empty_line())
|
||||
error("expected 'msgstr[N]' or empty line");
|
||||
|
||||
if (saw_nonempty_msgstr)
|
||||
{
|
||||
if (use_fuzzy || !fuzzy)
|
||||
if (saw_nonempty_msgstr)
|
||||
{
|
||||
if (use_fuzzy || !fuzzy)
|
||||
{
|
||||
if (!dict.get_plural_forms())
|
||||
{
|
||||
warning("msgstr[N] seen, but no Plural-Forms given");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (msgstr_num.size() != dict.get_plural_forms().get_nplural())
|
||||
{
|
||||
warning("msgstr[N] count doesn't match Plural-Forms.nplural");
|
||||
}
|
||||
}
|
||||
if (!dict.get_plural_forms())
|
||||
{
|
||||
warning("msgstr[N] seen, but no Plural-Forms given");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (msgstr_num.size() != dict.get_plural_forms().get_nplural())
|
||||
{
|
||||
warning("msgstr[N] count doesn't match Plural-Forms.nplural");
|
||||
}
|
||||
}
|
||||
|
||||
if (has_msgctxt)
|
||||
dict.add_translation(msgctxt, msgid, msgid_plural, msgstr_num);
|
||||
else
|
||||
dict.add_translation(msgid, msgid_plural, msgstr_num);
|
||||
}
|
||||
if (has_msgctxt)
|
||||
dict.add_translation(msgctxt, msgid, msgid_plural, msgstr_num);
|
||||
else
|
||||
dict.add_translation(msgid, msgid_plural, msgstr_num);
|
||||
}
|
||||
|
||||
if (0)
|
||||
{
|
||||
std::cout << (fuzzy?"fuzzy":"not-fuzzy") << std::endl;
|
||||
std::cout << "msgid \"" << msgid << "\"" << std::endl;
|
||||
std::cout << "msgid_plural \"" << msgid_plural << "\"" << std::endl;
|
||||
for(std::vector<std::string>::size_type i = 0; i < msgstr_num.size(); ++i)
|
||||
std::cout << "msgstr[" << i << "] \"" << msgstr_num[i] /*conv.convert(msgstr_num[i])*/ << "\"" << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
if ((false))
|
||||
{
|
||||
std::cout << (fuzzy?"fuzzy":"not-fuzzy") << std::endl;
|
||||
std::cout << "msgid \"" << msgid << "\"" << std::endl;
|
||||
std::cout << "msgid_plural \"" << msgid_plural << "\"" << std::endl;
|
||||
for(std::vector<std::string>::size_type i = 0; i < msgstr_num.size(); ++i)
|
||||
std::cout << "msgstr[" << i << "] \"" << conv.convert(msgstr_num[i]) << "\"" << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (prefix("msgstr"))
|
||||
{
|
||||
@ -464,16 +462,16 @@ POParser::parse()
|
||||
if (use_fuzzy || !fuzzy)
|
||||
{
|
||||
if (has_msgctxt)
|
||||
dict.add_translation(msgctxt, msgid, msgstr /*conv.convert(msgstr)*/);
|
||||
dict.add_translation(msgctxt, msgid, conv.convert(msgstr));
|
||||
else
|
||||
dict.add_translation(msgid, msgstr /*conv.convert(msgstr)*/);
|
||||
dict.add_translation(msgid, conv.convert(msgstr));
|
||||
}
|
||||
|
||||
if (0)
|
||||
if ((false))
|
||||
{
|
||||
std::cout << (fuzzy?"fuzzy":"not-fuzzy") << std::endl;
|
||||
std::cout << "msgid \"" << msgid << "\"" << std::endl;
|
||||
std::cout << "msgstr \"" << msgstr /*conv.convert(msgstr)*/ << "\"" << std::endl;
|
||||
std::cout << "msgstr \"" << conv.convert(msgstr) << "\"" << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
@ -498,4 +496,3 @@ POParser::parse()
|
||||
} // namespace tinygettext
|
||||
|
||||
/* EOF */
|
||||
#endif
|
24
lib/tinygettext/src/tinygettext.cpp
Normal file
24
lib/tinygettext/src/tinygettext.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
/* EOF */
|
66
lib/tinygettext/src/unix_file_system.cpp
Normal file
66
lib/tinygettext/src/unix_file_system.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (c) 2009 Ingo Ruhnke <grumbel@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgement in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#include "tinygettext/unix_file_system.hpp"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fstream>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
UnixFileSystem::UnixFileSystem()
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
UnixFileSystem::open_directory(const std::string& pathname)
|
||||
{
|
||||
DIR* dir = opendir(pathname.c_str());
|
||||
if (!dir)
|
||||
{
|
||||
// FIXME: error handling
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<std::string> files;
|
||||
|
||||
struct dirent* dp;
|
||||
while((dp = readdir(dir)) != 0)
|
||||
{
|
||||
files.push_back(dp->d_name);
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
return files;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<std::istream>
|
||||
UnixFileSystem::open_file(const std::string& filename)
|
||||
{
|
||||
return std::unique_ptr<std::istream>(new std::ifstream(filename.c_str()));
|
||||
}
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
/* EOF */
|
@ -1,251 +0,0 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2006-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include <assert.h>
|
||||
#include "dictionary.hpp"
|
||||
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
Dictionary::Dictionary(const std::string& charset_) :
|
||||
entries(),
|
||||
ctxt_entries(),
|
||||
charset(charset_),
|
||||
plural_forms()
|
||||
{
|
||||
m_has_fallback = false;
|
||||
}
|
||||
|
||||
Dictionary::~Dictionary()
|
||||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::get_charset() const
|
||||
{
|
||||
return charset;
|
||||
}
|
||||
|
||||
void
|
||||
Dictionary::set_plural_forms(const PluralForms& plural_forms_)
|
||||
{
|
||||
plural_forms = plural_forms_;
|
||||
}
|
||||
|
||||
PluralForms
|
||||
Dictionary::get_plural_forms() const
|
||||
{
|
||||
return plural_forms;
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::translate_plural(const std::string& msgid, const std::string& msgid_plural, int num)
|
||||
{
|
||||
return translate_plural(entries, msgid, msgid_plural, num);
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::translate_plural(const Entries& dict, const std::string& msgid, const std::string& msgid_plural, int count)
|
||||
{
|
||||
Entries::const_iterator i = dict.find(msgid);
|
||||
|
||||
if (i != dict.end())
|
||||
{
|
||||
const std::vector<std::string>& msgstrs = i->second;
|
||||
unsigned int n = 0;
|
||||
n = plural_forms.get_plural(count);
|
||||
assert(/*n >= 0 &&*/ n < msgstrs.size());
|
||||
|
||||
if (!msgstrs[n].empty())
|
||||
return msgstrs[n];
|
||||
else
|
||||
if (count == 1) // default to english rules
|
||||
return msgid;
|
||||
else
|
||||
return msgid_plural;
|
||||
}
|
||||
else
|
||||
{
|
||||
//log_info << "Couldn't translate: " << msgid << std::endl;
|
||||
//log_info << "Candidates: " << std::endl;
|
||||
//for (i = dict.begin(); i != dict.end(); ++i)
|
||||
// log_info << "'" << i->first << "'" << std::endl;
|
||||
|
||||
if (count == 1) // default to english rules
|
||||
return msgid;
|
||||
else
|
||||
return msgid_plural;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::translate(const std::string& msgid)
|
||||
{
|
||||
return translate(entries, msgid);
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::translate(const Entries& dict, const std::string& msgid)
|
||||
{
|
||||
Entries::const_iterator i = dict.find(msgid);
|
||||
if (i != dict.end() && !i->second.empty())
|
||||
{
|
||||
return i->second[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
//log_info << "Couldn't translate: " << msgid << std::endl;
|
||||
|
||||
if (m_has_fallback) return m_fallback->translate(msgid);
|
||||
else return msgid;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::translate_ctxt(const std::string& msgctxt, const std::string& msgid)
|
||||
{
|
||||
CtxtEntries::iterator i = ctxt_entries.find(msgctxt);
|
||||
if (i != ctxt_entries.end())
|
||||
{
|
||||
return translate(i->second, msgid);
|
||||
}
|
||||
else
|
||||
{
|
||||
//log_info << "Couldn't translate: " << msgid << std::endl;
|
||||
return msgid;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Dictionary::translate_ctxt_plural(const std::string& msgctxt,
|
||||
const std::string& msgid, const std::string& msgidplural, int num)
|
||||
{
|
||||
CtxtEntries::iterator i = ctxt_entries.find(msgctxt);
|
||||
if (i != ctxt_entries.end())
|
||||
{
|
||||
return translate_plural(i->second, msgid, msgidplural, num);
|
||||
}
|
||||
else
|
||||
{
|
||||
//log_info << "Couldn't translate: " << msgid << std::endl;
|
||||
if (num != 1) // default to english
|
||||
return msgidplural;
|
||||
else
|
||||
return msgid;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Dictionary::add_translation(const std::string& msgid, const std::string& ,
|
||||
const std::vector<std::string>& msgstrs)
|
||||
{
|
||||
// Do we need msgid2 for anything? its after all supplied to the
|
||||
// translate call, so we just throw it away here
|
||||
entries[msgid] = msgstrs;
|
||||
}
|
||||
|
||||
void
|
||||
Dictionary::add_translation(const std::string& msgid, const std::string& msgstr)
|
||||
{
|
||||
std::vector<std::string>& vec = entries[msgid];
|
||||
if (vec.empty())
|
||||
{
|
||||
vec.push_back(msgstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("tinygettext",
|
||||
"Collision in add translation: '%s' -> '%s' vs '%s'.",
|
||||
msgid.c_str(), msgstr.c_str(), vec[0].c_str());
|
||||
vec[0] = msgstr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Dictionary::add_translation(const std::string& msgctxt,
|
||||
const std::string& msgid, const std::string& msgid_plural,
|
||||
const std::vector<std::string>& msgstrs)
|
||||
{
|
||||
std::vector<std::string>& vec = ctxt_entries[msgctxt][msgid];
|
||||
if (vec.empty())
|
||||
{
|
||||
vec = msgstrs;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("tinygettext",
|
||||
"collision in add_translation(\"%s\", \"%s\", \"%s\")",
|
||||
msgctxt.c_str(), msgid.c_str(), msgid_plural.c_str());
|
||||
vec = msgstrs;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Dictionary::add_translation(const std::string& msgctxt, const std::string& msgid, const std::string& msgstr)
|
||||
{
|
||||
std::vector<std::string>& vec = ctxt_entries[msgctxt][msgid];
|
||||
if (vec.empty())
|
||||
{
|
||||
vec.push_back(msgstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("tinygettext", "collision in add_translation(\"%s\", \"%s\")",
|
||||
msgctxt.c_str(), msgid.c_str());
|
||||
vec[0] = msgstr;
|
||||
}
|
||||
}
|
||||
|
||||
std::set<wchar_t> Dictionary::get_all_used_chars()
|
||||
{
|
||||
std::set<wchar_t> UsedChars;
|
||||
for (Entries::const_iterator i = entries.begin(); i != entries.end(); ++i)
|
||||
{
|
||||
const std::vector<std::string>& msgstrs = i->second;
|
||||
for (unsigned int k = 0; k < msgstrs.size(); k++)
|
||||
{
|
||||
irr::core::stringw ws = StringUtils::utf8ToWide(msgstrs[k]);
|
||||
for (unsigned int l = 0; l < ws.size(); ++l)
|
||||
UsedChars.insert(ws[l]);
|
||||
}
|
||||
}
|
||||
|
||||
for (CtxtEntries::const_iterator i = ctxt_entries.begin(); i != ctxt_entries.end(); ++i)
|
||||
{
|
||||
for (Entries::const_iterator j = i->second.begin(); j != i->second.end(); ++j)
|
||||
{
|
||||
const std::vector<std::string>& msgstrs = j->second;
|
||||
for (unsigned int k = 0; k < msgstrs.size(); k++)
|
||||
{
|
||||
irr::core::stringw ws = StringUtils::utf8ToWide(msgstrs[k]);
|
||||
for (unsigned int l = 0; l < ws.size(); ++l)
|
||||
UsedChars.insert(ws[l]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return UsedChars;
|
||||
}
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
/* EOF */
|
||||
#endif
|
@ -1,44 +0,0 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2009-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_FILE_SYSTEM_HPP
|
||||
#define HEADER_TINYGETTEXT_FILE_SYSTEM_HPP
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
class FileSystem
|
||||
{
|
||||
public:
|
||||
virtual ~FileSystem() {}
|
||||
|
||||
virtual std::vector<std::string> open_directory(const std::string& pathname) =0;
|
||||
virtual std::unique_ptr<std::istream> open_file(const std::string& filename) =0;
|
||||
};
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
#endif
|
@ -1,124 +0,0 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2006-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include "plural_forms.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
/**
|
||||
* Plural functions are used to select a string that matches a given
|
||||
* count. \a n is the count and the return value is the string index
|
||||
* used in the .po file, for example:
|
||||
*
|
||||
* msgstr[0] = "You got %d error";
|
||||
* msgstr[1] = "You got %d errors";
|
||||
* ^-- return value of plural function
|
||||
*/
|
||||
// Base on Unicode CLDR (http://mlocati.github.io/cldr-to-gettext-plural-rules/)
|
||||
unsigned int plural1(int ) { return 0; }
|
||||
|
||||
unsigned int plural2_1(int n) { return (n != 1); }
|
||||
unsigned int plural2_2(int n) { return (n > 1); }
|
||||
unsigned int plural2_is(int n) { return n % 10 != 1 || n % 100 == 11; }
|
||||
unsigned int plural2_mk(int n) { return n==1 || n%10==1 ? 0 : 1; }
|
||||
|
||||
unsigned int plural3_be(int n) { return static_cast<unsigned int>(n % 10 == 1 && n % 100 != 11) ? 0 : ((n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) ? 1 : 2); }
|
||||
unsigned int plural3_kw(int n) { return static_cast<unsigned int>(n == 1) ? 0 : ((n == 2) ? 1 : 2); }
|
||||
unsigned int plural3_lv(int n) { return static_cast<unsigned int>(n % 10 == 0 || (n % 100 >= 11 && n % 100 <= 19)) ? 0 : ((n % 10 == 1 && n % 100 != 11) ? 1 : 2); }
|
||||
unsigned int plural3_lt(int n) { return static_cast<unsigned int>(n % 10 == 1 && (n % 100 < 11 || n % 100 > 19)) ? 0 : ((n % 10 >= 2 && n % 10 <= 9 && (n % 100 < 11 || n % 100 > 19)) ? 1 : 2); }
|
||||
unsigned int plural3_pl(int n) { return static_cast<unsigned int>(n == 1) ? 0 : ((n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) ? 1 : 2); }
|
||||
unsigned int plural3_ro(int n) { return static_cast<unsigned int>(n == 1) ? 0 : ((n == 0 || (n != 1 && n % 100 >= 1 && n % 100 <= 19)) ? 1 : 2); }
|
||||
unsigned int plural3_sk(int n) { return static_cast<unsigned int>(n == 1) ? 0 : ((n >= 2 && n <= 4) ? 1 : 2); }
|
||||
|
||||
unsigned int plural4_gd(int n) { return static_cast<unsigned int>(n == 1 || n == 11) ? 0 : ((n == 2 || n == 12) ? 1 : (((n >= 3 && n <= 10) || (n >= 13 && n <= 19)) ? 2 : 3)); }
|
||||
unsigned int plural4_sl(int n) { return static_cast<unsigned int>(n % 100 == 1) ? 0 : ((n % 100 == 2) ? 1 : ((n % 100 == 3 || n % 100 == 4) ? 2 : 3)); }
|
||||
|
||||
unsigned int plural5_ga(int n) { return static_cast<unsigned int>(n == 1) ? 0 : ((n == 2) ? 1 : ((n >= 3 && n <= 6) ? 2 : ((n >= 7 && n <= 10) ? 3 : 4))); }
|
||||
|
||||
unsigned int plural6_ar(int n) { return static_cast<unsigned int>(n == 0) ? 0 : ((n == 1) ? 1 : ((n == 2) ? 2 : ((n % 100 >= 3 && n % 100 <= 10) ? 3 : ((n % 100 >= 11 && n % 100 <= 99) ? 4 : 5)))); }
|
||||
|
||||
typedef std::map<std::string, class PluralForms> tPluralForms;
|
||||
|
||||
PluralForms
|
||||
PluralForms::from_string(const std::string& str)
|
||||
{
|
||||
static tPluralForms plural_forms;
|
||||
|
||||
if (plural_forms.empty())
|
||||
{
|
||||
// Note that the plural forms here shouldn't contain any spaces
|
||||
// Some strings are specific to STK po file
|
||||
// TODO in the future, map language code to plural form instead?
|
||||
plural_forms["Plural-Forms:nplurals=1;plural=0;"] = PluralForms(1, plural1);
|
||||
|
||||
plural_forms["Plural-Forms:nplurals=2;plural=(n!=1);"] = PluralForms(2, plural2_1);
|
||||
plural_forms["Plural-Forms:nplurals=2;plural=n!=1;"] = PluralForms(2, plural2_1);
|
||||
plural_forms["Plural-Forms:nplurals=2;plural=(n>1);"] = PluralForms(2, plural2_2);
|
||||
plural_forms["Plural-Forms:nplurals=2;plural=(n%10!=1||n%100==11);"] = PluralForms(2, plural2_is);
|
||||
plural_forms["Plural-Forms:nplurals=2;plural=n==1||n%10==1?0:1;"] = PluralForms(2, plural2_mk);
|
||||
|
||||
//FIXME wrong plural equation in be/ru translation files! (transifex error?) nplurals of be/ru is 3 indeed.
|
||||
plural_forms["Plural-Forms:nplurals=4;plural=(n%10==1&&n%100!=11?0:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?1:n%10==0||(n%10>=5&&n%10<=9)||(n%100>=11&&n%100<=14)?2:3);"] = PluralForms(4, plural3_be);
|
||||
plural_forms["Plural-Forms:nplurals=4;plural=(n%1==0&&n%10==1&&n%100!=11?0:n%1==0&&n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?1:n%1==0&&(n%10==0||(n%10>=5&&n%10<=9)||(n%100>=11&&n%100<=14))?2:3);"] = PluralForms(4, plural3_be);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=n%10==1&&n%100!=11?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2;"] = PluralForms(3, plural3_be);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=(n%10==1&&n%100!=11?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2);"] = PluralForms(3, plural3_be);
|
||||
//FIXME wrong again
|
||||
plural_forms["Plural-Forms:nplurals=4;plural=(n==1)?0:(n==2)?1:(n==3)?2:3;"] = PluralForms(4, plural3_kw);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=(n==1?0:n==2?1:2);"] = PluralForms(3, plural3_kw);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=(n%10==1&&n%100!=11?0:n!=0?1:2);"] = PluralForms(3, plural3_lv);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=(n%10==1&&n%100!=11?0:n%10>=2&&(n%100<10||n%100>=20)?1:2);"] = PluralForms(3, plural3_lt);
|
||||
plural_forms["Plural-Forms:nplurals=4;plural=(n%10==1&&(n%100>19||n%100<11)?0:(n%10>=2&&n%10<=9)&&(n%100>19||n%100<11)?1:n%1!=0?2:3);"] = PluralForms(4, plural3_lt);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=(n==1?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2);"] = PluralForms(3, plural3_pl);
|
||||
plural_forms["Plural-Forms:nplurals=4;plural=(n==1?0:(n%10>=2&&n%10<=4)&&(n%100<12||n%100>14)?1:n!=1&&(n%10>=0&&n%10<=1)||(n%10>=5&&n%10<=9)||(n%100>=12&&n%100<=14)?2:3);"] = PluralForms(4, plural3_pl);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"] = PluralForms(3, plural3_ro);
|
||||
plural_forms["Plural-Forms:nplurals=3;plural=(n==1)?0:(n>=2&&n<=4)?1:2;"] = PluralForms(3, plural3_sk);
|
||||
plural_forms["Plural-Forms:nplurals=4;plural=(n%1==0&&n==1?0:n%1==0&&n>=2&&n<=4?1:n%1!=0?2:3);"] = PluralForms(4, plural3_sk);
|
||||
plural_forms["Plural-Forms:nplurals=4;plural=(n==1&&n%1==0)?0:(n>=2&&n<=4&&n%1==0)?1:(n%1!=0)?2:3;"] = PluralForms(4, plural3_sk);
|
||||
|
||||
plural_forms["Plural-Forms:nplurals=4;plural=(n%100==1?0:n%100==2?1:n%100==3||n%100==4?2:3);"] = PluralForms(4, plural4_sl);
|
||||
plural_forms["Plural-Forms:nplurals=4;plural=(n==1||n==11)?0:(n==2||n==12)?1:(n>2&&n<20)?2:3;"] = PluralForms(4, plural4_gd);
|
||||
|
||||
plural_forms["Plural-Forms:nplurals=5;plural=(n==1?0:n==2?1:n<7?2:n<11?3:4);"] = PluralForms(5, plural5_ga);
|
||||
|
||||
plural_forms["Plural-Forms:nplurals=6;plural=n==0?0:n==1?1:n==2?2:n%100>=3&&n%100<=10?3:n%100>=11&&n%100<=99?4:5;"] = PluralForms(6, plural6_ar);
|
||||
}
|
||||
|
||||
// Remove spaces from string before lookup
|
||||
std::string space_less_str;
|
||||
for(std::string::size_type i = 0; i < str.size(); ++i)
|
||||
if (!isspace(str[i]))
|
||||
space_less_str += str[i];
|
||||
|
||||
tPluralForms::const_iterator it= plural_forms.find(space_less_str);
|
||||
if (it != plural_forms.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PluralForms();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
/* EOF */
|
||||
#endif
|
@ -1,64 +0,0 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2006-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_PLURAL_FORMS_HPP
|
||||
#define HEADER_TINYGETTEXT_PLURAL_FORMS_HPP
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
typedef unsigned int (*PluralFunc)(int n);
|
||||
|
||||
class PluralForms
|
||||
{
|
||||
private:
|
||||
unsigned int nplural;
|
||||
PluralFunc plural;
|
||||
|
||||
public:
|
||||
static PluralForms from_string(const std::string& str);
|
||||
|
||||
PluralForms()
|
||||
: nplural(0),
|
||||
plural(0)
|
||||
{}
|
||||
|
||||
PluralForms(unsigned int nplural_, PluralFunc plural_)
|
||||
: nplural(nplural_),
|
||||
plural(plural_)
|
||||
{}
|
||||
|
||||
unsigned int get_nplural() const { return nplural; }
|
||||
unsigned int get_plural(int n) const { if (plural) return plural(n); else return 0; }
|
||||
|
||||
bool operator==(const PluralForms& other) { return nplural == other.nplural && plural == other.plural; }
|
||||
bool operator!=(const PluralForms& other) { return !(*this == other); }
|
||||
|
||||
operator bool() const {
|
||||
return plural!=NULL;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
#endif
|
@ -1,61 +0,0 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2009-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include "stk_file_system.hpp"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "io/file_manager.hpp"
|
||||
#include "utils/file_utils.hpp"
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
StkFileSystem::StkFileSystem()
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
StkFileSystem::open_directory(const std::string& pathname)
|
||||
{
|
||||
std::set<std::string> result;
|
||||
|
||||
file_manager->listFiles(result, pathname);
|
||||
std::vector<std::string> files;
|
||||
for(std::set<std::string>::iterator i=result.begin(); i!=result.end(); i++)
|
||||
{
|
||||
files.push_back(*i);
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
std::unique_ptr<std::istream>
|
||||
StkFileSystem::open_file(const std::string& filename)
|
||||
{
|
||||
return std::unique_ptr<std::istream>(new std::ifstream(
|
||||
FileUtils::getPortableReadingPath(filename)));
|
||||
}
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
/* EOF */
|
||||
|
||||
#endif
|
@ -1,42 +0,0 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2009-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_STK_FILE_SYSTEM_HPP
|
||||
#define HEADER_TINYGETTEXT_STK_FILE_SYSTEM_HPP
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include "file_system.hpp"
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
class StkFileSystem : public FileSystem
|
||||
{
|
||||
public:
|
||||
StkFileSystem();
|
||||
|
||||
std::vector<std::string> open_directory(const std::string& pathname);
|
||||
std::unique_ptr<std::istream> open_file(const std::string& filename);
|
||||
};
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
||||
#endif
|
@ -1,22 +0,0 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2006-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
namespace tinygettext {
|
||||
|
||||
} // namespace tinygettext
|
||||
|
||||
/* EOF */
|
@ -1,27 +0,0 @@
|
||||
// tinygettext - A gettext replacement that works directly on .po files
|
||||
// Copyright (C) 2006-2015 Ingo Ruhnke <grumbel@gmx.de>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_TINYGETTEXT_TINYGETTEXT_HPP
|
||||
#define HEADER_TINYGETTEXT_TINYGETTEXT_HPP
|
||||
|
||||
#include "dictionary.hpp"
|
||||
#include "dictionary_manager.hpp"
|
||||
#include "language.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
@ -402,7 +402,7 @@ Translations::Translations() //: m_dictionary_manager("UTF-16")
|
||||
{
|
||||
Log::verbose("translation", "Language '%s'.",
|
||||
l.get_name().c_str());
|
||||
m_dictionary = m_dictionary_manager.get_dictionary(l);
|
||||
m_dictionary = &m_dictionary_manager.get_dictionary(l);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -418,7 +418,7 @@ Translations::Translations() //: m_dictionary_manager("UTF-16")
|
||||
}
|
||||
if (!l)
|
||||
{
|
||||
m_dictionary = m_dictionary_manager.get_dictionary();
|
||||
m_dictionary = &m_dictionary_manager.get_dictionary();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -431,7 +431,7 @@ Translations::Translations() //: m_dictionary_manager("UTF-16")
|
||||
m_current_language_name = "Default language";
|
||||
m_current_language_name_code = "en";
|
||||
m_current_language_tag = "en";
|
||||
m_dictionary = m_dictionary_manager.get_dictionary();
|
||||
m_dictionary = &m_dictionary_manager.get_dictionary();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -445,7 +445,7 @@ Translations::Translations() //: m_dictionary_manager("UTF-16")
|
||||
m_current_language_tag += tgtLang.get_country();
|
||||
}
|
||||
Log::verbose("translation", "Language '%s'.", m_current_language_name.c_str());
|
||||
m_dictionary = m_dictionary_manager.get_dictionary(tgtLang);
|
||||
m_dictionary = &m_dictionary_manager.get_dictionary(tgtLang);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -454,7 +454,7 @@ Translations::Translations() //: m_dictionary_manager("UTF-16")
|
||||
m_current_language_name = "Default language";
|
||||
m_current_language_name_code = "en";
|
||||
m_current_language_tag = m_current_language_name_code;
|
||||
m_dictionary = m_dictionary_manager.get_dictionary();
|
||||
m_dictionary = &m_dictionary_manager.get_dictionary();
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -497,8 +497,8 @@ irr::core::stringw Translations::w_gettext(const char* original, const char* con
|
||||
#endif
|
||||
|
||||
const std::string& original_t = (context == NULL ?
|
||||
m_dictionary.translate(original) :
|
||||
m_dictionary.translate_ctxt(context, original));
|
||||
m_dictionary->translate(original) :
|
||||
m_dictionary->translate_ctxt(context, original));
|
||||
// print
|
||||
//for (int n=0;; n+=4)
|
||||
const irr::core::stringw wide = StringUtils::utf8ToWide(original_t);
|
||||
@ -545,8 +545,8 @@ irr::core::stringw Translations::w_ngettext(const char* singular, const char* pl
|
||||
#else
|
||||
|
||||
const std::string& res = (context == NULL ?
|
||||
m_dictionary.translate_plural(singular, plural, num) :
|
||||
m_dictionary.translate_ctxt_plural(context, singular, plural, num));
|
||||
m_dictionary->translate_plural(singular, plural, num) :
|
||||
m_dictionary->translate_ctxt_plural(context, singular, plural, num));
|
||||
|
||||
const irr::core::stringw wide = StringUtils::utf8ToWide(res);
|
||||
const wchar_t* out_ptr = wide.c_str();
|
||||
@ -565,7 +565,7 @@ irr::core::stringw Translations::w_ngettext(const char* singular, const char* pl
|
||||
#ifndef SERVER_ONLY
|
||||
std::set<wchar_t> Translations::getCurrentAllChar()
|
||||
{
|
||||
return m_dictionary.get_all_used_chars();
|
||||
return m_dictionary->get_all_used_chars();
|
||||
} // getCurrentAllChar
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -49,7 +49,7 @@ class Translations
|
||||
private:
|
||||
#ifndef SERVER_ONLY
|
||||
tinygettext::DictionaryManager m_dictionary_manager;
|
||||
tinygettext::Dictionary m_dictionary;
|
||||
tinygettext::Dictionary* m_dictionary;
|
||||
|
||||
static std::map<std::string, std::string> m_localized_name;
|
||||
static std::map<std::string, std::map<std::string, irr::core::stringw> > m_localized_country_codes;
|
||||
|
Loading…
Reference in New Issue
Block a user