PR#6316: Scanf.scanf failure on %u formats when reading big integers.
The approach implemented is the second one suggested by Benoît Vaugon in the PR: - The int_of_string functions accept a "0u" prefix meaning "decimal unsigned". - The '%u' format of the scanf functions adds this "0u" prefix before conversion. This is consistent with the current handling of unsigned hexa, octal, and binary numbers. git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16241 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02master
parent
844b1af40c
commit
a1bafbbb67
2
Changes
2
Changes
|
@ -45,6 +45,8 @@ Runtime system:
|
|||
(Peter Zotov, review by Jacques-Henri Jourdan)
|
||||
|
||||
Standard library:
|
||||
- PR#6316: Scanf.scanf failure on %u formats when reading big integers
|
||||
(Xavier Leroy, Benoît Vaugon)
|
||||
- PR#6390, GPR#36: expose Sys.{int_size,max_wosize} for improved js_of_ocaml portability
|
||||
(Hugo Heuzard)
|
||||
* PR#6494: Add equal function in modules
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
static char * parse_sign_and_base(char * p,
|
||||
/*out*/ int * base,
|
||||
/*out*/ int * signedness,
|
||||
/*out*/ int * sign)
|
||||
{
|
||||
*sign = 1;
|
||||
|
@ -30,15 +31,17 @@ static char * parse_sign_and_base(char * p,
|
|||
*sign = -1;
|
||||
p++;
|
||||
}
|
||||
*base = 10;
|
||||
*base = 10; *signedness = 1;
|
||||
if (*p == '0') {
|
||||
switch (p[1]) {
|
||||
case 'x': case 'X':
|
||||
*base = 16; p += 2; break;
|
||||
*base = 16; *signedness = 0; p += 2; break;
|
||||
case 'o': case 'O':
|
||||
*base = 8; p += 2; break;
|
||||
*base = 8; *signedness = 0; p += 2; break;
|
||||
case 'b': case 'B':
|
||||
*base = 2; p += 2; break;
|
||||
*base = 2; *signedness = 0; p += 2; break;
|
||||
case 'u': case 'U':
|
||||
*signedness = 0; p += 2; break;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
|
@ -65,9 +68,9 @@ static intnat parse_intnat(value s, int nbits, const char *errmsg)
|
|||
{
|
||||
char * p;
|
||||
uintnat res, threshold;
|
||||
int sign, base, d;
|
||||
int sign, base, signedness, d;
|
||||
|
||||
p = parse_sign_and_base(String_val(s), &base, &sign);
|
||||
p = parse_sign_and_base(String_val(s), &base, &signedness, &sign);
|
||||
threshold = ((uintnat) -1) / base;
|
||||
d = parse_digit(*p);
|
||||
if (d < 0 || d >= base) caml_failwith(errmsg);
|
||||
|
@ -85,7 +88,7 @@ static intnat parse_intnat(value s, int nbits, const char *errmsg)
|
|||
if (p != String_val(s) + caml_string_length(s)){
|
||||
caml_failwith(errmsg);
|
||||
}
|
||||
if (base == 10) {
|
||||
if (signedness) {
|
||||
/* Signed representation expected, allow -2^(nbits-1) to 2^(nbits-1) - 1 */
|
||||
if (sign >= 0) {
|
||||
if (res >= (uintnat)1 << (nbits - 1)) caml_failwith(errmsg);
|
||||
|
@ -530,9 +533,9 @@ CAMLprim value caml_int64_of_string(value s)
|
|||
{
|
||||
char * p;
|
||||
uint64_t res, threshold;
|
||||
int sign, base, d;
|
||||
int sign, base, signedness, d;
|
||||
|
||||
p = parse_sign_and_base(String_val(s), &base, &sign);
|
||||
p = parse_sign_and_base(String_val(s), &base, &signedness, &sign);
|
||||
threshold = ((uint64_t) -1) / base;
|
||||
d = parse_digit(*p);
|
||||
if (d < 0 || d >= base) caml_failwith(INT64_ERRMSG);
|
||||
|
@ -551,7 +554,7 @@ CAMLprim value caml_int64_of_string(value s)
|
|||
if (p != String_val(s) + caml_string_length(s)){
|
||||
caml_failwith(INT64_ERRMSG);
|
||||
}
|
||||
if (base == 10) {
|
||||
if (signedness) {
|
||||
/* Signed representation expected, allow -2^63 to 2^63 - 1 only */
|
||||
if (sign >= 0) {
|
||||
if (res >= (uint64_t)1 << 63) caml_failwith(INT64_ERRMSG);
|
||||
|
|
|
@ -500,7 +500,8 @@ let token_bool ib =
|
|||
let token_int_literal conv ib =
|
||||
let tok =
|
||||
match conv with
|
||||
| 'd' | 'i' | 'u' -> Scanning.token ib
|
||||
| 'd' | 'i' -> Scanning.token ib
|
||||
| 'u' -> "0u" ^ Scanning.token ib
|
||||
| 'o' -> "0o" ^ Scanning.token ib
|
||||
| 'x' | 'X' -> "0x" ^ Scanning.token ib
|
||||
| 'b' -> "0b" ^ Scanning.token ib
|
||||
|
|
Loading…
Reference in New Issue