mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
OSX compatibility changes and other minor tweaks
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@32279 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
ee2bbe4f71
commit
38670c0a08
5 changed files with 114 additions and 59 deletions
|
@ -1,3 +1,8 @@
|
|||
2011-02-21 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSString.m: Modified stringByStandardizingPath and
|
||||
stringByDeletingLastPathComponent to better match OSX behavior.
|
||||
|
||||
2011-02-21 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSNumberFormatter.m:
|
||||
|
|
|
@ -160,7 +160,6 @@ static IMP gs_objc_msg_forward2 (id receiver, SEL sel)
|
|||
NSMethodSignature *sig = nil;
|
||||
GSCodeBuffer *memory;
|
||||
const char *types;
|
||||
Class c = object_getClass(receiver);
|
||||
|
||||
/*
|
||||
* If we're called with a typed selector, then use this when deconstructing
|
||||
|
@ -187,27 +186,24 @@ static IMP gs_objc_msg_forward2 (id receiver, SEL sel)
|
|||
*/
|
||||
if (nil == sig)
|
||||
{
|
||||
Class c = object_getClass(receiver);
|
||||
|
||||
if (class_respondsToSelector(c, @selector(methodSignatureForSelector:)))
|
||||
{
|
||||
sig = [receiver methodSignatureForSelector: sel];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is no
|
||||
*/
|
||||
if (nil == sig &&
|
||||
(NULL != (types = GSTypesFromSelector(gs_find_best_typed_sel(sel)))))
|
||||
{
|
||||
sig = [NSMethodSignature signatureWithObjCTypes: types];
|
||||
}
|
||||
|
||||
if (nil == sig)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"%c[%s %s]: unrecognized selector sent to instance %p",
|
||||
(class_isMetaClass(c) ? '+' : '-'),
|
||||
class_getName(c), sel_getName(sel), receiver];
|
||||
if (nil == sig
|
||||
&& (NULL != (types = GSTypesFromSelector(gs_find_best_typed_sel(sel)))))
|
||||
{
|
||||
sig = [NSMethodSignature signatureWithObjCTypes: types];
|
||||
}
|
||||
if (nil == sig)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"%c[%s %s]: unrecognized selector sent to instance %p",
|
||||
(class_isMetaClass(c) ? '+' : '-'),
|
||||
class_getName(c), sel_getName(sel), receiver];
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct the frame and closure. */
|
||||
|
|
|
@ -3675,21 +3675,23 @@ static NSFileManager *fm = nil;
|
|||
|
||||
- (NSString*) stringByDeletingLastPathComponent
|
||||
{
|
||||
NSRange range;
|
||||
unsigned int l = [self length];
|
||||
unsigned int length;
|
||||
unsigned int root;
|
||||
unsigned int end;
|
||||
unsigned int i;
|
||||
|
||||
if (l == 0)
|
||||
end = length = [self length];
|
||||
if (length == 0)
|
||||
{
|
||||
return @"";
|
||||
}
|
||||
i = rootOf(self, l);
|
||||
i = root = rootOf(self, length);
|
||||
|
||||
/*
|
||||
* Any root without a trailing path separator can be deleted
|
||||
* as it's either a relative path or a tilde expression.
|
||||
*/
|
||||
if (i == l && pathSepMember([self characterAtIndex: i-1]) == NO)
|
||||
if (i == length && pathSepMember([self characterAtIndex: i-1]) == NO)
|
||||
{
|
||||
return @""; // Delete relative root
|
||||
}
|
||||
|
@ -3697,9 +3699,9 @@ static NSFileManager *fm = nil;
|
|||
/*
|
||||
* Step past trailing path separators.
|
||||
*/
|
||||
while (l > i && pathSepMember([self characterAtIndex: l-1]) == YES)
|
||||
while (end > i && pathSepMember([self characterAtIndex: end-1]) == YES)
|
||||
{
|
||||
l--;
|
||||
end--;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3707,7 +3709,7 @@ static NSFileManager *fm = nil;
|
|||
* special case of a tilde expression ... which may be deleted even
|
||||
* when it is followed by a separator.
|
||||
*/
|
||||
if (l == i)
|
||||
if (end == i)
|
||||
{
|
||||
if ([self characterAtIndex: 0] == '~')
|
||||
{
|
||||
|
@ -3715,18 +3717,47 @@ static NSFileManager *fm = nil;
|
|||
}
|
||||
return [self substringToIndex: i]; // Return root component.
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate path separator preceding last path component.
|
||||
*/
|
||||
range = [self rangeOfCharacterFromSet: pathSeps()
|
||||
options: NSBackwardsSearch
|
||||
range: ((NSRange){i, l-i})];
|
||||
if (range.length == 0)
|
||||
else
|
||||
{
|
||||
return [self substringToIndex: i];
|
||||
NSString *result;
|
||||
unichar *to;
|
||||
unsigned o;
|
||||
unsigned lastComponent = root;
|
||||
GS_BEGINITEMBUF(from, (end * 2 * sizeof(unichar)), unichar)
|
||||
|
||||
to = from + end;
|
||||
[self getCharacters: from range: NSMakeRange(0, end)];
|
||||
for (o = 0; o < root; o++)
|
||||
{
|
||||
to[o] = from[o];
|
||||
}
|
||||
for (i = root; i < end; i++)
|
||||
{
|
||||
if (pathSepMember(from[i]))
|
||||
{
|
||||
if (o > lastComponent)
|
||||
{
|
||||
to[o++] = from[i];
|
||||
lastComponent = o;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
to[o++] = from[i];
|
||||
}
|
||||
}
|
||||
if (lastComponent > root)
|
||||
{
|
||||
o = lastComponent - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
o = root;
|
||||
}
|
||||
result = [NSString stringWithCharacters: to length: o];
|
||||
GS_ENDITEMBUF();
|
||||
return result;
|
||||
}
|
||||
return [self substringToIndex: range.location];
|
||||
}
|
||||
|
||||
- (NSString*) stringByDeletingPathExtension
|
||||
|
@ -4266,7 +4297,7 @@ static NSFileManager *fm = nil;
|
|||
caiImp = (unichar (*)())[s methodForSelector: caiSel];
|
||||
|
||||
/* Remove any separators ('/') immediately after the trailing
|
||||
* separator in the rot (if any).
|
||||
* separator in the root (if any).
|
||||
*/
|
||||
if (root > 0 && YES == pathSepMember((*caiImp)(s, caiSel, root-1)))
|
||||
{
|
||||
|
@ -4308,18 +4339,23 @@ static NSFileManager *fm = nil;
|
|||
}
|
||||
r.length = l - r.location;
|
||||
}
|
||||
// Remove trailing ('.') as long as it's preceeded by a path separator.
|
||||
if (l > root && l > 1 && (*caiImp)(s, caiSel, l-1) == '.'
|
||||
|
||||
/* Remove trailing ('.') as long as it's preceeded by a path separator.
|
||||
* As a special case for OSX compatibility, we only remove the trailing
|
||||
* dot if it's not immediately after the root.
|
||||
*/
|
||||
if (l > root + 1 && (*caiImp)(s, caiSel, l-1) == '.'
|
||||
&& pathSepMember((*caiImp)(s, caiSel, l-2)) == YES)
|
||||
{
|
||||
l--;
|
||||
[s deleteCharactersInRange: NSMakeRange(l, 1)];
|
||||
}
|
||||
|
||||
// Condense ('/./') sequences.
|
||||
r = (NSRange){root, l-root};
|
||||
while ((r = [s rangeOfString: @"." options: 0 range: r]).length == 1)
|
||||
{
|
||||
if (r.location > 0
|
||||
if (r.location > 0 && r.location < l - 1
|
||||
&& pathSepMember((*caiImp)(s, caiSel, r.location-1)) == YES
|
||||
&& pathSepMember((*caiImp)(s, caiSel, r.location+1)) == YES)
|
||||
{
|
||||
|
@ -4356,11 +4392,9 @@ static NSFileManager *fm = nil;
|
|||
}
|
||||
|
||||
/*
|
||||
* For absolute paths, we must resolve symbolic links or (on MINGW)
|
||||
* For absolute paths, we must
|
||||
* remove '/../' sequences and their matching parent directories.
|
||||
*/
|
||||
#if defined(__MINGW__)
|
||||
/* Condense `/../' */
|
||||
r = (NSRange){root, l-root};
|
||||
while ((r = [s rangeOfString: @".." options: 0 range: r]).length == 2)
|
||||
{
|
||||
|
@ -4369,6 +4403,8 @@ static NSFileManager *fm = nil;
|
|||
&& (NSMaxRange(r) == l
|
||||
|| pathSepMember((*caiImp)(s, caiSel, NSMaxRange(r))) == YES))
|
||||
{
|
||||
BOOL atEnd = (NSMaxRange(r) == l) ? YES : NO;
|
||||
|
||||
r.location--;
|
||||
r.length++;
|
||||
if (r.location > root)
|
||||
|
@ -4386,7 +4422,21 @@ static NSFileManager *fm = nil;
|
|||
{
|
||||
r.length = NSMaxRange(r2) - r.location;
|
||||
}
|
||||
r.length += 3; /* Add the `/..' */
|
||||
if (YES == atEnd)
|
||||
{
|
||||
r.length += 3; /* Add the `/..' */
|
||||
}
|
||||
else
|
||||
{
|
||||
r.length += 4; /* Add the `/../' */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Don't remove the root itsself.
|
||||
*/
|
||||
r.location++;
|
||||
r.length--;
|
||||
}
|
||||
[s deleteCharactersInRange: r];
|
||||
l -= r.length;
|
||||
|
@ -4398,7 +4448,6 @@ static NSFileManager *fm = nil;
|
|||
r.length = l - r.location;
|
||||
}
|
||||
|
||||
#endif
|
||||
return IMMUTABLE(s);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,15 +5,20 @@
|
|||
* Bitmask of all of the capabilities compiled into this version of the
|
||||
* runtime.
|
||||
*/
|
||||
static const int32_t caps =
|
||||
(1<<OBJC_CAP_EXCEPTIONS) |
|
||||
(1<<OBJC_CAP_SYNCRONIZE) |
|
||||
(1<<OBJC_CAP_PROPERTIES) |
|
||||
0;
|
||||
static const int32_t caps = 0
|
||||
| (1 << OBJC_CAP_EXCEPTIONS)
|
||||
| (1 << OBJC_CAP_SYNCRONIZE)
|
||||
| (1 << OBJC_CAP_PROPERTIES);
|
||||
|
||||
int objc_test_capability(int x)
|
||||
{
|
||||
if (x >= 32) { return 0; }
|
||||
if (caps & (1<<x)) { return 1; }
|
||||
return 0;
|
||||
if (x >= 32)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (caps & (1 << x))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -137,13 +137,13 @@ int main()
|
|||
|
||||
// Not UNC
|
||||
PASS_EQUAL([@"///host/share/" stringByDeletingLastPathComponent],
|
||||
@"///host",
|
||||
"'///host/share/' stringByDeletingLastPathComponent == '///host'");
|
||||
@"/host",
|
||||
"'///host/share/' stringByDeletingLastPathComponent == '/host'");
|
||||
|
||||
// Not UNC
|
||||
PASS_EQUAL([@"//host/share" stringByDeletingLastPathComponent],
|
||||
@"//host",
|
||||
"'//host/share' stringByDeletingLastPathComponent == '//host'");
|
||||
@"/host",
|
||||
"'//host/share' stringByDeletingLastPathComponent == '/host'");
|
||||
|
||||
// Not UNC
|
||||
PASS_EQUAL([@"//dir/" stringByDeletingLastPathComponent],
|
||||
|
@ -215,8 +215,8 @@ int main()
|
|||
@"\\\\home\\user\\",
|
||||
"\\\\home\\user\\ stringByStandardizingPath == \\\\home\\user\\");
|
||||
|
||||
PASS_EQUAL([@"c:\\." stringByStandardizingPath], @"c:\\",
|
||||
"'c:\\.' stringByStandardizingPath == 'c:\\'");
|
||||
PASS_EQUAL([@"c:\\." stringByStandardizingPath], @"c:\\.",
|
||||
"'c:\\.' stringByStandardizingPath == 'c:\\.'");
|
||||
|
||||
PASS_EQUAL([@"c:\\..." stringByStandardizingPath], @"c:\\...",
|
||||
"'c:\\...' stringByStandardizingPath == 'c:\\...'");
|
||||
|
|
Loading…
Reference in a new issue