adium 5204:92c9c36c10a3: Integrate changes from mainline AutoHyp...

commits at adium.im commits at adium.im
Sun Oct 28 01:27:11 UTC 2012


details:	http://hg.adium.im/adium/rev/92c9c36c10a3
revision:	5204:92c9c36c10a3
branch:		adium-1.6
author:		Stephen Holt <sholt at adium.im>
date:		Sat Oct 27 18:08:05 2012 -0700

Integrate changes from mainline AutoHyperlinks which fixes some issues with enclosure tracking.

Specifically, this change: http://hg.cloggedtubes.com/autohyperlinks2/changeset/5802517b0b9a38ce6c5c8f39ccad9a0f0b3ccd40

diffs (304 lines):

diff -r cc1b1e1e9bf3 -r 92c9c36c10a3 Frameworks/AutoHyperlinks Framework/Source/AHHyperlinkScanner.h
--- a/Frameworks/AutoHyperlinks Framework/Source/AHHyperlinkScanner.h	Thu Oct 25 14:50:07 2012 +0100
+++ b/Frameworks/AutoHyperlinks Framework/Source/AHHyperlinkScanner.h	Sat Oct 27 18:08:05 2012 -0700
@@ -47,7 +47,8 @@
 {
 	NSDictionary        *m_urlSchemes;
 	NSString            *m_scanString;
-#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+    NSMutableArray      *m_openEnclosureStack;
+#if TARGET_OS_IPHONE
 	NSString            *m_linkifiedString;
 #else
 	NSAttributedString  *m_scanAttrString;
@@ -59,7 +60,11 @@
 }
 
 @property (assign) unsigned long scanLocation;
+#if TARGET_OS_IPHONE
+ at property (readonly) NSString *linkifiedString;
+#else
 @property (readonly) NSAttributedString *linkifiedString;
+#endif
 
 /*!
  * @brief Allocs and inits a new lax AHHyperlinkScanner with the given NSString
diff -r cc1b1e1e9bf3 -r 92c9c36c10a3 Frameworks/AutoHyperlinks Framework/Source/AHHyperlinkScanner.m
--- a/Frameworks/AutoHyperlinks Framework/Source/AHHyperlinkScanner.m	Thu Oct 25 14:50:07 2012 +0100
+++ b/Frameworks/AutoHyperlinks Framework/Source/AHHyperlinkScanner.m	Sat Oct 27 18:08:05 2012 -0700
@@ -34,6 +34,8 @@
 #define ENC_INDEX_KEY @"encIndex"
 #define ENC_CHAR_KEY @"encChar"
 
+#define MIN_LINK_LENGTH 4
+
 @interface AHHyperlinkScanner (PRIVATE)
 - (AHMarkedHyperlink *)nextURIFromLocation:(unsigned long *)_scanLocation;
 #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
@@ -122,13 +124,14 @@
 #if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
 		m_scanAttrString = nil;
 #endif
+        m_openEnclosureStack = [[NSMutableArray alloc] init];
 	}
 	return self;
 }
 
 - (id)initWithString:(NSString *)inString usingStrictChecking:(BOOL)flag
 {
-	if((self = [super init])){
+	if((self = [self init])){
 		m_scanString = [inString retain];
 		m_urlSchemes = [[NSDictionary alloc] initWithObjectsAndKeys:
 						@"ftp://", @"ftp",
@@ -142,7 +145,7 @@
 #if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
 - (id)initWithAttributedString:(NSAttributedString *)inString usingStrictChecking:(BOOL)flag
 {
-	if((self = [super init])){
+	if((self = [self init])){
 		m_scanString = [[inString string] retain];
 		m_scanAttrString = [inString retain];
 		m_urlSchemes = [[NSDictionary alloc] initWithObjectsAndKeys:
@@ -161,6 +164,7 @@
 	[m_linkifiedString release];
 	[m_scanString release];
 	[m_urlSchemes release];
+    [m_openEnclosureStack release];
 #if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
 	if(m_scanAttrString) [m_scanAttrString release];
 #endif
@@ -253,96 +257,106 @@
 	
 	// main scanning loop
 	while([self _scanString:m_scanString upToCharactersFromSet:skipSet intoRange:&scannedRange fromIndex:&scannedLocation]) {
-		
-		// Check for and filter  enclosures.  We can't add (, [, etc. to the skipSet as they may be in a URI
-		if([enclosureSet characterIsMember:[m_scanString characterAtIndex:scannedRange.location]]){
-			unsigned long encIdx = [enclosureStartArray indexOfObject:[m_scanString substringWithRange:NSMakeRange(scannedRange.location, 1)]];
-			NSRange encRange;
-			if(NSNotFound != encIdx) {
-				encRange = [m_scanString rangeOfString:[enclosureStopArray objectAtIndex:encIdx] options:NSBackwardsSearch range:scannedRange];
-				if(NSNotFound != encRange.location){
-					scannedRange.location++; scannedRange.length -= 2;
-				}
-			}
-		}
-		if(!scannedRange.length) break;
-		
-		// Find balanced enclosure chars
-		NSRange longestEnclosure = [self _longestBalancedEnclosureInRange:scannedRange];
-		while (scannedRange.length > 2 && [endSet characterIsMember:[m_scanString characterAtIndex:(scannedRange.location + scannedRange.length - 1)]]) {
-			if((longestEnclosure.location + longestEnclosure.length) < scannedRange.length){
-				scannedRange.length--;
-			}else break;
-		}
-		
-        // if we have a valid URL then save the scanned string, and make a SHMarkedHyperlink out of it.
-        // this way, we can preserve things like the matched string (to be converted to a NSURL),
-        // parent string, its validation status (valid, file, degenerate, etc), and its range in the parent string
-		AH_URI_VERIFICATION_STATUS	 validStatus;
-		NSString					*_scanString = nil;
-		unsigned long				 schemeLength = 0;
-		if(4 < scannedRange.length) _scanString = [m_scanString substringWithRange:scannedRange];
-        if((4 < scannedRange.length) && [[self class] isStringValidURI:_scanString usingStrict:m_strictChecking fromIndex:&m_scanLocation withStatus:&validStatus schemeLength:&schemeLength]){
-            AHMarkedHyperlink	*markedLink;
-			BOOL				 makeLink = TRUE;
-            //insert typical specifiers if the URL is degenerate
-            switch(validStatus){
-                case AH_URL_DEGENERATE:
-                {
-                    NSString *scheme = DEFAULT_URL_SCHEME;
-					unsigned long i = 0;
-					
-                    NSRange  firstComponent;
-					[self		  _scanString:_scanString
-				   upToCharactersFromSet:hostnameComponentSeparatorSet
-							   intoRange:&firstComponent
-							   fromIndex:&i];
-					
-                    if(NSNotFound != firstComponent.location) {
-                    	NSString *hostnameScheme = [m_urlSchemes objectForKey:[_scanString substringWithRange:firstComponent]];
-                    	if(hostnameScheme) scheme = hostnameScheme;
+        if (MIN_LINK_LENGTH < scannedRange.length) {
+            // Check for and filter  enclosures.  We can't add (, [, etc. to the skipSet as they may be in a URI
+            NSString *topEncChar = [m_openEnclosureStack lastObject];
+            if(topEncChar || [enclosureSet characterIsMember:[m_scanString characterAtIndex:scannedRange.location]]){
+                unsigned long encIdx = [enclosureStartArray indexOfObject:topEncChar? topEncChar : [m_scanString substringWithRange:NSMakeRange(scannedRange.location, 1)]];
+                NSRange encRange;
+                if(NSNotFound != encIdx) {
+                    encRange = [m_scanString rangeOfString:[enclosureStopArray objectAtIndex:encIdx] options:NSBackwardsSearch range:scannedRange];
+                    if(NSNotFound != encRange.location){
+                         scannedRange.length--;
+                        if (topEncChar) {
+                            [m_openEnclosureStack removeLastObject];
+                        } else {
+                            scannedRange.location++;
+                            scannedRange.length--;
+                        }
+                    } else {
+                        [m_openEnclosureStack addObject:[enclosureStartArray objectAtIndex:encIdx]];
                     }
-					
-                    _scanString = [scheme stringByAppendingString:_scanString];
-					
-                    break;
                 }
-					
-                case AH_MAILTO_DEGENERATE:
-					_scanString = [@"mailto:" stringByAppendingString:_scanString];
-                    break;
-				case AH_URL_TENTATIVE:
-				{
-					NSString *scheme = [_scanString substringToIndex:schemeLength];
-					NSArray *apps = (NSArray *)LSCopyAllHandlersForURLScheme((CFStringRef)scheme);
-
-					if(!apps.count)
-						makeLink = FALSE;
-					[apps release];
-					break;
-				}
-                default:
-                    break;
+            }
+            if(!scannedRange.length) break;
+            
+            // Find balanced enclosure chars
+            NSRange longestEnclosure = [self _longestBalancedEnclosureInRange:scannedRange];
+            while (scannedRange.length > 2 && [endSet characterIsMember:[m_scanString characterAtIndex:(scannedRange.location + scannedRange.length - 1)]]) {
+                if((longestEnclosure.location + longestEnclosure.length) < scannedRange.length){
+                    scannedRange.length--;
+                }else break;
             }
             
-			if(makeLink){
-				//make a marked link
-				markedLink = [[AHMarkedHyperlink alloc] initWithString:_scanString
-												  withValidationStatus:validStatus
-														  parentString:m_scanString
-															  andRange:scannedRange];
-				return [markedLink autorelease];
-			}
+            // if we have a valid URL then save the scanned string, and make a SHMarkedHyperlink out of it.
+            // this way, we can preserve things like the matched string (to be converted to a NSURL),
+            // parent string, its validation status (valid, file, degenerate, etc), and its range in the parent string
+            AH_URI_VERIFICATION_STATUS	 validStatus;
+            NSString					*_scanString = nil;
+            unsigned long				 schemeLength = 0;
+            if(MIN_LINK_LENGTH < scannedRange.length) _scanString = [m_scanString substringWithRange:scannedRange];
+            if((MIN_LINK_LENGTH < scannedRange.length) && [[self class] isStringValidURI:_scanString usingStrict:m_strictChecking fromIndex:&m_scanLocation withStatus:&validStatus schemeLength:&schemeLength]){
+                AHMarkedHyperlink	*markedLink;
+                BOOL				 makeLink = TRUE;
+                //insert typical specifiers if the URL is degenerate
+                switch(validStatus){
+                    case AH_URL_DEGENERATE:
+                    {
+                        NSString *scheme = DEFAULT_URL_SCHEME;
+                        unsigned long i = 0;
+                        
+                        NSRange  firstComponent;
+                        [self		  _scanString:_scanString
+                       upToCharactersFromSet:hostnameComponentSeparatorSet
+                                   intoRange:&firstComponent
+                                   fromIndex:&i];
+                        
+                        if(NSNotFound != firstComponent.location) {
+                            NSString *hostnameScheme = [m_urlSchemes objectForKey:[_scanString substringWithRange:firstComponent]];
+                            if(hostnameScheme) scheme = hostnameScheme;
+                        }
+                        
+                        _scanString = [scheme stringByAppendingString:_scanString];
+                        
+                        break;
+                    }
+                        
+                    case AH_MAILTO_DEGENERATE:
+                        _scanString = [@"mailto:" stringByAppendingString:_scanString];
+                        break;
+                    case AH_URL_TENTATIVE:
+                    {
+                        NSString *scheme = [_scanString substringToIndex:schemeLength];
+                        NSArray *apps = (NSArray *)LSCopyAllHandlersForURLScheme((CFStringRef)scheme);
+
+                        if(!apps.count)
+                            makeLink = FALSE;
+                        [apps release];
+                        break;
+                    }
+                    default:
+                        break;
+                }
+                
+                if(makeLink){
+                    //make a marked link
+                    markedLink = [[AHMarkedHyperlink alloc] initWithString:_scanString
+                                                      withValidationStatus:validStatus
+                                                              parentString:m_scanString
+                                                                  andRange:scannedRange];
+                    return [markedLink autorelease];
+                }
+            }
+            
+            //step location after scanning a string
+            NSRange startRange = [m_scanString rangeOfCharacterFromSet:puncSet options:NSLiteralSearch range:scannedRange];
+            if (startRange.location != NSNotFound)
+                m_scanLocation = startRange.location + startRange.length;
+            else
+                m_scanLocation += scannedRange.length;
+            
+            scannedLocation = m_scanLocation;
         }
-		
-		//step location after scanning a string
-		NSRange startRange = [m_scanString rangeOfCharacterFromSet:puncSet options:NSLiteralSearch range:scannedRange];
-		if (startRange.location != NSNotFound)
-			m_scanLocation = startRange.location + startRange.length;
-		else
-			m_scanLocation += scannedRange.length;
-		
-		scannedLocation = m_scanLocation;
     }
 	
     // if we're here, then NSScanner hit the end of the string
diff -r cc1b1e1e9bf3 -r 92c9c36c10a3 Frameworks/AutoHyperlinks Framework/Source/AHLinkLexer.l
--- a/Frameworks/AutoHyperlinks Framework/Source/AHLinkLexer.l	Thu Oct 25 14:50:07 2012 +0100
+++ b/Frameworks/AutoHyperlinks Framework/Source/AHLinkLexer.l	Sat Oct 27 18:08:05 2012 -0700
@@ -54,7 +54,7 @@
 %{
 /*The Unicode standard, version 4.1, table 3-6, says that the highest byte that will occur in a valid UTF-8 sequence is 0xF4.*/
 %}
-userAndPass     [^:@]+(:[^:@]+)?
+userAndPass     [^:@[:space:]]+(:[^:@[:space:]]+)?
 singleDomain    [_[:alnum:]\x80-\xf4-]+
 
 urlPath         \/[^[:space:]]*
@@ -74,7 +74,7 @@
 userAtDomain	[^:@\/[:space:]]+\@{singleDomain}(\.{singleDomain})*
 mailSpec        {userAtDomain}\.{TLDs}
 
-%option noyywrap nounput noinput 8bit caseless never-interactive reentrant warn prefix="AH"
+%option noyywrap nounput noinput 8bit caseless align nodefault never-interactive reentrant warn prefix="AH"
 
 %x CANONICAL TENTATIVE
 %%
diff -r cc1b1e1e9bf3 -r 92c9c36c10a3 Frameworks/AutoHyperlinks Framework/UnitTests/HyperlinkContextTest.m
--- a/Frameworks/AutoHyperlinks Framework/UnitTests/HyperlinkContextTest.m	Thu Oct 25 14:50:07 2012 +0100
+++ b/Frameworks/AutoHyperlinks Framework/UnitTests/HyperlinkContextTest.m	Sat Oct 27 18:08:05 2012 -0700
@@ -13,7 +13,7 @@
 	AHHyperlinkScanner	*scanner = [AHHyperlinkScanner hyperlinkScannerWithString:testString];
 	AHMarkedHyperlink	*ahLink = [scanner nextURI];
 	
-	STAssertNotNil(ahLink.URL, @"-[SHHyperlinkScanner nextURL] found no URI in \"%@\"", testString);
+	STAssertNotNil(ahLink, @"-[SHHyperlinkScanner nextURL] found no URI in \"%@\"", testString);
 	STAssertEqualObjects([[ahLink parentString] substringWithRange:[ahLink range]], URIString, @"in context: '%@'", testString);
 }
 
@@ -218,6 +218,8 @@
 	[self testLaxContext:@"foo (bar) %@" withURI:@"http://example.com/path/to/url.html"];
 	
 	[self testLaxContext:@"%@ doesn't link." withURI:@"http://developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW3"];
+    [self testLaxContext:@"foo (bar: %@)" withURI:@"http://example.com/path/to/url_(other)"];
+    [self testLaxContext:@"foo [bar: %@]" withURI:@"http://example.com/path/to/url_(other)"];
 }
 
 - (void)testCompositeContext {




More information about the commits mailing list