6 #define DEFAULT_LANG_TAG "EN"
7 #define DEFAULT_LANG_NAME "English"
9 static struct language **langdict;
10 static struct language *lang_c;
13 langdict = calloc(MAXLANGUAGES, sizeof(*langdict));
20 void load_languages() {
23 printf_mysql_query("SELECT `lang`, `text` FROM `language` WHERE `ident` = 'name'");
25 while((row = mysql_fetch_row(res)) != NULL) {
26 load_language(row[0], row[1]);
30 static struct language* add_language(char *langtag, char *langname) {
32 for(cindex = 0; cindex < MAXLANGUAGES; cindex++) {
33 if(langdict[cindex] == NULL) break;
34 if(!strcmp(langdict[cindex]->langname, langname) || !strcmp(langdict[cindex]->langtag, langtag))
35 return langdict[cindex];
37 if(cindex == MAXLANGUAGES) return NULL;
38 struct language *lang = malloc(sizeof(*lang));
40 perror("malloc() failed");
43 lang->langtag = strdup(langtag);
44 lang->langname = strdup(langname);
45 struct language_table **entrys = calloc(27, sizeof(*entrys));
46 lang->entrys = entrys;
47 langdict[cindex] = lang;
51 static int get_entry_index(const char *ident) {
52 const char *underscore = strstr(ident, "_");
53 if(!underscore || !(underscore[1] >= 65 && underscore[1] <= 90)) return 26;
54 return (underscore[1] - 'A');
57 void load_language(char *tag, char *name) {
58 struct language *lang = get_language_by_tag(tag);
59 if(lang == get_default_language()) return;
63 struct language_table *entry, *next;
64 for(cindex = 0; cindex < 27; cindex++) {
65 for(entry = lang->entrys[cindex]; entry; entry = next) {
71 lang->entrys[cindex] = NULL;
74 lang = add_language(tag, name);
78 printf_mysql_query("SELECT `ident`, `text` FROM `language` WHERE `lang` = '%s' AND `ident` != 'name'", escape_string(tag));
80 while((row = mysql_fetch_row(res)) != NULL) {
81 register_language_string(lang, row[0], row[1]);
85 struct language* get_language_by_tag(char *tag) {
87 for(cindex = 0; cindex < MAXLANGUAGES; cindex++) {
88 if(langdict[cindex] == NULL) break;
89 if(!strcmp(langdict[cindex]->langtag, tag))
90 return langdict[cindex];
95 struct language* get_language_by_name(char *name) {
97 for(cindex = 0; cindex < MAXLANGUAGES; cindex++) {
98 if(langdict[cindex] == NULL) break;
99 if(!strcmp(langdict[cindex]->langname, name))
100 return langdict[cindex];
105 struct language* get_default_language() {
107 lang_c = add_language(DEFAULT_LANG_TAG, DEFAULT_LANG_NAME);
111 void register_default_language_table(const struct default_language_entry *msgtab) {
113 lang_c = add_language(DEFAULT_LANG_TAG, DEFAULT_LANG_NAME);
114 struct language_table *lang_entry;
116 while(msgtab->ident) {
117 cindex = get_entry_index(msgtab->ident);
118 lang_entry = malloc(sizeof(*lang_entry));
120 perror("malloc() failed");
123 lang_entry->ident = strdup(msgtab->ident);
124 lang_entry->text = strdup(msgtab->text);
125 lang_entry->next = lang_c->entrys[cindex];
126 lang_c->entrys[cindex] = lang_entry;
131 void register_language_string(struct language *lang, char *ident, char *text) {
132 int cindex = get_entry_index(ident);
133 struct language_table *lang_entry = malloc(sizeof(*lang_entry));
135 perror("malloc() failed");
138 lang_entry->ident = strdup(ident);
139 lang_entry->text = strdup(text);
140 lang_entry->next = lang->entrys[cindex];
141 lang->entrys[cindex] = lang_entry;
144 char *get_language_string(struct UserNode *user, const char* msg_ident) {
145 struct language* lang;
146 if((user->flags & USERFLAG_ISAUTHED)) {
147 loadUserSettings(user);
148 lang = user->language;
151 int cindex = get_entry_index(msg_ident);
152 struct language_table* entry;
153 for(entry = lang->entrys[cindex]; entry; entry = entry->next) {
154 if(!strcmp(entry->ident, msg_ident))
157 if(lang == lang_c) return NULL;
158 for(entry = lang_c->entrys[cindex]; entry; entry = entry->next) {
159 if(!strcmp(entry->ident, msg_ident))
165 char *build_language_string(struct UserNode *user, char *buffer, const char *msg_ident, ...) {
166 char *formatStr = get_language_string(user, msg_ident);
167 if(!formatStr) return NULL;
169 buffer = (char *)malloc((MAXLEN+1) * sizeof(char));
171 perror("malloc() failed");
178 va_start(arg_list, msg_ident);
179 pos = vsnprintf(buffer, MAXLEN - 2, formatStr, arg_list);
181 if (pos < 0 || pos > (MAXLEN - 2)) pos = MAXLEN - 2;