2
Copyright (C) 2000-2008 SKYRIX Software AG
3
Copyright (C) 2006-2008 Helge Hess
5
This file is part of SOPE.
7
SOPE is free software; you can redistribute it and/or modify it under
8
the terms of the GNU Lesser General Public License as published by the
9
Free Software Foundation; either version 2, or (at your option) any
12
SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
License for more details.
17
You should have received a copy of the GNU Lesser General Public
18
License along with SOPE; see the file COPYING. If not, write to the
19
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 valueForKeyPath:_key] stringValue];
39
@end /* NSObject(StringBindings) */
41
@implementation NSString(misc)
43
- (NSSet *)bindingVariables
45
unsigned len, pos = 0;
47
NSMutableSet *result = nil;
49
result = [NSMutableSet setWithCapacity:16];
51
wbuf = malloc(sizeof(unichar) * (len + 4));
52
[self getCharacters:wbuf];
57
if (pos + 1 == len) { /* last entry */
58
if (wbuf[pos] == '$') { /* found $ without end-char */
59
[[[NSStringVariableBindingException alloc]
60
initWithFormat:@"did not find end of variable for string %@", self]
65
if (wbuf[pos] != '$') {
70
if (wbuf[pos + 1] == '$') { /* found $$ --> ignore*/
79
pos += 2; /* wbuf[pos + 1] != '$' */
86
if (pos == len) { /* end of string was reached */
87
[[[NSStringVariableBindingException alloc]
88
initWithFormat:@"did not find end of variable for string %@", self]
94
key = [[NSString alloc]
95
initWithCharacters:(unichar *)wbuf + startPos + 1
96
length:(pos - startPos - 1)];
97
[result addObject:key];
102
if (wbuf != NULL) { free(wbuf); wbuf = NULL; }
104
return [[result copy] autorelease];
107
- (NSString *)stringByReplacingVariablesWithBindings:(id)_bindings
108
stringForUnknownBindings:(NSString *)_unknown
110
unsigned len, pos = 0;
111
unichar *wbuf = NULL;
112
NSMutableString *str = nil;
114
str = [self mutableCopy];
116
wbuf = malloc(sizeof(unichar) * (len + 4));
117
[self getCharacters:wbuf];
120
if (pos + 1 == len) { /* last entry */
121
if (wbuf[pos] == '$') { /* found $ without end-char */
122
[[[NSStringVariableBindingException alloc]
123
initWithFormat:@"did not find end of variable for string %@", self]
128
if (wbuf[pos] == '$') {
129
if (wbuf[pos + 1] == '$') { /* found $$ --> $ */
130
[str deleteCharactersInRange:NSMakeRange(pos, 1)];
132
if (wbuf != NULL) { free(wbuf); wbuf = NULL; }
134
wbuf = malloc(sizeof(unichar) * (len + 4));
135
[str getCharacters:wbuf];
138
unsigned startPos = pos;
140
pos += 2; /* wbuf[pos + 1] != '$' */
142
if (wbuf[pos] != '$')
147
if (pos == len) { /* end of string was reached */
148
[[[NSStringVariableBindingException alloc]
149
initWithFormat:@"did not find end of variable for string %@",
156
key = [[NSString alloc]
157
initWithCharacters:(wbuf + startPos + 1)
158
length:(pos - startPos - 1)];
160
if ((value = [_bindings valueForStringBinding:key]) == nil) {
161
if (_unknown == nil) {
162
[[[NSStringVariableBindingException alloc]
163
initWithFormat:@"did not find binding for "
164
@"name %@ in binding-dictionary %@",
165
[key autorelease], _bindings] raise];
170
[key release]; key = nil;
172
[str replaceCharactersInRange:
173
NSMakeRange(startPos, pos - startPos + 1)
176
if (wbuf != NULL) { free(wbuf); wbuf = NULL; }
178
wbuf = malloc(sizeof(unichar) * (len + 4));
179
[str getCharacters:wbuf];
181
pos = startPos - 1 + [value length];
187
if (wbuf != NULL) { free(wbuf); wbuf = NULL; }
191
[tmp release]; tmp = nil;
193
return [str autorelease];
196
- (NSString *)stringByReplacingVariablesWithBindings:(id)_bindings {
197
return [self stringByReplacingVariablesWithBindings:_bindings
198
stringForUnknownBindings:nil];
201
@end /* NSString(misc) */
204
@implementation NSString(FilePathVersioningMethods)
209
- (NSString *)pathVersion {
212
r = [self rangeOfString:@";"];
214
return ([self length] > r.location)
215
? [self substringFromIndex:(r.location + r.length)]
221
- (NSString *)stringByDeletingPathVersion {
224
r = [self rangeOfString:@";"];
225
return (r.length > 0)
226
? [self substringToIndex:r.location]
230
- (NSString *)stringByAppendingPathVersion:(NSString *)_version {
231
return [[self stringByAppendingString:@";"]
232
stringByAppendingString:_version];
235
@end /* NSString(FilePathMethodsVersioning) */
237
@implementation NSString(NGScanning)
239
- (NSRange)rangeOfString:(NSString *)_s
240
skipQuotes:(NSString *)_quotes
241
escapedByChar:(unichar)_escape
244
// TODO: check correctness with invalid input !
245
static NSRange notFound = { 0, 0 };
246
NSCharacterSet *quotes;
247
unsigned i, len, slen;
250
if ((slen = [_s length]) == 0)
252
if ((len = [self length]) < slen) /* to short */
255
if ([_quotes length] == 0)
257
quotes = [NSCharacterSet characterSetWithCharactersInString:_quotes];
259
sc = [_s characterAtIndex:0];
261
for (i = 0; i < len; i++) {
264
c = [self characterAtIndex:i];
267
/* start search section */
269
return NSMakeRange(i, 1);
271
if ([[self substringFromIndex:i] hasPrefix:_s])
272
return NSMakeRange(i, slen);
274
else if ([quotes characterIsMember:c]) {
277
c = [self characterAtIndex:i];
278
for (; i < len && ![quotes characterIsMember:c]; i++) {
279
c = [self characterAtIndex:i];
281
i++; /* skip next char (eg \') */
291
- (NSRange)rangeOfString:(NSString *)_s skipQuotes:(NSString *)_quotes {
292
return [self rangeOfString:_s skipQuotes:_quotes escapedByChar:'\\'];
295
@end /* NSString(NGScanning) */
298
@implementation NSString(MailQuoting)
300
- (NSString *)stringByApplyingMailQuoting {
303
unichar *sourceBuf, *targetBuf;
305
if ((len = [self length]) == 0)
308
sourceBuf = malloc((len + 4) * sizeof(unichar));
309
[self getCharacters:sourceBuf];
311
for (nl = 0, i = 0; i < len; i++) {
312
if (sourceBuf[i] == '\n')
317
if (sourceBuf) free(sourceBuf);
318
return [@"> " stringByAppendingString:self];
321
targetBuf = malloc((len + 8 + (nl * 3)) * sizeof(unichar));
326
for (i = 0; i < len; i++) {
327
targetBuf[nl] = sourceBuf[i];
330
if (sourceBuf[i] == '\n' && (i + 1 != len)) {
331
targetBuf[nl] = '>'; nl++;
332
targetBuf[nl] = ' '; nl++;
336
s = [[NSString alloc] initWithCharacters:targetBuf length:nl];
337
if (targetBuf) free(targetBuf);
338
if (sourceBuf) free(sourceBuf);
339
return [s autorelease];
342
@end /* NSString(MailQuoting) */
346
void __link_NSString_misc(void) {
347
__link_NSString_misc();