Skip to content

Commit

Permalink
Change String#to_i to parse octals with prefix 0o
Browse files Browse the repository at this point in the history
This is a breaking change.
Previously, numbers starting with 0 would be parsed as octals.
A previous change in Crystal requires octals start with 0o.
Now that is not the case, and they will be parsed as base-10.
The 0o prefix must be present to treat it as an octal.
This addresses parsing 0 with prefix: true raising an error.

Additionally, YAML parsing used the old style.
This updates the spec to handle the new parsing.
  • Loading branch information
icy-arctic-fox committed Apr 18, 2019
1 parent 639e476 commit fc5610f
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 16 deletions.
6 changes: 5 additions & 1 deletion spec/std/string_spec.cr
Expand Up @@ -235,7 +235,10 @@ describe "String" do
it { "0x123abc".to_i(prefix: true).should eq(1194684) }
it { "0b1101".to_i(prefix: true).should eq(13) }
it { "0b001101".to_i(prefix: true).should eq(13) }
it { "0123".to_i(prefix: true).should eq(83) }
it { "0123".to_i(prefix: true).should eq(123) }
it { "0o123".to_i(prefix: true).should eq(83) }
it { "5".to_i(prefix: true).should eq(5) }
it { "0".to_i(prefix: true).should eq(0) }
it { "123hello".to_i(strict: false).should eq(123) }
it { "99 red balloons".to_i(strict: false).should eq(99) }
it { " 99 red balloons".to_i(strict: false).should eq(99) }
Expand All @@ -247,6 +250,7 @@ describe "String" do
it { expect_raises(ArgumentError) { "0b123".to_i } }
it { expect_raises(ArgumentError) { "000b123".to_i(prefix: true) } }
it { expect_raises(ArgumentError) { "000x123".to_i(prefix: true) } }
it { expect_raises(ArgumentError) { "000o89a".to_i(prefix: true) } }
it { expect_raises(ArgumentError) { "123hello".to_i } }
it { "z".to_i(36).should eq(35) }
it { "Z".to_i(36).should eq(35) }
Expand Down
8 changes: 5 additions & 3 deletions spec/std/yaml/schema/core_spec.cr
Expand Up @@ -104,8 +104,9 @@ describe YAML::Schema::Core do
it_parses_scalar "0b10110", 0b10110

# integer (octal)
it_parses_scalar "00", 0
it_parses_scalar "0123", 0o123
it_parses_scalar "0o0", 0
it_parses_scalar "0o123", 0o123
it_parses_scalar "0755", 0o755

# integer (hex)
it_parses_scalar "0x0", 0
Expand Down Expand Up @@ -207,9 +208,10 @@ describe YAML::Schema::Core do
it_raises_on_parse "!!float 'hello'", "Invalid float"

# !!int
it_parses "!!int 0", 0
it_parses "!!int 123", 123
it_parses "!!int 0b10", 0b10
it_parses "!!int 0123", 0o123
it_parses "!!int 0o123", 0o123
it_parses "!!int 0xabc", 0xabc
it_parses "!!int -123", -123
it_raises_on_parse "!!int 'hello'", "Invalid int"
Expand Down
30 changes: 18 additions & 12 deletions src/string.cr
Expand Up @@ -289,7 +289,7 @@ class String
# Options:
# * **whitespace**: if `true`, leading and trailing whitespaces are allowed
# * **underscore**: if `true`, underscores in numbers are allowed
# * **prefix**: if `true`, the prefixes `"0x"`, `"0"` and `"0b"` override the base
# * **prefix**: if `true`, the prefixes `"0x"`, `"0o"` and `"0b"` override the base
# * **strict**: if `true`, extraneous characters past the end of the number are disallowed
#
# ```
Expand Down Expand Up @@ -539,17 +539,23 @@ class String
ptr += 1

if prefix
case ptr.value.unsafe_chr
when 'b'
base = 2
ptr += 1
when 'x'
base = 16
ptr += 1
else
base = 8
end
found_digit = false
found_digit = case ptr.value.unsafe_chr
when 'b'
base = 2
ptr += 1
false
when 'x'
base = 16
ptr += 1
false
when 'o'
base = 8
ptr += 1
false
else
base = 10
true
end
else
found_digit = true
end
Expand Down

0 comments on commit fc5610f

Please sign in to comment.