Unify gettext into language

This commit is contained in:
Xpl0itU 2022-09-26 19:27:09 +02:00
parent 129600f34e
commit 71e1422b77
4 changed files with 96 additions and 143 deletions

View File

@ -1,31 +0,0 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#pragma once
#include <wut_types.h>
#ifdef __cplusplus
extern "C" {
#endif
bool gettextLoadLanguage(const char *langFile);
void gettextCleanUp() __attribute__((__cold__));
const char *gettext(const char *msg) __attribute__((__hot__));
#ifdef __cplusplus
}
#endif

View File

@ -1,6 +1,6 @@
#pragma once
#include <gettext.h>
#include <wut_types.h>
#include <romfs-wiiu.h>
#include <coreinit/memdefaultheap.h>
@ -26,4 +26,7 @@ typedef enum {
} Swkbd_LanguageType;
void loadLanguage(Swkbd_LanguageType language) __attribute__((cold));
Swkbd_LanguageType getSystemLanguage() __attribute__((cold));
Swkbd_LanguageType getSystemLanguage() __attribute__((cold));
bool gettextLoadLanguage(const char *langFile);
void gettextCleanUp() __attribute__((__cold__));
const char *gettext(const char *msg) __attribute__((__hot__));

View File

@ -1,110 +0,0 @@
/***************************************************************************
* Copyright (C) 2015 Dimok *
* Copyright (c) 2022 V10lator <v10lator@myway.de> *
* Copyright (c) 2022 Xpl0itU <DaThinkingChair@protonmail.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 3 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, If not, see <http://www.gnu.org/licenses/>. * *
***************************************************************************/
#include <gettext.h>
#include <savemng.h>
#include <jansson.h>
#include <coreinit/memdefaultheap.h>
#include <coreinit/memory.h>
struct MSG;
typedef struct MSG MSG;
struct MSG {
uint32_t id;
const char *msgstr;
MSG *next;
};
static MSG *baseMSG = NULL;
#define HASHMULTIPLIER 31 // or 37
// Hashing function from https://stackoverflow.com/a/2351171
static inline uint32_t hash_string(const char *str_param) {
uint32_t hash = 0;
while (*str_param != '\0')
hash = HASHMULTIPLIER * hash + *str_param++;
return hash;
}
static inline MSG *findMSG(uint32_t id) {
for (MSG *msg = baseMSG; msg; msg = msg->next)
if (msg->id == id)
return msg;
return NULL;
}
static void setMSG(const char *msgid, const char *msgstr) {
if (!msgstr)
return;
uint32_t id = hash_string(msgid);
MSG *msg = (MSG *) MEMAllocFromDefaultHeap(sizeof(MSG));
msg->id = id;
msg->msgstr = strdup(msgstr);
msg->next = baseMSG;
baseMSG = msg;
return;
}
void gettextCleanUp() {
while (baseMSG) {
MSG *nextMsg = baseMSG->next;
MEMFreeToDefaultHeap((void *) (baseMSG->msgstr));
MEMFreeToDefaultHeap(baseMSG);
baseMSG = nextMsg;
}
}
bool gettextLoadLanguage(const char *langFile) {
uint8_t *buffer;
int32_t size = loadFile(langFile, &buffer);
if (buffer == nullptr)
return false;
bool ret = true;
json_t *json = json_loadb((const char *) buffer, size, 0, nullptr);
if (json) {
size = json_object_size(json);
if (size != 0) {
const char *key;
json_t *value;
json_object_foreach(json, key, value) if (json_is_string(value))
setMSG(key, json_string_value(value));
} else {
ret = false;
}
json_decref(json);
} else {
ret = false;
}
MEMFreeToDefaultHeap(buffer);
return ret;
}
const char *gettext(const char *msgid) {
MSG *msg = findMSG(hash_string(msgid));
return msg ? msg->msgstr : msgid;
}

View File

@ -1,4 +1,22 @@
#include <language.h>
#include <savemng.h>
#include <jansson.h>
#include <coreinit/memdefaultheap.h>
#include <coreinit/memory.h>
struct MSG;
typedef struct MSG MSG;
struct MSG {
uint32_t id;
const char *msgstr;
MSG *next;
};
static MSG *baseMSG = NULL;
#define HASHMULTIPLIER 31 // or 37
Swkbd_LanguageType sysLang;
@ -72,4 +90,77 @@ Swkbd_LanguageType getSystemLanguage() {
if (err != UC_ERROR_OK)
sysLang = Swkbd_LanguageType__English;
return sysLang;
}
// Hashing function from https://stackoverflow.com/a/2351171
static inline uint32_t hash_string(const char *str_param) {
uint32_t hash = 0;
while (*str_param != '\0')
hash = HASHMULTIPLIER * hash + *str_param++;
return hash;
}
static inline MSG *findMSG(uint32_t id) {
for (MSG *msg = baseMSG; msg; msg = msg->next)
if (msg->id == id)
return msg;
return NULL;
}
static void setMSG(const char *msgid, const char *msgstr) {
if (!msgstr)
return;
uint32_t id = hash_string(msgid);
MSG *msg = (MSG *) MEMAllocFromDefaultHeap(sizeof(MSG));
msg->id = id;
msg->msgstr = strdup(msgstr);
msg->next = baseMSG;
baseMSG = msg;
return;
}
void gettextCleanUp() {
while (baseMSG) {
MSG *nextMsg = baseMSG->next;
MEMFreeToDefaultHeap((void *) (baseMSG->msgstr));
MEMFreeToDefaultHeap(baseMSG);
baseMSG = nextMsg;
}
}
bool gettextLoadLanguage(const char *langFile) {
uint8_t *buffer;
int32_t size = loadFile(langFile, &buffer);
if (buffer == nullptr)
return false;
bool ret = true;
json_t *json = json_loadb((const char *) buffer, size, 0, nullptr);
if (json) {
size = json_object_size(json);
if (size != 0) {
const char *key;
json_t *value;
json_object_foreach(json, key, value) if (json_is_string(value))
setMSG(key, json_string_value(value));
} else {
ret = false;
}
json_decref(json);
} else {
ret = false;
}
MEMFreeToDefaultHeap(buffer);
return ret;
}
const char *gettext(const char *msgid) {
MSG *msg = findMSG(hash_string(msgid));
return msg ? msg->msgstr : msgid;
}