server/src/common/kernel/order.c
Enno Rehling 3bf96bdb12 http://eressea.upb.de/mantis/view.php?id=480
FOLGE SCHIFF wird ein langer Befehl

Neuer Parameter --lomem, um unkritische Strings zu ignorieren (spart mindestens 150 MB Speicher). Nicht für echte Auswertungen verwenden!

Tests für display/name/etc == NULL
2005-04-23 09:47:03 +00:00

185 lines
3.5 KiB
C

/* vi: set ts=2:
+-------------------+
| | Christian Schlittchen <corwin@amber.kn-bremen.de>
| Eressea PBEM host | Enno Rehling <enno@eressea-pbem.de>
| (c) 1998 - 2004 | Katja Zedel <katze@felidae.kn-bremen.de>
| |
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
*/
#include <config.h>
#include "eressea.h"
#include "order.h"
/* libc includes */
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
static const struct locale * locale_array[16];
static int nlocales = 0;
#undef SHORT_STRINGS
keyword_t
get_keyword(const order * ord)
{
if (ord==NULL) {
return NOKEYWORD;
}
return ord->_keyword;
}
char *
getcommand(const order * ord)
{
char sbuffer[DISPLAYSIZE*2];
char * str = sbuffer;
assert(ord->_lindex<nlocales);
if (ord->_persistent) *str++ = '@';
#ifdef SHORT_STRINGS
if (ord->_keyword!=NOKEYWORD) {
const struct locale * lang = locale_array[ord->_lindex];
strcpy(str, LOC(lang, keywords[ord->_keyword]));
str += strlen(str);
if (ord->_str) {
*str++ = ' ';
*str = 0;
}
}
#endif
strcpy(str, ord->_str);
return strdup(sbuffer);
}
void
free_order(order * ord)
{
if (ord!=NULL && --ord->_refcount==0) {
assert(ord->next==NULL);
if (ord->_str!=NULL) free(ord->_str);
free(ord);
}
}
order *
copy_order(order * ord)
{
if (ord!=NULL) ++ord->_refcount;
return ord;
}
void
set_order(struct order ** destp, struct order * src)
{
if (*destp==src) return;
free_order(*destp);
*destp = copy_order(src);
}
void
free_orders(order ** olist)
{
while (*olist) {
order * ord = *olist;
*olist = ord->next;
ord->next = NULL;
free_order(ord);
}
}
order *
parse_order(const char * s, const struct locale * lang)
{
while (*s && !isalnum(*(unsigned char*)s) && !ispunct(*(unsigned char*)s)) ++s;
if (*s==0) return NULL;
else {
keyword_t kwd;
const char * sptr;
order * ord = NULL;
int persistent = 0;
int i;
#ifdef AT_PERSISTENT
while (*s=='@') {
persistent = 1;
++s;
}
#endif
sptr = s;
kwd = findkeyword(parse_token(&sptr), lang);
/* if this is just nonsense, then we skip it. */
if (lomem) {
switch (kwd) {
case K_KOMMENTAR:
case NOKEYWORD:
return NULL;
default:
break;
}
}
ord = (order*)malloc(sizeof(order));
for (i=0;i!=nlocales;++i) {
if (locale_array[i]==lang) break;
}
if (i==nlocales) locale_array[nlocales++] = lang;
ord->_lindex = (unsigned char)i;
ord->_str = NULL;
ord->_persistent = persistent;
ord->_refcount = 1;
ord->next = NULL;
ord->_keyword = kwd;
#ifdef SHORT_STRINGS
if (ord->_keyword==NOKEYWORD) {
ord->_str = strdup(s);
} else {
while (isspace(*(unsigned char*)sptr)) ++sptr;
if (*sptr) {
ord->_str = strdup(sptr);
}
}
#else
ord->_str = strdup(s);
#endif
return ord;
}
}
boolean
is_persistent(const order * cmd)
{
switch (cmd->_keyword) {
case NOKEYWORD:
return false;
case K_KOMMENTAR:
case K_LIEFERE:
return true;
}
#ifdef AT_PERSISTENT
if (cmd->_persistent) return true;
#endif /* Nur kurze Befehle! */
return false;
}
char *
write_order(const order * ord, const struct locale * lang, char * buffer, size_t size)
{
if (ord==0 || ord->_keyword==NOKEYWORD) {
buffer[0]=0;
} else {
char * s = getcommand(ord);
strncpy(buffer, s, size);
free(s);
}
return buffer;
}