Merge pull request #60675 from voylin/Add-BBCode-support-for-printing-output
Adding print_rich() for printing with BBCode
This commit is contained in:
commit
b730d2ee09
16 changed files with 232 additions and 16 deletions
|
|
@ -208,7 +208,7 @@ void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *
|
|||
rd->script_debugger->send_error(String::utf8(p_func), String::utf8(p_file), p_line, String::utf8(p_err), String::utf8(p_descr), p_editor_notify, p_type, si);
|
||||
}
|
||||
|
||||
void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p_error) {
|
||||
void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p_error, bool p_rich) {
|
||||
RemoteDebugger *rd = static_cast<RemoteDebugger *>(p_this);
|
||||
|
||||
if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) { // Can't handle recursive prints during flush.
|
||||
|
|
@ -237,7 +237,13 @@ void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p
|
|||
|
||||
OutputString output_string;
|
||||
output_string.message = s;
|
||||
output_string.type = p_error ? MESSAGE_TYPE_ERROR : MESSAGE_TYPE_LOG;
|
||||
if (p_error) {
|
||||
output_string.type = MESSAGE_TYPE_ERROR;
|
||||
} else if (p_rich) {
|
||||
output_string.type = MESSAGE_TYPE_LOG_RICH;
|
||||
} else {
|
||||
output_string.type = MESSAGE_TYPE_LOG;
|
||||
}
|
||||
rd->output_strings.push_back(output_string);
|
||||
|
||||
if (overflowed) {
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public:
|
|||
enum MessageType {
|
||||
MESSAGE_TYPE_LOG,
|
||||
MESSAGE_TYPE_ERROR,
|
||||
MESSAGE_TYPE_LOG_RICH,
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
@ -82,7 +83,7 @@ private:
|
|||
Thread::ID flush_thread = 0;
|
||||
|
||||
PrintHandlerList phl;
|
||||
static void _print_handler(void *p_this, const String &p_string, bool p_error);
|
||||
static void _print_handler(void *p_this, const String &p_string, bool p_error, bool p_rich);
|
||||
ErrorHandlerList eh;
|
||||
static void _err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, bool p_editor_notify, ErrorHandlerType p_type);
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,21 @@ void OS::print(const char *p_format, ...) {
|
|||
va_end(argp);
|
||||
}
|
||||
|
||||
void OS::print_rich(const char *p_format, ...) {
|
||||
if (!_stdout_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_list argp;
|
||||
va_start(argp, p_format);
|
||||
|
||||
if (_logger) {
|
||||
_logger->logv(p_format, argp, false);
|
||||
}
|
||||
|
||||
va_end(argp);
|
||||
}
|
||||
|
||||
void OS::printerr(const char *p_format, ...) {
|
||||
if (!_stderr_enabled) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ public:
|
|||
|
||||
void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, Logger::ErrorType p_type = Logger::ERR_ERROR);
|
||||
void print(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
|
||||
void print_rich(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
|
||||
void printerr(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
|
||||
|
||||
virtual String get_stdin_string(bool p_block = true) = 0;
|
||||
|
|
|
|||
|
|
@ -79,7 +79,98 @@ void __print_line(String p_string) {
|
|||
_global_lock();
|
||||
PrintHandlerList *l = print_handler_list;
|
||||
while (l) {
|
||||
l->printfunc(l->userdata, p_string, false);
|
||||
l->printfunc(l->userdata, p_string, false, false);
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
_global_unlock();
|
||||
}
|
||||
|
||||
void __print_line_rich(String p_string) {
|
||||
if (!_print_line_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert a subset of BBCode tags to ANSI escape codes for correct display in the terminal.
|
||||
// Support of those ANSI escape codes varies across terminal emulators,
|
||||
// especially for italic and strikethrough.
|
||||
String p_string_ansi = p_string;
|
||||
|
||||
p_string_ansi = p_string_ansi.replace("[b]", "\u001b[1m");
|
||||
p_string_ansi = p_string_ansi.replace("[/b]", "\u001b[22m");
|
||||
p_string_ansi = p_string_ansi.replace("[i]", "\u001b[3m");
|
||||
p_string_ansi = p_string_ansi.replace("[/i]", "\u001b[23m");
|
||||
p_string_ansi = p_string_ansi.replace("[u]", "\u001b[4m");
|
||||
p_string_ansi = p_string_ansi.replace("[/u]", "\u001b[24m");
|
||||
p_string_ansi = p_string_ansi.replace("[s]", "\u001b[9m");
|
||||
p_string_ansi = p_string_ansi.replace("[/s]", "\u001b[29m");
|
||||
|
||||
p_string_ansi = p_string_ansi.replace("[indent]", " ");
|
||||
p_string_ansi = p_string_ansi.replace("[/indent]", "");
|
||||
p_string_ansi = p_string_ansi.replace("[code]", "\u001b[2m");
|
||||
p_string_ansi = p_string_ansi.replace("[/code]", "\u001b[22m");
|
||||
p_string_ansi = p_string_ansi.replace("[url]", "");
|
||||
p_string_ansi = p_string_ansi.replace("[/url]", "");
|
||||
p_string_ansi = p_string_ansi.replace("[center]", "\n\t\t\t");
|
||||
p_string_ansi = p_string_ansi.replace("[/center]", "");
|
||||
p_string_ansi = p_string_ansi.replace("[right]", "\n\t\t\t\t\t\t");
|
||||
p_string_ansi = p_string_ansi.replace("[/right]", "");
|
||||
|
||||
if (p_string_ansi.contains("[color")) {
|
||||
p_string_ansi = p_string_ansi.replace("[color=black]", "\u001b[30m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=red]", "\u001b[91m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=green]", "\u001b[92m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=lime]", "\u001b[92m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=yellow]", "\u001b[93m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=blue]", "\u001b[94m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=magenta]", "\u001b[95m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=pink]", "\u001b[38;5;218m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=purple]", "\u001b[38;5;98m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=cyan]", "\u001b[96m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=white]", "\u001b[97m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=orange]", "\u001b[38;5;208m");
|
||||
p_string_ansi = p_string_ansi.replace("[color=gray]", "\u001b[90m");
|
||||
p_string_ansi = p_string_ansi.replace("[/color]", "\u001b[39m");
|
||||
}
|
||||
if (p_string_ansi.contains("[bgcolor")) {
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=black]", "\u001b[40m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=red]", "\u001b[101m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=green]", "\u001b[102m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=lime]", "\u001b[102m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=yellow]", "\u001b[103m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=blue]", "\u001b[104m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=magenta]", "\u001b[105m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=pink]", "\u001b[48;5;218m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=purple]", "\u001b[48;5;98m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=cyan]", "\u001b[106m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=white]", "\u001b[107m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=orange]", "\u001b[48;5;208m");
|
||||
p_string_ansi = p_string_ansi.replace("[bgcolor=gray]", "\u001b[100m");
|
||||
p_string_ansi = p_string_ansi.replace("[/bgcolor]", "\u001b[49m");
|
||||
}
|
||||
if (p_string_ansi.contains("[fgcolor")) {
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=black]", "\u001b[30;40m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=red]", "\u001b[91;101m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=green]", "\u001b[92;102m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=lime]", "\u001b[92;102m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=yellow]", "\u001b[93;103m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=blue]", "\u001b[94;104m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=magenta]", "\u001b[95;105m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=pink]", "\u001b[38;5;218;48;5;218m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=purple]", "\u001b[38;5;98;48;5;98m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=cyan]", "\u001b[96;106m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=white]", "\u001b[97;107m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=orange]", "\u001b[38;5;208;48;5;208m");
|
||||
p_string_ansi = p_string_ansi.replace("[fgcolor=gray]", "\u001b[90;100m");
|
||||
p_string_ansi = p_string_ansi.replace("[/fgcolor]", "\u001b[39;49m");
|
||||
}
|
||||
|
||||
OS::get_singleton()->print_rich("%s\n", p_string_ansi.utf8().get_data());
|
||||
|
||||
_global_lock();
|
||||
PrintHandlerList *l = print_handler_list;
|
||||
while (l) {
|
||||
l->printfunc(l->userdata, p_string, false, true);
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +187,7 @@ void print_error(String p_string) {
|
|||
_global_lock();
|
||||
PrintHandlerList *l = print_handler_list;
|
||||
while (l) {
|
||||
l->printfunc(l->userdata, p_string, true);
|
||||
l->printfunc(l->userdata, p_string, true, false);
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
extern void (*_print_func)(String);
|
||||
|
||||
typedef void (*PrintHandlerFunc)(void *, const String &p_string, bool p_error);
|
||||
typedef void (*PrintHandlerFunc)(void *, const String &p_string, bool p_error, bool p_rich);
|
||||
|
||||
struct PrintHandlerList {
|
||||
PrintHandlerFunc printfunc = nullptr;
|
||||
|
|
@ -59,6 +59,7 @@ void remove_print_handler(const PrintHandlerList *p_handler);
|
|||
extern bool _print_line_enabled;
|
||||
extern bool _print_error_enabled;
|
||||
extern void __print_line(String p_string);
|
||||
extern void __print_line_rich(String p_string);
|
||||
extern void print_error(String p_string);
|
||||
extern void print_verbose(String p_string);
|
||||
|
||||
|
|
@ -66,9 +67,18 @@ inline void print_line(Variant v) {
|
|||
__print_line(stringify_variants(v));
|
||||
}
|
||||
|
||||
inline void print_line_rich(Variant v) {
|
||||
__print_line_rich(stringify_variants(v));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void print_line(Variant p_var, Args... p_args) {
|
||||
__print_line(stringify_variants(p_var, p_args...));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void print_line_rich(Variant p_var, Args... p_args) {
|
||||
__print_line_rich(stringify_variants(p_var, p_args...));
|
||||
}
|
||||
|
||||
#endif // PRINT_STRING_H
|
||||
|
|
|
|||
|
|
@ -560,6 +560,22 @@ struct VariantUtilityFunctions {
|
|||
r_error.error = Callable::CallError::CALL_OK;
|
||||
}
|
||||
|
||||
static inline void print_rich(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
|
||||
String s;
|
||||
for (int i = 0; i < p_arg_count; i++) {
|
||||
String os = p_args[i]->operator String();
|
||||
|
||||
if (i == 0) {
|
||||
s = os;
|
||||
} else {
|
||||
s += os;
|
||||
}
|
||||
}
|
||||
|
||||
print_line_rich(s);
|
||||
r_error.error = Callable::CallError::CALL_OK;
|
||||
}
|
||||
|
||||
static inline void print_verbose(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
String s;
|
||||
|
|
@ -1306,6 +1322,7 @@ void Variant::_register_variant_utility_functions() {
|
|||
FUNCBINDVARARGS(str, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
|
||||
FUNCBINDR(error_string, sarray("error"), Variant::UTILITY_FUNC_TYPE_GENERAL);
|
||||
FUNCBINDVARARGV(print, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
|
||||
FUNCBINDVARARGV(print_rich, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
|
||||
FUNCBINDVARARGV(printerr, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
|
||||
FUNCBINDVARARGV(printt, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
|
||||
FUNCBINDVARARGV(prints, sarray(), Variant::UTILITY_FUNC_TYPE_GENERAL);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue