Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ cmake --build cmake-build-relwithdebinfo --target translate # CLI: file to HTML
for index-like values (`std::size_t`) or where an API forces them.
- Use `std::array`, never a C array.
- Mark locals, parameters and members `const` where they do not mutate.
- For `std::optional` and similar value-or-error types, test presence with
`.has_value()`. Access the value with `.value()`, or use `*` and `->` where
they read more naturally.
- Prefer `std::ranges` algorithms and range-based loops over iterator pairs.
- Define a header-declared free function with its qualified name inside the
reopened namespace, never as a bare redeclaration. A signature that drifts
Expand Down
2 changes: 1 addition & 1 deletion apple/src/ODRDocument.mm
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ - (NSString *)locale {
return guarded_value(
[&]() -> NSString * {
const std::optional<std::string> locale = _handle->locale();
return locale ? odr::apple::to_nsstring(*locale) : nil;
return locale.has_value() ? odr::apple::to_nsstring(*locale) : nil;
},
nil);
}
Expand Down
2 changes: 1 addition & 1 deletion cli/src/meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ int main(const int argc, char **argv) {
DecodedFile file = open(input);

if (file.password_encrypted()) {
if (!password) {
if (!password.has_value()) {
ODR_FATAL(logger, "document encrypted but no password given");
return 2;
}
Expand Down
2 changes: 1 addition & 1 deletion cli/src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ int main(const int argc, char **argv) {
DecodedFile decoded_file = open(input, {}, logger);

if (decoded_file.password_encrypted()) {
if (!password) {
if (!password.has_value()) {
ODR_FATAL(logger, "document encrypted but no password given");
return 2;
}
Expand Down
2 changes: 1 addition & 1 deletion cli/src/translate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ int main(const int argc, char **argv) {
DecodedFile decoded_file = open(input);

if (decoded_file.password_encrypted()) {
if (!password) {
if (!password.has_value()) {
ODR_FATAL(logger, "document encrypted but no password given");
return 2;
}
Expand Down
13 changes: 8 additions & 5 deletions src/odr/document_element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,12 +433,15 @@ namespace {
void refuse_unwritable(const TableCellStyle &cell_style,
const TextStyle &text_style) {
const auto stated = [](const auto &sides) {
return sides.right || sides.top || sides.left || sides.bottom;
return sides.right.has_value() || sides.top.has_value() ||
sides.left.has_value() || sides.bottom.has_value();
};
if (cell_style.vertical_align || stated(cell_style.padding) ||
stated(cell_style.border) || cell_style.text_rotation ||
cell_style.wrap_text || text_style.font_name || text_style.font_shadow ||
text_style.background_color || text_style.font_position) {
if (cell_style.vertical_align.has_value() || stated(cell_style.padding) ||
stated(cell_style.border) || cell_style.text_rotation.has_value() ||
cell_style.wrap_text.has_value() || text_style.font_name.has_value() ||
text_style.font_shadow.has_value() ||
text_style.background_color.has_value() ||
text_style.font_position.has_value()) {
throw UnsupportedOperation();
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/odr/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ std::size_t File::size() const { return deref(m_impl).size(); }
std::string File::name() const { return deref(m_impl).name(); }

std::optional<std::string> File::disk_path() const {
if (const std::optional<internal::AbsPath> path = deref(m_impl).disk_path()) {
if (const std::optional<internal::AbsPath> path = deref(m_impl).disk_path();
path.has_value()) {
return path->string();
}
return {};
Expand Down
2 changes: 1 addition & 1 deletion src/odr/internal/common/list_numbering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ std::string ListCounter::advance(const std::uint32_t level,
if (number == std::numeric_limits<std::uint32_t>::max()) {
throw std::overflow_error("List counter overflow");
}
number = number ? *number + 1 : list_level.start;
number = number.has_value() ? *number + 1 : list_level.start;
m_formats[level] = list_level.format;
std::ranges::fill(m_numbers |
std::views::drop(static_cast<std::size_t>(level) + 1),
Expand Down
9 changes: 6 additions & 3 deletions src/odr/internal/common/sheet_cell_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ std::optional<formula::Value> value_of(const CellValue &value,
if (value.has_formula() && value.type() == ValueType::float_number &&
value.has_text()) {
if (const std::optional<formula::ErrorType> error =
formula::error_of_text(value.text())) {
formula::error_of_text(value.text());
error.has_value()) {
return Value{*error};
}
if (value.text().starts_with('#') || value.text().starts_with("Err:")) {
Expand Down Expand Up @@ -55,7 +56,8 @@ std::optional<formula::Value> value_of(const CellValue &value,
case ValueType::error:
if (const std::optional<formula::ErrorType> error =
value.has_text() ? formula::error_of_text(value.text())
: std::nullopt) {
: std::nullopt;
error.has_value()) {
return Value{*error};
}
return std::nullopt;
Expand Down Expand Up @@ -129,7 +131,8 @@ TableDimensions SheetCellSource::extent(const std::uint32_t sheet) const {
}
// the stated cells, a formula without a result too, which shows no content
TableDimensions extent;
if (const std::optional<std::vector<RowBand>> &sheet_bands = bands(sheet)) {
if (const std::optional<std::vector<RowBand>> &sheet_bands = bands(sheet);
sheet_bands.has_value()) {
for (const RowBand &band : *sheet_bands) {
extent.rows = std::max(extent.rows, band.end_row);
for (const CellRun &run : band.cells) {
Expand Down
3 changes: 2 additions & 1 deletion src/odr/internal/common/sheet_recalculation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ class StaleCells final : public formula::CellSource {
std::vector<std::pair<SheetPosition, std::size_t>> pending{{position, 0}};
while (true) {
const std::optional<formula::Value> result = cell(pending.back().first);
if (const auto frontier = std::exchange(m_frontier, std::nullopt)) {
if (const auto frontier = std::exchange(m_frontier, std::nullopt);
frontier.has_value()) {
const std::size_t previous = m_ancestors.size();
m_ancestors.insert(m_ancestors.end(), m_frontier_path.begin(),
m_frontier_path.end());
Expand Down
3 changes: 2 additions & 1 deletion src/odr/internal/csv/csv_document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ class ElementAdapter final : public AdapterBase {
CellValue result = CellValue(sheet_cell_value_type(element_id));
if (result.type() == ValueType::float_number) {
if (const std::optional<double> number = util::number::parse(
m_document->cell(column_of(element_id), row_of(element_id)))) {
m_document->cell(column_of(element_id), row_of(element_id)));
number.has_value()) {
result = result.with_number(*number);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/odr/internal/font/cff_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ void dict_number(std::string &out, const double value) {
throw std::runtime_error("cff: non-finite DICT operand");
}
if (const std::optional<std::int32_t> integer =
util::number::to_integer<std::int32_t>(value)) {
util::number::to_integer<std::int32_t>(value);
integer.has_value()) {
dict_int(out, *integer);
return;
}
Expand Down
5 changes: 3 additions & 2 deletions src/odr/internal/font/cff_font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ std::string_view checked_slice(const std::string_view bytes,
std::uint32_t dict_offset(const double value) {
const std::optional<std::uint32_t> result =
util::number::to_integer<std::uint32_t>(value);
if (!result) {
if (!result.has_value()) {
throw std::runtime_error("cff: invalid DICT offset or length");
}
return *result;
Expand Down Expand Up @@ -177,7 +177,8 @@ using Dict = std::map<std::uint16_t, std::vector<double>>;
}
// An unreadable real reads as zero, so it does not refuse the font.
const std::optional<double> value = util::number::parse(number);
operands.push_back(value && std::isfinite(*value) ? *value : 0.0);
operands.push_back(value.has_value() && std::isfinite(*value) ? *value
: 0.0);
} else if (b0 >= 32 && b0 <= 246) {
operands.push_back(static_cast<std::int32_t>(b0) - 139);
++p;
Expand Down
4 changes: 2 additions & 2 deletions src/odr/internal/font/type1_charstring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void emit_num(std::string &out, const double v) {
}
const std::optional<std::int32_t> scaled =
util::number::to_integer<std::int32_t>(std::round(v * 65536.0));
if (!scaled) {
if (!scaled.has_value()) {
throw std::runtime_error("type1: operand exceeds Type2 fixed-point range");
}
const std::int32_t fixed = *scaled;
Expand All @@ -97,7 +97,7 @@ void emit_num(std::string &out, const double v) {
std::int32_t integer_operand(const double value) {
const std::optional<std::int32_t> result =
util::number::to_integer<std::int32_t>(value);
if (!result) {
if (!result.has_value()) {
throw std::runtime_error("type1: invalid integer operand");
}
return *result;
Expand Down
4 changes: 2 additions & 2 deletions src/odr/internal/font/type1_crypt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ constexpr std::uint16_t c2 = 22719;
continue;
}
const std::optional<std::uint8_t> value = util::string::hex_digit(ch);
if (!value) {
if (!value.has_value()) {
break;
}
if (high < 0) {
Expand All @@ -44,7 +44,7 @@ constexpr std::uint16_t c2 = 22719;
if (util::string::is_ascii_whitespace(ch)) {
continue;
}
if (!util::string::hex_digit(ch)) {
if (!util::string::hex_digit(ch).has_value()) {
return false;
}
if (++seen == 4) {
Expand Down
13 changes: 7 additions & 6 deletions src/odr/internal/font/type1_font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace {
[[nodiscard]] double parse_double(const std::string_view token) {
// An unreadable number reads as zero, so it does not refuse the font.
const std::optional<double> value = util::number::parse(token);
return value && std::isfinite(*value) ? *value : 0.0;
return value.has_value() && std::isfinite(*value) ? *value : 0.0;
}

/// A `/FontBBox` number as an FWord. Clamping keeps an out-of-range number out
Expand Down Expand Up @@ -91,7 +91,7 @@ read_rd_binary(const std::string_view s, std::size_t &p) {
std::size_t q = p;
const std::string_view length_token = read_token(s, q);
const auto length = util::number::parse_integer<std::int32_t>(length_token);
if (!length || *length < 0) {
if (!length.has_value() || *length < 0) {
return std::nullopt;
}
const std::string_view rd = read_token(s, q); // "RD" or "-|"
Expand Down Expand Up @@ -209,7 +209,7 @@ void Type1Font::parse_clear(const std::string_view clear) {
const std::size_t slash = after.find('/', q);
if (const auto code =
util::number::parse_integer<std::int32_t>(code_token);
code && slash != std::string_view::npos) {
code.has_value() && slash != std::string_view::npos) {
std::size_t r = slash + 1;
m_encoding[*code] = std::string(read_token(after, r));
}
Expand All @@ -224,8 +224,9 @@ void Type1Font::parse_private(const std::string_view decrypted) {
if (const std::size_t k = decrypted.find("/lenIV");
k != std::string_view::npos) {
std::size_t p = k + 6;
if (const auto value = util::number::parse_integer<std::int32_t>(
read_token(decrypted, p))) {
if (const auto value =
util::number::parse_integer<std::int32_t>(read_token(decrypted, p));
value.has_value()) {
if (*value < -1) {
throw std::runtime_error("type1: invalid /lenIV");
}
Expand Down Expand Up @@ -254,7 +255,7 @@ void Type1Font::parse_private(const std::string_view decrypted) {
util::number::parse_integer<std::int32_t>(read_token(decrypted, q));
// Every subr needs at least one byte of input, so an index at or past the
// input size cannot name one — and must not size the vector.
if (!index || *index < 0 ||
if (!index.has_value() || *index < 0 ||
static_cast<std::size_t>(*index) >= decrypted.size()) {
p += 4;
continue;
Expand Down
3 changes: 2 additions & 1 deletion src/odr/internal/formula/formula_functions_logic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ Value combine(const Call &call, const bool start, const Combine &next) {
errors.add(std::get<ErrorType>(truth_of_text(*text)));
}
});
if (const std::optional<ErrorType> error = errors.first()) {
if (const std::optional<ErrorType> error = errors.first();
error.has_value()) {
return Value{*error};
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/odr/internal/formula/formula_functions_lookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ Value matched(const Call &call, const std::span<const Condition> conditions,
errors.add(*error);
}
});
if (const auto error = errors.first()) {
if (const auto error = errors.first(); error.has_value()) {
throw ErrorResult{*error};
}
if (average && numbers.empty()) {
Expand Down
9 changes: 6 additions & 3 deletions src/odr/internal/formula/formula_functions_math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,8 @@ std::optional<Value> no_numbers(const Call &call, const Collected &collected) {

Value median(const Call &call) {
Collected collected = collect(call);
if (const std::optional<Value> refused = no_numbers(call, collected)) {
if (const std::optional<Value> refused = no_numbers(call, collected);
refused.has_value()) {
return *refused;
}
std::vector<double> &numbers = collected.numbers;
Expand All @@ -285,7 +286,8 @@ Value median(const Call &call) {
template <bool largest> Value kth(const Call &call) {
expect_arguments(call, 2, 2);
Collected collected = collect(call, 1);
if (const std::optional<Value> refused = no_numbers(call, collected)) {
if (const std::optional<Value> refused = no_numbers(call, collected);
refused.has_value()) {
return *refused;
}
double rank = number_argument(call, 1);
Expand Down Expand Up @@ -435,7 +437,8 @@ Value sum_product(const Call &call) {
products[i] *= factor;
}
}
if (const std::optional<ErrorType> error = errors.first()) {
if (const std::optional<ErrorType> error = errors.first();
error.has_value()) {
return Value{*error};
}
return sum_of(call, products);
Expand Down
3 changes: 2 additions & 1 deletion src/odr/internal/formula/formula_functions_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ Value concat(const Call &call) {
throw NoAnswer{};
}
});
if (const std::optional<ErrorType> error = errors.first()) {
if (const std::optional<ErrorType> error = errors.first();
error.has_value()) {
return Value{*error};
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/odr/internal/formula/formula_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ std::optional<char16_t> mapped(const char16_t c, const bool to_upper) {
{0x14A, 0x177, false},
{0x179, 0x17E, true}}) {
if (const std::optional<char16_t> other =
alternating(c, first, last, parity, to_upper)) {
alternating(c, first, last, parity, to_upper);
other.has_value()) {
return other;
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/odr/internal/formula/formula_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ formula::number_of_text(const std::string_view text) {
}
const bool percent = trimmed.ends_with('%');
if (const std::optional<double> number = plain_number(
percent ? trimmed.substr(0, trimmed.size() - 1) : trimmed)) {
percent ? trimmed.substr(0, trimmed.size() - 1) : trimmed);
number.has_value()) {
// a point is the decimal sign of some locales only
if (trimmed.find('.') != std::string_view::npos) {
return std::nullopt;
Expand Down
2 changes: 1 addition & 1 deletion src/odr/internal/html/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ html::fill_path_variables(const std::string &path,
const std::optional<std::uint32_t> index) {
std::string result = path;
util::string::replace_all(result, "{index}",
index ? std::to_string(*index) : "");
index.has_value() ? std::to_string(*index) : "");
return result;
}

Expand Down
6 changes: 3 additions & 3 deletions src/odr/internal/html/document_element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,12 @@ TableDimensions html::sheet_rendered_extent(const Sheet &sheet,
end_column = content.columns;
end_row = content.rows;
}
if (config.spreadsheet_limit) {
if (config.spreadsheet_limit.has_value()) {
end_column = std::min(end_column, config.spreadsheet_limit->columns);
end_row = std::min(end_row, config.spreadsheet_limit->rows);
}
end_column = std::max(1u, end_column);
if (config.spreadsheet_cell_limit) {
if (config.spreadsheet_cell_limit.has_value()) {
const std::uint64_t limit =
std::max<std::uint64_t>(1, *config.spreadsheet_cell_limit);
end_column =
Expand Down Expand Up @@ -1175,7 +1175,7 @@ void html::translate_image(const Element &element, const WritingState &state) {
path, image.file(), false, false, true);
resource_location =
state.config().resource_locator(resource, state.config());
if (resource_location) {
if (resource_location.has_value()) {
// a location taken by anything but this same image embeds instead
const odr::HtmlResource *existing =
resource_at(state.resources(), *resource_location);
Expand Down
4 changes: 2 additions & 2 deletions src/odr/internal/html/document_style.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ std::string html::translate_text_style(const TextStyle &text_style) {
}
// one declaration: a second `text-decoration` replaces the first
const bool underline =
text_style.font_underline && *text_style.font_underline;
text_style.font_underline.has_value() && *text_style.font_underline;
const bool line_through =
text_style.font_line_through && *text_style.font_line_through;
text_style.font_line_through.has_value() && *text_style.font_line_through;
if (underline || line_through) {
result += "text-decoration:";
if (underline) {
Expand Down
5 changes: 3 additions & 2 deletions src/odr/internal/html/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,9 @@ class HtmlServiceImpl final : public HtmlService {
"a", HtmlElementOptions()
.set_inline(true)
.set_extra(std::string(
location ? link_target_attributes(uri_kind(*location))
: std::string_view()))
location.has_value()
? link_target_attributes(uri_kind(*location))
: std::string_view()))
.set_attributes(HtmlAttributesVector{
{"href", *href},
{"download", xml::escape_attribute(name)},
Expand Down
2 changes: 1 addition & 1 deletion src/odr/internal/html/font_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class HtmlServiceImpl final : public HtmlService {
out.out() << "<div class=\"cell\"><span class=\"glyph\">&#x" << std::hex
<< static_cast<std::uint32_t>(font::pua_code_point(gid))
<< std::dec << ";</span><span class=\"gid\">" << gid;
if (const auto cp = font->code_point_for_glyph(gid)) {
if (const auto cp = font->code_point_for_glyph(gid); cp.has_value()) {
out.out() << " U+" << std::hex << std::uppercase
<< static_cast<std::uint32_t>(*cp) << std::nouppercase
<< std::dec;
Expand Down
Loading
Loading