Re: setlocale() and gettext() (Re: CVS dpkg flaws)
Previously Fumitoshi UKAI wrote:
> Because AFAIK gettext() converts message's encoding as locale configurations.
> If it fails, it'll output the characters as `?'.
Oh bugger, so gettext has overloaded the meaning of LC_CTYPE to make
it also the indicater for the output character set. From the setlocale
manpage:
LC_CTYPE
for regular expression matching, character classi
fication, conversion, case-sensitive comparison,
and wide character functions.
I would consider this a very nasty bug in gettext
Can you try the (untested) patch below? That tries to work around this
problem by setting and resetting LC_CTYPE in the version comparison
routines.
Wichert.
diff -wur ../dpkg/ChangeLog dpkg/ChangeLog
--- ../dpkg/ChangeLog Mon Dec 31 15:29:56 2001
+++ dpkg/ChangeLog Mon Dec 31 15:48:16 2001
@@ -1,3 +1,10 @@
+Mon Dec 31 15:47:13 CET 2001 Wichert Akkerman <wakkerma@debian.org>
+
+ * lib/vercmp.c: Set and restore LC_CTYPE locale
+ * main/main.c, main/query.c, dselect/main.cc: do not force LC_CTYPE to
+ C since that breaks gettext (aargh), but trust the version comparison
+ routines to do the right thing instead.
+
Mon Dec 31 15:25:46 CET 2001 Wichert Akkerman <wakkerma@debian.org>
* scripts/dpkg-architecture.pl: fix syntax error
diff -wur ../dpkg/dselect/main.cc dpkg/dselect/main.cc
--- ../dpkg/dselect/main.cc Tue Jul 31 12:34:08 2001
+++ dpkg/dselect/main.cc Mon Dec 31 15:47:02 2001
@@ -470,7 +470,6 @@
char *home, *homerc;
setlocale(LC_ALL, "");
- setlocale(LC_CTYPE, "C");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
diff -wur ../dpkg/lib/vercmp.c dpkg/lib/vercmp.c
--- ../dpkg/lib/vercmp.c Tue Jul 17 00:10:21 2001
+++ dpkg/lib/vercmp.c Mon Dec 31 15:46:38 2001
@@ -115,19 +115,46 @@
const struct versionrevision *ref,
enum depverrel verrel) {
int r;
- if (verrel == dvr_none) return 1;
+ int ret;
+ char* pl;
+
+ pl=setlocale(LC_CTYPE, "C"); /* TODO: check for errors */
+ if (verrel == dvr_none)
+ ret= 1;
+ else {
r= versioncompare(it,ref);
switch (verrel) {
- case dvr_earlierequal: return r <= 0;
- case dvr_laterequal: return r >= 0;
- case dvr_earlierstrict: return r < 0;
- case dvr_laterstrict: return r > 0;
- case dvr_exact: return r == 0;
- default: internerr("unknown verrel");
+ case dvr_earlierequal:
+ ret= r <= 0;
+ break;
+ case dvr_laterequal:
+ ret= r >= 0;
+ break;
+ case dvr_earlierstrict:
+ ret= r < 0;
+ break;
+ case dvr_laterstrict:
+ ret= r > 0;
+ break;
+ case dvr_exact:
+ ret= r == 0;
+ break;
+ default:
+ internerr("unknown verrel");
+ }
}
- return 0;
+
+ setlocale(LC_CTYPE, pl); /* TODO: check for errors */
+ return ret;
}
int versionsatisfied(struct pkginfoperfile *it, struct deppossi *against) {
- return versionsatisfied3(&it->version,&against->version,against->verrel);
+ int ret;
+ char* pl;
+
+ pl=setlocale(LC_CTYPE, "C"); /* TODO: check for errors */
+ ret= versionsatisfied3(&it->version,&against->version,against->verrel);
+ setlocale(LC_CTYPE, pl); /* TODO: check for errors */
+
+ return ret;
}
diff -wur ../dpkg/main/main.c dpkg/main/main.c
--- ../dpkg/main/main.c Sun Oct 21 23:55:23 2001
+++ dpkg/main/main.c Mon Dec 31 15:46:48 2001
@@ -550,7 +550,6 @@
char *home, *homerc;
setlocale(LC_ALL, "");
- setlocale(LC_CTYPE, "C");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
diff -wur ../dpkg/main/query.c dpkg/main/query.c
--- ../dpkg/main/query.c Wed Sep 12 16:54:41 2001
+++ dpkg/main/query.c Mon Dec 31 15:47:04 2001
@@ -534,7 +534,6 @@
static void (*actionfunction)(const char *const *argv);
setlocale(LC_ALL, "");
- setlocale(LC_CTYPE, "C");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
--
_________________________________________________________________
/wichert@wiggy.net This space intentionally left occupied \
| wichert@deephackmode.org http://www.liacs.nl/~wichert/ |
| 1024D/2FA3BC2D 576E 100B 518D 2F16 36B0 2805 3CB8 9250 2FA3 BC2D |
Reply to: