Hi, Did you find anything wrong with this patch? Please let me know if it needs corrections.
Thanks ! Best Regards, Abbas Raza On 1 September 2016 at 14:45, Abbas Raza <abbas.raza.1...@gmail.com> wrote: > Signed-off-by: Abbas Raza <abbas.raza.1...@gmail.com> > --- > Headers/Foundation/NSScanner.h | 3 +- > Source/NSScanner.m | 143 ++++++++++++++++++++++++++++++ > +++++++++-- > Tests/base/NSScanner/test01.m | 17 +++++ > 3 files changed, 157 insertions(+), 6 deletions(-) > > diff --git a/Headers/Foundation/NSScanner.h b/Headers/Foundation/NSScanner > .h > index a3b61dd..b103642 100644 > --- a/Headers/Foundation/NSScanner.h > +++ b/Headers/Foundation/NSScanner.h > @@ -94,6 +94,7 @@ extern "C" { > - (BOOL) scanInt: (int*)value; > - (BOOL) scanHexInt: (unsigned int*)value; > - (BOOL) scanLongLong: (long long*)value; > +- (BOOL) scanHexLongLong: (unsigned long long*)value; > - (BOOL) scanFloat: (float*)value; > - (BOOL) scanDouble: (double*)value; > - (BOOL) scanString: (NSString*)string intoString: (NSString**)value; > @@ -116,8 +117,6 @@ extern "C" { > /** Not implemented */ > - (BOOL) scanHexFloat: (float *)result; > /** Not implemented */ > -- (BOOL) scanHexLongLong: (unsigned long long *)result; > -/** Not implemented */ > - (BOOL) scanInteger: (NSInteger *)value; > #endif > @end > diff --git a/Source/NSScanner.m b/Source/NSScanner.m > index 26c3077..149be49 100644 > --- a/Source/NSScanner.m > +++ b/Source/NSScanner.m > @@ -629,6 +629,145 @@ typedef GSString *ivars; > #endif /* defined(LLONG_MAX) */ > } > > +/* > + * Scan an unsigned long long of the given radix into value. > + * Internal version used by scanHexLongLong: . > + */ > +- (BOOL) scanUnsignedLongLong_: (unsigned long long int*)value > + radix: (NSUInteger)radix > + gotDigits: (BOOL)gotDigits > +{ > +#if defined(ULLONG_MAX) > + unsigned long long int num = 0; > + unsigned long long int numLimit, digitLimit, digitValue; > + BOOL overflow = NO; > + unsigned int saveScanLocation = _scanLocation; > + > + /* Set limits */ > + numLimit = ULLONG_MAX / radix; > + digitLimit = ULLONG_MAX % radix; > + > + /* Process digits */ > + while (_scanLocation < myLength()) > + { > + unichar digit = myCharacter(_scanLocation); > + > + switch (digit) > + { > + case '0': digitValue = 0; break; > + case '1': digitValue = 1; break; > + case '2': digitValue = 2; break; > + case '3': digitValue = 3; break; > + case '4': digitValue = 4; break; > + case '5': digitValue = 5; break; > + case '6': digitValue = 6; break; > + case '7': digitValue = 7; break; > + case '8': digitValue = 8; break; > + case '9': digitValue = 9; break; > + case 'a': digitValue = 0xA; break; > + case 'b': digitValue = 0xB; break; > + case 'c': digitValue = 0xC; break; > + case 'd': digitValue = 0xD; break; > + case 'e': digitValue = 0xE; break; > + case 'f': digitValue = 0xF; break; > + case 'A': digitValue = 0xA; break; > + case 'B': digitValue = 0xB; break; > + case 'C': digitValue = 0xC; break; > + case 'D': digitValue = 0xD; break; > + case 'E': digitValue = 0xE; break; > + case 'F': digitValue = 0xF; break; > + default: > + digitValue = radix; > + break; > + } > + if (digitValue >= radix) > + break; > + if (!overflow) > + { > + if ((num > numLimit) > + || ((num == numLimit) && (digitValue > digitLimit))) > + overflow = YES; > + else > + num = num * radix + digitValue; > + } > + _scanLocation++; > + gotDigits = YES; > + } > + > + /* Save result */ > + if (!gotDigits) > + { > + _scanLocation = saveScanLocation; > + return NO; > + } > + if (value) > + { > + if (overflow) > + *value = ULLONG_MAX; > + else > + *value = num; > + } > + return YES; > +#else /* defined(ULLONG_MAX) */ > + /* > + * Provide compile-time warning and run-time exception. > + */ > +# warning "Can't use unsigned long long variables." > + [NSException raise: NSGenericException > + format: @"Can't use unsigned long long variables."]; > + return NO; > +#endif /* defined(ULLONG_MAX) */ > +} > + > +/** > + * After initial skipping (if any), this method scans a hexadecimal > + * long long value (optionally prefixed by "0x" or "0X"), > + * placing it in <em>longLongValue</em> if that is not null. > + * <br/> > + * Returns YES if anything is scanned, NO otherwise. > + * <br/> > + * On overflow, ULLONG_MAX or ULLONG_MAX is put into > <em>longLongValue</em> > + * <br/> > + * Scans past any excess digits > + */ > +- (BOOL) scanHexLongLong: (unsigned long long*)value > +{ > + unsigned int saveScanLocation = _scanLocation; > + > + /* Skip whitespace */ > + if (!skipToNextField()) > + { > + _scanLocation = saveScanLocation; > + return NO; > + } > + > + if ((_scanLocation < myLength()) && (myCharacter(_scanLocation) == '0')) > + { > + _scanLocation++; > + if (_scanLocation < myLength()) > + { > + switch (myCharacter(_scanLocation)) > + { > + case 'x': > + case 'X': > + _scanLocation++; // Scan beyond the 0x prefix > + break; > + default: > + _scanLocation--; // Scan from the initial digit > + break; > + } > + } > + else > + { > + _scanLocation--; // Just scan the zero. > + } > + } > + if ([self scanUnsignedLongLong_: value radix: 16 gotDigits: NO]) > + return YES; > + _scanLocation = saveScanLocation; > + return NO; > +} > + > /** > * Not implemented. > */ > @@ -1140,10 +1279,6 @@ typedef GSString *ivars; > { > return NO; // FIXME > } > -- (BOOL) scanHexLongLong: (unsigned long long *)result > -{ > - return NO; // FIXME > -} > - (BOOL) scanInteger: (NSInteger *)value > { > #if GS_SIZEOF_VOIDP == GS_SIZEOF_INT > diff --git a/Tests/base/NSScanner/test01.m b/Tests/base/NSScanner/test01.m > index 63dd912..13cc29e 100644 > --- a/Tests/base/NSScanner/test01.m > +++ b/Tests/base/NSScanner/test01.m > @@ -51,6 +51,19 @@ static BOOL scanHex(NSString *str, > return ((expectValue == 1) ? (expectedValue == *retp) : YES > && expectedScanLoc == [scn scanLocation]); > } > + > +static BOOL scanHexLongLong(NSString *str, > + int expectValue, > + unsigned long long expectedValue, > + int expectedScanLoc, > + int *retp) > +{ > + NSScanner *scn = [NSScanner scannerWithString:str]; > + [scn scanHexLongLong:retp]; > + return ((expectValue == 1) ? (expectedValue == *retp) : YES > + && expectedScanLoc == [scn scanLocation]); > +} > + > static BOOL scanDouble(NSString *str, > double expectedValue, > double *retp) > @@ -104,6 +117,10 @@ int main() > PASS(scanHex(@"1234FOO", 1, 0x1234F, 5, &ret) > && scanHex(@"01234FOO", 1, 0x1234F, 6, &ret), > "NSScanner hex (non-digits terminate scan)"); > + > + PASS(scanHexLongLong(@"1234FOO", 1, 0x1234F, 5, &ret) > + && scanHexLongLong(@"01234FOO", 1, 0x1234F, 6, &ret), > + "NSScanner hex long long (non-digits terminate scan)"); > /* dbl1 = 123.456; > dbl2 = 123.45678901234567890123456789012345678901234567; > dbl3 = 1.23456789; > -- > 2.1.4 > > >
_______________________________________________ Bug-gnustep mailing list Bug-gnustep@gnu.org https://lists.gnu.org/mailman/listinfo/bug-gnustep