String fixes from stevo.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2685 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Adam Fedor 1998-01-08 15:25:59 +00:00
parent 2c49c63e47
commit 690a304f1a
17 changed files with 651 additions and 142 deletions

View file

@ -58,7 +58,8 @@ FILE_AUTHORS = \
"Scott Christley" \
"Luke Howard" \
"Yoo C. Chung" \
"Richard Frith-Macdonald"
"Richard Frith-Macdonald" \
"Stevo Crvenkovski"
# The GNU source files
@ -80,6 +81,7 @@ DelegatePool.m \
Dictionary.m \
Encoder.m \
GapArray.m \
GetDefEncoding.m \
Heap.m \
IndexedCollection.m \
Invocation.m \
@ -189,6 +191,7 @@ Dictionary.h \
Enumerating.h \
GapArray.h \
GapArrayPrivate.h \
GetDefEncoding.h \
Heap.h \
IndexedCollecting.h \
IndexedCollection.h \

130
Source/GetDefEncoding.m Normal file
View file

@ -0,0 +1,130 @@
/* Function to determine default c string encoding for
GNUstep based on GNUSTEP_STRING_ENCODING environment variable.
Copyright (C) 1997 Free Software Foundation, Inc.
Written by: Stevo Crvenkovski <stevo@btinternet.com>
Date: December 1997
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <Foundation/NSString.h>
#include <Foundation/NSBundle.h>
struct _strenc_ {NSStringEncoding enc; char *ename;};
const unsigned int str_encoding_table_size = 17;
const struct _strenc_ str_encoding_table[]=
{
{NSASCIIStringEncoding,"NSASCIIStringEncoding"},
{NSNEXTSTEPStringEncoding,"NSNEXTSTEPStringEncoding"},
{NSJapaneseEUCStringEncoding, "NSJapaneseEUCStringEncoding"},
{NSISOLatin1StringEncoding,"NSISOLatin1StringEncoding"},
{NSCyrillicStringEncoding,"NSCyrillicStringEncoding"},
{NSUTF8StringEncoding,"NSUTF8StringEncoding"},
{NSSymbolStringEncoding,"NSSymbolStringEncoding"},
{NSNonLossyASCIIStringEncoding,"NSNonLossyASCIIStringEncoding"},
{NSShiftJISStringEncoding,"NSShiftJISStringEncoding"},
{NSISOLatin2StringEncoding,"NSISOLatin2StringEncoding"},
{NSWindowsCP1251StringEncoding,"NSWindowsCP1251StringEncoding"},
{NSWindowsCP1252StringEncoding,"NSWindowsCP1252StringEncoding"},
{NSWindowsCP1253StringEncoding,"NSWindowsCP1253StringEncoding"},
{NSWindowsCP1254StringEncoding,"NSWindowsCP1254StringEncoding"},
{NSWindowsCP1250StringEncoding,"NSWindowsCP1250StringEncoding"},
{NSISO2022JPStringEncoding,"NSISO2022JPStringEncoding "},
{NSUnicodeStringEncoding, "NSUnicodeStringEncoding"}
};
NSStringEncoding GetDefEncoding()
{
char *encoding;
unsigned int count;
NSStringEncoding ret,tmp;
encoding = getenv("GNUSTEP_STRING_ENCODING");
if(encoding)
{
count=0;
while((count<str_encoding_table_size)&
strcmp(str_encoding_table[count].ename,encoding))
{
count++;
}
if(!(count==str_encoding_table_size))
{
ret= str_encoding_table[count].enc;
if((ret==NSUnicodeStringEncoding) ||
(ret==NSSymbolStringEncoding))
{
fprintf(stderr, "WARNING: %s - encoding not supported as default c string encoding.\n", encoding);
fprintf(stderr, "NSASCIIStringEncoding set as default.\n");
ret=NSASCIIStringEncoding;
}
else /*encoding should be supported but is it implemented?*/
{
count=0;
tmp=0;
while(!(_availableEncodings[count]==0))
{
if(!(ret==_availableEncodings[count]))
tmp=0;
else
tmp=ret;
count++;
};
if(!tmp)
{
fprintf(stderr, "WARNING: %s - encoding not yet implemented.\n", encoding);
fprintf(stderr, "NSASCIIStringEncoding set as default.\n");
ret=NSASCIIStringEncoding;
};
};
}
else /* encoding not found */
{
fprintf(stderr, "WARNING: %s - encoding not supported.\n", encoding);
fprintf(stderr, "NSASCIIStringEncoding set as default.\n");
ret=NSASCIIStringEncoding;
}
}
else /* envirinment var not found */
{
fprintf(stderr,"WARNING: GNUSTEP_STRING_ENCODING environment variable not found\n");
fprintf(stderr, "NSASCIIStringEncoding set as default.\n");
ret=NSASCIIStringEncoding;
}
return ret;
};
NSString*
GetEncodingName(NSStringEncoding encoding)
{
char* ret;
unsigned int count=0;
while((count<str_encoding_table_size)&
!(str_encoding_table[count].enc == encoding))
{
count++;
}
if(!(count==str_encoding_table_size))
ret= str_encoding_table[count].ename;
else ret="Unknown encoding";
return [NSString stringWithCString:ret];
};

View file

@ -49,11 +49,11 @@
length: (unsigned int)length
freeWhenDone: (BOOL)flag
{
/* assert(!flag); xxx need to make a subclass to handle this. */
/* assert(!flag); xxx need to make a subclass to handle this. */
[super init];
_count = length;
_contents_chars = byteString;
_free_contents = flag;
[super init];
return self;
}
@ -271,12 +271,12 @@ stringDecrementCountAndFillHoleAt(NSGMutableCStringStruct *self,
/* xxx Should capacity include the '\0' terminator? */
- initWithCapacity: (unsigned)capacity
{
[super init];
_count = 0;
_capacity = MAX(capacity, 2);
OBJC_MALLOC(_contents_chars, char, _capacity);
_contents_chars[0] = '\0';
_free_contents = YES;
[super init];
return self;
}
@ -352,11 +352,11 @@ stringDecrementCountAndFillHoleAt(NSGMutableCStringStruct *self,
length: (unsigned int)length
freeWhenDone: (BOOL)flag
{
[super init];
_count = length;
_capacity = length+1;
_contents_chars = byteString;
_free_contents = flag;
[super init];
return self;
}

View file

@ -1,7 +1,7 @@
/* Implementation of composite character sequence class for GNUSTEP
Copyright (C) 1997 Free Software Foundation, Inc.
Written by: Stevo Crvenkovski
Written by: Stevo Crvenkovski <stevo@btinternet.com>
Date: March 1997
This file is part of the GNUstep Base Library.
@ -275,13 +275,14 @@
unichar *first,*second,tmp;
int count,len;
BOOL notdone;
len=[self length];
if(len>1)
do
{
notdone=NO;
first=_contents_chars;
second=first+1;
len=[self length];
for(count=1;count<len;count++)
{
if(uni_cop(*second))

View file

@ -1,7 +1,7 @@
/* Implementation for GNUStep of NSStrings with Unicode-string backing
Copyright (C) 1997 Free Software Foundation, Inc.
Written by Stevo Crvenkovski <stevoc@lotus.mpt.com.mk>
Written by Stevo Crvenkovski <stevo@btinternet.com>
Date: February 1997
Based on NSGCSting and NSString
@ -63,10 +63,10 @@
freeWhenDone: (BOOL)flag
{
/* assert(!flag); xxx need to make a subclass to handle this. */
[super init];
_count = length;
_contents_chars = chars;
_free_contents = flag;
[super init];
return self;
}
@ -318,6 +318,7 @@ stringDecrementCountAndFillHoleAt(NSGMutableStringStruct *self,
// xxx Should capacity include the '\0' terminator?
- initWithCapacity: (unsigned)capacity
{
[super init];
_count = 0;
_capacity = MAX(capacity, 2);
OBJC_MALLOC(_contents_chars, unichar, _capacity);
@ -406,11 +407,11 @@ stringDecrementCountAndFillHoleAt(NSGMutableStringStruct *self,
length: (unsigned int)length
freeWhenDone: (BOOL)flag
{
[super init];
_count = length;
_capacity = length+1;
_contents_chars = chars;
_free_contents = flag;
[super init];
return self;
}

View file

@ -4,8 +4,7 @@
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: January 1995
Unicode implementation by Stevo Crvenkovski
<stevoc@lotus.mpt.com.mk>
Unicode implementation by Stevo Crvenkovski <stevo@btinternet.com>
Date: February 1997
This file is part of the GNUstep Base Library.
@ -49,6 +48,7 @@
#include <Foundation/NSUserDefaults.h>
#include <gnustep/base/IndexedCollection.h>
#include <Foundation/NSData.h>
#include <Foundation/NSBundle.h>
#include <gnustep/base/IndexedCollectionPrivate.h>
#include <limits.h>
#include <string.h> // for strstr()
@ -63,15 +63,9 @@
#include <gnustep/base/NSGSequence.h>
#include <gnustep/base/Unicode.h>
#include <gnustep/base/GetDefEncoding.h>
// Choose default encoding
// xxx Should be install time option, not compile time
#define DEFAULT_ENCODING NSNEXTSTEPStringEncoding
// #define DEFAULT_ENCODING NSASCIIStringEncoding
// #define DEFAULT_ENCODING NSISOLatin1StringEncoding
// #define DEFAULT_ENCODING NSCyrillicStringEncoding
#if defined(__WIN32__) || defined(_WIN32)
#define PATH_COMPONENT @"\\"
@ -96,6 +90,9 @@ static Class NSMutableString_concrete_class;
static Class NSString_c_concrete_class;
static Class NSMutableString_c_concrete_class;
static NSStringEncoding _DefaultStringEncoding;
+ (void) _setConcreteClass: (Class)c
{
NSString_concrete_class = c;
@ -199,6 +196,7 @@ handle_printf_atsign (FILE *stream,
{
if (self == [NSString class])
{
_DefaultStringEncoding = GetDefEncoding();
NSString_concrete_class = [NSGString class];
NSString_c_concrete_class = [NSGCString class];
NSMutableString_concrete_class = [NSGMutableString class];
@ -480,15 +478,12 @@ handle_printf_atsign (FILE *stream,
|| (encoding==NSASCIIStringEncoding))
{
char *s;
int count;
int len=[data length];
const char *b=[data bytes];
OBJC_MALLOC(s, char, len+1);
for(count=0;count<len;count++)
s[count]=b[count];
s[count]=0;
return [self initWithCStringNoCopy:s length:count freeWhenDone:YES];
[data getBytes:s];
s[len]=0;
return [self initWithCStringNoCopy:s length:len freeWhenDone:YES];
}
else
{
@ -499,14 +494,16 @@ handle_printf_atsign (FILE *stream,
const unsigned char *b=[data bytes];
OBJC_MALLOC(u, unichar, len+1);
count=len/2;
if(encoding==NSUnicodeStringEncoding)
{
if((b[0]==0xFE)&(b[1]==0xFF))
for(count=0;count<len;count+=2)
u[count/2]=256*b[count]+b[count+1];
for(count=2;count<(len-1);count+=2)
u[count/2 - 1]=256*b[count]+b[count+1];
else
for(count=0;count<len;count+=2)
u[count/2]=256*b[count+1]+b[count];
for(count=2;count<(len-1);count+=2)
u[count/2 -1]=256*b[count+1]+b[count];
count = count/2 -1;
}
else
count = encode_strtoustr(u,b,len,encoding);
@ -517,49 +514,18 @@ handle_printf_atsign (FILE *stream,
}
- (id) initWithContentsOfFile: (NSString*)path
{
/* xxx Maybe this should use StdioStream? */
#if defined(__WIN32__) || defined(_WIN32)
NSMutableString *s = [NSMutableString stringWithCString:""];
DWORD dwread;
char bytes[1024];
BOOL res, done = NO;
HANDLE fd = CreateFile([path cString], GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
if (fd == -1)
return nil;
{
unsigned char *buff;
NSStringEncoding enc;
id d = [NSData dataWithContentsOfFile: path];
const unsigned char *test=[d bytes];
unsigned int len = [d length];
while (!done)
{
res = ReadFile(fd, bytes, 1023, &dwread, NULL);
bytes[dwread] = '\0';
if ((res) && (dwread == 0))
done = YES;
else
[s appendString: [NSString stringWithCString: bytes]];
}
CloseHandle(fd);
[self initWithString: s];
[s release];
return self;
#else
int fd = open([path cString], O_RDONLY);
struct stat fstat_buf;
char* bytes = NULL;
if((fd == -1) || (fstat(fd, &fstat_buf) == -1))
return nil;
OBJC_MALLOC(bytes, char, fstat_buf.st_size + 1);
if (read(fd, bytes, fstat_buf.st_size) != fstat_buf.st_size) {
OBJC_FREE(bytes);
return nil;
}
close(fd);
bytes[fstat_buf.st_size] = '\0';
return [self initWithCStringNoCopy:bytes length:fstat_buf.st_size
freeWhenDone:YES];
#endif
if(((test[0]==0xFF) && (test[1]==0xFE)) || ((test[1]==0xFF) && (test[0]==0xFE)))
enc = NSUnicodeStringEncoding;
else
enc = [NSString defaultCStringEncoding];
return [self initWithData:d encoding:enc];
}
- (id) init
@ -1456,24 +1422,103 @@ else
- (unsigned int) hash
{
#define MAXDEC 18
unsigned ret = 0;
unsigned ctr = 0;
unsigned char_count = 0;
unichar *s,*p;
unichar *source,*p;
id g = [self _normalizedString];
int len = [g length];
OBJC_MALLOC(s, unichar, len + 1);
[g getCharacters: s];
s[len]=(unichar)0;
p = s;
unichar *target;
unichar *spoint;
unichar *tpoint;
unichar *dpoint;
BOOL notdone;
unichar *first,*second,tmp;
int count,len2;
int len = [self length];
if (len)
{
if(len > NSHashStringLength)
len = NSHashStringLength;
OBJC_MALLOC(source, unichar, len*MAXDEC + 1);
[self getCharacters: source range:NSMakeRange(0,len)];
source[len]=(unichar)0;
// decompose
OBJC_MALLOC(target, unichar, len*MAXDEC+1);
spoint = source;
tpoint = target;
do
{
notdone=NO;
do
{
if(!(dpoint=uni_is_decomp(*spoint)))
*tpoint++ = *spoint;
else
{
while(*dpoint)
*tpoint++=*dpoint++;
notdone=YES;
}
} while(*spoint++);
*tpoint=(unichar)0;
memcpy(source, target,2*(len*MAXDEC+1));
tpoint = target;
spoint = source;
} while(notdone);
OBJC_FREE(target);
// order
len2 = uslen(source);
if(len2>1)
do
{
notdone=NO;
first=source;
second=first+1;
for(count=1;count<len2;count++)
{
if(uni_cop(*second))
{
if(uni_cop(*first)>uni_cop(*second))
{
tmp= *first;
*first= *second;
*second=tmp;
notdone=YES;
}
if(uni_cop(*first)==uni_cop(*second))
if(*first>*second)
{
tmp= *first;
*first= *second;
*second=tmp;
notdone=YES;
}
}
first++;
second++;
}
} while(notdone);
p = source;
while (*p && char_count++ < NSHashStringLength)
{
ret ^= *p++ << ctr;
ctr = (ctr + 1) % sizeof (void*);
}
OBJC_FREE(s);
OBJC_FREE(source);
return ret;
}
else
return 0;
}
// Getting a Shared Prefix
@ -1590,27 +1635,168 @@ else
}
}
- (NSRange)lineRangeForRange:(NSRange)aRange
{
unsigned int startIndex;
unsigned int lineEndIndex;
[self getLineStart: &startIndex
end: &lineEndIndex
contentsEnd: NULL
forRange:aRange];
return NSMakeRange(startIndex, lineEndIndex - startIndex);
}
- (void)getLineStart:(unsigned int *)startIndex
end:(unsigned int *)lineEndIndex
contentsEnd:(unsigned int *)contentsEndIndex
forRange:(NSRange)aRange
{
unichar thischar;
BOOL done;
unsigned int start, end, len;
if (aRange.location > [self length])
[NSException raise: NSRangeException format:@"Invalid location."];
if (aRange.length > ([self length] - aRange.location))
[NSException raise: NSRangeException format:@"Invalid location+length."];
len = [self length];
start=aRange.location;
if(startIndex)
if(start==0)
*startIndex=0;
else
{
start--;
while(start>0)
{
BOOL done = NO;
thischar = [self characterAtIndex:start];
switch(thischar)
{
case (unichar)0x000A:
case (unichar)0x000D:
case (unichar)0x2028:
case (unichar)0x2029:
done = YES;
break;
default:
start--;
break;
};
if(done)
break;
};
if(start == 0)
{
thischar = [self characterAtIndex:start];
switch(thischar)
{
case (unichar)0x000A:
case (unichar)0x000D:
case (unichar)0x2028:
case (unichar)0x2029:
start++;
break;
default:
break;
};
}
else
start++;
*startIndex=start;
};
if(lineEndIndex || contentsEndIndex)
{
end=aRange.location+aRange.length;
while(end<len)
{
BOOL done = NO;
thischar = [self characterAtIndex:end];
switch(thischar)
{
case (unichar)0x000A:
case (unichar)0x000D:
case (unichar)0x2028:
case (unichar)0x2029:
done = YES;
break;
default:
break;
};
end++;
if(done)
break;
};
if(end<len)
{
if([self characterAtIndex:end]==(unichar)0x000D)
if([self characterAtIndex:end+1]==(unichar)0x000A)
*lineEndIndex = end+1;
else *lineEndIndex = end;
else *lineEndIndex = end;
}
else
*lineEndIndex = end;
};
if(contentsEndIndex)
{
if(end<len)
{
*contentsEndIndex= end-1;
}
else
/* xxx OPENSTEP documentation does not say what to do if last
line is not terminated. Assume this */
*contentsEndIndex= end;
};
}
// Changing Case
// xxx There is more than this in word capitalization in Unicode,
// but this will work in most cases
// xxx fix me - consider tab, newline and friends
- (NSString*) capitalizedString
{
unichar *s;
int count=0;
BOOL found=YES;
int len=[self length];
id white = [NSCharacterSet whitespaceAndNewlineCharacterSet];
OBJC_MALLOC(s, unichar,len +1);
s[0]=uni_toupper([self characterAtIndex:0]);
[self getCharacters:s];
while(count<len)
{
while((!([self characterAtIndex: count++]==' '))&(count<len))
s[count]=uni_tolower([self characterAtIndex:count]);
if(count<len)
s[count]=uni_toupper([self characterAtIndex:count]);
}
s[len] = (unichar)0;
return [NSString stringWithCharacters:s length:len];
if([white characterIsMember:s[count]])
{
count++;
found=YES;
while([white characterIsMember:s[count]]&(count<len))
count++;
};
if(found)
{
s[count]=uni_toupper(s[count]);
count++;
}
else
{
while(![white characterIsMember:s[count]]&(count<len))
{
s[count]=uni_tolower(s[count]);
count++;
};
};
found=NO;
};
s[count] = (unichar)0;
return [[[NSString alloc] initWithCharactersNoCopy:s length:len freeWhenDone:YES] autorelease];
}
- (NSString*) lowercaseString
@ -1735,7 +1921,31 @@ else
+ (NSStringEncoding) defaultCStringEncoding
{
return DEFAULT_ENCODING;
return _DefaultStringEncoding;
}
+ (NSStringEncoding*)availableStringEncodings
{
return _availableEncodings;
}
+ (NSString*)localizedNameOfStringEncoding:(NSStringEncoding)encoding
{
id ourbundle;
id ourname;
/*
Should be path to localizable.strings file.
Until we have it, just make shure that bundle
is initialized.
*/
ourbundle = [NSBundle bundleWithPath:@"/"];
ourname = GetEncodingName(encoding);
return [ourbundle
localizedStringForKey:ourname
value:ourname
table:nil];
}
- (BOOL) canBeConvertedToEncoding: (NSStringEncoding)encoding
@ -1753,7 +1963,6 @@ else
- (NSData*) dataUsingEncoding: (NSStringEncoding)encoding
allowLossyConversion: (BOOL)flag
{
unsigned char *buff="";
int count=0;
int len = [self length];
@ -1764,6 +1973,7 @@ else
|| (encoding==NSSymbolStringEncoding)
|| (encoding==NSCyrillicStringEncoding))
{
unsigned char *buff;
char t;
OBJC_MALLOC(buff, char, len+1);
for(count=0; count<len; count++)
@ -1790,19 +2000,22 @@ else
buff[count] = '*';
};
buff[count]=0;
return [NSData dataWithBytes: (char *)buff length: count];
}
else
if(encoding==NSUnicodeStringEncoding)
{
OBJC_MALLOC((unichar*)buff, unichar, len+2);
(unichar)buff[0]=0xFEFF;
unichar *buff;
OBJC_MALLOC(buff, unichar, len+2);
buff[0]=0xFEFF;
for(count=0; count<len; count++)
(unichar)buff[count]=[self characterAtIndex: count];
(unichar)buff[count]= (unichar)0;
buff[count+1]=[self characterAtIndex: count];
buff[count+1]= (unichar)0;
return [NSData dataWithBytes: (char *)buff length: 2*(count+1)];
}
else /* UTF8 or EUC */
[self notImplemented:_cmd];
return [NSData dataWithBytes: (char *)buff length: count];
return nil;
}
- (NSStringEncoding) fastestEncoding
@ -2168,9 +2381,10 @@ else
- (BOOL) writeToFile: (NSString*)filename
atomically: (BOOL)useAuxiliaryFile
{
id d = [self dataUsingEncoding: NSUnicodeStringEncoding allowLossyConversion: NO];
return [d writeToFile: filename
atomically: useAuxiliaryFile];
id d;
if(!(d = [self dataUsingEncoding:[NSString defaultCStringEncoding]]))
d = [self dataUsingEncoding: NSUnicodeStringEncoding];
return [d writeToFile: filename atomically: useAuxiliaryFile];
}
// #endif

View file

@ -1,7 +1,7 @@
/* Support functions for Unicode implementation
Copyright (C) 1997 Free Software Foundation, Inc.
Written by: Stevo Crvenkovski <stevoc@lotus.mpt.com.mk>
Written by: Stevo Crvenkovski <stevo@btinternet.com>
Date: March 1997
This file is part of the GNUstep Base Library.