mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
More localisation fixes.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@9733 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
37faeda178
commit
8d79b94cc1
4 changed files with 250 additions and 95 deletions
|
@ -1,3 +1,11 @@
|
|||
2001-04-28 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSLog.m: Use RETAIN/RELEASE
|
||||
* Source/GSLocale.m: Set up NSDecimalSeparator and NSThousandsSeparator
|
||||
from locale if possible. Fix bug dereferencing nil pointer.
|
||||
* Source/GSFormat.m: Hack to rewrite output from sprintf of floats and
|
||||
doubles to use the value in NSDecimalSeparator.
|
||||
|
||||
2001-04-27 Nicola Pero <n.pero@mi.flashnet.it>
|
||||
|
||||
* Source/NSString.m: Minor optimization for parsing property
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include <Foundation/NSZone.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <base/GSFormat.h>
|
||||
#include <base/GSLocale.h>
|
||||
#include <limits.h>
|
||||
#include <string.h> // for strstr()
|
||||
#include <sys/stat.h>
|
||||
|
@ -1368,116 +1369,240 @@ NSDictionary *locale)
|
|||
LABEL (form_float):
|
||||
{
|
||||
/* Floating-point number. This is handled by the native sprintf. */
|
||||
char buf1[32], *bp, buf2[specs[nspecs_done].info.width+specs[nspecs_done].info.prec+32];
|
||||
unichar work_buffer[MAX (specs[nspecs_done].info.width, specs[nspecs_done].info.spec) + 32];
|
||||
unichar *const workend
|
||||
= &work_buffer[sizeof (work_buffer) / sizeof (unichar)];
|
||||
register unichar *w;
|
||||
char buf1[32], *bp;
|
||||
char buf2[specs[nspecs_done].info.width
|
||||
+specs[nspecs_done].info.prec+32];
|
||||
unichar work_buffer[MAX (specs[nspecs_done].info.width,
|
||||
specs[nspecs_done].info.spec) + 32];
|
||||
unichar *const workend
|
||||
= &work_buffer[sizeof (work_buffer) / sizeof (unichar)];
|
||||
register unichar *w;
|
||||
NSString *decimal_sep;
|
||||
|
||||
bp = buf1;
|
||||
decimal_sep = [locale objectForKey: NSDecimalSeparator];
|
||||
|
||||
*bp++ = '%';
|
||||
bp = buf1;
|
||||
|
||||
if (specs[nspecs_done].info.alt)
|
||||
*bp++ = '#';
|
||||
if (specs[nspecs_done].info.group)
|
||||
*bp++ = '\'';
|
||||
if (specs[nspecs_done].info.showsign)
|
||||
*bp++ = '+';
|
||||
else if (specs[nspecs_done].info.space)
|
||||
*bp++ = ' ';
|
||||
if (specs[nspecs_done].info.left)
|
||||
*bp++ = '-';
|
||||
if (specs[nspecs_done].info.pad == '0')
|
||||
*bp++ = '0';
|
||||
if (specs[nspecs_done].info.i18n)
|
||||
*bp++ = 'I';
|
||||
*bp++ = '%';
|
||||
|
||||
if (specs[nspecs_done].info.width != 0)
|
||||
{
|
||||
w = _itowa_word (specs[nspecs_done].info.width, workend, 10, 0);
|
||||
while (w < workend)
|
||||
*bp++ = *w++;
|
||||
}
|
||||
if (specs[nspecs_done].info.alt)
|
||||
*bp++ = '#';
|
||||
if (specs[nspecs_done].info.group)
|
||||
*bp++ = '\'';
|
||||
if (specs[nspecs_done].info.showsign)
|
||||
*bp++ = '+';
|
||||
else if (specs[nspecs_done].info.space)
|
||||
*bp++ = ' ';
|
||||
if (specs[nspecs_done].info.left)
|
||||
*bp++ = '-';
|
||||
if (specs[nspecs_done].info.pad == '0')
|
||||
*bp++ = '0';
|
||||
if (specs[nspecs_done].info.i18n)
|
||||
*bp++ = 'I';
|
||||
|
||||
if (specs[nspecs_done].info.prec != -1)
|
||||
{
|
||||
*bp++ = '.';
|
||||
w = _itowa_word (specs[nspecs_done].info.prec, workend, 10, 0);
|
||||
while (w < workend)
|
||||
*bp++ = *w++;
|
||||
}
|
||||
if (specs[nspecs_done].info.width != 0)
|
||||
{
|
||||
w = _itowa_word (specs[nspecs_done].info.width, workend, 10, 0);
|
||||
while (w < workend)
|
||||
*bp++ = *w++;
|
||||
}
|
||||
|
||||
if (specs[nspecs_done].info.spec != '\0')
|
||||
*bp++ = specs[nspecs_done].info.spec;
|
||||
if (specs[nspecs_done].info.prec != -1)
|
||||
{
|
||||
*bp++ = '.';
|
||||
w = _itowa_word (specs[nspecs_done].info.prec, workend, 10, 0);
|
||||
while (w < workend)
|
||||
*bp++ = *w++;
|
||||
}
|
||||
|
||||
*bp++ = '\0';
|
||||
if (specs[nspecs_done].info.spec != '\0')
|
||||
*bp++ = specs[nspecs_done].info.spec;
|
||||
|
||||
if (specs[nspecs_done].info.is_long_double)
|
||||
sprintf(buf2, buf1, args_value[specs[nspecs_done].data_arg].pa_long_double);
|
||||
else
|
||||
sprintf(buf2, buf1, args_value[specs[nspecs_done].data_arg].pa_double);
|
||||
*bp++ = '\0';
|
||||
|
||||
bp = buf2;
|
||||
while (*bp) outchar(*bp++);
|
||||
if (specs[nspecs_done].info.is_long_double)
|
||||
{
|
||||
sprintf(buf2, buf1,
|
||||
args_value[specs[nspecs_done].data_arg].pa_long_double);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf2, buf1,
|
||||
args_value[specs[nspecs_done].data_arg].pa_double);
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME - hack to rewrite decimal separator into correct locale
|
||||
* if necessary.
|
||||
*/
|
||||
if (decimal_sep != nil)
|
||||
{
|
||||
NSDictionary *def = GSDomainFromDefaultLocale();
|
||||
NSString *sep = [def objectForKey: NSDecimalSeparator];
|
||||
|
||||
if (sep == nil)
|
||||
sep = @".";
|
||||
if ([decimal_sep isEqual: sep] == NO && [sep length] == 1)
|
||||
{
|
||||
unichar m = [sep characterAtIndex: 0];
|
||||
char *p = &buf2[strlen(buf2)];
|
||||
|
||||
/*
|
||||
* Assume that we won't be finding an escape in the string
|
||||
* so we can use it as a marker.
|
||||
*/
|
||||
while (p-- > buf2)
|
||||
{
|
||||
if (*p == m)
|
||||
{
|
||||
*p = '\033';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bp = buf2;
|
||||
while (*bp)
|
||||
{
|
||||
if (*bp == '\033')
|
||||
{
|
||||
int i = 0;
|
||||
int c = [decimal_sep length];
|
||||
unichar b[c];
|
||||
|
||||
[decimal_sep getCharacters: b];
|
||||
while (i < c)
|
||||
{
|
||||
outchar(b[i++]);
|
||||
}
|
||||
bp++;
|
||||
}
|
||||
else
|
||||
{
|
||||
outchar(*bp++);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
LABEL (form_floathex):
|
||||
{
|
||||
/* Floating point number printed as hexadecimal number. */
|
||||
char buf1[32], *bp, buf2[specs[nspecs_done].info.width+specs[nspecs_done].info.prec+32];
|
||||
unichar work_buffer[MAX (specs[nspecs_done].info.width, specs[nspecs_done].info.spec) + 32];
|
||||
unichar *const workend
|
||||
= &work_buffer[sizeof (work_buffer) / sizeof (unichar)];
|
||||
register unichar *w;
|
||||
/* Floating point number printed as hexadecimal number. */
|
||||
char buf1[32], *bp;
|
||||
char buf2[specs[nspecs_done].info.width
|
||||
+specs[nspecs_done].info.prec+32];
|
||||
unichar work_buffer[MAX (specs[nspecs_done].info.width,
|
||||
specs[nspecs_done].info.spec) + 32];
|
||||
unichar *const workend
|
||||
= &work_buffer[sizeof (work_buffer) / sizeof (unichar)];
|
||||
register unichar *w;
|
||||
NSString *decimal_sep;
|
||||
|
||||
bp = buf1;
|
||||
decimal_sep = [locale objectForKey: NSDecimalSeparator];
|
||||
|
||||
*bp++ = '%';
|
||||
bp = buf1;
|
||||
|
||||
if (specs[nspecs_done].info.alt)
|
||||
*bp++ = '#';
|
||||
if (specs[nspecs_done].info.group)
|
||||
*bp++ = '\'';
|
||||
if (specs[nspecs_done].info.showsign)
|
||||
*bp++ = '+';
|
||||
else if (specs[nspecs_done].info.space)
|
||||
*bp++ = ' ';
|
||||
if (specs[nspecs_done].info.left)
|
||||
*bp++ = '-';
|
||||
if (specs[nspecs_done].info.pad == '0')
|
||||
*bp++ = '0';
|
||||
if (specs[nspecs_done].info.i18n)
|
||||
*bp++ = 'I';
|
||||
*bp++ = '%';
|
||||
|
||||
if (specs[nspecs_done].info.width != 0)
|
||||
{
|
||||
w = _itowa_word (specs[nspecs_done].info.width, workend, 10, 0);
|
||||
while (w < workend)
|
||||
*bp++ = *w++;
|
||||
}
|
||||
if (specs[nspecs_done].info.alt)
|
||||
*bp++ = '#';
|
||||
if (specs[nspecs_done].info.group)
|
||||
*bp++ = '\'';
|
||||
if (specs[nspecs_done].info.showsign)
|
||||
*bp++ = '+';
|
||||
else if (specs[nspecs_done].info.space)
|
||||
*bp++ = ' ';
|
||||
if (specs[nspecs_done].info.left)
|
||||
*bp++ = '-';
|
||||
if (specs[nspecs_done].info.pad == '0')
|
||||
*bp++ = '0';
|
||||
if (specs[nspecs_done].info.i18n)
|
||||
*bp++ = 'I';
|
||||
|
||||
if (specs[nspecs_done].info.prec != -1)
|
||||
{
|
||||
*bp++ = '.';
|
||||
w = _itowa_word (specs[nspecs_done].info.prec, workend, 10, 0);
|
||||
while (w < workend)
|
||||
*bp++ = *w++;
|
||||
}
|
||||
if (specs[nspecs_done].info.width != 0)
|
||||
{
|
||||
w = _itowa_word (specs[nspecs_done].info.width, workend, 10, 0);
|
||||
while (w < workend)
|
||||
*bp++ = *w++;
|
||||
}
|
||||
|
||||
if (specs[nspecs_done].info.spec != '\0')
|
||||
*bp++ = specs[nspecs_done].info.spec;
|
||||
if (specs[nspecs_done].info.prec != -1)
|
||||
{
|
||||
*bp++ = '.';
|
||||
w = _itowa_word (specs[nspecs_done].info.prec, workend, 10, 0);
|
||||
while (w < workend)
|
||||
*bp++ = *w++;
|
||||
}
|
||||
|
||||
*bp++ = '\0';
|
||||
if (specs[nspecs_done].info.spec != '\0')
|
||||
*bp++ = specs[nspecs_done].info.spec;
|
||||
|
||||
if (specs[nspecs_done].info.is_long_double)
|
||||
sprintf(buf2, buf1, args_value[specs[nspecs_done].data_arg].pa_long_double);
|
||||
else
|
||||
sprintf(buf2, buf1, args_value[specs[nspecs_done].data_arg].pa_double);
|
||||
*bp++ = '\0';
|
||||
|
||||
bp = buf2;
|
||||
while (*bp) outchar(*bp++);
|
||||
if (specs[nspecs_done].info.is_long_double)
|
||||
{
|
||||
sprintf(buf2, buf1,
|
||||
args_value[specs[nspecs_done].data_arg].pa_long_double);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf2, buf1,
|
||||
args_value[specs[nspecs_done].data_arg].pa_double);
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME - hack to rewrite decimal separator into correct locale
|
||||
* if necessary.
|
||||
*/
|
||||
if (decimal_sep != nil)
|
||||
{
|
||||
NSDictionary *def = GSDomainFromDefaultLocale();
|
||||
NSString *sep = [def objectForKey: NSDecimalSeparator];
|
||||
|
||||
if (sep == nil)
|
||||
sep = @".";
|
||||
if ([decimal_sep isEqual: sep] == NO && [sep length] == 1)
|
||||
{
|
||||
unichar m = [sep characterAtIndex: 0];
|
||||
char *p = &buf2[strlen(buf2)];
|
||||
|
||||
/*
|
||||
* Assume that we won't be finding an escape in the string
|
||||
* so we can use it as a marker.
|
||||
*/
|
||||
while (p-- > buf2)
|
||||
{
|
||||
if (*p == m)
|
||||
{
|
||||
*p = '\033';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bp = buf2;
|
||||
while (*bp)
|
||||
{
|
||||
if (*bp == '\033')
|
||||
{
|
||||
int i = 0;
|
||||
int c = [decimal_sep length];
|
||||
unichar b[c];
|
||||
|
||||
[decimal_sep getCharacters: b];
|
||||
while (i < c)
|
||||
{
|
||||
outchar(b[i++]);
|
||||
}
|
||||
bp++;
|
||||
}
|
||||
else
|
||||
{
|
||||
outchar(*bp++);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <base/GSLocale.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSLock.h>
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
|
||||
|
@ -50,7 +51,7 @@ GSSetLocaleC(const char *loc)
|
|||
/* Set the locale for libc functions from the supplied string or from
|
||||
the environment if not specified. This function should be called
|
||||
as soon as possible after the start of the program. Passing
|
||||
@"" will set the locale from the environment varialbes LC_ALL or LANG (or
|
||||
@"" will set the locale from the environment variables LC_ALL or LANG (or
|
||||
whatever is specified by setlocale) Passing nil will just return the
|
||||
current locale. */
|
||||
NSString *
|
||||
|
@ -88,6 +89,7 @@ NSDictionary *
|
|||
GSDomainFromDefaultLocale(void)
|
||||
{
|
||||
#ifdef HAVE_LANGINFO_H
|
||||
static NSDictionary *saved = nil;
|
||||
int i;
|
||||
struct lconv *lconv;
|
||||
NSMutableDictionary *dict;
|
||||
|
@ -95,6 +97,9 @@ GSDomainFromDefaultLocale(void)
|
|||
NSString *str1;
|
||||
NSString *str2;
|
||||
|
||||
if (saved != nil)
|
||||
return saved;
|
||||
|
||||
dict = [NSMutableDictionary dictionary];
|
||||
|
||||
/* Time/Date Information */
|
||||
|
@ -164,17 +169,36 @@ GSDomainFromDefaultLocale(void)
|
|||
[dict setObject: [NSString stringWithCString: lconv->mon_thousands_sep]
|
||||
forKey: NSInternationalCurrencyString];
|
||||
}
|
||||
|
||||
if (lconv->decimal_point)
|
||||
{
|
||||
[dict setObject: [NSString stringWithCString: lconv->decimal_point]
|
||||
forKey: NSDecimalSeparator];
|
||||
}
|
||||
if (lconv->thousands_sep)
|
||||
{
|
||||
[dict setObject: [NSString stringWithCString: lconv->thousands_sep]
|
||||
forKey: NSThousandsSeparator];
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: Get currency format from localeconv */
|
||||
|
||||
str1 = GSSetLocale(nil);
|
||||
[dict setObject: str1 forKey: NSLocale];
|
||||
if (str1 != nil)
|
||||
{
|
||||
[dict setObject: str1 forKey: NSLocale];
|
||||
}
|
||||
str2 = GSLanguageFromLocale(str1);
|
||||
if (str2)
|
||||
if (str2 != nil)
|
||||
{
|
||||
[dict setObject: str2 forKey: NSLanguageName];
|
||||
}
|
||||
|
||||
return dict;
|
||||
[gnustep_global_lock lock];
|
||||
saved = [dict mutableCopy];
|
||||
[gnustep_global_lock unlock];
|
||||
return saved;
|
||||
#else /* HAVE_LANGINFO_H */
|
||||
return nil;
|
||||
#endif
|
||||
|
|
|
@ -89,13 +89,11 @@ void
|
|||
NSLogv (NSString* format, va_list args)
|
||||
{
|
||||
static NSRecursiveLock *myLock = nil;
|
||||
NSAutoreleasePool *arp;
|
||||
CREATE_AUTORELEASE_POOL(arp);
|
||||
NSString *prefix;
|
||||
NSString *message;
|
||||
int pid;
|
||||
|
||||
arp = [NSAutoreleasePool new];
|
||||
|
||||
if (_NSLog_printf_handler == NULL)
|
||||
_NSLog_printf_handler = *_NSLog_standard_printf_handler;
|
||||
|
||||
|
@ -134,6 +132,6 @@ NSLogv (NSString* format, va_list args)
|
|||
|
||||
[myLock unlock];
|
||||
|
||||
[arp release];
|
||||
RELEASE(arp);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue