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:
CaS 2001-04-28 05:53:56 +00:00
parent 7e4a1c54de
commit a70dd0619f
4 changed files with 250 additions and 95 deletions

View file

@ -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> 2001-04-27 Nicola Pero <n.pero@mi.flashnet.it>
* Source/NSString.m: Minor optimization for parsing property * Source/NSString.m: Minor optimization for parsing property

View file

@ -61,6 +61,7 @@
#include <Foundation/NSZone.h> #include <Foundation/NSZone.h>
#include <Foundation/NSDebug.h> #include <Foundation/NSDebug.h>
#include <base/GSFormat.h> #include <base/GSFormat.h>
#include <base/GSLocale.h>
#include <limits.h> #include <limits.h>
#include <string.h> // for strstr() #include <string.h> // for strstr()
#include <sys/stat.h> #include <sys/stat.h>
@ -1368,116 +1369,240 @@ NSDictionary *locale)
LABEL (form_float): LABEL (form_float):
{ {
/* Floating-point number. This is handled by the native sprintf. */ /* 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]; char buf1[32], *bp;
unichar work_buffer[MAX (specs[nspecs_done].info.width, specs[nspecs_done].info.spec) + 32]; char buf2[specs[nspecs_done].info.width
unichar *const workend +specs[nspecs_done].info.prec+32];
= &work_buffer[sizeof (work_buffer) / sizeof (unichar)]; unichar work_buffer[MAX (specs[nspecs_done].info.width,
register unichar *w; 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++ = '%';
*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.width != 0) if (specs[nspecs_done].info.alt)
{ *bp++ = '#';
w = _itowa_word (specs[nspecs_done].info.width, workend, 10, 0); if (specs[nspecs_done].info.group)
while (w < workend) *bp++ = '\'';
*bp++ = *w++; 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) if (specs[nspecs_done].info.width != 0)
{ {
*bp++ = '.'; w = _itowa_word (specs[nspecs_done].info.width, workend, 10, 0);
w = _itowa_word (specs[nspecs_done].info.prec, workend, 10, 0); while (w < workend)
while (w < workend) *bp++ = *w++;
*bp++ = *w++; }
}
if (specs[nspecs_done].info.spec != '\0') if (specs[nspecs_done].info.prec != -1)
*bp++ = specs[nspecs_done].info.spec; {
*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) *bp++ = '\0';
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 = buf2; if (specs[nspecs_done].info.is_long_double)
while (*bp) outchar(*bp++); {
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; break;
LABEL (form_floathex): LABEL (form_floathex):
{ {
/* Floating point number printed as hexadecimal number. */ /* Floating point number printed as hexadecimal number. */
char buf1[32], *bp, buf2[specs[nspecs_done].info.width+specs[nspecs_done].info.prec+32]; char buf1[32], *bp;
unichar work_buffer[MAX (specs[nspecs_done].info.width, specs[nspecs_done].info.spec) + 32]; char buf2[specs[nspecs_done].info.width
unichar *const workend +specs[nspecs_done].info.prec+32];
= &work_buffer[sizeof (work_buffer) / sizeof (unichar)]; unichar work_buffer[MAX (specs[nspecs_done].info.width,
register unichar *w; 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++ = '%';
*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.width != 0) if (specs[nspecs_done].info.alt)
{ *bp++ = '#';
w = _itowa_word (specs[nspecs_done].info.width, workend, 10, 0); if (specs[nspecs_done].info.group)
while (w < workend) *bp++ = '\'';
*bp++ = *w++; 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) if (specs[nspecs_done].info.width != 0)
{ {
*bp++ = '.'; w = _itowa_word (specs[nspecs_done].info.width, workend, 10, 0);
w = _itowa_word (specs[nspecs_done].info.prec, workend, 10, 0); while (w < workend)
while (w < workend) *bp++ = *w++;
*bp++ = *w++; }
}
if (specs[nspecs_done].info.spec != '\0') if (specs[nspecs_done].info.prec != -1)
*bp++ = specs[nspecs_done].info.spec; {
*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) *bp++ = '\0';
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 = buf2; if (specs[nspecs_done].info.is_long_double)
while (*bp) outchar(*bp++); {
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; break;

View file

@ -25,6 +25,7 @@
#include <base/GSLocale.h> #include <base/GSLocale.h>
#include <Foundation/NSDictionary.h> #include <Foundation/NSDictionary.h>
#include <Foundation/NSArray.h> #include <Foundation/NSArray.h>
#include <Foundation/NSLock.h>
#ifdef HAVE_LOCALE_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 /* Set the locale for libc functions from the supplied string or from
the environment if not specified. This function should be called the environment if not specified. This function should be called
as soon as possible after the start of the program. Passing 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 whatever is specified by setlocale) Passing nil will just return the
current locale. */ current locale. */
NSString * NSString *
@ -88,6 +89,7 @@ NSDictionary *
GSDomainFromDefaultLocale(void) GSDomainFromDefaultLocale(void)
{ {
#ifdef HAVE_LANGINFO_H #ifdef HAVE_LANGINFO_H
static NSDictionary *saved = nil;
int i; int i;
struct lconv *lconv; struct lconv *lconv;
NSMutableDictionary *dict; NSMutableDictionary *dict;
@ -95,6 +97,9 @@ GSDomainFromDefaultLocale(void)
NSString *str1; NSString *str1;
NSString *str2; NSString *str2;
if (saved != nil)
return saved;
dict = [NSMutableDictionary dictionary]; dict = [NSMutableDictionary dictionary];
/* Time/Date Information */ /* Time/Date Information */
@ -164,17 +169,36 @@ GSDomainFromDefaultLocale(void)
[dict setObject: [NSString stringWithCString: lconv->mon_thousands_sep] [dict setObject: [NSString stringWithCString: lconv->mon_thousands_sep]
forKey: NSInternationalCurrencyString]; 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 */ /* FIXME: Get currency format from localeconv */
str1 = GSSetLocale(nil); str1 = GSSetLocale(nil);
[dict setObject: str1 forKey: NSLocale]; if (str1 != nil)
{
[dict setObject: str1 forKey: NSLocale];
}
str2 = GSLanguageFromLocale(str1); str2 = GSLanguageFromLocale(str1);
if (str2) if (str2 != nil)
{ {
[dict setObject: str2 forKey: NSLanguageName]; [dict setObject: str2 forKey: NSLanguageName];
} }
return dict; [gnustep_global_lock lock];
saved = [dict mutableCopy];
[gnustep_global_lock unlock];
return saved;
#else /* HAVE_LANGINFO_H */ #else /* HAVE_LANGINFO_H */
return nil; return nil;
#endif #endif

View file

@ -89,13 +89,11 @@ void
NSLogv (NSString* format, va_list args) NSLogv (NSString* format, va_list args)
{ {
static NSRecursiveLock *myLock = nil; static NSRecursiveLock *myLock = nil;
NSAutoreleasePool *arp; CREATE_AUTORELEASE_POOL(arp);
NSString *prefix; NSString *prefix;
NSString *message; NSString *message;
int pid; int pid;
arp = [NSAutoreleasePool new];
if (_NSLog_printf_handler == NULL) if (_NSLog_printf_handler == NULL)
_NSLog_printf_handler = *_NSLog_standard_printf_handler; _NSLog_printf_handler = *_NSLog_standard_printf_handler;
@ -134,6 +132,6 @@ NSLogv (NSString* format, va_list args)
[myLock unlock]; [myLock unlock];
[arp release]; RELEASE(arp);
} }