2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
6 OGo is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include "EOQualifier+CtxEval.h"
24 #import <EOControl/EOKeyValueCoding.h>
25 #import <EOControl/EONull.h>
28 #if LIB_FOUNDATION_LIBRARY
29 # import <objc/objc-api.h>
30 # import <objc/objc.h>
31 # import <extensions/objc-runtime.h>
32 #elif GNUSTEP_BASE_LIBRARY
33 # import <objc/objc-api.h>
35 # import <objc/objc.h>
36 # define sel_get_name sel_getName
39 static inline int countSelArgs(SEL _sel) {
40 register const char *selName;
42 if ((selName = sel_get_name(_sel))) {
45 for (count = 0; *selName; selName++) {
55 @implementation EOQualifier(ContextEvaluation)
57 - (BOOL)evaluateWithObject:(id)_object context:(id)_context {
58 [self doesNotRecognizeSelector:_cmd]; /* subclass */
62 @end /* EOQualifier(ContextEvaluation) */
64 @implementation NSArray(ContextEvaluation)
66 - (NSArray *)filteredArrayUsingQualifier:(EOQualifier *)_qualifier
69 NSMutableArray *a = nil;
72 for (i = 0, count = [self count]; i < count; i++) {
75 o = [self objectAtIndex:i];
77 if ([_qualifier evaluateWithObject:o context:_context]) {
78 if (a == nil) a = [NSMutableArray arrayWithCapacity:count];
82 return a ? [[a copy] autorelease] : [NSArray array];
85 @end /* NSArray(ContextEvaluation) */
87 @implementation EOAndQualifier(ContextEvaluation)
89 - (BOOL)evaluateWithObject:(id)_object context:(id)_context {
94 qs = [self qualifiers];
95 objAtIdx = [qs methodForSelector:@selector(objectAtIndex:)];
97 for (i = 0; i < [qs count]; i++) {
100 q = objAtIdx(qs, @selector(objectAtIndex:), i);
102 if (![q evaluateWithObject:_object context:_context])
108 @end /* EOAndQualifier(ContextEvaluation) */
110 @implementation EOOrQualifier(ContextEvaluation)
112 - (BOOL)evaluateWithObject:(id)_object context:(id)_context {
117 qs = [self qualifiers];
118 objAtIdx = [qs methodForSelector:@selector(objectAtIndex:)];
120 for (i = 0; i < [qs count]; i++) {
123 q = objAtIdx(qs, @selector(objectAtIndex:), i);
125 if ([q evaluateWithObject:_object context:_context])
131 @end /* EOOrQualifier(ContextEvaluation) */
133 @implementation EONotQualifier(ContextEvaluation)
135 - (BOOL)evaluateWithObject:(id)_object context:(id)_context {
137 [[self qualifier] evaluateWithObject:_object context:_context]
141 @end /* EONotQualifier(ContextEvaluation) */
143 @implementation EOKeyValueQualifier(ContextEvaluation)
145 - (BOOL)evaluateWithObject:(id)_object context:(id)_context {
146 static EONull *null = nil;
150 BOOL (*unary)(id, SEL);
151 BOOL (*binary)(id, SEL, id);
152 BOOL (*ctx)(id, SEL, id, id);
156 op = [self selector];
157 lv = [_object valueForKeyPath:[self key]];
160 if (null == nil) null = [EONull null];
161 if (lv == nil) lv = null;
162 if (rv == nil) rv = null;
164 if ((m.m = [lv methodForSelector:op]) == NULL) {
165 /* no such operator method ! */
166 [lv doesNotRecognizeSelector:op];
169 switch (countSelArgs(op)) {
172 NSLog(@"%s: called with invalid selector %@", __PRETTY_FUNCTION__,
173 NSStringFromSelector(op));
177 return m.unary(lv, op);
179 return m.binary(lv, op, rv);
181 return m.ctx(lv, op, rv, _context);
185 @end /* EOKeyValueQualifier(ContextEvaluation) */
187 @implementation EOKeyComparisonQualifier(ContextEvaluation)
189 - (BOOL)evaluateWithObject:(id)_object context:(id)_context {
190 static EONull *null = nil;
194 BOOL (*unary)(id, SEL);
195 BOOL (*binary)(id, SEL, id);
196 BOOL (*ctx)(id, SEL, id, id);
200 lv = [_object valueForKeyPath:[self leftKey]];
201 rv = [_object valueForKeyPath:[self rightKey]];
202 if (null == nil) null = [EONull null];
203 if (lv == nil) lv = null;
204 if (rv == nil) rv = null;
206 op = [self selector];
208 if ((m.m = (void *)[lv methodForSelector:op]) == NULL) {
209 /* no such operator method ! */
210 [lv doesNotRecognizeSelector:op];
213 switch (countSelArgs(op)) {
216 NSLog(@"%s: called with invalid selector %@", __PRETTY_FUNCTION__,
217 NSStringFromSelector(op));
221 return m.unary(lv, op);
223 return m.binary(lv, op, rv);
225 return m.ctx(lv, op, rv, _context);
229 @end /* EOKeyComparisonQualifier(ContextEvaluation) */
231 @implementation NSObject(ImplementedQualifierComparisons2)
233 - (BOOL)isEqualTo:(id)_object inContext:(id)_context {
234 return [self isEqualTo:_object];
236 - (BOOL)isNotEqualTo:(id)_object inContext:(id)_context {
237 return [self isNotEqualTo:_object];
240 - (BOOL)isLessThan:(id)_object inContext:(id)_context {
241 return [self isLessThan:_object];
243 - (BOOL)isGreaterThan:(id)_object inContext:(id)_context {
244 return [self isGreaterThan:_object];
246 - (BOOL)isLessThanOrEqualTo:(id)_object inContext:(id)_context {
247 return [self isLessThanOrEqualTo:_object];
249 - (BOOL)isGreaterThanOrEqualTo:(id)_object inContext:(id)_context {
250 return [self isGreaterThanOrEqualTo:_object];
253 - (BOOL)doesContain:(id)_object inContext:(id)_context {
254 return [self doesContain:_object];
257 - (BOOL)isLike:(NSString *)_object inContext:(id)_context {
258 return [self isLike:_object];
260 - (BOOL)isCaseInsensitiveLike:(NSString *)_object inContext:(id)_context {
261 return [self isCaseInsensitiveLike:_object];