[Gtkradiant] ZeroRadiant and locale

Nerius Landys nlandys at gmail.com
Sat Nov 13 19:42:01 CST 2010


OK folks, I've committed the following code to the main() method of
Radiant.  Comment speaks for itself.



  /*
    Rambetter on Sat Nov 13, 2010:

    The following line fixes parsing and writing of floating point numbers
in locales such as
    Italy, Germany, and others outside of en_US.  In particular, in such
problem locales, users
    are not able to use certain map entities such as "light" because the
definitions of these entities
    in the entity definition files contain floating point values written in
the standard "C" format
    (containing a dot instead of, for example, a comma).  The call sscanf()
is all over the code,
    including parsing entity definition files and reading Radiant
preferences.  sscanf() is sensitive
    to locale (in particular when reading floating point numbers).

    The line below is the minimalistic way to address only this particular
problem - the parsing
    and writing of floating point values.  There may be other
yet-undiscovered bugs related to
    locale still lingering in the code.  When such bugs are discovered, they
should be addressed by
    setting more than just "LC_NUMERIC=C" (for example LC_CTYPE for regular
expression matching)
    or by fixing the problem in the actual code instead of fiddling with
LC_* variables.

    Another way to fix the floating point format problem is to locate all
calls such as *scanf()
    and *printf() in the code and replace them with other functions.
However, we're also using
    external libraries such as libxml and [maybe?] they use locale to parse
their numeric values.
    I'm just saying, it may get ugly if we try to fix the problem without
setting LC_NUMERIC.

    Usage of sscanf() throughout the code looks like so:
      sscanf(str, "%f %f %f", &val1, &val2, &val3);
    Code like this exists in many files, here are 4 examples:
      tools/quake3/q3map2/light.c
      tools/quake3/q3map2/model.c
      radiant/preferences.cpp
      plugins/entity/miscmodel.cpp

    Also affected are printf() calls when using formats that contain "%f".

    I did some research and putenv() seems to be the best choice for being
cross-platform.  It
    used to be a function in Windows (now deprecated):
      http://msdn.microsoft.com/en-us/library/ms235321(VS.80).aspx
    And of course it's defined in UNIX.

    One more thing.  the gtk_init() call below modifies all of the locale
settings.  In fact if it
    weren't for gtk_init(), we wouldn't have to set LC_NUMERIC (parsing of
floating points with
    a dot works just fine before the gtk_init() call on a sample Linux
system).  If we were to
    just setlocale() here, it would get clobbered by gtk_init().  So instead
of using setlocale()
    _after_ gtk_init(), I chose to fix this problem via environment
variable.  I think it's cleaner
    that way.
  */
  putenv("LC_NUMERIC=C");









- Rambetter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://zerowing.idsoftware.com/pipermail/gtkradiant/attachments/20101113/daa1e919/attachment.htm 


More information about the Gtkradiant mailing list