1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 08:04:57 +00:00

AK: Make string-to-number conversion helpers return Optional

Get rid of the weird old signature:

- int StringType::to_int(bool& ok) const

And replace it with sensible new signature:

- Optional<int> StringType::to_int() const
This commit is contained in:
Andreas Kling 2020-06-12 21:07:52 +02:00
parent 15f4043a7a
commit fdfda6dec2
55 changed files with 354 additions and 455 deletions

View file

@ -26,6 +26,7 @@
#include <AK/FlyString.h> #include <AK/FlyString.h>
#include <AK/HashTable.h> #include <AK/HashTable.h>
#include <AK/Optional.h>
#include <AK/String.h> #include <AK/String.h>
#include <AK/StringUtils.h> #include <AK/StringUtils.h>
#include <AK/StringView.h> #include <AK/StringView.h>
@ -88,9 +89,9 @@ FlyString::FlyString(const char* string)
{ {
} }
int FlyString::to_int(bool& ok) const Optional<int> FlyString::to_int() const
{ {
return StringUtils::convert_to_int(view(), ok); return StringUtils::convert_to_int(view());
} }
bool FlyString::equals_ignoring_case(const StringView& other) const bool FlyString::equals_ignoring_case(const StringView& other) const

View file

@ -82,7 +82,7 @@ public:
FlyString to_lowercase() const; FlyString to_lowercase() const;
int to_int(bool& ok) const; Optional<int> to_int() const;
bool equals_ignoring_case(const StringView&) const; bool equals_ignoring_case(const StringView&) const;
bool ends_with(const StringView&, CaseSensitivity = CaseSensitivity::CaseSensitive) const; bool ends_with(const StringView&, CaseSensitivity = CaseSensitivity::CaseSensitive) const;

View file

@ -78,18 +78,11 @@ public:
auto parts = string.split_view('.'); auto parts = string.split_view('.');
if (parts.size() != 4) if (parts.size() != 4)
return {}; return {};
bool ok; auto a = parts[0].to_uint().value_or(256);
auto a = parts[0].to_uint(ok); auto b = parts[1].to_uint().value_or(256);
if (!ok || a > 255) auto c = parts[2].to_uint().value_or(256);
return {}; auto d = parts[3].to_uint().value_or(256);
auto b = parts[1].to_uint(ok); if (a > 255 || b > 255 || c > 255 || d > 255)
if (!ok || b > 255)
return {};
auto c = parts[2].to_uint(ok);
if (!ok || c > 255)
return {};
auto d = parts[3].to_uint(ok);
if (!ok || d > 255)
return {}; return {};
return IPv4Address((u8)a, (u8)b, (u8)c, (u8)d); return IPv4Address((u8)a, (u8)b, (u8)c, (u8)d);
} }

View file

@ -123,10 +123,9 @@ String JsonParser::consume_quoted_string()
sb.append(consume()); sb.append(consume());
sb.append(consume()); sb.append(consume());
bool ok; auto codepoint = AK::StringUtils::convert_to_uint_from_hex(sb.to_string());
u32 codepoint = AK::StringUtils::convert_to_uint_from_hex(sb.to_string(), ok); if (codepoint.has_value() && codepoint.value() < 0x80) {
if (ok && codepoint < 128) { buffer.append((char)codepoint.value());
buffer.append((char)codepoint);
} else { } else {
// FIXME: This is obviously not correct, but we don't have non-ASCII support so meh. // FIXME: This is obviously not correct, but we don't have non-ASCII support so meh.
buffer.append('?'); buffer.append('?');
@ -202,7 +201,6 @@ JsonValue JsonParser::parse_string()
JsonValue JsonParser::parse_number() JsonValue JsonParser::parse_number()
{ {
bool ok;
JsonValue value; JsonValue value;
Vector<char, 128> number_buffer; Vector<char, 128> number_buffer;
Vector<char, 128> fraction_buffer; Vector<char, 128> fraction_buffer;
@ -231,14 +229,17 @@ JsonValue JsonParser::parse_number()
#ifndef KERNEL #ifndef KERNEL
if (is_double) { if (is_double) {
int whole = number_string.to_uint(ok); // FIXME: This logic looks shaky.
if (!ok) int whole = 0;
whole = number_string.to_int(ok); auto to_signed_result = number_string.to_uint();
ASSERT(ok); if (to_signed_result.has_value()) {
whole = to_signed_result.value();
} else {
whole = number_string.to_int().value();
}
int fraction = fraction_string.to_uint(ok); int fraction = fraction_string.to_uint().value();
fraction *= (whole < 0) ? -1 : 1; fraction *= (whole < 0) ? -1 : 1;
ASSERT(ok);
auto divider = 1; auto divider = 1;
for (size_t i = 0; i < fraction_buffer.size(); ++i) { for (size_t i = 0; i < fraction_buffer.size(); ++i) {
@ -247,10 +248,12 @@ JsonValue JsonParser::parse_number()
value = JsonValue((double)whole + ((double)fraction / divider)); value = JsonValue((double)whole + ((double)fraction / divider));
} else { } else {
#endif #endif
value = JsonValue(number_string.to_uint(ok)); auto to_unsigned_result = number_string.to_uint();
if (!ok) if (to_unsigned_result.has_value()) {
value = JsonValue(number_string.to_int(ok)); value = JsonValue(to_unsigned_result.value());
ASSERT(ok); } else {
value = JsonValue(number_string.to_int().value());
}
#ifndef KERNEL #ifndef KERNEL
} }
#endif #endif

View file

@ -196,14 +196,14 @@ ByteBuffer String::to_byte_buffer() const
return ByteBuffer::copy(reinterpret_cast<const u8*>(characters()), length()); return ByteBuffer::copy(reinterpret_cast<const u8*>(characters()), length());
} }
int String::to_int(bool& ok) const Optional<int> String::to_int() const
{ {
return StringUtils::convert_to_int(this->view(), ok); return StringUtils::convert_to_int(view());
} }
unsigned String::to_uint(bool& ok) const Optional<unsigned> String::to_uint() const
{ {
return StringUtils::convert_to_uint(this->view(), ok); return StringUtils::convert_to_uint(view());
} }
String String::number(unsigned long long value) String String::number(unsigned long long value)

View file

@ -108,8 +108,8 @@ public:
static String repeated(char, size_t count); static String repeated(char, size_t count);
bool matches(const StringView& mask, CaseSensitivity = CaseSensitivity::CaseInsensitive) const; bool matches(const StringView& mask, CaseSensitivity = CaseSensitivity::CaseInsensitive) const;
int to_int(bool& ok) const; Optional<int> to_int() const;
unsigned to_uint(bool& ok) const; Optional<unsigned> to_uint() const;
String to_lowercase() const; String to_lowercase() const;
String to_uppercase() const; String to_uppercase() const;

View file

@ -26,6 +26,7 @@
*/ */
#include <AK/Memory.h> #include <AK/Memory.h>
#include <AK/Optional.h>
#include <AK/String.h> #include <AK/String.h>
#include <AK/StringUtils.h> #include <AK/StringUtils.h>
#include <AK/StringView.h> #include <AK/StringView.h>
@ -87,69 +88,54 @@ bool matches(const StringView& str, const StringView& mask, CaseSensitivity case
return (mask_ptr == mask_end) && string_ptr == string_end; return (mask_ptr == mask_end) && string_ptr == string_end;
} }
int convert_to_int(const StringView& str, bool& ok) Optional<int> convert_to_int(const StringView& str)
{ {
if (str.is_empty()) { if (str.is_empty())
ok = false; return {};
return 0;
}
bool negative = false; bool negative = false;
size_t i = 0; size_t i = 0;
const auto characters = str.characters_without_null_termination(); const auto characters = str.characters_without_null_termination();
if (characters[0] == '-' || characters[0] == '+') { if (characters[0] == '-' || characters[0] == '+') {
if (str.length() == 1) { if (str.length() == 1)
ok = false; return {};
return 0;
}
i++; i++;
negative = (characters[0] == '-'); negative = (characters[0] == '-');
} }
int value = 0; int value = 0;
for (; i < str.length(); i++) { for (; i < str.length(); i++) {
if (characters[i] < '0' || characters[i] > '9') { if (characters[i] < '0' || characters[i] > '9')
ok = false; return {};
return 0;
}
value = value * 10; value = value * 10;
value += characters[i] - '0'; value += characters[i] - '0';
} }
ok = true;
return negative ? -value : value; return negative ? -value : value;
} }
unsigned convert_to_uint(const StringView& str, bool& ok) Optional<unsigned> convert_to_uint(const StringView& str)
{ {
if (str.is_empty()) { if (str.is_empty())
ok = false; return {};
return 0;
}
unsigned value = 0; unsigned value = 0;
const auto characters = str.characters_without_null_termination(); const auto characters = str.characters_without_null_termination();
for (size_t i = 0; i < str.length(); i++) { for (size_t i = 0; i < str.length(); i++) {
if (characters[i] < '0' || characters[i] > '9') { if (characters[i] < '0' || characters[i] > '9')
ok = false; return {};
return 0;
}
value = value * 10; value = value * 10;
value += characters[i] - '0'; value += characters[i] - '0';
} }
ok = true;
return value; return value;
} }
unsigned convert_to_uint_from_hex(const StringView& str, bool& ok) Optional<unsigned> convert_to_uint_from_hex(const StringView& str)
{ {
if (str.is_empty()) { if (str.is_empty())
ok = false; return {};
return 0;
}
unsigned value = 0; unsigned value = 0;
const auto count = str.length(); const auto count = str.length();
@ -165,14 +151,11 @@ unsigned convert_to_uint_from_hex(const StringView& str, bool& ok)
} else if (digit >= 'A' && digit <= 'F') { } else if (digit >= 'A' && digit <= 'F') {
digit_val = 10 + (digit - 'A'); digit_val = 10 + (digit - 'A');
} else { } else {
ok = false; return {};
return 0;
} }
value = (value << 4) + digit_val; value = (value << 4) + digit_val;
} }
ok = true;
return value; return value;
} }

View file

@ -39,9 +39,9 @@ enum class CaseSensitivity {
namespace StringUtils { namespace StringUtils {
bool matches(const StringView& str, const StringView& mask, CaseSensitivity = CaseSensitivity::CaseInsensitive); bool matches(const StringView& str, const StringView& mask, CaseSensitivity = CaseSensitivity::CaseInsensitive);
int convert_to_int(const StringView&, bool& ok); Optional<int> convert_to_int(const StringView&);
unsigned convert_to_uint(const StringView&, bool& ok); Optional<unsigned> convert_to_uint(const StringView&);
unsigned convert_to_uint_from_hex(const StringView&, bool& ok); Optional<unsigned> convert_to_uint_from_hex(const StringView&);
bool equals_ignoring_case(const StringView&, const StringView&); bool equals_ignoring_case(const StringView&, const StringView&);
bool ends_with(const StringView& a, const StringView& b, CaseSensitivity); bool ends_with(const StringView& a, const StringView& b, CaseSensitivity);
} }

View file

@ -215,14 +215,14 @@ StringView StringView::substring_view_starting_after_substring(const StringView&
return { remaining_characters, remaining_length }; return { remaining_characters, remaining_length };
} }
int StringView::to_int(bool& ok) const Optional<int> StringView::to_int() const
{ {
return StringUtils::convert_to_int(*this, ok); return StringUtils::convert_to_int(*this);
} }
unsigned StringView::to_uint(bool& ok) const Optional<unsigned> StringView::to_uint() const
{ {
return StringUtils::convert_to_uint(*this, ok); return StringUtils::convert_to_uint(*this);
} }
unsigned StringView::hash() const unsigned StringView::hash() const

View file

@ -96,8 +96,8 @@ public:
// following newline.". // following newline.".
Vector<StringView> lines(bool consider_cr = true) const; Vector<StringView> lines(bool consider_cr = true) const;
int to_int(bool& ok) const; Optional<int> to_int() const;
unsigned to_uint(bool& ok) const; Optional<unsigned> to_uint() const;
// Create a new substring view of this string view, starting either at the beginning of // Create a new substring view of this string view, starting either at the beginning of
// the given substring view, or after its end, and continuing until the end of this string // the given substring view, or after its end, and continuing until the end of this string

View file

@ -72,8 +72,7 @@ TEST_CASE(order)
} }
for (int i = 0; i < 10000; ++i) { for (int i = 0; i < 10000; ++i) {
bool ok; EXPECT_EQ(strings.dequeue().to_int().value(), i);
EXPECT_EQ(strings.dequeue().to_int(ok), i);
} }
EXPECT(strings.is_empty()); EXPECT(strings.is_empty());

View file

@ -127,9 +127,8 @@ TEST_CASE(repeated)
TEST_CASE(to_int) TEST_CASE(to_int)
{ {
bool ok; EXPECT_EQ(String("123").to_int().value(), 123);
EXPECT(String("123").to_int(ok) == 123 && ok); EXPECT_EQ(String("-123").to_int().value(), -123);
EXPECT(String("-123").to_int(ok) == -123 && ok);
} }
TEST_CASE(to_lowercase) TEST_CASE(to_lowercase)

View file

@ -69,79 +69,88 @@ TEST_CASE(matches_case_insensitive)
TEST_CASE(convert_to_int) TEST_CASE(convert_to_int)
{ {
bool ok = false; auto value = AK::StringUtils::convert_to_int(StringView());
AK::StringUtils::convert_to_int(StringView(), ok); EXPECT(!value.has_value());
EXPECT(!ok);
AK::StringUtils::convert_to_int("", ok); AK::StringUtils::convert_to_int("");
EXPECT(!ok); EXPECT(!value.has_value());
AK::StringUtils::convert_to_int("a", ok); AK::StringUtils::convert_to_int("a");
EXPECT(!ok); EXPECT(!value.has_value());
AK::StringUtils::convert_to_int("+", ok); AK::StringUtils::convert_to_int("+");
EXPECT(!ok); EXPECT(!value.has_value());
AK::StringUtils::convert_to_int("-", ok); AK::StringUtils::convert_to_int("-");
EXPECT(!ok); EXPECT(!value.has_value());
int actual = AK::StringUtils::convert_to_int("0", ok); auto actual = AK::StringUtils::convert_to_int("0");
EXPECT(ok && actual == 0); EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 0);
actual = AK::StringUtils::convert_to_int("1", ok); actual = AK::StringUtils::convert_to_int("1");
EXPECT(ok && actual == 1); EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 1);
actual = AK::StringUtils::convert_to_int("+1", ok); actual = AK::StringUtils::convert_to_int("+1");
EXPECT(ok && actual == 1); EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 1);
actual = AK::StringUtils::convert_to_int("-1", ok); actual = AK::StringUtils::convert_to_int("-1");
EXPECT(ok && actual == -1); EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), -1);
actual = AK::StringUtils::convert_to_int("01", ok); actual = AK::StringUtils::convert_to_int("01");
EXPECT(ok && actual == 1); EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 1);
actual = AK::StringUtils::convert_to_int("12345", ok); actual = AK::StringUtils::convert_to_int("12345");
EXPECT(ok && actual == 12345); EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 12345);
actual = AK::StringUtils::convert_to_int("-12345", ok); actual = AK::StringUtils::convert_to_int("-12345");
EXPECT(ok && actual == -12345); EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), -12345);
} }
TEST_CASE(convert_to_uint) TEST_CASE(convert_to_uint)
{ {
bool ok = false; auto value = AK::StringUtils::convert_to_uint(StringView());
AK::StringUtils::convert_to_uint(StringView(), ok); EXPECT(!value.has_value());
EXPECT(!ok);
AK::StringUtils::convert_to_uint("", ok); value = AK::StringUtils::convert_to_uint("");
EXPECT(!ok); EXPECT(!value.has_value());
AK::StringUtils::convert_to_uint("a", ok); value = AK::StringUtils::convert_to_uint("a");
EXPECT(!ok); EXPECT(!value.has_value());
AK::StringUtils::convert_to_uint("+", ok); value = AK::StringUtils::convert_to_uint("+");
EXPECT(!ok); EXPECT(!value.has_value());
AK::StringUtils::convert_to_uint("-", ok); value = AK::StringUtils::convert_to_uint("-");
EXPECT(!ok); EXPECT(!value.has_value());
AK::StringUtils::convert_to_uint("+1", ok); value = AK::StringUtils::convert_to_uint("+1");
EXPECT(!ok); EXPECT(!value.has_value());
AK::StringUtils::convert_to_uint("-1", ok); AK::StringUtils::convert_to_uint("-1");
EXPECT(!ok); EXPECT(!value.has_value());
unsigned actual = AK::StringUtils::convert_to_uint("0", ok); auto actual = AK::StringUtils::convert_to_uint("0");
EXPECT(ok && actual == 0u); EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 0u);
actual = AK::StringUtils::convert_to_uint("1", ok); actual = AK::StringUtils::convert_to_uint("1");
EXPECT(ok && actual == 1u); EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 1u);
actual = AK::StringUtils::convert_to_uint("01", ok); actual = AK::StringUtils::convert_to_uint("01");
EXPECT(ok && actual == 1u); EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 1u);
actual = AK::StringUtils::convert_to_uint("12345", ok); actual = AK::StringUtils::convert_to_uint("12345");
EXPECT(ok && actual == 12345u); EXPECT_EQ(actual.has_value(), true);
EXPECT_EQ(actual.value(), 12345u);
} }
TEST_CASE(ends_with) TEST_CASE(ends_with)

View file

@ -152,11 +152,11 @@ bool URL::parse(const StringView& string)
if (buffer.is_empty()) if (buffer.is_empty())
return false; return false;
{ {
bool ok; auto port_opt = String::copy(buffer).to_uint();
m_port = String::copy(buffer).to_uint(ok);
buffer.clear(); buffer.clear();
if (!ok) if (!port_opt.has_value())
return false; return false;
m_port = port_opt.value();
} }
if (peek() == '/') { if (peek() == '/') {
state = State::InPath; state = State::InPath;

View file

@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <AK/Optional.h>
#include <AK/String.h> #include <AK/String.h>
#include <AK/StringBuilder.h> #include <AK/StringBuilder.h>
#include <AK/StringUtils.h> #include <AK/StringUtils.h>
@ -60,9 +61,8 @@ String urldecode(const StringView& input)
builder.append(consume()); builder.append(consume());
continue; continue;
} }
bool ok; auto byte_point = StringUtils::convert_to_uint_from_hex(input.substring_view(cursor + 1, 2));
u8 byte_point = StringUtils::convert_to_uint_from_hex(input.substring_view(cursor + 1, 2), ok); builder.append(byte_point.value());
builder.append(byte_point);
consume(); consume();
consume(); consume();
consume(); consume();

View file

@ -76,10 +76,10 @@ bool handle_disassemble_command(const String& command, void* first_instruction)
auto parts = command.split(' '); auto parts = command.split(' ');
size_t number_of_instructions_to_disassemble = 5; size_t number_of_instructions_to_disassemble = 5;
if (parts.size() == 2) { if (parts.size() == 2) {
bool ok; auto number = parts[1].to_uint();
number_of_instructions_to_disassemble = parts[1].to_uint(ok); if (!number.has_value())
if (!ok)
return false; return false;
number_of_instructions_to_disassemble = number.value();
} }
// FIXME: Instead of using a fixed "dump_size", // FIXME: Instead of using a fixed "dump_size",
@ -126,14 +126,13 @@ bool handle_breakpoint_command(const String& command)
auto source_arguments = argument.split(':'); auto source_arguments = argument.split(':');
if (source_arguments.size() != 2) if (source_arguments.size() != 2)
return false; return false;
bool ok = false; auto line = source_arguments[1].to_uint();
size_t line = source_arguments[1].to_uint(ok); if (!line.has_value())
if (!ok)
return false; return false;
auto file = source_arguments[0]; auto file = source_arguments[0];
if (!file.contains("/")) if (!file.contains("/"))
file = String::format("./%s", file.characters()); file = String::format("./%s", file.characters());
auto result = g_debug_session->debug_info().get_instruction_from_source(file, line); auto result = g_debug_session->debug_info().get_instruction_from_source(file, line.value());
if (!result.has_value()) { if (!result.has_value()) {
printf("No matching instruction found\n"); printf("No matching instruction found\n");
return false; return false;

View file

@ -303,19 +303,9 @@ void DisplaySettingsWidget::load_current_settings()
/// Resolution //////////////////////////////////////////////////////////////////////////////// /// Resolution ////////////////////////////////////////////////////////////////////////////////
Gfx::IntSize find_size; Gfx::IntSize find_size;
bool okay = false;
// Let's attempt to find the current resolution and select it! // Let's attempt to find the current resolution and select it!
find_size.set_width(ws_config->read_entry("Screen", "Width", "1024").to_int(okay)); find_size.set_width(ws_config->read_num_entry("Screen", "Width", 1024));
if (!okay) { find_size.set_height(ws_config->read_num_entry("Screen", "Height", 768));
fprintf(stderr, "DisplaySettings: failed to convert width to int!");
ASSERT_NOT_REACHED();
}
find_size.set_height(ws_config->read_entry("Screen", "Height", "768").to_int(okay));
if (!okay) {
fprintf(stderr, "DisplaySettings: failed to convert height to int!");
ASSERT_NOT_REACHED();
}
size_t index = m_resolutions.find_first_index(find_size).value_or(0); size_t index = m_resolutions.find_first_index(find_size).value_or(0);
Gfx::IntSize m_current_resolution = m_resolutions.at(index); Gfx::IntSize m_current_resolution = m_resolutions.at(index);

View file

@ -82,11 +82,10 @@ HexEditorWidget::HexEditorWidget()
auto input_box = GUI::InputBox::construct("Enter new file size:", "New file size", window()); auto input_box = GUI::InputBox::construct("Enter new file size:", "New file size", window());
if (input_box->exec() == GUI::InputBox::ExecOK && !input_box->text_value().is_empty()) { if (input_box->exec() == GUI::InputBox::ExecOK && !input_box->text_value().is_empty()) {
auto valid = false; auto file_size = input_box->text_value().to_int();
auto file_size = input_box->text_value().to_int(valid); if (file_size.has_value() && file_size.value() > 0) {
if (valid && file_size > 0) {
m_document_dirty = false; m_document_dirty = false;
m_editor->set_buffer(ByteBuffer::create_zeroed(file_size)); m_editor->set_buffer(ByteBuffer::create_zeroed(file_size.value()));
set_path(LexicalPath()); set_path(LexicalPath());
update_title(); update_title();
} else { } else {
@ -149,11 +148,9 @@ HexEditorWidget::HexEditorWidget()
m_goto_decimal_offset_action = GUI::Action::create("Go To Offset (Decimal)...", { Mod_Ctrl | Mod_Shift, Key_G }, Gfx::Bitmap::load_from_file("/res/icons/16x16/go-forward.png"), [this](const GUI::Action&) { m_goto_decimal_offset_action = GUI::Action::create("Go To Offset (Decimal)...", { Mod_Ctrl | Mod_Shift, Key_G }, Gfx::Bitmap::load_from_file("/res/icons/16x16/go-forward.png"), [this](const GUI::Action&) {
auto input_box = GUI::InputBox::construct("Enter Decimal offset:", "Go To", window()); auto input_box = GUI::InputBox::construct("Enter Decimal offset:", "Go To", window());
if (input_box->exec() == GUI::InputBox::ExecOK && !input_box->text_value().is_empty()) { if (input_box->exec() == GUI::InputBox::ExecOK && !input_box->text_value().is_empty()) {
auto valid = false; auto new_offset = input_box->text_value().to_int();
auto new_offset = input_box->text_value().to_int(valid); if (new_offset.has_value())
if (valid) { m_editor->set_position(new_offset.value());
m_editor->set_position(new_offset);
}
} }
}); });

View file

@ -267,11 +267,10 @@ void IRCClient::handle(const Message& msg)
} }
#endif #endif
bool is_numeric; auto numeric = msg.command.to_uint();
int numeric = msg.command.to_uint(is_numeric);
if (is_numeric) { if (numeric.has_value()) {
switch (numeric) { switch (numeric.value()) {
case RPL_WELCOME: case RPL_WELCOME:
return handle_rpl_welcome(msg); return handle_rpl_welcome(msg);
case RPL_WHOISCHANNELS: case RPL_WHOISCHANNELS:
@ -798,10 +797,9 @@ void IRCClient::handle_rpl_topicwhotime(const Message& msg)
auto& channel_name = msg.arguments[1]; auto& channel_name = msg.arguments[1];
auto& nick = msg.arguments[2]; auto& nick = msg.arguments[2];
auto setat = msg.arguments[3]; auto setat = msg.arguments[3];
bool ok; auto setat_time = setat.to_uint();
time_t setat_time = setat.to_uint(ok); if (setat_time.has_value())
if (ok) setat = Core::DateTime::from_timestamp(setat_time.value()).to_string();
setat = Core::DateTime::from_timestamp(setat_time).to_string();
ensure_channel(channel_name).add_message(String::format("*** (set by %s at %s)", nick.characters(), setat.characters()), Color::Blue); ensure_channel(channel_name).add_message(String::format("*** (set by %s at %s)", nick.characters(), setat.characters()), Color::Blue);
} }

View file

@ -124,9 +124,10 @@ static Optional<u32> string_to_variable_value(const StringView& string_value, co
} }
if (variable.type_name == "int") { if (variable.type_name == "int") {
bool success = false; auto value = string_value.to_int();
auto value = string_value.to_int(success); if (value.has_value())
return success ? value : Optional<u32>(); return value.value();
return {};
} }
if (variable.type_name == "bool") { if (variable.type_name == "bool") {

View file

@ -227,9 +227,7 @@ int main(int argc, char** argv)
consume_specific('='); consume_specific('=');
consume_whitespace(); consume_whitespace();
auto magic_string = extract_while([](char ch) { return !isspace(ch) && ch != '{'; }); auto magic_string = extract_while([](char ch) { return !isspace(ch) && ch != '{'; });
bool ok; endpoints.last().magic = magic_string.to_int().value();
endpoints.last().magic = magic_string.to_int(ok);
ASSERT(ok);
consume_whitespace(); consume_whitespace();
consume_specific('{'); consume_specific('{');
parse_messages(); parse_messages();

View file

@ -65,11 +65,12 @@ int main(int argc, char** argv)
if (argc != 2) if (argc != 2)
print_usage_and_exit(); print_usage_and_exit();
bool ok; auto pid_opt = String(argv[1]).to_int();
pid_t pid = String(argv[1]).to_int(ok); if (!pid_opt.has_value())
if (!ok)
print_usage_and_exit(); print_usage_and_exit();
pid_t pid = pid_opt.value();
GUI::Application app(argc, argv); GUI::Application app(argc, argv);
auto window = GUI::Window::construct(); auto window = GUI::Window::construct();

View file

@ -177,10 +177,9 @@ RefPtr<Inode> DevPtsFSInode::lookup(StringView name)
if (name == "." || name == "..") if (name == "." || name == "..")
return fs().get_inode(identifier()); return fs().get_inode(identifier());
bool ok; auto pty_index = name.to_uint();
unsigned pty_index = name.to_uint(ok); if (pty_index.has_value() && ptys->contains(pty_index.value())) {
if (ok && ptys->contains(pty_index)) { return fs().get_inode({ fsid(), pty_index_to_inode_index(pty_index.value()) });
return fs().get_inode({ fsid(), pty_index_to_inode_index(pty_index) });
} }
return {}; return {};

View file

@ -1356,17 +1356,16 @@ RefPtr<Inode> ProcFSInode::lookup(StringView name)
} }
} }
} }
bool ok; auto name_as_number = name.to_uint();
unsigned name_as_number = name.to_uint(ok); if (!name_as_number.has_value())
if (ok) { return {};
bool process_exists = false; bool process_exists = false;
{ {
InterruptDisabler disabler; InterruptDisabler disabler;
process_exists = Process::from_pid(name_as_number); process_exists = Process::from_pid(name_as_number.value());
}
if (process_exists)
return fs().get_inode(to_identifier(fsid(), PDI_Root, name_as_number, FI_PID));
} }
if (process_exists)
return fs().get_inode(to_identifier(fsid(), PDI_Root, name_as_number.value(), FI_PID));
return {}; return {};
} }
@ -1413,18 +1412,17 @@ RefPtr<Inode> ProcFSInode::lookup(StringView name)
} }
if (proc_file_type == FI_PID_fd) { if (proc_file_type == FI_PID_fd) {
bool ok; auto name_as_number = name.to_uint();
unsigned name_as_number = name.to_uint(ok); if (!name_as_number.has_value())
if (ok) { return {};
bool fd_exists = false; bool fd_exists = false;
{ {
InterruptDisabler disabler; InterruptDisabler disabler;
if (auto* process = Process::from_pid(to_pid(identifier()))) if (auto* process = Process::from_pid(to_pid(identifier())))
fd_exists = process->file_description(name_as_number); fd_exists = process->file_description(name_as_number.value());
}
if (fd_exists)
return fs().get_inode(to_identifier_with_fd(fsid(), to_pid(identifier()), name_as_number));
} }
if (fd_exists)
return fs().get_inode(to_identifier_with_fd(fsid(), to_pid(identifier()), name_as_number.value()));
} }
return {}; return {};
} }

View file

@ -251,10 +251,9 @@ void init_stage2()
root = root.substring(strlen("/dev/hda"), root.length() - strlen("/dev/hda")); root = root.substring(strlen("/dev/hda"), root.length() - strlen("/dev/hda"));
if (root.length()) { if (root.length()) {
bool ok; auto partition_number = root.to_uint();
unsigned partition_number = root.to_uint(ok);
if (!ok) { if (!partition_number.has_value()) {
klog() << "init_stage2: couldn't parse partition number from root kernel parameter"; klog() << "init_stage2: couldn't parse partition number from root kernel parameter";
hang(); hang();
} }
@ -273,9 +272,9 @@ void init_stage2()
klog() << "init_stage2: couldn't read GPT from disk"; klog() << "init_stage2: couldn't read GPT from disk";
hang(); hang();
} }
auto partition = gpt.partition(partition_number); auto partition = gpt.partition(partition_number.value());
if (!partition) { if (!partition) {
klog() << "init_stage2: couldn't get partition " << partition_number; klog() << "init_stage2: couldn't get partition " << partition_number.value();
hang(); hang();
} }
root_dev = *partition; root_dev = *partition;
@ -287,20 +286,20 @@ void init_stage2()
klog() << "init_stage2: couldn't read EBR from disk"; klog() << "init_stage2: couldn't read EBR from disk";
hang(); hang();
} }
auto partition = ebr.partition(partition_number); auto partition = ebr.partition(partition_number.value());
if (!partition) { if (!partition) {
klog() << "init_stage2: couldn't get partition " << partition_number; klog() << "init_stage2: couldn't get partition " << partition_number.value();
hang(); hang();
} }
root_dev = *partition; root_dev = *partition;
} else { } else {
if (partition_number < 1 || partition_number > 4) { if (partition_number.value() < 1 || partition_number.value() > 4) {
klog() << "init_stage2: invalid partition number " << partition_number << "; expected 1 to 4"; klog() << "init_stage2: invalid partition number " << partition_number.value() << "; expected 1 to 4";
hang(); hang();
} }
auto partition = mbr.partition(partition_number); auto partition = mbr.partition(partition_number.value());
if (!partition) { if (!partition) {
klog() << "init_stage2: couldn't get partition " << partition_number; klog() << "init_stage2: couldn't get partition " << partition_number.value();
hang(); hang();
} }
root_dev = *partition; root_dev = *partition;

View file

@ -124,14 +124,13 @@ next_entry:
auto& e_passwd = parts[1]; auto& e_passwd = parts[1];
auto& e_gid_string = parts[2]; auto& e_gid_string = parts[2];
auto& e_members_string = parts[3]; auto& e_members_string = parts[3];
bool ok; auto e_gid = e_gid_string.to_uint();
gid_t e_gid = e_gid_string.to_uint(ok); if (!e_gid.has_value()) {
if (!ok) {
fprintf(stderr, "getgrent(): Malformed GID on line %u\n", __grdb_line_number); fprintf(stderr, "getgrent(): Malformed GID on line %u\n", __grdb_line_number);
goto next_entry; goto next_entry;
} }
auto members = e_members_string.split(','); auto members = e_members_string.split(',');
__grdb_entry->gr_gid = e_gid; __grdb_entry->gr_gid = e_gid.value();
__grdb_entry->gr_name = __grdb_entry->name_buffer; __grdb_entry->gr_name = __grdb_entry->name_buffer;
__grdb_entry->gr_passwd = __grdb_entry->passwd_buffer; __grdb_entry->gr_passwd = __grdb_entry->passwd_buffer;
for (size_t i = 0; i < members.size(); ++i) { for (size_t i = 0; i < members.size(); ++i) {

View file

@ -383,12 +383,11 @@ static bool fill_getserv_buffers(char* line, ssize_t read)
perror("malformed services file: port/protocol"); perror("malformed services file: port/protocol");
return false; return false;
} }
bool conversion_checker; auto number = port_protocol_split[0].to_int();
__getserv_port_buffer = port_protocol_split[0].to_int(conversion_checker); if (!number.has_value())
if (!conversion_checker) {
return false; return false;
}
__getserv_port_buffer = number.value();
//Removing any annoying whitespace at the end of the protocol. //Removing any annoying whitespace at the end of the protocol.
port_protocol_split[1].replace(" ", "", true); port_protocol_split[1].replace(" ", "", true);
@ -571,12 +570,11 @@ static bool fill_getproto_buffers(char* line, ssize_t read)
return false; return false;
} }
bool conversion_checker; auto number = split_line[1].to_int();
__getproto_protocol_buffer = split_line[1].to_int(conversion_checker); if (!number.has_value())
if (!conversion_checker) {
return false; return false;
}
__getproto_protocol_buffer = number.value();
__getproto_alias_list_buffer.clear(); __getproto_alias_list_buffer.clear();

View file

@ -128,19 +128,18 @@ next_entry:
auto& e_gecos = parts[4]; auto& e_gecos = parts[4];
auto& e_dir = parts[5]; auto& e_dir = parts[5];
auto& e_shell = parts[6]; auto& e_shell = parts[6];
bool ok; auto e_uid = e_uid_string.to_uint();
uid_t e_uid = e_uid_string.to_uint(ok); if (!e_uid.has_value()) {
if (!ok) {
fprintf(stderr, "getpwent(): Malformed UID on line %u\n", __pwdb_line_number); fprintf(stderr, "getpwent(): Malformed UID on line %u\n", __pwdb_line_number);
goto next_entry; goto next_entry;
} }
gid_t e_gid = e_gid_string.to_uint(ok); auto e_gid = e_gid_string.to_uint();
if (!ok) { if (!e_gid.has_value()) {
fprintf(stderr, "getpwent(): Malformed GID on line %u\n", __pwdb_line_number); fprintf(stderr, "getpwent(): Malformed GID on line %u\n", __pwdb_line_number);
goto next_entry; goto next_entry;
} }
__pwdb_entry->pw_uid = e_uid; __pwdb_entry->pw_uid = e_uid.value();
__pwdb_entry->pw_gid = e_gid; __pwdb_entry->pw_gid = e_gid.value();
__pwdb_entry->pw_name = __pwdb_entry->name_buffer; __pwdb_entry->pw_name = __pwdb_entry->name_buffer;
__pwdb_entry->pw_passwd = __pwdb_entry->passwd_buffer; __pwdb_entry->pw_passwd = __pwdb_entry->passwd_buffer;
__pwdb_entry->pw_gecos = __pwdb_entry->gecos_buffer; __pwdb_entry->pw_gecos = __pwdb_entry->gecos_buffer;

View file

@ -280,9 +280,9 @@ void ArgsParser::add_option(int& value, const char* help_string, const char* lon
short_name, short_name,
value_name, value_name,
[&value](const char* s) { [&value](const char* s) {
bool ok; auto opt = StringView(s).to_int();
value = StringView(s).to_int(ok); value = opt.value_or(0);
return ok; return opt.has_value();
} }
}; };
add_option(move(option)); add_option(move(option));
@ -316,9 +316,9 @@ void ArgsParser::add_positional_argument(int& value, const char* help_string, co
required == Required::Yes ? 1 : 0, required == Required::Yes ? 1 : 0,
1, 1,
[&value](const char* s) { [&value](const char* s) {
bool ok; auto opt = StringView(s).to_int();
value = StringView(s).to_int(ok); value = opt.value_or(0);
return ok; return opt.has_value();
} }
}; };
add_positional_argument(move(arg)); add_positional_argument(move(arg));

View file

@ -129,11 +129,7 @@ int ConfigFile::read_num_entry(const String& group, const String& key, int defau
return default_value; return default_value;
} }
bool ok; return read_entry(group, key).to_int().value_or(default_value);
int value = read_entry(group, key).to_int(ok);
if (!ok)
return default_value;
return value;
} }
bool ConfigFile::read_bool_entry(const String& group, const String& key, bool default_value) const bool ConfigFile::read_bool_entry(const String& group, const String& key, bool default_value) const

View file

@ -35,10 +35,9 @@ SpinBox::SpinBox()
m_editor = add<TextBox>(); m_editor = add<TextBox>();
m_editor->set_text("0"); m_editor->set_text("0");
m_editor->on_change = [this] { m_editor->on_change = [this] {
bool ok; auto value = m_editor->text().to_uint();
int value = m_editor->text().to_uint(ok); if (value.has_value())
if (ok) set_value(value.value());
set_value(value);
else else
m_editor->set_text(String::number(m_value)); m_editor->set_text(String::number(m_value));
}; };

View file

@ -91,10 +91,9 @@ void TextEditor::create_actions()
auto input_box = InputBox::construct("Line:", "Go to line", window()); auto input_box = InputBox::construct("Line:", "Go to line", window());
auto result = input_box->exec(); auto result = input_box->exec();
if (result == InputBox::ExecOK) { if (result == InputBox::ExecOK) {
bool ok; auto line_number = input_box->text_value().to_uint();
auto line_number = input_box->text_value().to_uint(ok); if (line_number.has_value())
if (ok) set_cursor(line_number.value() - 1, 0);
set_cursor(line_number - 1, 0);
} }
}, },
this); this);

View file

@ -158,13 +158,8 @@ public:
ASSERT(as_uint() <= INT32_MAX); ASSERT(as_uint() <= INT32_MAX);
return (int)as_uint(); return (int)as_uint();
} }
if (is_string()) { if (is_string())
bool ok; return as_string().to_int().value_or(0);
int value = as_string().to_int(ok);
if (!ok)
return 0;
return value;
}
return 0; return 0;
} }

View file

@ -77,13 +77,13 @@ void Job::on_socket_connected()
return deferred_invoke([this](auto&) { did_fail(Core::NetworkJob::Error::ProtocolFailed); }); return deferred_invoke([this](auto&) { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
} }
bool ok; auto status = parts[0].to_uint();
m_status = parts[0].to_uint(ok); if (!status.has_value()) {
if (!ok) {
fprintf(stderr, "Job: Expected numeric status code\n"); fprintf(stderr, "Job: Expected numeric status code\n");
return deferred_invoke([this](auto&) { did_fail(Core::NetworkJob::Error::ProtocolFailed); }); return deferred_invoke([this](auto&) { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
} }
m_status = status.value();
m_meta = parts[1]; m_meta = parts[1];
if (m_status >= 10 && m_status < 20) { if (m_status >= 10 && m_status < 20) {

View file

@ -139,22 +139,11 @@ static Optional<Color> parse_rgb_color(const StringView& string)
if (parts.size() != 3) if (parts.size() != 3)
return {}; return {};
bool ok; auto r = parts[0].to_uint().value_or(256);
auto r = parts[0].to_int(ok); auto g = parts[1].to_uint().value_or(256);
if (!ok) auto b = parts[2].to_uint().value_or(256);
return {};
auto g = parts[1].to_int(ok);
if (!ok)
return {};
auto b = parts[2].to_int(ok);
if (!ok)
return {};
if (r < 0 || r > 255) if (r > 255 || g > 255 || b > 255)
return {};
if (g < 0 || g > 255)
return {};
if (b < 0 || b > 255)
return {}; return {};
return Color(r, g, b); return Color(r, g, b);
@ -171,27 +160,14 @@ static Optional<Color> parse_rgba_color(const StringView& string)
if (parts.size() != 4) if (parts.size() != 4)
return {}; return {};
bool ok; auto r = parts[0].to_int().value_or(256);
auto r = parts[0].to_int(ok); auto g = parts[1].to_int().value_or(256);
if (!ok) auto b = parts[2].to_int().value_or(256);
return {};
auto g = parts[1].to_int(ok);
if (!ok)
return {};
auto b = parts[2].to_int(ok);
if (!ok)
return {};
double alpha = strtod(parts[3].to_string().characters(), nullptr); double alpha = strtod(parts[3].to_string().characters(), nullptr);
int a = alpha * 255; unsigned a = alpha * 255;
if (r < 0 || r > 255) if (r > 255 || g > 255 || b > 255 || a > 255)
return {};
if (g < 0 || g > 255)
return {};
if (b < 0 || b > 255)
return {};
if (a < 0 || a > 255)
return {}; return {};
return Color(r, g, b, a); return Color(r, g, b, a);

View file

@ -108,12 +108,12 @@ void Job::on_socket_connected()
fprintf(stderr, "Job: Expected 3-part HTTP status, got '%s'\n", line.data()); fprintf(stderr, "Job: Expected 3-part HTTP status, got '%s'\n", line.data());
return deferred_invoke([this](auto&) { did_fail(Core::NetworkJob::Error::ProtocolFailed); }); return deferred_invoke([this](auto&) { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
} }
bool ok; auto code = parts[1].to_uint();
m_code = parts[1].to_uint(ok); if (!code.has_value()) {
if (!ok) {
fprintf(stderr, "Job: Expected numeric HTTP status\n"); fprintf(stderr, "Job: Expected numeric HTTP status\n");
return deferred_invoke([this](auto&) { did_fail(Core::NetworkJob::Error::ProtocolFailed); }); return deferred_invoke([this](auto&) { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
} }
m_code = code.value();
m_state = State::InHeaders; m_state = State::InHeaders;
return; return;
} }
@ -266,10 +266,9 @@ void Job::on_socket_connected()
Optional<u32> content_length {}; Optional<u32> content_length {};
if (content_length_header.has_value()) { if (content_length_header.has_value()) {
bool ok; auto length = content_length_header.value().to_uint();
auto length = content_length_header.value().to_uint(ok); if (length.has_value())
if (ok) content_length = length.value();
content_length = length;
} }
deferred_invoke([this, content_length](auto&) { did_progress(content_length, m_received_size); }); deferred_invoke([this, content_length](auto&) { did_progress(content_length, m_received_size); });

View file

@ -410,9 +410,8 @@ bool Object::define_property(PropertyName property_name, Value value, PropertyAt
{ {
if (property_name.is_number()) if (property_name.is_number())
return put_own_property_by_index(*this, property_name.as_number(), value, attributes, PutOwnPropertyMode::DefineProperty, throw_exceptions); return put_own_property_by_index(*this, property_name.as_number(), value, attributes, PutOwnPropertyMode::DefineProperty, throw_exceptions);
bool ok; i32 property_index = property_name.as_string().to_int().value_or(-1);
i32 property_index = property_name.as_string().to_int(ok); if (property_index >= 0)
if (ok && property_index >= 0)
return put_own_property_by_index(*this, property_index, value, attributes, PutOwnPropertyMode::DefineProperty, throw_exceptions); return put_own_property_by_index(*this, property_index, value, attributes, PutOwnPropertyMode::DefineProperty, throw_exceptions);
return put_own_property(*this, property_name.as_string(), value, attributes, PutOwnPropertyMode::DefineProperty, throw_exceptions); return put_own_property(*this, property_name.as_string(), value, attributes, PutOwnPropertyMode::DefineProperty, throw_exceptions);
} }
@ -543,9 +542,8 @@ Value Object::delete_property(PropertyName property_name)
ASSERT(property_name.is_valid()); ASSERT(property_name.is_valid());
if (property_name.is_number()) if (property_name.is_number())
return Value(m_indexed_properties.remove(property_name.as_number())); return Value(m_indexed_properties.remove(property_name.as_number()));
bool ok; int property_index = property_name.as_string().to_int().value_or(-1);
int property_index = property_name.as_string().to_int(ok); if (property_index >= 0)
if (ok && property_index >= 0)
return Value(m_indexed_properties.remove(property_name.as_number())); return Value(m_indexed_properties.remove(property_name.as_number()));
auto metadata = shape().lookup(property_name.as_string()); auto metadata = shape().lookup(property_name.as_string());
@ -602,9 +600,8 @@ Value Object::get(PropertyName property_name) const
return get_by_index(property_name.as_number()); return get_by_index(property_name.as_number());
auto property_string = property_name.to_string(); auto property_string = property_name.to_string();
bool ok; i32 property_index = property_string.to_int().value_or(-1);
i32 property_index = property_string.to_int(ok); if (property_index >= 0)
if (ok && property_index >= 0)
return get_by_index(property_index); return get_by_index(property_index);
const Object* object = this; const Object* object = this;
@ -656,9 +653,8 @@ bool Object::put(PropertyName property_name, Value value)
ASSERT(!value.is_empty()); ASSERT(!value.is_empty());
auto property_string = property_name.to_string(); auto property_string = property_name.to_string();
bool ok; i32 property_index = property_string.to_int().value_or(-1);
i32 property_index = property_string.to_int(ok); if (property_index >= 0)
if (ok && property_index >= 0)
return put_by_index(property_index, value); return put_by_index(property_index, value);
// If there's a setter in the prototype chain, we go to the setter. // If there's a setter in the prototype chain, we go to the setter.
@ -737,9 +733,8 @@ bool Object::has_own_property(PropertyName property_name) const
if (property_name.is_number()) if (property_name.is_number())
return has_indexed_property(property_name.as_number()); return has_indexed_property(property_name.as_number());
bool ok; i32 property_index = property_name.as_string().to_int().value_or(-1);
i32 property_index = property_name.as_string().to_int(ok); if (property_index >= 0)
if (ok && property_index >= 0)
return has_indexed_property(property_index); return has_indexed_property(property_index);
return shape().lookup(property_name.as_string()).has_value(); return shape().lookup(property_name.as_string()).has_value();

View file

@ -1431,14 +1431,17 @@ Vector<size_t, 2> Editor::vt_dsr()
if (buf[0] == '\033' && buf[1] == '[') { if (buf[0] == '\033' && buf[1] == '[') {
auto parts = StringView(buf + 2, length - 3).split_view(';'); auto parts = StringView(buf + 2, length - 3).split_view(';');
bool ok; auto row_opt = parts[0].to_int();
row = parts[0].to_int(ok); if (!row_opt.has_value()) {
if (!ok) {
dbg() << "Terminal DSR issue; received garbage row"; dbg() << "Terminal DSR issue; received garbage row";
} else {
row = row_opt.value();
} }
col = parts[1].to_int(ok); auto col_opt = parts[1].to_int();
if (!ok) { if (!col_opt.has_value()) {
dbg() << "Terminal DSR issue; received garbage col"; dbg() << "Terminal DSR issue; received garbage col";
} else {
col = col_opt.value();
} }
} }
return { row, col }; return { row, col };

View file

@ -544,11 +544,8 @@ void Terminal::execute_xterm_command()
auto param_string = String::copy(m_xterm_parameters); auto param_string = String::copy(m_xterm_parameters);
auto params = param_string.split(';', true); auto params = param_string.split(';', true);
m_xterm_parameters.clear_with_capacity(); m_xterm_parameters.clear_with_capacity();
for (auto& parampart : params) { for (auto& parampart : params)
bool ok; numeric_params.append(parampart.to_uint().value_or(0));
unsigned value = parampart.to_uint(ok);
numeric_params.append(ok ? value : 0);
}
while (params.size() < 3) { while (params.size() < 3) {
params.append(String::empty()); params.append(String::empty());
@ -594,15 +591,14 @@ void Terminal::execute_escape_sequence(u8 final)
} }
auto paramparts = String::copy(m_parameters).split(';'); auto paramparts = String::copy(m_parameters).split(';');
for (auto& parampart : paramparts) { for (auto& parampart : paramparts) {
bool ok; auto value = parampart.to_uint();
unsigned value = parampart.to_uint(ok); if (!value.has_value()) {
if (!ok) {
// FIXME: Should we do something else? // FIXME: Should we do something else?
m_parameters.clear_with_capacity(); m_parameters.clear_with_capacity();
m_intermediates.clear_with_capacity(); m_intermediates.clear_with_capacity();
return; return;
} }
params.append(value); params.append(value.value());
} }
#if defined(TERMINAL_DEBUG) #if defined(TERMINAL_DEBUG)

View file

@ -47,22 +47,12 @@ HTMLCanvasElement::~HTMLCanvasElement()
int HTMLCanvasElement::requested_width() const int HTMLCanvasElement::requested_width() const
{ {
bool ok = false; return attribute(HTML::AttributeNames::width).to_int().value_or(300);
unsigned width = attribute(HTML::AttributeNames::width).to_int(ok);
if (ok)
return width;
return 300;
} }
int HTMLCanvasElement::requested_height() const int HTMLCanvasElement::requested_height() const
{ {
bool ok = false; return attribute(HTML::AttributeNames::height).to_int().value_or(150);
unsigned height = attribute(HTML::AttributeNames::height).to_int(ok);
if (ok)
return height;
return 150;
} }
RefPtr<LayoutNode> HTMLCanvasElement::create_layout_node(const StyleProperties* parent_style) const RefPtr<LayoutNode> HTMLCanvasElement::create_layout_node(const StyleProperties* parent_style) const

View file

@ -122,28 +122,12 @@ void HTMLImageElement::animate()
int HTMLImageElement::preferred_width() const int HTMLImageElement::preferred_width() const
{ {
bool ok = false; return attribute(HTML::AttributeNames::width).to_int().value_or(m_image_decoder ? m_image_decoder->width() : 0);
int width = attribute(HTML::AttributeNames::width).to_int(ok);
if (ok)
return width;
if (m_image_decoder)
return m_image_decoder->width();
return 0;
} }
int HTMLImageElement::preferred_height() const int HTMLImageElement::preferred_height() const
{ {
bool ok = false; return attribute(HTML::AttributeNames::height).to_int().value_or(m_image_decoder ? m_image_decoder->height() : 0);
int height = attribute(HTML::AttributeNames::height).to_int(ok);
if (ok)
return height;
if (m_image_decoder)
return m_image_decoder->height();
return 0;
} }
RefPtr<LayoutNode> HTMLImageElement::create_layout_node(const StyleProperties* parent_style) const RefPtr<LayoutNode> HTMLImageElement::create_layout_node(const StyleProperties* parent_style) const

View file

@ -85,10 +85,9 @@ RefPtr<LayoutNode> HTMLInputElement::create_layout_node(const StyleProperties*)
int text_width = Gfx::Font::default_font().width(value()); int text_width = Gfx::Font::default_font().width(value());
auto size_value = attribute(HTML::AttributeNames::size); auto size_value = attribute(HTML::AttributeNames::size);
if (!size_value.is_null()) { if (!size_value.is_null()) {
bool ok; auto size = size_value.to_uint();
auto size = size_value.to_int(ok); if (size.has_value())
if (ok && size >= 0) text_width = Gfx::Font::default_font().glyph_width('x') * size.value();
text_width = Gfx::Font::default_font().glyph_width('x') * size;
} }
text_box.set_relative_rect(0, 0, text_width + 20, 20); text_box.set_relative_rect(0, 0, text_width + 20, 20);
widget = text_box; widget = text_box;

View file

@ -53,9 +53,8 @@ void LayoutFrame::layout(LayoutMode layout_mode)
set_has_intrinsic_width(true); set_has_intrinsic_width(true);
set_has_intrinsic_height(true); set_has_intrinsic_height(true);
// FIXME: Do proper error checking, etc. // FIXME: Do proper error checking, etc.
bool ok; set_intrinsic_width(node().attribute(HTML::AttributeNames::width).to_int().value_or(300));
set_intrinsic_width(node().attribute(HTML::AttributeNames::width).to_int(ok)); set_intrinsic_height(node().attribute(HTML::AttributeNames::height).to_int().value_or(150));
set_intrinsic_height(node().attribute(HTML::AttributeNames::height).to_int(ok));
LayoutReplaced::layout(layout_mode); LayoutReplaced::layout(layout_mode);
} }

View file

@ -266,18 +266,17 @@ static bool parse_html_document(const StringView& html, Document& document, Pare
} }
if (j < 7) { // We found ; char if (j < 7) { // We found ; char
bool ok; Optional<u32> codepoint;
u32 codepoint;
String str_code_point = html.substring_view(i + 2, j - 2); String str_code_point = html.substring_view(i + 2, j - 2);
if (str_code_point.starts_with('x')) { if (str_code_point.starts_with('x')) {
String str = str_code_point.substring(1, str_code_point.length() - 1); String str = str_code_point.substring(1, str_code_point.length() - 1);
codepoint = AK::StringUtils::convert_to_uint_from_hex(str, ok); codepoint = AK::StringUtils::convert_to_uint_from_hex(str);
} else { } else {
codepoint = str_code_point.to_uint(ok); codepoint = str_code_point.to_uint();
} }
if (ok) { if (codepoint.has_value()) {
Vector<char> bytes = codepoint_to_bytes(codepoint); Vector<char> bytes = codepoint_to_bytes(codepoint.value());
if (bytes.size() > 0) { if (bytes.size() > 0) {
for (size_t i = 0; i < bytes.size(); i++) { for (size_t i = 0; i < bytes.size(); i++) {
text_buffer.append(bytes.at(i)); text_buffer.append(bytes.at(i));

View file

@ -463,10 +463,9 @@ int Shell::builtin_disown(int argc, const char** argv)
Vector<size_t> job_ids; Vector<size_t> job_ids;
for (auto& job_id : str_job_ids) { for (auto& job_id : str_job_ids) {
bool ok; auto id = StringView(job_id).to_uint();
auto id = StringView { job_id }.to_uint(ok); if (id.has_value())
if (ok) job_ids.append(id.value());
job_ids.append(id);
else else
printf("Invalid job id: %s\n", job_id); printf("Invalid job id: %s\n", job_id);
} }

View file

@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <AK/Optional.h>
#include <AK/String.h> #include <AK/String.h>
#include <LibCore/ElapsedTimer.h> #include <LibCore/ElapsedTimer.h>
#include <stdio.h> #include <stdio.h>
@ -36,7 +37,9 @@ void usage(void)
exit(1); exit(1);
} }
enum Unit { Bytes, KiloBytes, MegaBytes }; enum Unit { Bytes,
KiloBytes,
MegaBytes };
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
@ -44,11 +47,11 @@ int main(int argc, char** argv)
Unit unit = MegaBytes; Unit unit = MegaBytes;
if (argc >= 2) { if (argc >= 2) {
bool ok; auto number = String(argv[1]).to_uint();
count = String(argv[1]).to_uint(ok); if (!number.has_value()) {
if (!ok) {
usage(); usage();
} }
count = number.value();
} }
if (argc >= 3) { if (argc >= 3) {

View file

@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <AK/Optional.h>
#include <AK/String.h> #include <AK/String.h>
#include <grp.h> #include <grp.h>
#include <pwd.h> #include <pwd.h>
@ -52,10 +53,11 @@ int main(int argc, char** argv)
return 1; return 1;
} }
bool ok; auto number = gid_arg.to_uint();
new_gid = gid_arg.to_uint(ok);
if (!ok) { if (number.has_value()) {
new_gid = number.value();
} else {
auto* group = getgrnam(gid_arg.characters()); auto* group = getgrnam(gid_arg.characters());
if (!group) { if (!group) {
fprintf(stderr, "Unknown group '%s'\n", gid_arg.characters()); fprintf(stderr, "Unknown group '%s'\n", gid_arg.characters());

View file

@ -54,9 +54,10 @@ int main(int argc, char** argv)
return 1; return 1;
} }
bool ok; auto number = parts[0].to_uint();
new_uid = parts[0].to_uint(ok); if (number.has_value()) {
if (!ok) { new_uid = number.value();
} else {
auto* passwd = getpwnam(parts[0].characters()); auto* passwd = getpwnam(parts[0].characters());
if (!passwd) { if (!passwd) {
fprintf(stderr, "Unknown user '%s'\n", parts[0].characters()); fprintf(stderr, "Unknown user '%s'\n", parts[0].characters());
@ -66,8 +67,10 @@ int main(int argc, char** argv)
} }
if (parts.size() == 2) { if (parts.size() == 2) {
new_gid = parts[1].to_uint(ok); auto number = parts[1].to_uint();
if (!ok) { if (number.has_value()) {
new_gid = number.value();
} else {
auto* group = getgrnam(parts[1].characters()); auto* group = getgrnam(parts[1].characters());
if (!new_gid) { if (!new_gid) {
fprintf(stderr, "Unknown group '%s'\n", parts[1].characters()); fprintf(stderr, "Unknown group '%s'\n", parts[1].characters());

View file

@ -89,74 +89,70 @@ static void expand_list(Vector<String>& tokens, Vector<Index>& indexes)
} }
if (token[0] == '-') { if (token[0] == '-') {
bool ok = true; auto index = token.substring(1, token.length() - 1).to_int();
ssize_t index = token.substring(1, token.length() - 1).to_int(ok); if (!index.has_value()) {
if (!ok) {
fprintf(stderr, "cut: invalid byte/character position '%s'\n", token.characters()); fprintf(stderr, "cut: invalid byte/character position '%s'\n", token.characters());
print_usage_and_exit(1); print_usage_and_exit(1);
} }
if (index == 0) { if (index.value() == 0) {
fprintf(stderr, "cut: byte/character positions are numbered from 1\n"); fprintf(stderr, "cut: byte/character positions are numbered from 1\n");
print_usage_and_exit(1); print_usage_and_exit(1);
} }
Index tmp = { 1, index, Index::Type::RangedIndex }; Index tmp = { 1, index.value(), Index::Type::RangedIndex };
add_if_not_exists(indexes, tmp); add_if_not_exists(indexes, tmp);
} else if (token[token.length() - 1] == '-') { } else if (token[token.length() - 1] == '-') {
bool ok = true; auto index = token.substring(0, token.length() - 1).to_int();
ssize_t index = token.substring(0, token.length() - 1).to_int(ok); if (!index.has_value()) {
if (!ok) {
fprintf(stderr, "cut: invalid byte/character position '%s'\n", token.characters()); fprintf(stderr, "cut: invalid byte/character position '%s'\n", token.characters());
print_usage_and_exit(1); print_usage_and_exit(1);
} }
if (index == 0) { if (index.value() == 0) {
fprintf(stderr, "cut: byte/character positions are numbered from 1\n"); fprintf(stderr, "cut: byte/character positions are numbered from 1\n");
print_usage_and_exit(1); print_usage_and_exit(1);
} }
Index tmp = { index, -1, Index::Type::SliceIndex }; Index tmp = { index.value(), -1, Index::Type::SliceIndex };
add_if_not_exists(indexes, tmp); add_if_not_exists(indexes, tmp);
} else { } else {
auto range = token.split('-'); auto range = token.split('-');
if (range.size() == 2) { if (range.size() == 2) {
bool ok = true; auto index1 = range[0].to_int();
ssize_t index1 = range[0].to_int(ok); if (!index1.has_value()) {
if (!ok) {
fprintf(stderr, "cut: invalid byte/character position '%s'\n", range[0].characters()); fprintf(stderr, "cut: invalid byte/character position '%s'\n", range[0].characters());
print_usage_and_exit(1); print_usage_and_exit(1);
} }
ssize_t index2 = range[1].to_int(ok); auto index2 = range[1].to_int();
if (!ok) { if (!index2.has_value()) {
fprintf(stderr, "cut: invalid byte/character position '%s'\n", range[1].characters()); fprintf(stderr, "cut: invalid byte/character position '%s'\n", range[1].characters());
print_usage_and_exit(1); print_usage_and_exit(1);
} }
if (index1 > index2) { if (index1.value() > index2.value()) {
fprintf(stderr, "cut: invalid decreasing range\n"); fprintf(stderr, "cut: invalid decreasing range\n");
print_usage_and_exit(1); print_usage_and_exit(1);
} else if (index1 == 0 || index2 == 0) { } else if (index1.value() == 0 || index2.value() == 0) {
fprintf(stderr, "cut: byte/character positions are numbered from 1\n"); fprintf(stderr, "cut: byte/character positions are numbered from 1\n");
print_usage_and_exit(1); print_usage_and_exit(1);
} }
Index tmp = { index1, index2, Index::Type::RangedIndex }; Index tmp = { index1.value(), index2.value(), Index::Type::RangedIndex };
add_if_not_exists(indexes, tmp); add_if_not_exists(indexes, tmp);
} else if (range.size() == 1) { } else if (range.size() == 1) {
bool ok = true; auto index = range[0].to_int();
ssize_t index = range[0].to_int(ok); if (!index.has_value()) {
if (!ok) {
fprintf(stderr, "cut: invalid byte/character position '%s'\n", range[0].characters()); fprintf(stderr, "cut: invalid byte/character position '%s'\n", range[0].characters());
print_usage_and_exit(1); print_usage_and_exit(1);
} }
if (index == 0) { if (index.value() == 0) {
fprintf(stderr, "cut: byte/character positions are numbered from 1\n"); fprintf(stderr, "cut: byte/character positions are numbered from 1\n");
print_usage_and_exit(1); print_usage_and_exit(1);
} }
Index tmp = { index, index, Index::Type::SingleIndex }; Index tmp = { index.value(), index.value(), Index::Type::SingleIndex };
add_if_not_exists(indexes, tmp); add_if_not_exists(indexes, tmp);
} else { } else {
fprintf(stderr, "cut: invalid byte or character range\n"); fprintf(stderr, "cut: invalid byte or character range\n");

View file

@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <AK/Optional.h>
#include <AK/String.h> #include <AK/String.h>
#include <LibCore/DateTime.h> #include <LibCore/DateTime.h>
#include <stdio.h> #include <stdio.h>
@ -44,12 +45,12 @@ int main(int argc, char** argv)
return 0; return 0;
} }
if (argc == 3 && !strcmp(argv[1], "-s")) { if (argc == 3 && !strcmp(argv[1], "-s")) {
bool ok; auto number = StringView(argv[2]).to_uint();
timespec ts = { String(argv[2]).to_uint(ok), 0 }; if (!number.has_value()) {
if (!ok) {
fprintf(stderr, "date: Invalid timestamp value"); fprintf(stderr, "date: Invalid timestamp value");
return 1; return 1;
} }
timespec ts = { number.value(), 0 };
if (clock_settime(CLOCK_REALTIME, &ts) < 0) { if (clock_settime(CLOCK_REALTIME, &ts) < 0) {
perror("clock_settime"); perror("clock_settime");
return 1; return 1;

View file

@ -120,10 +120,10 @@ class LinksCommand final : public StatCommand {
public: public:
LinksCommand(const char* arg) LinksCommand(const char* arg)
{ {
bool ok; auto number = StringView(arg).to_uint();
m_links = StringView(arg).to_uint(ok); if (!number.has_value())
if (!ok)
fatal_error("Invalid number: \033[1m%s", arg); fatal_error("Invalid number: \033[1m%s", arg);
m_links = number.value();
} }
private: private:
@ -143,10 +143,10 @@ public:
m_uid = passwd->pw_uid; m_uid = passwd->pw_uid;
} else { } else {
// Attempt to parse it as decimal UID. // Attempt to parse it as decimal UID.
bool ok; auto number = StringView(arg).to_uint();
m_uid = StringView(arg).to_uint(ok); if (!number.has_value())
if (!ok)
fatal_error("Invalid user: \033[1m%s", arg); fatal_error("Invalid user: \033[1m%s", arg);
m_uid = number.value();
} }
} }
@ -167,10 +167,10 @@ public:
m_gid = gr->gr_gid; m_gid = gr->gr_gid;
} else { } else {
// Attempt to parse it as decimal GID. // Attempt to parse it as decimal GID.
bool ok; auto number = StringView(arg).to_int();
m_gid = StringView(arg).to_int(ok); if (!number.has_value())
if (!ok)
fatal_error("Invalid group: \033[1m%s", arg); fatal_error("Invalid group: \033[1m%s", arg);
m_gid = number.value();
} }
} }
@ -192,10 +192,10 @@ public:
m_is_bytes = true; m_is_bytes = true;
view = view.substring_view(0, view.length() - 1); view = view.substring_view(0, view.length() - 1);
} }
bool ok; auto number = view.to_uint();
m_size = view.to_uint(ok); if (!number.has_value())
if (!ok)
fatal_error("Invalid size: \033[1m%s", arg); fatal_error("Invalid size: \033[1m%s", arg);
m_size = number.value();
} }
private: private:

View file

@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <AK/Optional.h>
#include <AK/String.h> #include <AK/String.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
@ -45,24 +46,25 @@ int main(int argc, char** argv)
if (argc != 2 && argc != 3) if (argc != 2 && argc != 3)
print_usage_and_exit(); print_usage_and_exit();
bool ok;
unsigned signum = SIGTERM; unsigned signum = SIGTERM;
int pid_argi = 1; int pid_argi = 1;
if (argc == 3) { if (argc == 3) {
pid_argi = 2; pid_argi = 2;
if (argv[1][0] != '-') if (argv[1][0] != '-')
print_usage_and_exit(); print_usage_and_exit();
signum = String(&argv[1][1]).to_uint(ok); auto number = StringView(&argv[1][1]).to_uint();
if (!ok) { if (!number.has_value()) {
printf("'%s' is not a valid signal number\n", &argv[1][1]); printf("'%s' is not a valid signal number\n", &argv[1][1]);
return 2; return 2;
} }
signum = number.value();
} }
pid_t pid = String(argv[pid_argi]).to_int(ok); auto pid_opt = String(argv[pid_argi]).to_int();
if (!ok) { if (!pid_opt.has_value()) {
printf("'%s' is not a valid PID\n", argv[pid_argi]); printf("'%s' is not a valid PID\n", argv[pid_argi]);
return 3; return 3;
} }
pid_t pid = pid_opt.value();
int rc = kill(pid, signum); int rc = kill(pid, signum);
if (rc < 0) if (rc < 0)

View file

@ -54,7 +54,6 @@ static int kill_all(const String& process_name, const unsigned signum)
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
bool ok;
unsigned signum = SIGTERM; unsigned signum = SIGTERM;
int name_argi = 1; int name_argi = 1;
@ -67,11 +66,12 @@ int main(int argc, char** argv)
if (argv[1][0] != '-') if (argv[1][0] != '-')
print_usage_and_exit(); print_usage_and_exit();
signum = String(&argv[1][1]).to_uint(ok); auto number = String(&argv[1][1]).to_uint();
if (!ok) { if (!number.has_value()) {
printf("'%s' is not a valid signal number\n", &argv[1][1]); printf("'%s' is not a valid signal number\n", &argv[1][1]);
return 2; return 2;
} }
signum = number.value();
} }
return kill_all(argv[name_argi], signum); return kill_all(argv[name_argi], signum);

View file

@ -74,15 +74,16 @@ int main(int argc, char** argv)
pid_t pid_to_omit = 0; pid_t pid_to_omit = 0;
if (omit_pid_value) { if (omit_pid_value) {
bool ok = true; if (!strcmp(omit_pid_value, "%PPID")) {
if (!strcmp(omit_pid_value, "%PPID"))
pid_to_omit = getppid(); pid_to_omit = getppid();
else } else {
pid_to_omit = StringView(omit_pid_value).to_uint(ok); auto number = StringView(omit_pid_value).to_uint();
if (!ok) { if (!number.has_value()) {
fprintf(stderr, "Invalid value for -o\n"); fprintf(stderr, "Invalid value for -o\n");
args_parser.print_usage(stderr, argv[0]); args_parser.print_usage(stderr, argv[0]);
return 1; return 1;
}
pid_to_omit = number.value();
} }
} }
return pid_of(process_name, single_shot, omit_pid_value != nullptr, pid_to_omit); return pid_of(process_name, single_shot, omit_pid_value != nullptr, pid_to_omit);

View file

@ -75,12 +75,12 @@ int main(int argc, char** argv)
break; break;
} }
bool ok; auto size_opt = str.to_int();
size = str.to_int(ok); if (!size_opt.has_value()) {
if (!ok) {
args_parser.print_usage(stderr, argv[0]); args_parser.print_usage(stderr, argv[0]);
return 1; return 1;
} }
size = size_opt.value();
} }
if (reference) { if (reference) {