/* vi: set ts=2: +-------------------+ 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 "nrmessage.h" #include "nrmessage_struct.h" /* util includes */ #include "bsdstring.h" #include "log.h" #include "message.h" #include "language.h" #include "translation.h" #include "goodies.h" /* libc includes */ #include #include #include #define NRT_MAXHASH 1021 static nrmessage_type *nrtypes[NRT_MAXHASH]; const char *nrt_string(const struct nrmessage_type *type) { return type->string; } nrmessage_type *nrt_find(const struct locale * lang, const struct message_type * mtype) { nrmessage_type *found = NULL; unsigned int hash = hashstring(mtype->name) % NRT_MAXHASH; 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; } 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; } nrsection *sections; const nrsection *section_find(const char *name) { nrsection **mcp = §ions; if (name == NULL) return NULL; for (; *mcp; mcp = &(*mcp)->next) { nrsection *mc = *mcp; if (!strcmp(mc->name, name)) break; } return *mcp; } const nrsection *section_add(const char *name) { 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); mc->name = _strdup(name); *mcp = mc; } return *mcp; } void nrt_register(const struct message_type *mtype, const struct locale *lang, const char *string, int level, const char *section) { unsigned int hash = hashstring(mtype->name) % NRT_MAXHASH; 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); nrt->string = _strdup(string); *c = '\0'; for (i = 0; i != mtype->nparameters; ++i) { if (i != 0) *c++ = ' '; c += strlen(strcpy(c, mtype->pnames[i])); } nrt->vars = _strdup(zNames); } } size_t nr_render(const struct message *msg, const struct locale *lang, char *buffer, size_t size, const void *userdata) { struct nrmessage_type *nrt = nrt_find(lang, msg->type); if (nrt) { const char *m = translate(nrt->string, userdata, nrt->vars, msg->parameters); if (m) { return strlcpy((char *)buffer, m, size); } else { log_error("Couldn't render message %s\n", nrt->mtype->name); } } if (size > 0 && buffer) buffer[0] = 0; return 0; } int nr_level(const struct message *msg) { nrmessage_type *nrt = nrt_find(NULL, msg->type); return nrt ? nrt->level : 0; } const char *nr_section(const struct message *msg) { nrmessage_type *nrt = nrt_find(default_locale, msg->type); return nrt ? nrt->section : NULL; } const char *nrt_section(const nrmessage_type * nrt) { return nrt ? nrt->section : NULL; }