commit
132ba0ed97
@ -29,6 +29,7 @@
|
|||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
#include "error_macros.h"
|
#include "error_macros.h"
|
||||||
|
|
||||||
|
#include "io/logger.h"
|
||||||
#include "os/os.h"
|
#include "os/os.h"
|
||||||
|
|
||||||
bool _err_error_exists = false;
|
bool _err_error_exists = false;
|
||||||
@ -79,7 +80,7 @@ void remove_error_handler(ErrorHandlerList *p_handler) {
|
|||||||
|
|
||||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type) {
|
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type) {
|
||||||
|
|
||||||
OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, _err_error_exists ? OS::get_singleton()->get_last_error() : "", (OS::ErrorType)p_type);
|
OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, _err_error_exists ? OS::get_singleton()->get_last_error() : "", (Logger::ErrorType)p_type);
|
||||||
|
|
||||||
_global_lock();
|
_global_lock();
|
||||||
ErrorHandlerList *l = error_handler_list;
|
ErrorHandlerList *l = error_handler_list;
|
||||||
|
@ -76,6 +76,11 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void flush() {
|
||||||
|
|
||||||
|
f.flush();
|
||||||
|
};
|
||||||
|
|
||||||
void store_8(uint8_t p_dest) {
|
void store_8(uint8_t p_dest) {
|
||||||
|
|
||||||
f.store_8(p_dest);
|
f.store_8(p_dest);
|
||||||
|
@ -338,6 +338,13 @@ Error FileAccessCompressed::get_error() const {
|
|||||||
return read_eof ? ERR_FILE_EOF : OK;
|
return read_eof ? ERR_FILE_EOF : OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileAccessCompressed::flush() {
|
||||||
|
ERR_FAIL_COND(!f);
|
||||||
|
ERR_FAIL_COND(!writing);
|
||||||
|
|
||||||
|
// compressed files keep data in memory till close()
|
||||||
|
}
|
||||||
|
|
||||||
void FileAccessCompressed::store_8(uint8_t p_dest) {
|
void FileAccessCompressed::store_8(uint8_t p_dest) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!f);
|
ERR_FAIL_COND(!f);
|
||||||
|
@ -84,6 +84,7 @@ public:
|
|||||||
|
|
||||||
virtual Error get_error() const; ///< get last error
|
virtual Error get_error() const; ///< get last error
|
||||||
|
|
||||||
|
virtual void flush();
|
||||||
virtual void store_8(uint8_t p_dest); ///< store a byte
|
virtual void store_8(uint8_t p_dest); ///< store a byte
|
||||||
|
|
||||||
virtual bool file_exists(const String &p_name); ///< return true if a file exists
|
virtual bool file_exists(const String &p_name); ///< return true if a file exists
|
||||||
|
@ -268,6 +268,12 @@ void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileAccessEncrypted::flush() {
|
||||||
|
ERR_FAIL_COND(!writing);
|
||||||
|
|
||||||
|
// encrypted files keep data in memory till close()
|
||||||
|
}
|
||||||
|
|
||||||
void FileAccessEncrypted::store_8(uint8_t p_dest) {
|
void FileAccessEncrypted::store_8(uint8_t p_dest) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!writing);
|
ERR_FAIL_COND(!writing);
|
||||||
|
@ -71,6 +71,7 @@ public:
|
|||||||
|
|
||||||
virtual Error get_error() const; ///< get last error
|
virtual Error get_error() const; ///< get last error
|
||||||
|
|
||||||
|
virtual void flush();
|
||||||
virtual void store_8(uint8_t p_dest); ///< store a byte
|
virtual void store_8(uint8_t p_dest); ///< store a byte
|
||||||
virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes
|
virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes
|
||||||
|
|
||||||
|
@ -170,6 +170,10 @@ Error FileAccessMemory::get_error() const {
|
|||||||
return pos >= length ? ERR_FILE_EOF : OK;
|
return pos >= length ? ERR_FILE_EOF : OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileAccessMemory::flush() {
|
||||||
|
ERR_FAIL_COND(!data);
|
||||||
|
}
|
||||||
|
|
||||||
void FileAccessMemory::store_8(uint8_t p_byte) {
|
void FileAccessMemory::store_8(uint8_t p_byte) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!data);
|
ERR_FAIL_COND(!data);
|
||||||
|
@ -62,6 +62,7 @@ public:
|
|||||||
|
|
||||||
virtual Error get_error() const; ///< get last error
|
virtual Error get_error() const; ///< get last error
|
||||||
|
|
||||||
|
virtual void flush();
|
||||||
virtual void store_8(uint8_t p_byte); ///< store a byte
|
virtual void store_8(uint8_t p_byte); ///< store a byte
|
||||||
virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes
|
virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes
|
||||||
|
|
||||||
|
@ -456,6 +456,10 @@ Error FileAccessNetwork::get_error() const {
|
|||||||
return pos == total_size ? ERR_FILE_EOF : OK;
|
return pos == total_size ? ERR_FILE_EOF : OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileAccessNetwork::flush() {
|
||||||
|
ERR_FAIL();
|
||||||
|
}
|
||||||
|
|
||||||
void FileAccessNetwork::store_8(uint8_t p_dest) {
|
void FileAccessNetwork::store_8(uint8_t p_dest) {
|
||||||
|
|
||||||
ERR_FAIL();
|
ERR_FAIL();
|
||||||
|
@ -155,6 +155,7 @@ public:
|
|||||||
|
|
||||||
virtual Error get_error() const; ///< get last error
|
virtual Error get_error() const; ///< get last error
|
||||||
|
|
||||||
|
virtual void flush();
|
||||||
virtual void store_8(uint8_t p_dest); ///< store a byte
|
virtual void store_8(uint8_t p_dest); ///< store a byte
|
||||||
|
|
||||||
virtual bool file_exists(const String &p_path); ///< return true if a file exists
|
virtual bool file_exists(const String &p_path); ///< return true if a file exists
|
||||||
|
@ -293,6 +293,11 @@ Error FileAccessPack::get_error() const {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileAccessPack::flush() {
|
||||||
|
|
||||||
|
ERR_FAIL();
|
||||||
|
}
|
||||||
|
|
||||||
void FileAccessPack::store_8(uint8_t p_dest) {
|
void FileAccessPack::store_8(uint8_t p_dest) {
|
||||||
|
|
||||||
ERR_FAIL();
|
ERR_FAIL();
|
||||||
|
@ -161,6 +161,7 @@ public:
|
|||||||
|
|
||||||
virtual Error get_error() const;
|
virtual Error get_error() const;
|
||||||
|
|
||||||
|
virtual void flush();
|
||||||
virtual void store_8(uint8_t p_dest);
|
virtual void store_8(uint8_t p_dest);
|
||||||
|
|
||||||
virtual void store_buffer(const uint8_t *p_src, int p_length);
|
virtual void store_buffer(const uint8_t *p_src, int p_length);
|
||||||
|
@ -353,6 +353,11 @@ Error FileAccessZip::get_error() const {
|
|||||||
return OK;
|
return OK;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void FileAccessZip::flush() {
|
||||||
|
|
||||||
|
ERR_FAIL();
|
||||||
|
}
|
||||||
|
|
||||||
void FileAccessZip::store_8(uint8_t p_dest) {
|
void FileAccessZip::store_8(uint8_t p_dest) {
|
||||||
|
|
||||||
ERR_FAIL();
|
ERR_FAIL();
|
||||||
|
@ -108,6 +108,7 @@ public:
|
|||||||
|
|
||||||
virtual Error get_error() const; ///< get last error
|
virtual Error get_error() const; ///< get last error
|
||||||
|
|
||||||
|
virtual void flush();
|
||||||
virtual void store_8(uint8_t p_dest); ///< store a byte
|
virtual void store_8(uint8_t p_dest); ///< store a byte
|
||||||
virtual bool file_exists(const String &p_name); ///< return true if a file exists
|
virtual bool file_exists(const String &p_name); ///< return true if a file exists
|
||||||
|
|
||||||
|
252
core/io/logger.cpp
Normal file
252
core/io/logger.cpp
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/*************************************************************************/
|
||||||
|
/* logger.cpp */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
#include "logger.h"
|
||||||
|
#include "os/dir_access.h"
|
||||||
|
#include "os/os.h"
|
||||||
|
#include "print_string.h"
|
||||||
|
|
||||||
|
bool Logger::should_log(bool p_err) {
|
||||||
|
return (!p_err || _print_error_enabled) && (p_err || _print_line_enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
||||||
|
if (!should_log(true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *err_type = "**ERROR**";
|
||||||
|
switch (p_type) {
|
||||||
|
case ERR_ERROR: err_type = "**ERROR**"; break;
|
||||||
|
case ERR_WARNING: err_type = "**WARNING**"; break;
|
||||||
|
case ERR_SCRIPT: err_type = "**SCRIPT ERROR**"; break;
|
||||||
|
case ERR_SHADER: err_type = "**SHADER ERROR**"; break;
|
||||||
|
default: ERR_PRINT("Unknown error type"); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *err_details;
|
||||||
|
if (p_rationale && *p_rationale)
|
||||||
|
err_details = p_rationale;
|
||||||
|
else
|
||||||
|
err_details = p_code;
|
||||||
|
|
||||||
|
logf_error("%s: %s\n", err_type, err_details);
|
||||||
|
logf_error(" At: %s:%i:%s() - %s\n", p_file, p_line, p_function, p_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::logf(const char *p_format, ...) {
|
||||||
|
if (!should_log(false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list argp;
|
||||||
|
va_start(argp, p_format);
|
||||||
|
|
||||||
|
logv(p_format, argp, false);
|
||||||
|
|
||||||
|
va_end(argp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::logf_error(const char *p_format, ...) {
|
||||||
|
if (!should_log(true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list argp;
|
||||||
|
va_start(argp, p_format);
|
||||||
|
|
||||||
|
logv(p_format, argp, true);
|
||||||
|
|
||||||
|
va_end(argp);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::~Logger() {}
|
||||||
|
|
||||||
|
void RotatedFileLogger::close_file() {
|
||||||
|
if (file) {
|
||||||
|
memdelete(file);
|
||||||
|
file = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RotatedFileLogger::clear_old_backups() {
|
||||||
|
int max_backups = max_files - 1; // -1 for the current file
|
||||||
|
|
||||||
|
String basename = base_path.get_basename();
|
||||||
|
String extension = "." + base_path.get_extension();
|
||||||
|
|
||||||
|
DirAccess *da = DirAccess::open(base_path.get_base_dir());
|
||||||
|
if (!da) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
da->list_dir_begin();
|
||||||
|
String f = da->get_next();
|
||||||
|
Set<String> backups;
|
||||||
|
while (f != String()) {
|
||||||
|
if (!da->current_is_dir() && f.begins_with(basename) && f.ends_with(extension) && f != base_path) {
|
||||||
|
backups.insert(f);
|
||||||
|
}
|
||||||
|
f = da->get_next();
|
||||||
|
}
|
||||||
|
da->list_dir_end();
|
||||||
|
|
||||||
|
if (backups.size() > max_backups) {
|
||||||
|
// since backups are appended with timestamp and Set iterates them in sorted order,
|
||||||
|
// first backups are the oldest
|
||||||
|
int to_delete = backups.size() - max_backups;
|
||||||
|
for (Set<String>::Element *E = backups.front(); E && to_delete > 0; E = E->next(), --to_delete) {
|
||||||
|
da->remove(E->get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memdelete(da);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RotatedFileLogger::rotate_file() {
|
||||||
|
close_file();
|
||||||
|
|
||||||
|
if (FileAccess::exists(base_path)) {
|
||||||
|
if (max_files > 1) {
|
||||||
|
char timestamp[21];
|
||||||
|
OS::Date date = OS::get_singleton()->get_date();
|
||||||
|
OS::Time time = OS::get_singleton()->get_time();
|
||||||
|
sprintf(timestamp, "-%04d-%02d-%02d-%02d-%02d-%02d", date.year, date.month, date.day + 1, time.hour, time.min, time.sec);
|
||||||
|
|
||||||
|
String backup_name = base_path.get_basename() + timestamp + "." + base_path.get_extension();
|
||||||
|
|
||||||
|
DirAccess *da = DirAccess::open(base_path.get_base_dir());
|
||||||
|
if (da) {
|
||||||
|
da->copy(base_path, backup_name);
|
||||||
|
memdelete(da);
|
||||||
|
}
|
||||||
|
clear_old_backups();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DirAccess *da = DirAccess::create(DirAccess::ACCESS_USERDATA);
|
||||||
|
if (da) {
|
||||||
|
da->make_dir_recursive(base_path.get_base_dir());
|
||||||
|
memdelete(da);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file = FileAccess::open(base_path, FileAccess::WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
RotatedFileLogger::RotatedFileLogger(const String &p_base_path, int p_max_files) {
|
||||||
|
file = NULL;
|
||||||
|
base_path = p_base_path.simplify_path();
|
||||||
|
max_files = p_max_files > 0 ? p_max_files : 1;
|
||||||
|
|
||||||
|
rotate_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RotatedFileLogger::logv(const char *p_format, va_list p_list, bool p_err) {
|
||||||
|
if (!should_log(p_err)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
const int static_buf_size = 512;
|
||||||
|
char static_buf[static_buf_size];
|
||||||
|
char *buf = static_buf;
|
||||||
|
int len = vsnprintf(buf, static_buf_size, p_format, p_list);
|
||||||
|
if (len >= static_buf_size) {
|
||||||
|
buf = (char *)Memory::alloc_static(len + 1);
|
||||||
|
vsnprintf(buf, len + 1, p_format, p_list);
|
||||||
|
}
|
||||||
|
file->store_buffer((uint8_t *)buf, len);
|
||||||
|
if (len >= static_buf_size) {
|
||||||
|
Memory::free_static(buf);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
const bool need_flush = true;
|
||||||
|
#else
|
||||||
|
bool need_flush = p_err;
|
||||||
|
#endif
|
||||||
|
if (need_flush) {
|
||||||
|
file->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RotatedFileLogger::~RotatedFileLogger() {
|
||||||
|
close_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StdLogger::logv(const char *p_format, va_list p_list, bool p_err) {
|
||||||
|
if (!should_log(p_err)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_err) {
|
||||||
|
vfprintf(stderr, p_format, p_list);
|
||||||
|
} else {
|
||||||
|
vprintf(p_format, p_list);
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StdLogger::~StdLogger() {}
|
||||||
|
|
||||||
|
CompositeLogger::CompositeLogger(Vector<Logger *> p_loggers) {
|
||||||
|
loggers = p_loggers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompositeLogger::logv(const char *p_format, va_list p_list, bool p_err) {
|
||||||
|
if (!should_log(p_err)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < loggers.size(); ++i) {
|
||||||
|
va_list list_copy;
|
||||||
|
va_copy(list_copy, p_list);
|
||||||
|
loggers[i]->logv(p_format, list_copy, p_err);
|
||||||
|
va_end(list_copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompositeLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
||||||
|
if (!should_log(true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < loggers.size(); ++i) {
|
||||||
|
loggers[i]->log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CompositeLogger::~CompositeLogger() {
|
||||||
|
for (int i = 0; i < loggers.size(); ++i) {
|
||||||
|
memdelete(loggers[i]);
|
||||||
|
}
|
||||||
|
}
|
107
core/io/logger.h
Normal file
107
core/io/logger.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*************************************************************************/
|
||||||
|
/* logger.h */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef LOGGER_H
|
||||||
|
#define LOGGER_H
|
||||||
|
|
||||||
|
#include "os/file_access.h"
|
||||||
|
#include "ustring.h"
|
||||||
|
#include "vector.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
protected:
|
||||||
|
bool should_log(bool p_err);
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum ErrorType {
|
||||||
|
ERR_ERROR,
|
||||||
|
ERR_WARNING,
|
||||||
|
ERR_SCRIPT,
|
||||||
|
ERR_SHADER
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void logv(const char *p_format, va_list p_list, bool p_err) = 0;
|
||||||
|
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
|
||||||
|
|
||||||
|
void logf(const char *p_format, ...);
|
||||||
|
void logf_error(const char *p_format, ...);
|
||||||
|
|
||||||
|
virtual ~Logger();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes messages to stdout/stderr.
|
||||||
|
*/
|
||||||
|
class StdLogger : public Logger {
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void logv(const char *p_format, va_list p_list, bool p_err);
|
||||||
|
virtual ~StdLogger();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes messages to the specified file. If the file already exists, creates a copy (backup)
|
||||||
|
* of it with timestamp appended to the file name. Maximum number of backups is configurable.
|
||||||
|
* When maximum is reached, the oldest backups are erased. With the maximum being equal to 1,
|
||||||
|
* it acts as a simple file logger.
|
||||||
|
*/
|
||||||
|
class RotatedFileLogger : public Logger {
|
||||||
|
String base_path;
|
||||||
|
int max_files;
|
||||||
|
|
||||||
|
FileAccess *file;
|
||||||
|
|
||||||
|
void rotate_file_without_closing();
|
||||||
|
void close_file();
|
||||||
|
void clear_old_backups();
|
||||||
|
void rotate_file();
|
||||||
|
|
||||||
|
public:
|
||||||
|
RotatedFileLogger(const String &p_base_path, int p_max_files = 10);
|
||||||
|
|
||||||
|
virtual void logv(const char *p_format, va_list p_list, bool p_err);
|
||||||
|
|
||||||
|
virtual ~RotatedFileLogger();
|
||||||
|
};
|
||||||
|
|
||||||
|
class CompositeLogger : public Logger {
|
||||||
|
Vector<Logger *> loggers;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CompositeLogger(Vector<Logger *> p_loggers);
|
||||||
|
|
||||||
|
virtual void logv(const char *p_format, va_list p_list, bool p_err);
|
||||||
|
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
|
||||||
|
|
||||||
|
virtual ~CompositeLogger();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -55,7 +55,7 @@ FileAccess *FileAccess::create(AccessType p_access) {
|
|||||||
|
|
||||||
bool FileAccess::exists(const String &p_name) {
|
bool FileAccess::exists(const String &p_name) {
|
||||||
|
|
||||||
if (PackedData::get_singleton()->has_path(p_name))
|
if (PackedData::get_singleton() && PackedData::get_singleton()->has_path(p_name))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
FileAccess *f = open(p_name, READ);
|
FileAccess *f = open(p_name, READ);
|
||||||
|
@ -119,6 +119,7 @@ public:
|
|||||||
|
|
||||||
virtual Error get_error() const = 0; ///< get last error
|
virtual Error get_error() const = 0; ///< get last error
|
||||||
|
|
||||||
|
virtual void flush() = 0;
|
||||||
virtual void store_8(uint8_t p_dest) = 0; ///< store a byte
|
virtual void store_8(uint8_t p_dest) = 0; ///< store a byte
|
||||||
virtual void store_16(uint16_t p_dest); ///< store 16 bits uint
|
virtual void store_16(uint16_t p_dest); ///< store 16 bits uint
|
||||||
virtual void store_32(uint32_t p_dest); ///< store 32 bits uint
|
virtual void store_32(uint32_t p_dest); ///< store 32 bits uint
|
||||||
|
@ -62,20 +62,20 @@ void OS::debug_break(){
|
|||||||
// something
|
// something
|
||||||
};
|
};
|
||||||
|
|
||||||
void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
void OS::_set_logger(Logger *p_logger) {
|
||||||
|
if (_logger) {
|
||||||
const char *err_type = "**ERROR**";
|
memdelete(_logger);
|
||||||
switch (p_type) {
|
|
||||||
case ERR_ERROR: err_type = "**ERROR**"; break;
|
|
||||||
case ERR_WARNING: err_type = "**WARNING**"; break;
|
|
||||||
case ERR_SCRIPT: err_type = "**SCRIPT ERROR**"; break;
|
|
||||||
case ERR_SHADER: err_type = "**SHADER ERROR**"; break;
|
|
||||||
default: ERR_PRINT("Unknown error type"); break;
|
|
||||||
}
|
}
|
||||||
|
_logger = p_logger;
|
||||||
|
}
|
||||||
|
|
||||||
if (p_rationale && *p_rationale)
|
void OS::initialize_logger() {
|
||||||
print("%s: %s\n ", err_type, p_rationale);
|
_set_logger(memnew(StdLogger));
|
||||||
print("%s: At: %s:%i:%s() - %s\n", err_type, p_file, p_line, p_function, p_code);
|
}
|
||||||
|
|
||||||
|
void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type) {
|
||||||
|
|
||||||
|
_logger->log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS::print(const char *p_format, ...) {
|
void OS::print(const char *p_format, ...) {
|
||||||
@ -83,17 +83,16 @@ void OS::print(const char *p_format, ...) {
|
|||||||
va_list argp;
|
va_list argp;
|
||||||
va_start(argp, p_format);
|
va_start(argp, p_format);
|
||||||
|
|
||||||
vprint(p_format, argp);
|
_logger->logv(p_format, argp, false);
|
||||||
|
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
};
|
};
|
||||||
|
|
||||||
void OS::printerr(const char *p_format, ...) {
|
void OS::printerr(const char *p_format, ...) {
|
||||||
|
|
||||||
va_list argp;
|
va_list argp;
|
||||||
va_start(argp, p_format);
|
va_start(argp, p_format);
|
||||||
|
|
||||||
vprint(p_format, argp, true);
|
_logger->logv(p_format, argp, true);
|
||||||
|
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
};
|
};
|
||||||
@ -533,9 +532,12 @@ OS::OS() {
|
|||||||
|
|
||||||
_allow_hidpi = true;
|
_allow_hidpi = true;
|
||||||
_stack_bottom = (void *)(&stack_bottom);
|
_stack_bottom = (void *)(&stack_bottom);
|
||||||
|
|
||||||
|
_logger = NULL;
|
||||||
|
_set_logger(memnew(StdLogger));
|
||||||
}
|
}
|
||||||
|
|
||||||
OS::~OS() {
|
OS::~OS() {
|
||||||
|
memdelete(_logger);
|
||||||
singleton = NULL;
|
singleton = NULL;
|
||||||
}
|
}
|
||||||
|
21
core/os/os.h
21
core/os/os.h
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "io/logger.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "os/main_loop.h"
|
#include "os/main_loop.h"
|
||||||
#include "ustring.h"
|
#include "ustring.h"
|
||||||
@ -61,6 +62,11 @@ class OS {
|
|||||||
|
|
||||||
void *_stack_bottom;
|
void *_stack_bottom;
|
||||||
|
|
||||||
|
Logger *_logger;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void _set_logger(Logger *p_logger);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef void (*ImeCallback)(void *p_inp, String p_text, Point2 p_selection);
|
typedef void (*ImeCallback)(void *p_inp, String p_text, Point2 p_selection);
|
||||||
|
|
||||||
@ -108,6 +114,7 @@ protected:
|
|||||||
virtual int get_audio_driver_count() const = 0;
|
virtual int get_audio_driver_count() const = 0;
|
||||||
virtual const char *get_audio_driver_name(int p_driver) const = 0;
|
virtual const char *get_audio_driver_name(int p_driver) const = 0;
|
||||||
|
|
||||||
|
virtual void initialize_logger();
|
||||||
virtual void initialize_core() = 0;
|
virtual void initialize_core() = 0;
|
||||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) = 0;
|
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) = 0;
|
||||||
|
|
||||||
@ -127,18 +134,10 @@ public:
|
|||||||
|
|
||||||
static OS *get_singleton();
|
static OS *get_singleton();
|
||||||
|
|
||||||
enum ErrorType {
|
void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type = Logger::ERR_ERROR);
|
||||||
ERR_ERROR,
|
void print(const char *p_format, ...);
|
||||||
ERR_WARNING,
|
void printerr(const char *p_format, ...);
|
||||||
ERR_SCRIPT,
|
|
||||||
ERR_SHADER
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
|
|
||||||
|
|
||||||
virtual void print(const char *p_format, ...);
|
|
||||||
virtual void printerr(const char *p_format, ...);
|
|
||||||
virtual void vprint(const char *p_format, va_list p_list, bool p_stderr = false) = 0;
|
|
||||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") = 0;
|
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") = 0;
|
||||||
virtual String get_stdin_string(bool p_block = true) = 0;
|
virtual String get_stdin_string(bool p_block = true) = 0;
|
||||||
|
|
||||||
|
@ -223,6 +223,12 @@ Error FileAccessUnix::get_error() const {
|
|||||||
return last_error;
|
return last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileAccessUnix::flush() {
|
||||||
|
|
||||||
|
ERR_FAIL_COND(!f);
|
||||||
|
fflush(f);
|
||||||
|
}
|
||||||
|
|
||||||
void FileAccessUnix::store_8(uint8_t p_dest) {
|
void FileAccessUnix::store_8(uint8_t p_dest) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!f);
|
ERR_FAIL_COND(!f);
|
||||||
|
@ -72,6 +72,7 @@ public:
|
|||||||
|
|
||||||
virtual Error get_error() const; ///< get last error
|
virtual Error get_error() const; ///< get last error
|
||||||
|
|
||||||
|
virtual void flush();
|
||||||
virtual void store_8(uint8_t p_dest); ///< store a byte
|
virtual void store_8(uint8_t p_dest); ///< store a byte
|
||||||
|
|
||||||
virtual bool file_exists(const String &p_path); ///< return true if a file exists
|
virtual bool file_exists(const String &p_path); ///< return true if a file exists
|
||||||
|
@ -64,39 +64,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
extern bool _print_error_enabled;
|
|
||||||
|
|
||||||
void OS_Unix::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
|
||||||
|
|
||||||
if (!_print_error_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const char *err_details;
|
|
||||||
if (p_rationale && p_rationale[0])
|
|
||||||
err_details = p_rationale;
|
|
||||||
else
|
|
||||||
err_details = p_code;
|
|
||||||
|
|
||||||
switch (p_type) {
|
|
||||||
case ERR_ERROR:
|
|
||||||
print("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
|
||||||
print("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
|
|
||||||
break;
|
|
||||||
case ERR_WARNING:
|
|
||||||
print("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
|
||||||
print("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
|
|
||||||
break;
|
|
||||||
case ERR_SCRIPT:
|
|
||||||
print("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
|
||||||
print("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
|
|
||||||
break;
|
|
||||||
case ERR_SHADER:
|
|
||||||
print("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
|
||||||
print("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_Unix::debug_break() {
|
void OS_Unix::debug_break() {
|
||||||
|
|
||||||
@ -165,29 +133,16 @@ void OS_Unix::initialize_core() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OS_Unix::initialize_logger() {
|
||||||
|
Vector<Logger *> loggers;
|
||||||
|
loggers.push_back(memnew(UnixTerminalLogger));
|
||||||
|
loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
|
||||||
|
_set_logger(memnew(CompositeLogger(loggers)));
|
||||||
|
}
|
||||||
|
|
||||||
void OS_Unix::finalize_core() {
|
void OS_Unix::finalize_core() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_Unix::vprint(const char *p_format, va_list p_list, bool p_stder) {
|
|
||||||
|
|
||||||
if (p_stder) {
|
|
||||||
|
|
||||||
vfprintf(stderr, p_format, p_list);
|
|
||||||
fflush(stderr);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
vprintf(p_format, p_list);
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_Unix::print(const char *p_format, ...) {
|
|
||||||
|
|
||||||
va_list argp;
|
|
||||||
va_start(argp, p_format);
|
|
||||||
vprintf(p_format, argp);
|
|
||||||
va_end(argp);
|
|
||||||
}
|
|
||||||
void OS_Unix::alert(const String &p_alert, const String &p_title) {
|
void OS_Unix::alert(const String &p_alert, const String &p_title) {
|
||||||
|
|
||||||
fprintf(stderr, "ERROR: %s\n", p_alert.utf8().get_data());
|
fprintf(stderr, "ERROR: %s\n", p_alert.utf8().get_data());
|
||||||
@ -559,4 +514,38 @@ String OS_Unix::get_executable_path() const {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UnixTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
||||||
|
if (!should_log(true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *err_details;
|
||||||
|
if (p_rationale && p_rationale[0])
|
||||||
|
err_details = p_rationale;
|
||||||
|
else
|
||||||
|
err_details = p_code;
|
||||||
|
|
||||||
|
switch (p_type) {
|
||||||
|
case ERR_WARNING:
|
||||||
|
logf_error("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||||
|
logf_error("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||||
|
break;
|
||||||
|
case ERR_SCRIPT:
|
||||||
|
logf_error("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||||
|
logf_error("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||||
|
break;
|
||||||
|
case ERR_SHADER:
|
||||||
|
logf_error("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||||
|
logf_error("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||||
|
break;
|
||||||
|
case ERR_ERROR:
|
||||||
|
default:
|
||||||
|
logf_error("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||||
|
logf_error("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UnixTerminalLogger::~UnixTerminalLogger() {}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -54,11 +54,11 @@ protected:
|
|||||||
virtual int get_audio_driver_count() const;
|
virtual int get_audio_driver_count() const;
|
||||||
virtual const char *get_audio_driver_name(int p_driver) const;
|
virtual const char *get_audio_driver_name(int p_driver) const;
|
||||||
|
|
||||||
|
virtual void initialize_logger();
|
||||||
virtual void initialize_core();
|
virtual void initialize_core();
|
||||||
virtual int unix_initialize_audio(int p_audio_driver);
|
virtual int unix_initialize_audio(int p_audio_driver);
|
||||||
//virtual void initialize(int p_video_driver,int p_audio_driver);
|
//virtual void initialize(int p_video_driver,int p_audio_driver);
|
||||||
|
|
||||||
//virtual void finalize();
|
|
||||||
virtual void finalize_core();
|
virtual void finalize_core();
|
||||||
|
|
||||||
String stdin_buf;
|
String stdin_buf;
|
||||||
@ -66,10 +66,6 @@ protected:
|
|||||||
String get_global_settings_path() const;
|
String get_global_settings_path() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
|
|
||||||
|
|
||||||
virtual void print(const char *p_format, ...);
|
|
||||||
virtual void vprint(const char *p_format, va_list p_list, bool p_stder = false);
|
|
||||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||||
virtual String get_stdin_string(bool p_block);
|
virtual String get_stdin_string(bool p_block);
|
||||||
|
|
||||||
@ -120,6 +116,12 @@ public:
|
|||||||
//virtual void run( MainLoop * p_main_loop );
|
//virtual void run( MainLoop * p_main_loop );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UnixTerminalLogger : public StdLogger {
|
||||||
|
public:
|
||||||
|
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
|
||||||
|
virtual ~UnixTerminalLogger();
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
71
drivers/unix/syslog_logger.cpp
Normal file
71
drivers/unix/syslog_logger.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*************************************************************************/
|
||||||
|
/* syslog_logger.cpp */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
#ifdef UNIX_ENABLED
|
||||||
|
|
||||||
|
#include "syslog_logger.h"
|
||||||
|
#include "print_string.h"
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
void SyslogLogger::logv(const char *p_format, va_list p_list, bool p_err) {
|
||||||
|
if (!should_log(p_err)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vsyslog(p_err ? LOG_ERR : LOG_INFO, p_format, p_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SyslogLogger::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
||||||
|
if (!should_log(true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *err_type = "**ERROR**";
|
||||||
|
switch (p_type) {
|
||||||
|
case ERR_ERROR: err_type = "**ERROR**"; break;
|
||||||
|
case ERR_WARNING: err_type = "**WARNING**"; break;
|
||||||
|
case ERR_SCRIPT: err_type = "**SCRIPT ERROR**"; break;
|
||||||
|
case ERR_SHADER: err_type = "**SHADER ERROR**"; break;
|
||||||
|
default: ERR_PRINT("Unknown error type"); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *err_details;
|
||||||
|
if (p_rationale && *p_rationale)
|
||||||
|
err_details = p_rationale;
|
||||||
|
else
|
||||||
|
err_details = p_code;
|
||||||
|
|
||||||
|
syslog(p_type == ERR_WARNING ? LOG_WARNING : LOG_ERR, "%s: %s\n At: %s:%i:%s() - %s", err_type, err_details, p_file, p_line, p_function, p_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
SyslogLogger::~SyslogLogger() {
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
48
drivers/unix/syslog_logger.h
Normal file
48
drivers/unix/syslog_logger.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*************************************************************************/
|
||||||
|
/* syslog_logger.h */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef SYSLOG_LOGGER_H
|
||||||
|
#define SYSLOG_LOGGER_H
|
||||||
|
|
||||||
|
#ifdef UNIX_ENABLED
|
||||||
|
|
||||||
|
#include "io/logger.h"
|
||||||
|
|
||||||
|
class SyslogLogger : public Logger {
|
||||||
|
public:
|
||||||
|
virtual void logv(const char *p_format, va_list p_list, bool p_err);
|
||||||
|
virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type);
|
||||||
|
|
||||||
|
virtual ~SyslogLogger();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -162,10 +162,10 @@ Error DirAccessWindows::make_dir(String p_dir) {
|
|||||||
|
|
||||||
GLOBAL_LOCK_FUNCTION
|
GLOBAL_LOCK_FUNCTION
|
||||||
|
|
||||||
|
p_dir = fix_path(p_dir);
|
||||||
if (p_dir.is_rel_path())
|
if (p_dir.is_rel_path())
|
||||||
p_dir = get_current_dir().plus_file(p_dir);
|
p_dir = get_current_dir().plus_file(p_dir);
|
||||||
|
|
||||||
p_dir = fix_path(p_dir);
|
|
||||||
p_dir = p_dir.replace("/", "\\");
|
p_dir = p_dir.replace("/", "\\");
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
|
@ -207,6 +207,12 @@ Error FileAccessWindows::get_error() const {
|
|||||||
return last_error;
|
return last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileAccessWindows::flush() {
|
||||||
|
|
||||||
|
ERR_FAIL_COND(!f);
|
||||||
|
fflush(f);
|
||||||
|
}
|
||||||
|
|
||||||
void FileAccessWindows::store_8(uint8_t p_dest) {
|
void FileAccessWindows::store_8(uint8_t p_dest) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!f);
|
ERR_FAIL_COND(!f);
|
||||||
|
@ -64,6 +64,7 @@ public:
|
|||||||
|
|
||||||
virtual Error get_error() const; ///< get last error
|
virtual Error get_error() const; ///< get last error
|
||||||
|
|
||||||
|
virtual void flush();
|
||||||
virtual void store_8(uint8_t p_dest); ///< store a byte
|
virtual void store_8(uint8_t p_dest); ///< store a byte
|
||||||
|
|
||||||
virtual bool file_exists(const String &p_name); ///< return true if a file exists
|
virtual bool file_exists(const String &p_name); ///< return true if a file exists
|
||||||
|
@ -231,7 +231,6 @@ void Main::print_help(const char *p_binary) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) {
|
Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) {
|
||||||
|
|
||||||
RID_OwnerBase::init_rid();
|
RID_OwnerBase::init_rid();
|
||||||
|
|
||||||
OS::get_singleton()->initialize_core();
|
OS::get_singleton()->initialize_core();
|
||||||
@ -254,6 +253,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
|||||||
|
|
||||||
register_core_settings(); //here globals is present
|
register_core_settings(); //here globals is present
|
||||||
|
|
||||||
|
OS::get_singleton()->initialize_logger();
|
||||||
|
|
||||||
translation_server = memnew(TranslationServer);
|
translation_server = memnew(TranslationServer);
|
||||||
performance = memnew(Performance);
|
performance = memnew(Performance);
|
||||||
globals->add_singleton(ProjectSettings::Singleton("Performance", performance));
|
globals->add_singleton(ProjectSettings::Singleton("Performance", performance));
|
||||||
|
@ -146,6 +146,11 @@ Error FileAccessAndroid::get_error() const {
|
|||||||
return eof ? ERR_FILE_EOF : OK; //not sure what else it may happen
|
return eof ? ERR_FILE_EOF : OK; //not sure what else it may happen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileAccessAndroid::flush() {
|
||||||
|
|
||||||
|
ERR_FAIL();
|
||||||
|
}
|
||||||
|
|
||||||
void FileAccessAndroid::store_8(uint8_t p_dest) {
|
void FileAccessAndroid::store_8(uint8_t p_dest) {
|
||||||
|
|
||||||
ERR_FAIL();
|
ERR_FAIL();
|
||||||
|
@ -63,6 +63,7 @@ public:
|
|||||||
|
|
||||||
virtual Error get_error() const; ///< get last error
|
virtual Error get_error() const; ///< get last error
|
||||||
|
|
||||||
|
virtual void flush();
|
||||||
virtual void store_8(uint8_t p_dest); ///< store a byte
|
virtual void store_8(uint8_t p_dest); ///< store a byte
|
||||||
|
|
||||||
virtual bool file_exists(const String &p_path); ///< return true if a file exists
|
virtual bool file_exists(const String &p_path); ///< return true if a file exists
|
||||||
|
@ -157,6 +157,9 @@ Error FileAccessJAndroid::get_error() const {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileAccessJAndroid::flush() {
|
||||||
|
}
|
||||||
|
|
||||||
void FileAccessJAndroid::store_8(uint8_t p_dest) {
|
void FileAccessJAndroid::store_8(uint8_t p_dest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ public:
|
|||||||
|
|
||||||
virtual Error get_error() const; ///< get last error
|
virtual Error get_error() const; ///< get last error
|
||||||
|
|
||||||
|
virtual void flush();
|
||||||
virtual void store_8(uint8_t p_dest); ///< store a byte
|
virtual void store_8(uint8_t p_dest); ///< store a byte
|
||||||
|
|
||||||
virtual bool file_exists(const String &p_path); ///< return true if a file exists
|
virtual bool file_exists(const String &p_path); ///< return true if a file exists
|
||||||
|
@ -47,6 +47,15 @@
|
|||||||
#include "file_access_jandroid.h"
|
#include "file_access_jandroid.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class AndroidLogger : public Logger {
|
||||||
|
public:
|
||||||
|
virtual void logv(const char *p_format, va_list p_list, bool p_err) {
|
||||||
|
__android_log_vprint(p_err ? ANDROID_LOG_ERROR : ANDROID_LOG_INFO, "godot", p_format, p_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~AndroidLogger() {}
|
||||||
|
};
|
||||||
|
|
||||||
int OS_Android::get_video_driver_count() const {
|
int OS_Android::get_video_driver_count() const {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -111,6 +120,13 @@ void OS_Android::initialize_core() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OS_Android::initialize_logger() {
|
||||||
|
Vector<Logger *> loggers;
|
||||||
|
loggers.push_back(memnew(AndroidLogger));
|
||||||
|
loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
|
||||||
|
_set_logger(memnew(CompositeLogger(loggers)));
|
||||||
|
}
|
||||||
|
|
||||||
void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
|
void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!p_gl_extensions);
|
ERR_FAIL_COND(!p_gl_extensions);
|
||||||
@ -162,23 +178,9 @@ void OS_Android::delete_main_loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OS_Android::finalize() {
|
void OS_Android::finalize() {
|
||||||
|
|
||||||
memdelete(input);
|
memdelete(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_Android::vprint(const char *p_format, va_list p_list, bool p_stderr) {
|
|
||||||
|
|
||||||
__android_log_vprint(p_stderr ? ANDROID_LOG_ERROR : ANDROID_LOG_INFO, "godot", p_format, p_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_Android::print(const char *p_format, ...) {
|
|
||||||
|
|
||||||
va_list argp;
|
|
||||||
va_start(argp, p_format);
|
|
||||||
__android_log_vprint(ANDROID_LOG_INFO, "godot", p_format, argp);
|
|
||||||
va_end(argp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_Android::alert(const String &p_alert, const String &p_title) {
|
void OS_Android::alert(const String &p_alert, const String &p_title) {
|
||||||
|
|
||||||
//print("ALERT: %s\n", p_alert.utf8().get_data());
|
//print("ALERT: %s\n", p_alert.utf8().get_data());
|
||||||
@ -737,6 +739,8 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI
|
|||||||
set_keep_screen_on_func = p_set_keep_screen_on_func;
|
set_keep_screen_on_func = p_set_keep_screen_on_func;
|
||||||
alert_func = p_alert_func;
|
alert_func = p_alert_func;
|
||||||
use_reload_hooks = false;
|
use_reload_hooks = false;
|
||||||
|
|
||||||
|
_set_logger(memnew(AndroidLogger));
|
||||||
}
|
}
|
||||||
|
|
||||||
OS_Android::~OS_Android() {
|
OS_Android::~OS_Android() {
|
||||||
|
@ -149,6 +149,7 @@ public:
|
|||||||
virtual int get_audio_driver_count() const;
|
virtual int get_audio_driver_count() const;
|
||||||
virtual const char *get_audio_driver_name(int p_driver) const;
|
virtual const char *get_audio_driver_name(int p_driver) const;
|
||||||
|
|
||||||
|
virtual void initialize_logger();
|
||||||
virtual void initialize_core();
|
virtual void initialize_core();
|
||||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||||
|
|
||||||
@ -161,8 +162,6 @@ public:
|
|||||||
|
|
||||||
static OS *get_singleton();
|
static OS *get_singleton();
|
||||||
|
|
||||||
virtual void vprint(const char *p_format, va_list p_list, bool p_stderr = false);
|
|
||||||
virtual void print(const char *p_format, ...);
|
|
||||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||||
|
|
||||||
virtual void set_mouse_show(bool p_show);
|
virtual void set_mouse_show(bool p_show);
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "core/os/dir_access.h"
|
#include "core/os/dir_access.h"
|
||||||
#include "core/os/file_access.h"
|
#include "core/os/file_access.h"
|
||||||
#include "core/project_settings.h"
|
#include "core/project_settings.h"
|
||||||
|
#include "drivers/unix/syslog_logger.h"
|
||||||
|
|
||||||
#include "sem_iphone.h"
|
#include "sem_iphone.h"
|
||||||
|
|
||||||
@ -98,6 +99,13 @@ void OSIPhone::initialize_core() {
|
|||||||
SemaphoreIphone::make_default();
|
SemaphoreIphone::make_default();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void OSIPhone::initialize_logger() {
|
||||||
|
Vector<Logger *> loggers;
|
||||||
|
loggers.push_back(memnew(SyslogLogger));
|
||||||
|
loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
|
||||||
|
_set_logger(memnew(CompositeLogger(loggers)));
|
||||||
|
}
|
||||||
|
|
||||||
void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
|
void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
|
||||||
|
|
||||||
supported_orientations = 0;
|
supported_orientations = 0;
|
||||||
@ -568,6 +576,8 @@ OSIPhone::OSIPhone(int width, int height) {
|
|||||||
vm.resizable = false;
|
vm.resizable = false;
|
||||||
set_video_mode(vm);
|
set_video_mode(vm);
|
||||||
event_count = 0;
|
event_count = 0;
|
||||||
|
|
||||||
|
_set_logger(memnew(SyslogLogger));
|
||||||
};
|
};
|
||||||
|
|
||||||
OSIPhone::~OSIPhone() {
|
OSIPhone::~OSIPhone() {
|
||||||
|
@ -90,6 +90,7 @@ private:
|
|||||||
|
|
||||||
virtual VideoMode get_default_video_mode() const;
|
virtual VideoMode get_default_video_mode() const;
|
||||||
|
|
||||||
|
virtual void initialize_logger();
|
||||||
virtual void initialize_core();
|
virtual void initialize_core();
|
||||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||||
|
|
||||||
|
@ -85,6 +85,10 @@ void OS_JavaScript::initialize_core() {
|
|||||||
FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix> >(FileAccess::ACCESS_RESOURCES);
|
FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix> >(FileAccess::ACCESS_RESOURCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OS_JavaScript::initialize_logger() {
|
||||||
|
_set_logger(memnew(StdLogger));
|
||||||
|
}
|
||||||
|
|
||||||
void OS_JavaScript::set_opengl_extensions(const char *p_gl_extensions) {
|
void OS_JavaScript::set_opengl_extensions(const char *p_gl_extensions) {
|
||||||
|
|
||||||
ERR_FAIL_COND(!p_gl_extensions);
|
ERR_FAIL_COND(!p_gl_extensions);
|
||||||
|
@ -92,6 +92,7 @@ public:
|
|||||||
virtual int get_audio_driver_count() const;
|
virtual int get_audio_driver_count() const;
|
||||||
virtual const char *get_audio_driver_name(int p_driver) const;
|
virtual const char *get_audio_driver_name(int p_driver) const;
|
||||||
|
|
||||||
|
virtual void initialize_logger();
|
||||||
virtual void initialize_core();
|
virtual void initialize_core();
|
||||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||||
|
|
||||||
@ -104,11 +105,6 @@ public:
|
|||||||
|
|
||||||
//static OS* get_singleton();
|
//static OS* get_singleton();
|
||||||
|
|
||||||
virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
|
||||||
|
|
||||||
OS::print_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||||
|
|
||||||
virtual void set_mouse_mode(MouseMode p_mode);
|
virtual void set_mouse_mode(MouseMode p_mode);
|
||||||
|
@ -127,6 +127,7 @@ protected:
|
|||||||
virtual const char *get_video_driver_name(int p_driver) const;
|
virtual const char *get_video_driver_name(int p_driver) const;
|
||||||
virtual VideoMode get_default_video_mode() const;
|
virtual VideoMode get_default_video_mode() const;
|
||||||
|
|
||||||
|
virtual void initialize_logger();
|
||||||
virtual void initialize_core();
|
virtual void initialize_core();
|
||||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||||
virtual void finalize();
|
virtual void finalize();
|
||||||
@ -141,8 +142,6 @@ public:
|
|||||||
|
|
||||||
virtual String get_name();
|
virtual String get_name();
|
||||||
|
|
||||||
virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
|
|
||||||
|
|
||||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||||
|
|
||||||
virtual void set_cursor_shape(CursorShape p_shape);
|
virtual void set_cursor_shape(CursorShape p_shape);
|
||||||
|
@ -1145,43 +1145,67 @@ String OS_OSX::get_name() {
|
|||||||
return "OSX";
|
return "OSX";
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_OSX::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
|
||||||
if (!_print_error_enabled)
|
class OSXTerminalLogger : public StdLogger {
|
||||||
return;
|
public:
|
||||||
|
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR) {
|
||||||
|
if (!should_log(true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char *err_details;
|
const char *err_details;
|
||||||
if (p_rationale && p_rationale[0])
|
if (p_rationale && p_rationale[0])
|
||||||
err_details = p_rationale;
|
err_details = p_rationale;
|
||||||
else
|
else
|
||||||
err_details = p_code;
|
err_details = p_code;
|
||||||
|
|
||||||
switch (p_type) {
|
switch (p_type) {
|
||||||
case ERR_ERROR:
|
case ERR_WARNING:
|
||||||
os_log_error(OS_LOG_DEFAULT, "ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
|
os_log_info(OS_LOG_DEFAULT,
|
||||||
print("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
"WARNING: %{public}s: %{public}s\nAt: %{public}s:%i.",
|
||||||
print("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
|
p_function, err_details, p_file, p_line);
|
||||||
break;
|
logf_error("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function,
|
||||||
case ERR_WARNING:
|
err_details);
|
||||||
os_log_info(OS_LOG_DEFAULT, "WARNING: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
|
logf_error("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||||
print("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
break;
|
||||||
print("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
|
case ERR_SCRIPT:
|
||||||
break;
|
os_log_error(OS_LOG_DEFAULT,
|
||||||
case ERR_SCRIPT:
|
"SCRIPT ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.",
|
||||||
os_log_error(OS_LOG_DEFAULT, "SCRIPT ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
|
p_function, err_details, p_file, p_line);
|
||||||
print("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
logf_error("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function,
|
||||||
print("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
|
err_details);
|
||||||
break;
|
logf_error("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||||
case ERR_SHADER:
|
break;
|
||||||
os_log_error(OS_LOG_DEFAULT, "SHADER ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
|
case ERR_SHADER:
|
||||||
print("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
os_log_error(OS_LOG_DEFAULT,
|
||||||
print("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
|
"SHADER ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.",
|
||||||
break;
|
p_function, err_details, p_file, p_line);
|
||||||
|
logf_error("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function,
|
||||||
|
err_details);
|
||||||
|
logf_error("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||||
|
break;
|
||||||
|
case ERR_ERROR:
|
||||||
|
default:
|
||||||
|
os_log_error(OS_LOG_DEFAULT,
|
||||||
|
"ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.",
|
||||||
|
p_function, err_details, p_file, p_line);
|
||||||
|
logf_error("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||||
|
logf_error("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
OS_Unix::print_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
|
|
||||||
|
typedef UnixTerminalLogger OSXTerminalLogger;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void OS_OSX::initialize_logger() {
|
||||||
|
Vector<Logger *> loggers;
|
||||||
|
loggers.push_back(memnew(OSXTerminalLogger));
|
||||||
|
loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
|
||||||
|
_set_logger(memnew(CompositeLogger(loggers)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_OSX::alert(const String &p_alert, const String &p_title) {
|
void OS_OSX::alert(const String &p_alert, const String &p_title) {
|
||||||
@ -2016,6 +2040,8 @@ OS_OSX::OS_OSX() {
|
|||||||
window_size = Vector2(1024, 600);
|
window_size = Vector2(1024, 600);
|
||||||
zoomed = false;
|
zoomed = false;
|
||||||
display_scale = 1.0;
|
display_scale = 1.0;
|
||||||
|
|
||||||
|
_set_logger(memnew(OSXTerminalLogger));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OS_OSX::_check_internal_feature_support(const String &p_feature) {
|
bool OS_OSX::_check_internal_feature_support(const String &p_feature) {
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "platform/windows/packet_peer_udp_winsock.h"
|
#include "platform/windows/packet_peer_udp_winsock.h"
|
||||||
#include "platform/windows/stream_peer_winsock.h"
|
#include "platform/windows/stream_peer_winsock.h"
|
||||||
#include "platform/windows/tcp_server_winsock.h"
|
#include "platform/windows/tcp_server_winsock.h"
|
||||||
|
#include "platform/windows/windows_terminal_logger.h"
|
||||||
#include "project_settings.h"
|
#include "project_settings.h"
|
||||||
#include "servers/audio_server.h"
|
#include "servers/audio_server.h"
|
||||||
#include "servers/visual/visual_server_raster.h"
|
#include "servers/visual/visual_server_raster.h"
|
||||||
@ -182,6 +183,13 @@ void OSUWP::initialize_core() {
|
|||||||
cursor_shape = CURSOR_ARROW;
|
cursor_shape = CURSOR_ARROW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OSUWP::initialize_logger() {
|
||||||
|
Vector<Logger *> loggers;
|
||||||
|
loggers.push_back(memnew(WindowsTerminalLogger));
|
||||||
|
loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
|
||||||
|
_set_logger(memnew(CompositeLogger(loggers)));
|
||||||
|
}
|
||||||
|
|
||||||
bool OSUWP::can_draw() const {
|
bool OSUWP::can_draw() const {
|
||||||
|
|
||||||
return !minimized;
|
return !minimized;
|
||||||
@ -371,32 +379,6 @@ void OSUWP::finalize() {
|
|||||||
void OSUWP::finalize_core() {
|
void OSUWP::finalize_core() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSUWP::vprint(const char *p_format, va_list p_list, bool p_stderr) {
|
|
||||||
|
|
||||||
char buf[16384 + 1];
|
|
||||||
int len = vsnprintf(buf, 16384, p_format, p_list);
|
|
||||||
if (len <= 0)
|
|
||||||
return;
|
|
||||||
buf[len] = 0;
|
|
||||||
|
|
||||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0);
|
|
||||||
if (wlen < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
wchar_t *wbuf = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
|
|
||||||
MultiByteToWideChar(CP_UTF8, 0, buf, len, wbuf, wlen);
|
|
||||||
wbuf[wlen] = 0;
|
|
||||||
|
|
||||||
if (p_stderr)
|
|
||||||
fwprintf(stderr, L"%s", wbuf);
|
|
||||||
else
|
|
||||||
wprintf(L"%s", wbuf);
|
|
||||||
|
|
||||||
free(wbuf);
|
|
||||||
|
|
||||||
fflush(stdout);
|
|
||||||
};
|
|
||||||
|
|
||||||
void OSUWP::alert(const String &p_alert, const String &p_title) {
|
void OSUWP::alert(const String &p_alert, const String &p_title) {
|
||||||
|
|
||||||
Platform::String ^ alert = ref new Platform::String(p_alert.c_str());
|
Platform::String ^ alert = ref new Platform::String(p_alert.c_str());
|
||||||
@ -520,30 +502,6 @@ OS::VideoMode OSUWP::get_video_mode(int p_screen) const {
|
|||||||
void OSUWP::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
|
void OSUWP::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSUWP::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
|
||||||
|
|
||||||
const char *err_details;
|
|
||||||
if (p_rationale && p_rationale[0])
|
|
||||||
err_details = p_rationale;
|
|
||||||
else
|
|
||||||
err_details = p_code;
|
|
||||||
|
|
||||||
switch (p_type) {
|
|
||||||
case ERR_ERROR:
|
|
||||||
print("ERROR: %s: %s\n", p_function, err_details);
|
|
||||||
print(" At: %s:%i\n", p_file, p_line);
|
|
||||||
break;
|
|
||||||
case ERR_WARNING:
|
|
||||||
print("WARNING: %s: %s\n", p_function, err_details);
|
|
||||||
print(" At: %s:%i\n", p_file, p_line);
|
|
||||||
break;
|
|
||||||
case ERR_SCRIPT:
|
|
||||||
print("SCRIPT ERROR: %s: %s\n", p_function, err_details);
|
|
||||||
print(" At: %s:%i\n", p_file, p_line);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String OSUWP::get_name() {
|
String OSUWP::get_name() {
|
||||||
|
|
||||||
return "UWP";
|
return "UWP";
|
||||||
@ -890,6 +848,8 @@ OSUWP::OSUWP() {
|
|||||||
mouse_mode_changed = CreateEvent(NULL, TRUE, FALSE, L"os_mouse_mode_changed");
|
mouse_mode_changed = CreateEvent(NULL, TRUE, FALSE, L"os_mouse_mode_changed");
|
||||||
|
|
||||||
AudioDriverManager::add_driver(&audio_driver);
|
AudioDriverManager::add_driver(&audio_driver);
|
||||||
|
|
||||||
|
_set_logger(memnew(WindowsTerminalLogger));
|
||||||
}
|
}
|
||||||
|
|
||||||
OSUWP::~OSUWP() {
|
OSUWP::~OSUWP() {
|
||||||
|
@ -163,6 +163,7 @@ protected:
|
|||||||
virtual int get_audio_driver_count() const;
|
virtual int get_audio_driver_count() const;
|
||||||
virtual const char *get_audio_driver_name(int p_driver) const;
|
virtual const char *get_audio_driver_name(int p_driver) const;
|
||||||
|
|
||||||
|
virtual void initialize_logger();
|
||||||
virtual void initialize_core();
|
virtual void initialize_core();
|
||||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||||
|
|
||||||
@ -180,9 +181,6 @@ public:
|
|||||||
// Event to send to the app wrapper
|
// Event to send to the app wrapper
|
||||||
HANDLE mouse_mode_changed;
|
HANDLE mouse_mode_changed;
|
||||||
|
|
||||||
void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type);
|
|
||||||
|
|
||||||
virtual void vprint(const char *p_format, va_list p_list, bool p_stderr = false);
|
|
||||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||||
String get_stdin_string(bool p_block);
|
String get_stdin_string(bool p_block);
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ common_win = [
|
|||||||
"stream_peer_winsock.cpp",
|
"stream_peer_winsock.cpp",
|
||||||
"joypad.cpp",
|
"joypad.cpp",
|
||||||
"power_windows.cpp",
|
"power_windows.cpp",
|
||||||
|
"windows_terminal_logger.cpp"
|
||||||
]
|
]
|
||||||
|
|
||||||
restarget = "godot_res" + env["OBJSUFFIX"]
|
restarget = "godot_res" + env["OBJSUFFIX"]
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "servers/visual/visual_server_wrap_mt.h"
|
#include "servers/visual/visual_server_wrap_mt.h"
|
||||||
#include "stream_peer_winsock.h"
|
#include "stream_peer_winsock.h"
|
||||||
#include "tcp_server_winsock.h"
|
#include "tcp_server_winsock.h"
|
||||||
|
#include "windows_terminal_logger.h"
|
||||||
|
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <regstr.h>
|
#include <regstr.h>
|
||||||
@ -205,6 +206,13 @@ void OS_Windows::initialize_core() {
|
|||||||
cursor_shape = CURSOR_ARROW;
|
cursor_shape = CURSOR_ARROW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OS_Windows::initialize_logger() {
|
||||||
|
Vector<Logger *> loggers;
|
||||||
|
loggers.push_back(memnew(WindowsTerminalLogger));
|
||||||
|
loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
|
||||||
|
_set_logger(memnew(CompositeLogger(loggers)));
|
||||||
|
}
|
||||||
|
|
||||||
bool OS_Windows::can_draw() const {
|
bool OS_Windows::can_draw() const {
|
||||||
|
|
||||||
return !minimized;
|
return !minimized;
|
||||||
@ -1231,38 +1239,6 @@ void OS_Windows::finalize_core() {
|
|||||||
StreamPeerWinsock::cleanup();
|
StreamPeerWinsock::cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_Windows::vprint(const char *p_format, va_list p_list, bool p_stderr) {
|
|
||||||
|
|
||||||
const unsigned int BUFFER_SIZE = 16384;
|
|
||||||
char buf[BUFFER_SIZE + 1]; // +1 for the terminating character
|
|
||||||
int len = vsnprintf(buf, BUFFER_SIZE, p_format, p_list);
|
|
||||||
if (len <= 0)
|
|
||||||
return;
|
|
||||||
if (len >= BUFFER_SIZE)
|
|
||||||
len = BUFFER_SIZE; // Output is too big, will be truncated
|
|
||||||
buf[len] = 0;
|
|
||||||
|
|
||||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0);
|
|
||||||
if (wlen < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
wchar_t *wbuf = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
|
|
||||||
MultiByteToWideChar(CP_UTF8, 0, buf, len, wbuf, wlen);
|
|
||||||
wbuf[wlen] = 0;
|
|
||||||
|
|
||||||
if (p_stderr)
|
|
||||||
fwprintf(stderr, L"%ls", wbuf);
|
|
||||||
else
|
|
||||||
wprintf(L"%ls", wbuf);
|
|
||||||
|
|
||||||
#ifdef STDOUT_FILE
|
|
||||||
//vwfprintf(stdo,p_format,p_list);
|
|
||||||
#endif
|
|
||||||
free(wbuf);
|
|
||||||
|
|
||||||
fflush(stdout);
|
|
||||||
};
|
|
||||||
|
|
||||||
void OS_Windows::alert(const String &p_alert, const String &p_title) {
|
void OS_Windows::alert(const String &p_alert, const String &p_title) {
|
||||||
|
|
||||||
if (!is_no_window_mode_enabled())
|
if (!is_no_window_mode_enabled())
|
||||||
@ -1676,107 +1652,6 @@ void OS_Windows::request_attention() {
|
|||||||
FlashWindowEx(&info);
|
FlashWindowEx(&info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS_Windows::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
|
||||||
|
|
||||||
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
if (!hCon || hCon == INVALID_HANDLE_VALUE) {
|
|
||||||
|
|
||||||
const char *err_details;
|
|
||||||
if (p_rationale && p_rationale[0])
|
|
||||||
err_details = p_rationale;
|
|
||||||
else
|
|
||||||
err_details = p_code;
|
|
||||||
|
|
||||||
switch (p_type) {
|
|
||||||
case ERR_ERROR:
|
|
||||||
print("ERROR: %s: %s\n", p_function, err_details);
|
|
||||||
print(" At: %s:%i\n", p_file, p_line);
|
|
||||||
break;
|
|
||||||
case ERR_WARNING:
|
|
||||||
print("WARNING: %s: %s\n", p_function, err_details);
|
|
||||||
print(" At: %s:%i\n", p_file, p_line);
|
|
||||||
break;
|
|
||||||
case ERR_SCRIPT:
|
|
||||||
print("SCRIPT ERROR: %s: %s\n", p_function, err_details);
|
|
||||||
print(" At: %s:%i\n", p_file, p_line);
|
|
||||||
break;
|
|
||||||
case ERR_SHADER:
|
|
||||||
print("SHADER ERROR: %s: %s\n", p_function, err_details);
|
|
||||||
print(" At: %s:%i\n", p_file, p_line);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO sbi; //original
|
|
||||||
GetConsoleScreenBufferInfo(hCon, &sbi);
|
|
||||||
|
|
||||||
WORD current_fg = sbi.wAttributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
|
|
||||||
WORD current_bg = sbi.wAttributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY);
|
|
||||||
|
|
||||||
uint32_t basecol = 0;
|
|
||||||
switch (p_type) {
|
|
||||||
case ERR_ERROR: basecol = FOREGROUND_RED; break;
|
|
||||||
case ERR_WARNING: basecol = FOREGROUND_RED | FOREGROUND_GREEN; break;
|
|
||||||
case ERR_SCRIPT: basecol = FOREGROUND_RED | FOREGROUND_BLUE; break;
|
|
||||||
case ERR_SHADER: basecol = FOREGROUND_GREEN | FOREGROUND_BLUE; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
basecol |= current_bg;
|
|
||||||
|
|
||||||
if (p_rationale && p_rationale[0]) {
|
|
||||||
|
|
||||||
SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
|
|
||||||
switch (p_type) {
|
|
||||||
case ERR_ERROR: print("ERROR: "); break;
|
|
||||||
case ERR_WARNING: print("WARNING: "); break;
|
|
||||||
case ERR_SCRIPT: print("SCRIPT ERROR: "); break;
|
|
||||||
case ERR_SHADER: print("SHADER ERROR: "); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
|
|
||||||
print("%s\n", p_rationale);
|
|
||||||
|
|
||||||
SetConsoleTextAttribute(hCon, basecol);
|
|
||||||
switch (p_type) {
|
|
||||||
case ERR_ERROR: print(" At: "); break;
|
|
||||||
case ERR_WARNING: print(" At: "); break;
|
|
||||||
case ERR_SCRIPT: print(" At: "); break;
|
|
||||||
case ERR_SHADER: print(" At: "); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetConsoleTextAttribute(hCon, current_fg | current_bg);
|
|
||||||
print("%s:%i\n", p_file, p_line);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
|
|
||||||
switch (p_type) {
|
|
||||||
case ERR_ERROR: print("ERROR: %s: ", p_function); break;
|
|
||||||
case ERR_WARNING: print("WARNING: %s: ", p_function); break;
|
|
||||||
case ERR_SCRIPT: print("SCRIPT ERROR: %s: ", p_function); break;
|
|
||||||
case ERR_SHADER: print("SCRIPT ERROR: %s: ", p_function); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
|
|
||||||
print("%s\n", p_code);
|
|
||||||
|
|
||||||
SetConsoleTextAttribute(hCon, basecol);
|
|
||||||
switch (p_type) {
|
|
||||||
case ERR_ERROR: print(" At: "); break;
|
|
||||||
case ERR_WARNING: print(" At: "); break;
|
|
||||||
case ERR_SCRIPT: print(" At: "); break;
|
|
||||||
case ERR_SHADER: print(" At: "); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetConsoleTextAttribute(hCon, current_fg | current_bg);
|
|
||||||
print("%s:%i\n", p_file, p_line);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetConsoleTextAttribute(hCon, sbi.wAttributes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String OS_Windows::get_name() {
|
String OS_Windows::get_name() {
|
||||||
|
|
||||||
return "Windows";
|
return "Windows";
|
||||||
@ -2429,6 +2304,8 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
|
|||||||
#ifdef XAUDIO2_ENABLED
|
#ifdef XAUDIO2_ENABLED
|
||||||
AudioDriverManager::add_driver(&driver_xaudio2);
|
AudioDriverManager::add_driver(&driver_xaudio2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_set_logger(memnew(WindowsTerminalLogger));
|
||||||
}
|
}
|
||||||
|
|
||||||
OS_Windows::~OS_Windows() {
|
OS_Windows::~OS_Windows() {
|
||||||
|
@ -152,6 +152,7 @@ protected:
|
|||||||
virtual int get_audio_driver_count() const;
|
virtual int get_audio_driver_count() const;
|
||||||
virtual const char *get_audio_driver_name(int p_driver) const;
|
virtual const char *get_audio_driver_name(int p_driver) const;
|
||||||
|
|
||||||
|
virtual void initialize_logger();
|
||||||
virtual void initialize_core();
|
virtual void initialize_core();
|
||||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||||
|
|
||||||
@ -180,9 +181,6 @@ protected:
|
|||||||
public:
|
public:
|
||||||
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type);
|
|
||||||
|
|
||||||
virtual void vprint(const char *p_format, va_list p_list, bool p_stderr = false);
|
|
||||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||||
String get_stdin_string(bool p_block);
|
String get_stdin_string(bool p_block);
|
||||||
|
|
||||||
|
157
platform/windows/windows_terminal_logger.cpp
Normal file
157
platform/windows/windows_terminal_logger.cpp
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/*************************************************************************/
|
||||||
|
/* windows_terminal_logger.cpp */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
#include "windows_terminal_logger.h"
|
||||||
|
|
||||||
|
#ifdef WINDOWS_ENABLED
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
void WindowsTerminalLogger::logv(const char *p_format, va_list p_list, bool p_err) {
|
||||||
|
if (!should_log(p_err)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned int BUFFER_SIZE = 16384;
|
||||||
|
char buf[BUFFER_SIZE + 1]; // +1 for the terminating character
|
||||||
|
int len = vsnprintf(buf, BUFFER_SIZE, p_format, p_list);
|
||||||
|
if (len <= 0)
|
||||||
|
return;
|
||||||
|
if (len >= BUFFER_SIZE)
|
||||||
|
len = BUFFER_SIZE; // Output is too big, will be truncated
|
||||||
|
buf[len] = 0;
|
||||||
|
|
||||||
|
int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0);
|
||||||
|
if (wlen < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wchar_t *wbuf = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, buf, len, wbuf, wlen);
|
||||||
|
wbuf[wlen] = 0;
|
||||||
|
|
||||||
|
if (p_err)
|
||||||
|
fwprintf(stderr, L"%ls", wbuf);
|
||||||
|
else
|
||||||
|
wprintf(L"%ls", wbuf);
|
||||||
|
|
||||||
|
free(wbuf);
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
||||||
|
if (!should_log(true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef UWP_ENABLED
|
||||||
|
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
if (!hCon || hCon == INVALID_HANDLE_VALUE) {
|
||||||
|
#endif
|
||||||
|
StdLogger::log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
|
||||||
|
#ifndef UWP_ENABLED
|
||||||
|
} else {
|
||||||
|
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO sbi; //original
|
||||||
|
GetConsoleScreenBufferInfo(hCon, &sbi);
|
||||||
|
|
||||||
|
WORD current_fg = sbi.wAttributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
|
||||||
|
WORD current_bg = sbi.wAttributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY);
|
||||||
|
|
||||||
|
uint32_t basecol = 0;
|
||||||
|
switch (p_type) {
|
||||||
|
case ERR_ERROR: basecol = FOREGROUND_RED; break;
|
||||||
|
case ERR_WARNING: basecol = FOREGROUND_RED | FOREGROUND_GREEN; break;
|
||||||
|
case ERR_SCRIPT: basecol = FOREGROUND_RED | FOREGROUND_BLUE; break;
|
||||||
|
case ERR_SHADER: basecol = FOREGROUND_GREEN | FOREGROUND_BLUE; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
basecol |= current_bg;
|
||||||
|
|
||||||
|
if (p_rationale && p_rationale[0]) {
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
|
||||||
|
switch (p_type) {
|
||||||
|
case ERR_ERROR: logf("ERROR: "); break;
|
||||||
|
case ERR_WARNING: logf("WARNING: "); break;
|
||||||
|
case ERR_SCRIPT: logf("SCRIPT ERROR: "); break;
|
||||||
|
case ERR_SHADER: logf("SHADER ERROR: "); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
|
||||||
|
logf("%s\n", p_rationale);
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(hCon, basecol);
|
||||||
|
switch (p_type) {
|
||||||
|
case ERR_ERROR: logf(" At: "); break;
|
||||||
|
case ERR_WARNING: logf(" At: "); break;
|
||||||
|
case ERR_SCRIPT: logf(" At: "); break;
|
||||||
|
case ERR_SHADER: logf(" At: "); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(hCon, current_fg | current_bg);
|
||||||
|
logf("%s:%i\n", p_file, p_line);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
|
||||||
|
switch (p_type) {
|
||||||
|
case ERR_ERROR: logf("ERROR: %s: ", p_function); break;
|
||||||
|
case ERR_WARNING: logf("WARNING: %s: ", p_function); break;
|
||||||
|
case ERR_SCRIPT: logf("SCRIPT ERROR: %s: ", p_function); break;
|
||||||
|
case ERR_SHADER: logf("SCRIPT ERROR: %s: ", p_function); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
|
||||||
|
logf("%s\n", p_code);
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(hCon, basecol);
|
||||||
|
switch (p_type) {
|
||||||
|
case ERR_ERROR: logf(" At: "); break;
|
||||||
|
case ERR_WARNING: logf(" At: "); break;
|
||||||
|
case ERR_SCRIPT: logf(" At: "); break;
|
||||||
|
case ERR_SHADER: logf(" At: "); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(hCon, current_fg | current_bg);
|
||||||
|
logf("%s:%i\n", p_file, p_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetConsoleTextAttribute(hCon, sbi.wAttributes);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowsTerminalLogger::~WindowsTerminalLogger() {}
|
||||||
|
|
||||||
|
#endif
|
47
platform/windows/windows_terminal_logger.h
Normal file
47
platform/windows/windows_terminal_logger.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*************************************************************************/
|
||||||
|
/* windows_terminal_logger.h */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef WINDOWS_TERMINAL_LOGGER_H
|
||||||
|
#define WINDOWS_TERMINAL_LOGGER_H
|
||||||
|
|
||||||
|
#ifdef WINDOWS_ENABLED
|
||||||
|
|
||||||
|
#include "io/logger.h"
|
||||||
|
|
||||||
|
class WindowsTerminalLogger : public StdLogger {
|
||||||
|
public:
|
||||||
|
virtual void logv(const char *p_format, va_list p_list, bool p_err);
|
||||||
|
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
|
||||||
|
virtual ~WindowsTerminalLogger();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user