mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 08:41:03 +00:00
Patch by eric@skatter.usask.ca
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3638 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
3bb4214740
commit
34670971fc
4 changed files with 210 additions and 80 deletions
|
@ -211,42 +211,16 @@
|
|||
|
||||
/*
|
||||
* Scan an unsigned int of the given radix into value.
|
||||
* Internal version used by scanRadixUnsignedInt: and scanHexInt:.
|
||||
*/
|
||||
- (BOOL)scanRadixUnsignedInt: (unsigned int *)value
|
||||
- (BOOL)scanUnsignedInt_: (unsigned int *)value radix:(int)radix gotDigits:(BOOL)gotDigits
|
||||
{
|
||||
unsigned int num = 0;
|
||||
unsigned int numLimit, digitLimit, digitValue, radix;
|
||||
unsigned int numLimit, digitLimit, digitValue;
|
||||
BOOL overflow = NO;
|
||||
BOOL got_digits = NO;
|
||||
unsigned int saveScanLocation = scanLocation;
|
||||
|
||||
/* Skip whitespace */
|
||||
if (![self _skipToNextField])
|
||||
{
|
||||
scanLocation = saveScanLocation;
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* Check radix */
|
||||
radix = 10;
|
||||
if ((scanLocation < len) && ([string characterAtIndex:scanLocation] == '0'))
|
||||
{
|
||||
radix = 8;
|
||||
scanLocation++;
|
||||
got_digits = YES;
|
||||
if (scanLocation < len)
|
||||
{
|
||||
switch ([string characterAtIndex:scanLocation])
|
||||
{
|
||||
case 'x':
|
||||
case 'X':
|
||||
scanLocation++;
|
||||
radix = 16;
|
||||
got_digits = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Set limits */
|
||||
numLimit = UINT_MAX / radix;
|
||||
digitLimit = UINT_MAX % radix;
|
||||
|
||||
|
@ -292,11 +266,11 @@
|
|||
num = num * radix + digitValue;
|
||||
}
|
||||
scanLocation++;
|
||||
got_digits = YES;
|
||||
gotDigits = YES;
|
||||
}
|
||||
|
||||
/* Save result */
|
||||
if (!got_digits)
|
||||
if (!gotDigits)
|
||||
{
|
||||
scanLocation = saveScanLocation;
|
||||
return NO;
|
||||
|
@ -311,6 +285,67 @@
|
|||
return YES;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan an unsigned int of the given radix into value.
|
||||
*/
|
||||
- (BOOL)scanRadixUnsignedInt: (unsigned int *)value
|
||||
{
|
||||
int radix;
|
||||
BOOL gotDigits = NO;
|
||||
unsigned int saveScanLocation = scanLocation;
|
||||
|
||||
/* Skip whitespace */
|
||||
if (![self _skipToNextField])
|
||||
{
|
||||
scanLocation = saveScanLocation;
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* Check radix */
|
||||
radix = 10;
|
||||
if ((scanLocation < len) && ([string characterAtIndex:scanLocation] == '0'))
|
||||
{
|
||||
radix = 8;
|
||||
scanLocation++;
|
||||
gotDigits = YES;
|
||||
if (scanLocation < len)
|
||||
{
|
||||
switch ([string characterAtIndex:scanLocation])
|
||||
{
|
||||
case 'x':
|
||||
case 'X':
|
||||
scanLocation++;
|
||||
radix = 16;
|
||||
gotDigits = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( [self scanUnsignedInt_:value radix:radix gotDigits:gotDigits])
|
||||
return YES;
|
||||
scanLocation = saveScanLocation;
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan a hexadecimal unsigned integer into value.
|
||||
*/
|
||||
- (BOOL)scanHexInt: (unsigned int *)value
|
||||
{
|
||||
unsigned int saveScanLocation = scanLocation;
|
||||
|
||||
/* Skip whitespace */
|
||||
if (![self _skipToNextField])
|
||||
{
|
||||
scanLocation = saveScanLocation;
|
||||
return NO;
|
||||
}
|
||||
if ([self scanUnsignedInt_:value radix:16 gotDigits:NO])
|
||||
return YES;
|
||||
scanLocation = saveScanLocation;
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan a long long int into value.
|
||||
* Same as scanInt, except with different variable types and limits.
|
||||
|
@ -414,9 +449,9 @@
|
|||
}
|
||||
|
||||
/*
|
||||
* FIXME: Should get decimal point character from locale. The problem
|
||||
* is that I can't find anything in the OPENSTEP specification about
|
||||
* the format of the locale dictionary.
|
||||
* FIXME: Should get decimal point character from locale.
|
||||
* The key is NSDecimalSeparator.
|
||||
* The problem is that I can't find anything in GNUSTEP about locales.
|
||||
*/
|
||||
decimal = '.';
|
||||
|
||||
|
@ -471,27 +506,35 @@
|
|||
return NO;
|
||||
}
|
||||
|
||||
/* Check for trailing exponent
|
||||
Numbers like 1.23eFOO are rejected. */
|
||||
/* Check for trailing exponent */
|
||||
if ((scanLocation < len) && ((c == 'e') || (c == 'E')))
|
||||
{
|
||||
int exp;
|
||||
int expval;
|
||||
int expScanLocation = scanLocation;
|
||||
scanLocation++;
|
||||
if (![self _scanInt: &exp])
|
||||
if ([self _scanInt: &expval])
|
||||
{
|
||||
/* Check for exponent overflow */
|
||||
if (num)
|
||||
{
|
||||
if ((exponent > 0) && (expval > (LONG_MAX - exponent)))
|
||||
exponent = LONG_MAX;
|
||||
else if ((exponent < 0) && (expval < (LONG_MIN - exponent)))
|
||||
exponent = LONG_MIN;
|
||||
else
|
||||
exponent += expval;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _ACCEPT_BAD_EXPONENTS_
|
||||
/* Numbers like 1.23eFOO are accepted (as 1.23). */
|
||||
scanLocation = expScanLocation;
|
||||
#else
|
||||
/* Numbers like 1.23eFOO are rejected. */
|
||||
scanLocation = saveScanLocation;
|
||||
return NO;
|
||||
}
|
||||
|
||||
/* Check for exponent overflow */
|
||||
if (num)
|
||||
{
|
||||
if ((exponent > 0) && (exp > (LONG_MAX - exponent)))
|
||||
exponent = LONG_MAX;
|
||||
else if ((exponent < 0) && (exp < (LONG_MIN - exponent)))
|
||||
exponent = LONG_MIN;
|
||||
else
|
||||
exponent += exp;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (value)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue