? typescript 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/15 04:03:31 @@ -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/15 04:03:32 @@ -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: 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/15 04:03:36 @@ -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,9 +107,8 @@ { char **nptr; int i, j; - static int n_misc = -1; - static char tempname[MAX_LEN_NAME]; + static char tempname[MAX_LEN_NAME]; static const int num_tiles = MAP_MAX_WIDTH * MAP_MAX_HEIGHT; freelog(LOG_VERBOSE, "Suggesting city name for %s", pplayer->name); @@ -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/15 04:03:42 @@ -14,10 +14,11 @@ #include #endif +#include +#include #include #include #include -#include #include "capability.h" #include "city.h" @@ -36,6 +37,9 @@ #include "ruleset.h" +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, @@ -60,6 +64,8 @@ static enum tile_terrain_type lookup_terrain(char *name, int tthis); +static int check_name(const char *name); + static void load_tech_names(struct section_file *file); static void load_unit_names(struct section_file *file); static void load_building_names(struct section_file *file); @@ -90,16 +96,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 +113,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 +375,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) { @@ -391,8 +397,22 @@ return (i); } } + return (T_UNKNOWN); +} - return (T_UNKNOWN); +/************************************************************************** + Check that a name is not too long, and possibly warn about + truncation, but do not perform the actual truncation. Return 1 or 0 + depending on whether the name should be truncated or not. +**************************************************************************/ + +static int check_name(const char *name) +{ + if (strlen(name) >= MAX_LEN_NAME) { + freelog(LOG_ERROR, "Name too long; truncating: %s", name); + return 1; + } + return 0; } /************************************************************************** @@ -426,10 +446,12 @@ 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]); + check_name(name); + sz_strlcpy(a->name, name); a++; } } @@ -533,7 +555,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 +572,10 @@ 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]); + check_name(name); + sz_strlcpy(unit_types[i].name, name); } } @@ -839,7 +861,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 +885,11 @@ /* 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]); + check_name(name); + sz_strlcpy(improvement_types[i].name, name); + improvement_types[i].name_orig[0] = 0; } } @@ -1187,7 +1209,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 +1224,15 @@ 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]); + check_name(name); + sz_strlcpy(tile_types[i].terrain_name, name); + if (!strcmp(tile_types[i].terrain_name, "unused")) { + tile_types[i].terrain_name[0] = 0; } + } } /************************************************************************** @@ -1357,11 +1378,10 @@ } /************************************************************************** - ... + ... **************************************************************************/ 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 +1405,10 @@ /* 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]); + check_name(name); + sz_strlcpy(governments[i].name, name); + governments[i].index = i; } } @@ -1712,10 +1733,16 @@ 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); @@ -1724,15 +1751,14 @@ sz_strlcpy(pl->name, 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); + /* 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 +1774,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 +1788,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 == strcmp(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 +1847,27 @@ /* 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); + /* FIXME: We're supplying NULL as default? */ + 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 +1876,18 @@ 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); + + if (city_styles[pl->city_style].techreq != A_NONE) { + 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 +1897,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); + free(res); /* AI techs */ @@ -1866,11 +1918,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) { @@ -1880,7 +1932,7 @@ } freelog(LOG_DEBUG, "%s %d tech goals", pl->name, j); if(j==0) { - freelog(LOG_VERBOSE, "No valid goal techs for %s", pl->name); + freelog(LOG_VERBOSE, "No valid goal techs for %s.", pl->name); } while( j < MAX_NUM_TECH_GOALS ) pl->goals.tech[j++] = A_NONE; @@ -1919,8 +1971,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 +1984,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