Unicode WIP, backward compat:

- latin1 reader for datafile
- latin1 reader for orders

a number of minor conversion bugs fixed, this version can now run a turn and write reports, it seems.
This commit is contained in:
Enno Rehling 2007-08-12 09:51:26 +00:00
parent b837248601
commit d4d6776b50
28 changed files with 794 additions and 669 deletions

View file

@ -17,11 +17,12 @@
#include "object.h" #include "object.h"
/* kernel includes */ /* kernel includes */
#include <kernel/unit.h> #include <kernel/building.h>
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/region.h> #include <kernel/region.h>
#include <kernel/save.h>
#include <kernel/ship.h> #include <kernel/ship.h>
#include <kernel/building.h> #include <kernel/unit.h>
/* util includes */ /* util includes */
#include <util/attrib.h> #include <util/attrib.h>

View file

@ -15,6 +15,8 @@
#include <attrib.h> #include <attrib.h>
#include "variable.h" #include "variable.h"
#include <kernel/save.h>
/* libc includes */ /* libc includes */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>

View file

@ -372,7 +372,7 @@ cr_skill(variant var, char * buffer, const void * userdata)
const faction * report = (const faction*)userdata; const faction * report = (const faction*)userdata;
skill_t sk = (skill_t)var.i; skill_t sk = (skill_t)var.i;
if (sk!=NOSKILL) sprintf(buffer, "\"%s\"", if (sk!=NOSKILL) sprintf(buffer, "\"%s\"",
add_translation(skillnames[sk], skillname(sk, report->locale))); add_translation(mkname("skill", skillnames[sk]), skillname(sk, report->locale)));
else strcpy(buffer, "\"\""); else strcpy(buffer, "\"\"");
return 0; return 0;
} }
@ -850,7 +850,7 @@ cr_output_unit(FILE * F, const region * r,
fprintf(F, "TALENTE\n"); fprintf(F, "TALENTE\n");
} }
fprintf(F, "%d %d;%s\n", u->number*level_days(sv->level), esk, fprintf(F, "%d %d;%s\n", u->number*level_days(sv->level), esk,
add_translation(skillnames[sk], skillname(sk, f->locale))); add_translation(mkname("skill", skillnames[sk]), skillname(sk, f->locale)));
} }
} }
/* spells */ /* spells */

View file

@ -1258,11 +1258,11 @@ init_prefixnames(void)
int key; int key;
for (key=0;race_prefixes[key];++key) { for (key=0;race_prefixes[key];++key) {
variant var; variant var;
const char * pname = locale_string(lang, race_prefixes[key]); const char * pname = locale_string(lang, mkname("prefix", race_prefixes[key]));
if (findtoken(&in->names, pname, &var)==E_TOK_NOMATCH || var.i!=key) { if (findtoken(&in->names, pname, &var)==E_TOK_NOMATCH || var.i!=key) {
var.i = key; var.i = key;
addtoken(&in->names, pname, var); addtoken(&in->names, pname, var);
addtoken(&in->names, locale_string(lang, race_prefixes[key]), var); addtoken(&in->names, locale_string(lang, mkname("prefix", race_prefixes[key])), var);
} }
} }
} }
@ -1883,7 +1883,7 @@ mail_cmd(unit * u, struct order * ord)
default: default:
/* possibly filler token? */ /* possibly filler token? */
s = getstrtoken(); s = getstrtoken();
cont = 1; if (s && *s) cont = 1;
break; break;
} }
} while (cont); } while (cont);

View file

@ -155,7 +155,7 @@ get_money_for_dragon(region * r, unit * u, int wanted)
if (rmoney(r) >= wanted) { if (rmoney(r) >= wanted) {
/* 5% chance, dass der drache aus einer laune raus attackiert */ /* 5% chance, dass der drache aus einer laune raus attackiert */
if (chance(1.0-u->race->aggression)) { if (chance(1.0-u->race->aggression)) {
return create_order(K_TAX, default_locale, ""); return create_order(K_TAX, default_locale, NULL);
} }
} }
@ -178,7 +178,7 @@ get_money_for_dragon(region * r, unit * u, int wanted)
/* falls die einnahmen erreicht werden, bleibt das monster noch eine /* falls die einnahmen erreicht werden, bleibt das monster noch eine
* runde hier. */ * runde hier. */
if (n + rmoney(r) >= wanted) { if (n + rmoney(r) >= wanted) {
return create_order(K_TAX, default_locale, ""); return create_order(K_TAX, default_locale, NULL);
} }
/* wenn wir NULL zurückliefern, macht der drache was anderes, z.b. weggehen */ /* wenn wir NULL zurückliefern, macht der drache was anderes, z.b. weggehen */
@ -965,7 +965,7 @@ plan_monsters(void)
/* All monsters guard the region: */ /* All monsters guard the region: */
if (!is_waiting(u) && r->land) { if (!is_waiting(u) && r->land) {
addlist(&u->orders, create_order(K_GUARD, u->faction->locale, "")); addlist(&u->orders, create_order(K_GUARD, u->faction->locale, NULL));
} }
/* Einheiten mit Bewegungsplan kriegen ein NACH: */ /* Einheiten mit Bewegungsplan kriegen ein NACH: */
@ -997,7 +997,7 @@ plan_monsters(void)
switch (old_race(u->race)) { switch (old_race(u->race)) {
case RC_SEASERPENT: case RC_SEASERPENT:
long_order = create_order(K_PIRACY, f->locale, ""); long_order = create_order(K_PIRACY, f->locale, NULL);
break; break;
case RC_ALP: case RC_ALP:
long_order = monster_seeks_target(r, u); long_order = monster_seeks_target(r, u);

View file

@ -38,7 +38,6 @@
/* kernel includes */ /* kernel includes */
#include <kernel/alchemy.h> #include <kernel/alchemy.h>
#include <kernel/alliance.h>
#include <kernel/border.h> #include <kernel/border.h>
#include <kernel/build.h> #include <kernel/build.h>
#include <kernel/building.h> #include <kernel/building.h>
@ -48,7 +47,6 @@
#include <kernel/item.h> #include <kernel/item.h>
#include <kernel/karma.h> #include <kernel/karma.h>
#include <kernel/message.h> #include <kernel/message.h>
#include <kernel/move.h>
#include <kernel/objtypes.h> #include <kernel/objtypes.h>
#include <kernel/order.h> #include <kernel/order.h>
#include <kernel/plane.h> #include <kernel/plane.h>
@ -77,7 +75,6 @@
#include <util/message.h> #include <util/message.h>
#include <util/nrmessage.h> #include <util/nrmessage.h>
#include <util/rng.h> #include <util/rng.h>
#include <util/translation.h>
/* libc includes */ /* libc includes */
#include <assert.h> #include <assert.h>
@ -621,34 +618,6 @@ rp_battles(FILE * F, faction * f)
} }
} }
size_t
f_regionid(const region * r, const faction * f, char * buffer, size_t size)
{
if (!r) {
strncpy(buffer, "(Chaos)", size);
} else {
plane * pl = r->planep;
strncpy(buffer, rname(r, f->locale), size);
buffer[size-1]=0;
if (pl==NULL || !fval(pl, PFL_NOCOORDS)) {
sprintf(buffer+strlen(buffer), " (%d,%d%s%s)", region_x(r,f), region_y(r,f), pl?",":"", pl?pl->name:"");
}
}
return strlen(buffer);
}
static char *
f_regionid_s(const region * r, const faction * f)
{
static int i = 0;
static char bufs[4][NAMESIZE + 20];
char * buf = bufs[(++i)%4];
f_regionid(r, f, buf, NAMESIZE + 20);
return buf;
}
static void static void
prices(FILE * F, const region * r, const faction * f) prices(FILE * F, const region * r, const faction * f)
{ {
@ -720,46 +689,6 @@ see_border(const border * b, const faction * f, const region * r)
return cs; return cs;
} }
const char *
trailinto(const region * r, const struct locale * lang)
{
char ref[32];
const char * s;
if (r) {
const char * tname = terrain_name(r);
strcat(strcpy(ref, tname), "_trail");
s = locale_string(lang, ref);
if (s && *s) {
if (strstr(s, "%s")) return s;
}
}
return "%s";
}
static void
eval_localize(struct opstack ** stack, const void * userdata) /* (string, locale) -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct locale * lang = f?f->locale:default_locale;
const char *c = (const char *)opop_v(stack);
c = locale_string(lang, c);
opush_v(stack, strcpy(balloc(strlen(c)+1), c));
}
static void
eval_trail(struct opstack ** stack, const void * userdata) /* (int, int) -> int */
{
const struct faction * f = (const struct faction *)userdata;
const struct locale * lang = f?f->locale:default_locale;
const struct region * r = (const struct region*)opop(stack).v;
const char * trail = trailinto(r, lang);
const char * rn = f_regionid_s(r, f);
variant var;
char * x = var.v = balloc(strlen(trail)+strlen(rn));
sprintf(x, trail, rn);
opush(stack, var);
}
static void static void
describe(FILE * F, const region * r, int partial, faction * f) describe(FILE * F, const region * r, int partial, faction * f)
{ {
@ -949,6 +878,7 @@ describe(FILE * F, const region * r, int partial, faction * f)
if(!r2) continue; if(!r2) continue;
nrd--; nrd--;
if (dh) { if (dh) {
char regname[4096];
if (nrd == 0) { if (nrd == 0) {
strcpy(bufp++, " "); strcpy(bufp++, " ");
bufp += strxcpy(bufp, LOC(f->locale, "nr_nb_final")); bufp += strxcpy(bufp, LOC(f->locale, "nr_nb_final"));
@ -958,7 +888,7 @@ describe(FILE * F, const region * r, int partial, faction * f)
bufp += strxcpy(bufp, LOC(f->locale, directions[d])); bufp += strxcpy(bufp, LOC(f->locale, directions[d]));
strcpy(bufp++, " "); strcpy(bufp++, " ");
bufp += sprintf(bufp, trailinto(r2, f->locale), bufp += sprintf(bufp, trailinto(r2, f->locale),
f_regionid_s(r2, f)); f_regionid(r2, f, regname, sizeof(regname)));
} }
else { else {
strcpy(bufp++, " "); strcpy(bufp++, " ");
@ -2326,374 +2256,9 @@ writemonument(void)
/******* end summary ******/ /******* end summary ******/
static void
eval_unit(struct opstack ** stack, const void * userdata) /* unit -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct unit * u = (const struct unit *)opop(stack).v;
const char * c = u?unitname(u):LOC(f->locale, "an_unknown_unit");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_unit_dative(struct opstack ** stack, const void * userdata) /* unit -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct unit * u = (const struct unit *)opop(stack).v;
const char * c = u?unitname(u):LOC(f->locale, "unknown_unit_dative");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_spell(struct opstack ** stack, const void * userdata) /* unit -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct spell * sp = (const struct spell *)opop(stack).v;
const char * c = sp?spell_name(sp, f->locale):LOC(f->locale, "an_unknown_spell");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_curse(struct opstack ** stack, const void * userdata) /* unit -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct curse_type * sp = (const struct curse_type *)opop(stack).v;
const char * c = sp?curse_name(sp, f->locale):LOC(f->locale, "an_unknown_curse");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_unitname(struct opstack ** stack, const void * userdata) /* unit -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct unit * u = (const struct unit *)opop(stack).v;
const char * c = u?u->name:LOC(f->locale, "an_unknown_unit");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_unitid(struct opstack ** stack, const void * userdata) /* unit -> int */
{
const struct faction * f = (const struct faction *)userdata;
const struct unit * u = (const struct unit *)opop(stack).v;
const char * c = u?u->name:LOC(f->locale, "an_unknown_unit");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_unitsize(struct opstack ** stack, const void * userdata) /* unit -> int */
{
const struct unit * u = (const struct unit *)opop(stack).v;
variant var;
var.i = u->number;
opush(stack, var);
}
static void
eval_faction(struct opstack ** stack, const void * userdata) /* faction -> string */
{
const struct faction * f = (const struct faction *)opop(stack).v;
const char * c = factionname(f);
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_alliance(struct opstack ** stack, const void * userdata) /* faction -> string */
{
const struct alliance * al = (const struct alliance *)opop(stack).v;
const char * c = alliancename(al);
variant var;
if (c!=NULL) {
size_t len = strlen(c);
var.v = strcpy(balloc(len+1), c);
}
else var.v = NULL;
opush(stack, var);
}
static void
eval_region(struct opstack ** stack, const void * userdata) /* region -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct region * r = (const struct region *)opop(stack).v;
const char * c = regionname(r, f);
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_terrain(struct opstack ** stack, const void * userdata) /* region -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct region * r = (const struct region *)opop(stack).v;
const char * c = LOC(f->locale, terrain_name(r));
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_ship(struct opstack ** stack, const void * userdata) /* ship -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct ship * u = (const struct ship *)opop(stack).v;
const char * c = u?shipname(u):LOC(f->locale, "an_unknown_ship");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_building(struct opstack ** stack, const void * userdata) /* building -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct building * u = (const struct building *)opop(stack).v;
const char * c = u?buildingname(u):LOC(f->locale, "an_unknown_building");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_weight(struct opstack ** stack, const void * userdata) /* region -> string */
{
char buffer[32];
const struct faction * f = (const struct faction *)userdata;
const struct locale * lang = f->locale;
int weight = opop_i(stack);
variant var;
if (weight % SCALEWEIGHT == 0) {
if (weight==SCALEWEIGHT) {
sprintf(buffer, "1 %s", LOC(lang, "weight_unit"));
} else {
sprintf(buffer, "%u %s", weight/SCALEWEIGHT, LOC(lang, "weight_unit_p"));
}
} else {
if (weight==1) {
sprintf(buffer, "1 %s %u", LOC(lang, "weight_per"), SCALEWEIGHT);
} else {
sprintf(buffer, "%u %s %u", weight, LOC(lang, "weight_per_p"), SCALEWEIGHT);
}
}
var.v = strcpy(balloc(strlen(buffer)+1), buffer);
opush(stack, var);
}
static void
eval_resource(struct opstack ** stack, const void * userdata)
{
const faction * report = (const faction*)userdata;
int j = opop(stack).i;
const struct resource_type * res = (const struct resource_type *)opop(stack).v;
const char * c = LOC(report->locale, resourcename(res, j!=1));
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_race(struct opstack ** stack, const void * userdata)
{
const faction * report = (const faction*)userdata;
int j = opop(stack).i;
const race * r = (const race *)opop(stack).v;
const char * c = LOC(report->locale, rc_name(r, j!=1));
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_order(struct opstack ** stack, const void * userdata) /* order -> string */
{
const faction * report = (const faction*)userdata;
const struct order * ord = (const struct order *)opop(stack).v;
static char buf[256];
size_t len;
variant var;
write_order(ord, report->locale, buf, sizeof(buf));
len = strlen(buf);
var.v = strcpy(balloc(len+1), buf);
opush(stack, var);
}
static void
eval_resources(struct opstack ** stack, const void * userdata) /* order -> string */
{
const faction * report = (const faction*)userdata;
const struct resource * res = (const struct resource *)opop(stack).v;
static char buf[256];
size_t len = sizeof(buf);
variant var;
char * edit = buf;
while (res!=NULL && len > 4) {
const char * rname = resourcename(res->type, (res->number!=1)?NMF_PLURAL:0);
int written = snprintf(edit, len, "%d %s", res->number, LOC(report->locale, rname));
len -= written;
edit += written;
res = res->next;
if (res!=NULL && len>2) {
strcat(edit, ", ");
edit += 2;
len -= 2;
}
}
*edit = 0;
var.v = strcpy(balloc(edit-buf+1), buf);
opush(stack, var);
}
static void
eval_regions(struct opstack ** stack, const void * userdata) /* order -> string */
{
const faction * report = (const faction*)userdata;
int i = opop(stack).i;
int end, begin = opop(stack).i;
const arg_regions * regions = (const arg_regions *)opop(stack).v;
static char buf[256];
size_t len = sizeof(buf);
variant var;
char * edit = buf;
if (regions==NULL) {
end = begin;
} else {
if (i>=0) end = begin+i;
else end = regions->nregions+i;
}
for (i=begin;i<end;++i) {
const char * rname = (const char*)regionname(regions->regions[i], report);
size_t written = strlcpy(edit, rname, len);
len -= written;
edit += written;
if (i+1<end && len>2) {
strcat(edit, ", ");
edit += 2;
len -= 2;
}
}
*edit = 0;
var.v = strcpy(balloc(edit-buf+1), buf);
opush(stack, var);
}
static void
eval_direction(struct opstack ** stack, const void * userdata)
{
const faction * report = (const faction*)userdata;
int i = opop(stack).i;
const char * c = LOC(report->locale, (i>=0)?directions[i]:"unknown_direction");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_skill(struct opstack ** stack, const void * userdata)
{
const faction * report = (const faction*)userdata;
skill_t sk = (skill_t)opop(stack).i;
const char * c = skillname(sk, report->locale);
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_int36(struct opstack ** stack, const void * userdata)
{
int i = opop(stack).i;
const char * c = itoa36(i);
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
unused(userdata);
}
void void
report_init(void) report_init(void)
{ {
/* register functions that turn message contents to readable strings */
add_function("alliance", &eval_alliance);
add_function("region", &eval_region);
add_function("terrain", &eval_terrain);
add_function("weight", &eval_weight);
add_function("resource", &eval_resource);
add_function("race", &eval_race);
add_function("faction", &eval_faction);
add_function("ship", &eval_ship);
add_function("unit", &eval_unit);
add_function("unit.dative", &eval_unit_dative);
add_function("unit.name", &eval_unitname);
add_function("unit.id", &eval_unitid);
add_function("unit.size", &eval_unitsize);
add_function("building", &eval_building);
add_function("skill", &eval_skill);
add_function("order", &eval_order);
add_function("direction", &eval_direction);
add_function("int36", &eval_int36);
add_function("trail", &eval_trail);
add_function("localize", &eval_localize);
add_function("spell", &eval_spell);
add_function("curse", &eval_curse);
add_function("resources", &eval_resources);
add_function("regions", &eval_regions);
register_reporttype("nr", &report_plaintext, 1<<O_REPORT); register_reporttype("nr", &report_plaintext, 1<<O_REPORT);
register_reporttype("txt", &report_template, 1<<O_ZUGVORLAGE); register_reporttype("txt", &report_template, 1<<O_ZUGVORLAGE);
} }

View file

@ -351,6 +351,7 @@ teach_cmd(unit * u, struct order * ord)
char zOrder[4096]; char zOrder[4096];
order * new_order; order * new_order;
zOrder[0] = '\0';
init_tokens(ord); init_tokens(ord);
skip_token(); skip_token();

View file

@ -2832,7 +2832,7 @@ print_stats(battle * b)
message_faction(b, f, msg_separator); message_faction(b, f, msg_separator);
msg = msg_message("msg_army", "index name", army_index(s), sname); msg = msg_message("battle_army", "index name", army_index(s), sname);
message_faction(b, f, msg); message_faction(b, f, msg);
msg_release(msg); msg_release(msg);

View file

@ -2015,7 +2015,7 @@ init_locale(const struct locale * lang)
tokens = get_translations(lang, UT_MAGIC); tokens = get_translations(lang, UT_MAGIC);
for (i=0;i!=MAXMAGIETYP;++i) { for (i=0;i!=MAXMAGIETYP;++i) {
var.i = i; var.i = i;
addtoken(tokens, LOC(lang, magietypen[i]), var); addtoken(tokens, LOC(lang, mkname("school", magietypen[i])), var);
} }
tokens = get_translations(lang, UT_DIRECTIONS); tokens = get_translations(lang, UT_DIRECTIONS);
@ -2914,92 +2914,3 @@ entertainmoney(const region *r)
return n; return n;
} }
int
freadstr(FILE * F, char * start, size_t size)
{
char * str = start;
boolean quote = false;
int nread = 0;
for (;;) {
int c = fgetc(F);
++nread;
if (isspace(c)) {
if (str==start) {
continue;
}
if (!quote) {
*str = 0;
return nread;
}
}
switch (c) {
case EOF:
return EOF;
case '"':
if (!quote && str!=start) {
log_error(("datafile contains a \" that isn't at the start of a string.\n"));
assert(!"datafile contains a \" that isn't at the start of a string.\n");
}
if (quote) {
*str = 0;
return nread;
}
quote = true;
break;
case '\\':
c = fgetc(F);
++nread;
switch (c) {
case EOF:
return EOF;
case 'n':
if ((size_t)(str-start+1)<size) {
*str++ = '\n';
}
break;
default:
if ((size_t)(str-start+1)<size) {
*str++ = (char)c;
}
}
break;
default:
if ((size_t)(str-start+1)<size) {
*str++ = (char)c;
}
}
}
}
/** writes a quoted string to the file
* no trailing space, since this is used to make the creport.
*/
int
fwritestr(FILE * F, const char * str)
{
int nwrite = 0;
fputc('\"', F);
while (*str) {
int c = (int)(unsigned char)*str++;
switch (c) {
case '"':
case '\\':
fputc('\\', F);
fputc(c, F);
nwrite+=2;
break;
case '\n':
fputc('\\', F);
fputc('n', F);
nwrite+=2;
break;
default:
fputc(c, F);
++nwrite;
}
}
fputc('\"', F);
return nwrite + 2;
}

View file

@ -430,9 +430,6 @@ extern int AllianceRestricted(void); /* flags restricted to allied factions */
extern struct order * default_order(const struct locale * lang); extern struct order * default_order(const struct locale * lang);
extern int entertainmoney(const struct region * r); extern int entertainmoney(const struct region * r);
extern int freadstr(FILE * F, int encoding, char * str, size_t size);
extern int fwritestr(FILE * F, const char * str);
extern void plagues(struct region * r, boolean ismagic); extern void plagues(struct region * r, boolean ismagic);
extern struct attrib_type at_guard; extern struct attrib_type at_guard;

View file

@ -220,9 +220,9 @@ const char *
generic_name(const unit *u) generic_name(const unit *u)
{ {
if (u->no == 1) { if (u->no == 1) {
return LOC(u->faction->locale, u->race->_name[0]); return LOC(u->faction->locale, mkname("race", u->race->_name[0]));
} }
return LOC(u->faction->locale, u->race->_name[1]); return LOC(u->faction->locale, mkname("race", u->race->_name[1]));
} }
const char * const char *

View file

@ -265,37 +265,43 @@ create_order_i(keyword_t kwd, const char * sptr, int persistent, const struct lo
order * order *
create_order(keyword_t kwd, const struct locale * lang, const char * params, ...) create_order(keyword_t kwd, const struct locale * lang, const char * params, ...)
{ {
va_list marker;
char zBuffer[DISPLAYSIZE]; char zBuffer[DISPLAYSIZE];
char * sptr = zBuffer; if (params) {
char * sptr = zBuffer;
va_list marker;
va_start(marker, params); va_start(marker, params);
while (*params) { while (*params) {
switch (*params) { if (*params=='%') {
case '%': int i;
/* ignore these, they are syntactical sugar */ const char * s;
break; ++params;
case '"': switch (*params) {
case '\'': case 's':
case ' ': s = va_arg(marker, const char *);
sptr += strlcpy(sptr, s, sizeof(zBuffer)-(sptr-zBuffer));
break;
case 'd':
i = va_arg(marker, int);
sptr += strlcpy(sptr, itoa10(i), sizeof(zBuffer)-(sptr-zBuffer));
break;
case 'i':
i = va_arg(marker, int);
sptr += strlcpy(sptr, itoa36(i), sizeof(zBuffer)-(sptr-zBuffer));
break;
default:
assert(!"unknown format-character in create_order");
}
} else {
*sptr++ = *params; *sptr++ = *params;
break; }
case 's': ++params;
sptr += strlcpy(sptr, va_arg(marker, const char *), sizeof(zBuffer)-(sptr-zBuffer));
break;
case 'd':
sptr += strlcpy(sptr, itoa10(va_arg(marker, int)), sizeof(zBuffer)-(sptr-zBuffer));
break;
case 'i':
sptr += strlcpy(sptr, itoa36(va_arg(marker, int)), sizeof(zBuffer)-(sptr-zBuffer));
break;
default:
assert(!"unknown format-character in create_order");
} }
++params; va_end(marker);
*sptr = 0;
} else {
zBuffer[0] = 0;
} }
va_end(marker);
return create_order_i(kwd, zBuffer, 0, lang); return create_order_i(kwd, zBuffer, 0, lang);
} }

View file

@ -128,7 +128,7 @@ write_regionname(const region * r, const faction * f, char * buffer, size_t size
const char * const char *
regionname(const region * r, const faction * f) regionname(const region * r, const faction * f)
{ {
static char buf[65]; static char buf[NAMESIZE];
return write_regionname(r, f, buf, sizeof(buf)); return write_regionname(r, f, buf, sizeof(buf));
} }
@ -758,7 +758,8 @@ r_setdemand(region * r, const luxury_type * ltype, int value)
while (*dp && (*dp)->type != ltype) dp = &(*dp)->next; while (*dp && (*dp)->type != ltype) dp = &(*dp)->next;
d = *dp; d = *dp;
if (!d) { if (!d) {
d = *dp = calloc(sizeof(struct demand), 1); d = *dp = malloc(sizeof(struct demand));
d->next = NULL;
d->type = ltype; d->type = ltype;
} }
d->value = value; d->value = value;
@ -945,9 +946,10 @@ setluxuries(region * r, const luxury_type * sale)
if(r->land->demands) freelist(r->land->demands); if(r->land->demands) freelist(r->land->demands);
for (ltype=luxurytypes; ltype; ltype=ltype->next) { for (ltype=luxurytypes; ltype; ltype=ltype->next) {
struct demand * dmd = calloc(sizeof(struct demand), 1); struct demand * dmd = malloc(sizeof(struct demand));
dmd->type = ltype; dmd->type = ltype;
if (ltype!=sale) dmd->value = 1 + rng_int() % 5; if (ltype!=sale) dmd->value = 1 + rng_int() % 5;
else dmd->value = 0;
dmd->next = r->land->demands; dmd->next = r->land->demands;
r->land->demands = dmd; r->land->demands = dmd;
} }

View file

@ -22,6 +22,7 @@
#include "reports.h" #include "reports.h"
/* kernel includes */ /* kernel includes */
#include <kernel/alliance.h>
#include <kernel/border.h> #include <kernel/border.h>
#include <kernel/building.h> #include <kernel/building.h>
#include <kernel/curse.h> #include <kernel/curse.h>
@ -31,6 +32,7 @@
#include <kernel/karma.h> #include <kernel/karma.h>
#include <kernel/magic.h> #include <kernel/magic.h>
#include <kernel/message.h> #include <kernel/message.h>
#include <kernel/move.h>
#include <kernel/order.h> #include <kernel/order.h>
#include <kernel/plane.h> #include <kernel/plane.h>
#include <kernel/race.h> #include <kernel/race.h>
@ -45,6 +47,7 @@
#include <util/bsdstring.h> #include <util/bsdstring.h>
#include <util/base36.h> #include <util/base36.h>
#include <util/functions.h> #include <util/functions.h>
#include <util/translation.h>
#include <util/goodies.h> #include <util/goodies.h>
#include <util/lists.h> #include <util/lists.h>
#include <util/log.h> #include <util/log.h>
@ -1553,6 +1556,416 @@ var_free_regions(variant x)
free(x.v); free(x.v);
} }
const char *
trailinto(const region * r, const struct locale * lang)
{
char ref[32];
const char * s;
if (r) {
const char * tname = terrain_name(r);
strcat(strcpy(ref, tname), "_trail");
s = locale_string(lang, ref);
if (s && *s) {
if (strstr(s, "%s")) return s;
}
}
return "%s";
}
size_t
f_regionid(const region * r, const faction * f, char * buffer, size_t size)
{
if (!r) {
strncpy(buffer, "(Chaos)", size);
} else {
plane * pl = r->planep;
strncpy(buffer, rname(r, f->locale), size);
buffer[size-1]=0;
if (pl==NULL || !fval(pl, PFL_NOCOORDS)) {
sprintf(buffer+strlen(buffer), " (%d,%d%s%s)", region_x(r,f), region_y(r,f), pl?",":"", pl?pl->name:"");
}
}
return strlen(buffer);
}
static char *
f_regionid_s(const region * r, const faction * f)
{
static int i = 0;
static char bufs[4][NAMESIZE + 20];
char * buf = bufs[(++i)%4];
f_regionid(r, f, buf, NAMESIZE + 20);
return buf;
}
/*** BEGIN MESSAGE RENDERING ***/
static void
eval_localize(struct opstack ** stack, const void * userdata) /* (string, locale) -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct locale * lang = f?f->locale:default_locale;
const char *c = (const char *)opop_v(stack);
c = locale_string(lang, c);
opush_v(stack, strcpy(balloc(strlen(c)+1), c));
}
static void
eval_trail(struct opstack ** stack, const void * userdata) /* (int, int) -> int */
{
const struct faction * f = (const struct faction *)userdata;
const struct locale * lang = f?f->locale:default_locale;
const struct region * r = (const struct region*)opop(stack).v;
const char * trail = trailinto(r, lang);
const char * rn = f_regionid_s(r, f);
variant var;
char * x = var.v = balloc(strlen(trail)+strlen(rn));
sprintf(x, trail, rn);
opush(stack, var);
}
static void
eval_unit(struct opstack ** stack, const void * userdata) /* unit -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct unit * u = (const struct unit *)opop(stack).v;
const char * c = u?unitname(u):LOC(f->locale, "an_unknown_unit");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_unit_dative(struct opstack ** stack, const void * userdata) /* unit -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct unit * u = (const struct unit *)opop(stack).v;
const char * c = u?unitname(u):LOC(f->locale, "unknown_unit_dative");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_spell(struct opstack ** stack, const void * userdata) /* unit -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct spell * sp = (const struct spell *)opop(stack).v;
const char * c = sp?spell_name(sp, f->locale):LOC(f->locale, "an_unknown_spell");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_curse(struct opstack ** stack, const void * userdata) /* unit -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct curse_type * sp = (const struct curse_type *)opop(stack).v;
const char * c = sp?curse_name(sp, f->locale):LOC(f->locale, "an_unknown_curse");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_unitname(struct opstack ** stack, const void * userdata) /* unit -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct unit * u = (const struct unit *)opop(stack).v;
const char * c = u?u->name:LOC(f->locale, "an_unknown_unit");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_unitid(struct opstack ** stack, const void * userdata) /* unit -> int */
{
const struct faction * f = (const struct faction *)userdata;
const struct unit * u = (const struct unit *)opop(stack).v;
const char * c = u?u->name:LOC(f->locale, "an_unknown_unit");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_unitsize(struct opstack ** stack, const void * userdata) /* unit -> int */
{
const struct unit * u = (const struct unit *)opop(stack).v;
variant var;
var.i = u->number;
opush(stack, var);
}
static void
eval_faction(struct opstack ** stack, const void * userdata) /* faction -> string */
{
const struct faction * f = (const struct faction *)opop(stack).v;
const char * c = factionname(f);
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_alliance(struct opstack ** stack, const void * userdata) /* faction -> string */
{
const struct alliance * al = (const struct alliance *)opop(stack).v;
const char * c = alliancename(al);
variant var;
if (c!=NULL) {
size_t len = strlen(c);
var.v = strcpy(balloc(len+1), c);
}
else var.v = NULL;
opush(stack, var);
}
static void
eval_region(struct opstack ** stack, const void * userdata) /* region -> string */
{
char name[NAMESIZE+32];
const struct faction * f = (const struct faction *)userdata;
const struct region * r = (const struct region *)opop(stack).v;
const char * c = write_regionname(r, f, name, sizeof(name));
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_terrain(struct opstack ** stack, const void * userdata) /* region -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct region * r = (const struct region *)opop(stack).v;
const char * c = LOC(f->locale, terrain_name(r));
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_ship(struct opstack ** stack, const void * userdata) /* ship -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct ship * u = (const struct ship *)opop(stack).v;
const char * c = u?shipname(u):LOC(f->locale, "an_unknown_ship");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_building(struct opstack ** stack, const void * userdata) /* building -> string */
{
const struct faction * f = (const struct faction *)userdata;
const struct building * u = (const struct building *)opop(stack).v;
const char * c = u?buildingname(u):LOC(f->locale, "an_unknown_building");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_weight(struct opstack ** stack, const void * userdata) /* region -> string */
{
char buffer[32];
const struct faction * f = (const struct faction *)userdata;
const struct locale * lang = f->locale;
int weight = opop_i(stack);
variant var;
if (weight % SCALEWEIGHT == 0) {
if (weight==SCALEWEIGHT) {
sprintf(buffer, "1 %s", LOC(lang, "weight_unit"));
} else {
sprintf(buffer, "%u %s", weight/SCALEWEIGHT, LOC(lang, "weight_unit_p"));
}
} else {
if (weight==1) {
sprintf(buffer, "1 %s %u", LOC(lang, "weight_per"), SCALEWEIGHT);
} else {
sprintf(buffer, "%u %s %u", weight, LOC(lang, "weight_per_p"), SCALEWEIGHT);
}
}
var.v = strcpy(balloc(strlen(buffer)+1), buffer);
opush(stack, var);
}
static void
eval_resource(struct opstack ** stack, const void * userdata)
{
const faction * report = (const faction*)userdata;
int j = opop(stack).i;
const struct resource_type * res = (const struct resource_type *)opop(stack).v;
const char * c = LOC(report->locale, resourcename(res, j!=1));
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_race(struct opstack ** stack, const void * userdata)
{
const faction * report = (const faction*)userdata;
int j = opop(stack).i;
const race * r = (const race *)opop(stack).v;
const char * c = LOC(report->locale, rc_name(r, j!=1));
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_order(struct opstack ** stack, const void * userdata) /* order -> string */
{
const faction * report = (const faction*)userdata;
const struct order * ord = (const struct order *)opop(stack).v;
static char buf[256];
size_t len;
variant var;
write_order(ord, report->locale, buf, sizeof(buf));
len = strlen(buf);
var.v = strcpy(balloc(len+1), buf);
opush(stack, var);
}
static void
eval_resources(struct opstack ** stack, const void * userdata) /* order -> string */
{
const faction * report = (const faction*)userdata;
const struct resource * res = (const struct resource *)opop(stack).v;
static char buf[256];
size_t len = sizeof(buf);
variant var;
char * edit = buf;
while (res!=NULL && len > 4) {
const char * rname = resourcename(res->type, (res->number!=1)?NMF_PLURAL:0);
int written = snprintf(edit, len, "%d %s", res->number, LOC(report->locale, rname));
len -= written;
edit += written;
res = res->next;
if (res!=NULL && len>2) {
strcat(edit, ", ");
edit += 2;
len -= 2;
}
}
*edit = 0;
var.v = strcpy(balloc(edit-buf+1), buf);
opush(stack, var);
}
static void
eval_regions(struct opstack ** stack, const void * userdata) /* order -> string */
{
const faction * report = (const faction*)userdata;
int i = opop(stack).i;
int end, begin = opop(stack).i;
const arg_regions * regions = (const arg_regions *)opop(stack).v;
static char buf[256];
size_t len = sizeof(buf);
variant var;
char * edit = buf;
if (regions==NULL) {
end = begin;
} else {
if (i>=0) end = begin+i;
else end = regions->nregions+i;
}
for (i=begin;i<end;++i) {
const char * rname = (const char*)regionname(regions->regions[i], report);
size_t written = strlcpy(edit, rname, len);
len -= written;
edit += written;
if (i+1<end && len>2) {
strcat(edit, ", ");
edit += 2;
len -= 2;
}
}
*edit = 0;
var.v = strcpy(balloc(edit-buf+1), buf);
opush(stack, var);
}
static void
eval_direction(struct opstack ** stack, const void * userdata)
{
const faction * report = (const faction*)userdata;
int i = opop(stack).i;
const char * c = LOC(report->locale, (i>=0)?directions[i]:"unknown_direction");
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_skill(struct opstack ** stack, const void * userdata)
{
const faction * report = (const faction*)userdata;
skill_t sk = (skill_t)opop(stack).i;
const char * c = skillname(sk, report->locale);
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
}
static void
eval_int36(struct opstack ** stack, const void * userdata)
{
int i = opop(stack).i;
const char * c = itoa36(i);
size_t len = strlen(c);
variant var;
var.v = strcpy(balloc(len+1), c);
opush(stack, var);
unused(userdata);
}
/*** END MESSAGE RENDERING ***/
void void
reports_init(void) reports_init(void)
{ {
@ -1576,6 +1989,32 @@ reports_init(void)
register_argtype("items", var_free_resources, var_copy_items, VAR_VOIDPTR); register_argtype("items", var_free_resources, var_copy_items, VAR_VOIDPTR);
register_argtype("regions", var_free_regions, var_copy_regions, VAR_VOIDPTR); register_argtype("regions", var_free_regions, var_copy_regions, VAR_VOIDPTR);
/* register functions that turn message contents to readable strings */
add_function("alliance", &eval_alliance);
add_function("region", &eval_region);
add_function("terrain", &eval_terrain);
add_function("weight", &eval_weight);
add_function("resource", &eval_resource);
add_function("race", &eval_race);
add_function("faction", &eval_faction);
add_function("ship", &eval_ship);
add_function("unit", &eval_unit);
add_function("unit.dative", &eval_unit_dative);
add_function("unit.name", &eval_unitname);
add_function("unit.id", &eval_unitid);
add_function("unit.size", &eval_unitsize);
add_function("building", &eval_building);
add_function("skill", &eval_skill);
add_function("order", &eval_order);
add_function("direction", &eval_direction);
add_function("int36", &eval_int36);
add_function("trail", &eval_trail);
add_function("localize", &eval_localize);
add_function("spell", &eval_spell);
add_function("curse", &eval_curse);
add_function("resources", &eval_resources);
add_function("regions", &eval_regions);
/* register alternative visibility functions */ /* register alternative visibility functions */
register_function((pf_generic)view_neighbours, "view_neighbours"); register_function((pf_generic)view_neighbours, "view_neighbours");
register_function((pf_generic)view_regatta, "view_regatta"); register_function((pf_generic)view_regatta, "view_regatta");

View file

@ -116,6 +116,7 @@ extern const char * report_kampfstatus(const struct unit * u, const struct local
struct region ** regions; struct region ** regions;
} arg_regions; } arg_regions;
extern size_t f_regionid(const struct region * r, const struct faction * f, char * buffer, size_t size);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -87,8 +87,8 @@
const char * xmlfile = "eressea.xml"; const char * xmlfile = "eressea.xml";
const char * g_datadir; const char * g_datadir;
int firstx = 0, firsty = 0; int firstx = 0, firsty = 0;
const char * enc_gamedata = NULL; int enc_gamedata = 0;
const char * enc_orderfile = NULL; int enc_orderfile = 0;
/* local symbols */ /* local symbols */
static region * current_region; static region * current_region;
@ -246,6 +246,109 @@ convertunique(faction * f)
} }
#endif #endif
int
freadstr(FILE * F, int encoding, char * start, size_t size)
{
char * str = start;
boolean quote = false;
for (;;) {
int c = fgetc(F);
if (isspace(c)) {
if (str==start) {
continue;
}
if (!quote) {
*str = 0;
return (int)(str-start);
}
}
switch (c) {
case EOF:
return EOF;
case '"':
if (!quote && str!=start) {
log_error(("datafile contains a \" that isn't at the start of a string.\n"));
assert(!"datafile contains a \" that isn't at the start of a string.\n");
}
if (quote) {
*str = 0;
return (int)(str-start);
}
quote = true;
break;
case '\\':
c = fgetc(F);
switch (c) {
case EOF:
return EOF;
case 'n':
if ((size_t)(str-start+1)<size) {
*str++ = '\n';
}
break;
default:
if ((size_t)(str-start+1)<size) {
if (encoding == XML_CHAR_ENCODING_8859_1 && c&0x80) {
char inbuf = (char)c;
int inbytes = 1;
int outbytes = (int)(size-(str-start));
int ret = isolat1ToUTF8((xmlChar *)str, &outbytes, (const xmlChar *)&inbuf, &inbytes);
if (ret>0) str+=ret;
} else {
*str++ = (char)c;
}
}
}
break;
default:
if ((size_t)(str-start+1)<size) {
if (encoding == XML_CHAR_ENCODING_8859_1 && c&0x80) {
char inbuf = (char)c;
int inbytes = 1;
int outbytes = (int)(size-(str-start));
int ret = isolat1ToUTF8((xmlChar *)str, &outbytes, (const xmlChar *)&inbuf, &inbytes);
if (ret>0) str+=ret;
} else {
*str++ = (char)c;
}
}
}
}
}
/** writes a quoted string to the file
* no trailing space, since this is used to make the creport.
*/
int
fwritestr(FILE * F, const char * str)
{
int nwrite = 0;
fputc('\"', F);
while (*str) {
int c = (int)(unsigned char)*str++;
switch (c) {
case '"':
case '\\':
fputc('\\', F);
fputc(c, F);
nwrite+=2;
break;
case '\n':
fputc('\\', F);
fputc('n', F);
nwrite+=2;
break;
default:
fputc(c, F);
++nwrite;
}
}
fputc('\"', F);
return nwrite + 2;
}
static void static void
rds(FILE * F, void **ds) rds(FILE * F, void **ds)
{ {
@ -283,61 +386,12 @@ rds(FILE * F, void **ds)
} }
} }
static int
xrs(FILE * F, char *dest, size_t size, int encoding)
{
char buffer[4096];
char * begin = dest;
char * s = begin;
boolean quote = false;
size_t maxs = size;
for (;;) {
int c = getc(F);
if (c=='"') {
if (quote) {
c = getc(F);
if (isspace(c)) break;
} else if (s==begin) {
quote = true;
continue;
}
} else if (isspace(c) && !quote) {
break;
}
if ((c & 0x80) && encoding!=XML_CHAR_ENCODING_NONE && encoding!=XML_CHAR_ENCODING_UTF8) {
if (begin!=buffer) {
size_t cp = s-begin;
maxs = min(sizeof(buffer), maxs);
if (cp>maxs) cp = maxs;
memcpy(buffer, begin, cp);
begin = buffer;
s = begin + cp;
}
}
*s++ = (char)c;
}
*s = 0;
if (begin==buffer) {
// convert
const char * inbuf = begin;
char * outbuf = dest;
int inbytes = (int)(s-begin)+1;
int outbytes = (int)size;
assert(encoding==XML_CHAR_ENCODING_8859_1);
return isolat1ToUTF8((xmlChar *)outbuf, &outbytes, (const xmlChar *)inbuf, &inbytes);
}
return (int)(s-begin);
}
static void static void
xrds(FILE * F, void **ds, int encoding) xrds(FILE * F, void **ds, int encoding)
{ {
static char buffer[DISPLAYSIZE + 1]; /*Platz für null-char nicht vergessen!*/ static char buffer[DISPLAYSIZE + 1]; /*Platz für null-char nicht vergessen!*/
int len = xrs(F, buffer, sizeof(buffer), encoding); int len = freadstr(F, encoding, buffer, sizeof(buffer));
if (len>=0) { if (len>=0) {
if (ds) { if (ds) {
@ -1314,7 +1368,7 @@ readregion(FILE * F, int encoding, short x, short y)
rawmaterial * res; rawmaterial * res;
rss(F, token, sizeof(token)); rss(F, token, sizeof(token));
if (strcmp(token, "end")==0) break; if (strcmp(token, "end")==0) break;
res = calloc(sizeof(rawmaterial), 1); res = malloc(sizeof(rawmaterial));
res->type = rmt_find(token); res->type = rmt_find(token);
if (res->type==NULL) { if (res->type==NULL) {
log_error(("invalid resourcetype %s in data.\n", token)); log_error(("invalid resourcetype %s in data.\n", token));
@ -1322,6 +1376,7 @@ readregion(FILE * F, int encoding, short x, short y)
assert(res->type!=NULL); assert(res->type!=NULL);
res->level = ri(F); res->level = ri(F);
res->amount = ri(F); res->amount = ri(F);
res->flags = 0;
if(global.data_version >= RANDOMIZED_RESOURCES_VERSION) { if(global.data_version >= RANDOMIZED_RESOURCES_VERSION) {
res->startlevel = ri(F); res->startlevel = ri(F);
@ -1341,6 +1396,7 @@ readregion(FILE * F, int encoding, short x, short y)
*pres = res; *pres = res;
pres=&res->next; pres=&res->next;
} }
*pres = NULL;
} }
rss(F, token, sizeof(token)); rss(F, token, sizeof(token));
if (strcmp(token, "noherb") != 0) { if (strcmp(token, "noherb") != 0) {
@ -1672,7 +1728,7 @@ writefaction(FILE * F, const faction * f)
} }
int int
readgame(const char * filename, int backup, const char * encoding) readgame(const char * filename, int backup, int encoding)
{ {
int i, n, p; int i, n, p;
faction *f, **fp; faction *f, **fp;
@ -1684,7 +1740,6 @@ readgame(const char * filename, int backup, const char * encoding)
int rmax = maxregions; int rmax = maxregions;
char path[MAX_PATH]; char path[MAX_PATH];
char token[32]; char token[32];
int enc = xmlParseCharEncoding(encoding);
sprintf(path, "%s/%s", datapath(), filename); sprintf(path, "%s/%s", datapath(), filename);
log_printf("- reading game data from %s\n", filename); log_printf("- reading game data from %s\n", filename);
@ -1732,7 +1787,7 @@ readgame(const char * filename, int backup, const char * encoding)
while(--n >= 0) { while(--n >= 0) {
plane *pl = calloc(1, sizeof(plane)); plane *pl = calloc(1, sizeof(plane));
pl->id = ri(F); pl->id = ri(F);
xrds(F, &pl->name, enc); xrds(F, &pl->name, encoding);
pl->minx = (short)ri(F); pl->minx = (short)ri(F);
pl->maxx = (short)ri(F); pl->maxx = (short)ri(F);
pl->miny = (short)ri(F); pl->miny = (short)ri(F);
@ -1767,7 +1822,7 @@ readgame(const char * filename, int backup, const char * encoding)
/* fflush (stdout); */ /* fflush (stdout); */
while (--n >= 0) { while (--n >= 0) {
faction * f = readfaction(F, enc); faction * f = readfaction(F, encoding);
*fp = f; *fp = f;
fp = &f->next; fp = &f->next;
@ -1825,7 +1880,7 @@ readgame(const char * filename, int backup, const char * encoding)
} }
--rmax; --rmax;
r = readregion(F, enc, x, y); r = readregion(F, encoding, x, y);
/* Burgen */ /* Burgen */
p = ri(F); p = ri(F);
@ -1838,9 +1893,9 @@ readgame(const char * filename, int backup, const char * encoding)
*bp = b; *bp = b;
bp = &b->next; bp = &b->next;
bhash(b); bhash(b);
xrds(F, &b->name, enc); xrds(F, &b->name, encoding);
if (lomem) rds(F, 0); if (lomem) rds(F, 0);
else xrds(F, &b->display, enc); else xrds(F, &b->display, encoding);
b->size = ri(F); b->size = ri(F);
if (global.data_version < TYPES_VERSION) { if (global.data_version < TYPES_VERSION) {
assert(!"data format is no longer supported"); assert(!"data format is no longer supported");
@ -1865,9 +1920,9 @@ readgame(const char * filename, int backup, const char * encoding)
*shp = sh; *shp = sh;
shp = &sh->next; shp = &sh->next;
shash(sh); shash(sh);
xrds(F, &sh->name, enc); xrds(F, &sh->name, encoding);
if (lomem) rds(F, NULL); if (lomem) rds(F, NULL);
else xrds(F, &sh->display, enc); else xrds(F, &sh->display, encoding);
rss(F, token, sizeof(token)); rss(F, token, sizeof(token));
sh->type = st_find(token); sh->type = st_find(token);
@ -1893,7 +1948,7 @@ readgame(const char * filename, int backup, const char * encoding)
up = &r->units; up = &r->units;
while (--p >= 0) { while (--p >= 0) {
unit * u = readunit(F, enc); unit * u = readunit(F, encoding);
sc_mage * mage; sc_mage * mage;
assert(u->region==NULL); assert(u->region==NULL);

View file

@ -36,7 +36,7 @@ double version(void);
FILE * cfopen(const char *filename, const char *mode); FILE * cfopen(const char *filename, const char *mode);
int readorders(const char *filename, const char * encoding); int readorders(const char *filename, const char * encoding);
int creategame(void); int creategame(void);
extern int readgame(const char * filename, int backup, const char * encoding); extern int readgame(const char * filename, int backup, int encoding);
int writegame(const char *filename, int quiet); int writegame(const char *filename, int quiet);
extern void rsf(FILE * F, char *s, size_t len); extern void rsf(FILE * F, char *s, size_t len);
@ -47,8 +47,8 @@ extern int data_version;
extern int maxregions; extern int maxregions;
extern int firstx, firsty; extern int firstx, firsty;
extern const char *xmlfile; extern const char *xmlfile;
extern const char * enc_gamedata; extern int enc_gamedata;
extern const char * enc_orderfile; extern int enc_orderfile;
extern void init_locales(void); extern void init_locales(void);
extern int lastturn(void); extern int lastturn(void);
@ -81,6 +81,9 @@ extern int a_readstring(struct attrib * a, FILE * F);
extern void a_writestring(const struct attrib * a, FILE * F); extern void a_writestring(const struct attrib * a, FILE * F);
extern void a_finalizestring(struct attrib * a); extern void a_finalizestring(struct attrib * a);
extern int freadstr(FILE * F, int encoding, char * str, size_t size);
extern int fwritestr(FILE * F, const char * str);
extern void create_backup(char *file); extern void create_backup(char *file);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -2404,7 +2404,7 @@ patzer_peasantmob(castorder *co)
u = create_unit(r, f, n, new_race[RC_PEASANT], 0, LOC(f->locale, "angry_mob"), NULL); u = create_unit(r, f, n, new_race[RC_PEASANT], 0, LOC(f->locale, "angry_mob"), NULL);
fset(u, UFL_ISNEW); fset(u, UFL_ISNEW);
/* guard(u, GUARD_ALL); hier zu früh! Befehl BEWACHE setzten */ /* guard(u, GUARD_ALL); hier zu früh! Befehl BEWACHE setzten */
addlist(&u->orders, create_order(K_GUARD, lang, "")); addlist(&u->orders, create_order(K_GUARD, lang, NULL));
set_order(&u->thisorder, default_order(lang)); set_order(&u->thisorder, default_order(lang));
a = a_new(&at_unitdissolve); a = a_new(&at_unitdissolve);
a->data.ca[0] = 1; /* An rpeasants(r). */ a->data.ca[0] = 1; /* An rpeasants(r). */

View file

@ -4,6 +4,11 @@
#include <util/log.h> #include <util/log.h>
#include <util/unicode.h> #include <util/unicode.h>
#include <libxml/encoding.h>
#include <ctype.h>
#include <wctype.h>
#define COMMENT_CHAR ';' #define COMMENT_CHAR ';'
#define CONTINUE_CHAR '\\' #define CONTINUE_CHAR '\\'
#define MAXLINE 4096*16 #define MAXLINE 4096*16
@ -22,7 +27,6 @@ eatwhite(const char * ptr, size_t * total_size)
int ret = 0; int ret = 0;
*total_size = 0; *total_size = 0;
#ifdef USE_UNICODE
while (*ptr) { while (*ptr) {
wint_t ucs; wint_t ucs;
@ -33,15 +37,128 @@ eatwhite(const char * ptr, size_t * total_size)
*total_size += size; *total_size += size;
ptr += size; ptr += size;
} }
#else
*total_size = 0;
while (ptr[*total_size] && isspace(*(unsigned char*)ptr[*total_size])) ++*total_size;
#endif
return ret; return ret;
} }
const char * static const char *
getbuf(FILE * F, int encoding) getbuf_latin1(FILE * F)
{
boolean cont = false;
char quote = 0;
boolean comment = false;
char * cp = fbuf;
char * tail = lbuf+MAXLINE-2;
tail[1] = '@'; /* if this gets overwritten by fgets then the line was very long. */
do {
const char * bp = fgets(lbuf, MAXLINE, F);
if (bp==NULL) return NULL;
while (*bp && isspace(*(unsigned char*)bp)) ++bp; /* eatwhite */
comment = (boolean)(comment && cont);
if (tail[1]==0) {
/* we read he maximum number of bytes! */
if (tail[0]!='\n') {
/* it wasn't enough space to finish the line, eat the rest */
for (;;) {
tail[1] = '@';
bp = fgets(lbuf, MAXLINE, F);
if (bp==NULL) return NULL;
if (tail[1]) {
/* read enough this time to end the line */
break;
}
}
comment = false;
cont = false;
bp = NULL;
continue;
} else {
tail[1] = '@';
}
}
cont = false;
while (*bp && cp<fbuf+MAXLINE) {
int c = *(unsigned char *)bp;
if (c==COMMENT_CHAR && !quote) {
/* comment begins. we need to keep going, to look for CONTINUE_CHAR */
comment = true;
++bp;
continue;
}
if (c=='"' || c=='\'') {
if (quote==c) {
quote = 0;
if (cp<fbuf+MAXLINE) *cp++ = *bp;
++bp;
continue;
} else if (!quote) {
quote = *bp++;
if (cp<fbuf+MAXLINE) *cp++ = quote;
continue;
}
}
if (isspace(c)) {
if (!quote) {
++bp;
while (*bp && isspace(*(unsigned char*)bp)) ++bp; /* eatwhite */
if (!comment && *bp && *bp!=COMMENT_CHAR && cp<fbuf+MAXLINE) *(cp++) = ' ';
}
else if (!comment && cp+1<=fbuf+MAXLINE) {
*(cp++)=*(bp++);
} else {
++bp;
}
continue;
} else if (iscntrl(c)) {
if (!comment && cp<fbuf+MAXLINE) *(cp++) = '?';
++bp;
continue;
} else if (c==CONTINUE_CHAR) {
const char * end = ++bp;
while (*end && isspace(*(unsigned char*)end)) ++end; /* eatwhite */
if (*end == '\0') {
bp = end;
cont = true;
continue;
}
if (comment) {
++bp;
continue;
}
} else if (comment) {
++bp;
continue;
}
if (c < 0x80) {
if (cp+1<=fbuf+MAXLINE) {
*(cp++)=*(bp++);
}
} else {
char inbuf = (char)c;
int inbytes = 1;
int outbytes = (int)(MAXLINE-(cp-fbuf));
int ret = isolat1ToUTF8((xmlChar *)cp, &outbytes, (const xmlChar *)&inbuf, &inbytes);
if (ret>0) cp+=ret;
++bp;
continue;
}
}
if (cp==fbuf+MAXLINE) {
--cp;
}
*cp=0;
} while (cont || cp==fbuf);
return fbuf;
}
static const char *
getbuf_utf8(FILE * F)
{ {
boolean cont = false; boolean cont = false;
char quote = 0; char quote = 0;
@ -74,7 +191,9 @@ getbuf(FILE * F, int encoding)
} }
} }
comment = false; comment = false;
cont = false;
bp = NULL; bp = NULL;
continue;
} else { } else {
tail[1] = '@'; tail[1] = '@';
} }
@ -161,3 +280,10 @@ getbuf(FILE * F, int encoding)
} while (cont || cp==fbuf); } while (cont || cp==fbuf);
return fbuf; return fbuf;
} }
const char *
getbuf(FILE * F, int encoding)
{
if (encoding==XML_CHAR_ENCODING_UTF8) return getbuf_utf8(F);
return getbuf_latin1(F);
}

View file

@ -54,7 +54,7 @@ nrt_find(const struct locale * lang, const struct message_type * mtype)
} }
type = type->next; type = type->next;
} }
if (lang && found->lang!=lang) { if (lang && found && found->lang!=lang) {
log_warning(("could not find nr-type %s for locale %s, substituting with %s\n", log_warning(("could not find nr-type %s for locale %s, substituting with %s\n",
mtype->name, locale_name(lang), locale_name(found->lang))); mtype->name, locale_name(lang), locale_name(found->lang)));
} }

View file

@ -47,13 +47,13 @@ addtoken(tnode * root, const char * str, variant id)
const char str[3]; const char str[3];
} replace[] = { } replace[] = {
/* match lower-case (!) umlauts and others to transcriptions */ /* match lower-case (!) umlauts and others to transcriptions */
{ 228, "AE"}, { 228, "AE"}, /* auml */
{ 246, "OE"}, { 246, "OE"}, /* ouml */
{ 252, "UE"}, { 252, "UE"}, /* uuml */
{ 223, "SS"}, { 223, "SS"}, /* szlig */
{ 230, "AE"}, { 230, "AE"}, /* norsk */
{ 248, "OE"}, { 248, "OE"}, /* norsk */
{ 229, "AA"}, { 229, "AA"}, /* norsk */
{ 0, "" } { 0, "" }
}; };

View file

@ -169,7 +169,7 @@ typedef struct _stat stat_type;
# define strdup _strdup # define strdup _strdup
# define HAVE_STRDUP # define HAVE_STRDUP
# define sleep _sleep # define sleep(sec) _sleep(sec*1000000)
# define HAVE_SLEEP # define HAVE_SLEEP
# define stricmp(a, b) _stricmp(a, b) # define stricmp(a, b) _stricmp(a, b)

View file

@ -62,6 +62,8 @@
#include <iniparser/iniparser.h> #include <iniparser/iniparser.h>
#include <libxml/encoding.h>
#include <string.h> #include <string.h>
#include <locale.h> #include <locale.h>
@ -1299,10 +1301,13 @@ load_inifile(const char * filename)
{ {
dictionary * d = iniparser_new(filename); dictionary * d = iniparser_new(filename);
if (d) { if (d) {
const char * str;
g_basedir = iniparser_getstring(d, "common:base", g_basedir); g_basedir = iniparser_getstring(d, "common:base", g_basedir);
g_resourcedir = iniparser_getstring(d, "common:res", g_resourcedir); g_resourcedir = iniparser_getstring(d, "common:res", g_resourcedir);
xmlfile = iniparser_getstring(d, "common:xml", xmlfile); xmlfile = iniparser_getstring(d, "common:xml", xmlfile);
enc_gamedata = iniparser_getstring(d, "common:gamedata_encoding", enc_gamedata);
str = iniparser_getstring(d, "common:gamedata_encoding", NULL);
if (str) enc_gamedata = xmlParseCharEncoding(str);
} }
inifile = d; inifile = d;
} }

View file

@ -46,6 +46,8 @@
#include <util/rand.h> #include <util/rand.h>
#include <util/rng.h> #include <util/rng.h>
#include <libxml/encoding.h>
#include <cstring> #include <cstring>
#include <ctime> #include <ctime>
@ -108,7 +110,8 @@ message_region(unit& sender, const char * str)
static int static int
read_game(const char * filename, const char * encoding) read_game(const char * filename, const char * encoding)
{ {
int rv = readgame(filename, false, encoding); int enc = xmlParseCharEncoding(encoding);
int rv = readgame(filename, false, enc);
printf(" - Korrekturen Runde %d\n", turn); printf(" - Korrekturen Runde %d\n", turn);
korrektur(); korrektur();
return rv; return rv;

View file

@ -110,6 +110,8 @@
#include <lua.hpp> #include <lua.hpp>
#include <luabind/luabind.hpp> #include <luabind/luabind.hpp>
#include <libxml/encoding.h>
/* stdc++ includes */ /* stdc++ includes */
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
@ -386,18 +388,17 @@ game_done(void)
#include "magic.h" #include "magic.h"
#define CRTDBG
#ifdef CRTDBG #ifdef CRTDBG
void void
init_crtdbg(void) init_crtdbg(void)
{ {
#if (defined(_MSC_VER)) #if (defined(_MSC_VER))
# if MALLOCDBG == 2 int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
# define CHECKON() _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF) // flags = (flags&0x0000FFFF) | _CRTDBG_CHECK_EVERY_1024_DF;
# elif MALLOCDBG == 3 // flags |= _CRTDBG_CHECK_ALWAYS_DF; /* expensive */
# define CHECKON() _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) & 0) _CrtSetDbgFlag(flags);
# elif MALLOCDBG == 1
# define CHECKON() _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_CRT_DF | _CRTDBG_DELAY_FREE_MEM_DF)
# endif
#endif #endif
} }
#endif #endif
@ -601,14 +602,17 @@ load_inifile(const char * filename)
{ {
dictionary * d = iniparser_new(filename); dictionary * d = iniparser_new(filename);
if (d) { if (d) {
const char * str;
g_basedir = iniparser_getstring(d, "common:base", g_basedir); g_basedir = iniparser_getstring(d, "common:base", g_basedir);
g_resourcedir = iniparser_getstring(d, "common:res", g_resourcedir); g_resourcedir = iniparser_getstring(d, "common:res", g_resourcedir);
xmlfile = iniparser_getstring(d, "common:xml", xmlfile); xmlfile = iniparser_getstring(d, "common:xml", xmlfile);
script_path = iniparser_getstring(d, "common:scripts", script_path); script_path = iniparser_getstring(d, "common:scripts", script_path);
lomem = iniparser_getint(d, "common:lomem", lomem)?1:0; lomem = iniparser_getint(d, "common:lomem", lomem)?1:0;
enc_gamedata = iniparser_getstring(d, "common:gamedata_encoding", enc_gamedata); str = iniparser_getstring(d, "common:gamedata_encoding", NULL);
enc_orderfile = iniparser_getstring(d, "common:orderfile_encoding", enc_orderfile); if (str) enc_gamedata = xmlParseCharEncoding(str);
str = iniparser_getstring(d, "common:orderfile_encoding", NULL);
if (str) enc_orderfile = xmlParseCharEncoding(str);
quiet = iniparser_getint(d, "eressea:verbose", 0)?0:1; quiet = iniparser_getint(d, "eressea:verbose", 0)?0:1;
battledebug = iniparser_getint(d, "eressea:debug", battledebug)?1:0; battledebug = iniparser_getint(d, "eressea:debug", battledebug)?1:0;

View file

@ -8,7 +8,8 @@
--> -->
<string name="vortex"> <string name="vortex">
<text locale="de">Wirbel</text> <text locale="de">Wirbel</text>
<text locale="en">Vortex</text> <text locale="en">vortex</text>
<text locale="fr">remous</text>
</string> </string>
<string name="vortex_desc"> <string name="vortex_desc">
<text locale="de">Ein Wirbel aus reinem Chaos zieht über die Region</text> <text locale="de">Ein Wirbel aus reinem Chaos zieht über die Region</text>

View file

@ -173,6 +173,9 @@
<string name="glacier_trail"> <string name="glacier_trail">
<text locale="en">the glacier of %s</text> <text locale="en">the glacier of %s</text>
</string> </string>
<string name="wall1">
<text locale="en">Wall</text>
</string>
<string name="hall1_trail"> <string name="hall1_trail">
<text locale="en">the %s</text> <text locale="en">the %s</text>
</string> </string>

View file

@ -1,6 +1,6 @@
-- the locales that this gameworld supports. -- the locales that this gameworld supports.
local locales = { "de", "en" } local locales = { "de", "en" }
enc_orders = "UTF-8" enc_orders = "ISO-8859-1"
enc_game = "ISO-8859-1" enc_game = "ISO-8859-1"
function loadscript(name) function loadscript(name)