VMProtect/VMProtectCon/console.cc

169 lines
3.9 KiB
C++

#include "../core/objects.h"
#include "../core/osutils.h"
#include "../core/files.h"
#include "../core/processors.h"
#include "../core/lang.h"
#include "console.h"
/**
* ConsoleLog
*/
ConsoleLog::ConsoleLog()
: pos_(0), max_(0), percent_value_(0), percent_chars_(0), warnings_as_errors_(false)
{
show_progress_ = (isatty(fileno(stdout)) != 0);
}
static const char *compilation_type[] = {
"V",
"M",
"U"
};
bool IsUserFunction(const IFunction *func)
{
IArchitecture *file = func->owner()->owner();
return (file && file->function_list()->IndexOf(func) != NOT_ID);
}
void ConsoleLog::Notify(MessageType type, IObject *sender, const std::string &message)
{
static const LangString message_lang_type[] = {
lsInformation,
lsWarning,
lsError,
lsLoading,
lsChanging,
lsDeleting,
lsScript,
};
bool need_throw;
if (type == mtWarning && warnings_as_errors_) {
type = mtError;
need_throw = true;
} else {
need_throw = false;
}
std::string log_message, add;
std::string message_type = language[message_lang_type[type]];
if (sender) {
if (IFunction *func = dynamic_cast<IFunction *>(sender)) {
if (IsUserFunction(func) && (type == mtAdded || type == mtChanged || type == mtDeleted)) {
std::string compilation_type_str = func->need_compile() ? compilation_type[func->compilation_type()] : "-";
std::string address_str = func->type() != otUnknown ? string_format("%.8llX", func->address()) : "????????";
log_message = string_format("%s [%s] %s %s", message_type.c_str(), compilation_type_str.c_str(), address_str.c_str(), func->display_name().c_str());
}
} else if (ICommand *command = dynamic_cast<ICommand *>(sender)) {
if (IsUserFunction(command->owner())) {
std::string func_name;
if (command->owner()) {
func_name = command->owner()->display_name();
if (!func_name.empty())
func_name += ".";
}
add = string_format("%s%.8llX: ", func_name.c_str(), command->address());
}
}
}
if (type == mtInformation || type == mtWarning || type == mtError || type == mtScript)
log_message = string_format("[%s] %s%s", message_type.c_str(), add.c_str(), message.c_str());
if (!log_message.empty()) {
EndProgress();
PrintArch();
operator << (log_message) << endl;
}
if (need_throw)
throw abort_error("");
}
void ConsoleLog::StartProgress(const std::string &caption, unsigned long long max)
{
EndProgress();
caption_ = caption;
pos_ = 0;
max_ = max;
percent_value_ = 0;
}
void ConsoleLog::PrintArch()
{
if (!arch_name_.empty())
operator << (arch_name_) << "> ";
}
void ConsoleLog::PrintPercent()
{
std::string percent_str = string_format(" %d%%", percent_value_);
operator << (percent_str);
percent_chars_ = percent_str.size();
}
void ConsoleLog::StepProgress(unsigned long long value, bool is_project)
{
if (is_project)
return;
pos_ += value;
size_t old_percent_value = percent_value_;
percent_value_ = static_cast<size_t>(100.0 * pos_ / max_);
if (percent_chars_) {
if (percent_value_ == old_percent_value)
return;
if (percent_chars_ != NEED_PRINT_PERCENT) {
std::string back_str;
size_t i;
for (i = 0; i < percent_chars_; i++) {
back_str += '\b';
}
for (i = 0; i < percent_chars_; i++) {
back_str += ' ';
}
for (i = 0; i < percent_chars_; i++) {
back_str += '\b';
}
operator << (back_str);
}
} else {
PrintArch();
operator << (caption_);
}
if (show_progress_)
PrintPercent();
else
percent_chars_ = NEED_PRINT_PERCENT;
}
void ConsoleLog::EndProgress()
{
if (!percent_chars_)
return;
if (percent_chars_ == NEED_PRINT_PERCENT)
PrintPercent();
operator << (endl);
percent_chars_ = 0;
}
ConsoleLog &ConsoleLog::operator<<(ConsoleLog & (* function)(ConsoleLog &))
{
(*function)(*this);
return *this;
}
ConsoleLog &ConsoleLog::operator<<(const std::string &text)
{
os::Print(text.c_str());
return *this;
}
ConsoleLog &endl(ConsoleLog &log)
{
return log << "\n";
}