mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 08:21:25 +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
7e4a1c54de
commit
a70dd0619f
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>
|
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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue