Project import
diff --git a/libintl-lite/Android.mk b/libintl-lite/Android.mk new file mode 100644 index 0000000..e0684f8 --- /dev/null +++ b/libintl-lite/Android.mk
@@ -0,0 +1,9 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE := libintl +LOCAL_SRC_FILES := internal/libintl.cpp +LOCAL_CPPFLAGS := -fexceptions +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) + +include $(BUILD_SHARED_LIBRARY)
diff --git a/libintl-lite/LICENSE b/libintl-lite/LICENSE new file mode 100644 index 0000000..36b7cd9 --- /dev/null +++ b/libintl-lite/LICENSE
@@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE.
diff --git a/libintl-lite/MODULE_LICENSE_BSD_LIKE b/libintl-lite/MODULE_LICENSE_BSD_LIKE new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/libintl-lite/MODULE_LICENSE_BSD_LIKE
diff --git a/libintl-lite/README.google b/libintl-lite/README.google new file mode 100644 index 0000000..c97f64d --- /dev/null +++ b/libintl-lite/README.google
@@ -0,0 +1,13 @@ +URL: https://sourceforge.net/projects/libintl-lite/files/libintl-lite-0.5.tar.gz/download +Version: 0.5 +License: Boost Software License +License File: LICENSE + +Description: +libintl-lite is a simple (but less powerful) GNU gettext libintl replacement +and does not depend on any libraries except the standard C/C++ (POSIX/STL) +libraries. + +Local Modifications: +Add Android.mk +Add definitions of dcgettext, bindtextdomain, and bind_text_domain_codeset to libintl.h
diff --git a/libintl-lite/internal/MessageCatalog.hpp b/libintl-lite/internal/MessageCatalog.hpp new file mode 100644 index 0000000..c85c765 --- /dev/null +++ b/libintl-lite/internal/MessageCatalog.hpp
@@ -0,0 +1,92 @@ +/* +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#ifndef LIBINTL_INTERNAL_MESSAGECATALOG_HPP_ +#define LIBINTL_INTERNAL_MESSAGECATALOG_HPP_ + +#include <algorithm> +#include <string> + +namespace libintllite +{ + +namespace internal +{ + +class MessageCatalog +{ +private: + MessageCatalog(const MessageCatalog&); + MessageCatalog& operator=(const MessageCatalog&); + + uint32_t numberOfStrings; + const std::string* sortedOrigStringsArray; + const std::string* translatedStringsArray; + +public: + // The ownership of these arrays is transfered to the created message + // catalog object! + // Does not throw exceptions! + MessageCatalog(uint32_t numberOfStrings, + const std::string* sortedOrigStringsArray, + const std::string* translatedStringsArray) : + numberOfStrings(numberOfStrings), + sortedOrigStringsArray(sortedOrigStringsArray), + translatedStringsArray(translatedStringsArray) + { + } + + ~MessageCatalog() + { + delete[] this->sortedOrigStringsArray; + delete[] this->translatedStringsArray; + } + + // Returns NULL, if the original string was not found. + // Does not throw exceptions! + const std::string* getTranslatedStrPtr(const std::string& orig) const + { + const std::string* lastSortedOrigStringEndIter + = this->sortedOrigStringsArray + this->numberOfStrings; + const std::string* origStrPtr = std::lower_bound(this->sortedOrigStringsArray, + lastSortedOrigStringEndIter, + orig); + if (!origStrPtr || (origStrPtr == lastSortedOrigStringEndIter)) + { + return NULL; + } + else + { + return &this->translatedStringsArray[origStrPtr - this->sortedOrigStringsArray]; + } + } +}; + +} // namespace internal + +} // namespace libintllite + +#endif // LIBINTL_INTERNAL_MESSAGECATALOG_HPP_
diff --git a/libintl-lite/internal/Util.hpp b/libintl-lite/internal/Util.hpp new file mode 100644 index 0000000..e8efdf1 --- /dev/null +++ b/libintl-lite/internal/Util.hpp
@@ -0,0 +1,221 @@ +/* +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#ifndef LIBINTL_INTERNAL_UTIL_HPP_ +#define LIBINTL_INTERNAL_UTIL_HPP_ + +#if defined(WIN32) || defined(WINCE) +typedef unsigned int uint32_t; +#else +#include <stdint.h> +#endif + +namespace libintllite +{ + +namespace internal +{ + +// Helper functions for handling numbers and char array conversions: + +static inline bool isBigEndian() +{ + uint32_t checkNumber = 0x1100; + return (*reinterpret_cast<const char*>(&checkNumber) != 0); +} + +static inline uint32_t swapUInt32Bytes(uint32_t number) +{ + const char* numberAsCharArray = reinterpret_cast<const char*>(&number); + + uint32_t swappedNumber; + char* swappedNumberAsCharArray = reinterpret_cast<char*>(&swappedNumber); + swappedNumberAsCharArray[0] = numberAsCharArray[3]; + swappedNumberAsCharArray[1] = numberAsCharArray[2]; + swappedNumberAsCharArray[2] = numberAsCharArray[1]; + swappedNumberAsCharArray[3] = numberAsCharArray[0]; + return swappedNumber; +} + +static inline uint32_t charArrayToUInt32(const char uint32CharArray[4]) +{ + return *reinterpret_cast<const uint32_t*>(uint32CharArray); +} + +static inline bool readUIn32FromFile(FILE* fileHandle, bool needsBeToLeConversion, uint32_t& outReadUInt32) +{ + char uint32CharArray[4]; + if ((fread(uint32CharArray, 1, 4, fileHandle)) != 4) + { + return false; + } + + if (needsBeToLeConversion) + { + outReadUInt32 = swapUInt32Bytes(charArrayToUInt32(uint32CharArray)); + return true; + } + else + { + outReadUInt32 = charArrayToUInt32(uint32CharArray); + return true; + } +} + +// RAII classes: + +template <class T> +class ArrayGurard +{ +private: + ArrayGurard(const ArrayGurard&); + ArrayGurard& operator=(const ArrayGurard&); + + T*& arrayRef; + bool released; + +public: + explicit ArrayGurard(T*& arrayRef) : + arrayRef(arrayRef), + released(false) + { + } + + ~ArrayGurard() + { + if (!this->released) + { + delete[] this->arrayRef; + } + } + + const T* release() + { + this->released = true; + return this->arrayRef; + } +}; + +class CloseFileHandleGuard +{ +private: + CloseFileHandleGuard(const CloseFileHandleGuard&); + CloseFileHandleGuard& operator=(const CloseFileHandleGuard&); + + FILE*& fileHandleRef; + +public: + explicit CloseFileHandleGuard(FILE*& fileHandleRef) : + fileHandleRef(fileHandleRef) + { + } + + ~CloseFileHandleGuard() + { + if (this->fileHandleRef) + { + fclose(this->fileHandleRef); + } + } +}; + +// Helper function to load strings from a .mo file and stores them in a given array + +static bool loadMoFileStringsToArray(FILE* moFile, + uint32_t numberOfStrings, + uint32_t stringsTableOffsetFromFileBegin, + bool needsBeToLeConversion, + std::string* outStringsFromMoFileArray) +{ + if (fseek(moFile, stringsTableOffsetFromFileBegin, SEEK_SET) != 0) return false; + + uint32_t* stringsLengthsArray = NULL; + ArrayGurard<uint32_t> stringsLengthsArrayGuard(stringsLengthsArray); + stringsLengthsArray = new uint32_t[numberOfStrings]; + if (!stringsLengthsArray) + { + return false; + } + + uint32_t firstStringOffset; + uint32_t lastStringOffset; + { + uint32_t currentStringLength; + uint32_t currentStringOffset; + for (uint32_t i = 0; i < numberOfStrings; i++) + { + if (!readUIn32FromFile(moFile, needsBeToLeConversion, currentStringLength)) return false; + if (!readUIn32FromFile(moFile, needsBeToLeConversion, currentStringOffset)) return false; + + stringsLengthsArray[i] = currentStringLength; + + if (i == 0) + { + firstStringOffset = currentStringOffset; + } + + if (i == (numberOfStrings - 1)) + { + lastStringOffset = currentStringOffset; + } + } + } + + { + char* stringCharsArray = NULL; + ArrayGurard<char> stringCharsArrayGuard(stringCharsArray); + + uint32_t stringCharsArraySize = lastStringOffset + stringsLengthsArray[numberOfStrings - 1] + 1 - firstStringOffset; + if (stringCharsArraySize == 0) + { + return false; + } + + if (fseek(moFile, firstStringOffset, SEEK_SET) != 0) return false; + stringCharsArray = new char[stringCharsArraySize]; + if (!stringCharsArray) + { + return false; + } + if (fread(stringCharsArray, 1, stringCharsArraySize, moFile) != stringCharsArraySize) return false; + + const char* stringsCharsArrayIter = stringCharsArray; + for (uint32_t i = 0; i < numberOfStrings; i++) + { + const char* currentStrEndIter = stringsCharsArrayIter + stringsLengthsArray[i] + 1; + outStringsFromMoFileArray[i] = std::string(stringsCharsArrayIter, currentStrEndIter); + stringsCharsArrayIter = currentStrEndIter; + } + } + + return true; +} + +} // namespace internal + +} // namespace libintllite + +#endif // LIBINTL_INTERNAL_UTIL_HPP_
diff --git a/libintl-lite/internal/libintl.cpp b/libintl-lite/internal/libintl.cpp new file mode 100644 index 0000000..6498312 --- /dev/null +++ b/libintl-lite/internal/libintl.cpp
@@ -0,0 +1,271 @@ +/* +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#include "../libintl.h" + +#include <map> +#include <string> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if defined(WIN32) || defined(WINCE) +typedef unsigned int uint32_t; +#else +#include <stdint.h> +#endif + +#include "MessageCatalog.hpp" +#include "Util.hpp" + +using namespace std; + +using namespace libintllite; +using namespace libintllite::internal; + +static char* currentDefaultDomain = NULL; +static map<char*, MessageCatalog*> loadedMessageCatalogPtrsByDomain; + +libintl_lite_bool_t loadMessageCatalog(const char* domain, const char* moFilePath) +{ + try + { + if (sizeof(uint32_t) != 4) + { + return LIBINTL_LITE_BOOL_FALSE; + } + + if (!moFilePath || !domain) + { + return LIBINTL_LITE_BOOL_FALSE; + } + + FILE* moFile = NULL; + CloseFileHandleGuard closeFileHandleGuard(moFile); + moFile = fopen(moFilePath, "rb"); + if (!moFile) + { + return LIBINTL_LITE_BOOL_FALSE; + } + + uint32_t magicNumber; + if (!readUIn32FromFile(moFile, false, magicNumber)) return LIBINTL_LITE_BOOL_FALSE; + if ((magicNumber != 0x950412de) && (magicNumber != 0xde120495)) return LIBINTL_LITE_BOOL_FALSE; + + uint32_t fileFormatRevision; + if (!readUIn32FromFile(moFile, false, fileFormatRevision)) return LIBINTL_LITE_BOOL_FALSE; + if (fileFormatRevision != 0) return LIBINTL_LITE_BOOL_FALSE; + + bool needsBeToLeConversion = isBigEndian(); + + uint32_t numberOfStrings; + if (!readUIn32FromFile(moFile, needsBeToLeConversion, numberOfStrings)) return false; + if (numberOfStrings == 0) + { + return LIBINTL_LITE_BOOL_TRUE; + } + + uint32_t offsetOrigTable; + if (!readUIn32FromFile(moFile, needsBeToLeConversion, offsetOrigTable)) return LIBINTL_LITE_BOOL_FALSE; + + uint32_t offsetTransTable; + if (!readUIn32FromFile(moFile, needsBeToLeConversion, offsetTransTable)) return LIBINTL_LITE_BOOL_FALSE; + + string* sortedOrigStringsArray = NULL; + ArrayGurard<string> sortedOrigStringsArrayGuard(sortedOrigStringsArray); + sortedOrigStringsArray = new string[numberOfStrings]; + if (!sortedOrigStringsArray) + { + return LIBINTL_LITE_BOOL_FALSE; + } + + if (!loadMoFileStringsToArray(moFile, + numberOfStrings, + offsetOrigTable, + needsBeToLeConversion, + sortedOrigStringsArray)) return LIBINTL_LITE_BOOL_FALSE; + + string* translatedStringsArray = NULL; + ArrayGurard<string> translatedStringsArrayGuard(translatedStringsArray); + translatedStringsArray = new string[numberOfStrings]; + if (!translatedStringsArray) + { + return LIBINTL_LITE_BOOL_FALSE; + } + + if (!loadMoFileStringsToArray(moFile, + numberOfStrings, + offsetTransTable, + needsBeToLeConversion, + translatedStringsArray)) return LIBINTL_LITE_BOOL_FALSE; + + MessageCatalog* newMessageCatalogPtr = new MessageCatalog(numberOfStrings, + sortedOrigStringsArray, + translatedStringsArray); + if (!newMessageCatalogPtr) return LIBINTL_LITE_BOOL_FALSE; + sortedOrigStringsArrayGuard.release(); + translatedStringsArrayGuard.release(); + + char* domainDup = strdup(domain); + if (!domainDup) return LIBINTL_LITE_BOOL_FALSE; + closeLoadedMessageCatalog(domain); + loadedMessageCatalogPtrsByDomain[domainDup] = newMessageCatalogPtr; + + return LIBINTL_LITE_BOOL_TRUE; + } + catch (...) + { + return LIBINTL_LITE_BOOL_FALSE; + } +} + +void closeLoadedMessageCatalog(const char* domain) +{ + if (domain) + { + for (map<char*, MessageCatalog*>::iterator i = loadedMessageCatalogPtrsByDomain.begin(); + i != loadedMessageCatalogPtrsByDomain.end(); + i++) + { + if (strcmp(i->first, domain) == 0) + { + free(i->first); + delete i->second; + loadedMessageCatalogPtrsByDomain.erase(i); + return; + } + } + } +} + +void closeAllLoadedMessageCatalogs() +{ + for (map<char*, MessageCatalog*>::iterator i = loadedMessageCatalogPtrsByDomain.begin(); + i != loadedMessageCatalogPtrsByDomain.end(); + i++) + { + free(i->first); + delete i->second; + } + loadedMessageCatalogPtrsByDomain.clear(); + free(currentDefaultDomain); + currentDefaultDomain = NULL; +} + +const char* textdomain(const char* domain) +{ + if (domain) + { + char* newDefaultDomain = strdup(domain); + if (!newDefaultDomain) + { + return NULL; + } + free(currentDefaultDomain); + currentDefaultDomain = newDefaultDomain; + return newDefaultDomain; + } + else + { + return NULL; + } +} + +const char* gettext(const char* origStr) +{ + return dgettext(NULL, origStr); +} + +const char* dgettext(const char* domain, const char* origStr) +{ + if (!origStr) + { + return NULL; + } + + if (!domain) + { + if (currentDefaultDomain) + { + domain = currentDefaultDomain; + } + else + { + return origStr; + } + } + + const MessageCatalog* msgCat = NULL; + for (map<char*, MessageCatalog*>::iterator i = loadedMessageCatalogPtrsByDomain.begin(); + !msgCat && (i != loadedMessageCatalogPtrsByDomain.end()); + i++) + { + if (strcmp(i->first, domain) == 0) + { + msgCat = i->second; + } + } + + if (!msgCat) + { + return origStr; + } + + const string* translatedStrPtr = msgCat->getTranslatedStrPtr(origStr); + if (translatedStrPtr) + { + return translatedStrPtr->c_str(); + } + else + { + return origStr; + } +} + +const char* ngettext(const char* origStr, const char* origStrPlural, unsigned long n) +{ + if (n == 1) + { + return gettext(origStr); + } + else + { + return gettext(origStrPlural); + } +} + +const char* dngettext(const char* domain, const char* origStr, const char* origStrPlural, unsigned long n) +{ + if (n == 1) + { + return dgettext(domain, origStr); + } + else + { + return dgettext(domain, origStrPlural); + } +}
diff --git a/libintl-lite/libintl.h b/libintl-lite/libintl.h new file mode 100644 index 0000000..b0946b7 --- /dev/null +++ b/libintl-lite/libintl.h
@@ -0,0 +1,120 @@ +/* +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#ifndef LIBINTL_HPP_ +#define LIBINTL_HPP_ + +#define LIBINTL_LITE_API +#if (defined(WIN32) || defined(WINCE)) && defined(LIBINTL_LITE_WIN32_SHARED) + #undef LIBINTL_LITE_API + #ifdef LIBINTL_LITE_EXPORTS + #define LIBINTL_LITE_API __declspec(dllexport) + #else + #define LIBINTL_LITE_API __declspec(dllimport) + #endif +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef int libintl_lite_bool_t; +#define LIBINTL_LITE_BOOL_TRUE 1 +#define LIBINTL_LITE_BOOL_FALSE 0 + +/** + * Loads a message catalog from a given (GNU-compatible) .mo file. + * Returns true, if the message catalog was loaded successfully and + * false otherwise. + * This function is specific to libintl-lite and serves as a simple + * replacement for bindtextdomain() function of GNU gettext. + * The parameter "domain" must not be NULL! + * This function is NOT thread safe! + * Pay attention to the thread safety remarks of the gettext() function! + */ +LIBINTL_LITE_API libintl_lite_bool_t loadMessageCatalog(const char* domain, const char* moFilePath); + +/** + * Closes a message catalog for the specified domain and releases its obtained resources. + * This function is NOT thread safe! + * Pay attention to the thread safety remarks of the gettext() function! + */ +LIBINTL_LITE_API void closeLoadedMessageCatalog(const char* domain); + +/** + * Closes all loaded message catalogs releases their obtained resources. + * This function is NOT thread safe! + * Pay attention to the thread safety remarks of the gettext() function! + */ +LIBINTL_LITE_API void closeAllLoadedMessageCatalogs(); + +/** + * Sets the default text domain for gettext() / ngettext() calls. + * This function is NOT thread safe! + */ +LIBINTL_LITE_API const char* textdomain(const char* domain); + +/** + * Returns a pointer to the NULL-terminated string in the loaded for the default + * message catalog, or origString if origStr is NULL, textdomain() was not called, + * no message catalog for the specified domain is loaded or no translated message + * could be found. + * This function is thread-safe, but loadMessageCatalog(), textdomain(), + * closeLoadedMessageCatalog() or closeAllLoadedMessageCatalogs() + * must not be called at the same time! A returned string in the current + * loaded message catalog will be deleted, if loadMessageCatalog() or + * closeLoadedMessageCatalog() is called for the used domain afterwards! + * Does not perform any character set conversion! + */ +LIBINTL_LITE_API const char* gettext(const char* origStr); + +/** + * Works like the gettext() function, but uses the message catalog for a specified domain. + */ +LIBINTL_LITE_API const char* dgettext(const char* domain, const char* origStr); + +/** + * Works like the gettext() function, but distinguishes between singular + * and plural form of a message. + * Always returns the suitable singular string, if n == 1, and the plural string + * otherwise, regardless of the language. + */ +LIBINTL_LITE_API const char* ngettext(const char* origStr, const char* origStrPlural, unsigned long n); + +/** + * Works like the ngettext() function, but uses the message catalog for a specified domain. + */ +LIBINTL_LITE_API const char* dngettext(const char* domain, const char* origStr, const char* origStrPlural, unsigned long n); + +# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) +# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) +# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // LIBINTL_HPP_