-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCoverStoryFilePredicate.m
142 lines (128 loc) · 4.74 KB
/
CoverStoryFilePredicate.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//
// CoverStoryFilePredicate.m
// CoverStory
//
// Created by dmaclach on 03/20/08.
// Copyright 2008 Google Inc.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
//
#import "CoverStoryFilePredicate.h"
#import "CoverStoryPreferenceKeys.h"
#import "CoverStoryDocument.h"
#import "GTMRegex.h"
#import <fnmatch.h>
@interface NSString (CoverStoryStringMatching)
- (BOOL)cs_isRegularExpressionEqual:(NSString *)string;
- (BOOL)cs_isWildcardPatternEqual:(NSString *)string;
- (BOOL)cs_isMatchForPatternArray:(NSArray *)patterns;
@end
// the one key in our array of dictionaries. we uses an array of dicts instead
// of an array of strings, because then we can KVC the UI for editing them.
static NSString * const kFilter = @"filter";
@implementation CoverStoryFilePredicate
+ (void)registerDefaults {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *predicateDefaults =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], // hide the systems sources by default
kCoverStoryHideSystemSourcesKey,
[NSArray arrayWithObjects:
[NSDictionary dictionaryWithObject:@"/usr/*" forKey:kFilter],
[NSDictionary dictionaryWithObject:@"/System/Library/Frameworks/*" forKey:kFilter],
[NSDictionary dictionaryWithObject:@"*/SDKs/MacOSX10.*" forKey:kFilter],
[NSDictionary dictionaryWithObject:@"*/SDKs/iPhone*" forKey:kFilter],
nil],
kCoverStorySystemSourcesPatternsKey,
[NSNumber numberWithBool:NO], // do NOT hide the unittest sources by default
kCoverStoryHideUnittestSourcesKey,
[NSArray arrayWithObjects:
[NSDictionary dictionaryWithObject:@"*Test.[hHmM]" forKey:kFilter],
[NSDictionary dictionaryWithObject:@"*Test.mm" forKey:kFilter],
nil],
kCoverStoryUnittestSourcesPatternsKey,
nil];
[defaults registerDefaults:predicateDefaults];
}
- (BOOL)evaluateWithObject:(id)object {
BOOL isGood = YES;
NSString *path = [object valueForKey:@"sourcePath"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
BOOL hideSDKFiles = [document_ hideSDKSources];
if (hideSDKFiles) {
NSArray *systemSourcesPatterns =
[defaults arrayForKey:kCoverStorySystemSourcesPatternsKey];
if (systemSourcesPatterns) {
isGood = ![path cs_isMatchForPatternArray:systemSourcesPatterns];
}
}
if (isGood) {
BOOL hideUnittestFiles = [document_ hideUnittestSources];
if (hideUnittestFiles) {
NSArray *unittestSourcesPatterns =
[defaults arrayForKey:kCoverStoryUnittestSourcesPatternsKey];
if (unittestSourcesPatterns) {
isGood = ![path cs_isMatchForPatternArray:unittestSourcesPatterns];
}
}
}
if (isGood) {
NSString *text = [searchField_ stringValue];
if ([text length] == 0) {
isGood = YES;
} else {
CoverStoryFilterStringType type
= [defaults integerForKey:kCoverStoryFilterStringTypeKey];
switch (type) {
default:
case kCoverStoryFilterStringTypeWildcardPattern:
isGood = [path cs_isWildcardPatternEqual:text];
break;
case kCoverStoryFilterStringTypeRegularExpression:
isGood = [path cs_isRegularExpressionEqual:text];
break;
}
}
}
return isGood;
}
@end
@implementation NSString (CoverStoryStringMatching)
- (BOOL)cs_isRegularExpressionEqual:(NSString*)string {
// if the pattern didn't parse, always show things
BOOL result = YES;
// no point in catching errors since we do this as they type
GTMRegex *regex = [GTMRegex regexWithPattern:string
options:kGTMRegexOptionIgnoreCase];
if (regex) {
result = [regex matchesSubStringInString:self];
}
return result;
}
- (BOOL)cs_isWildcardPatternEqual:(NSString*)string {
NSString *pattern = [NSString stringWithFormat:@"*%@*", string];
int flags = FNM_CASEFOLD;
BOOL isGood = fnmatch([pattern UTF8String], [self UTF8String], flags) == 0;
return isGood;
}
- (BOOL)cs_isMatchForPatternArray:(NSArray *)patterns {
const char *utf8Self = [self UTF8String];
for (NSDictionary *patternDict in patterns) {
NSString *pattern = [patternDict objectForKey:kFilter];
if (([pattern length] > 0) &&
(fnmatch([pattern UTF8String], utf8Self, 0) == 0)) {
return YES;
}
}
return NO;
}
@end