diff --git a/src/common/attributes/giveitem.c b/src/common/attributes/giveitem.c index fd27aee3b..87d296ac0 100644 --- a/src/common/attributes/giveitem.c +++ b/src/common/attributes/giveitem.c @@ -52,22 +52,26 @@ a_writegive(const attrib * a, FILE * F) static int a_readgive(attrib * a, FILE * F) { - give_data * gdata = (give_data*)a->data.v; - variant var; - char zText[32]; + give_data * gdata = (give_data*)a->data.v; + variant var; + int result; + char zText[32]; - fscanf(F, "%s ", zText); - var.i = atoi36(zText); - gdata->building = findbuilding(var.i); - if (gdata->building==NULL) ur_add(var, (void**)&gdata->building, resolve_building); - for (;;) { + result = fscanf(F, "%s ", zText); + if (result<0) return result; + var.i = atoi36(zText); + gdata->building = findbuilding(var.i); + if (gdata->building==NULL) ur_add(var, (void**)&gdata->building, resolve_building); + for (;;) { int i; - fscanf(F, "%s", zText); - if (!strcmp("end", zText)) break; - fscanf(F, "%d", &i); - if (i==0) i_add(&gdata->items, i_new(it_find(zText), i)); - } - return AT_READ_OK; + result = fscanf(F, "%s", zText); + if (result==EOF) return EOF; + if (!strcmp("end", zText)) break; + result = fscanf(F, "%d", &i); + if (result==EOF) return EOF; + if (i==0) i_add(&gdata->items, i_new(it_find(zText), i)); + } + return AT_READ_OK; } static void diff --git a/src/common/attributes/moved.c b/src/common/attributes/moved.c index 02b2892de..90ecf90a5 100644 --- a/src/common/attributes/moved.c +++ b/src/common/attributes/moved.c @@ -34,7 +34,8 @@ write_moved(const attrib * a, FILE * F) static int read_moved(attrib * a, FILE * F) { - fscanf(F, "%d", &a->data.i); + int result = fscanf(F, "%d", &a->data.i); + if (result<0) return result; if (a->data.i !=0 ) return AT_READ_OK; else return AT_READ_FAIL; } diff --git a/src/common/attributes/movement.c b/src/common/attributes/movement.c index 655099b4e..6d115e3e5 100644 --- a/src/common/attributes/movement.c +++ b/src/common/attributes/movement.c @@ -27,9 +27,10 @@ write_movement(const attrib * a, FILE * F) static int read_movement(attrib * a, FILE * F) { - fscanf(F, "%d", &a->data.i); - if (a->data.i !=0 ) return AT_READ_OK; - else return AT_READ_FAIL; + int result = fscanf(F, "%d", &a->data.i); + if (result<0) return result; + if (a->data.i !=0 ) return AT_READ_OK; + else return AT_READ_FAIL; } attrib_type at_movement = { diff --git a/src/common/attributes/object.c b/src/common/attributes/object.c index 1a3f0712a..170a5753b 100644 --- a/src/common/attributes/object.c +++ b/src/common/attributes/object.c @@ -88,20 +88,21 @@ static int object_read(attrib *a, FILE *F) { object_data * data = (object_data *)a->data.v; - int type; + int type, result; char buffer[128]; - fscanf(F, "%s %d", buffer, &type); + result = fscanf(F, "%s %d", buffer, &type); + if (result<0) return result; data->name = strdup(buffer); data->type = (object_type)type; switch (data->type) { case TINTEGER: - fscanf(F, "%d", &data->data.i); + result = fscanf(F, "%d", &data->data.i); break; case TREAL: - fscanf(F, "%lf", &data->data.real); + result = fscanf(F, "%lf", &data->data.real); break; case TSTRING: - freadstr(F, enc_gamedata, buffer, sizeof(buffer)); + result = freadstr(F, enc_gamedata, buffer, sizeof(buffer)); data->data.str = strdup(buffer); break; case TBUILDING: @@ -121,6 +122,7 @@ object_read(attrib *a, FILE *F) default: return AT_READ_FAIL; } + if (result<0) return result; return AT_READ_OK; } diff --git a/src/common/attributes/otherfaction.c b/src/common/attributes/otherfaction.c index 36588bbaf..03fe411f3 100644 --- a/src/common/attributes/otherfaction.c +++ b/src/common/attributes/otherfaction.c @@ -35,12 +35,13 @@ write_of(const struct attrib * a, FILE* F) int read_of(struct attrib * a, FILE* F) /* return 1 on success, 0 if attrib needs removal */ -{ - int of; - fscanf(F, "%d", &of); - a->data.v = findfaction(of); - if (a->data.v) return AT_READ_OK; - return AT_READ_FAIL; + { + int of, result; + result = fscanf(F, "%d", &of); + if (result<0) return result; + a->data.v = findfaction(of); + if (a->data.v) return AT_READ_OK; + return AT_READ_FAIL; } attrib_type at_otherfaction = { diff --git a/src/common/attributes/variable.c b/src/common/attributes/variable.c index 5d7e0c91b..b6dba2dce 100644 --- a/src/common/attributes/variable.c +++ b/src/common/attributes/variable.c @@ -51,15 +51,17 @@ write_variable(const struct attrib * a, FILE *F) static int read_variable(struct attrib *a, FILE *F) { - char localBuffer[1024]; + char localBuffer[1024]; - fscanf(F, "%s", localBuffer); - ((variable *)(a->data.v))->key = strdup(localBuffer); + int result = fscanf(F, "%s", localBuffer); + if (result<0) return result; + ((variable *)(a->data.v))->key = strdup(localBuffer); - freadstr(F, enc_gamedata, localBuffer, sizeof(localBuffer)); - ((variable *)(a->data.v))->value = strdup(localBuffer); + result = freadstr(F, enc_gamedata, localBuffer, sizeof(localBuffer)); + if (result<0) return result; + ((variable *)(a->data.v))->value = strdup(localBuffer); - return AT_READ_OK; + return AT_READ_OK; } attrib_type at_variable = { diff --git a/src/common/attributes/viewrange.c b/src/common/attributes/viewrange.c index a8d800bed..36acb0aa8 100644 --- a/src/common/attributes/viewrange.c +++ b/src/common/attributes/viewrange.c @@ -33,7 +33,8 @@ a_readfunction(struct attrib *a, FILE *F) /* return 1 on success, 0 if attrib needs removal */ { char buf[64]; - fscanf(F, "%s ", buf); + int result = fscanf(F, "%s ", buf); + if (result<0) return result; a->data.f = get_function(buf); return AT_READ_OK; } diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index bc2a4d322..e8530c7c8 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -1559,7 +1559,7 @@ creport_init(void) tsf_register("items", &cr_resources); tsf_register("regions", &cr_regions); - register_reporttype("cr", &report_computer, 1<data.v; - char zText[32]; - fscanf(f, "%s %d", zText, &power); - itype = it_find(zText); + effect_data * edata = (effect_data*)a->data.v; + char zText[32]; + + result = fscanf(f, "%s %d", zText, &power); + if (result<0) return result; + itype = it_find(zText); if (itype==NULL || itype->rtype==NULL || itype->rtype->ptype==NULL || power<=0) { return AT_READ_FAIL; } - edata->type = itype->rtype->ptype; - edata->value = power; - return AT_READ_OK; + edata->type = itype->rtype->ptype; + edata->value = power; + return AT_READ_OK; } attrib_type at_effect = { diff --git a/src/common/kernel/border.c b/src/common/kernel/border.c index c9b72f8dc..ed7e48db5 100644 --- a/src/common/kernel/border.c +++ b/src/common/kernel/border.c @@ -164,20 +164,23 @@ find_bordertype(const char * name) void b_read(border * b, FILE *f) { + int result; switch (b->type->datatype) { case VAR_NONE: case VAR_INT: - fscanf(f, "%x ", &b->data.i); + result = fscanf(f, "%x ", &b->data.i); break; case VAR_VOIDPTR: - fscanf(f, "%p ", &b->data.v); + result = fscanf(f, "%p ", &b->data.v); break; case VAR_SHORTA: - fscanf(f, "%hd %hd ", &b->data.sa[0], &b->data.sa[1]); + result = fscanf(f, "%hd %hd ", &b->data.sa[0], &b->data.sa[1]); break; default: assert(!"unhandled variant type in border"); + result = 0; } + assert(result>=0 || "EOF encountered?"); } void @@ -531,7 +534,7 @@ write_borders(FILE * f) fputs("end ", f); } -void +int read_borders(FILE * f) { for (;;) { @@ -541,10 +544,13 @@ read_borders(FILE * f) border * b; region * from, * to; border_type * type; + int result; - fscanf(f, "%s", zText); + result = fscanf(f, "%s", zText); + if (result<0) return result; if (!strcmp(zText, "end")) break; - fscanf(f, "%u %hd %hd %hd %hd", &bid, &fx, &fy, &tx, &ty); + result = fscanf(f, "%u %hd %hd %hd %hd", &bid, &fx, &fy, &tx, &ty); + if (result<0) return result; from = findregion(fx, fy); if (!incomplete_data && from==NULL) { @@ -574,9 +580,11 @@ read_borders(FILE * f) b->id = bid; assert(bid<=nextborder); if (type->read) type->read(b, f); - a_read(f, &b->attribs); + result = a_read(f, &b->attribs); + if (result<0) return result; if (!to || !from) { erase_border(b); } } + return 0; } diff --git a/src/common/kernel/border.h b/src/common/kernel/border.h index 762a32bff..3a5b5edb9 100644 --- a/src/common/kernel/border.h +++ b/src/common/kernel/border.h @@ -101,7 +101,7 @@ extern "C" { extern void register_bordertype(border_type * type); /* register a new bordertype */ - extern void read_borders(FILE * f); + extern int read_borders(FILE * f); extern void write_borders(FILE * f); extern void age_borders(void); diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index 5e8741e59..e7235d70c 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -1216,6 +1216,9 @@ write_reports(faction * f, time_t ltime) struct report_context ctx; const char * encoding = "UTF-8"; + if (noreports) { + return false; + } ctx.f = f; ctx.report_time = time(NULL); ctx.seen = prepare_report(f); diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index 41d03703e..b3a29abd3 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -431,6 +431,11 @@ unitorders(FILE * F, int enc, struct faction * f) i = getid(); u = findunitg(i, NULL); + if (quiet==0) { + log_stdio(stdout, "-%4s;", unitid(u)); + fflush(stdout); + } + if (u && u->race == new_race[RC_SPELL]) return NULL; if (u && u->faction == f) { order ** ordp; @@ -472,13 +477,22 @@ unitorders(FILE * F, int enc, struct faction * f) if (stok) { boolean quit = false; - switch (findparam(stok, u->faction->locale)) { + param_t param = findparam(stok, u->faction->locale); + switch (param) { case P_UNIT: case P_REGION: + quit = true; + break; case P_FACTION: case P_NEXT: case P_GAMENAME: - quit = true; + /* these terminate the orders, so we apply extra checking */ + if (strlen(stok)>=3) { + quit = true; + break; + } else { + quit = false; + } } if (quit) break; } @@ -1021,7 +1035,9 @@ writeunit(FILE * F, const unit * u) wi36(F, u->no); wi36(F, u->faction->no); fwritestr(F, (const char *)u->name); + fputc(' ', F); fwritestr(F, u->display?(const char *)u->display:""); + fputc(' ', F); wi(F, u->number); wi(F, u->age); ws(F, u->race->_name[0]); @@ -1243,6 +1259,7 @@ void writeregion(FILE * F, const region * r) { fwritestr(F, r->display?(const char *)r->display:""); + fputc(' ', F); ws(F, r->terrain->_name); wi(F, r->flags & RF_SAVEMASK); wi(F, r->age); @@ -1252,6 +1269,7 @@ writeregion(FILE * F, const region * r) struct demand * demand; rawmaterial * res = r->resources; fwritestr(F, (const char *)r->land->name); + fputc(' ', F); assert(rtrees(r,0)>=0); assert(rtrees(r,1)>=0); assert(rtrees(r,2)>=0); @@ -1462,7 +1480,9 @@ writefaction(FILE * F, const faction * f) } fwritestr(F, (const char *)f->name); + fputc(' ', F); fwritestr(F, (const char *)f->banner); + fputc(' ', F); ws(F, f->email); ws(F, (const char *)f->passw); ws(F, (const char *)f->override); @@ -1866,6 +1886,7 @@ writegame(const char *filename, int quiet) watcher * w; wi(F, pl->id); fwritestr(F, pl->name); + fputc(' ', F); wi(F, pl->minx); wi(F, pl->maxx); wi(F, pl->miny); @@ -1924,7 +1945,9 @@ writegame(const char *filename, int quiet) for (b = r->buildings; b; b = b->next) { wi36(F, b->no); fwritestr(F, b->name); + fputc(' ', F); fwritestr(F, b->display?b->display:""); + fputc(' ', F); wi(F, b->size); ws(F, b->type->_name); wnl(F); @@ -1938,7 +1961,9 @@ writegame(const char *filename, int quiet) assert(sh->region == r); wi36(F, sh->no); fwritestr(F, (const char *)sh->name); + fputc(' ', F); fwritestr(F, sh->display?(const char *)sh->display:""); + fputc(' ', F); ws(F, sh->type->name[0]); wi(F, sh->size); wi(F, sh->damage); diff --git a/src/common/util/event.c b/src/common/util/event.c index c9e6b9785..6477f0b1e 100644 --- a/src/common/util/event.c +++ b/src/common/util/event.c @@ -38,33 +38,35 @@ write_triggers(FILE * F, const trigger * t) fputs("end ", F); } -void +int read_triggers(FILE * F, trigger ** tp) { - for (;;) { - trigger_type * ttype; - char zText[128]; - fscanf(F, "%s", zText); - if (!strcmp(zText, "end")) break; - ttype = tt_find(zText); - assert(ttype || !"unknown trigger-type"); - *tp = t_new(ttype); - if (ttype->read) { - int i = ttype->read(*tp, F); - switch (i) { - case AT_READ_OK: - tp = &(*tp)->next; - break; - case AT_READ_FAIL: - t_free(*tp); - *tp = NULL; - break; - default: - assert(!"invalid return value"); - break; - } - } - } + for (;;) { + trigger_type * ttype; + char zText[128]; + int result = fscanf(F, "%s", zText); + if (result<0) return result; + if (!strcmp(zText, "end")) break; + ttype = tt_find(zText); + assert(ttype || !"unknown trigger-type"); + *tp = t_new(ttype); + if (ttype->read) { + int i = ttype->read(*tp, F); + switch (i) { + case AT_READ_OK: + tp = &(*tp)->next; + break; + case AT_READ_FAIL: + t_free(*tp); + *tp = NULL; + break; + default: + assert(!"invalid return value"); + break; + } + } + } + return 0; } trigger * @@ -142,7 +144,8 @@ read_handler(attrib * a, FILE * F) { char zText[128]; handler_info *hi = (handler_info*)a->data.v; - fscanf(F, "%s ", zText); + int result = fscanf(F, "%s", zText); + if (result<0) return result; hi->event = strdup(zText); read_triggers(F, &hi->triggers); if (hi->triggers!=NULL) { diff --git a/src/common/util/event.h b/src/common/util/event.h index 9d2a465f3..2e6e35ff0 100644 --- a/src/common/util/event.h +++ b/src/common/util/event.h @@ -63,7 +63,7 @@ extern void handle_event(struct attrib * attribs, const char * eventname, void * /* functions for making complex triggers: */ extern void free_triggers(trigger * triggers); /* release all these triggers */ extern void write_triggers(FILE * F, const trigger * t); -extern void read_triggers(FILE * F, trigger ** tp); +extern int read_triggers(FILE * F, trigger ** tp); extern int handle_triggers(trigger ** triggers, void * data); extern struct attrib_type at_eventhandler;