forked from Bananymous/banan-os
				
			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 | 	inttypes.cpp | ||||||
| 	langinfo.cpp | 	langinfo.cpp | ||||||
| 	libgen.cpp | 	libgen.cpp | ||||||
|  | 	libintl.cpp | ||||||
| 	locale.cpp | 	locale.cpp | ||||||
| 	malloc.cpp | 	malloc.cpp | ||||||
| 	math.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