Skip to Content.
Sympa Menu

freetds - Re: [freetds] How to set locales.conf in spanish

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Steve Langasek <vorlon AT netexpress.net>
  • To: freetds AT lists.ibiblio.org
  • Subject: Re: [freetds] How to set locales.conf in spanish
  • Date: Mon, 13 Jan 2003 00:03:28 -0600

On Sat, Jan 11, 2003 at 10:52:41PM -0500, James K. Lowden wrote:
> On Sat, 11 Jan 2003 21:02:53 -0600, Steve Langasek <vorlon AT netexpress.net>
> wrote:

> > Yes, it seems likely to me that there'll still be a need to map between
> > platform-specific charset names and canonical ones. However, this is
> > something that can be done deterministically without bothering the user
> > to set up a config file, whereas the mapping between a locale name and a
> > charset, even using canonical names, may be different on different
> > machines.

> Agreed. For the record, I never intended to try to infer a
> language-charset map. I expected to parse the charset from setlocale(3).

> > However, nl_langinfo(D_T_FMT) looks promising for getting date formats
> > into the local standard by default.

> Ehm, I'm not sure where we should take that. For db-lib and ct-lib, we
> emulate Sybase's default format by default, if you see what I mean.

Ok. Well, I'm attaching a patch that starts to add nl_langinfo()
support to libtds. It's not much at this point, but perhaps we can use
it to focus the discussion.

Notes about the patch:

- I've added a 'client_charset' member to the TDSLOCALE struct, because
I believe there's a need to track the client charset and the server
charset separately. In the case of TDS7/TDS8, for instance, it may be
preferable to use UCS2 on the wire and just use iconv for converting
to avoid problems with trying to turn platform-specific charset names
into something the server understands.
- In src/tds/locale.c, we look for locale information from the following
sources, in decreasing order of preference:
* a locale-specific section in locales.conf
* the current system locale, as determined by nl_langinfo()
* a default section in locales.conf
I figured this was gentler than ripping locales.conf out altogether
just yet. :) Note that the application has to call setlocale() for
#2 to work; I've fixed tsql's handling of this, and have a patch to
add similar support to sqsh. Users of perl/php need to call
setlocale() for their scripts.
- I replaced the getenv("LANG") call with a call to
setlocale(LC_MESSAGES,NULL), which returns the authoritative locale
for the process. This is still kinda kludgy, since the charset really
corresponds to LC_CTYPE, and the date format corresponds to LC_TIME;
but LC_MESSAGES is what corresponds most closely to the LANG variable.
The whole thing should really just go away.

Things to be done:

- start building a mapping table to convert charsets to something the
TDS server understands
- make the iconv routines use the client_charset; this may require
another mapping table on some platforms
- another map, to turn LC_MESSAGES names into a language setting --
/without/ locales.conf
- find some way to handle multibyte charsets on the client side, so
that my UTF8 queries don't truncate halfway through the string :)

Cheers,
--
Steve Langasek
postmodern programmer
Index: include/tds.h
===================================================================
RCS file: /cvsroot/freetds/freetds/include/tds.h,v
retrieving revision 1.77
diff -u -r1.77 tds.h
--- include/tds.h 5 Jan 2003 13:42:00 -0000 1.77
+++ include/tds.h 13 Jan 2003 05:39:27 -0000
@@ -469,6 +469,7 @@
typedef struct tds_locale {
char *language;
char *char_set;
+ char *client_charset;
char *date_fmt;
} TDSLOCALE;

Index: src/tds/locale.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/tds/locale.c,v
retrieving revision 1.17
diff -u -r1.17 locale.c
--- src/tds/locale.c 28 Dec 2002 19:50:58 -0000 1.17
+++ src/tds/locale.c 13 Jan 2003 05:39:27 -0000
@@ -32,6 +32,10 @@
#include <stdlib.h>
#endif /* HAVE_STDLIB_H */

+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+
#include "tds.h"
#include "tds_configs.h"
#ifdef DMALLOC
@@ -61,22 +65,41 @@
if (!locale)
return NULL;

+ locale->client_charset = NULL;
tdsdump_log(TDS_DBG_INFO1, "%L Attempting to read locales.conf
file\n");

in = fopen(FREETDS_LOCALECONFFILE, "r");
if (in) {
tds_read_conf_section(in, "default", tds_parse_locale,
locale);
+ }

- s = getenv("LANG");
+#ifdef HAVE_NL_LANGINFO
+ /* Try to determine locale settings using the system routines */
+ if ((s = nl_langinfo(CODESET))) {
+ if (locale->char_set) free(locale->char_set);
+ if (locale->client_charset) free(locale->client_charset);
+ locale->client_charset = strdup(s);
+ locale->char_set = strdup(s);
+ }
+ if ((s = nl_langinfo(D_T_FMT))) {
+ if (locale->date_fmt) free(locale->date_fmt);
+ locale->date_fmt = strdup(s);
+ }
+#endif
+
+ /* Allow an explicit section in locales.conf to override...
+ for the time being. */
+ if (in) {
+ /* This is really what 'LANG' is supposed to represent. */
+ s = setlocale(LC_MESSAGES,NULL);
if (s && strlen(s)) {
rewind(in);
- for (i = 0; i < strlen(s); i++)
- s[i] = tolower(s[i]);
tds_read_conf_section(in, s, tds_parse_locale,
locale);
}

fclose(in);
}
+
return locale;
}

Index: src/tds/mem.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/tds/mem.c,v
retrieving revision 1.58
diff -u -r1.58 mem.c
--- src/tds/mem.c 28 Dec 2002 19:50:58 -0000 1.58
+++ src/tds/mem.c 13 Jan 2003 05:39:28 -0000
@@ -527,6 +527,9 @@
if (locale->char_set)
if
(!tds_dstr_copy(&connect_info->char_set,locale->char_set))
goto Cleanup;
+ if (locale->client_charset)
+ if
(!tds_dstr_copy(&connect_info->client_charset,locale->client_charset))
+ goto Cleanup;
}
if (tds_dstr_isempty(&connect_info->language)) {
if (!tds_dstr_copy(&connect_info->language,TDS_DEF_LANG))
@@ -663,6 +666,7 @@
if (locale->language) free(locale->language);
if (locale->char_set) free(locale->char_set);
if (locale->date_fmt) free(locale->date_fmt);
+ if (locale->client_charset) free(locale->client_charset);
TDS_ZERO_FREE(locale);
}
void tds_free_connect(TDSCONNECTINFO *connect_info)

Attachment: pgpqtl80I_sCM.pgp
Description: PGP signature




Archive powered by MHonArc 2.6.24.

Top of Page