bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#12392: emacs-gtk misinterprets floating-point numbers under certain


From: Holger Arnold
Subject: bug#12392: emacs-gtk misinterprets floating-point numbers under certain locales on openSUSE 12.2
Date: Sat, 22 Sep 2012 16:38:22 +0200
User-agent: KMail/4.9.1 (Linux/3.5.4-1-default; KDE/4.9.1; i686; ; )

Achim Gratz wrote:
> Holger Arnold writes:
> > 1. Emacs changes the locale _after_ GTK has been initialized, which,
> > according to the GTK docs, "may produce inconsistent results and is
> > not really supported" (see
> > http://developer.gnome.org/gtk/stable/gtk-General.html#gtk-set-locale).
> 
> No, this docstring talks about gtk_set_locale, which emacs doesn't want
> or need to change.

May I cite: "Note, however, that changing the locale after GTK+ is initialized 
may produce inconsistent results and is not really supported."  This warning 
is not related to this particular function, as gtk_set_locale() does nothing 
more than calling setlocale(LC_ALL, "").  Emacs calls this function via 
gtk_init().

> > 2. To make the parsing (and printing?) of number literals in Emacs
> > Lisp locale-dependent is the wrong approach.
> 
> There are a lot of things that are wrong with internationalization, but
> this isn't one of them IMHO.  Emacs does call setlocale for it.

I don't know which are the things that are wrong with internationalization you 
are referring to, but, IMHO, setting the locale or parts of it to a value 
different from what the user has specified is the wrong approach.  Lisp 
programs are simply not localizable text.

> > What is happening here is that, after Emacs's second call to
> > fixup_locale() (after initializing GTK), a module implicitly loaded by
> > GTK (GStreamer in this case, accessed by GTK via libcanberra) calls
> > setlocale(LC_ALL, "") again.  The GTK docs explicitly say that such
> > things may happen.
> 
> Please cite chapter and verse: if it's documented, then there should be
> a documented way of dealing with it.  Otherwise a _library_ changing the
> locale out from under a program is a bug, especially when it is already
> guaranteed that the library comes into existence in a sane locale
> environment.  I'd think that the gstreamer part is what has changed
> between openSUSE 12.1 and 12.2, BTW.

To me, the warning cited above sounds sufficiently explicit.

Note that _any_ program having a localized user interface has to call 
setlocale(LC_ALL, "") at the start to set the locale to the value specified by 
its environment.  gtk_init() simply does this for you.  If you don't like that 
behavior, you can initialize GTK without calling gtk_init() (but this wouldn't 
help with GStreamer).

As to whether calling setlocale(LC_ALL, "") in a library is a bug, what would 
you expect a library that wants to provide localized messages to do?  Changing 
the locale before and after each call?  This would be racy in a multi-threaded 
program.

> > Note that inserting gtk_disable_setlocale() before gtk_init() does not
> > help because this setting does not transcend to the loaded module.
> 
> That dangling carrot looks appealing, but it appears we'd really want to
> gtk be initialized with the users' locale and not with the emacs altered
> one.

And calling gtk_disable_setlocale() wouldn't help anyway.

> > A quick work-around is to start Emacs with LC_NUMERIC set to "C".
> > 
> > The long-term solution would be to fix Emacs's Lisp parser so that it
> > does not depend on the current locale.  Hard-setting the locale to "C"
> > is bad style because it ignores the user's interface preferences.
> 
> This is done all the time in other applications.  What's the point of
> internationalization if you'd then need another function for each locale
> and variant that the program intends to use?  That is exactly why
> setlocale returns an object that you can use to restore the locale at
> any point in time.

I know that many programs do it that way, but this does not make it the 
correct approach.  Programs that reset (parts of) the locale to "C" have been 
developed under the idea that the program "owns" the locale and can manipulate 
it at will.  In my -- extremely humble -- opinion, that is a misconception of 
the locale concept.  Locales provide a way for *users* to specify their 
preferences wrt. localization.  Therefore, the current locale belongs to the 
*user*, and a localized program should not manipulate it beyond calling 
setlocale(LC_ALL, ""), which is basically just an alias for "yes, I want to be 
localized".

Now, what can programs do that have to manipulate text in multiple locales?

If you have complete control over everything, you can indeed switch the 
current locale before and after each call to an input, output, conversion, or 
string manipulation function.  If you have multiple threads, don't forget to 
properly synchronize these calls.  The problem is that this is inefficient and 
that you _don't have_ complete control in a program that interacts with many 
components, like Emacs does.  Do you want to race with GTK, GStreamer, or 
whatever library over the current locale?

The better approach would be to have input, output, conversion, and string 
manipulation functions that take a locale as an additional argument, similarly 
to the C++ standard lib, where each stream has an assigned locale.  Since the 
code is already there, it would be an easy task to add such functions to glibc 
(but this is probably not going to happen).

But for Emacs and most other programs, this isn't even needed.  Most programs 
manipulate only two kinds of text: user interface text, which should be 
processed in the locale specified by the environment, and formal language 
text, such as configuration files or program code, which should be processed 
independently from the locale.

So, the only thing that has to be done for Emacs is to make all functions that 
print or parse Lisp objects locale-independent (yes, this means you can't use 
atof() for converting a number).  This isn't too hard.

The other option would be to simply ignore localization and start Emacs always 
with LANG=C.


        Holger






reply via email to

[Prev in Thread] Current Thread [Next in Thread]