Handle unicode in C string property lists.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@9747 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2001-04-30 05:38:03 +00:00
parent ed81edb18f
commit 1037eba204
2 changed files with 85 additions and 29 deletions

View file

@ -1,3 +1,10 @@
2001-04-30 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSString.m: parseQuotedString() handle \U escape sequences
of eight digit hex encoded unicode values.
([descriptionWithLocale:indent:to@]) handle unicode strings by using
\U escape sequences in output C string.
2000-04-28 Fred Kiefer <FredKiefer@gmx.de> 2000-04-28 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSString.m: * Source/NSString.m:

View file

@ -3092,7 +3092,9 @@ handle_printf_atsign (FILE *stream,
indent: (unsigned)level indent: (unsigned)level
to: (id<GNUDescriptionDestination>)output to: (id<GNUDescriptionDestination>)output
{ {
if ([self length] == 0) unsigned length;
if ((length = [self length]) == 0)
{ {
[output appendString: @"\"\""]; [output appendString: @"\"\""];
return; return;
@ -3104,11 +3106,23 @@ handle_printf_atsign (FILE *stream,
} }
if ([self rangeOfCharacterFromSet: quotables].length > 0) if ([self rangeOfCharacterFromSet: quotables].length > 0)
{ {
const char *cstring = [self cString]; unichar tmp[length <= 1024 ? length : 0];
const char *from; unichar *ustring;
int len = 0; unichar *from;
unichar *end;
int len = 0;
for (from = cstring; *from; from++) if (length <= 1024)
{
ustring = tmp;
}
else
{
ustring = NSZoneMalloc(NSDefaultMallocZone(), length);
}
end = &ustring[length];
[self getCharacters: ustring];
for (from = ustring; from < end; from++)
{ {
switch (*from) switch (*from)
{ {
@ -3126,13 +3140,20 @@ handle_printf_atsign (FILE *stream,
break; break;
default: default:
if (isprint(*from) || *from == ' ') if (*from < 128)
{ {
len++; if (isprint(*from) || *from == ' ')
{
len++;
}
else
{
len += 4;
}
} }
else else
{ {
len += 4; len += 10;
} }
break; break;
} }
@ -3143,7 +3164,7 @@ handle_printf_atsign (FILE *stream,
char *ptr = buf; char *ptr = buf;
*ptr++ = '"'; *ptr++ = '"';
for (from = cstring; *from; from++) for (from = ustring; from < end; from++)
{ {
switch (*from) switch (*from)
{ {
@ -3159,14 +3180,22 @@ handle_printf_atsign (FILE *stream,
case '"' : *ptr++ = '\\'; *ptr++ = '"'; break; case '"' : *ptr++ = '\\'; *ptr++ = '"'; break;
default: default:
if (isprint(*from) || *from == ' ') if (*from < 128)
{ {
*ptr++ = *from; if (isprint(*from) || *from == ' ')
{
*ptr++ = *from;
}
else
{
sprintf(ptr, "\\%03o", *(unsigned char*)from);
ptr = &ptr[4];
}
} }
else else
{ {
sprintf(ptr, "\\%03o", *(unsigned char*)from); sprintf(ptr, "\\U%08x", *from);
ptr = &ptr[4]; ptr = &ptr[10];
} }
break; break;
} }
@ -3175,6 +3204,10 @@ handle_printf_atsign (FILE *stream,
*ptr = '\0'; *ptr = '\0';
[output appendString: [NSStringClass stringWithCString: buf]]; [output appendString: [NSStringClass stringWithCString: buf]];
} }
if (length > 1024)
{
NSZoneFree(NSDefaultMallocZone(), ustring);
}
} }
else else
{ {
@ -3847,28 +3880,35 @@ static inline id parseQuotedString(pldata* pld)
if (escaped) if (escaped)
{ {
if (escaped == 1 && c == '0') if (escaped == 1 && c >= '0' && c <= '7')
{ {
escaped = 2; escaped = 2;
hex = NO; hex = NO;
} }
else if (escaped == 1 && c == 'U')
{
escaped = 2;
shrink++;
hex = YES;
}
else if (escaped > 1) else if (escaped > 1)
{ {
if (escaped == 2 && c == 'x') if (hex && GS_IS_HEXDIGIT(c))
{
hex = YES;
shrink++;
escaped++;
}
else if (hex && GS_IS_HEXDIGIT(c))
{ {
shrink++; shrink++;
escaped++; escaped++;
if (escaped == 10)
{
escaped = 0;
}
} }
else if (c >= '0' && c <= '7') else if (c >= '0' && c <= '7')
{ {
shrink++; shrink++;
escaped++; if (escaped == 4)
{
escaped = 0;
}
} }
else else
{ {
@ -3920,30 +3960,39 @@ static inline id parseQuotedString(pldata* pld)
if (escaped) if (escaped)
{ {
if (escaped == 1 && c == '0') if (escaped == 1 && c >= '0' && c <= '7')
{ {
chars[k] = 0; chars[k] = 0;
hex = NO; hex = NO;
escaped++; escaped++;
} }
else if (escaped == 1 && c == 'U')
{
chars[k] = 0;
hex = YES;
escaped++;
}
else if (escaped > 1) else if (escaped > 1)
{ {
if (escaped == 2 && c == 'x') if (hex && GS_IS_HEXDIGIT(c))
{
hex = YES;
escaped++;
}
else if (hex && GS_IS_HEXDIGIT(c))
{ {
chars[k] <<= 4; chars[k] <<= 4;
chars[k] |= char2num(c); chars[k] |= char2num(c);
escaped++; escaped++;
if (escaped == 10)
{
escaped = 0;
}
} }
else if (c >= '0' && c <= '7') else if (c >= '0' && c <= '7')
{ {
chars[k] <<= 3; chars[k] <<= 3;
chars[k] |= (c - '0'); chars[k] |= (c - '0');
escaped++; escaped++;
if (escaped == 4)
{
escaped = 0;
}
} }
else else
{ {