Skip to content

Commit bfef2b6

Browse files
author
Andy C
committed
[mycpp/runtime] Move hex/octal functions from mylib -> mops
So they can support mops::BigInt, which is 64 bits, and used in printf.
1 parent 77b823e commit bfef2b6

File tree

8 files changed

+85
-41
lines changed

8 files changed

+85
-41
lines changed

builtin/printf_osh.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from frontend import lexer
3232
from frontend import match
3333
from frontend import reader
34+
from mycpp import mops
3435
from mycpp import mylib
3536
from mycpp.mylib import log
3637
from osh import sh_expr_eval
@@ -378,14 +379,15 @@ def _Percent(self, pr, part, varargs, locs):
378379
"Can't format negative number %d with %%%s" % (d, typ),
379380
part.type)
380381

382+
big_d = mops.IntWiden(d)
381383
if typ == 'o':
382-
s = mylib.octal(d)
384+
s = mops.ToOctal(big_d)
383385
elif typ == 'x':
384-
s = mylib.hex_lower(d)
386+
s = mops.ToHexLower(big_d)
385387
elif typ == 'X':
386-
s = mylib.hex_upper(d)
388+
s = mops.ToHexUpper(big_d)
387389
else: # diu
388-
s = str(d) # without spaces like ' -42 '
390+
s = mops.ToStr(big_d) # without spaces like ' -42 '
389391

390392
# There are TWO different ways to ZERO PAD, and they differ on
391393
# the negative sign! See spec/builtin-printf

mycpp/gc_mops.cc

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "mycpp/gc_mops.h"
22

33
#include <errno.h>
4+
#include <inttypes.h> // PRIo64, PRIx64
45
#include <stdio.h>
56

67
#include "mycpp/gc_alloc.h"
@@ -15,12 +16,32 @@ const BigInt MINUS_ONE = BigInt{-1};
1516

1617
static const int kInt64BufSize = 32; // more than twice as big as kIntBufSize
1718

18-
// Copied from gc_builtins - str(int i)
19+
// Note: Could also use OverAllocatedStr, but most strings are small?
20+
21+
// Similar to str(int i) in gc_builtins.cc
22+
1923
BigStr* ToStr(BigInt b) {
20-
BigStr* s = OverAllocatedStr(kInt64BufSize);
21-
int length = snprintf(s->data(), kInt64BufSize, "%ld", b);
22-
s->MaybeShrink(length);
23-
return s;
24+
char buf[kInt64BufSize];
25+
int len = snprintf(buf, kInt64BufSize, "%" PRId64, b);
26+
return ::StrFromC(buf, len);
27+
}
28+
29+
BigStr* ToOctal(BigInt b) {
30+
char buf[kInt64BufSize];
31+
int len = snprintf(buf, kInt64BufSize, "%" PRIo64, b);
32+
return ::StrFromC(buf, len);
33+
}
34+
35+
BigStr* ToHexUpper(BigInt b) {
36+
char buf[kInt64BufSize];
37+
int len = snprintf(buf, kInt64BufSize, "%" PRIX64, b);
38+
return ::StrFromC(buf, len);
39+
}
40+
41+
BigStr* ToHexLower(BigInt b) {
42+
char buf[kInt64BufSize];
43+
int len = snprintf(buf, kInt64BufSize, "%" PRIx64, b);
44+
return ::StrFromC(buf, len);
2445
}
2546

2647
// Copied from gc_builtins - to_int()

mycpp/gc_mops.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ extern const BigInt ONE;
2323
extern const BigInt MINUS_ONE;
2424

2525
BigStr* ToStr(BigInt b);
26+
BigStr* ToOctal(BigInt b);
27+
BigStr* ToHexUpper(BigInt b);
28+
BigStr* ToHexLower(BigInt b);
29+
2630
BigInt FromStr(BigStr* s, int base = 10);
2731

2832
inline int BigTruncate(BigInt b) {

mycpp/gc_mops_test.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,38 @@ TEST static_cast_test() {
5353
PASS();
5454
}
5555

56+
TEST conversion_test() {
57+
mops::BigInt int_min{INT64_MIN};
58+
mops::BigInt int_max{INT64_MAX};
59+
BigStr* int_str;
60+
61+
int_str = mops::ToStr(15);
62+
ASSERT(str_equals0("15", int_str));
63+
print(mops::ToStr(int_min));
64+
print(mops::ToStr(int_max));
65+
print(kEmptyString);
66+
67+
int_str = mops::ToOctal(15);
68+
ASSERT(str_equals0("17", int_str));
69+
print(mops::ToOctal(int_min));
70+
print(mops::ToOctal(int_max));
71+
print(kEmptyString);
72+
73+
int_str = mops::ToHexLower(15);
74+
ASSERT(str_equals0("f", int_str));
75+
print(mops::ToHexLower(int_min));
76+
print(mops::ToHexLower(int_max));
77+
print(kEmptyString);
78+
79+
int_str = mops::ToHexUpper(15);
80+
ASSERT(str_equals0("F", int_str));
81+
print(mops::ToHexUpper(int_min));
82+
print(mops::ToHexUpper(int_max));
83+
print(kEmptyString);
84+
85+
PASS();
86+
}
87+
5688
GREATEST_MAIN_DEFS();
5789

5890
int main(int argc, char** argv) {
@@ -62,6 +94,7 @@ int main(int argc, char** argv) {
6294

6395
RUN_TEST(bigint_test);
6496
RUN_TEST(static_cast_test);
97+
RUN_TEST(conversion_test);
6598

6699
gHeap.CleanProcessExit();
67100

mycpp/gc_mylib.h

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -121,26 +121,13 @@ void dict_erase(Dict<K, V>* haystack, K needle) {
121121
DCHECK(haystack->len_ < haystack->capacity_);
122122
}
123123

124-
// NOTE: Can use OverAllocatedStr for all of these, rather than copying
125-
126124
inline BigStr* hex_lower(int i) {
125+
// Note: Could also use OverAllocatedStr, but most strings are small?
127126
char buf[kIntBufSize];
128127
int len = snprintf(buf, kIntBufSize, "%x", i);
129128
return ::StrFromC(buf, len);
130129
}
131130

132-
inline BigStr* hex_upper(int i) {
133-
char buf[kIntBufSize];
134-
int len = snprintf(buf, kIntBufSize, "%X", i);
135-
return ::StrFromC(buf, len);
136-
}
137-
138-
inline BigStr* octal(int i) {
139-
char buf[kIntBufSize];
140-
int len = snprintf(buf, kIntBufSize, "%o", i);
141-
return ::StrFromC(buf, len);
142-
}
143-
144131
// Abstract type: Union of LineReader and Writer
145132
class File {
146133
public:

mycpp/gc_mylib_test.cc

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,6 @@ TEST int_to_str_test() {
5555
print(int_str);
5656
print(mylib::hex_lower(int_min));
5757

58-
int_str = mylib::hex_upper(15);
59-
ASSERT(str_equals0("F", int_str));
60-
print(mylib::hex_upper(int_min));
61-
62-
int_str = mylib::octal(15);
63-
ASSERT(str_equals0("17", int_str));
64-
print(mylib::octal(int_min));
65-
6658
PASS();
6759
}
6860

mycpp/mops.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,21 @@ def ToStr(b):
5656
return str(b.i)
5757

5858

59+
def ToOctal(b):
60+
# type: (BigInt) -> str
61+
return '%o' % b.i
62+
63+
64+
def ToHexUpper(b):
65+
# type: (BigInt) -> str
66+
return '%X' % b.i
67+
68+
69+
def ToHexLower(b):
70+
# type: (BigInt) -> str
71+
return '%x' % b.i
72+
73+
5974
def FromStr(s, base=10):
6075
# type: (str, int) -> BigInt
6176
return BigInt(int(s, base))

mycpp/mylib.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -374,16 +374,6 @@ def hex_lower(i):
374374
return '%x' % i
375375

376376

377-
def hex_upper(i):
378-
# type: (int) -> str
379-
return '%X' % i
380-
381-
382-
def octal(i):
383-
# type: (int) -> str
384-
return '%o' % i
385-
386-
387377
def dict_erase(d, key):
388378
# type: (Dict[Any, Any], Any) -> None
389379
"""

0 commit comments

Comments
 (0)