main
1//
2// Licensed under the terms in License.txt
3//
4// Copyright 2010 Allen Ding. All rights reserved.
5//
6
7#import "KWStringUtilities.h"
8
9#pragma mark -
10#pragma mark Checking for Case Separated Words
11
12BOOL KWStringHasWordPrefix(NSString *string, NSString *prefix) {
13 return [string isEqualToString:prefix] || KWStringHasStrictWordPrefix(string, prefix);
14}
15
16BOOL KWStringHasStrictWordPrefix(NSString *string, NSString *prefix) {
17 if (![string hasPrefix:prefix] || [string length] == [prefix length])
18 return NO;
19
20 unichar firstCharacterAfterPrefix = [string characterAtIndex:[prefix length]];
21 NSCharacterSet *uppercaseCharacterSet = [NSCharacterSet uppercaseLetterCharacterSet];
22 return [uppercaseCharacterSet characterIsMember:firstCharacterAfterPrefix];
23}
24
25BOOL KWStringHasWord(NSString *string, NSString *word) {
26 if (KWStringHasWordPrefix(string, word))
27 return YES;
28
29 NSCharacterSet *lowercaseCharacterSet = [NSCharacterSet lowercaseLetterCharacterSet];
30 NSCharacterSet *uppercaseCharacterSet = [NSCharacterSet uppercaseLetterCharacterSet];
31 NSRange searchRange = NSMakeRange(0, [string length]);
32
33 // Never match if word begins with a lowercase letter and was not a prefix.
34 if ([lowercaseCharacterSet characterIsMember:[word characterAtIndex:0]])
35 return NO;
36
37 while (1) {
38 if (searchRange.location >= [string length])
39 return NO;
40
41 NSRange range = [string rangeOfString:word options:0 range:searchRange];
42 searchRange.location = range.location + range.length;
43 searchRange.length = [string length] - searchRange.location;
44
45 if (range.location == NSNotFound)
46 return NO;
47
48 if (range.location > 0) {
49 unichar charBeforeRange = [string characterAtIndex:range.location - 1];
50
51
52 if (![lowercaseCharacterSet characterIsMember:charBeforeRange])
53 continue;
54 }
55
56 if (range.location + range.length < [string length]) {
57 unichar charAfterRange = [string characterAtIndex:range.location + range.length];
58
59 if (![uppercaseCharacterSet characterIsMember:charAfterRange])
60 continue;
61 }
62
63 return YES;
64 }
65}
66
67#pragma mark -
68#pragma mark Getting Type Encodings
69
70NSString *KWEncodingWithObjCTypes(const char *firstType, ...) {
71 if (firstType == nil)
72 return nil;
73
74 NSMutableString *encoding = [NSMutableString stringWithCapacity:8];
75 va_list argumentList;
76 va_start(argumentList, firstType);
77 const char *type = firstType;
78
79 do {
80 [encoding appendFormat:@"%s", type];
81 type = va_arg(argumentList, const char *);
82 } while (type != nil);
83
84 va_end(argumentList);
85 return encoding;
86}
87
88NSString *KWEncodingForVoidMethod(void) {
89 return KWEncodingWithObjCTypes(@encode(void), @encode(id), @encode(SEL), nil);
90}