2 Copyright (C) 2000-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
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 "NSString+misc.h"
26 @interface NSStringVariableBindingException : NSException
29 @implementation NSStringVariableBindingException
32 @implementation NSObject(StringBindings)
34 - (NSString *)valueForStringBinding:(NSString *)_key {
35 if (_key == nil) return nil;
36 return [[self valueForKey:_key] stringValue];
39 @end /* NSObject(StringBindings) */
41 @implementation NSDictionary(StringBindings)
43 - (NSString *)valueForStringBinding:(NSString *)_key {
44 if (_key == nil) return nil;
45 return [[self objectForKey:_key] stringValue];
48 @end /* NSDictionary(StringBindings) */
50 @implementation NSString(misc)
52 - (NSSet *)bindingVariables
54 unsigned len, pos = 0;
55 const char *buf = NULL;
56 NSMutableSet *result = nil;
58 result = [NSMutableSet set];
59 len = [self cStringLength];
65 if (pos + 1 == len) { /* last entry */
66 if (buf[pos] == '$') { /* found $ without end-char */
67 [[[NSStringVariableBindingException alloc]
68 initWithFormat:@"did not find end of variable for string %@", self]
73 if (buf[pos] != '$') {
78 if (buf[pos + 1] == '$') { /* found $$ --> ignore*/
87 pos += 2; /* buf[pos + 1] != '$' */
94 if (pos == len) { /* end of string was reached */
95 [[[NSStringVariableBindingException alloc]
96 initWithFormat:@"didn`t find end of "
97 @"variable for string %@", self]
103 key = [[NSString alloc]
104 initWithCStringNoCopy:(char*)buf + startPos + 1
105 length:pos - startPos - 1
107 [result addObject:key];
112 return [[result copy] autorelease];
115 - (NSString *)stringByReplacingVariablesWithBindings:(id)_bindings
116 stringForUnknownBindings:(NSString *)_unknown
118 unsigned len, pos = 0;
119 const char *buf = NULL;
120 NSMutableString *str = nil;
122 str = [self mutableCopy];
123 len = [str cStringLength];
127 if (pos + 1 == len) { /* last entry */
128 if (buf[pos] == '$') { /* found $ without end-char */
129 [[[NSStringVariableBindingException alloc]
130 initWithFormat:@"did not find end of variable for string %@", self]
135 if (buf[pos] == '$') {
136 if (buf[pos + 1] == '$') { /* found $$ --> $ */
137 [str deleteCharactersInRange:NSMakeRange(pos, 1)];
139 len = [str cStringLength];
142 unsigned startPos = pos;
144 pos += 2; /* buf[pos + 1] != '$' */
151 if (pos == len) { /* end of string was reached */
152 [[[NSStringVariableBindingException alloc]
153 initWithFormat:@"did not find end of variable for string %@",
160 key = [[NSString alloc]
161 initWithCStringNoCopy:(char*)buf + startPos + 1
162 length:pos - startPos - 1
165 if ((value = [_bindings valueForStringBinding:key]) == nil) {
166 if (_unknown == nil) {
167 [[[NSStringVariableBindingException alloc]
168 initWithFormat:@"did not find binding for "
169 @"name %@ in binding-dictionary %@",
170 [key autorelease], _bindings] raise];
175 [key release]; key = nil;
176 [str replaceCharactersInRange:
177 NSMakeRange(startPos, pos - startPos + 1)
180 len = [str cStringLength];
181 pos = startPos - 1 + [value length];
190 [tmp release]; tmp = nil;
192 return [str autorelease];
195 - (NSString *)stringByReplacingVariablesWithBindings:(id)_bindings {
196 return [self stringByReplacingVariablesWithBindings:_bindings
197 stringForUnknownBindings:nil];
200 @end /* NSString(misc) */
203 @implementation NSString(FilePathVersioningMethods)
208 - (NSString *)pathVersion {
211 r = [self rangeOfString:@";"];
213 return ([self length] > r.location)
214 ? [self substringFromIndex:(r.location + r.length)]
220 - (NSString *)stringByDeletingPathVersion {
223 r = [self rangeOfString:@";"];
224 return (r.length > 0)
225 ? [self substringToIndex:r.location]
229 - (NSString *)stringByAppendingPathVersion:(NSString *)_version {
230 return [[self stringByAppendingString:@";"]
231 stringByAppendingString:_version];
234 @end /* NSString(FilePathMethodsVersioning) */
236 @implementation NSString(NGScanning)
238 - (NSRange)rangeOfString:(NSString *)_s
239 skipQuotes:(NSString *)_quotes
240 escapedByChar:(unichar)_escape
243 // TODO: check correctness with invalid input !
244 static NSRange notFound = { 0, 0 };
245 NSCharacterSet *quotes;
246 unsigned i, len, slen;
249 if ((slen = [_s length]) == 0)
251 if ((len = [self length]) < slen) /* to short */
254 if ([_quotes length] == 0)
256 quotes = [NSCharacterSet characterSetWithCharactersInString:_quotes];
258 sc = [_s characterAtIndex:0];
260 for (i = 0; i < len; i++) {
263 c = [self characterAtIndex:i];
266 /* start search section */
268 return NSMakeRange(i, 1);
270 if ([[self substringFromIndex:i] hasPrefix:_s])
271 return NSMakeRange(i, slen);
273 else if ([quotes characterIsMember:c]) {
275 for (i++; i < len && ![quotes characterIsMember:c]; i++) {
277 i++; /* skip next char (eg \') */
287 - (NSRange)rangeOfString:(NSString *)_s skipQuotes:(NSString *)_quotes {
288 return [self rangeOfString:_s skipQuotes:_quotes escapedByChar:'\\'];
291 @end /* NSString(NGScanning) */
295 void __link_NSString_misc(void) {
296 __link_NSString_misc();