Skip to content

Commit d9db3ac

Browse files
Fix everything else
A bunch of string conversion/testing code needed to be updated. I'm gonna need to clean it up more later but that's gonna be a followup. Also I need to set up the ctype function in bazel. Blarg.
1 parent 795ba04 commit d9db3ac

File tree

21 files changed

+312
-81
lines changed

21 files changed

+312
-81
lines changed

libc/src/__support/high_precision_decimal.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,11 @@ class HighPrecisionDecimal {
178178
if (digit_index >= this->num_digits) {
179179
return new_digits - 1;
180180
}
181-
if (this->digits[digit_index] != power_of_five[digit_index] - '0') {
181+
if (this->digits[digit_index] !=
182+
internal::b36_char_to_int(power_of_five[digit_index])) {
182183
return new_digits -
183-
((this->digits[digit_index] < power_of_five[digit_index] - '0')
184+
((this->digits[digit_index] <
185+
internal::b36_char_to_int(power_of_five[digit_index]))
184186
? 1
185187
: 0);
186188
}
@@ -337,8 +339,8 @@ class HighPrecisionDecimal {
337339
}
338340
++total_digits;
339341
if (this->num_digits < MAX_NUM_DIGITS) {
340-
this->digits[this->num_digits] =
341-
static_cast<uint8_t>(num_string[num_cur] - '0');
342+
this->digits[this->num_digits] = static_cast<uint8_t>(
343+
internal::b36_char_to_int(num_string[num_cur]));
342344
++this->num_digits;
343345
} else if (num_string[num_cur] != '0') {
344346
this->truncated = true;

libc/src/__support/integer_to_string.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
#include "src/__support/CPP/type_traits.h"
7070
#include "src/__support/big_int.h" // make_integral_or_big_int_unsigned_t
7171
#include "src/__support/common.h"
72+
#include "src/__support/ctype_utils.h"
7273
#include "src/__support/macros/config.h"
7374

7475
namespace LIBC_NAMESPACE_DECL {
@@ -214,9 +215,9 @@ template <typename T, typename Fmt = radix::Dec> class IntegerToString {
214215
using UNSIGNED_T = make_integral_or_big_int_unsigned_t<T>;
215216

216217
LIBC_INLINE static char digit_char(uint8_t digit) {
217-
if (digit < 10)
218-
return '0' + static_cast<char>(digit);
219-
return (Fmt::IS_UPPERCASE ? 'A' : 'a') + static_cast<char>(digit - 10);
218+
const char result = static_cast<char>(internal::int_to_b36_char(digit));
219+
return static_cast<char>(Fmt::IS_UPPERCASE ? internal::toupper(result)
220+
: result);
220221
}
221222

222223
LIBC_INLINE static void

libc/src/__support/str_to_float.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ decimal_string_to_float(const char *__restrict src, const char DECIMAL_POINT,
909909
cpp::numeric_limits<StorageType>::max() / BASE;
910910
while (true) {
911911
if (isdigit(src[index])) {
912-
uint32_t digit = src[index] - '0';
912+
uint32_t digit = b36_char_to_int(src[index]);
913913
seen_digit = true;
914914

915915
if (mantissa < bitstype_max_div_by_base) {

libc/src/__support/str_to_integer.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,14 @@ first_non_whitespace(const char *__restrict src,
4242
return src + src_cur;
4343
}
4444

45-
LIBC_INLINE int b36_char_to_int(char input) {
46-
if (isdigit(input))
47-
return input - '0';
48-
if (isalpha(input))
49-
return (input | 32) + 10 - 'a';
50-
return 0;
51-
}
52-
5345
// checks if the next 3 characters of the string pointer are the start of a
5446
// hexadecimal number. Does not advance the string pointer.
5547
LIBC_INLINE bool
5648
is_hex_start(const char *__restrict src,
5749
size_t src_len = cpp::numeric_limits<size_t>::max()) {
5850
if (src_len < 3)
5951
return false;
60-
return *src == '0' && (*(src + 1) | 32) == 'x' && isalnum(*(src + 2)) &&
52+
return *src == '0' && tolower(*(src + 1)) == 'x' && isalnum(*(src + 2)) &&
6153
b36_char_to_int(*(src + 2)) < 16;
6254
}
6355

libc/src/ctype/toupper.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@
1414

1515
namespace LIBC_NAMESPACE_DECL {
1616

17-
LLVM_LIBC_FUNCTION(int, toupper, (int c)) {
18-
if (internal::islower(c))
19-
return c - ('a' - 'A');
20-
return c;
21-
}
17+
LLVM_LIBC_FUNCTION(int, toupper, (int c)) { return internal::toupper(c); }
2218

2319
} // namespace LIBC_NAMESPACE_DECL

libc/src/ctype/toupper_l.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
namespace LIBC_NAMESPACE_DECL {
1616

1717
LLVM_LIBC_FUNCTION(int, toupper_l, (int c, locale_t)) {
18-
if (internal::islower(c))
19-
return c - ('a' - 'A');
20-
return c;
18+
return internal::toupper(c);
2119
}
2220

2321
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdio/printf_core/float_hex_converter.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer,
2929
const FormatSection &to_conv) {
3030
using LDBits = fputil::FPBits<long double>;
3131
using StorageType = LDBits::StorageType;
32-
// All of the letters will be defined relative to variable a, which will be
33-
// the appropriate case based on the name of the conversion. This converts any
34-
// conversion name into the letter 'a' with the appropriate case.
3532

3633
bool is_negative;
3734
int exponent;

libc/test/UnitTest/MemoryMatcher.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "MemoryMatcher.h"
1010

11+
#include "src/__support/ctype_utils.h"
1112
#include "src/__support/macros/config.h"
1213
#include "test/UnitTest/Test.h"
1314

@@ -40,7 +41,8 @@ bool MemoryMatcher::match(MemoryView actualValue) {
4041

4142
static void display(char C) {
4243
const auto print = [](unsigned char I) {
43-
tlog << static_cast<char>(I < 10 ? '0' + I : 'A' + I - 10);
44+
tlog << static_cast<char>(LIBC_NAMESPACE::internal::toupper(
45+
LIBC_NAMESPACE::internal::int_to_b36_char(I)));
4446
};
4547
print(static_cast<unsigned char>(C) / 16);
4648
print(static_cast<unsigned char>(C) & 15);

libc/test/src/__support/CPP/stringview_test.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,6 @@ TEST(LlvmLibcStringViewTest, Observer) {
109109
ASSERT_EQ(ABC.back(), 'c');
110110
}
111111

112-
bool isDigit(char c) { return c >= '0' && c <= '9'; }
113-
114112
TEST(LlvmLibcStringViewTest, FindFirstOf) {
115113
string_view Tmp("abca");
116114
ASSERT_TRUE(Tmp.find_first_of('a') == 0);
@@ -236,6 +234,9 @@ TEST(LlvmLibcStringViewTest, FindFirstNotOf) {
236234

237235
TEST(LlvmLibcStringViewTest, Contains) {
238236
string_view Empty;
237+
static_assert(
238+
'a' < 'z',
239+
"This test only supports character encodings where 'a' is below 'z'");
239240
for (char c = 'a'; c < 'z'; ++c)
240241
EXPECT_FALSE(Empty.contains(c));
241242

libc/test/src/ctype/isalnum_test.cpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,46 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "src/__support/CPP/span.h"
910
#include "src/ctype/isalnum.h"
1011

1112
#include "test/UnitTest/Test.h"
1213

14+
TEST(LlvmLibcIsAlNum, SimpleTest) {
15+
EXPECT_NE(LIBC_NAMESPACE::isalnum('a'), 0);
16+
EXPECT_NE(LIBC_NAMESPACE::isalnum('B'), 0);
17+
EXPECT_NE(LIBC_NAMESPACE::isalnum('3'), 0);
18+
19+
EXPECT_EQ(LIBC_NAMESPACE::isalnum(' '), 0);
20+
EXPECT_EQ(LIBC_NAMESPACE::isalnum('?'), 0);
21+
EXPECT_EQ(LIBC_NAMESPACE::isalnum('\0'), 0);
22+
EXPECT_EQ(LIBC_NAMESPACE::isalnum(-1), 0);
23+
}
24+
25+
// TODO: Merge the ctype tests using this framework.
26+
constexpr char ALNUM_ARRAY[] = {
27+
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
28+
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
29+
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
30+
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
31+
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
32+
};
33+
34+
bool in_span(int ch, LIBC_NAMESPACE::cpp::span<const char> arr) {
35+
for (size_t i = 0; i < arr.size(); ++i) {
36+
if (static_cast<int>(arr[i]) == ch)
37+
return true;
38+
}
39+
return false;
40+
}
41+
1342
TEST(LlvmLibcIsAlNum, DefaultLocale) {
1443
// Loops through all characters, verifying that numbers and letters
1544
// return non-zero integer and everything else returns a zero.
16-
for (int c = -255; c < 255; ++c) {
17-
if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') ||
18-
('0' <= c && c <= '9'))
19-
EXPECT_NE(LIBC_NAMESPACE::isalnum(c), 0);
45+
for (int ch = -255; ch < 255; ++ch) {
46+
if (in_span(ch, ALNUM_ARRAY))
47+
EXPECT_NE(LIBC_NAMESPACE::isalnum(ch), 0);
2048
else
21-
EXPECT_EQ(LIBC_NAMESPACE::isalnum(c), 0);
49+
EXPECT_EQ(LIBC_NAMESPACE::isalnum(ch), 0);
2250
}
2351
}

0 commit comments

Comments
 (0)