mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-29 19:20:09 +00:00
Merge branch 'new-log'
This commit is contained in:
commit
bc9c3b0ec2
@ -109,8 +109,8 @@ public:
|
||||
// This is a raw pointer because we want to delete this explicitly.
|
||||
app::crash::DataRecovery* m_recovery;
|
||||
|
||||
Modules(bool verbose)
|
||||
: m_loggerModule(verbose)
|
||||
Modules(bool createLogInDesktop)
|
||||
: m_loggerModule(createLogInDesktop)
|
||||
, m_recovery(nullptr) {
|
||||
}
|
||||
|
||||
@ -164,10 +164,23 @@ void App::initialize(const AppOptions& options)
|
||||
if (m_isGui)
|
||||
m_uiSystem.reset(new ui::UISystem);
|
||||
|
||||
// Initializes the application loading the modules, setting the
|
||||
// graphics mode, loading the configuration and resources, etc.
|
||||
m_coreModules = new CoreModules;
|
||||
m_modules = new Modules(options.verbose());
|
||||
|
||||
bool createLogInDesktop = false;
|
||||
switch (options.verboseLevel()) {
|
||||
case AppOptions::kNoVerbose:
|
||||
base::set_log_level(ERROR);
|
||||
break;
|
||||
case AppOptions::kVerbose:
|
||||
base::set_log_level(INFO);
|
||||
break;
|
||||
case AppOptions::kHighlyVerbose:
|
||||
base::set_log_level(VERBOSE);
|
||||
createLogInDesktop = true;
|
||||
break;
|
||||
}
|
||||
|
||||
m_modules = new Modules(createLogInDesktop);
|
||||
m_legacy = new LegacyModules(isGui() ? REQUIRE_INTERFACE: 0);
|
||||
m_brushes.reset(new AppBrushes);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -24,7 +24,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
|
||||
: m_exeName(base::get_file_name(argv[0]))
|
||||
, m_startUI(true)
|
||||
, m_startShell(false)
|
||||
, m_verboseEnabled(false)
|
||||
, m_verboseLevel(kNoVerbose)
|
||||
, m_palette(m_po.add("palette").requiresValue("<filename>").description("Use a specific palette by default"))
|
||||
, m_shell(m_po.add("shell").description("Start an interactive console to execute scripts"))
|
||||
, m_batch(m_po.add("batch").mnemonic('b').description("Do not start the UI"))
|
||||
@ -52,13 +52,18 @@ AppOptions::AppOptions(int argc, const char* argv[])
|
||||
, m_listLayers(m_po.add("list-layers").description("List layers of the next given sprite\nor include layers in JSON data"))
|
||||
, m_listTags(m_po.add("list-tags").description("List tags of the next given sprite sprite\nor include frame tags in JSON data"))
|
||||
, m_verbose(m_po.add("verbose").mnemonic('v').description("Explain what is being done"))
|
||||
, m_debug(m_po.add("debug").description("Extreme verbose mode and\ncopy log to desktop"))
|
||||
, m_help(m_po.add("help").mnemonic('?').description("Display this help and exits"))
|
||||
, m_version(m_po.add("version").description("Output version information and exit"))
|
||||
{
|
||||
try {
|
||||
m_po.parse(argc, argv);
|
||||
|
||||
m_verboseEnabled = m_po.enabled(m_verbose);
|
||||
if (m_po.enabled(m_debug))
|
||||
m_verboseLevel = kHighlyVerbose;
|
||||
else if (m_po.enabled(m_verbose))
|
||||
m_verboseLevel = kVerbose;
|
||||
|
||||
m_paletteFileName = m_po.value_of(m_palette);
|
||||
m_startShell = m_po.enabled(m_shell);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -19,6 +19,12 @@ namespace app {
|
||||
|
||||
class AppOptions {
|
||||
public:
|
||||
enum VerboseLevel {
|
||||
kNoVerbose,
|
||||
kVerbose,
|
||||
kHighlyVerbose,
|
||||
};
|
||||
|
||||
typedef base::ProgramOptions PO;
|
||||
typedef PO::Option Option;
|
||||
typedef PO::ValueList ValueList;
|
||||
@ -27,7 +33,7 @@ public:
|
||||
|
||||
bool startUI() const { return m_startUI; }
|
||||
bool startShell() const { return m_startShell; }
|
||||
bool verbose() const { return m_verboseEnabled; }
|
||||
VerboseLevel verboseLevel() const { return m_verboseLevel; }
|
||||
|
||||
const std::string& paletteFileName() const { return m_paletteFileName; }
|
||||
|
||||
@ -70,7 +76,7 @@ private:
|
||||
base::ProgramOptions m_po;
|
||||
bool m_startUI;
|
||||
bool m_startShell;
|
||||
bool m_verboseEnabled;
|
||||
VerboseLevel m_verboseLevel;
|
||||
std::string m_paletteFileName;
|
||||
|
||||
Option& m_palette;
|
||||
@ -101,6 +107,7 @@ private:
|
||||
Option& m_listTags;
|
||||
|
||||
Option& m_verbose;
|
||||
Option& m_debug;
|
||||
Option& m_help;
|
||||
Option& m_version;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -17,19 +17,17 @@
|
||||
|
||||
namespace app {
|
||||
|
||||
static LoggerModule* logger_instance = NULL;
|
||||
|
||||
LoggerModule::LoggerModule(bool verbose)
|
||||
: m_verbose(verbose)
|
||||
LoggerModule::LoggerModule(bool createLogInDesktop)
|
||||
{
|
||||
logger_instance = this;
|
||||
app::ResourceFinder rf(false);
|
||||
|
||||
if (verbose) {
|
||||
app::ResourceFinder rf(false);
|
||||
if (createLogInDesktop)
|
||||
rf.includeDesktopDir(PACKAGE "-v" VERSION "-DebugOutput.txt");
|
||||
else
|
||||
rf.includeUserDir("aseprite.log");
|
||||
auto filename = rf.defaultFilename();
|
||||
base_set_log_filename(filename.c_str());
|
||||
}
|
||||
|
||||
auto filename = rf.defaultFilename();
|
||||
base::set_log_filename(filename.c_str());
|
||||
}
|
||||
|
||||
LoggerModule::~LoggerModule()
|
||||
@ -37,8 +35,7 @@ LoggerModule::~LoggerModule()
|
||||
LOG("Logger module: shutting down (this is the last line)\n");
|
||||
|
||||
// Close log file
|
||||
base_set_log_filename("");
|
||||
logger_instance = nullptr;
|
||||
base::set_log_filename("");
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -13,13 +13,8 @@ namespace app {
|
||||
|
||||
class LoggerModule {
|
||||
public:
|
||||
LoggerModule(bool verbose);
|
||||
LoggerModule(bool createLogInDesktop);
|
||||
~LoggerModule();
|
||||
|
||||
bool isVerbose() const { return m_verbose; }
|
||||
|
||||
private:
|
||||
bool m_verbose;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -19,6 +19,11 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
namespace app {
|
||||
|
||||
ResourceFinder::ResourceFinder(bool log)
|
||||
@ -163,6 +168,41 @@ void ResourceFinder::includeUserDir(const char* filename)
|
||||
#endif
|
||||
}
|
||||
|
||||
void ResourceFinder::includeDesktopDir(const char* filename)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
std::vector<wchar_t> buf(MAX_PATH);
|
||||
HRESULT hr = SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, NULL,
|
||||
SHGFP_TYPE_DEFAULT, &buf[0]);
|
||||
if (hr == S_OK) {
|
||||
addPath(base::join_path(base::to_utf8(&buf[0]), filename));
|
||||
}
|
||||
else {
|
||||
includeHomeDir(filename);
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
// TODO get the desktop folder
|
||||
// $HOME/Desktop/filename
|
||||
includeHomeDir(base::join_path(std::string("Desktop"), filename).c_str());
|
||||
|
||||
#else
|
||||
|
||||
char* desktopDir = std::getenv("XDG_DESKTOP_DIR");
|
||||
if (desktopDir) {
|
||||
// $XDG_DESKTOP_DIR/filename
|
||||
addPath(base::join_path(desktopDir, filename));
|
||||
}
|
||||
else {
|
||||
// $HOME/Desktop/filename
|
||||
includeHomeDir(base::join_path(std::string("Desktop"), filename).c_str());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string ResourceFinder::getFirstOrCreateDefault()
|
||||
{
|
||||
std::string fn;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
@ -51,6 +51,8 @@ namespace app {
|
||||
// - The filename will be in $HOME/.config/aseprite/
|
||||
void includeUserDir(const char* filename);
|
||||
|
||||
void includeDesktopDir(const char* filename);
|
||||
|
||||
// Returns the first file found or creates the whole directory
|
||||
// structure to create the file in its default location.
|
||||
std::string getFirstOrCreateDefault();
|
||||
|
102
src/base/log.cpp
102
src/base/log.cpp
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
// Copyright (c) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -10,47 +10,99 @@
|
||||
|
||||
#include "base/log.h"
|
||||
|
||||
#include "base/file_handle.h"
|
||||
#include "base/fstream_path.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
static FILE* log_fileptr = nullptr;
|
||||
static std::string log_filename;
|
||||
namespace {
|
||||
|
||||
void base_set_log_filename(const char* filename)
|
||||
{
|
||||
if (log_fileptr) {
|
||||
fclose(log_fileptr);
|
||||
log_fileptr = nullptr;
|
||||
class nullbuf : public std::streambuf {
|
||||
protected:
|
||||
int_type overflow(int_type ch) override {
|
||||
return traits_type::not_eof(ch);
|
||||
}
|
||||
};
|
||||
|
||||
class nullstream : public std::ostream {
|
||||
public:
|
||||
nullstream()
|
||||
: std::basic_ios<char_type, traits_type>(&m_buf)
|
||||
, std::ostream(&m_buf) { }
|
||||
private:
|
||||
nullbuf m_buf;
|
||||
};
|
||||
|
||||
LogLevel log_level = LogLevel::NONE;
|
||||
nullstream null_stream;
|
||||
std::ofstream log_stream;
|
||||
std::string log_filename;
|
||||
|
||||
bool open_log_stream()
|
||||
{
|
||||
if (!log_stream.is_open()) {
|
||||
if (log_filename.empty())
|
||||
return false;
|
||||
|
||||
log_stream.open(FSTREAM_PATH(log_filename));
|
||||
}
|
||||
return log_stream.is_open();
|
||||
}
|
||||
|
||||
void log_text(const char* text)
|
||||
{
|
||||
if (!open_log_stream())
|
||||
return;
|
||||
|
||||
log_stream.write(text, strlen(text));
|
||||
log_stream.flush();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void base::set_log_filename(const char* filename)
|
||||
{
|
||||
if (log_stream.is_open())
|
||||
log_stream.close();
|
||||
|
||||
log_filename = filename;
|
||||
}
|
||||
|
||||
void base_log(const char* format, ...)
|
||||
void base::set_log_level(LogLevel level)
|
||||
{
|
||||
if (!log_fileptr) {
|
||||
if (log_filename.empty())
|
||||
return;
|
||||
log_level = level;
|
||||
}
|
||||
|
||||
log_fileptr = base::open_file_raw(log_filename, "w");
|
||||
}
|
||||
std::ostream& base::get_log_stream(LogLevel level)
|
||||
{
|
||||
ASSERT(level != NONE);
|
||||
|
||||
if (log_fileptr) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
if ((log_level < level) ||
|
||||
(!log_stream.is_open() && !open_log_stream()))
|
||||
return null_stream;
|
||||
else
|
||||
return log_stream;
|
||||
}
|
||||
|
||||
vfprintf(log_fileptr, format, ap);
|
||||
fflush(log_fileptr);
|
||||
void LOG(const char* format, ...)
|
||||
{
|
||||
if (log_level < INFO)
|
||||
return;
|
||||
|
||||
char buf[2048];
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
std::vsnprintf(buf, sizeof(buf)-1, format, ap);
|
||||
log_text(buf);
|
||||
|
||||
#ifdef _DEBUG
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
fflush(stderr);
|
||||
fputs(buf, stderr);
|
||||
fflush(stderr);
|
||||
#endif
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
// Copyright (c) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -8,12 +8,35 @@
|
||||
#define BASE_LOG_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
// Define BASE_DONT_DEFINE_LOG_MACRO in case that you don't need LOG
|
||||
#ifndef BASE_DONT_DEFINE_LOG_MACRO
|
||||
#define LOG base_log
|
||||
#endif
|
||||
enum LogLevel {
|
||||
NONE = 0, // Default log level: do not log
|
||||
FATAL = 1, // Something failed and we CANNOT continue the execution
|
||||
ERROR = 2, // Something failed, the UI should show this, and we can continue
|
||||
WARNING = 3, // Something failed, the UI don't need to show this, and we can continue
|
||||
INFO = 4, // Information about some important event
|
||||
VERBOSE = 5, // Information step by step
|
||||
};
|
||||
|
||||
void base_set_log_filename(const char* filename);
|
||||
void base_log(const char* format, ...);
|
||||
// E.g. LOG("text in information log level\n");
|
||||
void LOG(const char* format, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <iosfwd>
|
||||
|
||||
namespace base {
|
||||
|
||||
void set_log_filename(const char* filename);
|
||||
void set_log_level(LogLevel level);
|
||||
|
||||
std::ostream& get_log_stream(LogLevel level);
|
||||
|
||||
} // namespace base
|
||||
|
||||
// E.g. LOG(INFO) << "some information\n";
|
||||
inline std::ostream& LOG(LogLevel level) {
|
||||
return base::get_log_stream(level);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user