Merge branch 'CPScanner' of https://github.com/cacaodev/cappuccino into cacaodev-CPScanner

Conflicts:
	Foundation/CPScanner.j
This commit is contained in:
Randall Luecke
2011-03-23 21:43:43 -04:00
2 changed files with 95 additions and 102 deletions
+21 -102
View File
@@ -33,41 +33,6 @@
CPCharacterSet _charactersToBeSkipped;
}
// TODO Not all methods of NSScanner are available!
/*
- (BOOL)scanLongLong:(long long *)longLongValue
{
}
- (BOOL)scanDecimal:(NSDecimal *)decimalValue
{
}
- (BOOL)scanHexDouble:(double *)result
{
}
- (BOOL)scanHexFloat:(float *)result
{
}
- (BOOL)scanHexInt:(unsigned *)intValue
{
}
- (BOOL)scanHexLongLong:(unsigned long long *)result
{
}
- (BOOL)scanInteger:(NSInteger *)value
{
}
+ (id)localizedScannerWithString:(CPString)string
{
var scanner = [self scannerWithString:string];
[scanner setLocale:[CPLocale currentLocale]];
return scanner;
}
*/
+ (id)scannerWithString:(CPString)aString
{
return [[self alloc] initWithString:aString];
@@ -158,10 +123,13 @@
{
var ret = [self performSelector:s withObject:arg];
if (ret == nil)
return NO;
if (ref != nil)
ref(ret);
return ret != NULL;
return YES;
}
/* ================================ */
@@ -307,88 +275,39 @@
/* = Scanning numbers = */
/* ==================== */
- (float)scanFloat
- (float)scanWithParseFunction:(Function)parseFunction
{
[self _movePastCharactersToBeSkipped];
var str = [self string],
current = [self scanLocation];
loc = [self scanLocation];
if ([self isAtEnd])
return 0;
var s = str.substring(current, str.length),
f = parseFloat(s); // wont work with non . decimal separator !!
var s = str.substring(loc, str.length),
f = parseFunction(s);
if (f)
{
var pos = current,
foundDash = NO;
/*
var decimalSeparatorString;
if (_locale != nil)
decimalSeparatorString = [_locale objectForKey:CPLocaleDecimalSeparator];
else
decimalSeparatorString = [[CPLocale systemLocale] objectForKey:CPLocaleDecimalSeparator];
if (isNaN(f))
return nil;
var separatorCode = (decimalSeparatorString.length >0) decimalSeparatorString.charCodeAt(0) : 45;
*/
var separatorCode = 45;
loc += (""+f).length;
var i = 0;
while (!isNaN(parseFloat(str.substring(loc+i, str.length))))
{i++;}
for (; pos < current + str.length; pos++)
{
var charCode = str.charCodeAt(pos);
if (charCode == separatorCode)
{
if (foundDash == YES)
break; // We already found a decimal separator so this one is an extra char
foundDash = YES;
}
else if (charCode < 48 || charCode > 57 || (charCode == 45 && pos != current)) // not a digit or a "-" but not prefix
break;
}
[self setScanLocation:loc + i];
return f;
[self setScanLocation:pos];
return f;
}
}
return nil;
- (float)scanFloat
{
return [self scanWithParseFunction:parseFloat];
}
- (int)scanInt
{
[self _movePastCharactersToBeSkipped];
var str = [self string],
current = [self scanLocation];
if ([self isAtEnd])
return 0;
var s = str.substring(current, str.length),
i = parseInt(s);
if (i)
{
var pos = current,
foundDash = NO;
for (; pos < current + str.length; pos++)
{
var charCode = str.charCodeAt(pos);
if (charCode == 46)
{
if (foundDash == YES)
break;
foundDash = YES;
}
else if (charCode < 48 || charCode > 57 || (charCode == 45 && pos != current))
break;
}
[self setScanLocation:pos];
return i;
}
return nil;
return [self scanWithParseFunction:parseInt];
}
- (BOOL)scanInt:(int)intoInt
+74
View File
@@ -0,0 +1,74 @@
@import <Foundation/CPScanner.j>
@implementation CPScannerTest : OJTestCase
- (void)performScanMethod:(SEL)selector searchFor:(id)search inScanner:(CPString)scanner succeeded:(BOOL)success found:/*accumulated result or nil if nothing should be accumulated*/(id)accumulator endedAt:(int)endLocation
{
if ([scanner isKindOfClass:[CPString class]])
scanner = [CPScanner scannerWithString:scanner];
var objj_args = [scanner, selector],
value = @"initialValue";
if (accumulator == nil)
accumulator = value;
if (search != nil)
objj_args.push(search);
objj_args.push(function(v){value = v;});
var didScan = objj_msgSend.apply(this, objj_args);
[self assert:success equals:didScan message:scanner + " Scan operation: "];
[self assert:accumulator equals:value message:scanner + " Accumulator: "];
if (endLocation != nil)
[self assert:endLocation equals:[scanner scanLocation] message:scanner + " Scan location: "];
}
- (void)testScanInt
{
[self performScanMethod:@selector(scanInt:) searchFor:nil inScanner:@"1" succeeded:YES found:1 endedAt:1];
[self performScanMethod:@selector(scanInt:) searchFor:nil inScanner:@" 12" succeeded:YES found:12 endedAt:3];
[self performScanMethod:@selector(scanInt:) searchFor:nil inScanner:@"01" succeeded:YES found:1 endedAt:2];
[self performScanMethod:@selector(scanInt:) searchFor:nil inScanner:@"131F02" succeeded:YES found:131 endedAt:3];
[self performScanMethod:@selector(scanInt:) searchFor:nil inScanner:@"word" succeeded:NO found:nil endedAt:0];
[self performScanMethod:@selector(scanInt:) searchFor:nil inScanner:@"0S" succeeded:YES found:0 endedAt:1];
}
- (void)testScanFloat
{
[self performScanMethod:@selector(scanFloat:) searchFor:nil inScanner:@"1" succeeded:YES found:1 endedAt:1];
[self performScanMethod:@selector(scanFloat:) searchFor:nil inScanner:@"1.2" succeeded:YES found:1.2 endedAt:3];
[self performScanMethod:@selector(scanFloat:) searchFor:nil inScanner:@"-1.2" succeeded:YES found:-1.2 endedAt:4];
[self performScanMethod:@selector(scanFloat:) searchFor:nil inScanner:@"1.2x" succeeded:YES found:1.2 endedAt:3];
[self performScanMethod:@selector(scanFloat:) searchFor:nil inScanner:@"word" succeeded:NO found:nil endedAt:0];
[self performScanMethod:@selector(scanFloat:) searchFor:nil inScanner:@"0.00" succeeded:YES found:0 endedAt:4];
// wrong end location
[self performScanMethod:@selector(scanFloat:) searchFor:nil inScanner:@".1-2" succeeded:YES found:0.1 endedAt:nil];
[self performScanMethod:@selector(scanFloat:) searchFor:nil inScanner:@"1.2.3" succeeded:YES found:1.2 endedAt:nil];
[self performScanMethod:@selector(scanFloat:) searchFor:nil inScanner:@"-1.2-3" succeeded:YES found:-1.2 endedAt:nil];
}
- (void)testScanString
{
[self performScanMethod:@selector(scanString:intoString:) searchFor:@"t" inScanner:@"topaz" succeeded:YES found:@"t" endedAt:1];
[self performScanMethod:@selector(scanString:intoString:) searchFor:@"z" inScanner:@"topaz" succeeded:NO found:nil endedAt:0];
[self performScanMethod:@selector(scanString:intoString:) searchFor:@"tt" inScanner:@"topaz" succeeded:NO found:nil endedAt:0];
[self performScanMethod:@selector(scanUpToString:intoString:) searchFor:@"a" inScanner:@"topaz" succeeded:YES found:@"top" endedAt:3];
[self performScanMethod:@selector(scanUpToString:intoString:) searchFor:@"x" inScanner:@"topaz" succeeded:YES found:@"topaz" endedAt:5];
[self performScanMethod:@selector(scanUpToString:intoString:) searchFor:@"x" inScanner:@"" succeeded:NO found:nil endedAt:0];
}
- (void)testScanCharactersFromSet
{
[self performScanMethod:@selector(scanCharactersFromSet:intoString:) searchFor:[CPCharacterSet lowercaseLetterCharacterSet] inScanner:@"topAz" succeeded:YES found:@"top" endedAt:3];
[self performScanMethod:@selector(scanCharactersFromSet:intoString:) searchFor:[CPCharacterSet alphanumericCharacterSet] inScanner:@"top12Az&x" succeeded:YES found:@"top12Az" endedAt:7];
[self performScanMethod:@selector(scanCharactersFromSet:intoString:) searchFor:[CPCharacterSet decomposableCharacterSet] inScanner:@"êñço" succeeded:YES found:@"êñç" endedAt:3];
}
@end