LibC: Add dummy libintl support
This doesn't really do anything but allows some ports to use it :D
This commit is contained in:
parent
418c3c9cfa
commit
e2eb555ca0
|
@ -15,6 +15,7 @@ set(LIBC_SOURCES
|
|||
inttypes.cpp
|
||||
langinfo.cpp
|
||||
libgen.cpp
|
||||
libintl.cpp
|
||||
locale.cpp
|
||||
malloc.cpp
|
||||
math.cpp
|
||||
|
|
|
@ -0,0 +1,207 @@
|
|||
#include <langinfo.h>
|
||||
#include <libintl.h>
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct text_domain_t
|
||||
{
|
||||
char* domain_name;
|
||||
char* codeset;
|
||||
char* dir_name;
|
||||
};
|
||||
|
||||
static text_domain_t* s_text_domains = nullptr;
|
||||
static size_t s_text_domain_count = 0;
|
||||
static char* s_current_domain = nullptr;
|
||||
|
||||
static text_domain_t* find_text_domain(const char* domainname)
|
||||
{
|
||||
for (size_t i = 0; i < s_text_domain_count; i++)
|
||||
{
|
||||
if (strcmp(s_text_domains[i].domain_name, domainname) != 0)
|
||||
continue;
|
||||
return &s_text_domains[i];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static text_domain_t* bind_new_textdomain(const char* domainname, const char* codeset, const char* dirname)
|
||||
{
|
||||
auto* new_text_domains = static_cast<text_domain_t*>(realloc(s_text_domains, (s_text_domain_count + 1) * sizeof(text_domain_t)));
|
||||
if (new_text_domains == nullptr)
|
||||
return nullptr;
|
||||
s_text_domains = new_text_domains;
|
||||
|
||||
auto& new_text_domain = new_text_domains[s_text_domain_count];
|
||||
|
||||
new_text_domain.domain_name = strdup(domainname);
|
||||
new_text_domain.dir_name = strdup(dirname);
|
||||
new_text_domain.codeset = strdup(codeset);
|
||||
|
||||
if (!new_text_domain.domain_name || !new_text_domain.codeset || !new_text_domain.dir_name)
|
||||
{
|
||||
if (new_text_domain.domain_name)
|
||||
free(new_text_domain.domain_name);
|
||||
if (new_text_domain.codeset)
|
||||
free(new_text_domain.codeset);
|
||||
if (new_text_domain.dir_name)
|
||||
free(new_text_domain.dir_name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
s_text_domain_count++;
|
||||
|
||||
return &new_text_domain;
|
||||
}
|
||||
|
||||
char* bindtextdomain(const char* domainname, const char* dirname)
|
||||
{
|
||||
if (domainname == nullptr || *domainname == '\0')
|
||||
return nullptr;
|
||||
|
||||
auto* text_domain = find_text_domain(domainname);
|
||||
|
||||
if (dirname == nullptr)
|
||||
{
|
||||
if (text_domain != nullptr)
|
||||
return text_domain->dir_name;
|
||||
return const_cast<char*>("");
|
||||
}
|
||||
|
||||
if (text_domain)
|
||||
{
|
||||
char* dirname_copy = strdup(dirname);
|
||||
if (dirname_copy == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (text_domain->dir_name)
|
||||
free(text_domain->dir_name);
|
||||
|
||||
text_domain->dir_name = dirname_copy;
|
||||
return text_domain->dir_name;
|
||||
}
|
||||
|
||||
auto* new_current_domain = bind_new_textdomain(domainname, nl_langinfo(CODESET), dirname);
|
||||
if (new_current_domain == nullptr)
|
||||
return nullptr;
|
||||
return new_current_domain->domain_name;
|
||||
}
|
||||
|
||||
char* bind_textdomain_codeset(const char* domainname, const char* codeset)
|
||||
{
|
||||
if (domainname == nullptr || *domainname == '\0')
|
||||
return nullptr;
|
||||
|
||||
auto* text_domain = find_text_domain(domainname);
|
||||
|
||||
if (codeset == nullptr || *codeset == '\0')
|
||||
{
|
||||
if (text_domain == nullptr)
|
||||
return nl_langinfo(CODESET);
|
||||
return text_domain->codeset;
|
||||
}
|
||||
|
||||
if (text_domain)
|
||||
{
|
||||
char* codeset_copy = strdup(codeset);
|
||||
if (codeset_copy == nullptr)
|
||||
return nullptr;
|
||||
|
||||
free(text_domain->codeset);
|
||||
text_domain->codeset = codeset_copy;
|
||||
return codeset_copy;
|
||||
}
|
||||
|
||||
auto* new_text_domain = bind_new_textdomain(domainname, codeset, "");
|
||||
if (new_text_domain == nullptr)
|
||||
return nullptr;
|
||||
return new_text_domain->codeset;
|
||||
}
|
||||
|
||||
char* textdomain(const char* domainname)
|
||||
{
|
||||
if (domainname == nullptr || *domainname == '\0')
|
||||
{
|
||||
if (s_current_domain == nullptr)
|
||||
s_current_domain = strdup("messages");
|
||||
return s_current_domain;
|
||||
}
|
||||
|
||||
char* new_current_domain = strdup(domainname);
|
||||
if (new_current_domain == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (s_current_domain != nullptr)
|
||||
free(s_current_domain);
|
||||
|
||||
s_current_domain = new_current_domain;
|
||||
return s_current_domain;
|
||||
}
|
||||
|
||||
char* dgettext(const char* domainname, const char* msgid)
|
||||
{
|
||||
return dgettext_l(domainname, msgid, __getlocale(LC_MESSAGES));
|
||||
}
|
||||
|
||||
char* dgettext_l(const char* domainname, const char* msgid, locale_t locale)
|
||||
{
|
||||
return dngettext_l(domainname, msgid, nullptr, 1, locale);
|
||||
}
|
||||
|
||||
char* dcgettext(const char* domainname, const char* msgid, int category)
|
||||
{
|
||||
return dcgettext_l(domainname, msgid, category, __getlocale(LC_MESSAGES));
|
||||
}
|
||||
|
||||
char* dcgettext_l(const char* domainname, const char* msgid, int category, locale_t locale)
|
||||
{
|
||||
return dcngettext_l(domainname, msgid, nullptr, 1, category, locale);
|
||||
}
|
||||
|
||||
char* dngettext(const char* domainname, const char* msgid, const char* msgid_plural, unsigned long int n)
|
||||
{
|
||||
return dngettext_l(domainname, msgid, msgid_plural, n, __getlocale(LC_MESSAGES));
|
||||
}
|
||||
|
||||
char* dngettext_l(const char* domainname, const char* msgid, const char* msgid_plural, unsigned long int n, locale_t locale)
|
||||
{
|
||||
return dcngettext_l(domainname, msgid, msgid_plural, n, 0, locale);
|
||||
}
|
||||
|
||||
char* dcngettext(const char* domainname, const char* msgid, const char* msgid_plural, unsigned long int n, int category)
|
||||
{
|
||||
return dcngettext_l(domainname, msgid, msgid_plural, n, category, __getlocale(LC_MESSAGES));
|
||||
}
|
||||
|
||||
char* dcngettext_l(const char* domainname, const char* msgid, const char* msgid_plural, unsigned long int n, int category, locale_t locale)
|
||||
{
|
||||
// TODO: do actual translations :D
|
||||
// FIXME: handle domain codeset
|
||||
|
||||
(void)locale;
|
||||
(void)domainname;
|
||||
(void)category;
|
||||
return const_cast<char*>((n == 1) ? msgid : msgid_plural);
|
||||
}
|
||||
|
||||
char* gettext(const char* msgid)
|
||||
{
|
||||
return gettext_l(msgid, __getlocale(LC_MESSAGES));
|
||||
}
|
||||
|
||||
char* gettext_l(const char* msgid, locale_t locale)
|
||||
{
|
||||
return dgettext_l(s_current_domain, msgid, locale);
|
||||
}
|
||||
|
||||
char* ngettext(const char* msgid, const char* msgid_plural, unsigned long int n)
|
||||
{
|
||||
return ngettext_l(msgid, msgid_plural, n, __getlocale(LC_MESSAGES));
|
||||
}
|
||||
|
||||
char* ngettext_l(const char* msgid, const char* msgid_plural, unsigned long int n, locale_t locale)
|
||||
{
|
||||
return dngettext_l(s_current_domain, msgid, msgid_plural, n, locale);
|
||||
}
|
Loading…
Reference in New Issue