2015-01-30 20:37:14 +01:00
|
|
|
/*
|
2010-08-08 10:06:34 +02:00
|
|
|
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
|
|
|
| | Enno Rehling <enno@eressea.de>
|
|
|
|
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
|
|
|
| (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de>
|
|
|
|
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
|
|
|
|
+-------------------+ Stefan Reich <reich@halbling.de>
|
|
|
|
|
|
|
|
This program may not be used, modified or distributed
|
|
|
|
without prior permission by the authors of Eressea.
|
|
|
|
|
2015-01-30 20:37:14 +01:00
|
|
|
*/
|
2010-08-08 10:06:34 +02:00
|
|
|
|
|
|
|
#include <platform.h>
|
|
|
|
#include "nrmessage.h"
|
|
|
|
#include "nrmessage_struct.h"
|
|
|
|
|
|
|
|
/* util includes */
|
|
|
|
#include "log.h"
|
|
|
|
#include "message.h"
|
|
|
|
#include "language.h"
|
|
|
|
#include "translation.h"
|
2015-05-18 08:59:38 +02:00
|
|
|
#include "strings.h"
|
2010-08-08 10:06:34 +02:00
|
|
|
|
|
|
|
/* libc includes */
|
|
|
|
#include <assert.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#define NRT_MAXHASH 1021
|
2011-03-07 08:02:35 +01:00
|
|
|
static nrmessage_type *nrtypes[NRT_MAXHASH];
|
2010-08-08 10:06:34 +02:00
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
const char *nrt_string(const struct nrmessage_type *type)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2018-05-17 16:53:56 +02:00
|
|
|
if (type->string) {
|
|
|
|
return type->string;
|
|
|
|
}
|
|
|
|
return locale_get(type->lang, type->mtype->name);
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
nrmessage_type *nrt_find(const struct locale * lang,
|
2015-01-30 20:37:14 +01:00
|
|
|
const struct message_type * mtype)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
nrmessage_type *found = NULL;
|
2016-09-11 21:29:42 +02:00
|
|
|
unsigned int hash = mtype->key % NRT_MAXHASH;
|
2015-01-30 20:37:14 +01:00
|
|
|
nrmessage_type *type = nrtypes[hash];
|
|
|
|
while (type) {
|
|
|
|
if (type->mtype == mtype) {
|
|
|
|
if (found == NULL)
|
|
|
|
found = type;
|
|
|
|
else if (type->lang == NULL)
|
|
|
|
found = type;
|
|
|
|
if (lang == type->lang) {
|
|
|
|
found = type;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
type = type->next;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
2015-01-30 20:37:14 +01:00
|
|
|
if (!found) {
|
|
|
|
log_warning("could not find nr-type %s for locale %s\n", mtype->name, locale_name(lang));
|
|
|
|
}
|
|
|
|
if (lang && found && found->lang != lang) {
|
|
|
|
log_warning("could not find nr-type %s for locale %s, using %s\n", mtype->name, locale_name(lang), locale_name(found->lang));
|
|
|
|
}
|
|
|
|
return found;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
nrsection *sections;
|
2010-08-08 10:06:34 +02:00
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
const nrsection *section_find(const char *name)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
nrsection **mcp = §ions;
|
|
|
|
if (name == NULL)
|
|
|
|
return NULL;
|
|
|
|
for (; *mcp; mcp = &(*mcp)->next) {
|
|
|
|
nrsection *mc = *mcp;
|
|
|
|
if (!strcmp(mc->name, name))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return *mcp;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
const nrsection *section_add(const char *name)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
nrsection **mcp = §ions;
|
|
|
|
if (name == NULL)
|
|
|
|
return NULL;
|
|
|
|
for (; *mcp; mcp = &(*mcp)->next) {
|
|
|
|
nrsection *mc = *mcp;
|
|
|
|
if (!strcmp(mc->name, name))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!*mcp) {
|
|
|
|
nrsection *mc = calloc(sizeof(nrsection), 1);
|
2017-12-28 18:29:40 +01:00
|
|
|
mc->name = str_strdup(name);
|
2015-01-30 20:37:14 +01:00
|
|
|
*mcp = mc;
|
|
|
|
}
|
|
|
|
return *mcp;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-03-07 08:02:35 +01:00
|
|
|
nrt_register(const struct message_type *mtype, const struct locale *lang,
|
2015-01-30 20:37:14 +01:00
|
|
|
const char *string, int level, const char *section)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2016-09-11 21:29:42 +02:00
|
|
|
unsigned int hash = mtype->key % NRT_MAXHASH;
|
2015-01-30 20:37:14 +01:00
|
|
|
nrmessage_type *nrt = nrtypes[hash];
|
|
|
|
while (nrt && (nrt->lang != lang || nrt->mtype != mtype)) {
|
|
|
|
nrt = nrt->next;
|
|
|
|
}
|
|
|
|
if (nrt) {
|
|
|
|
log_error("duplicate message-type %s\n", mtype->name);
|
|
|
|
assert(!nrt || !"trying to register same nr-type twice");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
int i;
|
|
|
|
char zNames[256];
|
|
|
|
char *c = zNames;
|
|
|
|
nrt = malloc(sizeof(nrmessage_type));
|
|
|
|
nrt->lang = lang;
|
|
|
|
nrt->mtype = mtype;
|
|
|
|
nrt->next = nrtypes[hash];
|
|
|
|
nrt->level = level;
|
|
|
|
if (section) {
|
|
|
|
const nrsection *s = section_find(section);
|
|
|
|
if (s == NULL) {
|
|
|
|
s = section_add(section);
|
|
|
|
}
|
|
|
|
nrt->section = s->name;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nrt->section = NULL;
|
|
|
|
nrtypes[hash] = nrt;
|
|
|
|
assert(string && *string);
|
2017-12-28 18:29:40 +01:00
|
|
|
nrt->string = str_strdup(string);
|
2015-01-30 20:37:14 +01:00
|
|
|
*c = '\0';
|
|
|
|
for (i = 0; i != mtype->nparameters; ++i) {
|
|
|
|
if (i != 0)
|
|
|
|
*c++ = ' ';
|
2017-12-30 19:49:21 +01:00
|
|
|
c += str_strlcpy(c, mtype->pnames[i], sizeof(zNames)-(c-zNames));
|
2015-01-30 20:37:14 +01:00
|
|
|
}
|
2017-12-28 18:29:40 +01:00
|
|
|
nrt->vars = str_strdup(zNames);
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
2011-03-07 08:02:35 +01:00
|
|
|
nr_render(const struct message *msg, const struct locale *lang, char *buffer,
|
2015-01-30 20:37:14 +01:00
|
|
|
size_t size, const void *userdata)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
struct nrmessage_type *nrt = nrt_find(lang, msg->type);
|
|
|
|
|
|
|
|
if (nrt) {
|
|
|
|
const char *m =
|
2018-05-17 16:53:56 +02:00
|
|
|
translate(nrt_string(nrt), userdata, nrt->vars, msg->parameters);
|
2015-01-30 20:37:14 +01:00
|
|
|
if (m) {
|
2017-12-30 19:49:21 +01:00
|
|
|
return str_strlcpy((char *)buffer, m, size);
|
2015-01-30 20:37:14 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
log_error("Couldn't render message %s\n", nrt->mtype->name);
|
|
|
|
}
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
2015-01-30 20:37:14 +01:00
|
|
|
if (size > 0 && buffer)
|
|
|
|
buffer[0] = 0;
|
|
|
|
return 0;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
int nr_level(const struct message *msg)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
nrmessage_type *nrt = nrt_find(NULL, msg->type);
|
|
|
|
return nrt ? nrt->level : 0;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
const char *nr_section(const struct message *msg)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
nrmessage_type *nrt = nrt_find(default_locale, msg->type);
|
|
|
|
return nrt ? nrt->section : NULL;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
const char *nrt_section(const nrmessage_type * nrt)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2015-01-30 20:37:14 +01:00
|
|
|
return nrt ? nrt->section : NULL;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
2017-01-23 21:35:01 +01:00
|
|
|
|
|
|
|
void free_nrmesssages(void) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i != NRT_MAXHASH; ++i) {
|
|
|
|
while (nrtypes[i]) {
|
|
|
|
nrmessage_type *nr = nrtypes[i];
|
|
|
|
nrtypes[i] = nr->next;
|
|
|
|
free(nr->string);
|
|
|
|
free(nr->vars);
|
|
|
|
free(nr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-05-16 21:58:02 +02:00
|
|
|
|
2018-05-17 10:43:23 +02:00
|
|
|
void export_messages(const struct locale * lang, FILE *F, const char *context) {
|
2018-05-16 21:58:02 +02:00
|
|
|
int i;
|
|
|
|
for (i = 0; i != NRT_MAXHASH; ++i) {
|
|
|
|
nrmessage_type *nrt = nrtypes[i];
|
|
|
|
while (nrt) {
|
2018-05-17 10:43:23 +02:00
|
|
|
po_write_msg(F, nrt->mtype->name, nrt->string, context);
|
2018-05-16 21:58:02 +02:00
|
|
|
nrt = nrt->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|