[Freeciv-Dev] Re: (PR#1824) ruleset data is in incompatible charsets
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://rt.freeciv.org/Ticket/Display.html?id=1824 >
Jason Short wrote:
> Note that this is different from what Vasco does now in the conversion
> step for gui-gtk-2.0. He automatically converts strings to and from
> (basically) the "network" charset and UTF-8 when the strings are
> received from the network. This works well with the gtk2 client because
> UTF-8 can then basically be used everywhere. It also works because
> ascii strings can safely be converted into utf-8 and still used. It
> won't work well for other GUIs with less convenient charsets (like
> gui-sdl with a UTF-16 charset).
OK, this patch does it the way the gtk2 client did it. This is much
easier, leading to a relatively small patch (only 50k :-).
- The server keeps all text strings in the data encoding.
- The client keeps all text strings in the display encoding.
- Text strings are converted by the client's network code.
- Gettext translates into the internal encoding: the data encoding at
the server, the display encoding at the client.
- fprintf must therefore generally convert from this encoding to the
local encoding. So I write a new function fc_fprintf to do this. Of
course this replaces gui-gtk-2.0's fprintf_utf8. I didn't replace all
fprintf's with this new function, however.
It's still pretty unpolished, but I believe this design is workable.
Please test.
jason
Index: configure.ac
===================================================================
RCS file: /home/freeciv/CVS/freeciv/configure.ac,v
retrieving revision 1.61
diff -u -r1.61 configure.ac
--- configure.ac 19 Apr 2004 17:24:16 -0000 1.61
+++ configure.ac 26 Apr 2004 20:14:26 -0000
@@ -305,6 +305,11 @@
AC_MSG_ERROR([zlib found but not zlib.h.
You may need to install a zlib \"development\" package.]))
+dnl Check for libiconv (which is usually included in glibc, but may be
+dnl distributed separately).
+AM_ICONV
+LIBS="$LIBS $LIBICONV"
+
dnl Check and choose clients
if test x$client != xno; then
Index: configure.in
===================================================================
RCS file: /home/freeciv/CVS/freeciv/configure.in,v
retrieving revision 1.237
diff -u -r1.237 configure.in
--- configure.in 20 Apr 2004 17:26:13 -0000 1.237
+++ configure.in 26 Apr 2004 20:14:26 -0000
@@ -298,6 +298,11 @@
AC_MSG_ERROR([zlib found but not zlib.h.
You may need to install a zlib \"development\" package.]))
+dnl Check for libiconv (which is usually included in glibc, but may be
+dnl distributed separately).
+AM_ICONV
+LIBS="$LIBS $LIBICONV"
+
dnl Check and choose clients
if test x$client != xno; then
Index: client/civclient.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/civclient.c,v
retrieving revision 1.187
diff -u -r1.187 civclient.c
--- client/civclient.c 21 Apr 2004 19:46:37 -0000 1.187
+++ client/civclient.c 26 Apr 2004 20:14:26 -0000
@@ -32,7 +32,9 @@
#endif
#include "capstr.h"
+#include "dataio.h"
#include "diptreaty.h"
+#include "fciconv.h"
#include "fcintl.h"
#include "game.h"
#include "idex.h"
@@ -102,6 +104,64 @@
*/
bool turn_done_sent = FALSE;
+/**************************************************************************
+ Convert a text string from the data to the display encoding, when it
+ is read from the network.
+**************************************************************************/
+static unsigned char *put_conv(const char *src, size_t *length)
+{
+ char *out = display_to_data_string_malloc(src);
+
+ if (out) {
+ *length = strlen(out);
+ return out;
+ } else {
+ *length = 0;
+ return NULL;
+ }
+}
+
+/**************************************************************************
+ Convert a text string from the data to the display encoding when it is
+ first read from the network. Returns FALSE if the destination isn't
+ large enough or the source was bad.
+**************************************************************************/
+static bool get_conv(char *dst, size_t ndst,
+ const unsigned char *src, size_t nsrc)
+{
+ char *out = data_to_display_string_malloc(src);
+ bool ret = TRUE;
+ size_t len;
+
+ if (!out) {
+ dst[0] = '\0';
+ return FALSE;
+ }
+
+ len = strlen(out);
+ if (ndst > 0 && len >= ndst) {
+ ret = FALSE;
+ len = ndst - 1;
+ }
+
+ memcpy(dst, out, len);
+ dst[len] = '\0';
+ free(out);
+
+ return ret;
+}
+
+/**************************************************************************
+ Set up charsets for the client.
+**************************************************************************/
+static void charsets_init(void)
+{
+#ifdef ENABLE_NLS
+ bind_textdomain_codeset(PACKAGE, get_display_encoding());
+#endif
+ dio_set_put_conv_callback(put_conv);
+ dio_set_get_conv_callback(get_conv);
+}
/**************************************************************************
...
@@ -214,6 +274,7 @@
conn_list_init(&game.game_connections);
ui_init();
+ charsets_init();
my_init_network();
init_messages_where();
init_city_report_data();
Index: client/clinet.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/clinet.c,v
retrieving revision 1.96
diff -u -r1.96 clinet.c
--- client/clinet.c 13 Apr 2004 16:40:00 -0000 1.96
+++ client/clinet.c 26 Apr 2004 20:14:26 -0000
@@ -812,12 +812,12 @@
if (type != SERVER_LAN_VERSION) {
return lan_servers;
}
- dio_get_string(&din, servername, sizeof(servername));
- dio_get_string(&din, port, sizeof(port));
- dio_get_string(&din, version, sizeof(version));
- dio_get_string(&din, status, sizeof(status));
- dio_get_string(&din, players, sizeof(players));
- dio_get_string(&din, metastring, sizeof(metastring));
+ dio_get_ascii_string(&din, servername, sizeof(servername));
+ dio_get_ascii_string(&din, port, sizeof(port));
+ dio_get_ascii_string(&din, version, sizeof(version));
+ dio_get_ascii_string(&din, status, sizeof(status));
+ dio_get_ascii_string(&din, players, sizeof(players));
+ dio_get_ascii_string(&din, metastring, sizeof(metastring));
if (!mystrcasecmp("none", servername)) {
from = gethostbyaddr((char *) &fromend.sockaddr_in.sin_addr,
Index: client/gui-gtk/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/gui_main.c,v
retrieving revision 1.148
diff -u -r1.148 gui_main.c
--- client/gui-gtk/gui_main.c 15 Apr 2004 19:36:01 -0000 1.148
+++ client/gui-gtk/gui_main.c 26 Apr 2004 20:14:26 -0000
@@ -31,6 +31,7 @@
#include <unistd.h>
#endif
+#include "fciconv.h"
#include "fcintl.h"
#include "game.h"
#include "government.h"
@@ -798,6 +799,7 @@
**************************************************************************/
void ui_init(void)
{
+ init_character_encodings(NULL, 1);
}
/**************************************************************************
Index: client/gui-gtk-2.0/connectdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/connectdlg.c,v
retrieving revision 1.32
diff -u -r1.32 connectdlg.c
--- client/gui-gtk-2.0/connectdlg.c 23 Apr 2004 23:13:55 -0000 1.32
+++ client/gui-gtk-2.0/connectdlg.c 26 Apr 2004 20:14:27 -0000
@@ -260,12 +260,12 @@
GtkTreeIter it;
int i;
- row[0] = ntoh_str(pserver->name);
- row[1] = ntoh_str(pserver->port);
- row[2] = ntoh_str(pserver->version);
+ row[0] = pserver->name;
+ row[1] = pserver->port;
+ row[2] = pserver->version;
row[3] = _(pserver->status);
- row[4] = ntoh_str(pserver->players);
- row[5] = ntoh_str(pserver->metastring);
+ row[4] = pserver->players;
+ row[5] = pserver->metastring;
gtk_list_store_append(storelan, &it);
gtk_list_store_set(storelan, &it,
@@ -1135,12 +1135,12 @@
GtkTreeIter it;
int i;
- row[0] = ntoh_str(pserver->name);
- row[1] = ntoh_str(pserver->port);
- row[2] = ntoh_str(pserver->version);
+ row[0] = pserver->name;
+ row[1] = pserver->port;
+ row[2] = pserver->version;
row[3] = _(pserver->status);
- row[4] = ntoh_str(pserver->players);
- row[5] = ntoh_str(pserver->metastring);
+ row[4] = pserver->players;
+ row[5] = pserver->metastring;
gtk_list_store_append(storemeta, &it);
gtk_list_store_set(storemeta, &it,
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gui_main.c,v
retrieving revision 1.71
diff -u -r1.71 gui_main.c
--- client/gui-gtk-2.0/gui_main.c 15 Apr 2004 19:36:01 -0000 1.71
+++ client/gui-gtk-2.0/gui_main.c 26 Apr 2004 20:14:27 -0000
@@ -33,6 +33,7 @@
#include <gdk/gdkkeysyms.h>
#include "dataio.h"
+#include "fciconv.h"
#include "fcintl.h"
#include "game.h"
#include "government.h"
@@ -170,107 +171,13 @@
static gint timer_callback(gpointer data);
static gboolean show_conn_popup(GtkWidget *view, GdkEventButton *ev,
gpointer data);
-static char *network_charset = NULL;
-
-
-/**************************************************************************
-Network string charset conversion functions.
-**************************************************************************/
-gchar *ntoh_str(const gchar *netstr)
-{
- return g_convert(netstr, -1, "UTF-8", network_charset, NULL, NULL, NULL);
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-static unsigned char *put_conv(const char *src, size_t *length)
-{
- gsize len;
- gchar *out =
- g_convert(src, -1, network_charset, "UTF-8", NULL, &len, NULL);
-
- if (out) {
- unsigned char *dst = fc_malloc(len + 1);
-
- memcpy(dst, out, len);
- g_free(out);
- dst[len] = '\0';
-
- *length = len;
- return dst;
- } else {
- *length = 0;
- return NULL;
- }
-}
-
-/**************************************************************************
- Returns FALSE if the destination isn't large enough or the source was
- bad.
-**************************************************************************/
-static bool get_conv(char *dst, size_t ndst, const unsigned char *src,
- size_t nsrc)
-{
- gsize len; /* length to copy, not including null */
- gchar *out = g_convert(src, nsrc, "UTF-8", network_charset, NULL, &len,
NULL);
- bool ret = TRUE;
-
- if (!out) {
- dst[0] = '\0';
- return FALSE;
- }
-
- if (ndst > 0 && len >= ndst) {
- ret = FALSE;
- len = ndst - 1;
- }
-
- memcpy(dst, out, len);
- dst[len] = '\0';
- g_free(out);
-
- return ret;
-}
-
-/**************************************************************************
-Local log callback functions.
-**************************************************************************/
-static void fprintf_utf8(FILE *stream, const char *format, ...)
-{
- va_list ap;
- const gchar *charset;
- gchar *s;
-
- va_start(ap, format);
- s = g_strdup_vprintf(format, ap);
- va_end(ap);
-
- if (!g_get_charset(&charset)) {
- GError *error = NULL;
- gchar *s2;
-
- s2 = g_convert(s, -1, charset, "UTF-8", NULL, NULL, &error);
-
- if (error) {
- fprintf(stream, "fprintf_utf8: %s\n", error->message);
- g_error_free(error);
- } else {
- g_free(s);
- s = s2;
- }
- }
- fputs(s, stream);
- fflush(stream);
- g_free(s);
-}
/**************************************************************************
...
**************************************************************************/
static void log_callback_utf8(int level, const char *message)
{
- fprintf_utf8(stderr, "%d: %s\n", level, message);
+ fc_fprintf(stderr, "%d: %s\n", level, message);
}
/**************************************************************************
@@ -280,7 +187,7 @@
static void print_usage(const char *argv0)
{
/* add client-specific usage information here */
- fprintf_utf8(stderr, _("Report bugs to <%s>.\n"), BUG_EMAIL_ADDRESS);
+ fc_fprintf(stderr, _("Report bugs to <%s>.\n"), BUG_EMAIL_ADDRESS);
}
/**************************************************************************
@@ -1012,32 +919,10 @@
void ui_init(void)
{
gchar *s;
- char *net_charset;
-#ifdef ENABLE_NLS
- bind_textdomain_codeset(PACKAGE, "UTF-8");
-#endif
+ init_character_encodings("UTF-8", 1);
log_set_callback(log_callback_utf8);
-
- /* set networking string conversion callbacks */
- if ((net_charset = getenv("FREECIV_NETWORK_ENCODING"))) {
- network_charset = mystrdup(net_charset);
- } else {
- const gchar *charset;
-
- g_get_charset(&charset);
-
- if (!strcmp(charset, "ANSI_X3.4-1968")
- || !strcmp(charset, "ASCII")) {
- charset = "ISO-8859-1";
- }
-
- network_charset = mystrdup(charset);
- }
-
- dio_set_put_conv_callback(put_conv);
- dio_set_get_conv_callback(get_conv);
/* convert inputs */
s = g_locale_to_utf8(user_name, -1, NULL, NULL, NULL);
Index: client/gui-xaw/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/gui_main.c,v
retrieving revision 1.91
diff -u -r1.91 gui_main.c
--- client/gui-xaw/gui_main.c 15 Apr 2004 19:36:01 -0000 1.91
+++ client/gui-xaw/gui_main.c 26 Apr 2004 20:14:27 -0000
@@ -37,6 +37,7 @@
#include "canvas.h"
#include "pixcomm.h"
+#include "fciconv.h"
#include "fcintl.h"
#include "game.h"
#include "government.h"
@@ -261,6 +262,7 @@
**************************************************************************/
void ui_init(void)
{
+ init_character_encodings(NULL);
}
/**************************************************************************
Index: common/Makefile.am
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/Makefile.am,v
retrieving revision 1.49
diff -u -r1.49 Makefile.am
--- common/Makefile.am 13 Feb 2004 07:57:58 -0000 1.49
+++ common/Makefile.am 26 Apr 2004 20:14:27 -0000
@@ -28,6 +28,8 @@
effects.c \
effects.h \
events.h \
+ fciconv.c \
+ fciconv.h \
fcintl.c \
fcintl.h \
game.c \
Index: common/dataio.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/dataio.c,v
retrieving revision 1.10
diff -u -r1.10 dataio.c
--- common/dataio.c 14 Feb 2004 02:21:25 -0000 1.10
+++ common/dataio.c 26 Apr 2004 20:14:27 -0000
@@ -317,7 +317,15 @@
/**************************************************************************
...
**************************************************************************/
-void dio_put_string(struct data_out *dout, const char *value)
+void dio_put_ascii_string(struct data_out *dout, const char *value)
+{
+ dio_put_memory(dout, value, strlen(value) + 1);
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+void dio_put_text_string(struct data_out *dout, const char *value)
{
if (put_conv_callback) {
size_t length;
@@ -546,7 +554,53 @@
/**************************************************************************
...
**************************************************************************/
-void dio_get_string(struct data_in *din, char *dest, size_t max_dest_size)
+void dio_get_ascii_string(struct data_in *din,
+ char *dest, size_t max_dest_size)
+{
+ unsigned char *c;
+ size_t ps_len; /* length in packet, not including null */
+ size_t offset, remaining;
+
+ assert(max_dest_size > 0 || dest == NULL);
+
+ if (!enough_data(din, 1)) {
+ dest[0] = '\0';
+ return;
+ }
+
+ remaining = dio_input_remaining(din);
+ c = ADD_TO_POINTER(din->src, din->current);
+
+ /* avoid using strlen (or strcpy) on an (unsigned char*) --dwp */
+ for (offset = 0; c[offset] != '\0' && offset < remaining; offset++) {
+ /* nothing */
+ }
+
+ if (offset >= remaining) {
+ ps_len = remaining;
+ din->too_short = TRUE;
+ din->bad_string = TRUE;
+ } else {
+ ps_len = offset;
+ }
+
+ {
+ size_t copy_len = MIN(ps_len + 1, max_dest_size);
+
+ mystrlcpy(dest, c, copy_len);
+ dest[copy_len - 1] = '\0';
+ }
+
+ if (!din->too_short) {
+ din->current += (ps_len + 1); /* past terminator */
+ }
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+void dio_get_text_string(struct data_in *din,
+ char *dest, size_t max_dest_size)
{
unsigned char *c;
size_t ps_len; /* length in packet, not including null */
Index: common/dataio.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/dataio.h,v
retrieving revision 1.5
diff -u -r1.5 dataio.h
--- common/dataio.h 10 Apr 2004 03:47:49 -0000 1.5
+++ common/dataio.h 26 Apr 2004 20:14:27 -0000
@@ -65,7 +65,10 @@
void dio_get_bool8(struct data_in *din, bool *dest);
void dio_get_bool32(struct data_in *din, bool *dest);
void dio_get_memory(struct data_in *din, void *dest, size_t dest_size);
-void dio_get_string(struct data_in *din, char *dest, size_t max_dest_size);
+void dio_get_ascii_string(struct data_in *din,
+ char *dest, size_t max_dest_size);
+void dio_get_text_string(struct data_in *din,
+ char *dest, size_t max_dest_size);
void dio_get_bit_string(struct data_in *din, char *dest,
size_t max_dest_size);
void dio_get_city_map(struct data_in *din, char *dest, size_t max_dest_size);
@@ -94,7 +97,8 @@
void dio_put_bool32(struct data_out *dout, bool value);
void dio_put_memory(struct data_out *dout, const void *value, size_t size);
-void dio_put_string(struct data_out *dout, const char *value);
+void dio_put_ascii_string(struct data_out *dout, const char *value);
+void dio_put_text_string(struct data_out *dout, const char *value);
void dio_put_bit_string(struct data_out *dout, const char *value);
void dio_put_city_map(struct data_out *dout, const char *value);
void dio_put_tech_list(struct data_out *dout, const int *value);
Index: common/fciconv.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/fciconv.c,v
retrieving revision 1.1
diff -u -r1.1 fciconv.c
--- common/fciconv.c 26 Apr 2004 02:13:30 -0000 1.1
+++ common/fciconv.c 26 Apr 2004 20:14:27 -0000
@@ -0,0 +1,310 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 2003 - The Freeciv Project
+ 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, 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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_ICONV
+#include <iconv.h>
+#endif
+
+#ifdef HAVE_LANGINFO_CODESET
+#include <langinfo.h>
+#endif
+
+#include "fciconv.h"
+#include "fcintl.h"
+#include "mem.h"
+#include "support.h"
+
+#ifdef HAVE_ICONV
+#include "log.h"
+#endif
+
+#define DEFAULT_DATA_ENCODING "ISO-8859-1"
+
+static bool is_init = FALSE;
+static char convert_buffer[4096];
+
+#ifdef HAVE_ICONV
+static char *local_encoding, *data_encoding, *display_encoding;
+static const size_t local_encoding_size = 1, data_encoding_size = 1;
+static size_t display_encoding_size = 1;
+#endif
+
+/***************************************************************************
+ Must be called during the initialization phase of server and client to
+ initialize the character encodings to be used.
+***************************************************************************/
+void init_character_encodings(char *my_display_encoding,
+ size_t encoding_size)
+{
+#ifdef HAVE_ICONV
+ static char local[128];
+
+ /* Set the data encoding - first check $FREECIV_DATA_ENCODING,
+ * then fall back to the default. */
+ data_encoding = getenv("FREECIV_DATA_ENCODING");
+ if (!data_encoding) {
+ /* Currently the rulesets are in latin1 (ISO-8859-1). */
+ data_encoding = DEFAULT_DATA_ENCODING;
+ }
+
+ /* Set the local encoding - first check $FREECIV_LOCAL_ENCODING,
+ * then ask the system. */
+ local_encoding = getenv("FREECIV_LOCAL_ENCODING");
+ if (!local_encoding) {
+#ifdef HAVE_LIBCHARSET
+ local_encoding = locale_charset();
+#else
+#ifdef HAVE_LANGINFO_CODESET
+ local_encoding = nl_langinfo(CODESET);
+#else
+ local_encoding = "";
+#endif
+#endif
+ if (strcasecmp(local_encoding, "ANSI_X3.4-1968") == 0
+ || strcasecmp(local_encoding, "ASCII") == 0) {
+ /* HACK: use latin1 instead of ascii in typical cases when the
+ * encoding is unconfigured. */
+ local_encoding = "ISO-8859-1";
+ }
+
+
+ my_snprintf(local, sizeof(local), "%s//TRANSLIT", local_encoding);
+ local_encoding = local;
+ }
+
+ /* Set the display encoding - first check $FREECIV_DISPLAY_ENCODING,
+ * then check the passed-in default value, then fall back to the local
+ * encoding. */
+ display_encoding = getenv("FREECIV_DISPLAY_ENCODING");
+ if (!display_encoding) {
+ display_encoding = my_display_encoding;
+
+ if (!display_encoding) {
+ display_encoding = local_encoding;
+ }
+ }
+ display_encoding_size = encoding_size;
+
+ fprintf(stderr, "Data=%s, Local=%s, Display=%s\n",
+ data_encoding, local_encoding, display_encoding);
+#else
+ /* freelog may not work at this point. */
+ fprintf(stderr,
+ _("You are running Freeciv without using iconv. Unless\n"
+ "you are using the latin1 character set, some characters\n"
+ "may not be displayed properly. You can download iconv\n"
+ "at http://gnu.org/.\n"));
+ assert(encoding_size == 1);
+#endif
+
+ is_init = TRUE;
+}
+
+const char *get_data_encoding(void)
+{
+ return data_encoding;
+}
+
+const char *get_local_encoding(void)
+{
+ return local_encoding;
+}
+
+const char *get_display_encoding(void)
+{
+ return display_encoding;
+}
+
+#ifdef HAVE_ICONV
+/***************************************************************************
+ Return the number of characters in the string. from_sz is the character
+ encoding size (currently 1 or 2).
+***************************************************************************/
+static size_t char_strlen(const char *text, size_t from_sz)
+{
+ size_t length = 0;
+
+ do {
+ size_t i;
+
+ for (i = 0; i < from_sz; i++) {
+ if (text[length * from_sz + i] != 0) {
+ break;
+ }
+ }
+
+ if (i == from_sz) {
+ return length;
+ }
+
+ length++;
+ } while (TRUE);
+}
+
+/***************************************************************************
+ Convert the text. This assumes 'from' is an 8-bit charset. The result
+ will be put into the buf buffer unless it is NULL, in which case it
+ will be allocated on demand.
+***************************************************************************/
+static char *convert_string(const char *text,
+ const char *from, size_t from_sz,
+ const char *to,
+ char *buf, size_t bufsz)
+{
+ iconv_t cd = iconv_open(to, from);
+ size_t from_len = char_strlen(text, from_sz) + from_sz, to_len;
+ bool alloc = (buf == NULL);
+
+ assert(is_init && from != NULL && to != NULL);
+ assert(text != NULL);
+
+ if (cd == (iconv_t) (-1)) {
+ freelog(LOG_ERROR,
+ _("Could not convert text from %s to %s: %s"),
+ from, to, strerror(errno));
+ /* The best we can do? */
+ if (alloc) {
+ return mystrdup(text);
+ } else {
+ my_snprintf(buf, bufsz, "%s", text);
+ return buf;
+ }
+ }
+
+ if (alloc) {
+ to_len = from_len;
+ } else {
+ to_len = bufsz;
+ }
+
+ do {
+ size_t flen = from_len, tlen = to_len, res;
+ const char *mytext = text;
+ char *myresult;
+
+ if (alloc) {
+ buf = fc_malloc(to_len);
+ }
+
+ myresult = buf;
+
+ /* Since we may do multiple translations, we may need to reset iconv
+ * in between. */
+ iconv(cd, NULL, NULL, NULL, NULL);
+
+ res = iconv(cd, (char**)&mytext, &flen, &myresult, &tlen);
+ if (res == (size_t) (-1)) {
+ if (errno != E2BIG) {
+ /* Invalid input. */
+ freelog(LOG_ERROR, "Invalid string conversion from %s to %s.",
+ from, to);
+ iconv_close(cd);
+ if (alloc) {
+ free(buf);
+ return mystrdup(text); /* The best we can do? */
+ } else {
+ my_snprintf(buf, bufsz, "%s", text);
+ return buf;
+ }
+ }
+ } else {
+ /* Success. */
+ iconv_close(cd);
+
+ /* There may be wasted space here, but there's nothing we can do
+ * about it. */
+ return buf;
+ }
+
+ if (alloc) {
+ /* Not enough space; try again. */
+ buf[to_len - 1] = 0;
+ freelog(LOG_VERBOSE, " Result was '%s'.", buf);
+
+ free(buf);
+ to_len *= 2;
+ }
+ } while (alloc);
+
+ return buf;
+}
+
+#endif
+
+#ifdef HAVE_ICONV
+
+#define CONV_FUNC_MALLOC(src, dst) \
+char *src ## _to_ ## dst ## _string_malloc(const char *text) \
+{ \
+ return convert_string(text, (src ## _encoding), (src ## _encoding_size), \
+ (dst ## _encoding), NULL, 0); \
+}
+
+#define CONV_FUNC_BUFFER(src, dst) \
+char *src ## _to_ ## dst ## _string_buffer(const char *text, \
+ char *buf, size_t bufsz) \
+{ \
+ return convert_string(text, (src ## _encoding), (src ## _encoding_size), \
+ (dst ## _encoding), buf, bufsz); \
+}
+
+#else /* HAVE_ICONV */
+
+#define CONV_FUNC_MALLOC(src, dst) \
+char *src ## _to_ ## dst ## _string_malloc(const char *text) \
+{ \
+ return mystrdup(text); \
+}
+
+#define CONV_FUNC_BUFFER(src, dst) \
+char *src ## _to_ ## dst ## _string_buffer(const char *text, \
+ char *buf, size_t bufsz) \
+{ \
+ my_snprintf(buf, bufsz, "%s", text); \
+ return buf; \
+}
+
+#endif /* HAVE_ICONV */
+
+#define CONV_FUNC_STATIC(src, dst) \
+char *src ## _to_ ## dst ## _string_static(const char *text) \
+{ \
+ (src ## _to_ ## dst ## _string_buffer)(text, \
+ convert_buffer, \
+ sizeof(convert_buffer)); \
+ return convert_buffer; \
+}
+
+CONV_FUNC_MALLOC(data, display)
+CONV_FUNC_MALLOC(display, data)
+
+CONV_FUNC_STATIC(data, display)
+CONV_FUNC_STATIC(display, data)
+
+CONV_FUNC_BUFFER(data, display)
+CONV_FUNC_BUFFER(display, data)
+
+static CONV_FUNC_BUFFER(display, local)
+CONV_FUNC_STATIC(display, local)
+
+static CONV_FUNC_BUFFER(data, local)
+CONV_FUNC_STATIC(data, local)
Index: common/fciconv.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/fciconv.h,v
retrieving revision 1.1
diff -u -r1.1 fciconv.h
--- common/fciconv.h 26 Apr 2004 02:13:30 -0000 1.1
+++ common/fciconv.h 26 Apr 2004 20:14:27 -0000
@@ -0,0 +1,36 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 2003 - The Freeciv Project
+ 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, 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.
+***********************************************************************/
+#ifndef FC__FCICONV_H
+#define FC__FCICONV_H
+
+void init_character_encodings(char *my_display_encoding,
+ size_t encoding_size);
+
+const char *get_data_encoding(void);
+const char *get_local_encoding(void);
+const char *get_display_encoding(void);
+
+char *data_to_display_string_malloc(const char *text);
+char *data_to_display_string_static(const char *text);
+char *data_to_display_string_buffer(const char *text,
+ char *buf, size_t bufsz);
+
+char *display_to_data_string_malloc(const char *text);
+char *display_to_data_string_static(const char *text);
+char *display_to_data_string_buffer(const char *text,
+ char *buf, size_t bufsz);
+
+char *display_to_local_string_static(const char *text);
+char *data_to_local_string_static(const char *text);
+
+#endif /* FC__FCICONV_H */
Index: common/generate_packets.py
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/generate_packets.py,v
retrieving revision 1.10
diff -u -r1.10 generate_packets.py
--- common/generate_packets.py 7 Apr 2004 21:12:43 -0000 1.10
+++ common/generate_packets.py 26 Apr 2004 20:14:28 -0000
@@ -218,7 +218,7 @@
return result
def get_handle_type(self,const=0):
- if self.dataio_type=="string":
+ if self.dataio_type in ["ascii_string","text_string"]:
if const: return "const char *"
else: return "char *"
@@ -245,7 +245,7 @@
return " copy_worklist(&real_packet->%(name)s,
%(name)s);"%self.__dict__
if self.is_array==0:
return " real_packet->%(name)s = %(name)s;"%self.__dict__
- if self.dataio_type=="string":
+ if self.dataio_type in ["ascii_string", "text_string"]:
return " sz_strlcpy(real_packet->%(name)s,
%(name)s);"%self.__dict__
if self.is_array==1:
tmp="real_packet->%(name)s[i] = %(name)s[i]"%self.__dict__
@@ -266,14 +266,14 @@
return " differ = (memcmp(old->%(name)s, real_packet->%(name)s,
%(array_size_d)s) != 0);"%self.__dict__
if self.dataio_type=="bitvector":
return " differ = !BV_ARE_EQUAL(old->%(name)s,
real_packet->%(name)s);"%self.__dict__
- if self.dataio_type in ["string","bit_string"] and self.is_array==1:
+ if self.dataio_type in ["ascii_string","text_string","bit_string"] and
self.is_array==1:
return " differ = (strcmp(old->%(name)s, real_packet->%(name)s)
!= 0);"%self.__dict__
if self.is_struct and self.is_array==0:
return " differ = !are_%(dataio_type)ss_equal(&old->%(name)s,
&real_packet->%(name)s);"%self.__dict__
if not self.is_array:
return " differ = (old->%(name)s !=
real_packet->%(name)s);"%self.__dict__
- if self.dataio_type=="string":
+ if self.dataio_type in ["ascii_string","text_string"]:
c="strcmp(old->%(name)s[i], real_packet->%(name)s[i]) !=
0"%self.__dict__
array_size_u=self.array_size1_u
array_size_o=self.array_size1_o
@@ -349,13 +349,13 @@
if self.dataio_type in ["memory"]:
return " dio_put_%(dataio_type)s(&dout, &real_packet->%(name)s,
%(array_size_u)s);"%self.__dict__
- arr_types=["string","bit_string","city_map","tech_list"]
+
arr_types=["ascii_string","text_string","bit_string","city_map","tech_list"]
if (self.dataio_type in arr_types and self.is_array==1) or \
(self.dataio_type not in arr_types and self.is_array==0):
return " dio_put_%(dataio_type)s(&dout,
real_packet->%(name)s);"%self.__dict__
if self.is_struct:
c="dio_put_%(dataio_type)s(&dout,
&real_packet->%(name)s[i]);"%self.__dict__
- elif self.dataio_type=="string":
+ elif self.dataio_type in ["ascii_string","text_string"]:
c="dio_put_%(dataio_type)s(&dout,
real_packet->%(name)s[i]);"%self.__dict__
array_size_u=self.array_size1_u
@@ -422,7 +422,7 @@
if self.dataio_type=="memory":
return "dio_get_%(dataio_type)s(&din, real_packet->%(name)s,
%(array_size_u)s);"%self.__dict__
- if self.dataio_type in ["string","bit_string","city_map","memory"] and
\
+ if self.dataio_type in
["ascii_string","text_string","bit_string","city_map","memory"] and \
self.is_array!=2:
return "dio_get_%(dataio_type)s(&din, real_packet->%(name)s,
sizeof(real_packet->%(name)s));"%self.__dict__
if self.is_struct and self.is_array==0:
@@ -436,7 +436,7 @@
if self.is_struct:
c="dio_get_%(dataio_type)s(&din,
&real_packet->%(name)s[i]);"%self.__dict__
- elif self.dataio_type=="string":
+ elif self.dataio_type in ["ascii_string","text_string"]:
c="dio_get_%(dataio_type)s(&din, real_packet->%(name)s[i],
sizeof(real_packet->%(name)s[i]));"%self.__dict__
elif self.struct_type=="float":
c='''int tmp;
Index: common/log.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/log.c,v
retrieving revision 1.45
diff -u -r1.45 log.c
--- common/log.c 10 Apr 2004 03:47:49 -0000 1.45
+++ common/log.c 26 Apr 2004 20:14:28 -0000
@@ -80,16 +80,16 @@
}
if (n == 0) {
if (sscanf(level_str, "%d", &level) != 1) {
- fprintf(stderr, _("Bad log level \"%s\".\n"), level_str);
+ fc_fprintf(stderr, _("Bad log level \"%s\".\n"), level_str);
return -1;
}
if (level >= LOG_FATAL && level <= max_level) {
return level;
} else {
- fprintf(stderr, _("Bad log level %d in \"%s\".\n"), level, level_str);
+ fc_fprintf(stderr, _("Bad log level %d in \"%s\".\n"), level, level_str);
if (level == LOG_DEBUG && max_level < LOG_DEBUG) {
- fprintf(stderr, _("Freeciv must be compiled with the DEBUG flag"
- " to use debug level %d.\n"), LOG_DEBUG);
+ fc_fprintf(stderr, _("Freeciv must be compiled with the DEBUG flag"
+ " to use debug level %d.\n"), LOG_DEBUG);
}
return -1;
}
@@ -99,12 +99,13 @@
if (c[0] == ('0' + LOG_DEBUG) && c[1] == ':') {
level = LOG_DEBUG;
if (max_level < LOG_DEBUG) {
- fprintf(stderr, _("Freeciv must be compiled with the DEBUG flag"
- " to use debug level %d.\n"), LOG_DEBUG);
+ fc_fprintf(stderr, _("Freeciv must be compiled with the DEBUG flag"
+ " to use debug level %d.\n"), LOG_DEBUG);
return -1;
}
} else {
- fprintf(stderr, _("Badly formed log level argument \"%s\".\n"), level_str);
+ fc_fprintf(stderr, _("Badly formed log level argument \"%s\".\n"),
+ level_str);
return -1;
}
logd_num_files = n;
@@ -115,7 +116,8 @@
tok = strtok(dup, ":");
if (!tok) {
- fprintf(stderr, _("Badly formed log level argument \"%s\".\n"), level_str);
+ fc_fprintf(stderr, _("Badly formed log level argument \"%s\".\n"),
+ level_str);
level = -1;
goto out;
}
@@ -132,20 +134,20 @@
if (d && *pc != '\0' && d[1] != '\0') {
d[0] = '\0';
if (sscanf(pc, "%d", &logd_files[i].min) != 1) {
- fprintf(stderr, _("Not an integer: '%s'\n"), pc);
+ fc_fprintf(stderr, _("Not an integer: '%s'\n"), pc);
level = -1;
goto out;
}
if (sscanf(d + 1, "%d", &logd_files[i].max) != 1) {
- fprintf(stderr, _("Not an integer: '%s'\n"), d + 1);
+ fc_fprintf(stderr, _("Not an integer: '%s'\n"), d + 1);
level = -1;
goto out;
}
}
}
if(strlen(tok)==0) {
- fprintf(stderr, _("Empty filename in log level argument \"%s\".\n"),
- level_str);
+ fc_fprintf(stderr, _("Empty filename in log level argument \"%s\".\n"),
+ level_str);
level = -1;
goto out;
}
@@ -155,7 +157,8 @@
} while(tok);
if (i!=logd_num_files) {
- fprintf(stderr, _("Badly formed log level argument \"%s\".\n"), level_str);
+ fc_fprintf(stderr, _("Badly formed log level argument \"%s\".\n"),
+ level_str);
level = -1;
goto out;
}
@@ -236,7 +239,7 @@
log_callback(level, message);
}
if (log_filename || (!log_callback)) {
- fprintf(fs, "%d: %s\n", level, message);
+ fc_fprintf(fs, "%d: %s\n", level, message);
fflush(fs);
}
}
@@ -264,7 +267,7 @@
if (log_filename) {
if(!(fs=fopen(log_filename, "a"))) {
- fprintf(stderr, _("Couldn't open logfile: %s for appending.\n"),
+ fc_fprintf(stderr, _("Couldn't open logfile: %s for appending.\n"),
log_filename);
exit(EXIT_FAILURE);
}
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.21
diff -u -r1.21 packets.def
--- common/packets.def 24 Apr 2004 17:32:47 -0000 1.21
+++ common/packets.def 26 Apr 2004 20:14:28 -0000
@@ -149,7 +149,8 @@
# typedefs for arrays/structs
type MEMORY = memory(unsigned char)
-type STRING = string(char)
+type ASCII = ascii_string(char)
+type TEXT = text_string(char)
type BIT_STRING = bit_string(char)
type CITY_MAP = city_map(char)
type WORKLIST = worklist(struct worklist)
@@ -235,29 +236,29 @@
# This packet is the first real (freeciv specific) packet send by the
# client. The player hasn't been accepted yet.
PACKET_SERVER_JOIN_REQ=4; cs, dsend,no-delta,no-handle
- STRING username[MAX_LEN_NAME];
- STRING capability[MAX_LEN_CAPSTR];
- STRING version_label[MAX_LEN_NAME];
+ TEXT username[MAX_LEN_NAME];
+ ASCII capability[MAX_LEN_CAPSTR];
+ ASCII version_label[MAX_LEN_NAME];
UINT32 major_version, minor_version, patch_version;
end
# ... and the server replies.
PACKET_SERVER_JOIN_REPLY=5; sc,no-delta
BOOL you_can_join;
- STRING message[MAX_LEN_MSG];
- STRING capability[MAX_LEN_CAPSTR];
- STRING challenge_file[MAX_LEN_PATH];
+ TEXT message[MAX_LEN_MSG];
+ ASCII capability[MAX_LEN_CAPSTR];
+ ASCII challenge_file[MAX_LEN_PATH];
# clients conn id as known in server
CONNECTION conn_id;
end
PACKET_AUTHENTICATION_REQ=6;sc,handle-per-conn,dsend
AUTH_TYPE type;
- STRING message[MAX_LEN_MSG]; /* explain to the client if there's a problem */
+ TEXT message[MAX_LEN_MSG]; /* explain to the client if there's a problem */
end
PACKET_AUTHENTICATION_REPLY=7;cs,no-handle
- STRING password[MAX_LEN_NAME];
+ TEXT password[MAX_LEN_NAME];
end
@@ -272,7 +273,7 @@
PACKET_NATION_SELECT_REQ=10;cs,dsend
NATION nation_no;
BOOL is_male;
- STRING name[MAX_LEN_NAME];
+ TEXT name[MAX_LEN_NAME];
UINT8 city_style;
end
@@ -311,7 +312,7 @@
SPECIAL special;
PLAYER owner;
CONTINENT continent;
- STRING spec_sprite[MAX_LEN_NAME];
+ ASCII spec_sprite[MAX_LEN_NAME];
end
PACKET_GAME_INFO=15; is-info,sc
@@ -357,13 +358,13 @@
/************** Chat/event packets **********************/
PACKET_CHAT_MSG=18;sc, pre-send, post-recv,lsend
- STRING message[MAX_LEN_MSG];
+ TEXT message[MAX_LEN_MSG];
COORD x, y;
EVENT event;
end
PACKET_CHAT_MSG_REQ=19;cs,handle-per-conn,dsend
- STRING message[MAX_LEN_MSG];
+ TEXT message[MAX_LEN_MSG];
end
/************** City packets **********************/
@@ -376,7 +377,7 @@
CITY id; key
PLAYER owner;
COORD x,y;
- STRING name[MAX_LEN_NAME];
+ TEXT name[MAX_LEN_NAME];
UINT8 size;
UINT8 ppl_happy[5], ppl_content[5], ppl_unhappy[5], ppl_angry[5];
@@ -421,7 +422,7 @@
PLAYER owner;
COORD x;
COORD y;
- STRING name[MAX_LEN_NAME];
+ TEXT name[MAX_LEN_NAME];
UINT8 size;
BOOL happy;
BOOL unhappy;
@@ -468,7 +469,7 @@
PACKET_CITY_RENAME=30;cs,dsend
CITY city_id;
- STRING name[MAX_LEN_NAME];
+ TEXT name[MAX_LEN_NAME];
end
PACKET_CITY_OPTIONS_REQ=31;cs,dsend
@@ -501,7 +502,7 @@
PACKET_CITY_NAME_SUGGESTION_INFO=36;sc,dsend,lsend
UNIT unit_id;
- STRING name[MAX_LEN_NAME];
+ TEXT name[MAX_LEN_NAME];
end
PACKET_CITY_SABOTAGE_LIST=37;sc,lsend
@@ -518,7 +519,7 @@
PACKET_PLAYER_INFO=39; is-info,sc
PLAYER playerno; key
- STRING name[MAX_LEN_NAME];
+ TEXT name[MAX_LEN_NAME];
BOOL is_male;
GOVERNMENT government;
UINT32 embassy;
@@ -648,7 +649,7 @@
PACKET_UNIT_BUILD_CITY=53;cs,dsend
UNIT unit_id;
- STRING name[MAX_LEN_NAME];
+ TEXT name[MAX_LEN_NAME];
end
PACKET_UNIT_DISBAND=54;cs,dsend
@@ -813,7 +814,7 @@
/************** Report packets **********************/
PACKET_PAGE_MSG=84;sc,lsend
- STRING message[MAX_LEN_MSG];
+ TEXT message[MAX_LEN_MSG];
EVENT event;
end
@@ -836,9 +837,9 @@
BOOL observer;
PLAYER player_num;
CMDLEVEL access_level;
- STRING username[MAX_LEN_NAME];
- STRING addr[MAX_LEN_ADDR];
- STRING capability[MAX_LEN_CAPSTR];
+ TEXT username[MAX_LEN_NAME];
+ ASCII addr[MAX_LEN_ADDR];
+ ASCII capability[MAX_LEN_CAPSTR];
end
# Information about the ping times of the connections.
@@ -912,13 +913,13 @@
PACKET_RULESET_UNIT=96;sc,lsend
UNIT_TYPE id;
- STRING name[MAX_LEN_NAME];
- STRING graphic_str[MAX_LEN_NAME];
- STRING graphic_alt[MAX_LEN_NAME];
- STRING sound_move[MAX_LEN_NAME];
- STRING sound_move_alt[MAX_LEN_NAME];
- STRING sound_fight[MAX_LEN_NAME];
- STRING sound_fight_alt[MAX_LEN_NAME];
+ ASCII name[MAX_LEN_NAME];
+ ASCII graphic_str[MAX_LEN_NAME];
+ ASCII graphic_alt[MAX_LEN_NAME];
+ ASCII sound_move[MAX_LEN_NAME];
+ ASCII sound_move_alt[MAX_LEN_NAME];
+ ASCII sound_fight[MAX_LEN_NAME];
+ ASCII sound_fight_alt[MAX_LEN_NAME];
UINT8 move_type;
UINT16 build_cost;
UINT8 pop_cost;
@@ -943,13 +944,13 @@
UINT8 paratroopers_mr_req;
UINT8 paratroopers_mr_sub;
- STRING veteran_name[MAX_VET_LEVELS][MAX_LEN_NAME]; add-cap(veteran)
+ ASCII veteran_name[MAX_VET_LEVELS][MAX_LEN_NAME]; add-cap(veteran)
FLOAT power_fact[MAX_VET_LEVELS]; add-cap(veteran)
UINT8 move_bonus[MAX_VET_LEVELS]; add-cap(veteran)
UINT8 bombard_rate; add-cap(bombard)
- STRING helptext[MAX_LEN_PACKET];
+ ASCII helptext[MAX_LEN_PACKET];
bitvector(bv_flags) flags;
bitvector(bv_roles) roles;
@@ -982,8 +983,8 @@
GOVERNMENT gov;
UINT8 id;
NATION nation;
- STRING male_title[MAX_LEN_NAME];
- STRING female_title[MAX_LEN_NAME];
+ ASCII male_title[MAX_LEN_NAME];
+ ASCII female_title[MAX_LEN_NAME];
end
PACKET_RULESET_TECH=99;sc,lsend
@@ -991,10 +992,10 @@
TECH req[2];
TECH root_req;
UINT32 flags, preset_cost, num_reqs;
- STRING name[MAX_LEN_NAME];
- STRING helptext[MAX_LEN_PACKET];
- STRING graphic_str[MAX_LEN_NAME];
- STRING graphic_alt[MAX_LEN_NAME];
+ ASCII name[MAX_LEN_NAME];
+ ASCII helptext[MAX_LEN_PACKET];
+ ASCII graphic_str[MAX_LEN_NAME];
+ ASCII graphic_alt[MAX_LEN_NAME];
end
PACKET_RULESET_GOVERNMENT=100;sc,lsend
@@ -1054,10 +1055,10 @@
UINT8 num_ruler_titles;
- STRING name[MAX_LEN_NAME];
- STRING graphic_str[MAX_LEN_NAME];
- STRING graphic_alt[MAX_LEN_NAME];
- STRING helptext[MAX_LEN_PACKET];
+ ASCII name[MAX_LEN_NAME];
+ ASCII graphic_str[MAX_LEN_NAME];
+ ASCII graphic_alt[MAX_LEN_NAME];
+ ASCII helptext[MAX_LEN_PACKET];
end
PACKET_RULESET_TERRAIN_CONTROL=101;sc,lsend
@@ -1073,7 +1074,7 @@
UINT16 river_defense_bonus; /* % added to defense if Civ2 river */
UINT16 river_trade_incr; /* added to trade if Civ2 river */
- STRING river_help_text[MAX_LEN_PACKET]; # help for Civ2-style rivers
+ ASCII river_help_text[MAX_LEN_PACKET]; # help for Civ2-style rivers
UINT16 fortress_defense_bonus; /* % added to defense if fortress */
UINT16 road_superhighway_trade_bonus; # % added to trade if road/s-highway
@@ -1092,37 +1093,37 @@
PACKET_RULESET_NATION=102;sc,lsend
NATION id;
- STRING name[MAX_LEN_NAME];
- STRING name_plural[MAX_LEN_NAME];
- STRING graphic_str[MAX_LEN_NAME];
- STRING graphic_alt[MAX_LEN_NAME];
- STRING class[MAX_LEN_NAME];
- STRING legend[MAX_LEN_MSG];
+ TEXT name[MAX_LEN_NAME];
+ TEXT name_plural[MAX_LEN_NAME];
+ ASCII graphic_str[MAX_LEN_NAME];
+ ASCII graphic_alt[MAX_LEN_NAME];
+ ASCII class[MAX_LEN_NAME];
+ ASCII legend[MAX_LEN_MSG];
UINT8 city_style;
TECH_LIST init_techs[MAX_NUM_TECH_LIST];
UINT8 leader_count;
- STRING leader_name[MAX_NUM_LEADERS:leader_count][MAX_LEN_NAME];
+ TEXT leader_name[MAX_NUM_LEADERS:leader_count][MAX_LEN_NAME];
BOOL leader_sex[MAX_NUM_LEADERS:leader_count];
end
PACKET_RULESET_CITY=103;sc,lsend
UINT8 style_id;
UINT8 techreq;
- STRING name[MAX_LEN_NAME];
- STRING citizens_graphic[MAX_LEN_NAME];
- STRING citizens_graphic_alt[MAX_LEN_NAME];
- STRING graphic[MAX_LEN_NAME];
- STRING graphic_alt[MAX_LEN_NAME];
+ ASCII name[MAX_LEN_NAME];
+ ASCII citizens_graphic[MAX_LEN_NAME];
+ ASCII citizens_graphic_alt[MAX_LEN_NAME];
+ ASCII graphic[MAX_LEN_NAME];
+ ASCII graphic_alt[MAX_LEN_NAME];
SINT8 replaced_by;
end
PACKET_RULESET_BUILDING=104;sc,lsend
IMPROVEMENT id;
- STRING name[MAX_LEN_NAME];
- STRING graphic_str[MAX_LEN_NAME];
- STRING graphic_alt[MAX_LEN_NAME];
+ ASCII name[MAX_LEN_NAME];
+ ASCII graphic_str[MAX_LEN_NAME];
+ ASCII graphic_alt[MAX_LEN_NAME];
TECH tech_req, obsolete_by;
IMPROVEMENT bldg_req;
BOOL is_wonder;
@@ -1130,9 +1131,9 @@
UINT16 build_cost;
UINT8 upkeep, sabotage;
UINT8 variant; /* FIXME: remove when gen-impr obsoletes */
- STRING soundtag[MAX_LEN_NAME];
- STRING soundtag_alt[MAX_LEN_NAME];
- STRING helptext[MAX_LEN_PACKET];
+ ASCII soundtag[MAX_LEN_NAME];
+ ASCII soundtag_alt[MAX_LEN_NAME];
+ ASCII helptext[MAX_LEN_PACKET];
UINT8 terr_gate_count;
TERRAIN terr_gate[255:terr_gate_count];
UINT8 spec_gate_count;
@@ -1150,9 +1151,9 @@
bitvector(bv_terrain_flags) flags;
- STRING terrain_name[MAX_LEN_NAME];
- STRING graphic_str[MAX_LEN_NAME];
- STRING graphic_alt[MAX_LEN_NAME];
+ ASCII terrain_name[MAX_LEN_NAME];
+ ASCII graphic_str[MAX_LEN_NAME];
+ ASCII graphic_alt[MAX_LEN_NAME];
UINT8 movement_cost;
UINT8 defense_bonus;
@@ -1161,19 +1162,19 @@
UINT8 shield;
UINT8 trade;
- STRING special_1_name[MAX_LEN_NAME];
+ ASCII special_1_name[MAX_LEN_NAME];
UINT8 food_special_1;
UINT8 shield_special_1;
UINT8 trade_special_1;
- STRING graphic_str_special_1[MAX_LEN_NAME];
- STRING graphic_alt_special_1[MAX_LEN_NAME];
+ ASCII graphic_str_special_1[MAX_LEN_NAME];
+ ASCII graphic_alt_special_1[MAX_LEN_NAME];
- STRING special_2_name[MAX_LEN_NAME];
+ ASCII special_2_name[MAX_LEN_NAME];
UINT8 food_special_2;
UINT8 shield_special_2;
UINT8 trade_special_2;
- STRING graphic_str_special_2[MAX_LEN_NAME];
- STRING graphic_alt_special_2[MAX_LEN_NAME];
+ ASCII graphic_str_special_2[MAX_LEN_NAME];
+ ASCII graphic_alt_special_2[MAX_LEN_NAME];
UINT8 road_trade_incr;
UINT8 road_time;
@@ -1189,7 +1190,7 @@
TERRAIN transform_result;
UINT8 transform_time;
- STRING helptext[MAX_LEN_PACKET];
+ ASCII helptext[MAX_LEN_PACKET];
end
/*********************************************************
@@ -1222,7 +1223,7 @@
UINT8 borders;
BOOL slow_invasions; add-cap(slow_invasions)
- STRING team_name[MAX_NUM_TEAMS][MAX_LEN_NAME];
+ TEXT team_name[MAX_NUM_TEAMS][MAX_LEN_NAME];
end
@@ -1242,11 +1243,11 @@
PACKET_SINGLE_PLAYERLIST_REPLY=111;sc
UINT8 nplayers;
- STRING load_filename[MAX_LEN_PACKET];
- STRING name[MAX_NUM_PLAYERS:nplayers][MAX_LEN_NAME];
- STRING username[MAX_NUM_PLAYERS:nplayers][MAX_LEN_NAME];
- STRING nation_name[MAX_NUM_PLAYERS:nplayers][MAX_LEN_NAME];
- STRING nation_flag[MAX_NUM_PLAYERS:nplayers][MAX_LEN_NAME];
+ ASCII load_filename[MAX_LEN_PACKET];
+ TEXT name[MAX_NUM_PLAYERS:nplayers][MAX_LEN_NAME];
+ TEXT username[MAX_NUM_PLAYERS:nplayers][MAX_LEN_NAME];
+ TEXT nation_name[MAX_NUM_PLAYERS:nplayers][MAX_LEN_NAME];
+ ASCII nation_flag[MAX_NUM_PLAYERS:nplayers][MAX_LEN_NAME];
BOOL is_alive[MAX_NUM_PLAYERS:nplayers];
BOOL is_ai[MAX_NUM_PLAYERS:nplayers];
end
@@ -1254,14 +1255,14 @@
PACKET_OPTIONS_SETTABLE_CONTROL=112;sc,handle-via-packet
UINT16 nids;
UINT8 ncategories;
- STRING category_names[256:ncategories][MAX_LEN_NAME];
+ ASCII category_names[256:ncategories][MAX_LEN_NAME];
end
PACKET_OPTIONS_SETTABLE=113;sc
UINT16 id;
- STRING name[MAX_LEN_NAME];
- STRING short_help[MAX_LEN_PACKET];
- STRING extra_help[MAX_LEN_PACKET];
+ ASCII name[MAX_LEN_NAME];
+ ASCII short_help[MAX_LEN_PACKET];
+ ASCII extra_help[MAX_LEN_PACKET];
SSET_TYPE type;
SINT32 val; /* value for bool or int */
@@ -1269,8 +1270,8 @@
SINT32 min; /* min value for int */
SINT32 max; /* max value for int */
- STRING strval[MAX_LEN_PACKET]; /* space for string */
- STRING default_strval[MAX_LEN_PACKET]; /* space for string */
+ ASCII strval[MAX_LEN_PACKET]; /* space for string */
+ ASCII default_strval[MAX_LEN_PACKET]; /* space for string */
UINT8 category; /* which category this is in */
end
Index: common/shared.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/shared.c,v
retrieving revision 1.109
diff -u -r1.109 shared.c
--- common/shared.c 10 Apr 2004 01:40:17 -0000 1.109
+++ common/shared.c 26 Apr 2004 20:14:28 -0000
@@ -43,7 +43,9 @@
#endif
#include "astring.h"
+#include "fciconv.h"
#include "fcintl.h"
+#include "game.h"
#include "log.h"
#include "mem.h"
#include "support.h"
@@ -668,6 +670,29 @@
assert(FALSE);
exit(EXIT_FAILURE);
+}
+
+/***************************************************************************
+ Do a printf in the currently bound codeset.
+***************************************************************************/
+void fc_fprintf(FILE *stream, const char *format, ...)
+{
+ va_list ap;
+ char string[4096];
+ const char *output;
+
+ va_start(ap, format);
+ my_vsnprintf(string, sizeof(string), format, ap);
+ va_end(ap);
+
+ if (is_server) {
+ output = data_to_display_string_static(string);
+ } else {
+ output = display_to_local_string_static(string);
+ }
+
+ fputs(output, stream);
+ fflush(stream);
}
/***************************************************************************
Index: common/shared.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/shared.h,v
retrieving revision 1.124
diff -u -r1.124 shared.h
--- common/shared.h 10 Apr 2004 03:47:49 -0000 1.124
+++ common/shared.h 26 Apr 2004 20:14:28 -0000
@@ -13,6 +13,7 @@
#ifndef FC__SHARED_H
#define FC__SHARED_H
+#include <stdio.h>
#include <stdlib.h> /* size_t */
#include <string.h> /* memset */
@@ -196,6 +197,9 @@
#define die(...) real_die(__FILE__, __LINE__, __VA_ARGS__)
void real_die(const char *file, int line, const char *format, ...)
fc__attribute((format (printf, 3, 4)));
+
+void fc_fprintf(FILE *stream, const char *format, ...)
+ fc__attribute((format (printf, 2, 3)));
char *user_home_dir(void);
const char *user_username(void);
Index: server/meta.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/meta.c,v
retrieving revision 1.59
diff -u -r1.59 meta.c
--- server/meta.c 25 Jan 2004 13:55:14 -0000 1.59
+++ server/meta.c 26 Apr 2004 20:14:29 -0000
@@ -140,8 +140,8 @@
dio_put_uint16(&dout, 0);
dio_put_uint8(&dout, PACKET_UDP_PCKT);
- dio_put_string(&dout, desc);
- dio_put_string(&dout, info);
+ dio_put_ascii_string(&dout, desc);
+ dio_put_ascii_string(&dout, info);
size = dio_output_used(&dout);
Index: server/sernet.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sernet.c,v
retrieving revision 1.116
diff -u -r1.116 sernet.c
--- server/sernet.c 17 Mar 2004 00:22:44 -0000 1.116
+++ server/sernet.c 26 Apr 2004 20:14:29 -0000
@@ -1076,12 +1076,12 @@
dio_output_init(&dout, buffer, sizeof(buffer));
dio_put_uint8(&dout, SERVER_LAN_VERSION);
- dio_put_string(&dout, hostname);
- dio_put_string(&dout, port);
- dio_put_string(&dout, version);
- dio_put_string(&dout, status);
- dio_put_string(&dout, players);
- dio_put_string(&dout, srvarg.metaserver_info_line);
+ dio_put_ascii_string(&dout, hostname);
+ dio_put_ascii_string(&dout, port);
+ dio_put_ascii_string(&dout, version);
+ dio_put_ascii_string(&dout, status);
+ dio_put_ascii_string(&dout, players);
+ dio_put_ascii_string(&dout, srvarg.metaserver_info_line);
size = dio_output_used(&dout);
/* Sending packet to client with the information gathered above. */
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.159
diff -u -r1.159 srv_main.c
--- server/srv_main.c 25 Apr 2004 19:03:40 -0000 1.159
+++ server/srv_main.c 26 Apr 2004 20:14:29 -0000
@@ -49,6 +49,7 @@
#include "city.h"
#include "dataio.h"
#include "events.h"
+#include "fciconv.h"
#include "fcintl.h"
#include "game.h"
#include "log.h"
@@ -152,6 +153,9 @@
{
/* NLS init */
init_nls();
+#ifdef ENABLE_NLS
+ bind_textdomain_codeset(PACKAGE, get_data_encoding());
+#endif
/* init server arguments... */
@@ -180,6 +184,9 @@
/* mark as initialized */
has_been_srv_init = TRUE;
+ /* init character encodings. */
+ init_character_encodings(NULL, 1);
+
/* done */
return;
}
@@ -751,11 +758,12 @@
dio_put_uint8(&dout, 1);
dio_put_bool32(&dout, FALSE);
- dio_put_string(&dout, _("Your client is too old. To use this server "
- "please upgrade your client to a CVS version "
- "later than 2003-11-28 or Freeciv 1.15.0 or "
- "later."));
- dio_put_string(&dout, "");
+ dio_put_text_string(&dout,
+ _("Your client is too old. To use this server "
+ "please upgrade your client to a CVS version "
+ "later than 2003-11-28 or Freeciv 1.15.0 or "
+ "later."));
+ dio_put_text_string(&dout, "");
{
size_t size = dio_output_used(&dout);
|
|