15 : file_path_{std::move(file_path)}, format_{format}
30 if (!std::filesystem::exists(file_path_)) {
33 FormattableError{format_->
format(
"{}: file not found", FormatParam{file_path_.string(),
Style::bold})};
37 std::ifstream file{file_path_};
38 if (!file.is_open()) {
41 FormattableError{format_->
format(
"{}: failed to open file", FormatParam{file_path_.string(),
Style::bold})};
46 std::ostringstream buffer;
47 buffer << file.rdbuf();
48 content_ = buffer.str();
52 std::istringstream line_stream{content_};
54 while (std::getline(line_stream, line)) {
56 file_lines_.push_back(line);
60 context_ = std::make_unique<CParserContext>(&file_lines_, format_, file_path_.string());
68 auto load_result = ensure_loaded();
69 if (!load_result.has_value()) {
77 Lexer lexer{format_, content_, context_.get()};
78 auto lex_result = lexer.lex();
79 if (!lex_result.has_value()) {
87 Parser parser{format_, std::move(lex_result).value(), context_.get()};
88 auto parse_result = parser.parse_defines();
89 if (!parse_result.has_value()) {
96 return std::move(parse_result).value();
101 auto load_result = ensure_loaded();
102 if (!load_result.has_value()) {
110 Lexer lexer{format_, content_, context_.get()};
111 auto lex_result = lexer.lex();
112 if (!lex_result.has_value()) {
120 Parser parser{format_, std::move(lex_result).value(), context_.get()};
121 auto parse_result = parser.parse_enums();
122 if (!parse_result.has_value()) {
129 return std::move(parse_result).value();
135 auto load_result = ensure_loaded();
136 if (!load_result.has_value()) {
144 Lexer lexer{format_, content_, context_.get()};
145 auto lex_result = lexer.lex();
146 if (!lex_result.has_value()) {
154 Parser parser{format_, std::move(lex_result).value(), context_.get()};
155 auto parse_result = parser.parse_pointer_arrays();
156 if (!parse_result.has_value()) {
164 auto arrays = std::move(parse_result).value();
165 if (name_prefix.has_value()) {
167 arrays, [&](
const ArrayDeclaration &arr) {
return !arr.
name().starts_with(name_prefix.value()); });
176 auto load_result = ensure_loaded();
177 if (!load_result.has_value()) {
185 Lexer lexer{format_, content_, context_.get()};
186 auto lex_result = lexer.lex();
187 if (!lex_result.has_value()) {
195 Parser parser{format_, std::move(lex_result).value(), context_.get()};
196 auto parse_result = parser.parse_functions();
197 if (!parse_result.has_value()) {
205 auto functions = std::move(parse_result).value();
206 if (name_prefix.has_value()) {
208 functions, [&](
const FunctionDefinition &func) {
return !func.
name().starts_with(name_prefix.value()); });
217 auto load_result = ensure_loaded();
218 if (!load_result.has_value()) {
226 Lexer lexer{format_, content_, context_.get()};
227 auto lex_result = lexer.lex();
228 if (!lex_result.has_value()) {
236 Parser parser{format_, std::move(lex_result).value(), context_.get()};
237 auto parse_result = parser.parse_struct_variables();
238 if (!parse_result.has_value()) {
246 auto structs = std::move(parse_result).value();
247 if (name_prefix.has_value()) {
259 auto load_result = ensure_loaded();
260 if (!load_result.has_value()) {
268 Lexer lexer{format_, content_, context_.get()};
269 auto lex_result = lexer.lex();
270 if (!lex_result.has_value()) {
278 Parser parser{format_, std::move(lex_result).value(), context_.get()};
279 auto parse_result = parser.parse_struct_initializers();
280 if (!parse_result.has_value()) {
288 auto structs = std::move(parse_result).value();
289 if (name_prefix.has_value()) {
301 auto load_result = ensure_loaded();
302 if (!load_result.has_value()) {
310 Lexer lexer{format_, content_, context_.get()};
311 auto lex_result = lexer.lex();
312 if (!lex_result.has_value()) {
320 Parser parser{format_, std::move(lex_result).value(), context_.get()};
321 auto parse_result = parser.parse_incbin_arrays();
322 if (!parse_result.has_value()) {
330 auto incbins = std::move(parse_result).value();
331 if (name_prefix.has_value()) {
333 return !inc.
variable_name().starts_with(name_prefix.value());
343 if (!cached_defines_.has_value()) {
345 if (!result.has_value()) {
348 "{}: failed to find #define '{}'",
353 cached_defines_ = std::move(result.value());
357 for (
const auto &define : cached_defines_.value()) {
358 if (define.name() == define_name) {
359 return std::optional{define};
364 return std::optional<DefineStatement>{std::nullopt};
Represents a parsed C pointer array declaration.
const std::string & name() const
Returns the array variable name.
const std::vector< std::string > & file_lines() const
Returns the cached file lines.
ChainableResult< std::vector< IncbinDeclaration > > parse_incbin_arrays(const std::optional< std::string > &name_prefix=std::nullopt)
Parses INCBIN array declarations from the file.
ChainableResult< std::vector< EnumDeclaration > > parse_enums()
Parses all enum declarations from the file.
ChainableResult< std::vector< StructVariableDeclaration > > parse_struct_variables(const std::optional< std::string > &name_prefix=std::nullopt)
Parses struct variable declarations from the file.
ChainableResult< std::vector< DefineStatement > > parse_defines()
Parses all #define statements from the file.
ChainableResult< std::optional< DefineStatement > > find_define(const std::string &define_name)
Finds a specific #define statement by name.
CParserFacade(std::filesystem::path file_path, gsl::not_null< const TextFormatter * > format)
Constructs a facade for parsing the specified file.
ChainableResult< std::vector< FunctionDefinition > > parse_functions(const std::optional< std::string > &name_prefix=std::nullopt)
Parses function definitions from the file.
ChainableResult< std::vector< StructInitializerDeclaration > > parse_struct_initializers(const std::optional< std::string > &name_prefix=std::nullopt)
Parses struct variable declarations with their designated initializer fields.
ChainableResult< std::vector< ArrayDeclaration > > parse_pointer_arrays(const std::optional< std::string > &name_prefix=std::nullopt)
Parses all pointer array declarations from the file.
A result type that maintains a chainable sequence of errors for debugging and error reporting.
Represents a parsed C function definition.
const std::string & name() const
Returns the function name.
Represents a parsed INCBIN array declaration from C source code.
const std::string & variable_name() const
Returns the variable name.
Lexical analyzer for C/C++ source code.
Parser for C preprocessor constructs.
Represents a parsed C struct variable declaration with its initializer fields.
const std::string & variable_name() const
Returns the variable name.
Represents a parsed C struct variable declaration.
const std::string & variable_name() const
Returns the variable name.
static const Style bold
Bold text formatting.
virtual std::string format(const std::string &format_str, const std::vector< FormatParam > ¶ms) const
Formats a string with styled parameters using fmtlib syntax.
std::string & trim_line_ending(std::string &line)
Removes line ending characters from a string in-place.
Utility functions for string manipulation and formatting.