2010-08-08 10:06:34 +02:00
|
|
|
/* vi: set ts=2:
|
|
|
|
+-------------------+ 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.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <platform.h>
|
|
|
|
#include "crmessage.h"
|
|
|
|
|
|
|
|
#include "message.h"
|
|
|
|
#include "goodies.h"
|
|
|
|
#include "log.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
/** type to string conversion **/
|
|
|
|
typedef struct tsf_list {
|
2011-03-07 08:02:35 +01:00
|
|
|
struct tsf_list *next;
|
|
|
|
const char *name;
|
|
|
|
tostring_f fun;
|
2010-08-08 10:06:34 +02:00
|
|
|
} tsf_list;
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
static tsf_list *tostringfs;
|
2010-08-08 10:06:34 +02:00
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
static tostring_f tsf_find(const char *name)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2011-03-07 08:02:35 +01:00
|
|
|
if (name != NULL) {
|
|
|
|
tsf_list *tsf;
|
|
|
|
for (tsf = tostringfs; tsf; tsf = tsf->next) {
|
|
|
|
if (!strcmp(tsf->name, name))
|
|
|
|
return tsf->fun;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
void tsf_register(const char *name, tostring_f fun)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2011-03-07 08:02:35 +01:00
|
|
|
tsf_list *tsf;
|
|
|
|
for (tsf = tostringfs; tsf; tsf = tsf->next) {
|
|
|
|
if (!strcmp(tsf->name, name))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (tsf == NULL) {
|
|
|
|
tsf = malloc(sizeof(tsf_list));
|
|
|
|
tsf->fun = fun;
|
|
|
|
tsf->name = name;
|
|
|
|
tsf->next = tostringfs;
|
|
|
|
tostringfs = tsf;
|
|
|
|
}
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/** crmesssage **/
|
|
|
|
typedef struct crmessage_type {
|
2011-03-07 08:02:35 +01:00
|
|
|
const struct message_type *mtype;
|
|
|
|
tostring_f *renderers;
|
|
|
|
struct crmessage_type *next;
|
2010-08-08 10:06:34 +02:00
|
|
|
} crmessage_type;
|
|
|
|
|
|
|
|
#define CRMAXHASH 63
|
2011-03-07 08:02:35 +01:00
|
|
|
static crmessage_type *crtypes[CRMAXHASH];
|
2010-08-08 10:06:34 +02:00
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
static crmessage_type *crt_find(const struct message_type *mtype)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
|
|
|
unsigned int hash = hashstring(mtype->name) % CRMAXHASH;
|
2011-03-07 08:02:35 +01:00
|
|
|
crmessage_type *found = NULL;
|
|
|
|
crmessage_type *type = crtypes[hash];
|
2010-08-08 10:06:34 +02:00
|
|
|
while (type) {
|
2011-03-07 08:02:35 +01:00
|
|
|
if (type->mtype == mtype)
|
|
|
|
found = type;
|
2010-08-08 10:06:34 +02:00
|
|
|
type = type->next;
|
|
|
|
}
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
void crt_register(const struct message_type *mtype)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
|
|
|
unsigned int hash = hashstring(mtype->name) % CRMAXHASH;
|
2011-03-07 08:02:35 +01:00
|
|
|
crmessage_type *crt = crtypes[hash];
|
|
|
|
while (crt && crt->mtype != mtype) {
|
2010-08-08 10:06:34 +02:00
|
|
|
crt = crt->next;
|
|
|
|
}
|
|
|
|
if (!crt) {
|
|
|
|
int i;
|
|
|
|
crt = malloc(sizeof(crmessage_type));
|
|
|
|
crt->mtype = mtype;
|
|
|
|
crt->next = crtypes[hash];
|
|
|
|
crtypes[hash] = crt;
|
2011-03-07 08:02:35 +01:00
|
|
|
if (mtype->nparameters > 0) {
|
|
|
|
crt->renderers = malloc(sizeof(tostring_f) * mtype->nparameters);
|
2010-08-08 10:06:34 +02:00
|
|
|
} else {
|
|
|
|
crt->renderers = NULL;
|
|
|
|
}
|
2011-03-07 08:02:35 +01:00
|
|
|
|
2010-08-08 10:06:34 +02:00
|
|
|
/* can be scrapped for memory vs. speed */
|
2011-03-07 08:02:35 +01:00
|
|
|
for (i = 0; i != mtype->nparameters; ++i) {
|
2010-08-08 10:06:34 +02:00
|
|
|
crt->renderers[i] = tsf_find(mtype->types[i]->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
int cr_render(const message * msg, char *buffer, const void *userdata)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2011-03-07 08:02:35 +01:00
|
|
|
int i;
|
|
|
|
char *c = buffer;
|
|
|
|
struct crmessage_type *crt = crt_find(msg->type);
|
|
|
|
|
|
|
|
if (crt == NULL)
|
|
|
|
return -1;
|
|
|
|
for (i = 0; i != msg->type->nparameters; ++i) {
|
|
|
|
if (crt->renderers[i] == NULL) {
|
|
|
|
log_error(("No renderer for argument %s:%s of \"%s\"\n",
|
|
|
|
msg->type->pnames[i], msg->type->types[i]->name, msg->type->name));
|
|
|
|
continue; /* strcpy(c, (const char*)msg->locale_string(u->faction->locale, parameters[i])); */
|
|
|
|
} else {
|
|
|
|
if (crt->renderers[i] (msg->parameters[i], c, userdata) != 0)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
c += strlen(c);
|
|
|
|
sprintf(c, ";%s\n", msg->type->pnames[i]);
|
|
|
|
c += strlen(c);
|
|
|
|
}
|
|
|
|
return 0;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
int cr_string(variant var, char *buffer, const void *userdata)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2011-03-07 08:02:35 +01:00
|
|
|
sprintf(buffer, "\"%s\"", (const char *)var.v);
|
|
|
|
unused(userdata);
|
|
|
|
return 0;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
int cr_int(variant var, char *buffer, const void *userdata)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2011-03-07 08:02:35 +01:00
|
|
|
sprintf(buffer, "%d", var.i);
|
|
|
|
unused(userdata);
|
|
|
|
return 0;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
int cr_ignore(variant var, char *buffer, const void *userdata)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2011-03-07 08:02:35 +01:00
|
|
|
unused(var);
|
|
|
|
unused(buffer);
|
|
|
|
unused(userdata);
|
|
|
|
return -1;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|