Skip to content

Commit 57d06d9

Browse files
committed
Simplify integer parsing
Simply treat the special octal case and let Python handle the rest. Also add extra tests, to show additional edge cases that are handled correctly.
1 parent 5c84d08 commit 57d06d9

File tree

2 files changed

+13
-17
lines changed

2 files changed

+13
-17
lines changed

esp32_ulp/util.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -79,24 +79,14 @@ def validate_expression(param):
7979

8080
def parse_int(literal):
8181
"""
82-
Parses string literals into integers, using base prefixes
83-
0xNNN (hex), 0bNNN (binary), and 0oNNN or 0NNN (octal).
84-
Without prefix will be treated as decimal.
82+
GNU as compatible parsing of string literals into integers
83+
Specifically, GNU as treats literals starting with 0 as octal
84+
All other literals are correctly parsed by Python
85+
See: https://sourceware.org/binutils/docs/as/Integers.html
8586
"""
86-
if len(literal) > 2:
87-
prefix_start = 1 if literal[0] == '-' else 0 # skip negative sign if present
88-
89-
if literal[prefix_start] == "0":
90-
prefix = literal[prefix_start + 1]
91-
if prefix == "x": # Hex
92-
return int(literal, 16)
93-
elif prefix == "b": # Binary
94-
return int(literal, 2)
95-
elif prefix == "o": # Octal, Python style (0oNNN)
96-
return int(literal, 8)
97-
return int(literal, 8) # Octal, GNU as style (0NNN)
98-
99-
return int(literal) # implicit decimal (base10)
87+
if len(literal) >= 2 and (literal.startswith("0") or literal.startswith("-0")) and literal.lstrip("-0").isdigit():
88+
return int(literal, 8)
89+
return int(literal, 0)
10090

10191

10292
def file_exists(filename):

tests/util.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ def test_validate_expression():
8585
@test
8686
def test_parse_int():
8787
# decimal
88+
assert parse_int("0") == 0, "0 == 0"
8889
assert parse_int("5") == 5, "5 == 5"
90+
assert parse_int("-0") == 0, "-0 == 0"
8991
assert parse_int("-5") == -5, "-5 == -5"
9092
# hex
9193
assert parse_int("0x5") == 5, "0x5 == 5"
@@ -95,10 +97,14 @@ def test_parse_int():
9597
assert parse_int("0b1001") == 9, "0b1001 == 9"
9698
assert parse_int("-0b1001") == -9, "-0b1001 == 9"
9799
# octal
100+
assert parse_int("07") == 7, "07 == 7"
98101
assert parse_int("0100") == 64, "0100 == 64"
99102
assert parse_int("0o210") == 136, "0o210 == 136"
103+
assert parse_int("00000010") == 8, "00000010 == 8"
104+
assert parse_int("-07") == -7, "-07 == -7"
100105
assert parse_int("-0100") == -64, "-0100 == -64"
101106
assert parse_int("-0o210") == -136, "-0o210 == -136"
107+
assert parse_int("-00000010") == -8, "-00000010 == -8"
102108
# negative cases
103109
assert_raises(ValueError, parse_int, '0b123', message="invalid syntax for integer with base 2: '123'")
104110
assert_raises(ValueError, parse_int, '0900', message="invalid syntax for integer with base 8: '0900'")

0 commit comments

Comments
 (0)