Skip to content
Browse files

adding URLState/EmailState

  • Loading branch information...
1 parent 66e813d commit 37311564f9fab5c23fc953c819db6574a19792b0 @itod committed
View
36 ParseKit.xcodeproj/project.pbxproj
@@ -242,6 +242,16 @@
D355C8810FEB36A1006A91A4 /* xml.grammar in Resources */ = {isa = PBXBuildFile; fileRef = D355C8800FEB36A1006A91A4 /* xml.grammar */; };
D355C8840FEB4B94006A91A4 /* proto.grammar in Resources */ = {isa = PBXBuildFile; fileRef = D355C8830FEB4B94006A91A4 /* proto.grammar */; };
D3587EAF0FE83EC900DDD023 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D6A5FE840307C02AAC07 /* AppKit.framework */; };
+ D35F4A8711643630003811F3 /* PKEmailState.m in Sources */ = {isa = PBXBuildFile; fileRef = D35F4A8511643630003811F3 /* PKEmailState.m */; };
+ D35F4A8811643630003811F3 /* PKURLState.m in Sources */ = {isa = PBXBuildFile; fileRef = D35F4A8611643630003811F3 /* PKURLState.m */; };
+ D35F4A8911643630003811F3 /* PKEmailState.m in Sources */ = {isa = PBXBuildFile; fileRef = D35F4A8511643630003811F3 /* PKEmailState.m */; };
+ D35F4A8A11643630003811F3 /* PKURLState.m in Sources */ = {isa = PBXBuildFile; fileRef = D35F4A8611643630003811F3 /* PKURLState.m */; };
+ D35F4A8D11643662003811F3 /* PKEmailState.h in Headers */ = {isa = PBXBuildFile; fileRef = D35F4A8B11643662003811F3 /* PKEmailState.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ D35F4A8E11643662003811F3 /* PKURLState.h in Headers */ = {isa = PBXBuildFile; fileRef = D35F4A8C11643662003811F3 /* PKURLState.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ D35F4A8F11643662003811F3 /* PKEmailState.h in Headers */ = {isa = PBXBuildFile; fileRef = D35F4A8B11643662003811F3 /* PKEmailState.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ D35F4A9011643662003811F3 /* PKURLState.h in Headers */ = {isa = PBXBuildFile; fileRef = D35F4A8C11643662003811F3 /* PKURLState.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ D35F4AA21164380C003811F3 /* TDURLStateTest.m in Sources */ = {isa = PBXBuildFile; fileRef = D35F4AA11164380C003811F3 /* TDURLStateTest.m */; };
+ D35F4ABA11643979003811F3 /* TDEmailStateTest.m in Sources */ = {isa = PBXBuildFile; fileRef = D35F4AB911643979003811F3 /* TDEmailStateTest.m */; };
D36568A70EEF9FE900226554 /* TDPlistParser.m in Sources */ = {isa = PBXBuildFile; fileRef = D36568A60EEF9FE900226554 /* TDPlistParser.m */; };
D36568AA0EEFA05300226554 /* TDPlistParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = D36568A90EEFA05300226554 /* TDPlistParserTest.m */; };
D3656DFE0EF2620E00226554 /* TDTokenArraySourceTest.m in Sources */ = {isa = PBXBuildFile; fileRef = D3656DFD0EF2620E00226554 /* TDTokenArraySourceTest.m */; };
@@ -922,6 +932,14 @@
D355C6300FE9EFEA006A91A4 /* TDNSPredicateEvaluatorTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TDNSPredicateEvaluatorTest.m; path = test/TDNSPredicateEvaluatorTest.m; sourceTree = "<group>"; };
D355C8800FEB36A1006A91A4 /* xml.grammar */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = xml.grammar; path = res/xml.grammar; sourceTree = "<group>"; };
D355C8830FEB4B94006A91A4 /* proto.grammar */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = proto.grammar; path = res/proto.grammar; sourceTree = "<group>"; };
+ D35F4A8511643630003811F3 /* PKEmailState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PKEmailState.m; path = src/PKEmailState.m; sourceTree = "<group>"; };
+ D35F4A8611643630003811F3 /* PKURLState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PKURLState.m; path = src/PKURLState.m; sourceTree = "<group>"; };
+ D35F4A8B11643662003811F3 /* PKEmailState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PKEmailState.h; path = include/ParseKit/PKEmailState.h; sourceTree = "<group>"; };
+ D35F4A8C11643662003811F3 /* PKURLState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PKURLState.h; path = include/ParseKit/PKURLState.h; sourceTree = "<group>"; };
+ D35F4AA01164380C003811F3 /* TDURLStateTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TDURLStateTest.h; path = test/TDURLStateTest.h; sourceTree = "<group>"; };
+ D35F4AA11164380C003811F3 /* TDURLStateTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TDURLStateTest.m; path = test/TDURLStateTest.m; sourceTree = "<group>"; };
+ D35F4AB811643979003811F3 /* TDEmailStateTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TDEmailStateTest.h; path = test/TDEmailStateTest.h; sourceTree = "<group>"; };
+ D35F4AB911643979003811F3 /* TDEmailStateTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TDEmailStateTest.m; path = test/TDEmailStateTest.m; sourceTree = "<group>"; };
D36568A50EEF9FE900226554 /* TDPlistParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TDPlistParser.h; path = test/TDPlistParser.h; sourceTree = "<group>"; };
D36568A60EEF9FE900226554 /* TDPlistParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TDPlistParser.m; path = test/TDPlistParser.m; sourceTree = "<group>"; };
D36568A80EEFA05300226554 /* TDPlistParserTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TDPlistParserTest.h; path = test/TDPlistParserTest.h; sourceTree = "<group>"; };
@@ -1524,6 +1542,10 @@
D34BAECE0FF9D56400D7773A /* PKSingleLineCommentState.m */,
D3C221E70FFE8C60004514FE /* PKMultiLineCommentState.h */,
D34BAEC80FF9D56400D7773A /* PKMultiLineCommentState.m */,
+ D35F4A8B11643662003811F3 /* PKEmailState.h */,
+ D35F4A8511643630003811F3 /* PKEmailState.m */,
+ D35F4A8C11643662003811F3 /* PKURLState.h */,
+ D35F4A8611643630003811F3 /* PKURLState.m */,
D3541F890DFB108300429B4F /* symbol */,
);
name = states;
@@ -1561,6 +1583,10 @@
D3DDDAFD0F083C9700A58000 /* TDCommentStateTest.m */,
D3E39C3D0FC5FFD10022DAB9 /* TDDelimitStateTest.h */,
D3E39C3E0FC5FFD10022DAB9 /* TDDelimitStateTest.m */,
+ D35F4AA01164380C003811F3 /* TDURLStateTest.h */,
+ D35F4AA11164380C003811F3 /* TDURLStateTest.m */,
+ D35F4AB811643979003811F3 /* TDEmailStateTest.h */,
+ D35F4AB911643979003811F3 /* TDEmailStateTest.m */,
);
name = "tokenizer states";
sourceTree = "<group>";
@@ -2376,6 +2402,8 @@
D3C2222E0FFE8DEE004514FE /* NSString+ParseKitAdditions.h in Headers */,
D3F0E2480FFE8EB900C9DF74 /* PKQuoteState.h in Headers */,
D3376D5910093A1600E4602E /* PKGrammarParser.h in Headers */,
+ D35F4A8D11643662003811F3 /* PKEmailState.h in Headers */,
+ D35F4A8E11643662003811F3 /* PKURLState.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2484,6 +2512,8 @@
D3F0E2490FFE8EB900C9DF74 /* PKQuoteState.h in Headers */,
D3F0E3CB0FFEB70100C9DF74 /* PKNumber.h in Headers */,
D37A28681013942A00E936B7 /* PKGrammarParser.h in Headers */,
+ D35F4A8F11643662003811F3 /* PKEmailState.h in Headers */,
+ D35F4A9011643662003811F3 /* PKURLState.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2853,6 +2883,8 @@
D34BAFDE0FF9E95500D7773A /* PKParserFactory.m in Sources */,
D3126D060FFD9BA700CBF4C4 /* PKNegation.m in Sources */,
D3376D5A10093A1600E4602E /* PKGrammarParser.m in Sources */,
+ D35F4A8711643630003811F3 /* PKEmailState.m in Sources */,
+ D35F4A8811643630003811F3 /* PKURLState.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3075,6 +3107,8 @@
D38E97CC1061CF6500739C39 /* TDTokenizerBlocksTest.m in Sources */,
D38E98D81062C5BA00739C39 /* TDParserBlocksTest.m in Sources */,
D319E42E106D8A31008C63DD /* TDArithmeticAssembler.m in Sources */,
+ D35F4AA21164380C003811F3 /* TDURLStateTest.m in Sources */,
+ D35F4ABA11643979003811F3 /* TDEmailStateTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3135,6 +3169,8 @@
D3126DEC0FFDBC1D00CBF4C4 /* PKNegation.m in Sources */,
D3F0E3CC0FFEB70700C9DF74 /* PKNumber.m in Sources */,
D37A28671013942300E936B7 /* PKGrammarParser.m in Sources */,
+ D35F4A8911643630003811F3 /* PKEmailState.m in Sources */,
+ D35F4A8A11643630003811F3 /* PKURLState.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
3 include/ParseKit/PKDelimitState.h
@@ -49,7 +49,8 @@
/*!
@property balancesEOFTerminatedStrings
- @brief if true, this state will append a matching end delimiter marker (e.g. <tt>--></tt> or <tt>%></tt>) to strings terminated by EOF. Default is NO.
+ @brief if YES, this state will append a matching end delimiter marker (e.g. <tt>--></tt> or <tt>%></tt>) to strings terminated by EOF.
+ @details Default is NO.
*/
@property (nonatomic) BOOL balancesEOFTerminatedStrings;
View
21 include/ParseKit/PKEmailState.h
@@ -0,0 +1,21 @@
+//
+// PKEmailState.h
+// ParseKit
+//
+// Created by Todd Ditchendorf on 3/31/10.
+// Copyright 2010 Todd Ditchendorf. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <ParseKit/PKTokenizerState.h>
+
+/*!
+ @class PKEmailState
+ @brief An email state returns an email address from a reader.
+ @details
+*/
+@interface PKEmailState : PKTokenizerState {
+ PKUniChar c;
+}
+
+@end
View
18 include/ParseKit/PKToken.h
@@ -35,7 +35,9 @@ typedef enum {
PKTokenTypeWhitespace,
PKTokenTypeComment,
PKTokenTypeDelimitedString,
- PKTokenTypeAny
+ PKTokenTypeAny,
+ PKTokenTypeURL,
+ PKTokenTypeEmail
} PKTokenType;
/*!
@@ -55,6 +57,8 @@ typedef enum {
BOOL whitespace;
BOOL comment;
BOOL delimitedString;
+ BOOL URL;
+ BOOL email;
id value;
NSUInteger offset;
@@ -141,6 +145,18 @@ typedef enum {
@property (nonatomic, readonly, getter=isDelimitedString) BOOL delimitedString;
/*!
+ @property URL
+ @brief True if this token is a URL. getter=isURL
+*/
+@property (nonatomic, readonly, getter=isURL) BOOL URL;
+
+/*!
+ @property email
+ @brief True if this token is an email address. getter=isEmail
+*/
+@property (nonatomic, readonly, getter=isEmailString) BOOL email;
+
+/*!
@property tokenType
@brief The type of this token.
*/
View
11 include/ParseKit/PKTokenizer.h
@@ -24,6 +24,8 @@
@class PKWhitespaceState;
@class PKWordState;
@class PKDelimitState;
+@class PKURLState;
+@class PKEmailState;
@class PKReader;
/*!
@@ -36,8 +38,8 @@
@code
From To State
0 ' ' whitespaceState
- 'a' 'z' wordState
- 'A' 'Z' wordState
+ 'a' 'z' URLState
+ 'A' 'Z' URLState
160 255 wordState
'0' '9' numberState
'-' '-' numberState
@@ -61,6 +63,8 @@
PKWhitespaceState *whitespaceState;
PKWordState *wordState;
PKDelimitState *delimitState;
+ PKURLState *URLState;
+ PKEmailState *emailState;
}
/*!
@@ -153,4 +157,7 @@
@brief The state this tokenizer uses to build delimited strings.
*/
@property (nonatomic, retain) PKDelimitState *delimitState;
+
+@property (nonatomic, retain) PKURLState *URLState;
+@property (nonatomic, retain) PKEmailState *emailState;
@end
View
2 include/ParseKit/PKTokenizerState.h
@@ -22,7 +22,7 @@
/*!
@class PKTokenizerState
@brief A <tt>PKTokenizerState</tt> returns a token, given a reader, an initial character read from the reader, and a tokenizer that is conducting an overall tokenization of the reader.
- @details The tokenizer will typically have a character state table that decides which state to use, depending on an initial character. If a single character is insufficient, a state such as <tt>PKCommentState</tt> will read a second character, and may delegate to another state, such as <tt>PKSingleLineState</tt>. This prospect of delegation is the reason that the <tt>-nextToken</tt> method has a tokenizer argument.
+ @details The tokenizer will typically have a character state table that decides which state to use, depending on an initial character. If a single character is insufficient, a state such as <tt>PKCommentState</tt> will read a second character, and may delegate to another state, such as <tt>PKSingleLineCommentState</tt>. This prospect of delegation is the reason that the <tt>-nextToken</tt> method has a tokenizer argument.
*/
@interface PKTokenizerState : NSObject {
NSMutableString *stringbuf;
View
23 include/ParseKit/PKURLState.h
@@ -0,0 +1,23 @@
+//
+// PKURLState.h
+// ParseKit
+//
+// Created by Todd Ditchendorf on 3/26/10.
+// Copyright 2010 Todd Ditchendorf. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <ParseKit/PKTokenizerState.h>
+
+/*!
+ @class PKURLState
+ @brief A URL state returns a URL from a reader.
+ @details
+*/
+@interface PKURLState : PKTokenizerState {
+ PKUniChar c;
+ BOOL allowsWWWPrefix;
+}
+
+@property (nonatomic) BOOL allowsWWWPrefix;
+@end
View
2 include/ParseKit/ParseKit.h
@@ -62,6 +62,8 @@
#import <ParseKit/PKNumberState.h>
#import <ParseKit/PKQuoteState.h>
#import <ParseKit/PKDelimitState.h>
+#import <ParseKit/PKURLState.h>
+#import <ParseKit/PKEmailState.h>
#import <ParseKit/PKCommentState.h>
#import <ParseKit/PKSingleLineCommentState.h>
#import <ParseKit/PKMultiLineCommentState.h>
View
110 src/PKEmailState.m
@@ -0,0 +1,110 @@
+//
+// PKEmailState.m
+// ParseKit
+//
+// Created by Todd Ditchendorf on 3/31/10.
+// Copyright 2010 Todd Ditchendorf. All rights reserved.
+//
+
+#import <ParseKit/PKEmailState.h>
+#import <ParseKit/PKReader.h>
+#import <ParseKit/PKTokenizer.h>
+#import <ParseKit/PKToken.h>
+#import <ParseKit/PKTypes.h>
+
+@interface PKToken ()
+@property (nonatomic, readwrite) NSUInteger offset;
+@end
+
+@interface PKTokenizerState ()
+- (void)resetWithReader:(PKReader *)r;
+- (void)append:(PKUniChar)c;
+- (NSString *)bufferedString;
+- (PKTokenizerState *)nextTokenizerStateFor:(PKUniChar)c tokenizer:(PKTokenizer *)t;
+@end
+
+@interface PKEmailState ()
+- (BOOL)parseNameFromReader:(PKReader *)r;
+- (BOOL)parseHostFromReader:(PKReader *)r;
+@end
+
+@implementation PKEmailState
+
+- (void)dealloc {
+ [super dealloc];
+}
+
+
+- (PKToken *)nextTokenFromReader:(PKReader *)r startingWith:(PKUniChar)cin tokenizer:(PKTokenizer *)t {
+ NSParameterAssert(r);
+ [self resetWithReader:r];
+
+ c = cin;
+ BOOL matched = [self parseNameFromReader:r];
+ if (matched) {
+ matched = [self parseHostFromReader:r];
+ }
+
+ if (PKEOF != c) {
+ [r unread];
+ }
+
+ NSString *s = [self bufferedString];
+ if (matched) {
+ PKToken *tok = [PKToken tokenWithTokenType:PKTokenTypeEmail stringValue:s floatValue:0.0];
+ tok.offset = offset;
+ return tok;
+ } else {
+ [r unread:[s length] - 1];
+ return [[self nextTokenizerStateFor:cin tokenizer:t] nextTokenFromReader:r startingWith:cin tokenizer:t];
+ }
+}
+
+
+- (BOOL)parseNameFromReader:(PKReader *)r {
+ BOOL result = NO;
+ BOOL hasAtLeastOneChar = NO;
+
+ for (;;) {
+ if (PKEOF == c || isspace(c)) {
+ result = NO;
+ break;
+ } else if ('@' == c && hasAtLeastOneChar) {
+ [self append:c];
+ result = YES;
+ break;
+ } else {
+ hasAtLeastOneChar = YES;
+ [self append:c];
+ c = [r read];
+ }
+ }
+
+ return result;
+}
+
+
+- (BOOL)parseHostFromReader:(PKReader *)r {
+ BOOL result = NO;
+ BOOL hasAtLeastOneChar = NO;
+ BOOL hasDot = NO;
+
+ // ^[:space:]()<>/
+ for (;;) {
+ if (PKEOF == c || isspace(c) || '(' == c || ')' == c || '<' == c || '>' == c || '/' == c) {
+ result = hasAtLeastOneChar && hasDot;
+ break;
+ } else {
+ if ('.' == c) {
+ hasDot = YES;
+ }
+ hasAtLeastOneChar = YES;
+ [self append:c];
+ c = [r read];
+ }
+ }
+
+ return result;
+}
+
+@end
View
2 src/PKSymbolNode.m
@@ -34,7 +34,7 @@ - (id)initWithParent:(PKSymbolNode *)p character:(PKUniChar)c {
self.children = [NSMutableDictionary dictionary];
// this private property is an optimization.
- // cache the NSString for the char to prevent it being constantly recreated in -determinAncestry
+ // cache the NSString for the char to prevent it being constantly recreated in -determineAncestry
self.string = [NSString stringWithFormat:@"%C", character];
[self determineAncestry];
View
23 src/PKSymbolRootNode.m
@@ -28,8 +28,7 @@ - (NSString *)nextWithFirst:(PKUniChar)c rest:(PKReader *)r parent:(PKSymbolNode
@implementation PKSymbolRootNode
- (id)init {
- self = [super initWithParent:nil character:PKEOF];
- if (self) {
+ if (self = [super initWithParent:nil character:PKEOF]) {
}
return self;
@@ -55,18 +54,19 @@ - (void)remove:(NSString *)s {
- (void)addWithFirst:(PKUniChar)c rest:(NSString *)s parent:(PKSymbolNode *)p {
NSParameterAssert(p);
NSNumber *key = [NSNumber numberWithInteger:c];
- PKSymbolNode *child = [p.children objectForKey:key];
+ PKSymbolNode *child = [p->children objectForKey:key];
if (!child) {
child = [[PKSymbolNode alloc] initWithParent:p character:c];
- [p.children setObject:child forKey:key];
+ [p->children setObject:child forKey:key];
[child release];
}
NSString *rest = nil;
- if (0 == [s length]) {
+ NSUInteger len = [s length];
+ if (0 == len) {
return;
- } else if ([s length] > 1) {
+ } else if (len > 1) {
rest = [s substringFromIndex:1];
}
@@ -77,18 +77,19 @@ - (void)addWithFirst:(PKUniChar)c rest:(NSString *)s parent:(PKSymbolNode *)p {
- (void)removeWithFirst:(PKUniChar)c rest:(NSString *)s parent:(PKSymbolNode *)p {
NSParameterAssert(p);
NSNumber *key = [NSNumber numberWithInteger:c];
- PKSymbolNode *child = [p.children objectForKey:key];
+ PKSymbolNode *child = [p->children objectForKey:key];
if (child) {
NSString *rest = nil;
- if (0 == [s length]) {
+ NSUInteger len = [s length];
+ if (0 == len) {
return;
- } else if ([s length] > 1) {
+ } else if (len > 1) {
rest = [s substringFromIndex:1];
[self removeWithFirst:[s characterAtIndex:0] rest:rest parent:child];
}
- [p.children removeObjectForKey:key];
+ [p->children removeObjectForKey:key];
}
}
@@ -126,7 +127,7 @@ - (NSString *)nextWithFirst:(PKUniChar)c rest:(PKReader *)r parent:(PKSymbolNode
// NSLog(@"iso: '%@'", iso);
NSNumber *key = [NSNumber numberWithInteger:c];
- PKSymbolNode *child = [p.children objectForKey:key];
+ PKSymbolNode *child = [p->children objectForKey:key];
if (!child) {
if (p == self) {
View
24 src/PKToken.m
@@ -80,7 +80,7 @@ - (NSString *)debugDescription {
- (NSUInteger)offset {
- return -1;
+ return NSNotFound;
}
@end
@@ -95,6 +95,8 @@ - (BOOL)isEqual:(id)obj ignoringCase:(BOOL)ignoringCase;
@property (nonatomic, readwrite, getter=isWhitespace) BOOL whitespace;
@property (nonatomic, readwrite, getter=isComment) BOOL comment;
@property (nonatomic, readwrite, getter=isDelimitedString) BOOL delimitedString;
+@property (nonatomic, readwrite, getter=isURL) BOOL URL;
+@property (nonatomic, readwrite, getter=isEmail) BOOL email;
@property (nonatomic, readwrite) CGFloat floatValue;
@property (nonatomic, readwrite, copy) NSString *stringValue;
@@ -131,6 +133,8 @@ - (id)initWithTokenType:(PKTokenType)t stringValue:(NSString *)s floatValue:(CGF
self.whitespace = (PKTokenTypeWhitespace == t);
self.comment = (PKTokenTypeComment == t);
self.delimitedString = (PKTokenTypeDelimitedString == t);
+ self.URL = (PKTokenTypeURL == t);
+ self.email = (PKTokenTypeEmail == t);
}
return self;
}
@@ -169,17 +173,17 @@ - (BOOL)isEqual:(id)obj ignoringCase:(BOOL)ignoringCase {
}
PKToken *tok = (PKToken *)obj;
- if (tokenType != tok.tokenType) {
+ if (tokenType != tok->tokenType) {
return NO;
}
- if (self.isNumber) {
- return floatValue == tok.floatValue;
+ if (number) {
+ return floatValue == tok->floatValue;
} else {
if (ignoringCase) {
- return (NSOrderedSame == [stringValue caseInsensitiveCompare:tok.stringValue]);
+ return (NSOrderedSame == [stringValue caseInsensitiveCompare:tok->stringValue]);
} else {
- return [stringValue isEqualToString:tok.stringValue];
+ return [stringValue isEqualToString:tok->stringValue];
}
}
}
@@ -188,7 +192,7 @@ - (BOOL)isEqual:(id)obj ignoringCase:(BOOL)ignoringCase {
- (id)value {
if (!value) {
id v = nil;
- if (self.isNumber) {
+ if (number) {
v = [NSNumber numberWithFloat:floatValue];
} else {
v = stringValue;
@@ -215,6 +219,10 @@ - (NSString *)debugDescription {
typeString = @"Comment";
} else if (self.isDelimitedString) {
typeString = @"Delimited String";
+ } else if (self.isURL) {
+ typeString = @"URL";
+ } else if (self.isEmail) {
+ typeString = @"Email";
}
return [NSString stringWithFormat:@"<%@ %C%@%C>", typeString, 0x00AB, self.value, 0x00BB];
}
@@ -231,6 +239,8 @@ - (NSString *)description {
@synthesize whitespace;
@synthesize comment;
@synthesize delimitedString;
+@synthesize URL;
+@synthesize email;
@synthesize floatValue;
@synthesize stringValue;
@synthesize tokenType;
View
20 src/PKTokenizer.m
@@ -57,6 +57,11 @@ - (id)initWithString:(NSString *)s {
self.whitespaceState = [[[PKWhitespaceState alloc] init] autorelease];
self.wordState = [[[PKWordState alloc] init] autorelease];
self.delimitState = [[[PKDelimitState alloc] init] autorelease];
+ self.URLState = [[[PKURLState alloc] init] autorelease];
+ self.emailState = [[[PKEmailState alloc] init] autorelease];
+
+ URLState.fallbackState = wordState;
+ //emailState.fallbackState = wordState;
self.tokenizerStates = [NSMutableArray arrayWithCapacity:STATE_COUNT];
@@ -89,6 +94,8 @@ - (void)dealloc {
self.whitespaceState = nil;
self.wordState = nil;
self.delimitState = nil;
+ self.URLState = nil;
+ self.emailState = nil;
[super dealloc];
}
@@ -140,7 +147,7 @@ - (void)setTokenizerState:(PKTokenizerState *)state from:(PKUniChar)start to:(PK
- (void)setReader:(PKReader *)r {
if (reader != r) {
- [reader release];
+ [reader autorelease];
reader = [r retain];
reader.string = string;
}
@@ -149,7 +156,7 @@ - (void)setReader:(PKReader *)r {
- (void)setString:(NSString *)s {
if (string != s) {
- [string release];
+ [string autorelease];
string = [s retain];
}
reader.string = string;
@@ -159,7 +166,7 @@ - (void)setString:(NSString *)s {
#pragma mark -
- (PKTokenizerState *)tokenizerStateFor:(PKUniChar)c {
- if (c < 0 || c > 255) {
+ if (c < 0 || c >= STATE_COUNT) {
// customization above 255 is not supported, so fetch default.
return [self defaultTokenizerStateFor:c];
} else {
@@ -168,6 +175,7 @@ - (PKTokenizerState *)tokenizerStateFor:(PKUniChar)c {
}
}
+
- (PKTokenizerState *)defaultTokenizerStateFor:(PKUniChar)c {
if (c >= 0 && c <= ' ') { // From: 0 to: 32 From:0x00 to:0x20
return whitespaceState;
@@ -196,11 +204,11 @@ - (PKTokenizerState *)defaultTokenizerStateFor:(PKUniChar)c {
} else if (c >= 58 && c <= 64) {
return symbolState;
} else if (c >= 'A' && c <= 'Z') { // From: 65 to: 90 From:0x41 to:0x5A
- return wordState;
+ return URLState;
} else if (c >= 91 && c <= 96) {
return symbolState;
} else if (c >= 'a' && c <= 'z') { // From: 97 to:122 From:0x61 to:0x7A
- return wordState;
+ return URLState;
} else if (c >= 123 && c <= 191) {
return symbolState;
} else if (c >= 0xC0 && c <= 0xFF) { // From:192 to:255 From:0xC0 to:0xFF
@@ -233,6 +241,8 @@ - (PKTokenizerState *)defaultTokenizerStateFor:(PKUniChar)c {
@synthesize whitespaceState;
@synthesize wordState;
@synthesize delimitState;
+@synthesize URLState;
+@synthesize emailState;
@synthesize string;
@synthesize reader;
@synthesize tokenizerStates;
View
199 src/PKURLState.m
@@ -0,0 +1,199 @@
+//
+// PKURLState.m
+// ParseKit
+//
+// Created by Todd Ditchendorf on 3/26/10.
+// Copyright 2010 Todd Ditchendorf. All rights reserved.
+//
+
+#import <ParseKit/PKURLState.h>
+#import <ParseKit/PKReader.h>
+#import <ParseKit/PKTokenizer.h>
+#import <ParseKit/PKToken.h>
+#import <ParseKit/PKTypes.h>
+
+// Gruber original
+// \b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))
+
+@interface PKToken ()
+@property (nonatomic, readwrite) NSUInteger offset;
+@end
+
+@interface PKTokenizerState ()
+- (void)resetWithReader:(PKReader *)r;
+- (void)append:(PKUniChar)c;
+- (NSString *)bufferedString;
+- (PKTokenizerState *)nextTokenizerStateFor:(PKUniChar)c tokenizer:(PKTokenizer *)t;
+@end
+
+@interface PKURLState ()
+- (BOOL)parseWWWFromReader:(PKReader *)r;
+- (BOOL)parseSchemeFromReader:(PKReader *)r;
+- (BOOL)parseHostFromReader:(PKReader *)r;
+- (void)parsePathFromReader:(PKReader *)r;
+@end
+
+@implementation PKURLState
+
+- (id)init {
+ if (self = [super init]) {
+ self.allowsWWWPrefix = YES;
+ }
+ return self;
+}
+
+
+- (void)dealloc {
+ [super dealloc];
+}
+
+
+- (PKToken *)nextTokenFromReader:(PKReader *)r startingWith:(PKUniChar)cin tokenizer:(PKTokenizer *)t {
+ NSParameterAssert(r);
+ [self resetWithReader:r];
+
+ c = cin;
+ BOOL matched = NO;
+ if (allowsWWWPrefix && 'w' == c) {
+ matched = [self parseWWWFromReader:r];
+ } else {
+ matched = [self parseSchemeFromReader:r];
+ }
+ if (matched) {
+ matched = [self parseHostFromReader:r];
+ }
+ if (matched) {
+ [self parsePathFromReader:r];
+ }
+
+ if (PKEOF != c) {
+ [r unread];
+ }
+
+ NSString *s = [self bufferedString];
+ if (matched) {
+ PKToken *tok = [PKToken tokenWithTokenType:PKTokenTypeURL stringValue:s floatValue:0.0];
+ tok.offset = offset;
+ return tok;
+ } else {
+ [r unread:[s length] - 1];
+ return [[self nextTokenizerStateFor:cin tokenizer:t] nextTokenFromReader:r startingWith:cin tokenizer:t];
+ }
+}
+
+
+- (BOOL)parseWWWFromReader:(PKReader *)r {
+ BOOL result = NO;
+ NSInteger wcount = 0;
+
+ while ('w' == c) {
+ wcount++;
+ [self append:c];
+ c = [r read];
+
+ if (3 == wcount) {
+ if ('.' == c) {
+ [self append:c];
+ c = [r read];
+ result = YES;
+ break;
+ } else {
+ result = NO;
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
+
+- (BOOL)parseSchemeFromReader:(PKReader *)r {
+ BOOL result = NO;
+
+ // [[:alpha:]-]+://?
+ for (;;) {
+ if (isalnum(c) || '-' == c) {
+ [self append:c];
+ } else if (':' == c) {
+ [self append:c];
+
+ c = [r read];
+ if ('/' == c) { // endgame
+ [self append:c];
+ c = [r read];
+ if ('/' == c) {
+ [self append:c];
+ c = [r read];
+ }
+ result = YES;
+ break;
+ } else {
+ result = NO;
+ break;
+ }
+ } else {
+ result = NO;
+ break;
+ }
+
+ c = [r read];
+ }
+
+ return result;
+}
+
+
+- (BOOL)parseHostFromReader:(PKReader *)r {
+ BOOL result = NO;
+ BOOL hasAtLeastOneChar = NO;
+// BOOL hasDot = NO;
+
+ // ^[:space:]()<>
+ for (;;) {
+ if (PKEOF == c || isspace(c) || '(' == c || ')' == c || '<' == c || '>' == c) {
+ result = hasAtLeastOneChar;
+ break;
+ } else if ('/' == c && hasAtLeastOneChar/* && hasDot*/) {
+ //[self append:c];
+ result = YES;
+ break;
+ } else {
+// if ('.' == c) {
+// hasDot = YES;
+// }
+ hasAtLeastOneChar = YES;
+ [self append:c];
+ c = [r read];
+ }
+ }
+
+ return result;
+}
+
+
+- (void)parsePathFromReader:(PKReader *)r {
+ BOOL hasOpenParen = NO;
+
+ for (;;) {
+ if (PKEOF == c || isspace(c) || '<' == c || '>' == c || '.' == c) {
+ break;
+ } else if (')' == c) {
+ if (hasOpenParen) {
+ hasOpenParen = NO;
+ [self append:c];
+ } else {
+ break;
+ }
+ } else {
+ if (!hasOpenParen) {
+ hasOpenParen = ('(' == c);
+ }
+ [self append:c];
+ }
+ c = [r read];
+ }
+}
+
+@synthesize allowsWWWPrefix;
+@end
View
4 src/RegexKitLite.m
@@ -384,7 +384,7 @@ static BOOL rkl_collectingEnabled_first (void) {
RKL_STATIC_INLINE id rkl_CFAutorelease (CFTypeRef obj) { return([(id)obj autorelease]); }
RKL_STATIC_INLINE id rkl_CreateArrayWithObjects (void **objects, NSUInteger count) { return((id)CFArrayCreate(NULL, (const void **)objects, (CFIndex)count, &transferOwnershipArrayCallBacks)); }
RKL_STATIC_INLINE id rkl_CreateAutoreleasedArray (void **objects, NSUInteger count) { return(rkl_CFAutorelease(rkl_CreateArrayWithObjects(objects, count))); }
-RKL_STATIC_INLINE id rkl_CreateStringWithSubstring (id string, NSRange range) { return((id)CFStringCreateWithSubstring(NULL, (CFStringRef)string, CFMakeRange((CFIndex)range.location, (CFIndex)[range length]))); }
+RKL_STATIC_INLINE id rkl_CreateStringWithSubstring (id string, NSRange range) { return((id)CFStringCreateWithSubstring(NULL, (CFStringRef)string, CFMakeRange((CFIndex)range.location, (CFIndex)range.length))); }
RKL_STATIC_INLINE id rkl_ReleaseObject (id obj) { CFRelease((CFTypeRef)obj); return(NULL); }
#endif // __OBJC_GC__
@@ -508,7 +508,7 @@ +(void)lowMemoryWarning:(id)notification {
#ifdef _RKL_DTRACE_ENABLED
// compiledRegexCache(unsigned long eventID, const char *regexUTF8, int options, int captures, int hitMiss, int icuStatusCode, const char *icuErrorMessage, double *hitRate);
-// utf16ConversionCache(unsigned long eventID, unsigned int lookupResultFlags, double *hitRate, const void *string, unsigned long NSRange.location, unsigned long [NSRange length], long length);
+// utf16ConversionCache(unsigned long eventID, unsigned int lookupResultFlags, double *hitRate, const void *string, unsigned long NSRange.location, unsigned long NSRange.length, long length);
/*
provider RegexKitLite {
View
2 test/TDCommentStateTest.m
@@ -35,7 +35,6 @@ - (void)testSlashSlashFoo {
t.string = s;
tok = [commentState nextTokenFromReader:r startingWith:'/' tokenizer:t];
TDEqualObjects(tok, [PKToken EOFToken]);
- TDEquals(tok.offset, (NSUInteger)-1);
TDEquals([r read], PKEOF);
}
@@ -114,7 +113,6 @@ - (void)testAddHashFoo {
tok = [t nextToken];
TDEquals(tok, [PKToken EOFToken]);
TDEqualObjects(tok.stringValue, [[PKToken EOFToken] stringValue]);
- TDEquals(tok.offset, (NSUInteger)-1);
}
View
18 test/TDEmailStateTest.h
@@ -0,0 +1,18 @@
+//
+// TDEmailStateTest.h
+// ParseKit
+//
+// Created by Todd Ditchendorf on 3/31/10.
+// Copyright 2010 Todd Ditchendorf. All rights reserved.
+//
+
+#import "TDTestScaffold.h"
+
+@interface TDEmailStateTest : SenTestCase {
+ PKEmailState *emailState;
+ PKTokenizer *t;
+ NSString *s;
+ PKToken *tok;
+}
+
+@end
View
38 test/TDEmailStateTest.m
@@ -0,0 +1,38 @@
+//
+// TDEmailStateTest.m
+// ParseKit
+//
+// Created by Todd Ditchendorf on 3/31/10.
+// Copyright 2010 Todd Ditchendorf. All rights reserved.
+//
+
+#import "TDEmailStateTest.h"
+
+@implementation TDEmailStateTest
+
+- (void)setUp {
+ t = [[PKTokenizer alloc] init];
+ emailState = t.emailState;
+}
+
+
+- (void)tearDown {
+ [t release];
+}
+
+
+//- (void)testFooComBlahBlah {
+// s = @"http://foo.com/blah_blah";
+// t.string = s;
+//
+// tok = [t nextToken];
+//
+// TDTrue(tok.isURL);
+// TDEqualObjects(tok.stringValue, s);
+// TDEquals(tok.floatValue, (CGFloat)0.0);
+//
+// tok = [t nextToken];
+// TDEqualObjects(tok, [PKToken EOFToken]);
+//}
+
+@end
View
4 test/TDTestScaffold.m
@@ -15,7 +15,7 @@
#import "TDTestScaffold.h"
#define RUN_ALL_TEST_CASES 1
-#define SOLO_TEST_CASE @"TDParserBlocksTest"
+#define SOLO_TEST_CASE @"TDEmailStateTest"
@interface SenTestSuite (TDAdditions)
- (void)addSuitesForClassNames:(NSArray *)classNames;
@@ -45,6 +45,8 @@ - (void)addSuitesForClassNames:(NSArray *)classNames;
@"TDSymbolStateTest",
@"TDCommentStateTest",
@"TDDelimitStateTest",
+ @"TDURLStateTest",
+ @"TDEmailStateTest",
@"TDTokenizerStateTest",
#ifdef TARGET_OS_SNOW_LEOPARD
@"TDTokenizerBlocksTest",
View
3 test/TDTokenizerTest.m
@@ -128,7 +128,6 @@ - (void)testStuff2 {
tok = [t nextToken];
TDNotNil(tok);
TDTrue(tok == eof);
- TDEquals(tok.offset, (NSUInteger)PKEOF);
}
@@ -157,7 +156,6 @@ - (void)testFortySevenDot {
tok = [t nextToken];
TDNotNil(tok);
TDTrue(tok == eof);
- TDEquals(tok.offset, (NSUInteger)PKEOF);
}
@@ -194,7 +192,6 @@ - (void)testFortySevenDotSpaceFoo {
tok = [t nextToken];
TDNotNil(tok);
TDTrue(tok == eof);
- TDEquals(tok.offset, (NSUInteger)PKEOF);
}
View
18 test/TDURLStateTest.h
@@ -0,0 +1,18 @@
+//
+// TDURLStateTest.h
+// ParseKit
+//
+// Created by Todd Ditchendorf on 3/26/10.
+// Copyright 2010 Todd Ditchendorf. All rights reserved.
+//
+
+#import "TDTestScaffold.h"
+
+@interface TDURLStateTest : SenTestCase {
+ PKURLState *URLState;
+ PKTokenizer *t;
+ NSString *s;
+ PKToken *tok;
+}
+
+@end
View
507 test/TDURLStateTest.m
@@ -0,0 +1,507 @@
+//
+// TDURLStateTest.m
+// ParseKit
+//
+// Created by Todd Ditchendorf on 3/26/10.
+// Copyright 2010 Todd Ditchendorf. All rights reserved.
+//
+
+#import "TDURLStateTest.h"
+
+@implementation TDURLStateTest
+
+- (void)setUp {
+ t = [[PKTokenizer alloc] init];
+ URLState = t.URLState;
+}
+
+
+- (void)tearDown {
+ [t release];
+}
+
+
+- (void)testFooComBlahBlah {
+ s = @"http://foo.com/blah_blah";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testFooComBlahBlahSlash {
+ s = @"http://foo.com/blah_blah/";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testSomethingLikeFooComBlahBlahSlash {
+ s = @"(Something like http://foo.com/blah_blah)";
+ t.string = s;
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @"(");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isWord);
+ TDEqualObjects(tok.stringValue, @"Something");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isWord);
+ TDEqualObjects(tok.stringValue, @"like");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, @"http://foo.com/blah_blah");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @")");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testFooComBlahBlahWiki {
+ s = @"http://foo.com/blah_blah_(wikipedia)";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testSomethingLikeFooComBlahBlahWiki {
+ s = @"(Something like http://foo.com/blah_blah_(wikipedia))";
+ t.string = s;
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @"(");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isWord);
+ TDEqualObjects(tok.stringValue, @"Something");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isWord);
+ TDEqualObjects(tok.stringValue, @"like");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, @"http://foo.com/blah_blah_(wikipedia)");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @")");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testFooComBlahBlahDot {
+ s = @"http://foo.com/blah_blah.";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, @"http://foo.com/blah_blah");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @".");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testFooComBlahBlahSlashDot {
+ s = @"http://foo.com/blah_blah/.";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, @"http://foo.com/blah_blah/");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @".");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testLtFooComBlahBlahGt {
+ s = @"<http://foo.com/blah_blah>";
+ t.string = s;
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @"<");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, @"http://foo.com/blah_blah");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @">");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testLtFooComBlahBlahSlashGt {
+ s = @"<http://foo.com/blah_blah/>";
+ t.string = s;
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @"<");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, @"http://foo.com/blah_blah/");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @">");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testExampleComArgDot {
+ s = @"http://www.example.com/wpstyle/?p=364.";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, @"http://www.example.com/wpstyle/?p=364");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @".");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testStarDF {
+ s = @"http://✪df.ws/123";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testRadarSlashSlash {
+ s = @"rdar://1234";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testRadarSlash {
+ s = @"rdar:/1234";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testUserIdPasswordPort {
+ s = @"http://userid:password@example.com:8080";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testUserId {
+ s = @"http://userid@example.com";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testUserIdPort {
+ s = @"http://userid@example.com:8080";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testUserIdPassword {
+ s = @"http://userid:password@example.com";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testExampleComPort {
+ s = @"http://example.com:8080";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testYojimbo {
+ s = @"x-yojimbo-item://6303E4C1-xxxx-45A6-AB9D-3A908F59AE0E";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testMessage {
+ s = @"message://%3c330e7f8409726r6a4ba78dkf1fd71420c1bf6ff@mail.gmail.com%3e";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testArrow {
+ s = @"http://➡.ws/䨹";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testWWWArrow {
+ s = @"www.➡.ws/䨹";
+ t.string = s;
+
+ tok = [t nextToken];
+
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, s);
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testTagExampleComTag {
+ s = @"<tag>http://example.com</tag>";
+ t.string = s;
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @"<");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isWord);
+ TDEqualObjects(tok.stringValue, @"tag");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @">");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, @"http://example.com");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @"<");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @"/");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isWord);
+ TDEqualObjects(tok.stringValue, @"tag");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @">");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+
+- (void)testJustAnExampleComLinkDot {
+ s = @"Just a www.example.com link.";
+ t.string = s;
+
+ tok = [t nextToken];
+ TDTrue(tok.isWord);
+ TDEqualObjects(tok.stringValue, @"Just");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isWord);
+ TDEqualObjects(tok.stringValue, @"a");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isURL);
+ TDEqualObjects(tok.stringValue, @"www.example.com");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isWord);
+ TDEqualObjects(tok.stringValue, @"link");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDTrue(tok.isSymbol);
+ TDEqualObjects(tok.stringValue, @".");
+ TDEquals(tok.floatValue, (CGFloat)0.0);
+
+ tok = [t nextToken];
+ TDEqualObjects(tok, [PKToken EOFToken]);
+}
+
+@end

0 comments on commit 3731156

Please sign in to comment.
Something went wrong with that request. Please try again.