Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: f5b33c992b
Fetching contributors…

Cannot retrieve contributors at this time

336 lines (293 sloc) 7.019 kb
/*
* atheme-services: A collection of minimalist IRC services
* culture.c: Translation framework.
*
* Copyright (c) 2005-2009 Atheme Project (http://www.atheme.org)
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "atheme.h"
#include "internal.h"
#include <dirent.h>
struct translation_
{
char *name;
char *replacement;
};
typedef struct translation_ translation_t;
static mowgli_patricia_t *itranslation_tree; /* internal translations, userserv/nickserv etc */
static mowgli_patricia_t *translation_tree; /* language translations */
/*
* translation_init()
*
* Initializes the translation DTrees.
*
* Inputs:
* - none
*
* Outputs:
* - nothing
*
* Side Effects:
* - on success, nothing
* - on failure, the program will abort
*/
void translation_init(void)
{
itranslation_tree = mowgli_patricia_create(noopcanon);
translation_tree = mowgli_patricia_create(noopcanon);
}
/*
* translation_get(const char *str)
*
* Inputs:
* - string to get translation for
*
* Outputs:
* - translated string, or the original string if no translation
* was found
*
* Side Effects:
* - none
*/
const char *translation_get(const char *str)
{
translation_t *t;
/* See if an internal substitution is present. */
if ((t = mowgli_patricia_retrieve(itranslation_tree, str)) != NULL)
str = t->replacement;
if ((t = mowgli_patricia_retrieve(translation_tree, str)) != NULL)
return t->replacement;
return str;
}
/*
* itranslation_create(const char *str, const char *trans)
*
* Inputs:
* - string to translate, translation of the string
*
* Outputs:
* - none
*
* Side Effects:
* - a new translation is added to the cache
*/
void itranslation_create(const char *str, const char *trans)
{
translation_t *t = smalloc(sizeof(translation_t));
t->name = sstrdup(str);
t->replacement = sstrdup(trans);
mowgli_patricia_add(itranslation_tree, t->name, t);
}
/*
* itranslation_destroy(const char *str)
*
* Inputs:
* - string to remove from the translation cache
*
* Outputs:
* - none
*
* Side Effects:
* - a string is removed from the translation cache
*/
void itranslation_destroy(const char *str)
{
translation_t *t = mowgli_patricia_delete(itranslation_tree, str);
if (t == NULL)
return;
free(t->name);
free(t->replacement);
free(t);
}
/*
* translation_create(const char *str, const char *trans)
*
* Inputs:
* - string to translate, translation of the string
*
* Outputs:
* - none
*
* Side Effects:
* - a new translation is added to the cache
*/
void translation_create(const char *str, const char *trans)
{
char buf[BUFSIZE];
translation_t *t = smalloc(sizeof(translation_t));
mowgli_strlcpy(buf, str, BUFSIZE);
replace(buf, BUFSIZE, "\\2", "\2");
t->name = sstrdup(buf);
mowgli_strlcpy(buf, trans, BUFSIZE);
replace(buf, BUFSIZE, "\\2", "\2");
t->replacement = sstrdup(buf);
mowgli_patricia_add(translation_tree, t->name, t);
}
/*
* translation_destroy(const char *str)
*
* Inputs:
* - string to remove from the translation cache
*
* Outputs:
* - none
*
* Side Effects:
* - a string is removed from the translation cache
*/
void translation_destroy(const char *str)
{
translation_t *t = mowgli_patricia_delete(translation_tree, str);
if (t == NULL)
return;
free(t->name);
free(t->replacement);
free(t);
}
enum
{
LANG_VALID = 1 /* have catalogs for this */
};
struct language_
{
char *name;
unsigned int flags; /* LANG_* */
mowgli_node_t node;
};
static mowgli_list_t language_list;
void
language_init(void)
{
DIR *dir;
struct dirent *ent;
language_t *lang;
lang = language_add("en");
lang->flags |= LANG_VALID;
dir = opendir(LOCALEDIR);
if (dir != NULL)
{
while ((ent = readdir(dir)) != NULL)
{
if (ent->d_name[0] != '.' &&
strcmp(ent->d_name, "all_languages") &&
strcmp(ent->d_name, "locale.alias") &&
strcmp(ent->d_name, "default"))
{
lang = language_add(ent->d_name);
lang->flags |= LANG_VALID;
}
}
closedir(dir);
}
}
language_t *
language_add(const char *name)
{
language_t *lang;
if (!strcmp(name, "default"))
return NULL;
lang = language_find(name);
if (lang != NULL)
return lang;
slog(LG_DEBUG, "language_add(): %s", name);
lang = smalloc(sizeof(*lang));
lang->name = sstrdup(name);
mowgli_node_add(lang, &lang->node, &language_list);
return lang;
}
language_t *
language_find(const char *name)
{
mowgli_node_t *n;
language_t *lang;
MOWGLI_ITER_FOREACH(n, language_list.head)
{
lang = n->data;
if (!strcmp(lang->name, name))
return lang;
}
return NULL;
}
const char *
language_names(void)
{
static char names[512];
mowgli_node_t *n;
language_t *lang;
names[0] = '\0';
MOWGLI_ITER_FOREACH(n, language_list.head)
{
lang = n->data;
if (lang->flags & LANG_VALID)
{
if (names[0] != '\0')
mowgli_strlcat(names, " ", sizeof names);
mowgli_strlcat(names, lang->name, sizeof names);
}
}
return names;
}
const char *
language_get_name(const language_t *lang)
{
if (lang == NULL)
return "default";
return lang->name;
}
const char *
language_get_real_name(const language_t *lang)
{
if (lang == NULL)
return config_options.language;
return lang->name;
}
bool
language_is_valid(const language_t *lang)
{
if (lang == NULL)
return true;
return (lang->flags & LANG_VALID) != 0;
}
void
language_set_active(language_t *lang)
{
#ifdef ENABLE_NLS
static language_t *currlang;
if (lang == NULL)
{
lang = language_find(config_options.language);
if (lang == NULL)
lang = language_find("en");
}
if (currlang == lang)
return;
slog(LG_DEBUG, "language_set_active(): changing language from [%s] to [%s]",
currlang != NULL ? currlang->name : "default",
lang->name);
setlocale(LC_MESSAGES, lang->name);
textdomain(PACKAGE_NAME);
bindtextdomain(PACKAGE_NAME, LOCALEDIR);
currlang = lang;
setenv("LANGUAGE", currlang->name, 1);
#endif
}
/* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
* vim:ts=8
* vim:sw=8
* vim:noexpandtab
*/
Jump to Line
Something went wrong with that request. Please try again.