/* +-------------------+ Christian Schlittchen | | Enno Rehling | Eressea PBEM host | Katja Zedel | (c) 1998 - 2003 | Henning Peters | | Ingo Wilken +-------------------+ Stefan Reich This program may not be used, modified or distributed without prior permission by the authors of Eressea. */ #include #include "crmessage.h" #include "message.h" #include "strings.h" #include "log.h" #include #include #include #include /** type to string conversion **/ typedef struct tsf_list { struct tsf_list *next; const char *name; tostring_f fun; } tsf_list; static tsf_list *tostringfs; static tostring_f tsf_find(const char *name) { if (name != NULL) { tsf_list *tsf; for (tsf = tostringfs; tsf; tsf = tsf->next) { if (!strcmp(tsf->name, name)) return tsf->fun; } } return NULL; } void tsf_register(const char *name, tostring_f fun) { 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; } } /** crmesssage **/ typedef struct crmessage_type { const struct message_type *mtype; tostring_f *renderers; struct crmessage_type *next; } crmessage_type; #define CRMAXHASH 63 static crmessage_type *crtypes[CRMAXHASH]; static crmessage_type *crt_find(const struct message_type *mtype) { unsigned int hash = hashstring(mtype->name) % CRMAXHASH; crmessage_type *found = NULL; crmessage_type *type = crtypes[hash]; while (type) { if (type->mtype == mtype) found = type; type = type->next; } return found; } void crt_register(const struct message_type *mtype) { unsigned int hash = hashstring(mtype->name) % CRMAXHASH; crmessage_type *crt = crtypes[hash]; while (crt && crt->mtype != mtype) { crt = crt->next; } if (!crt) { int i; crt = malloc(sizeof(crmessage_type)); crt->mtype = mtype; crt->next = crtypes[hash]; crtypes[hash] = crt; if (mtype->nparameters > 0) { crt->renderers = malloc(sizeof(tostring_f) * mtype->nparameters); } else { crt->renderers = NULL; } /* can be scrapped for memory vs. speed */ for (i = 0; i != mtype->nparameters; ++i) { crt->renderers[i] = tsf_find(mtype->types[i]->name); } } } int cr_render(const message * msg, char *buffer, const void *userdata) { 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; } int cr_string(variant var, char *buffer, const void *userdata) { sprintf(buffer, "\"%s\"", (const char *)var.v); unused_arg(userdata); return 0; } int cr_int(variant var, char *buffer, const void *userdata) { sprintf(buffer, "%d", var.i); unused_arg(userdata); return 0; } int cr_ignore(variant var, char *buffer, const void *userdata) { unused_arg(var); unused_arg(buffer); unused_arg(userdata); return -1; }