t- New config variable "Encoding" added to override the locale's codeset - New "convert" module added to translate strings between codesets; all old code in gtk_client.c and configfile.c changed to use this API - UTF8 ability added to network code; as yet, it is non-functional, but will be used to translate network messages to and from UTF8 if necessary - vaccinewars - be a doctor and try to vaccinate the world | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 203e30e33f384b52c4b4d60050b9722c6d876d90 | |
parent 693a111612284494085ee70284eb8cc05155e689 | |
Author: Ben Webb | |
Date: Mon, 5 Aug 2002 11:35:44 +0000 - New config variable "Encoding" added to override the locale's codeset - New "convert" module added to translate strings between codesets; all old code in gtk_client.c and configfile.c changed to use this API - UTF8 ability added to network code; as yet, it is non-functional, but will be used to translate network messages to and from UTF8 if necessary Diffstat: M doc/configfile.html | 11 ++++++++++- M src/Makefile.am | 2 +- M src/configfile.c | 82 ++++++++++++++++++++----------- M src/configfile.h | 1 + A src/convert.c | 136 +++++++++++++++++++++++++++++++ A src/convert.h | 45 +++++++++++++++++++++++++++++++ M src/dopewars.c | 8 ++++++++ M src/dopewars.h | 4 +++- M src/gui_client/gtk_client.c | 63 ++----------------------------- M src/message.c | 1 + 10 files changed, 262 insertions(+), 91 deletions(-) --- | |
diff --git a/doc/configfile.html b/doc/configfile.html | |
t@@ -638,6 +638,15 @@ feature.)
- Last update: 16-07-2002 |
diff --git a/src/Makefile.am b/src/Makefile.am
t@@ -26,7 +26,7 @@ dopewars_DEPENDENCIES = @GUILIB@ @CURSESLIB@ @GTKPORTLIB@ @CURSESPORTLIB@ @INTLL bin_PROGRAMS = dopewars dopewars_SOURCES = admin.c admin.h AIPlayer.c AIPlayer.h util.c util.h \ - configfile.c configfile.h \ + configfile.c configfile.h convert.c convert.h \ dopewars.c dopewars.h error.c error.h log.c log.h \ message.c message.h network.c network.h nls.h \ serverside.c serverside.h sound.c sound.h \
diff --git a/src/configfile.c b/src/configfile.c
t@@ -31,6 +31,7 @@ #include/* For isprint */ #include +#include "convert.h" /* For Converter */ #include "dopewars.h" /* For struct GLOBALS etc. */ #include "nls.h" /* For _ function */ #include "error.h" /* For ErrStrFromErrno */ t@@ -77,35 +78,12 @@ static void PrintEscaped(FILE *fp, gchar *str) } /* - * Converts the given string from UTF-8 to the locale's codeset. If the - * locale codeset already is UTF-8, returns a copy of the original - * string. The returned string is dynamically allocated, and should be - * later g_free'd by the caller. - */ -static gchar *ToLocaleCodeset(const gchar *origstr) -{ -#ifdef HAVE_GLIB2 - if (!g_get_charset(NULL)) { - gchar *convstr = g_locale_from_utf8(origstr, -1, NULL, NULL, NULL); - if (convstr) { - return convstr; - } else { - return g_strdup("[Could not convert string from UTF8]"); - } - } else { - return g_strdup(origstr); - } -#else - return g_strdup(origstr); -#endif -} - -/* * Writes a single configuration file variable (identified by GlobalIndex * and StructIndex) to the specified file, in a format suitable for reading * back in (via. ParseNextConfig and friends). */ -static void WriteConfigValue(FILE *fp, int GlobalIndex, int StructIndex) +static void WriteConfigValue(FILE *fp, Converter *conv, int GlobalIndex, + int StructIndex) { gchar *GlobalName; t@@ -133,19 +111,24 @@ static void WriteConfigValue(FILE *fp, int GlobalIndex, int StructIndex) gchar *convstr; fprintf(fp, "%s = \"", GlobalName); - convstr = ToLocaleCodeset(*GetGlobalString(GlobalIndex, StructIndex)); + convstr = Conv_ToExternal(conv, + *GetGlobalString(GlobalIndex, StructIndex), -1); PrintEscaped(fp, convstr); g_free(convstr); fprintf(fp, "\"\n"); } else if (Globals[GlobalIndex].StringList) { int i; + gchar *convstr; fprintf(fp, "%s = { ", GlobalName); for (i = 0; i < *Globals[GlobalIndex].MaxIndex; i++) { if (i > 0) fprintf(fp, ", "); fputc('"', fp); - PrintEscaped(fp, (*Globals[GlobalIndex].StringList)[i]); + convstr = Conv_ToExternal(conv, + (*Globals[GlobalIndex].StringList)[i], -1); + PrintEscaped(fp, convstr); + g_free(convstr); fputc('"', fp); } fprintf(fp, " }\n"); t@@ -209,18 +192,24 @@ static void ReadFileToString(FILE *fp, gchar *str, int matchlen) static void WriteConfigFile(FILE *fp) { int i, j; + Converter *conv = Conv_New(); + + if (Encoding && Encoding[0]) { + Conv_SetCodeset(conv, Encoding); + } for (i = 0; i < NUMGLOB; i++) { if (Globals[i].Modified) { if (Globals[i].NameStruct[0]) { for (j = 1; j <= *Globals[i].MaxIndex; j++) { - WriteConfigValue(fp, i, j); + WriteConfigValue(fp, conv, i, j); } } else { - WriteConfigValue(fp, i, 0); + WriteConfigValue(fp, conv, i, 0); } } } + Conv_Free(conv); } gboolean UpdateConfigFile(const gchar *cfgfile) t@@ -261,3 +250,38 @@ gboolean UpdateConfigFile(const gchar *cfgfile) g_free(defaultfile); return TRUE; } + +static void ConvertString(Converter *conv, gchar **str) +{ + AssignName(str, Conv_ToInternal(conv, *str, -1)); +} + +void ConvertConfigFile(void) +{ + int i, j; + struct GLOBALS *gvar; + Converter *conv = Conv_New(); + + if (Encoding && Encoding[0]) { + Conv_SetCodeset(conv, Encoding); + } + + for (i = 0; i < NUMGLOB; i++) { + gvar = &Globals[i]; + if (gvar->StringVal) { + if (gvar->StructListPt) { + for (j = 1; j <= *gvar->MaxIndex; j++) { + ConvertString(conv, GetGlobalString(i, j)); + } + } else { + ConvertString(conv, GetGlobalString(i, 0)); + } + } else if (gvar->StringList) { + for (j = 0; j < *gvar->MaxIndex; j++) { + ConvertString(conv, (*gvar->StringList) + j); + } + } + } + + Conv_Free(conv); +}
diff --git a/src/configfile.h b/src/configfile.h
t@@ -26,5 +26,6 @@ #includegboolean UpdateConfigFile(const gchar *cfgfile); +void ConvertConfigFile(void); #endif /* __DP_CONFIGFILE_H__ */
diff --git a/src/convert.c b/src/convert.c
t@@ -0,0 +1,136 @@ +/************************************************************************ + * convert.c Codeset conversion functions * + * Copyright (C) 2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include+#endif + +#include +#include + +#include "convert.h" + +static gchar *int_codeset = NULL; + +static const gchar *FixedCodeset(const gchar *codeset) +{ + if (strcmp(codeset, "ANSI_X3.4-1968") == 0 + || strcmp(codeset, "ASCII") == 0) { + return "ISO-8859-1"; + } else { + return codeset; + } +} + +void Conv_SetInternalCodeset(const gchar *codeset) +{ + g_free(int_codeset); + int_codeset = g_strdup(FixedCodeset(codeset)); +} + +static const gchar *GetLocaleCodeset(void) +{ +#ifdef HAVE_GLIB2 + const gchar *codeset; + + g_get_charset(&codeset); + return FixedCodeset(codeset); +#else + return "ISO-8859-1"; +#endif +} + +Converter *Conv_New(void) +{ + Converter *conv; + + conv = g_new(Converter, 1); + conv->ext_codeset = g_strdup(GetLocaleCodeset()); + if (!int_codeset) { + int_codeset = g_strdup(GetLocaleCodeset()); + } + return conv; +} + +void Conv_Free(Converter *conv) +{ + g_free(conv->ext_codeset); + g_free(conv); +} + +void Conv_SetCodeset(Converter *conv, const gchar *codeset) +{ + g_free(conv->ext_codeset); + conv->ext_codeset = g_strdup(FixedCodeset(codeset)); +} + +gboolean Conv_Needed(Converter *conv) +{ +#ifdef HAVE_GLIB2 + return (strcmp(conv->ext_codeset, int_codeset) != 0 + || strcmp(int_codeset, "UTF-8") == 0); +#else + return FALSE; +#endif +} + +static gchar *do_convert(const gchar *from_codeset, const gchar *to_codeset, + const gchar *from_str, size_t from_len) +{ +#ifdef HAVE_GLIB2 + gchar *to_str; + + if (strcmp(to_codeset, "UTF-8") == 0 && strcmp(from_codeset, "UTF-8") == 0) { + const gchar *end; + + to_str = g_strdup(from_str); + if (!g_utf8_validate(to_str, -1, &end) && end) { + *((gchar *)end) = '\0'; + } + return to_str; + } else { + to_str = g_convert(from_str, from_len, to_codeset, from_codeset, + NULL, NULL, NULL); + if (to_str) { + return to_str; + } else { + return g_strdup("[?]"); + } + } +#else + if (from_len == -1) { + return g_strdup(from_str); + } else { + return g_strndup(from_str, from_len); + } +#endif +} + +gchar *Conv_ToExternal(Converter *conv, const gchar *int_str, size_t len) +{ + return do_convert(int_codeset, conv->ext_codeset, int_str, len); +} + +gchar *Conv_ToInternal(Converter *conv, const gchar *ext_str, size_t len) +{ + return do_convert(conv->ext_codeset, int_codeset, ext_str, len); +}
diff --git a/src/convert.h b/src/convert.h
t@@ -0,0 +1,45 @@ +/************************************************************************ + * convert.h Header file for codeset conversion functions * + * Copyright (C) 2002 Ben Webb * + * Email: ben@bellatrix.pcl.ox.ac.uk * + * WWW: http://dopewars.sourceforge.net/ * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + ************************************************************************/ + +#ifndef __DP_CONVERT_H__ +#define __DP_CONVERT_H__ + +#ifdef HAVE_CONFIG_H +# include+#endif + +#include + +typedef struct _Converter Converter; +struct _Converter { + gchar *ext_codeset; +}; + +void Conv_SetInternalCodeset(const gchar *codeset); +Converter *Conv_New(void); +void Conv_SetCodeset(Converter *conv, const gchar *codeset); +gboolean Conv_Needed(Converter *conv); +gchar *Conv_ToExternal(Converter *conv, const gchar *int_str, size_t len); +gchar *Conv_ToInternal(Converter *conv, const gchar *ext_str, size_t len); +void Conv_Free(Converter *conv); + +#endif /* __DP_CONVERT_H__ */
diff --git a/src/dopewars.c b/src/dopewars.c
t@@ -80,6 +80,7 @@ unsigned Port = 7902; gboolean Sanitized, ConfigVerbose, DrugValue; gchar *HiScoreFile = NULL, *ServerName = NULL, *ConvertFile = NULL; gchar *ServerMOTD = NULL, *WantedPlugin = NULL, *BindAddress = NULL; +gchar *Encoding = NULL; gboolean WantHelp, WantVersion, WantAntique, WantColour, WantNetwork; gboolean WantConvert, WantAdmin; t@@ -226,6 +227,11 @@ struct GLOBALS Globals[] = { /* The following strings are the helptexts for all the options that can * be set in a dopewars configuration file, or in the server. See * doc/configfile.html for more detailed explanations. */ +#ifdef HAVE_GLIB2 + {NULL, NULL, NULL, &Encoding, NULL, "Encoding", + N_("Charset encoding of the config file (e.g. UTF-8)"), NULL, NULL, + 0, "", NULL, NULL, FALSE, 0}, +#endif {&Port, NULL, NULL, NULL, NULL, "Port", N_("Network port to connect to"), NULL, NULL, 0, "", NULL, NULL, FALSE, 0}, {NULL, NULL, NULL, &HiScoreFile, NULL, "HiScoreFile", t@@ -2331,9 +2337,11 @@ void SetupParameters(void) /* Set hard-coded default values */ g_free(ServerName); g_free(ServerMOTD); + g_free(Encoding); g_free(BindAddress); ServerName = g_strdup("localhost"); ServerMOTD = g_strdup(""); + Encoding = g_strdup(""); BindAddress = g_strdup(""); g_free(WebBrowser); WebBrowser = g_strdup("/usr/bin/mozilla");
diff --git a/src/dopewars.h b/src/dopewars.h
t@@ -66,6 +66,8 @@ typedef enum { * notation */ A_DONEFIGHT, /* A fight is only considered over once the * client sends the server a C_DONE message */ + A_UTF8, /* All strings are sent over the network using + * UTF-8 (Unicode) encoding */ A_NUM /* N.B. Must be last */ } AbilType; t@@ -169,7 +171,7 @@ extern int NumLocation, NumGun, NumCop, NumDrug, NumSubway, NumPlaying, NumStoppedTo; extern int DebtInterest, BankInterest; extern gchar *HiScoreFile, *ServerName, *ConvertFile, *ServerMOTD, - *WantedPlugin, *BindAddress; + *WantedPlugin, *BindAddress, *Encoding; extern gboolean WantHelp, WantVersion, WantAntique, WantColour, WantNetwork, WantConvert, WantAdmin; #ifdef CYGWIN
diff --git a/src/gui_client/gtk_client.c b/src/gui_client/gtk_client.c
t@@ -28,6 +28,8 @@ #include#include +#include "configfile.h" +#include "convert.h" #include "dopewars.h" #include "gtk_client.h" #include "message.h" t@@ -2117,64 +2119,6 @@ static void SetIcon(GtkWidget *window, gchar **xpmdata) #endif } -#ifdef HAVE_GLIB2 -/* - * Converts a single string from the locale's codeset (e.g. ISO-8859-1) - * to UTF8. (If the locale codeset is already UTF8, and the string is - * invalid, truncate it at the first invalid character.) - */ -static void ConvertString(gchar **str) -{ - gchar *utf8str; - const gchar *end; - - if (str && *str && **str) { - if (g_get_charset(NULL)) { - if (!g_utf8_validate(*str, strlen(*str), &end) && end) { - *((gchar *)end) = '\0'; - } - } else { - utf8str = g_locale_to_utf8(*str, strlen(*str), NULL, NULL, NULL); - if (utf8str) { - AssignName(str, utf8str); - g_free(utf8str); - } - } - } -} - -/* - * Converts all configuration file strings from the locale's encoding to - * UTF-8. This is a bit of a hack, as ideally all strings would be in - * UTF-8 anyway, but we need to support old GTK+1 and curses builds, - * which are not Unicode-aware. (N.B. As the default location names, etc. - * are set before bind_text_domain_codeset is called, if the locale's - * encoding is not UTF-8, then these strings will not be UTF-8 either.) - */ -static void ConvertToUTF8(void) -{ - int i, j; - struct GLOBALS *gvar; - - for (i = 0; i < NUMGLOB; i++) { - gvar = &Globals[i]; - if (gvar->StringVal) { - if (gvar->StructListPt) { - for (j = 1; j <= *gvar->MaxIndex; j++) { - ConvertString(GetGlobalString(i, j)); - } - } else { - ConvertString(GetGlobalString(i, 0)); - } - } else if (gvar->StringList) { - for (j = 0; j < *gvar->MaxIndex; j++) { - ConvertString((*gvar->StringList) + j); - } - } - } -} -#endif - static void make_tags(GtkTextView *textview) { #ifdef HAVE_GLIB2 t@@ -2216,7 +2160,8 @@ gboolean GtkLoop(int *argc, char **argv[], gboolean ReturnOnFail) * all translations in this encoding here. */ bind_textdomain_codeset(PACKAGE, "UTF-8"); - ConvertToUTF8(); + Conv_SetInternalCodeset("UTF-8"); + ConvertConfigFile(); WantUTF8Errors(TRUE); #endif
diff --git a/src/message.c b/src/message.c
t@@ -247,6 +247,7 @@ void InitAbilities(Player *Play) Play->Abil.Local[A_DRUGVALUE] = (DrugValue ? TRUE : FALSE); Play->Abil.Local[A_TSTRING] = TRUE; Play->Abil.Local[A_DONEFIGHT] = TRUE; + Play->Abil.Local[A_UTF8] = FALSE; if (!Network) { for (i = 0; i < A_NUM; i++) {