Skip to content

feat: codegen error reporting #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 2, 2024
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
47 changes: 45 additions & 2 deletions ecsact/codegen/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,48 @@ typedef void (*ecsact_codegen_write_fn_t)( //
int32_t str_len
);

typedef enum ecsact_codegen_report_type {
/**
* Informational report. Mostly used for debugging. May or may not be shown to
* user.
*/
ECSACT_CODEGEN_REPORT_INFO,

/**
* Warning. May or may not be shown to user.
*/
ECSACT_CODEGEN_REPORT_WARNING,

/**
* An error has occurred, but can still continue running. Will be shown to
* user when possible.
*/
ECSACT_CODEGEN_REPORT_ERROR,

/**
* An error has occurred and plugin cannot continue running. Will be shown to
* user when possible.
*/
ECSACT_CODEGEN_REPORT_FATAL,
} ecsact_codegen_report_message_type;

/**
* Message passed to this function is reported to the codegen host and may be
* shown to the user. Characters that go beyond @p msg_len are not read. Some
* report types may hault the codegen process. @see ecsact_codegen_report_type
*
* @NOTE: it is _NOT_ assumed that @p msg is null-terminated, you must set
* @p msg_len properly.
*
* @param msg - array of characters of length @p msg_len
* @param msg_len - length of array of characters @p msg
*/
typedef void (*ecsact_codegen_report_fn_t)( //
ecsact_codegen_report_type report_type,
const char* msg,
int32_t msg_len
);

ECSACT_CODEGEN_PLUGIN_API const char* ecsact_codegen_plugin_name();

/**
Expand All @@ -50,8 +92,9 @@ ECSACT_CODEGEN_PLUGIN_API const char* ecsact_codegen_plugin_name();
* output
*/
ECSACT_CODEGEN_PLUGIN_API void ecsact_codegen_plugin( //
ecsact_package_id package_id,
ecsact_codegen_write_fn_t write_fn
ecsact_package_id package_id,
ecsact_codegen_write_fn_t write_fn,
ecsact_codegen_report_fn_t report_fn
Copy link
Member Author

@zaucy zaucy Jul 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

breaking change - new paramter on the codegen plugin interface

);

#endif // ECSACT_CODEGEN_PLUGIN_H
64 changes: 57 additions & 7 deletions ecsact/codegen/plugin.hh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#include <string_view>
#include <cstring>
#include <iterator>
#ifdef __cpp_lib_format
# include <format>
#endif
#include "ecsact/runtime/common.h"
#include "ecsact/codegen/plugin.h"

Expand All @@ -15,23 +18,36 @@ namespace ecsact {
* Helper type to give a more C++ friendly write function
* @example
* void ecsact_codegen_plugin
* ( ecsact_package_id package_id
* , ecsact_codegen_write_fn_t write_fn
* ( ecsact_package_id package_id
* , ecsact_codegen_write_fn_t write_fn
* , ecsact_codegen_report_fn_t report_fn
* )
* {
* ecsact::codegen_plugin_context ctx{package_id, write_fn};
* ctx.write("Hello, World!\n");
* ecsact::codegen_plugin_context ctx{package_id, write_fn, report_fn};
* ctx.writef("Hello, World!\n");
* ctx.info("We made it!");
* }
*/
struct codegen_plugin_context {
const ecsact_package_id package_id;
const ecsact_codegen_write_fn_t write_fn;
int indentation = 0;
const ecsact_package_id package_id;
const ecsact_codegen_write_fn_t write_fn;
const ecsact_codegen_report_fn_t report_fn;
int indentation = 0;

std::string get_indent_str() {
return std::string(indentation, '\t');
}

void report_(
ecsact_codegen_report_type report_type,
const char* str_data,
int32_t str_data_len
) {
if(report_fn != nullptr) {
report_fn(report_type, str_data, str_data_len);
}
}

void write_(const char* str_data, int32_t str_data_len) {
assert(indentation >= 0);

Expand All @@ -56,6 +72,7 @@ struct codegen_plugin_context {
}

template<typename T>
[[deprecated("use writef instead")]]
void write(T&& arg) {
using NoRefT = std::remove_cvref_t<T>;

Expand All @@ -72,6 +89,7 @@ struct codegen_plugin_context {
}

template<typename... T>
[[deprecated("use writef instead")]]
void write(T&&... args) {
(write<T>(std::forward<T>(args)), ...);
}
Expand All @@ -87,6 +105,38 @@ struct codegen_plugin_context {
}
}
}

#ifdef __cpp_lib_format
template<typename... Args>
auto writef(std::format_string<Args...> fmt, Args&&... args) {
auto str = std::format(fmt, std::make_format_args(args...));
write_(str.data(), static_cast<int32_t>(str.size()));
}

template<typename... Args>
auto info(std::format_string<Args...> fmt, Args&&... args) {
auto str = std::format(fmt, std::make_format_args(args...));
report_(ECSACT_CODEGEN_REPORT_INFO, str.data(), str.size());
}

template<typename... Args>
auto warn(std::format_string<Args...> fmt, Args&&... args) {
auto str = std::format(fmt, std::make_format_args(args...));
report_(ECSACT_CODEGEN_REPORT_WARNING, str.data(), str.size());
}

template<typename... Args>
auto error(std::format_string<Args...> fmt, Args&&... args) {
auto str = std::format(fmt, std::make_format_args(args...));
report_(ECSACT_CODEGEN_REPORT_ERROR, str.data(), str.size());
}

template<typename... Args>
auto fatal(std::format_string<Args...> fmt, Args&&... args) {
auto str = std::format(fmt, std::make_format_args(args...));
report_(ECSACT_CODEGEN_REPORT_FATAL, str.data(), str.size());
}
#endif
};

} // namespace ecsact