1 /* lang.c - NeonServ v5.6
2 * Copyright (C) 2011-2012 Philipp Kreil (pk910)
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "mysqlConn.h"
24 #define DEFAULT_LANG_TAG "EN"
25 #define DEFAULT_LANG_NAME "English"
27 static struct language **langdict;
28 static struct language *lang_c;
31 langdict = calloc(MAXLANGUAGES, sizeof(*langdict));
38 void load_languages() {
41 printf_mysql_query("SELECT `lang`, `text` FROM `language` WHERE `ident` = 'name'");
43 while((row = mysql_fetch_row(res)) != NULL) {
44 load_language(row[0], row[1]);
48 static struct language* add_language(char *langtag, char *langname) {
50 for(cindex = 0; cindex < MAXLANGUAGES; cindex++) {
51 if(langdict[cindex] == NULL) break;
52 if(!strcmp(langdict[cindex]->langname, langname) || !strcmp(langdict[cindex]->langtag, langtag))
53 return langdict[cindex];
55 if(cindex == MAXLANGUAGES) return NULL;
56 struct language *lang = malloc(sizeof(*lang));
58 printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
61 lang->langtag = strdup(langtag);
62 lang->langname = strdup(langname);
63 struct language_table **entrys = calloc(27, sizeof(*entrys));
64 lang->entrys = entrys;
65 langdict[cindex] = lang;
69 static int get_entry_index(const char *ident) {
70 const char *underscore = strstr(ident, "_");
71 if(!underscore || !(underscore[1] >= 65 && underscore[1] <= 90)) return 26;
72 return (underscore[1] - 'A');
75 void load_language(char *tag, char *name) {
76 struct language *lang = get_language_by_tag(tag);
77 if(lang == get_default_language()) return;
81 struct language_table *entry, *next;
82 for(cindex = 0; cindex < 27; cindex++) {
83 for(entry = lang->entrys[cindex]; entry; entry = next) {
89 lang->entrys[cindex] = NULL;
92 lang = add_language(tag, name);
96 printf_mysql_query("SELECT `ident`, `text` FROM `language` WHERE `lang` = '%s' AND `ident` != 'name'", escape_string(tag));
98 while((row = mysql_fetch_row(res)) != NULL) {
99 register_language_string(lang, row[0], row[1]);
103 struct language* get_language_by_tag(char *tag) {
105 for(cindex = 0; cindex < MAXLANGUAGES; cindex++) {
106 if(langdict[cindex] == NULL) break;
107 if(!stricmp(langdict[cindex]->langtag, tag))
108 return langdict[cindex];
113 struct language* get_language_by_name(char *name) {
115 for(cindex = 0; cindex < MAXLANGUAGES; cindex++) {
116 if(langdict[cindex] == NULL) break;
117 if(!stricmp(langdict[cindex]->langname, name))
118 return langdict[cindex];
123 struct language* get_default_language() {
125 lang_c = add_language(DEFAULT_LANG_TAG, DEFAULT_LANG_NAME);
129 void register_default_language_table(const struct default_language_entry *msgtab) {
131 lang_c = add_language(DEFAULT_LANG_TAG, DEFAULT_LANG_NAME);
132 while(msgtab->ident) {
133 register_language_string(lang_c, msgtab->ident, msgtab->text);
138 void register_language_string(struct language *lang, char *ident, char *text) {
139 int cindex = get_entry_index(ident);
140 struct language_table *lang_entry;
141 for(lang_entry = lang->entrys[cindex]; lang_entry; lang_entry = lang_entry->next) {
142 if(!strcmp(lang_entry->ident, ident)) break;
145 lang_entry = malloc(sizeof(*lang_entry));
147 printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
150 lang_entry->ident = strdup(ident);
151 lang_entry->next = lang->entrys[cindex];
152 lang->entrys[cindex] = lang_entry;
154 free(lang_entry->text); //free old text (new one will be set below)
166 tmppos += sprintf(tmp + tmppos, "%s", b);
179 //unknown - just write it
180 tmppos += sprintf(tmp + tmppos, "$%c", a[1]);
185 lang_entry->text = strdup(tmp);
188 char *get_language_string(struct UserNode *user, const char* msg_ident) {
189 struct language* lang;
190 if(user && (user->flags & USERFLAG_ISAUTHED)) {
191 loadUserSettings(user);
192 lang = user->language;
195 int cindex = get_entry_index(msg_ident);
196 struct language_table* entry;
197 for(entry = lang->entrys[cindex]; entry; entry = entry->next) {
198 if(!strcmp(entry->ident, msg_ident))
201 if(lang == lang_c) return NULL;
202 for(entry = lang_c->entrys[cindex]; entry; entry = entry->next) {
203 if(!strcmp(entry->ident, msg_ident))
209 char *build_language_string(struct UserNode *user, char *buffer, const char *msg_ident, ...) {
210 char *formatStr = get_language_string(user, msg_ident);
211 if(!formatStr) return NULL;
213 buffer = (char *)malloc((MAXLEN+1) * sizeof(char));
215 printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
222 va_start(arg_list, msg_ident);
223 pos = vsnprintf(buffer, MAXLEN - 2, formatStr, arg_list);
225 if (pos < 0 || pos > (MAXLEN - 2)) pos = MAXLEN - 2;