Skip to content

Commit

Permalink
fdt-v2: code cleanups and alignments
Browse files Browse the repository at this point in the history
Signed-off-by: Bartłomiej Burdukiewicz <[email protected]>
  • Loading branch information
dev-0x7C6 committed Jul 2, 2024
1 parent 0fe0da8 commit 0ab93f8
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 108 deletions.
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: false
AlignTrailingComments: false
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true
Expand Down
12 changes: 7 additions & 5 deletions src/fdt/fdt-generator-qt.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include "fdt-generator-qt.hpp"
#include "fdt/fdt-parser-v2.hpp"
#include "fdt/fdt-parser-tokens.hpp"
#include "fdt/fdt-property-types.hpp"
#include <string_view>

qt_tree_fdt_generator::qt_tree_fdt_generator(tree_info &reference, tree_widget *target, string &&name, string &&id) {
using namespace fdt::qt_wrappers;

tree_generator::tree_generator(tree_info &reference, tree_widget *target, string &&name, string &&id) {
m_root = [&]() {
if (reference.root)
return reference.root;
Expand All @@ -21,7 +23,7 @@ qt_tree_fdt_generator::qt_tree_fdt_generator(tree_info &reference, tree_widget *
m_root->setSelected(true);
}

void qt_tree_fdt_generator::begin_node(std::string_view vname) noexcept {
void tree_generator::begin_node(std::string_view vname) noexcept {
const auto name = QString::fromUtf8(vname.data(), vname.size());

auto child = [&]() {
Expand Down Expand Up @@ -51,11 +53,11 @@ void qt_tree_fdt_generator::begin_node(std::string_view vname) noexcept {
m_tree_stack.emplace(child);
}

void qt_tree_fdt_generator::end_node() noexcept {
void tree_generator::end_node() noexcept {
m_tree_stack.pop();
}

void qt_tree_fdt_generator::insert_property(const fdt::tokenizer::types::property &prop) noexcept {
void tree_generator::insert_property(const fdt::parser::token_types::property &prop) noexcept {
auto item = new QTreeWidgetItem(m_tree_stack.top());

fdt::qt_wrappers::property property{
Expand Down
17 changes: 10 additions & 7 deletions src/fdt/fdt-generator-qt.hpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
#pragma once

#include <fdt/fdt-generator.hpp>
#include <fdt/fdt-header.hpp>
#include <fdt/fdt-property-types.hpp>
#include <types.hpp>

#include <QMetaType>
#include <QTreeWidgetItem>
#include <QHash>
#include "fdt/fdt-parser-v2.hpp"
#include "fdt/fdt-parser-tokens.hpp"
#include <stack>
#include <string_view>

Expand Down Expand Up @@ -38,16 +37,20 @@ struct tree_info {

using tree_map = hash_map<string, tree_info>;

struct qt_tree_fdt_generator : public iface_fdt_generator {
qt_tree_fdt_generator(tree_info &reference, tree_widget *target, string &&name, string &&id);
namespace fdt::qt_wrappers {

void begin_node(std::string_view) noexcept final;
void end_node() noexcept final;
void insert_property(const fdt::tokenizer::types::property &) noexcept final;
struct tree_generator {
tree_generator(tree_info &reference, tree_widget *target, string &&name, string &&id);

void begin_node(std::string_view) noexcept;
void end_node() noexcept;
void insert_property(const fdt::parser::token_types::property &) noexcept;

auto root() { return m_root; }

private:
QTreeWidgetItem *m_root{nullptr};
std::stack<QTreeWidgetItem *> m_tree_stack;
};

} // namespace fdt::qt_wrappers
13 changes: 0 additions & 13 deletions src/fdt/fdt-generator.hpp

This file was deleted.

12 changes: 7 additions & 5 deletions src/fdt/fdt-header.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace fdt {

namespace raw {
struct header {
u32 magic;
u32 totalsize;
Expand All @@ -21,17 +22,18 @@ struct property {
u32 len;
u32 nameoff;
};
}; // namespace raw

constexpr auto is_magic_invalid(const header &v) -> bool {
constexpr auto is_magic_invalid(const fdt::raw::header &v) -> bool {
constexpr auto header_magic_value = 0xD00DFEED;
return v.magic != header_magic_value;
}

constexpr auto is_version_unsupported(const header &v) -> bool {
constexpr auto is_version_unsupported(const fdt::raw::header &v) -> bool {
constexpr auto header_support_above = 16;
return v.version <= header_support_above;
}

static_assert(sizeof(header) == 40);
static_assert(sizeof(property) == 8);
}; // namespace fdt

static_assert(sizeof(fdt::raw::header) == 40);
static_assert(sizeof(fdt::raw::property) == 8);
19 changes: 19 additions & 0 deletions src/fdt/fdt-parser-context.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

#pragma once

#include "fdt/fdt-parser-tokens.hpp"

namespace fdt::parser {

struct context {
std::string_view structs;
std::string_view strings;
fdt::parser::tokens &tokens;

struct {
const char *data{nullptr};
int skip{};
} state;
};

} // namespace fdt::parser
29 changes: 13 additions & 16 deletions src/fdt/fdt-parser-v2.hpp → src/fdt/fdt-parser-tokens.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@

using u32 = std::uint32_t;

namespace fdt::tokenizer {
namespace fdt::parser::token_types {

namespace types {
struct node_begin {
std::string name;
};
Expand All @@ -28,25 +27,23 @@ constexpr auto id_of(property) -> u32 { return 0x03; };
constexpr auto id_of(nop) -> u32 { return 0x04; };
constexpr auto id_of(end) -> u32 { return 0x09; };

} // namespace types
} // namespace fdt::parser::token_types

using token = std::variant<types::property, types::node_begin, types::node_end, types::nop, types::end>;
using token_list = std::vector<token>;
namespace fdt::parser {

struct context {
std::string_view structs;
std::string_view strings;
token_list &tokens;
using token = std::variant<
token_types::property, //
token_types::node_begin, //
token_types::node_end, //
token_types::nop, //
token_types::end //
>;

struct {
const char *data{nullptr};
int skip{};
} state;
};
using tokens = std::vector<token>;

template <typename T>
concept Tokenizable = requires(T t) {
{ fdt::tokenizer::types::id_of(t) } -> std::convertible_to<u32>;
{ fdt::parser::token_types::id_of(t) } -> std::convertible_to<u32>;
};

} // namespace fdt::tokenizer
} // namespace fdt::parser
81 changes: 39 additions & 42 deletions src/fdt/fdt-parser.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "fdt-parser.hpp"
#include "fdt/fdt-header.hpp"
#include "fdt-parser-v2.hpp"
#include "fdt/fdt-parser-tokens.hpp"
#include "fdt-parser-context.hpp"
#include "endian-conversions.hpp"

#include <algorithm>
Expand All @@ -21,22 +22,19 @@ auto align(const std::size_t size) {

namespace fdt::parser {

using namespace fdt::tokenizer;
using namespace fdt::tokenizer::types;

auto parse(node_begin &&token, context &ctx) -> fdt::tokenizer::token {
auto parse(token_types::node_begin &&token, context &ctx) -> fdt::parser::token {
const auto size = std::strlen(ctx.state.data);
token.name = std::string_view(ctx.state.data, size);
ctx.state.skip += align(size + 1);
return {std::move(token)};
}

auto parse(node_end &&token, context &ctx) -> fdt::tokenizer::token {
auto parse(token_types::node_end &&token, context &) -> fdt::parser::token {
return {std::move(token)};
}

auto parse(types::property &&token, context &ctx) -> fdt::tokenizer::token {
const auto header = read_data_32be<fdt::property>(ctx.state.data);
auto parse(token_types::property &&token, context &ctx) -> fdt::parser::token {
const auto header = read_data_32be<fdt::raw::property>(ctx.state.data);
ctx.state.skip += align(sizeof(header)) + align(header.len);
ctx.state.data += sizeof(header);

Expand All @@ -50,19 +48,19 @@ auto parse(types::property &&token, context &ctx) -> fdt::tokenizer::token {
return {std::move(token)};
}

auto parse(nop &&token, context &ctx) -> fdt::tokenizer::token {
auto parse(token_types::nop &&token, context &) -> fdt::parser::token {
return {std::move(token)};
}

auto parse(end &&token, context &ctx) -> fdt::tokenizer::token {
auto parse(token_types::end &&token, context &) -> fdt::parser::token {
return {std::move(token)};
}
} // namespace fdt::parser

template <fdt::tokenizer::Tokenizable... Ts>
auto foreach_token_type(std::variant<Ts...>, const u32 token_id, fdt::tokenizer::context &ctx) {
template <fdt::parser::Tokenizable... Ts>
auto foreach_token_type(std::variant<Ts...>, const u32 token_id, fdt::parser::context &ctx) {
auto conditional_parse = [&](auto &&token) {
if (fdt::tokenizer::types::id_of(token) == token_id) {
if (fdt::parser::token_types::id_of(token) == token_id) {
ctx.tokens.emplace_back(fdt::parser::parse(std::move(token), ctx));
return true;
}
Expand All @@ -71,56 +69,55 @@ auto foreach_token_type(std::variant<Ts...>, const u32 token_id, fdt::tokenizer:
return (conditional_parse(Ts{}) || ...);
}

auto fdt::tokenizer::generator(std::string_view view, std::string_view root_name) -> std::expected<fdt::tokenizer::token_list, error> {
if (view.size() < sizeof(fdt::header))
return std::unexpected(fdt::error::invalid_header);
auto fdt::parser::parse(std::string_view view, std::string_view root_name) -> std::expected<fdt::parser::tokens, fdt::parser::error> {
using error = fdt::parser::error;

if (view.size() < sizeof(fdt::raw::header))
return std::unexpected(error::invalid_header);

const auto header = read_data_32be<fdt::header>(view.data());
const auto header = read_data_32be<fdt::raw::header>(view.data());

if (fdt::is_magic_invalid(header))
return std::unexpected(fdt::error::invalid_magic);
return std::unexpected(error::invalid_magic);

if (view.size() < header.totalsize)
return std::unexpected(fdt::error::data_truncated);
return std::unexpected(error::data_truncated);

if (fdt::is_version_unsupported(header))
return std::unexpected(fdt::error::unsupported_version);
return std::unexpected(error::unsupported_version);

const auto dt_struct = view.data() + header.off_dt_struct;
const auto dt_strings = view.data() + header.off_dt_strings;

fdt::tokenizer::token_list tokens;
tokens.reserve(50000);

using namespace fdt::tokenizer;
using namespace fdt::tokenizer::types;

context ctx{
.structs = {dt_struct, header.size_dt_struct}, //
fdt::parser::tokens tokens;
fdt::parser::context ctx{
.structs = {dt_struct, header.size_dt_struct}, //
.strings = {dt_strings, header.size_dt_strings}, //
.tokens = tokens,
};

tokens.reserve(50000);

const auto begin = reinterpret_cast<const u32 *>(dt_struct);
const auto end = reinterpret_cast<const u32 *>(dt_struct) + header.size_dt_struct / sizeof(u32);

if (header.size_dt_struct % sizeof(u32) != 0)
return std::unexpected(fdt::error::data_unaligned);
return std::unexpected(error::data_unaligned);

for (auto iter = begin; iter != end;) {
const auto id = static_cast<u32>(convert(*iter));
ctx.state.data = reinterpret_cast<const char *>(++iter);
ctx.state.skip = 0;

if (!foreach_token_type(token{}, id, ctx))
return std::unexpected(fdt::error::invalid_token);
return std::unexpected(error::invalid_token);

iter += ctx.state.skip;

if (std::holds_alternative<types::property>(tokens.back())) {
auto &prop = std::get<types::property>(tokens.back());
if (std::holds_alternative<token_types::property>(tokens.back())) {
auto &prop = std::get<token_types::property>(tokens.back());

if (auto dtb = fdt::tokenizer::generator(prop.data, prop.name); dtb.has_value()) {
if (auto dtb = fdt::parser::parse(prop.data, prop.name); dtb.has_value()) {
auto &embedded_tokens = dtb.value();
std::move(std::begin(embedded_tokens), std::end(embedded_tokens), std::back_inserter(tokens));
}
Expand All @@ -129,8 +126,8 @@ auto fdt::tokenizer::generator(std::string_view view, std::string_view root_name

// change property name for first node
for (auto &&token : tokens)
if (std::holds_alternative<types::node_begin>(token)) {
std::get<types::node_begin>(token).name = root_name;
if (std::holds_alternative<token_types::node_begin>(token)) {
std::get<token_types::node_begin>(token).name = root_name;
break;
}

Expand All @@ -142,8 +139,8 @@ struct overloaded : Ts... {
using Ts::operator()...;
};

auto fdt::tokenizer::validate(const fdt::tokenizer::token_list &tokens) -> bool {
using namespace fdt::tokenizer;
auto fdt::parser::validate(const fdt::parser::tokens &tokens) -> bool {
using namespace fdt::parser;

bool valid_depth_test{true};
std::int32_t node_scope_depth{};
Expand All @@ -155,19 +152,19 @@ auto fdt::tokenizer::validate(const fdt::tokenizer::token_list &tokens) -> bool

for (auto &&token : tokens) {
std::visit(overloaded{
[&](const types::node_begin &arg) {
[&](const token_types::node_begin &) {
node_begin_count++;
node_scope_depth++;
},
[&](const types::node_end &arg) {
[&](const token_types::node_end &) {
node_end_count++;
node_scope_depth--;
},
[&](const types::property &arg) {
[&](const token_types::property &) {
property_count++;
},
[&](const types::nop &) { nop_count++; },
[&](const types::end &) { end_count++; },
[&](const token_types::nop &) { nop_count++; },
[&](const token_types::end &) { end_count++; },
},
token);

Expand Down
Loading

0 comments on commit 0ab93f8

Please sign in to comment.