2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE 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 SOPE 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 SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include "EOQualifier+CtxEval.h"
23 #import <EOControl/EOKeyValueCoding.h>
24 #import <EOControl/EONull.h>
27 #if LIB_FOUNDATION_LIBRARY
28 # import <objc/objc-api.h>
29 # import <objc/objc.h>
30 # import <extensions/objc-runtime.h>
31 #elif GNUSTEP_BASE_LIBRARY
32 # import <objc/objc-api.h>
34 # import <objc/objc.h>
35 # define sel_get_name sel_getName
38 static inline int countSelArgs(SEL _sel) {
39 register const char *selName;
41 if ((selName = sel_get_name(_sel))) {
44 for (count = 0; *selName; selName++) {
54 @implementation EOQualifier(ContextEvaluation)
56 - (BOOL)evaluateWithObject:(id)_object context:(id)_context {
57 [self doesNotRecognizeSelector:_cmd]; /* subclass */
61 @end /* EOQualifier(ContextEvaluation) */
63 @implementation NSArray(ContextEvaluation)
65 - (NSArray *)filteredArrayUsingQualifier:(EOQualifier *)_qualifier
68 NSMutableArray *a = nil;
71 for (i = 0, count = [self count]; i < count; i++) {
74 o = [self objectAtIndex:i];
76 if ([_qualifier evaluateWithObject:o context:_context]) {
77 if (a == nil) a = [NSMutableArray arrayWithCapacity:count];
81 return a ? [[a copy] autorelease] : [NSArray array];
84 @end /* NSArray(ContextEvaluation) */
86 @implementation EOAndQualifier(ContextEvaluation)
88 - (BOOL)evaluateWithObject:(id)_object context:(id)_context {
93 qs = [self qualifiers];
94 objAtIdx = [qs methodForSelector:@selector(objectAtIndex:)];
96 for (i = 0; i < [qs count]; i++) {
99 q = objAtIdx(qs, @selector(objectAtIndex:), i);
101 if (![q evaluateWithObject:_object context:_context])
107 @end /* EOAndQualifier(ContextEvaluation) */
109 @implementation EOOrQualifier(ContextEvaluation)
111 - (BOOL)evaluateWithObject:(id)_object context:(id)_context {
116 qs = [self qualifiers];
117 objAtIdx = [qs methodForSelector:@selector(objectAtIndex:)];
119 for (i = 0; i < [qs count]; i++) {
122 q = objAtIdx(qs, @selector(objectAtIndex:), i);
124 if ([q evaluateWithObject:_object context:_context])
130 @end /* EOOrQualifier(ContextEvaluation) */
132 @implementation EONotQualifier(ContextEvaluation)
134 - (BOOL)evaluateWithObject:(id)_object context:(id)_context {
136 [[self qualifier] evaluateWithObject:_object context:_context]
140 @end /* EONotQualifier(ContextEvaluation) */
142 @implementation EOKeyValueQualifier(ContextEvaluation)
144 - (BOOL)evaluateWithObject:(id)_object context:(id)_context {
145 static EONull *null = nil;
149 BOOL (*unary)(id, SEL);
150 BOOL (*binary)(id, SEL, id);
151 BOOL (*ctx)(id, SEL, id, id);
155 op = [self selector];
156 lv = [_object valueForKeyPath:[self key]];
159 if (null == nil) null = [EONull null];
160 if (lv == nil) lv = null;
161 if (rv == nil) rv = null;
163 if ((m.m = [lv methodForSelector:op]) == NULL) {
164 /* no such operator method ! */
165 [lv doesNotRecognizeSelector:op];
168 switch (countSelArgs(op)) {
171 NSLog(@"%s: called with invalid selector %@", __PRETTY_FUNCTION__,
172 NSStringFromSelector(op));
176 return m.unary(lv, op);
178 return m.binary(lv, op, rv);
180 return m.ctx(lv, op, rv, _context);
184 @end /* EOKeyValueQualifier(ContextEvaluation) */
186 @implementation EOKeyComparisonQualifier(ContextEvaluation)
188 - (BOOL)evaluateWithObject:(id)_object context:(id)_context {
189 static EONull *null = nil;
193 BOOL (*unary)(id, SEL);
194 BOOL (*binary)(id, SEL, id);
195 BOOL (*ctx)(id, SEL, id, id);
199 lv = [_object valueForKeyPath:[self leftKey]];
200 rv = [_object valueForKeyPath:[self rightKey]];
201 if (null == nil) null = [EONull null];
202 if (lv == nil) lv = null;
203 if (rv == nil) rv = null;
205 op = [self selector];
207 if ((m.m = (void *)[lv methodForSelector:op]) == NULL) {
208 /* no such operator method ! */
209 [lv doesNotRecognizeSelector:op];
212 switch (countSelArgs(op)) {
215 NSLog(@"%s: called with invalid selector %@", __PRETTY_FUNCTION__,
216 NSStringFromSelector(op));
220 return m.unary(lv, op);
222 return m.binary(lv, op, rv);
224 return m.ctx(lv, op, rv, _context);
228 @end /* EOKeyComparisonQualifier(ContextEvaluation) */
230 @implementation NSObject(ImplementedQualifierComparisons2)
232 - (BOOL)isEqualTo:(id)_object inContext:(id)_context {
233 return [self isEqualTo:_object];
235 - (BOOL)isNotEqualTo:(id)_object inContext:(id)_context {
236 return [self isNotEqualTo:_object];
239 - (BOOL)isLessThan:(id)_object inContext:(id)_context {
240 return [self isLessThan:_object];
242 - (BOOL)isGreaterThan:(id)_object inContext:(id)_context {
243 return [self isGreaterThan:_object];
245 - (BOOL)isLessThanOrEqualTo:(id)_object inContext:(id)_context {
246 return [self isLessThanOrEqualTo:_object];
248 - (BOOL)isGreaterThanOrEqualTo:(id)_object inContext:(id)_context {
249 return [self isGreaterThanOrEqualTo:_object];
252 - (BOOL)doesContain:(id)_object inContext:(id)_context {
253 return [self doesContain:_object];
256 - (BOOL)isLike:(NSString *)_object inContext:(id)_context {
257 return [self isLike:_object];
259 - (BOOL)isCaseInsensitiveLike:(NSString *)_object inContext:(id)_context {
260 return [self isCaseInsensitiveLike:_object];