Index: common/city.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/city.c,v retrieving revision 1.93 diff -u -r1.93 city.c --- city.c 2000/08/31 13:32:44 1.93 +++ city.c 2000/09/17 18:53:43 @@ -49,10 +49,7 @@ { 3, 4 }, { 1, 4 } }; -char **misc_city_names; - struct citystyle *city_styles = NULL; - /************************************************************************** Set the worker on the citymap. Also sets the worked field in the map. Index: common/city.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/city.h,v retrieving revision 1.67 diff -u -r1.67 city.h --- city.h 2000/08/25 13:54:27 1.67 +++ city.h 2000/09/17 18:53:45 @@ -239,9 +239,6 @@ TYPED_LIST_ITERATE(struct city, citylist, pcity) #define city_list_iterate_end LIST_ITERATE_END - -extern char **misc_city_names; - /* properties */ struct player *city_owner(struct city *pcity); Index: common/game.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/game.c,v retrieving revision 1.89 diff -u -r1.89 game.c --- game.c 2000/08/31 13:32:45 1.89 +++ game.c 2000/09/17 18:53:47 @@ -972,54 +972,60 @@ ***************************************************************/ void translate_data_names(void) { - int i, j; + int i; + static const char too_long_msg[] + = N_("Translated name is too long, truncating: %s"); + +#define name_strlcpy(dst, src) sz_loud_strlcpy(dst, src, _(too_long_msg)) for (i=0; iname_orig, tthis->name); - sz_strlcpy(tthis->name, Q_(tthis->name_orig)); + name_strlcpy(tthis->name, Q_(tthis->name_orig)); } for (i=0; iname_orig, tthis->name); - sz_strlcpy(tthis->name, Q_(tthis->name_orig)); + name_strlcpy(tthis->name, Q_(tthis->name_orig)); } for (i=0; iname_orig, tthis->name); - sz_strlcpy(tthis->name, Q_(tthis->name_orig)); + name_strlcpy(tthis->name, Q_(tthis->name_orig)); } for (i=T_FIRST; iterrain_name_orig, tthis->terrain_name); - sz_strlcpy(tthis->terrain_name, Q_(tthis->terrain_name_orig)); + name_strlcpy(tthis->terrain_name, Q_(tthis->terrain_name_orig)); sz_strlcpy(tthis->special_1_name_orig, tthis->special_1_name); - sz_strlcpy(tthis->special_1_name, Q_(tthis->special_1_name_orig)); + name_strlcpy(tthis->special_1_name, Q_(tthis->special_1_name_orig)); sz_strlcpy(tthis->special_2_name_orig, tthis->special_2_name); - sz_strlcpy(tthis->special_2_name, Q_(tthis->special_2_name_orig)); + name_strlcpy(tthis->special_2_name, Q_(tthis->special_2_name_orig)); } for (i=0; iname_orig, tthis->name); - sz_strlcpy(tthis->name, Q_(tthis->name_orig)); + name_strlcpy(tthis->name, Q_(tthis->name_orig)); for(j=0; jnum_ruler_titles; j++) { struct ruler_title *that = &tthis->ruler_titles[j]; sz_strlcpy(that->male_title_orig, that->male_title); - sz_strlcpy(that->male_title, Q_(that->male_title_orig)); + name_strlcpy(that->male_title, Q_(that->male_title_orig)); sz_strlcpy(that->female_title_orig, that->female_title); - sz_strlcpy(that->female_title, Q_(that->female_title_orig)); + name_strlcpy(that->female_title, Q_(that->female_title_orig)); } } for (i=0; iname_orig, tthis->name); - sz_strlcpy(tthis->name, Q_(tthis->name_orig)); + name_strlcpy(tthis->name, Q_(tthis->name_orig)); sz_strlcpy(tthis->name_plural_orig, tthis->name_plural); - sz_strlcpy(tthis->name_plural, Q_(tthis->name_plural_orig)); + name_strlcpy(tthis->name_plural, Q_(tthis->name_plural_orig)); } for (i=0; iname_orig, tthis->name); - sz_strlcpy(tthis->name, Q_(tthis->name_orig)); + name_strlcpy(tthis->name, Q_(tthis->name_orig)); } } +#undef name_strlcpy Index: common/log.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/log.c,v retrieving revision 1.21 diff -u -r1.21 log.c --- log.c 2000/08/08 12:23:37 1.21 +++ log.c 2000/09/17 18:53:48 @@ -217,7 +217,7 @@ Calls log_callback if non-null, else prints to stderr. **************************************************************************/ #define MAX_LEN_LOG_LINE 512 -void vreal_freelog(int level, char *message, va_list ap) +void vreal_freelog(int level, const char *message, va_list ap) { static char bufbuf[2][MAX_LEN_LOG_LINE]; char buf[MAX_LEN_LOG_LINE]; @@ -283,7 +283,7 @@ fclose(fs); } } -void real_freelog(int level, char *message, ...) +void real_freelog(int level, const char *message, ...) { va_list ap; va_start(ap, message); Index: common/log.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/log.h,v retrieving revision 1.9 diff -u -r1.9 log.h --- log.h 2000/08/08 12:23:38 1.9 +++ log.h 2000/09/17 18:53:48 @@ -54,9 +54,9 @@ void log_init(char *filename, int initial_level, log_callback_fn callback); void log_set_level(int level); -void real_freelog(int level, char *message, ...) +void real_freelog(int level, const char *message, ...) fc__attribute((format (printf, 2, 3))); -void vreal_freelog(int level, char *message, va_list ap); +void vreal_freelog(int level, const char *message, va_list ap); /* A static (per-file) function to use/update the above per-file vars. Index: common/shared.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/shared.c,v retrieving revision 1.60 diff -u -r1.60 shared.c --- shared.c 2000/09/08 01:53:30 1.60 +++ shared.c 2000/09/17 18:53:51 @@ -450,6 +450,30 @@ } /********************************************************************** + Check the length of the given string. If the string is too long, + log errmsg, which should be a string in printf-format taking up to + two arguments: the string and the length. +**********************************************************************/ +int check_strlen(const char *str, size_t len, const char *errmsg) +{ + if (strlen(str) >= len) { + freelog(LOG_ERROR, errmsg, str, len); + return 1; + } + return 0; +} + +/********************************************************************** + Call check_strlen() on str and then strlcpy() it into buffer. +**********************************************************************/ +size_t loud_strlcpy(char *buffer, const char *str, size_t len, + const char *errmsg) +{ + check_strlen(str, len, errmsg); + return mystrlcpy(buffer, str, len); +} + +/********************************************************************** cat_snprintf is like a combination of my_snprintf and mystrlcat; it does snprintf to the end of an existing string. Index: common/shared.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/shared.h,v retrieving revision 1.84 diff -u -r1.84 shared.h --- shared.h 2000/09/02 01:58:35 1.84 +++ shared.h 2000/09/17 18:53:51 @@ -74,6 +74,13 @@ void remove_trailing_char(char *s, char trailing); int wordwrap_string(char *s, int len); +int check_strlen(const char *str, size_t len, const char *errmsg); +size_t loud_strlcpy(char *buffer, const char *str, size_t len, + const char *errmsg); +/* Convenience macro. */ +#define sz_loud_strlcpy(buffer, str, errmsg) \ + loud_strlcpy(buffer, str, sizeof(buffer), errmsg) + char *end_of_strn(char *str, int *nleft); int cat_snprintf(char *str, size_t n, const char *format, ...) fc__attribute((format (printf, 3, 4))); Index: server/cityhand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/cityhand.c,v retrieving revision 1.88 diff -u -r1.88 cityhand.c --- cityhand.c 2000/08/31 13:32:47 1.88 +++ cityhand.c 2000/09/17 18:53:55 @@ -54,6 +54,9 @@ struct packet_short_city *packet); static void remove_trade_route(int c1, int c2); +char **misc_city_names; +int num_misc_city_names; + /************************************************************************** Establish a trade route, notice that there has to be space for them, So use can_establish_Trade_route first. @@ -104,7 +107,6 @@ { char **nptr; int i, j; - static int n_misc = -1; static char tempname[MAX_LEN_NAME]; static const int num_tiles = MAP_MAX_WIDTH * MAP_MAX_HEIGHT; @@ -115,16 +117,14 @@ if(!game_find_city_by_name(*nptr)) return *nptr; } - - if (n_misc == -1) - for (n_misc = 0; misc_city_names[n_misc]; n_misc++) - ; - if (n_misc > 0) { - j = myrand(n_misc); + if (num_misc_city_names > 0) { + j = myrand(num_misc_city_names); - for (i=0; i= n_misc) j = 0; + for (i = 0; i < num_misc_city_names; i++) { + if (j >= num_misc_city_names) { + j = 0; + } if (!game_find_city_by_name(misc_city_names[j])) return misc_city_names[j]; j++; Index: server/ruleset.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v retrieving revision 1.65 diff -u -r1.65 ruleset.c --- ruleset.c 2000/08/31 13:32:49 1.65 +++ ruleset.c 2000/09/17 18:54:01 @@ -14,10 +14,11 @@ #include #endif +#include +#include #include #include #include -#include #include "capability.h" #include "city.h" @@ -36,6 +37,13 @@ #include "ruleset.h" +static const char name_too_long[] = N_("Name \"%s\" too long; truncating."); +#define check_name(name) check_strlen(name, MAX_LEN_NAME, _(name_too_long)) +#define name_strlcpy(dst, src) sz_loud_strlcpy(dst, src, _(name_too_long)) + +extern char **misc_city_names; +extern int num_misc_city_names; + static void openload_ruleset_file(struct section_file *file, char *subdir, char *whichset); static char *check_ruleset_capabilities(struct section_file *file, @@ -90,16 +98,16 @@ /************************************************************************** Do initial section_file_load on a ruleset file. "subdir" = "default", "civ1", "custom", ... - "whichset" = "techs", "units", "buildings", "terrain" (...) + "whichset" = "techs", "units", "buildings", "terrain", ... Calls exit(1) on failure. This no longer returns the full filename opened; used secfile_filename() if you want it. **************************************************************************/ static void openload_ruleset_file(struct section_file *file, - char *subdir, char *whichset) + char *subdir, char *whichset) { - char filename1[512], filename2[512], *dfilename; - char sfilename[512]; + char filename1[PATH_MAX + 1], filename2[PATH_MAX + 1], *dfilename; + char sfilename[PATH_MAX + 1]; my_snprintf(filename1, sizeof(filename1), "%s_%s.ruleset", subdir, whichset); dfilename = datafilename(filename1); @@ -107,9 +115,9 @@ my_snprintf(filename2, sizeof(filename2), "%s/%s.ruleset", subdir, whichset); dfilename = datafilename(filename2); if (!dfilename) { - freelog(LOG_FATAL, _("Could not find readable ruleset file \"%s\""), - filename1); - freelog(LOG_FATAL, _("or \"%s\" in data path."), filename2); + freelog(LOG_FATAL, + _("Could not find readable ruleset" + " file \"%s\" or \"%s\" in data path."), filename1, filename2); freelog(LOG_FATAL, _("The data path may be set via" " the environment variable FREECIV_PATH.")); freelog(LOG_FATAL, _("Current data path is: \"%s\""), datafilename(NULL)); @@ -369,7 +377,7 @@ } /************************************************************************** - Lookup a terrain name in the tile_types array; return its index. + Look up a terrain name in the tile_types array and return its index. **************************************************************************/ static enum tile_terrain_type lookup_terrain(char *name, int tthis) { @@ -426,10 +434,11 @@ sz_strlcpy(advances[A_NONE].name, "None"); game.num_tech_types = num_techs + 1; /* includes A_NONE */ - a = &advances[A_FIRST]; - for( i=0; iname, secfile_lookup_str(file, "%s.name", sec[i])); + a = &advances[A_FIRST]; + for (i = 0; i < num_techs; i++ ) { + char *name = secfile_lookup_str(file, "%s.name", sec[i]); + name_strlcpy(a->name, name); a++; } } @@ -533,7 +542,6 @@ { char **sec; int nval, i; - struct unit_type *u; const char *filename = secfile_filename(file); section_file_lookup(file,"datafile.description"); /* unused */ @@ -551,9 +559,9 @@ exit(1); } game.num_unit_types = nval; - for( i=0; iname, secfile_lookup_str(file, "%s.name", sec[i])); + for (i = 0; i < game.num_unit_types; i++ ) { + char *name = secfile_lookup_str(file, "%s.name", sec[i]); + name_strlcpy(unit_types[i].name, name); } } @@ -839,7 +847,6 @@ { char **sec; int nval, i; - struct impr_type *b; const char *filename = secfile_filename(file); section_file_lookup(file,"datafile.description"); /* unused */ @@ -864,10 +871,10 @@ /* REMOVE TO HERE when gen-impr implemented. */ game.num_impr_types = nval; - for (i=0; iname, secfile_lookup_str(file, "%s.name", sec[i])); - b->name_orig[0] = '\0'; + for (i = 0; i < game.num_impr_types; i++) { + char *name = secfile_lookup_str(file, "%s.name", sec[i]); + name_strlcpy(improvement_types[i].name, name); + improvement_types[i].name_orig[0] = 0; } } @@ -1187,7 +1194,6 @@ **************************************************************************/ static void load_terrain_names(struct section_file *file) { - struct tile_type *t; int nval, i; char **sec; const char *filename = secfile_filename(file); @@ -1203,15 +1209,14 @@ freelog(LOG_FATAL, "Bad number of terrains %d (%s)", nval, filename); exit(1); } - - for (i = T_FIRST; i < T_COUNT; i++) - { - t = &(tile_types[i]); - sz_strlcpy(t->terrain_name, - secfile_lookup_str(file, "%s.terrain_name", sec[i])); - if (0 == strcmp(t->terrain_name, "unused")) *(t->terrain_name) = '\0'; + for (i = T_FIRST; i < T_COUNT; i++) { + char *name = secfile_lookup_str(file, "%s.terrain_name", sec[i]); + name_strlcpy(tile_types[i].terrain_name, name); + if (!strcmp(tile_types[i].terrain_name, "unused")) { + tile_types[i].terrain_name[0] = 0; } + } } /************************************************************************** @@ -1291,6 +1296,8 @@ for (i = T_FIRST; i < T_COUNT; i++) { + char *s1_name; + char *s2_name; t = &(tile_types[i]); sz_strlcpy(t->graphic_str, @@ -1305,15 +1312,15 @@ t->shield = secfile_lookup_int(file, "%s.shield", sec[i]); t->trade = secfile_lookup_int(file, "%s.trade", sec[i]); - sz_strlcpy(t->special_1_name, - secfile_lookup_str(file, "%s.special_1_name", sec[i])); + s1_name = secfile_lookup_str(file, "%s.special_1_name", sec[i]); + name_strlcpy(t->special_1_name, s1_name); if (0 == strcmp(t->special_1_name, "none")) *(t->special_1_name) = '\0'; t->food_special_1 = secfile_lookup_int(file, "%s.food_special_1", sec[i]); t->shield_special_1 = secfile_lookup_int(file, "%s.shield_special_1", sec[i]); t->trade_special_1 = secfile_lookup_int(file, "%s.trade_special_1", sec[i]); - sz_strlcpy(t->special_2_name, - secfile_lookup_str(file, "%s.special_2_name", sec[i])); + s2_name = secfile_lookup_str(file, "%s.special_2_name", sec[i]); + name_strlcpy(t->special_2_name, s2_name); if (0 == strcmp(t->special_2_name, "none")) *(t->special_2_name) = '\0'; t->food_special_2 = secfile_lookup_int(file, "%s.food_special_2", sec[i]); t->shield_special_2 = secfile_lookup_int(file, "%s.shield_special_2", sec[i]); @@ -1361,7 +1368,6 @@ **************************************************************************/ static void load_government_names(struct section_file *file) { - struct government *g = NULL; int nval, i; char **sec; const char *filename = secfile_filename(file); @@ -1385,9 +1391,9 @@ /* first fill in government names so find_government_by_name will work -SKi */ for(i = 0; i < game.government_count; i++) { - g = &governments[i]; - sz_strlcpy(g->name, secfile_lookup_str(file, "%s.name", sec[i])); - g->index = i; + char *name = secfile_lookup_str(file, "%s.name", sec[i]); + name_strlcpy(governments[i].name, name); + governments[i].index = i; } } @@ -1704,7 +1710,6 @@ { char **sec; int i, j; - struct nation_type *pl; section_file_lookup(file,"datafile.description"); /* unused */ @@ -1712,27 +1717,35 @@ game.playable_nation_count = game.nation_count - 1; freelog(LOG_VERBOSE, "There are %d nations defined", game.playable_nation_count); - if ( game.playable_nation_count >= MAX_NUM_NATIONS - || game.playable_nation_count == 0) { - freelog(LOG_FATAL, "There must be between 1 and %d nations", MAX_NUM_NATIONS); - exit(1); + if (game.playable_nation_count < 0) { + freelog(LOG_FATAL, + "There must be at least one nation defined; number is %d", + game.playable_nation_count); + exit(1); + } else if (game.playable_nation_count >= MAX_NUM_NATIONS) { + freelog(LOG_ERROR, + "There are too many nations; only using %d of %d available.", + MAX_NUM_NATIONS - 1, game.playable_nation_count); + game.playable_nation_count = MAX_NUM_NATIONS - 1; } alloc_nations(game.nation_count); for( i=0; iname, secfile_lookup_str(file, "%s.name", sec[i])); - sz_strlcpy(pl->name_plural, secfile_lookup_str(file, "%s.plural", sec[i])); - - /* check if nation name is not already defined */ - for( j=0; jname) ) { - freelog(LOG_FATAL, "Nation %s already defined in section nation%d", pl->name, j); - exit(1); - } - if( !strcmp(get_nation_name_plural(j), pl->name_plural) ) { - freelog(LOG_FATAL, "Nation %s already defined in section nation%d", - pl->name_plural, j); + char *name = secfile_lookup_str(file, "%s.name", sec[i]); + char *name_plural = secfile_lookup_str(file, "%s.plural", sec[i]); + struct nation_type *pl = get_nation_by_idx(i); + + name_strlcpy(pl->name, name); + name_strlcpy(pl->name_plural, name_plural); + + /* Check if nation name is already defined. */ + for(j = 0; j < i; j++) { + if (!strcmp(get_nation_name(j), pl->name) + || !strcmp(get_nation_name_plural(j), pl->name_plural)) { + freelog(LOG_FATAL, + "Nation %s (the %s) defined twice; " + "in section nation%d and section nation%d", + pl->name, pl->name, j, i); exit(1); } } @@ -1748,7 +1761,7 @@ struct nation_type *pl; struct government *gov; int *res, dim, val, i, j, nval; - char temp_name[MAX_LEN_NAME], male[MAX_LEN_NAME], female[MAX_LEN_NAME]; + char temp_name[MAX_LEN_NAME]; char **cities, **techs, **leaders, **sec; const char *filename = secfile_filename(file); @@ -1762,37 +1775,51 @@ /* nation leaders */ leaders = secfile_lookup_str_vec(file, &dim, "%s.leader", sec[i]); - if( dim<1 || dim > MAX_NUM_LEADERS ) { - freelog(LOG_FATAL, "Nation %s: number of leaders must be 1-%d", pl->name, - MAX_NUM_LEADERS); + if (dim > MAX_NUM_LEADERS) { + freelog(LOG_ERROR, "Nation %s: too many leaders; only using %d of %d", + pl->name, MAX_NUM_LEADERS, dim); + dim = MAX_NUM_LEADERS; + } else if (dim < 1) { + freelog(LOG_FATAL, + "Nation %s: number of leaders is %d; at least one is required.", + pl->name, dim); exit(1); } pl->leader_count = dim; - for( j=0; jleader_name[j] = mystrdup(leaders[j]); + if (check_name(leaders[j])) { + pl->leader_name[j][MAX_LEN_NAME - 1] = 0; + } } free(leaders); /* check if leader name is not already defined */ if( (bad_leader=check_leader_names(i)) ) { - freelog(LOG_FATAL, "Nation %s leader %s already defined", pl->name, bad_leader); + freelog(LOG_FATAL, "Nation %s: leader %s defined more than once", + pl->name, bad_leader); exit(1); } /* read leaders'sexes */ leaders = secfile_lookup_str_vec(file, &dim, "%s.leader_sex", sec[i]); - if( dim != pl->leader_count ) { - freelog(LOG_FATAL, "Nation %s: leader sex count not equal to number of leaders", - pl->name); + if (dim != pl->leader_count) { + freelog(LOG_FATAL, + "Nation %s: the leader sex count (%d) " + "is not equal to the number of leaders (%d)", + pl->name, dim, pl->leader_count); exit(1); } - for(j=0; jleader_is_male[j] = 1; - else if( strcmp(leaders[j], "Female")==0 ) + } else if (0 == mystrcasecmp(leaders[j], "Female")) { pl->leader_is_male[j] = 0; - else { - freelog( LOG_FATAL, "Nation %s leader sex must be Male or Female", pl->name); - exit(1); + } else { + freelog(LOG_ERROR, + "Nation %s, leader %s: sex must be either Male or Female; " + "assuming Male", + pl->name, pl->leader_name[j]); + pl->leader_is_male[j] = 1; } } free(leaders); @@ -1807,18 +1834,26 @@ /* Ruler titles */ j = -1; - while((g = secfile_lookup_str_default(file, NULL, "%s.ruler_titles%d.government", - sec[i], ++j))) { - sz_strlcpy(male, secfile_lookup_str(file, "%s.ruler_titles%d.male_title", - sec[i], j)); - sz_strlcpy(female, secfile_lookup_str(file, - "%s.ruler_titles%d.female_title", - sec[i], j)); - if( (gov = find_government_by_name(g)) != NULL ) { - set_ruler_title(gov, i, male, female); - } - else { - freelog(LOG_VERBOSE,"Nation %s, government %s not found", pl->name, g); + while ((g = secfile_lookup_str_default(file, NULL, + "%s.ruler_titles%d.government", + sec[i], ++j))) { + char *male_name; + char *female_name; + + male_name = secfile_lookup_str(file, "%s.ruler_titles%d.male_title", + sec[i], j); + female_name = secfile_lookup_str(file, "%s.ruler_titles%d.female_title", + sec[i], j); + + gov = find_government_by_name(g); + if (gov != NULL) { + check_name(male_name); + check_name(female_name); + /* Truncation is handled by set_ruler_title(). */ + set_ruler_title(gov, i, male_name, female_name); + } else { + freelog(LOG_VERBOSE, + "Nation %s: government %s not found", pl->name, g); } } @@ -1827,15 +1862,25 @@ sz_strlcpy(temp_name, secfile_lookup_str_default(file, "-", "%s.city_style", sec[i])); pl->city_style = get_style_by_name(temp_name); - if( pl->city_style == -1 ) { - freelog( LOG_NORMAL, "Nation %d city style %s not known, using default", - i, temp_name); + if (pl->city_style == -1) { + freelog(LOG_NORMAL, + "Nation %s: city style %s is unknown, using default.", + pl->name_plural, temp_name); pl->city_style = 0; } - if( city_styles[pl->city_style].techreq != A_NONE ) { - freelog( LOG_FATAL, "Nation %d city style %s is not available from beginning", - i, temp_name); - exit(1); + + while (city_styles[pl->city_style].techreq != A_NONE) { + if (pl->city_style == 0) { + freelog(LOG_FATAL, + "Nation %s: the default city style is not available " + "from the beginning", pl->name); + /* Note that we can't use temp_name here. */ + exit(1); + } + freelog(LOG_ERROR, + "Nation %s: city style %s is not available from beginning; " + "using default.", pl->name, temp_name); + pl->city_style = 0; } /* AI stuff */ @@ -1845,14 +1890,14 @@ pl->civilized = secfile_lookup_int_default(file, 2, "%s.civilized", sec[i]); res = secfile_lookup_int_vec(file, &dim, "%s.advisors", sec[i]); - if( dim != ADV_LAST ) { - freelog( LOG_FATAL, "Nation %d number of advisors must be %d but is %d", - i, ADV_LAST, dim); - exit(1); + if (dim != ADV_LAST) { + freelog(LOG_FATAL, "Nation %s: number of advisors must be %d but is %d", + pl->name_plural, ADV_LAST, dim); + exit(1); } for ( j=0; jadvisors[j] = res[j]; - if(res) free(res); + if(res) free(res); /* AI techs */ @@ -1866,11 +1911,11 @@ for( j=0; jname); - } else if(!tech_exists(val)) { - freelog(LOG_VERBOSE, "Goal tech %d \"%s\" for %s doesn't exist", - j, techs[j], pl->name); + freelog(LOG_VERBOSE, "Could not match tech goal \"%s\" for the %s", + techs[j], pl->name_plural); + } else if (!tech_exists(val)) { + freelog(LOG_VERBOSE, "Goal tech \"%s\" for the %s doesn't exist", + techs[j], pl->name_plural); val = A_LAST; } if(val != A_LAST && val != A_NONE) { @@ -1919,8 +1964,11 @@ cities = secfile_lookup_str_vec(file, &dim, "%s.cities", sec[i]); pl->default_city_names = fc_calloc(dim+1, sizeof(char*)); pl->default_city_names[dim] = NULL; - for ( j=0; jdefault_city_names[j] = mystrdup(cities[j]); + if (check_name(cities[j])) { + pl->default_city_names[j][MAX_LEN_NAME - 1] = 0; + } } if(cities) free(cities); } @@ -1929,12 +1977,17 @@ /* read miscellaneous city names */ cities = secfile_lookup_str_vec(file, &dim, "misc.cities"); - misc_city_names = fc_calloc(dim+1, sizeof(char*)); - for ( j=0; j