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 - (NSString *)stringByApplyingCEscaping {
58 cstr = [self cString];
59 buffer = malloc([self cStringLength] * 2 + 1);
64 buffer[pos] = '\\'; pos++;
68 buffer[pos] = '\\'; pos++;
72 buffer[pos] = '\\'; pos++;
85 #if NeXT_Foundation_LIBRARY || GNUSTEP_BASE_LIBRARY
89 s = buffer ? [NSString stringWithCString:buffer] : nil;
90 if (buffer) free(buffer);
94 return [NSString stringWithCStringNoCopy:buffer freeWhenDone:YES];
97 - (NSSet *)bindingVariables
99 unsigned len, pos = 0;
100 const char *buf = NULL;
101 NSMutableSet *result = nil;
103 result = [NSMutableSet set];
104 len = [self cStringLength];
105 buf = [self cString];
110 if (pos + 1 == len) { /* last entry */
111 if (buf[pos] == '$') { /* found $ without end-char */
112 [[[NSStringVariableBindingException alloc]
113 initWithFormat:@"did not find end of variable for string %@", self]
118 if (buf[pos] != '$') {
123 if (buf[pos + 1] == '$') { /* found $$ --> ignore*/
128 /* process binding */
132 pos += 2; /* buf[pos + 1] != '$' */
139 if (pos == len) { /* end of string was reached */
140 [[[NSStringVariableBindingException alloc]
141 initWithFormat:@"didn`t find end of "
142 @"variable for string %@", self]
148 key = [[NSString alloc]
149 initWithCStringNoCopy:(char*)buf + startPos + 1
150 length:pos - startPos - 1
152 [result addObject:key];
157 return [[result copy] autorelease];
160 - (NSString *)stringByReplacingVariablesWithBindings:(id)_bindings
161 stringForUnknownBindings:(NSString *)_unknown
163 unsigned len, pos = 0;
164 const char *buf = NULL;
165 NSMutableString *str = nil;
167 str = [self mutableCopy];
168 len = [str cStringLength];
172 if (pos + 1 == len) { /* last entry */
173 if (buf[pos] == '$') { /* found $ without end-char */
174 [[[NSStringVariableBindingException alloc]
175 initWithFormat:@"did not find end of variable for string %@", self]
180 if (buf[pos] == '$') {
181 if (buf[pos + 1] == '$') { /* found $$ --> $ */
182 [str deleteCharactersInRange:NSMakeRange(pos, 1)];
184 len = [str cStringLength];
187 unsigned startPos = pos;
189 pos += 2; /* buf[pos + 1] != '$' */
196 if (pos == len) { /* end of string was reached */
197 [[[NSStringVariableBindingException alloc]
198 initWithFormat:@"did not find end of variable for string %@",
205 key = [[NSString alloc]
206 initWithCStringNoCopy:(char*)buf + startPos + 1
207 length:pos - startPos - 1
210 if ((value = [_bindings valueForStringBinding:key]) == nil) {
211 if (_unknown == nil) {
212 [[[NSStringVariableBindingException alloc]
213 initWithFormat:@"did not find binding for "
214 @"name %@ in binding-dictionary %@",
215 [key autorelease], _bindings] raise];
220 [key release]; key = nil;
221 [str replaceCharactersInRange:
222 NSMakeRange(startPos, pos - startPos + 1)
225 len = [str cStringLength];
226 pos = startPos - 1 + [value length];
235 [tmp release]; tmp = nil;
237 return [str autorelease];
240 - (NSString *)stringByReplacingVariablesWithBindings:(id)_bindings {
241 return [self stringByReplacingVariablesWithBindings:_bindings
242 stringForUnknownBindings:nil];
245 @end /* NSString(misc) */
248 @implementation NSString(FilePathVersioningMethods)
253 - (NSString *)pathVersion {
256 r = [self rangeOfString:@";"];
258 return ([self length] > r.location)
259 ? [self substringFromIndex:(r.location + r.length)]
265 - (NSString *)stringByDeletingPathVersion {
268 r = [self rangeOfString:@";"];
269 return (r.length > 0)
270 ? [self substringToIndex:r.location]
274 - (NSString *)stringByAppendingPathVersion:(NSString *)_version {
275 return [[self stringByAppendingString:@";"]
276 stringByAppendingString:_version];
279 @end /* NSString(FilePathMethodsVersioning) */
281 @implementation NSString(NGScanning)
283 - (NSRange)rangeOfString:(NSString *)_s
284 skipQuotes:(NSString *)_quotes
285 escapedByChar:(unichar)_escape
288 // TODO: check correctness with invalid input !
289 static NSRange notFound = { 0, 0 };
290 NSCharacterSet *quotes;
291 unsigned i, len, slen;
294 if ((slen = [_s length]) == 0)
296 if ((len = [self length]) < slen) /* to short */
299 if ([_quotes length] == 0)
301 quotes = [NSCharacterSet characterSetWithCharactersInString:_quotes];
303 sc = [_s characterAtIndex:0];
305 for (i = 0; i < len; i++) {
308 c = [self characterAtIndex:i];
311 /* start search section */
313 return NSMakeRange(i, 1);
315 if ([[self substringFromIndex:i] hasPrefix:_s])
316 return NSMakeRange(i, slen);
318 else if ([quotes characterIsMember:c]) {
320 for (i++; i < len && ![quotes characterIsMember:c]; i++) {
322 i++; /* skip next char (eg \') */
332 - (NSRange)rangeOfString:(NSString *)_s skipQuotes:(NSString *)_quotes {
333 return [self rangeOfString:_s skipQuotes:_quotes escapedByChar:'\\'];
336 @end /* NSString(NGScanning) */
340 void __link_NSString_misc(void) {
341 __link_NSString_misc();