Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -873,10 +873,17 @@ * * @return The last component of the path */ - (OFString*)lastPathComponent; +/*! + * @brief Returns the file extension of the path. + * + * @return The file extension of the path + */ +- (OFString*)pathExtension; + /*! * @brief Returns the directory name of the path. * * @return The directory name of the path */ Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -2092,10 +2092,30 @@ if (i < 0) i = 0; return [self substringWithRange: of_range(i, length - i)]; } + +- (OFString*)pathExtension +{ + void *pool = objc_autoreleasePoolPush(); + OFString *ret, *fileName; + size_t pos; + + fileName = [self lastPathComponent]; + pos = [fileName rangeOfString: @"." + options: OF_STRING_SEARCH_BACKWARDS].location; + if (pos == OF_NOT_FOUND || pos == 0) + return @""; + + ret = [fileName substringWithRange: + of_range(pos + 1, [fileName length] - pos - 1)]; + + [ret retain]; + objc_autoreleasePoolPop(pool); + return [ret autorelease]; +} - (OFString*)stringByDeletingLastPathComponent { void *pool; const of_unichar_t *characters; @@ -2172,11 +2192,10 @@ ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); - return [ret autorelease]; } - (OFString*)stringByStandardizingPath { Index: tests/OFStringTests.m ================================================================== --- tests/OFStringTests.m +++ tests/OFStringTests.m @@ -327,10 +327,16 @@ [[@"/" lastPathComponent] isEqual: @""] && [[@"foo" lastPathComponent] isEqual: @"foo"] && [[@"foo/bar" lastPathComponent] isEqual: @"bar"] && [[@"foo/bar/baz/" lastPathComponent] isEqual: @"baz"]) + TEST(@"-[pathExtension]", + [[@"foo.bar" pathExtension] isEqual: @"bar"] && + [[@"foo/.bar" pathExtension] isEqual: @""] && + [[@"foo/.bar.baz" pathExtension] isEqual: @"baz"] && + [[@"foo/bar.baz/" pathExtension] isEqual: @"baz"]) + TEST(@"-[stringByDeletingLastPathComponent]", [[@"/tmp" stringByDeletingLastPathComponent] isEqual: @"/"] && [[@"/tmp/" stringByDeletingLastPathComponent] isEqual: @"/"] && [[@"/tmp/foo/" stringByDeletingLastPathComponent] isEqual: @"/tmp"] &&