diff -Nur -X/mnt/data/freeciv-dev/freeciv/diff_ignore freeciv/server/ruleset.c codeciv/server/ruleset.c --- freeciv/server/ruleset.c Thu Jul 19 15:07:57 2001 +++ codeciv/server/ruleset.c Thu Jul 19 21:08:32 2001 @@ -1763,6 +1763,143 @@ } /************************************************************************** +Temporary (hopefully) kludge to avoid upper ascii character trouble. +(By replacing the offending characters with approximations.) +Also checks the string length. + +The upper ascii characters created strange behaviour in the gtk client when +running with LANG=C. The root of the problems in the gtk client was libc. +There was/is also potential for trange behavious other places if this +kludge is not in place. +**************************************************************************/ +struct entry { + char from; + char *to; +}; +struct entry etable[] = { + {'À', "A"}, + {'Á', "A"}, + {'Â', "A"}, + {'Ã', "A"}, + {'Ä', "A"}, + {'Å', "AA"}, + {'Æ', "AE"}, + {'Ç', "C"}, + {'È', "E"}, + {'É', "E"}, + {'Ê', "E"}, + {'Ë', "E"}, + {'Ì', "I"}, + {'Í', "I"}, + {'Î', "I"}, + {'Ï', "I"}, + {'Ð', "?"}, + {'Ñ', "N"}, + {'Ò', "O"}, + {'Ó', "O"}, + {'Ô', "O"}, + {'Õ', "O"}, + {'Ö', "O"}, + {'×', "?"}, + {'Ø', "OE"}, + {'Ù', "U"}, + {'Ú', "U"}, + {'Û', "U"}, + {'Ü', "U"}, + {'Ý', "Y"}, + {'Þ', "?"}, + {'ß', "ss"}, + {'à', "a"}, + {'á', "a"}, + {'â', "a"}, + {'ã', "a"}, + {'ä', "a"}, + {'å', "aa"}, + {'æ', "ae"}, + {'ç', "c"}, + {'è', "e"}, + {'é', "e"}, + {'ê', "e"}, + {'ë', "e"}, + {'ì', "i"}, + {'í', "i"}, + {'î', "i"}, + {'ï', "i"}, + {'ð', "o"}, + {'ñ', "n"}, + {'ò', "o"}, + {'ó', "o"}, + {'ô', "o"}, + {'õ', "o"}, + {'ö', "o"}, + {'÷', "?"}, + {'ø', "oe"}, + {'ù', "u"}, + {'ú', "u"}, + {'û', "u"}, + {'ü', "u"}, + {'ý', "y"}, + {'þ', "?"}, + {'ÿ', "y"}, + {'\0', ""} +}; +static void convert_name_and_check(char *str) +{ + char *strp; + + /* If the longest replacement in etable grows to more than 2 chars + then you need to replace the multiplicator. */ + char res[2 * MAX_LEN_NAME]; + char *resp; + static int is_init = 0; + + if (!is_init) { + is_init = 1; + freelog(LOG_NORMAL, "Converting upper ascii characters to " + "lower ascii approximations"); + } + + if (check_name(str)) { + str[MAX_LEN_NAME-1] = '\0'; + } + + for (resp = res, strp = str; *strp != '\0'; strp++) { + int converted = 0; + + /* You could make an array lookup using the char as index, but I + don't know if signed/unsigned char issues will cause trouble. */ + int i; + for (i=0; etable[i].from != '\0'; i++) { + if (*strp == etable[i].from) { + char *ep; + for (ep = etable[i].to; *ep != '\0'; ep++) { + *(resp++) = *ep; + } + + converted = 1; + } + } + + if (!converted) { + if (*strp & 0x80) { + /* upper ascii character not found in etable. */ + *(resp++) = '?'; + freelog(LOG_ERROR, "replacing unknown character \'%c\' with \'?\'", *strp); + } else { + *(resp++) = *strp; + } + } + } + *resp = '\0'; + + if (check_name(res)) { + res[MAX_LEN_NAME-1] = '\0'; + } + + strcpy(str, res); +} + +/************************************************************************** Load nations.ruleset file **************************************************************************/ static void load_ruleset_nations(struct section_file *file) @@ -1798,9 +1935,7 @@ pl->leader_count = dim; for(j = 0; j < dim; j++) { pl->leader_name[j] = mystrdup(leaders[j]); - if (check_name(leaders[j])) { - pl->leader_name[j][MAX_LEN_NAME - 1] = 0; - } + convert_name_and_check(pl->leader_name[j]); } free(leaders); @@ -1857,10 +1992,16 @@ 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); + char *male_name2, *female_name2; + male_name2 = mystrdup(male_name); + female_name2 = mystrdup(female_name); + convert_name_and_check(male_name2); + convert_name_and_check(female_name2); + + set_ruler_title(gov, i, male_name2, female_name2); + + free(male_name2); + free(female_name2); } else { /* LOG_VERBOSE rather than LOG_ERROR so that can use single nation ruleset file with variety of government ruleset files: */ @@ -1984,9 +2125,7 @@ pl->default_city_names[dim] = NULL; for (j = 0; j < dim; j++) { pl->default_city_names[j] = mystrdup(cities[j]); - if (check_name(cities[j])) { - pl->default_city_names[j][MAX_LEN_NAME - 1] = 0; - } + convert_name_and_check(pl->default_city_names[j]); } if(cities) free(cities); } @@ -1998,9 +2137,7 @@ for (j = 0; j < dim; j++) { misc_city_names[j] = mystrdup(cities[j]); - if (check_name(cities[j])) { - misc_city_names[j][MAX_LEN_NAME - 1] = 0; - } + convert_name_and_check(misc_city_names[j]); } num_misc_city_names = dim;