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 "NSString+misc.h"
25
@interface NSStringVariableBindingException : NSException
28
@implementation NSStringVariableBindingException
31
@implementation NSObject(StringBindings)
33
- (NSString *)valueForStringBinding:(NSString *)_key {
34
if (_key == nil) return nil;
35
return [[self valueForKey:_key] stringValue];
38
@end /* NSObject(StringBindings) */
40
@implementation NSDictionary(StringBindings)
42
- (NSString *)valueForStringBinding:(NSString *)_key {
43
if (_key == nil) return nil;
44
return [[self objectForKey:_key] stringValue];
47
@end /* NSDictionary(StringBindings) */
49
@implementation NSString(misc)
51
- (NSSet *)bindingVariables
53
unsigned len, pos = 0;
54
const char *buf = NULL;
55
NSMutableSet *result = nil;
57
result = [NSMutableSet set];
58
len = [self cStringLength];
64
if (pos + 1 == len) { /* last entry */
65
if (buf[pos] == '$') { /* found $ without end-char */
66
[[[NSStringVariableBindingException alloc]
67
initWithFormat:@"did not find end of variable for string %@", self]
72
if (buf[pos] != '$') {
77
if (buf[pos + 1] == '$') { /* found $$ --> ignore*/
86
pos += 2; /* buf[pos + 1] != '$' */
93
if (pos == len) { /* end of string was reached */
94
[[[NSStringVariableBindingException alloc]
95
initWithFormat:@"didn`t find end of "
96
@"variable for string %@", self]
102
key = [[NSString alloc]
103
initWithCStringNoCopy:(char*)buf + startPos + 1
104
length:pos - startPos - 1
106
[result addObject:key];
111
return [[result copy] autorelease];
114
- (NSString *)stringByReplacingVariablesWithBindings:(id)_bindings
115
stringForUnknownBindings:(NSString *)_unknown
117
unsigned len, pos = 0;
118
const char *buf = NULL;
119
NSMutableString *str = nil;
121
str = [self mutableCopy];
122
len = [str cStringLength];
126
if (pos + 1 == len) { /* last entry */
127
if (buf[pos] == '$') { /* found $ without end-char */
128
[[[NSStringVariableBindingException alloc]
129
initWithFormat:@"did not find end of variable for string %@", self]
134
if (buf[pos] == '$') {
135
if (buf[pos + 1] == '$') { /* found $$ --> $ */
136
[str deleteCharactersInRange:NSMakeRange(pos, 1)];
138
len = [str cStringLength];
141
unsigned startPos = pos;
143
pos += 2; /* buf[pos + 1] != '$' */
150
if (pos == len) { /* end of string was reached */
151
[[[NSStringVariableBindingException alloc]
152
initWithFormat:@"did not find end of variable for string %@",
159
key = [[NSString alloc]
160
initWithCStringNoCopy:(char*)buf + startPos + 1
161
length:pos - startPos - 1
164
if ((value = [_bindings valueForStringBinding:key]) == nil) {
165
if (_unknown == nil) {
166
[[[NSStringVariableBindingException alloc]
167
initWithFormat:@"did not find binding for "
168
@"name %@ in binding-dictionary %@",
169
[key autorelease], _bindings] raise];
174
[key release]; key = nil;
175
[str replaceCharactersInRange:
176
NSMakeRange(startPos, pos - startPos + 1)
179
len = [str cStringLength];
180
pos = startPos - 1 + [value length];
189
[tmp release]; tmp = nil;
191
return [str autorelease];
194
- (NSString *)stringByReplacingVariablesWithBindings:(id)_bindings {
195
return [self stringByReplacingVariablesWithBindings:_bindings
196
stringForUnknownBindings:nil];
199
@end /* NSString(misc) */
202
@implementation NSString(FilePathVersioningMethods)
207
- (NSString *)pathVersion {
210
r = [self rangeOfString:@";"];
212
return ([self length] > r.location)
213
? [self substringFromIndex:(r.location + r.length)]
219
- (NSString *)stringByDeletingPathVersion {
222
r = [self rangeOfString:@";"];
223
return (r.length > 0)
224
? [self substringToIndex:r.location]
228
- (NSString *)stringByAppendingPathVersion:(NSString *)_version {
229
return [[self stringByAppendingString:@";"]
230
stringByAppendingString:_version];
233
@end /* NSString(FilePathMethodsVersioning) */
235
@implementation NSString(NGScanning)
237
- (NSRange)rangeOfString:(NSString *)_s
238
skipQuotes:(NSString *)_quotes
239
escapedByChar:(unichar)_escape
242
// TODO: check correctness with invalid input !
243
static NSRange notFound = { 0, 0 };
244
NSCharacterSet *quotes;
245
unsigned i, len, slen;
248
if ((slen = [_s length]) == 0)
250
if ((len = [self length]) < slen) /* to short */
253
if ([_quotes length] == 0)
255
quotes = [NSCharacterSet characterSetWithCharactersInString:_quotes];
257
sc = [_s characterAtIndex:0];
259
for (i = 0; i < len; i++) {
262
c = [self characterAtIndex:i];
265
/* start search section */
267
return NSMakeRange(i, 1);
269
if ([[self substringFromIndex:i] hasPrefix:_s])
270
return NSMakeRange(i, slen);
272
else if ([quotes characterIsMember:c]) {
274
for (i++; i < len && ![quotes characterIsMember:c]; i++) {
276
i++; /* skip next char (eg \') */
286
- (NSRange)rangeOfString:(NSString *)_s skipQuotes:(NSString *)_quotes {
287
return [self rangeOfString:_s skipQuotes:_quotes escapedByChar:'\\'];
290
@end /* NSString(NGScanning) */
294
void __link_NSString_misc(void) {
295
__link_NSString_misc();