PICout improvement:

* renamed private members for more clear code
 * registerExternalBufferID() method to obtain unique ID for withExternalBuffer()
 * PICoutManipulators::PICoutStdStream enum for select stream (stdout or stderr)
 * Constructors now accept optional stream
 * piCerr and piCerrObj macros

PIDir::temporary() moved to "mkdtemp"

PILog:
 * now 4 levels
 * you can set max level
 * Error writes to piCerr
This commit is contained in:
2024-09-16 16:06:07 +03:00
parent 9d4357c066
commit 000ce2a54d
11 changed files with 357 additions and 320 deletions

View File

@@ -76,6 +76,10 @@ PILog::PILog(): PIThread(), log_ts(&log_file) {
split_time = 8_h; split_time = 8_h;
timestamp_format = "yyyy-MM-dd hh:mm:ss.zzz"; timestamp_format = "yyyy-MM-dd hh:mm:ss.zzz";
setLineFormat("t - c: m"); setLineFormat("t - c: m");
id_by_cat[Level::Info] = PICout::registerExternalBufferID();
id_by_cat[Level::Debug] = PICout::registerExternalBufferID();
id_by_cat[Level::Warning] = PICout::registerExternalBufferID();
id_by_cat[Level::Error] = PICout::registerExternalBufferID();
CONNECTU(PICout::Notifier::object(), finished, this, coutDone); CONNECTU(PICout::Notifier::object(), finished, this, coutDone);
} }
@@ -101,18 +105,28 @@ void PILog::setLineFormat(const PIString & f) {
} }
PICout PILog::debug(PIObject * context) { void PILog::setLevel(Level l) {
return makePICout(context, Category::Debug); max_level = l;
}
PICout PILog::warning(PIObject * context) {
return makePICout(context, Category::Warning);
} }
PICout PILog::error(PIObject * context) { PICout PILog::error(PIObject * context) {
return makePICout(context, Category::Error); return makePICout(context, Level::Error);
}
PICout PILog::warning(PIObject * context) {
return makePICout(context, Level::Warning);
}
PICout PILog::info(PIObject * context) {
return makePICout(context, Level::Info);
}
PICout PILog::debug(PIObject * context) {
return makePICout(context, Level::Debug);
} }
@@ -129,35 +143,27 @@ void PILog::stop() {
void PILog::coutDone(int id, PIString * buffer) { void PILog::coutDone(int id, PIString * buffer) {
cout_mutex.lock();
if (!cout_cat_by_id.contains(id)) {
cout_mutex.unlock();
return;
}
auto cat = cout_cat_by_id.take(id, PILog::Category::Debug);
cout_mutex.unlock();
if (!buffer) return; if (!buffer) return;
if (!id_by_cat.containsValue(id)) return;
auto cat = id_by_cat.key(id, PILog::Level::Debug);
if (cat > max_level) return;
enqueue(*buffer, cat); enqueue(*buffer, cat);
delete buffer; delete buffer;
} }
PICout PILog::makePICout(PIObject * context, Category cat) { PICout PILog::makePICout(PIObject * context, Level cat) {
cout_mutex.lock(); auto buffer = new PIString();
int id = ++cout_id;
auto buffer = new PIString();
cout_cat_by_id[id] = cat;
cout_mutex.unlock();
if (context) { if (context) {
*buffer = "["_a + context->className(); *buffer = "["_a + context->className();
if (context->name().isNotEmpty()) *buffer += " \"" + context->name() + "\""; if (context->name().isNotEmpty()) *buffer += " \"" + context->name() + "\"";
*buffer += "] "; *buffer += "] ";
} }
return PICout::withExternalBuffer(buffer, id, PICoutManipulators::AddSpaces); return PICout::withExternalBuffer(buffer, id_by_cat.value(cat), PICoutManipulators::AddSpaces);
} }
void PILog::enqueue(const PIString & msg, Category cat) { void PILog::enqueue(const PIString & msg, Level cat) {
if (log_file.isClosed()) return; if (log_file.isClosed()) return;
auto t = PIDateTime::fromSystemTime(PISystemTime::current()); auto t = PIDateTime::fromSystemTime(PISystemTime::current());
PIMutexLocker ml(log_mutex); PIMutexLocker ml(log_mutex);
@@ -166,7 +172,7 @@ void PILog::enqueue(const PIString & msg, Category cat) {
PIString PILog::entryToString(const Entry & e) const { PIString PILog::entryToString(const Entry & e) const {
static PIStringList categories{"debug", "warn ", "error"}; static PIStringList categories{"error", "warn ", "info ", "debug"};
PIString t = e.time.toString(timestamp_format); PIString t = e.time.toString(timestamp_format);
PIString ret = line_format_p; PIString ret = line_format_p;
ret.replace("${t}", t).replace("${c}", categories[static_cast<int>(e.cat)]).replace("${m}", e.msg); ret.replace("${t}", t).replace("${c}", categories[static_cast<int>(e.cat)]).replace("${m}", e.msg);
@@ -175,7 +181,7 @@ PIString PILog::entryToString(const Entry & e) const {
void PILog::newFile() { void PILog::newFile() {
PIString aname = app_name; PIString aname = log_name;
if (aname.isNotEmpty()) aname += "__"; if (aname.isNotEmpty()) aname += "__";
log_file.open(log_dir + "/" + aname + PIDateTime::current().toString("yyyy_MM_dd__hh_mm_ss") + ".log." + log_file.open(log_dir + "/" + aname + PIDateTime::current().toString("yyyy_MM_dd__hh_mm_ss") + ".log." +
PIString::fromNumber(++part_number), PIString::fromNumber(++part_number),
@@ -205,6 +211,9 @@ void PILog::run() {
log_mutex.unlock(); log_mutex.unlock();
auto str = entryToString(qi); auto str = entryToString(qi);
log_ts << str << "\n"; log_ts << str << "\n";
piCout << str; if (qi.cat == Level::Error)
piCerr << str;
else
piCout << str;
} }
} }

View File

@@ -41,11 +41,18 @@ public:
PILog(); PILog();
~PILog(); ~PILog();
enum class Level {
Error,
Warning,
Info,
Debug,
};
//! \~english Returns prefix for filename. //! \~english Returns prefix for filename.
PIString applicationName() const { return app_name; } PIString logName() const { return log_name; }
//! \~english Set prefix for filename. Should be set \b before \a setDir()! //! \~english Set prefix for filename. Should be set \b before \a setDir()!
void setApplicationName(const PIString & n) { app_name = n; } void setLogName(const PIString & n) { log_name = n; }
//! \~english Returns directory for log files. //! \~english Returns directory for log files.
@@ -75,27 +82,30 @@ public:
//! \~english Set line format. "t" is timestamp, "c" is category and "m" is message. Default is "t - c: m". //! \~english Set line format. "t" is timestamp, "c" is category and "m" is message. Default is "t - c: m".
void setLineFormat(const PIString & f); void setLineFormat(const PIString & f);
PICout debug(PIObject * context = nullptr);
PICout warning(PIObject * context = nullptr); //! \~english Returns maximum level.
Level level() const { return max_level; }
//! \~english Set maximum level. All levels greater than \"l\" will be ignored. Default if \a Level::Debug.
void setLevel(Level l);
PICout error(PIObject * context = nullptr); PICout error(PIObject * context = nullptr);
PICout warning(PIObject * context = nullptr);
PICout info(PIObject * context = nullptr);
PICout debug(PIObject * context = nullptr);
//! \~english Write all queued lines and stop. Also called in destructor. //! \~english Write all queued lines and stop. Also called in destructor.
void stop(); void stop();
private: private:
enum class Category {
Debug,
Warning,
Error
};
EVENT_HANDLER2(void, coutDone, int, id, PIString *, buff); EVENT_HANDLER2(void, coutDone, int, id, PIString *, buff);
PICout makePICout(PIObject * context, Category cat); PICout makePICout(PIObject * context, Level cat);
void enqueue(const PIString & msg, Category cat = Category::Debug); void enqueue(const PIString & msg, Level cat = Level::Debug);
struct Entry { struct Entry {
Category cat; Level cat;
PIDateTime time; PIDateTime time;
PIString msg; PIString msg;
}; };
@@ -104,14 +114,15 @@ private:
void newFile(); void newFile();
void run() override; void run() override;
PIMutex log_mutex, cout_mutex; PIMutex log_mutex;
PIFile log_file; PIFile log_file;
PIIOTextStream log_ts; PIIOTextStream log_ts;
PITimeMeasurer split_tm; PITimeMeasurer split_tm;
PISystemTime split_time; PISystemTime split_time;
PIString log_dir, timestamp_format, line_format, line_format_p, app_name; PIString log_dir, timestamp_format, line_format, line_format_p, log_name;
PIQueue<Entry> queue; PIQueue<Entry> queue;
PIMap<int, Category> cout_cat_by_id; PIMap<Level, int> id_by_cat;
Level max_level = Level::Debug;
int part_number = -1, cout_id = -1; int part_number = -1, cout_id = -1;
}; };

View File

@@ -1383,7 +1383,7 @@ public:
if (v.isEmpty()) return *this; if (v.isEmpty()) return *this;
#ifndef NDEBUG #ifndef NDEBUG
if (&v == this) { if (&v == this) {
printf("error with PIDeque<%s>::insert\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>::insert\n", __PIP_TYPENAME__(T));
} }
#endif #endif
assert(&v != this); assert(&v != this);
@@ -1738,7 +1738,7 @@ public:
if (v.isEmpty()) return *this; if (v.isEmpty()) return *this;
#ifndef NDEBUG #ifndef NDEBUG
if (&v == this) { if (&v == this) {
printf("error with PIDeque<%s>::append\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>::append\n", __PIP_TYPENAME__(T));
} }
#endif #endif
assert(&v != this); assert(&v != this);
@@ -2400,7 +2400,7 @@ public:
if (isEmpty()) return ret; if (isEmpty()) return ret;
#ifndef NDEBUG #ifndef NDEBUG
if (rows * cols != pid_size) { if (rows * cols != pid_size) {
printf("error with PIDeque<%s>::reshape\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>::reshape\n", __PIP_TYPENAME__(T));
} }
#endif #endif
assert(rows * cols == pid_size); assert(rows * cols == pid_size);
@@ -2689,7 +2689,7 @@ private:
T * p_d = reinterpret_cast<T *>(realloc(reinterpret_cast<void *>(pid_data), as * sizeof(T))); T * p_d = reinterpret_cast<T *>(realloc(reinterpret_cast<void *>(pid_data), as * sizeof(T)));
#ifndef NDEBUG #ifndef NDEBUG
if (!p_d) { if (!p_d) {
printf("error with PIDeque<%s>::alloc\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>::alloc\n", __PIP_TYPENAME__(T));
} }
#endif #endif
assert(p_d); assert(p_d);

View File

@@ -355,7 +355,7 @@ public:
inline PIMap<Key, T> & operator<<(const PIMap<Key, T> & other) { inline PIMap<Key, T> & operator<<(const PIMap<Key, T> & other) {
#ifndef NDEBUG #ifndef NDEBUG
if (&other == this) { if (&other == this) {
printf("error with PIMap<%s, %s>::<<\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIMap<%s, %s>::<<\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
} }
#endif #endif
assert(&other != this); assert(&other != this);

View File

@@ -1341,7 +1341,7 @@ public:
if (v.isEmpty()) return *this; if (v.isEmpty()) return *this;
#ifndef NDEBUG #ifndef NDEBUG
if (&v == this) { if (&v == this) {
printf("error with PIVector<%s>::insert\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>::insert\n", __PIP_TYPENAME__(T));
} }
#endif #endif
assert(&v != this); assert(&v != this);
@@ -1663,7 +1663,7 @@ public:
if (v.isEmpty()) return *this; if (v.isEmpty()) return *this;
#ifndef NDEBUG #ifndef NDEBUG
if (&v == this) { if (&v == this) {
printf("error with PIVector<%s>::push_back\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>::push_back\n", __PIP_TYPENAME__(T));
} }
#endif #endif
assert(&v != this); assert(&v != this);
@@ -2296,7 +2296,7 @@ public:
inline PIVector<PIVector<T>> reshape(size_t rows, size_t cols, ReshapeOrder order = ReshapeByRow) const { inline PIVector<PIVector<T>> reshape(size_t rows, size_t cols, ReshapeOrder order = ReshapeByRow) const {
#ifndef NDEBUG #ifndef NDEBUG
if (rows * cols != piv_size) { if (rows * cols != piv_size) {
printf("error with PIVector<%s>::reshape\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>::reshape\n", __PIP_TYPENAME__(T));
} }
#endif #endif
assert(rows * cols == piv_size); assert(rows * cols == piv_size);
@@ -2565,7 +2565,7 @@ private:
T * p_d = reinterpret_cast<T *>(realloc(reinterpret_cast<void *>(piv_data), as * sizeof(T))); T * p_d = reinterpret_cast<T *>(realloc(reinterpret_cast<void *>(piv_data), as * sizeof(T)));
#ifndef NDEBUG #ifndef NDEBUG
if (!p_d) { if (!p_d) {
printf("error with PIVector<%s>::alloc\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>::alloc\n", __PIP_TYPENAME__(T));
} }
#endif #endif
assert(p_d); assert(p_d);

View File

@@ -141,7 +141,7 @@ PIString & PICout::__string__() {
return *ret; return *ret;
} }
PICout::OutputDevices PICout::devs = PICout::StdOut; PICout::OutputDevices PICout::devs = PICout::Console;
PRIVATE_DEFINITION_START(PICout) PRIVATE_DEFINITION_START(PICout)
PIStack<PICoutControls> cos_; PIStack<PICoutControls> cos_;
@@ -158,35 +158,53 @@ WORD PICout::__Private__::dattr = 0;
DWORD PICout::__Private__::smode = 0; DWORD PICout::__Private__::smode = 0;
#endif #endif
PICout::PICout(int controls): fo_(true), cc_(false), fc_(false), act_(true), cnb_(10), co_(controls) {
buffer_ = nullptr; std::ostream & getStdStream(PICoutManipulators::PICoutStdStream s) {
switch (s) {
case PICoutManipulators::StdOut: return std::cout;
case PICoutManipulators::StdErr: return std::cerr;
default: break;
}
return std::cout;
}
std::wostream & getStdWStream(PICoutManipulators::PICoutStdStream s) {
switch (s) {
case PICoutManipulators::StdOut: return std::wcout;
case PICoutManipulators::StdErr: return std::wcerr;
default: break;
}
return std::wcout;
}
PICout::PICout(int controls, PICoutStdStream stream): ctrl_(controls), stream_(stream) {
init(); init();
} }
PICout::PICout(bool active): fo_(true), cc_(false), fc_(false), act_(active), cnb_(10), co_(PICoutManipulators::DefaultControls) { PICout::PICout(bool active, PICoutStdStream stream): actve_(active), stream_(stream) {
buffer_ = nullptr; if (actve_) init();
if (act_) init();
} }
PICout::PICout(const PICout & other) PICout::PICout(const PICout & other)
: fo_(other.fo_) : first_out_(other.first_out_)
, cc_(true) , is_copy_(true)
, fc_(false) , actve_(other.actve_)
, act_(other.act_) , int_base_(other.int_base_)
, cnb_(other.cnb_) , win_attr_(other.win_attr_)
, attr_(other.attr_)
, id_(other.id_) , id_(other.id_)
, buffer_(other.buffer_) , buffer_(other.buffer_)
, co_(other.co_) {} , ctrl_(other.ctrl_)
, stream_(other.stream_) {}
PICout::~PICout() { PICout::~PICout() {
if (!act_) return; if (!actve_) return;
if (fc_) applyFormat(PICoutManipulators::Default); if (format_changed_) applyFormat(PICoutManipulators::Default);
if (cc_) return; if (is_copy_) return;
newLine(); newLine();
if ((co_ & NoLock) != NoLock) { if ((ctrl_ & NoLock) != NoLock) {
PICout::__mutex__().unlock(); PICout::__mutex__().unlock();
} }
if (buffer_) { if (buffer_) {
@@ -196,7 +214,7 @@ PICout::~PICout() {
PICout & PICout::operator<<(PICoutAction v) { PICout & PICout::operator<<(PICoutAction v) {
if (!act_) return *this; if (!actve_) return *this;
#ifdef WINDOWS #ifdef WINDOWS
CONSOLE_SCREEN_BUFFER_INFO sbi; CONSOLE_SCREEN_BUFFER_INFO sbi;
COORD coord; COORD coord;
@@ -204,12 +222,12 @@ PICout & PICout::operator<<(PICoutAction v) {
#endif #endif
switch (v) { switch (v) {
case PICoutManipulators::Flush: case PICoutManipulators::Flush:
if (!buffer_ && isOutputDeviceActive(StdOut)) { if (!buffer_ && isOutputDeviceActive(Console)) {
std::cout << std::flush; getStdStream(stream_) << std::flush;
} }
break; break;
case PICoutManipulators::Backspace: case PICoutManipulators::Backspace:
if (isOutputDeviceActive(StdOut)) { if (isOutputDeviceActive(Console)) {
#ifdef WINDOWS #ifdef WINDOWS
GetConsoleScreenBufferInfo(__Private__::hOut, &sbi); GetConsoleScreenBufferInfo(__Private__::hOut, &sbi);
coord = sbi.dwCursorPosition; coord = sbi.dwCursorPosition;
@@ -223,7 +241,7 @@ PICout & PICout::operator<<(PICoutAction v) {
} }
break; break;
case PICoutManipulators::ShowCursor: case PICoutManipulators::ShowCursor:
if (isOutputDeviceActive(StdOut)) { if (isOutputDeviceActive(Console)) {
#ifdef WINDOWS #ifdef WINDOWS
GetConsoleCursorInfo(__Private__::hOut, &curinfo); GetConsoleCursorInfo(__Private__::hOut, &curinfo);
curinfo.bVisible = true; curinfo.bVisible = true;
@@ -234,7 +252,7 @@ PICout & PICout::operator<<(PICoutAction v) {
} }
break; break;
case PICoutManipulators::HideCursor: case PICoutManipulators::HideCursor:
if (isOutputDeviceActive(StdOut)) { if (isOutputDeviceActive(Console)) {
#ifdef WINDOWS #ifdef WINDOWS
GetConsoleCursorInfo(__Private__::hOut, &curinfo); GetConsoleCursorInfo(__Private__::hOut, &curinfo);
curinfo.bVisible = false; curinfo.bVisible = false;
@@ -245,7 +263,7 @@ PICout & PICout::operator<<(PICoutAction v) {
} }
break; break;
case PICoutManipulators::ClearLine: case PICoutManipulators::ClearLine:
if (isOutputDeviceActive(StdOut)) { if (isOutputDeviceActive(Console)) {
#ifdef WINDOWS #ifdef WINDOWS
GetConsoleScreenBufferInfo(__Private__::hOut, &sbi); GetConsoleScreenBufferInfo(__Private__::hOut, &sbi);
coord = sbi.dwCursorPosition; coord = sbi.dwCursorPosition;
@@ -266,7 +284,7 @@ PICout & PICout::operator<<(PICoutAction v) {
} }
break; break;
case PICoutManipulators::ClearScreen: case PICoutManipulators::ClearScreen:
if (isOutputDeviceActive(StdOut)) { if (isOutputDeviceActive(Console)) {
#ifdef WINDOWS #ifdef WINDOWS
/// TODO : wondows ClearScreen !!! /// TODO : wondows ClearScreen !!!
#else #else
@@ -282,12 +300,31 @@ PICout & PICout::operator<<(PICoutAction v) {
} }
PICout & PICout::setControl(PICoutManipulators::PICoutControl c, bool on) {
ctrl_.setFlag(c, on);
return *this;
}
PICout & PICout::setControls(PICoutManipulators::PICoutControls c) {
ctrl_ = c;
return *this;
}
PICout & PICout::saveAndSetControls(PICoutManipulators::PICoutControls c) {
saveControls();
ctrl_ = c;
return *this;
}
PICout & PICout::operator<<(PICoutManipulators::PICoutFormat v) { PICout & PICout::operator<<(PICoutManipulators::PICoutFormat v) {
switch (v) { switch (v) {
case PICoutManipulators::Bin: cnb_ = 2; break; case PICoutManipulators::Bin: int_base_ = 2; break;
case PICoutManipulators::Oct: cnb_ = 8; break; case PICoutManipulators::Oct: int_base_ = 8; break;
case PICoutManipulators::Dec: cnb_ = 10; break; case PICoutManipulators::Dec: int_base_ = 10; break;
case PICoutManipulators::Hex: cnb_ = 16; break; case PICoutManipulators::Hex: int_base_ = 16; break;
default: applyFormat(v); default: applyFormat(v);
}; };
return *this; return *this;
@@ -295,10 +332,10 @@ PICout & PICout::operator<<(PICoutManipulators::PICoutFormat v) {
PICout & PICout::operator<<(PIFlags<PICoutManipulators::PICoutFormat> v) { PICout & PICout::operator<<(PIFlags<PICoutManipulators::PICoutFormat> v) {
if (v[PICoutManipulators::Bin]) cnb_ = 2; if (v[PICoutManipulators::Bin]) int_base_ = 2;
if (v[PICoutManipulators::Oct]) cnb_ = 8; if (v[PICoutManipulators::Oct]) int_base_ = 8;
if (v[PICoutManipulators::Dec]) cnb_ = 10; if (v[PICoutManipulators::Dec]) int_base_ = 10;
if (v[PICoutManipulators::Hex]) cnb_ = 16; if (v[PICoutManipulators::Hex]) int_base_ = 16;
if (v[PICoutManipulators::Bold]) applyFormat(PICoutManipulators::Bold); if (v[PICoutManipulators::Bold]) applyFormat(PICoutManipulators::Bold);
if (v[PICoutManipulators::Faint]) applyFormat(PICoutManipulators::Faint); if (v[PICoutManipulators::Faint]) applyFormat(PICoutManipulators::Faint);
if (v[PICoutManipulators::Italic]) applyFormat(PICoutManipulators::Italic); if (v[PICoutManipulators::Italic]) applyFormat(PICoutManipulators::Italic);
@@ -324,31 +361,78 @@ PICout & PICout::operator<<(PIFlags<PICoutManipulators::PICoutFormat> v) {
return *this; return *this;
} }
#define PIINTCOUT(v) \
{ \ void PICout::stdoutPIString(const PIString & str, PICoutStdStream s) {
if (!act_) return *this; \ #ifdef HAS_LOCALE
space(); \ std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> utf8conv;
if (cnb_ == 10) { \ getStdStream(s) << utf8conv.to_bytes((char16_t *)&(const_cast<PIString &>(str).front()),
if (buffer_) { \ (char16_t *)&(const_cast<PIString &>(str).front()) + str.size());
(*buffer_) += PIString::fromNumber(v); \ #else
} else { \ for (PIChar c: str)
if (PICout::isOutputDeviceActive(PICout::StdOut)) std::cout << (v); \ getStdWStream(s).put(c.toWChar());
if (PICout::isOutputDeviceActive(PICout::Buffer)) PICout::__string__() += PIString::fromNumber(v); \ #endif
} \ }
} else \
write(PIString::fromNumber(v, cnb_)); \
return *this; \ PICout & PICout::write(const char * str, int len) {
if (!actve_ || !str) return *this;
if (buffer_) {
buffer_->append(PIString(str, len));
} else {
if (isOutputDeviceActive(Console)) getStdStream(stream_).write(str, len);
if (isOutputDeviceActive(Buffer)) PICout::__string__().append(PIString(str, len));
}
return *this;
}
PICout & PICout::write(const PIString & s) {
if (!actve_) return *this;
if (buffer_) {
buffer_->append(s);
} else {
if (isOutputDeviceActive(Console)) stdoutPIString(s, stream_);
if (isOutputDeviceActive(Buffer)) PICout::__string__().append(s);
}
return *this;
}
void PICout::writeChar(char c) {
if (buffer_) {
buffer_->append(c);
} else {
if (isOutputDeviceActive(Console)) getStdStream(stream_) << c;
if (isOutputDeviceActive(Buffer)) PICout::__string__().append(c);
}
}
#define PIINTCOUT(v) \
{ \
if (!actve_) return *this; \
space(); \
if (int_base_ == 10) { \
if (buffer_) { \
(*buffer_) += PIString::fromNumber(v); \
} else { \
if (isOutputDeviceActive(Console)) getStdStream(stream_) << (v); \
if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIString::fromNumber(v); \
} \
} else \
write(PIString::fromNumber(v, int_base_)); \
return *this; \
} }
#define PIFLOATCOUT(v) \ #define PIFLOATCOUT(v) \
{ \ { \
if (buffer_) { \ if (buffer_) { \
(*buffer_) += PIString::fromNumber(v, 'g'); \ (*buffer_) += PIString::fromNumber(v, 'g'); \
} else { \ } else { \
if (PICout::isOutputDeviceActive(PICout::StdOut)) std::cout << (v); \ if (isOutputDeviceActive(Console)) getStdStream(stream_) << (v); \
if (PICout::isOutputDeviceActive(PICout::Buffer)) PICout::__string__() += PIString::fromNumber(v, 'g'); \ if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIString::fromNumber(v, 'g'); \
} \ } \
} \ } \
return *this; return *this;
@@ -361,7 +445,7 @@ PICout & PICout::operator<<(const PIString & v) {
} }
PICout & PICout::operator<<(const char * v) { PICout & PICout::operator<<(const char * v) {
if (!act_ || !v) return *this; if (!actve_ || !v) return *this;
if (v[0] == '\0') return *this; if (v[0] == '\0') return *this;
space(); space();
quote(); quote();
@@ -371,7 +455,7 @@ PICout & PICout::operator<<(const char * v) {
} }
PICout & PICout::operator<<(bool v) { PICout & PICout::operator<<(bool v) {
if (!act_) return *this; if (!actve_) return *this;
space(); space();
if (v) if (v)
write("true"); write("true");
@@ -381,7 +465,7 @@ PICout & PICout::operator<<(bool v) {
} }
PICout & PICout::operator<<(char v) { PICout & PICout::operator<<(char v) {
if (!act_) return *this; if (!actve_) return *this;
space(); space();
write(v); write(v);
return *this; return *this;
@@ -406,32 +490,32 @@ PICout & PICout::operator<<(llong v){PIINTCOUT(v)}
PICout & PICout::operator<<(ullong v){PIINTCOUT(v)} PICout & PICout::operator<<(ullong v){PIINTCOUT(v)}
PICout & PICout::operator<<(float v) { PICout & PICout::operator<<(float v) {
if (!act_) return *this; if (!actve_) return *this;
space(); space();
PIFLOATCOUT(v) PIFLOATCOUT(v)
} }
PICout & PICout::operator<<(double v) { PICout & PICout::operator<<(double v) {
if (!act_) return *this; if (!actve_) return *this;
space(); space();
PIFLOATCOUT(v) PIFLOATCOUT(v)
} }
PICout & PICout::operator<<(ldouble v) { PICout & PICout::operator<<(ldouble v) {
if (!act_) return *this; if (!actve_) return *this;
space(); space();
PIFLOATCOUT(v) PIFLOATCOUT(v)
} }
PICout & PICout::operator<<(const void * v) { PICout & PICout::operator<<(const void * v) {
if (!act_) return *this; if (!actve_) return *this;
space(); space();
write("0x" + PIString::fromNumber(ullong(v), 16)); write("0x" + PIString::fromNumber(ullong(v), 16));
return *this; return *this;
} }
PICout & PICout::operator<<(const PIObject * v) { PICout & PICout::operator<<(const PIObject * v) {
if (!act_) return *this; if (!actve_) return *this;
space(); space();
if (v == 0) if (v == 0)
write("PIObject*(0x0)"); write("PIObject*(0x0)");
@@ -443,74 +527,38 @@ PICout & PICout::operator<<(const PIObject * v) {
} }
PICout & PICout::operator<<(PICoutSpecialChar v) { PICout & PICout::operator<<(PICoutSpecialChar v) {
if (!act_) return *this; if (!actve_) return *this;
switch (v) { switch (v) {
case Null: case Null: writeChar(char(0)); break;
if (buffer_) {
(*buffer_) += PIChar();
} else {
if (isOutputDeviceActive(StdOut)) std::cout << char(0);
if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIChar();
}
break;
case NewLine: case NewLine:
if (buffer_) { first_out_ = true;
(*buffer_) += "\n"; writeChar('\n');
} else {
if (isOutputDeviceActive(StdOut)) std::cout << '\n';
if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\n";
}
fo_ = true;
break;
case Tab:
if (buffer_) {
(*buffer_) += "\t";
} else {
if (isOutputDeviceActive(StdOut)) std::cout << '\t';
if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\t";
}
break; break;
case Tab: writeChar('\t'); break;
case Esc: case Esc:
#ifdef CC_VC #ifdef CC_VC
if (buffer_) { writeChar(char(27));
(*buffer_) += PIChar(27);
} else {
if (isOutputDeviceActive(StdOut)) std::cout << char(27);
if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIChar(27);
}
#else #else
if (buffer_) { writeChar('\e');
(*buffer_) += "\e";
} else {
if (isOutputDeviceActive(StdOut)) std::cout << '\e';
if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\e";
}
#endif #endif
break; break;
case Quote: case Quote: writeChar('"'); break;
if (buffer_) {
(*buffer_) += "\"";
} else {
if (isOutputDeviceActive(StdOut)) std::cout << '"';
if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\"";
}
break;
}; };
return *this; return *this;
} }
PICout & PICout::saveControls() { PICout & PICout::saveControls() {
if (!act_) return *this; if (!actve_) return *this;
PRIVATE->cos_.push(co_); PRIVATE->cos_.push(ctrl_);
return *this; return *this;
} }
PICout & PICout::restoreControls() { PICout & PICout::restoreControls() {
if (!act_) return *this; if (!actve_) return *this;
if (!PRIVATE->cos_.isEmpty()) { if (!PRIVATE->cos_.isEmpty()) {
co_ = PRIVATE->cos_.top(); ctrl_ = PRIVATE->cos_.top();
PRIVATE->cos_.pop(); PRIVATE->cos_.pop();
} }
return *this; return *this;
@@ -524,16 +572,11 @@ PICout & PICout::restoreControls() {
//! Добавляет пробел если это не первый вывод и установлен флаг \a AddSpaces //! Добавляет пробел если это не первый вывод и установлен флаг \a AddSpaces
//! \~\sa \a quote(), \a newLine() //! \~\sa \a quote(), \a newLine()
PICout & PICout::space() { PICout & PICout::space() {
if (!act_) return *this; if (!actve_) return *this;
if (!fo_ && co_[AddSpaces]) { if (!first_out_ && ctrl_[AddSpaces]) {
if (buffer_) { writeChar(' ');
(*buffer_) += " ";
} else {
if (isOutputDeviceActive(StdOut)) std::cout << ' ';
if (isOutputDeviceActive(Buffer)) PICout::__string__() += " ";
}
} }
fo_ = false; first_out_ = false;
return *this; return *this;
} }
@@ -544,16 +587,11 @@ PICout & PICout::space() {
//! Добавляет кавычки если установлен флаг \a AddQuotes //! Добавляет кавычки если установлен флаг \a AddQuotes
//! \~\sa \a space(), \a newLine() //! \~\sa \a space(), \a newLine()
PICout & PICout::quote() { PICout & PICout::quote() {
if (!act_) return *this; if (!actve_) return *this;
if (co_[AddQuotes]) { if (ctrl_[AddQuotes]) {
if (buffer_) { writeChar('"');
(*buffer_) += "\"";
} else {
if (isOutputDeviceActive(StdOut)) std::cout << '"';
if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\"";
}
} }
fo_ = false; first_out_ = false;
return *this; return *this;
} }
@@ -564,74 +602,28 @@ PICout & PICout::quote() {
//! Добавляет новую строку если установлен флаг \a AddNewLine //! Добавляет новую строку если установлен флаг \a AddNewLine
//! \~\sa \a space(), \a quote() //! \~\sa \a space(), \a quote()
PICout & PICout::newLine() { PICout & PICout::newLine() {
if (!act_) return *this; if (!actve_) return *this;
if (co_[AddNewLine]) { if (ctrl_[AddNewLine]) {
if (buffer_) { writeChar('\n');
(*buffer_) += "\n";
} else {
if (isOutputDeviceActive(StdOut)) std::cout << std::endl;
if (isOutputDeviceActive(Buffer)) PICout::__string__() += "\n";
}
} }
fo_ = false; first_out_ = false;
return *this; return *this;
} }
PICout & PICout::write(char c) { PICout & PICout::write(char c) {
if (!act_) return *this; if (!actve_) return *this;
if (buffer_) { writeChar(c);
buffer_->append(c);
} else {
if (PICout::isOutputDeviceActive(PICout::StdOut)) std::cout << c;
if (PICout::isOutputDeviceActive(PICout::Buffer)) PICout::__string__().append(c);
}
return *this; return *this;
} }
PICout & PICout::write(const char * str) { PICout & PICout::write(const char * str) {
if (!act_ || !str) return *this; if (!actve_ || !str) return *this;
return write(str, strlen(str)); return write(str, strlen(str));
} }
PICout & PICout::write(const char * str, int len) {
if (!act_ || !str) return *this;
if (buffer_) {
buffer_->append(PIString(str, len));
} else {
if (PICout::isOutputDeviceActive(PICout::StdOut)) std::cout.write(str, len);
if (PICout::isOutputDeviceActive(PICout::Buffer)) PICout::__string__().append(PIString(str, len));
}
return *this;
}
PICout & PICout::write(const PIString & s) {
if (!act_) return *this;
if (buffer_) {
buffer_->append(s);
} else {
if (PICout::isOutputDeviceActive(PICout::StdOut)) stdoutPIString(s);
if (PICout::isOutputDeviceActive(PICout::Buffer)) PICout::__string__().append(s);
}
return *this;
}
void PICout::stdoutPIString(const PIString & s) {
#ifdef HAS_LOCALE
std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> utf8conv;
std::cout << utf8conv.to_bytes((char16_t *)&(const_cast<PIString &>(s).front()),
(char16_t *)&(const_cast<PIString &>(s).front()) + s.size());
#else
for (PIChar c: s)
std::wcout.put(c.toWChar());
#endif
}
void PICout::init() { void PICout::init() {
#ifdef WINDOWS #ifdef WINDOWS
if (__Private__::hOut == 0) { if (__Private__::hOut == 0) {
@@ -640,19 +632,18 @@ void PICout::init() {
GetConsoleScreenBufferInfo(__Private__::hOut, &sbi); GetConsoleScreenBufferInfo(__Private__::hOut, &sbi);
__Private__::dattr = sbi.wAttributes; __Private__::dattr = sbi.wAttributes;
} }
attr_ = __Private__::dattr; win_attr_ = __Private__::dattr;
#endif #endif
id_ = 0; if ((ctrl_ & NoLock) != NoLock) {
if ((co_ & NoLock) != NoLock) {
PICout::__mutex__().lock(); PICout::__mutex__().lock();
} }
} }
void PICout::applyFormat(PICoutFormat f) { void PICout::applyFormat(PICoutFormat f) {
if (!act_) return; if (!actve_) return;
if (buffer_ || !isOutputDeviceActive(StdOut)) return; if (buffer_ || !isOutputDeviceActive(Console)) return;
fc_ = true; format_changed_ = true;
#ifdef WINDOWS #ifdef WINDOWS
static int mask_fore = ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); static int mask_fore = ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
static int mask_back = ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); static int mask_back = ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
@@ -661,28 +652,28 @@ void PICout::applyFormat(PICoutFormat f) {
case Oct: case Oct:
case Dec: case Dec:
case Hex: break; case Hex: break;
case PICoutManipulators::Bold: attr_ |= FOREGROUND_INTENSITY; break; case PICoutManipulators::Bold: win_attr_ |= FOREGROUND_INTENSITY; break;
case PICoutManipulators::Underline: attr_ |= COMMON_LVB_UNDERSCORE; break; case PICoutManipulators::Underline: win_attr_ |= COMMON_LVB_UNDERSCORE; break;
case PICoutManipulators::Black: attr_ = (attr_ & mask_fore); break; case PICoutManipulators::Black: win_attr_ = (win_attr_ & mask_fore); break;
case PICoutManipulators::Red: attr_ = (attr_ & mask_fore) | FOREGROUND_RED; break; case PICoutManipulators::Red: win_attr_ = (win_attr_ & mask_fore) | FOREGROUND_RED; break;
case PICoutManipulators::Green: attr_ = (attr_ & mask_fore) | FOREGROUND_GREEN; break; case PICoutManipulators::Green: win_attr_ = (win_attr_ & mask_fore) | FOREGROUND_GREEN; break;
case PICoutManipulators::Blue: attr_ = (attr_ & mask_fore) | FOREGROUND_BLUE; break; case PICoutManipulators::Blue: win_attr_ = (win_attr_ & mask_fore) | FOREGROUND_BLUE; break;
case PICoutManipulators::Yellow: attr_ = (attr_ & mask_fore) | FOREGROUND_RED | FOREGROUND_GREEN; break; case PICoutManipulators::Yellow: win_attr_ = (win_attr_ & mask_fore) | FOREGROUND_RED | FOREGROUND_GREEN; break;
case PICoutManipulators::Magenta: attr_ = (attr_ & mask_fore) | FOREGROUND_RED | FOREGROUND_BLUE; break; case PICoutManipulators::Magenta: win_attr_ = (win_attr_ & mask_fore) | FOREGROUND_RED | FOREGROUND_BLUE; break;
case PICoutManipulators::Cyan: attr_ = (attr_ & mask_fore) | FOREGROUND_GREEN | FOREGROUND_BLUE; break; case PICoutManipulators::Cyan: win_attr_ = (win_attr_ & mask_fore) | FOREGROUND_GREEN | FOREGROUND_BLUE; break;
case PICoutManipulators::White: attr_ = (attr_ & mask_fore) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; break; case PICoutManipulators::White: win_attr_ = (win_attr_ & mask_fore) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; break;
case PICoutManipulators::BackBlack: attr_ = (attr_ & mask_back); break; case PICoutManipulators::BackBlack: win_attr_ = (win_attr_ & mask_back); break;
case PICoutManipulators::BackRed: attr_ = (attr_ & mask_back) | BACKGROUND_RED; break; case PICoutManipulators::BackRed: win_attr_ = (win_attr_ & mask_back) | BACKGROUND_RED; break;
case PICoutManipulators::BackGreen: attr_ = (attr_ & mask_back) | BACKGROUND_GREEN; break; case PICoutManipulators::BackGreen: win_attr_ = (win_attr_ & mask_back) | BACKGROUND_GREEN; break;
case PICoutManipulators::BackBlue: attr_ = (attr_ & mask_back) | BACKGROUND_BLUE; break; case PICoutManipulators::BackBlue: win_attr_ = (win_attr_ & mask_back) | BACKGROUND_BLUE; break;
case PICoutManipulators::BackYellow: attr_ = (attr_ & mask_back) | BACKGROUND_RED | BACKGROUND_GREEN; break; case PICoutManipulators::BackYellow: win_attr_ = (win_attr_ & mask_back) | BACKGROUND_RED | BACKGROUND_GREEN; break;
case PICoutManipulators::BackMagenta: attr_ = (attr_ & mask_back) | BACKGROUND_RED | BACKGROUND_BLUE; break; case PICoutManipulators::BackMagenta: win_attr_ = (win_attr_ & mask_back) | BACKGROUND_RED | BACKGROUND_BLUE; break;
case PICoutManipulators::BackCyan: attr_ = (attr_ & mask_back) | BACKGROUND_GREEN | BACKGROUND_BLUE; break; case PICoutManipulators::BackCyan: win_attr_ = (win_attr_ & mask_back) | BACKGROUND_GREEN | BACKGROUND_BLUE; break;
case PICoutManipulators::BackWhite: attr_ = (attr_ & mask_back) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; break; case PICoutManipulators::BackWhite: win_attr_ = (win_attr_ & mask_back) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; break;
case PICoutManipulators::Default: attr_ = __Private__::dattr; break; case PICoutManipulators::Default: win_attr_ = __Private__::dattr; break;
default: break; default: break;
} }
SetConsoleTextAttribute(__Private__::hOut, attr_); SetConsoleTextAttribute(__Private__::hOut, win_attr_);
#else #else
switch (f) { switch (f) {
case Bin: case Bin:
@@ -761,3 +752,8 @@ PICout PICout::withExternalBuffer(PIString * buffer, int id, PIFlags<PICoutManip
c.id_ = id; c.id_ = id;
return c; return c;
} }
int PICout::registerExternalBufferID() {
return Notifier::instance()->new_id.fetch_add(1);
}

View File

@@ -40,10 +40,14 @@
# define piCoutObj # define piCoutObj
#else #else
# define piCout PICout(piDebug) # define piCout PICout(piDebug, PICoutManipulators::StdOut)
# define piCoutObj \ # define piCoutObj \
PICout(piDebug && debug()) << (PIStringAscii("[") + className() + \ PICout(piDebug && debug(), PICoutManipulators::StdOut) \
(name().isEmpty() ? "]" : PIStringAscii(" \"") + name() + PIStringAscii("\"]"))) << (PIStringAscii("[") + className() + (name().isEmpty() ? "]" : PIStringAscii(" \"") + name() + PIStringAscii("\"]")))
# define piCerr PICout(piDebug, PICoutManipulators::StdErr)
# define piCerrObj \
PICout(piDebug && debug(), PICoutManipulators::StdErr) \
<< (PIStringAscii("[") + className() + (name().isEmpty() ? "]" : PIStringAscii(" \"") + name() + PIStringAscii("\"]")))
#endif #endif
@@ -55,6 +59,7 @@ class PIObject;
//! \~russian Пространство имен содержит перечисления для контроля PICout //! \~russian Пространство имен содержит перечисления для контроля PICout
namespace PICoutManipulators { namespace PICoutManipulators {
//! \~english Enum contains special characters //! \~english Enum contains special characters
//! \~russian Перечисление со спецсимволами //! \~russian Перечисление со спецсимволами
enum PICoutSpecialChar { enum PICoutSpecialChar {
@@ -65,6 +70,7 @@ enum PICoutSpecialChar {
Quote /*! \~english Quote character, '\"' \~russian Кавычки, '\"' */ Quote /*! \~english Quote character, '\"' \~russian Кавычки, '\"' */
}; };
//! \~english Enum contains immediate action //! \~english Enum contains immediate action
//! \~russian Перечисление с немедленными действиями //! \~russian Перечисление с немедленными действиями
enum PICoutAction { enum PICoutAction {
@@ -79,6 +85,7 @@ enum PICoutAction {
restoreControl() */ restoreControl() */
}; };
//! \~english Enum contains control of PICout //! \~english Enum contains control of PICout
//! \~russian Перечисление с управлением PICout //! \~russian Перечисление с управлением PICout
enum PICoutControl { enum PICoutControl {
@@ -91,6 +98,7 @@ enum PICoutControl {
NoLock /*! \~english Don`t use mutex for output \~russian Не использовать мьютекс при выводе */ = 0x100, NoLock /*! \~english Don`t use mutex for output \~russian Не использовать мьютекс при выводе */ = 0x100,
}; };
//! \~english Enum contains output format //! \~english Enum contains output format
//! \~russian Перечисление с форматом вывода //! \~russian Перечисление с форматом вывода
enum PICoutFormat { enum PICoutFormat {
@@ -122,7 +130,17 @@ enum PICoutFormat {
Default /*! \~english Default format \~russian Формат по умолчанию */ = 0x4000000 Default /*! \~english Default format \~russian Формат по умолчанию */ = 0x4000000
}; };
//! \~english Enum contains console streams
//! \~russian Перечисление с потоками консоли
enum PICoutStdStream {
StdOut /*! \~english Standard output stream \~russian Стандартный поток вывода */ = 0,
StdErr /*! \~english Standard error stream \~russian Стандартный поток ошибок */ = 1,
};
typedef PIFlags<PICoutControl> PICoutControls; typedef PIFlags<PICoutControl> PICoutControls;
} // namespace PICoutManipulators } // namespace PICoutManipulators
@@ -134,11 +152,11 @@ class PIP_EXPORT PICout {
public: public:
//! \~english Default constructor with default features (AddSpaces and AddNewLine) //! \~english Default constructor with default features (AddSpaces and AddNewLine)
//! \~russian Конструктор по умолчанию (AddSpaces и AddNewLine) //! \~russian Конструктор по умолчанию (AddSpaces и AddNewLine)
PICout(int controls = PICoutManipulators::DefaultControls); PICout(int controls = PICoutManipulators::DefaultControls, PICoutManipulators::PICoutStdStream stream = PICoutManipulators::StdOut);
//! \~english Construct with default features (AddSpaces and AddNewLine), but if \"active\" is false does nothing //! \~english Construct with default features (AddSpaces and AddNewLine), but if \"active\" is false does nothing
//! \~russian Конструктор по умолчанию (AddSpaces и AddNewLine), но если не \"active\" то будет неактивным //! \~russian Конструктор по умолчанию (AddSpaces и AddNewLine), но если не \"active\" то будет неактивным
PICout(bool active); PICout(bool active, PICoutManipulators::PICoutStdStream stream = PICoutManipulators::StdOut);
PICout(const PICout & other); PICout(const PICout & other);
@@ -146,6 +164,8 @@ public:
class PIP_EXPORT Notifier { class PIP_EXPORT Notifier {
friend class PICout;
public: public:
//! \~english Singleton access to %PICout::Notifier //! \~english Singleton access to %PICout::Notifier
//! \~russian Синглтон класса %PICout::Notifier //! \~russian Синглтон класса %PICout::Notifier
@@ -158,15 +178,17 @@ public:
private: private:
Notifier(); Notifier();
PIObject * o; PIObject * o;
std::atomic_int new_id = {1};
}; };
//! \~english Enum contains output devices of %PICout //! \~english Enum contains output devices of %PICout
//! \~russian Перечисление с устройствами вывода для %PICout //! \~russian Перечисление с устройствами вывода для %PICout
enum OutputDevice { enum OutputDevice {
NoDevices /** \~english %PICout is disabled \~russian %PICout неактивен */ = 0x0, NoDevices /** \~english %PICout is disabled \~russian %PICout неактивен */ = 0x0,
StdOut /** \~english Standard console output \~russian Стандартный вывод в консоль */ = 0x1, Console /** \~english Standard console output \~russian Стандартный вывод в консоль */ = 0x1,
Buffer /** \~english Internal buffer \~russian Внутренний буфер */ = 0x2, StdOut DEPRECATEDM("use PICout::Console") = Console,
AllDevices /** \~english All \~russian Все */ = 0xFFFF, Buffer /** \~english Internal buffer \~russian Внутренний буфер */ = 0x2,
AllDevices /** \~english All \~russian Все */ = 0xFFFF,
}; };
typedef PIFlags<OutputDevice> OutputDevices; typedef PIFlags<OutputDevice> OutputDevices;
@@ -261,25 +283,15 @@ public:
//! \~english Set control flag "c" is "on" state //! \~english Set control flag "c" is "on" state
//! \~russian Установить флаг "c" в "on" состояние //! \~russian Установить флаг "c" в "on" состояние
PICout & setControl(PICoutManipulators::PICoutControl c, bool on = true) { PICout & setControl(PICoutManipulators::PICoutControl c, bool on = true);
co_.setFlag(c, on);
return *this;
}
//! \~english Set control flags "c" //! \~english Set control flags "c"
//! \~russian Установить флаги "c" //! \~russian Установить флаги "c"
PICout & setControls(PICoutManipulators::PICoutControls c) { PICout & setControls(PICoutManipulators::PICoutControls c);
co_ = c;
return *this;
}
//! \~english Exec \a saveControls() and set control flags to "c" //! \~english Exec \a saveControls() and set control flags to "c"
//! \~russian Иыполнить \a saveControls() и Установить флаги "c" //! \~russian Иыполнить \a saveControls() и Установить флаги "c"
PICout & saveAndSetControls(PICoutManipulators::PICoutControls c) { PICout & saveAndSetControls(PICoutManipulators::PICoutControls c);
saveControls();
co_ = c;
return *this;
}
//! \~english Save control flags to internal stack //! \~english Save control flags to internal stack
//! \~russian Сохраняет состояние флагов во внутренний стек //! \~russian Сохраняет состояние флагов во внутренний стек
@@ -321,7 +333,7 @@ public:
//! \~english Output \a PIString to stdout //! \~english Output \a PIString to stdout
//! \~russian Вывод \a PIString в stdout //! \~russian Вывод \a PIString в stdout
static void stdoutPIString(const PIString & s); static void stdoutPIString(const PIString & str, PICoutManipulators::PICoutStdStream s = PICoutManipulators::StdOut);
//! \~english Returns internal PIString buffer //! \~english Returns internal PIString buffer
//! \~russian Возвращает внутренний PIString буфер //! \~russian Возвращает внутренний PIString буфер
@@ -368,19 +380,25 @@ public:
PIFlags<PICoutManipulators::PICoutControl> controls = PICoutManipulators::AddSpaces | PIFlags<PICoutManipulators::PICoutControl> controls = PICoutManipulators::AddSpaces |
PICoutManipulators::AddNewLine); PICoutManipulators::AddNewLine);
//! \~english Returns unique external buffer ID for later use in \a withExternalBuffer()
//! \~russian Возвращает уникальный ID для внешнего буфера для дальнейшего использования в \a withExternalBuffer()
static int registerExternalBufferID();
static PIMutex & __mutex__(); static PIMutex & __mutex__();
static PIString & __string__(); static PIString & __string__();
private: private:
void init(); void init();
void applyFormat(PICoutManipulators::PICoutFormat f); void applyFormat(PICoutManipulators::PICoutFormat f);
void writeChar(char c);
static OutputDevices devs; static OutputDevices devs;
PRIVATE_DECLARATION(PIP_EXPORT) PRIVATE_DECLARATION(PIP_EXPORT)
bool fo_, cc_, fc_, act_; bool first_out_ = true, is_copy_ = false, format_changed_ = false, actve_ = true;
int cnb_, attr_, id_; int int_base_ = 10, win_attr_ = 0, id_ = 0;
PIString * buffer_; PIString * buffer_ = nullptr;
PICoutManipulators::PICoutControls co_; PICoutManipulators::PICoutControls ctrl_ = PICoutManipulators::DefaultControls;
PICoutManipulators::PICoutStdStream stream_ = PICoutManipulators::StdOut;
}; };
#endif // PICOUT_H #endif // PICOUT_H

View File

@@ -459,7 +459,7 @@ PIDir PIDir::current() {
PIDir PIDir::home() { PIDir PIDir::home() {
#ifndef ESP_PLATFORM #ifndef ESP_PLATFORM
char * rc = 0; char * rc = nullptr;
#endif #endif
#ifdef WINDOWS #ifdef WINDOWS
rc = new char[1024]; rc = new char[1024];
@@ -482,7 +482,7 @@ PIDir PIDir::home() {
#else #else
# ifndef ESP_PLATFORM # ifndef ESP_PLATFORM
rc = getenv("HOME"); rc = getenv("HOME");
if (rc == 0) return PIDir(); if (!rc) return PIDir();
return PIDir(rc); return PIDir(rc);
# else # else
return PIDir(); return PIDir();
@@ -492,7 +492,7 @@ PIDir PIDir::home() {
PIDir PIDir::temporary() { PIDir PIDir::temporary() {
char * rc = 0; char * rc = nullptr;
#ifdef WINDOWS #ifdef WINDOWS
rc = new char[1024]; rc = new char[1024];
memset(rc, 0, 1024); memset(rc, 0, 1024);
@@ -507,8 +507,8 @@ PIDir PIDir::temporary() {
s.prepend(separator); s.prepend(separator);
return PIDir(s); return PIDir(s);
#else #else
rc = tmpnam(0); rc = mkdtemp("/tmp/pidir_tmp_XXXXXX");
if (rc == 0) return PIDir(); if (!rc) return PIDir();
PIString s(rc); PIString s(rc);
return PIDir(s.left(s.findLast(PIDir::separator))); return PIDir(s.left(s.findLast(PIDir::separator)));
#endif #endif

View File

@@ -70,7 +70,7 @@ public:
bool binaryStreamAppend(const void * d, size_t s) { bool binaryStreamAppend(const void * d, size_t s) {
if (!static_cast<P *>(this)->binaryStreamAppendImp(d, s)) { if (!static_cast<P *>(this)->binaryStreamAppendImp(d, s)) {
return false; return false;
printf("[PIBinaryStream] binaryStreamAppend() error\n"); fprintf(stderr, "[PIBinaryStream] binaryStreamAppend() error\n");
} }
return true; return true;
} }
@@ -81,7 +81,7 @@ public:
if (!static_cast<P *>(this)->binaryStreamTakeImp(d, s)) { if (!static_cast<P *>(this)->binaryStreamTakeImp(d, s)) {
_was_read_error_ = true; _was_read_error_ = true;
return false; return false;
printf("[PIBinaryStream] binaryStreamTake() error\n"); fprintf(stderr, "[PIBinaryStream] binaryStreamTake() error\n");
} }
return true; return true;
} }
@@ -323,7 +323,7 @@ template<typename P,
typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0> typename std::enable_if<std::is_trivially_copyable<T>::value, int>::type = 0>
inline PIBinaryStreamTrivialRef<P> operator>>(PIBinaryStream<P> & s, T & v) { inline PIBinaryStreamTrivialRef<P> operator>>(PIBinaryStream<P> & s, T & v) {
if (!s.binaryStreamTake(&v, sizeof(v))) { if (!s.binaryStreamTake(&v, sizeof(v))) {
printf("error with %s\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with %s\n", __PIP_TYPENAME__(T));
} }
return s; return s;
} }
@@ -341,13 +341,13 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
// piCout << ">> vector trivial default"; // piCout << ">> vector trivial default";
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
v._resizeRaw(sz); v._resizeRaw(sz);
if (!s.binaryStreamTake(v.data(), sz * sizeof(T))) { if (!s.binaryStreamTake(v.data(), sz * sizeof(T))) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
} }
return s; return s;
@@ -362,7 +362,7 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
// piCout << ">> vector trivial custom"; // piCout << ">> vector trivial custom";
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
@@ -370,7 +370,7 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
for (int i = 0; i < sz; ++i) { for (int i = 0; i < sz; ++i) {
s >> v[i]; s >> v[i];
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
@@ -391,13 +391,13 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
// piCout << ">> deque trivial default"; // piCout << ">> deque trivial default";
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
v._resizeRaw(sz); v._resizeRaw(sz);
if (!s.binaryStreamTake(v.data(), sz * sizeof(T))) { if (!s.binaryStreamTake(v.data(), sz * sizeof(T))) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
} }
return s; return s;
@@ -412,7 +412,7 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
// piCout << ">> deque trivial custom"; // piCout << ">> deque trivial custom";
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
@@ -420,7 +420,7 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
for (int i = 0; i < sz; ++i) { for (int i = 0; i < sz; ++i) {
s >> v[i]; s >> v[i];
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
@@ -443,13 +443,13 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v)
r = s.binaryStreamTakeInt(); r = s.binaryStreamTakeInt();
c = s.binaryStreamTakeInt(); c = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIVector2D<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
v._resizeRaw(r, c); v._resizeRaw(r, c);
if (!s.binaryStreamTake(v.data(), v.size() * sizeof(T))) { if (!s.binaryStreamTake(v.data(), v.size() * sizeof(T))) {
printf("error with PIVector2D<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
} }
return s; return s;
@@ -468,7 +468,7 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v)
c = s.binaryStreamTakeInt(); c = s.binaryStreamTakeInt();
s >> tmp; s >> tmp;
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIVector2D<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
@@ -543,7 +543,7 @@ template<typename P, typename T, typename std::enable_if<!std::is_trivially_copy
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) { inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
@@ -551,7 +551,7 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
for (size_t i = 0; i < v.size(); ++i) { for (size_t i = 0; i < v.size(); ++i) {
s >> v[i]; s >> v[i];
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIVector<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
@@ -566,7 +566,7 @@ template<typename P, typename T, typename std::enable_if<!std::is_trivially_copy
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) { inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
@@ -574,7 +574,7 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
for (size_t i = 0; i < v.size(); ++i) { for (size_t i = 0; i < v.size(); ++i) {
s >> v[i]; s >> v[i];
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIDeque<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
@@ -593,7 +593,7 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v)
c = s.binaryStreamTakeInt(); c = s.binaryStreamTakeInt();
s >> tmp; s >> tmp;
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIVector2D<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
@@ -625,7 +625,7 @@ template<typename P, typename Key, typename T>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMap<Key, T> & v) { inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMap<Key, T> & v) {
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
@@ -635,7 +635,7 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMap<Key, T> & v)
ind = s.binaryStreamTakeInt(); ind = s.binaryStreamTakeInt();
s >> v.pim_index[i].key; s >> v.pim_index[i].key;
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }
@@ -643,7 +643,7 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMap<Key, T> & v)
} }
s >> v.pim_content; s >> v.pim_content;
if (s.wasReadError()) { if (s.wasReadError()) {
printf("error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
} }

View File

@@ -66,10 +66,10 @@ protected:
int counter = 0; int counter = 0;
}; };
#include <iostream>
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
PILog log; PILog log;
log.setApplicationName("test"); log.setLogName("test");
log.setDir("logs"); log.setDir("logs");
// log.setTimestampFormat("hh-mm-ss"); // log.setTimestampFormat("hh-mm-ss");
// log.setLineFormat("[c] m (t)"); // log.setLineFormat("[c] m (t)");
@@ -78,12 +78,15 @@ int main(int argc, char * argv[]) {
// log.enqueue("debug msg"); // log.enqueue("debug msg");
// log.enqueue("warn msg with ${c}", PILog::Category::Warning); // log.enqueue("warn msg with ${c}", PILog::Category::Warning);
// log.enqueue("ERROR${m}${t}", PILog::Category::Error); // log.enqueue("ERROR${m}${t}", PILog::Category::Error);
log.setLevel(PILog::Level::Info);
log.debug(&log) << "some msg"; log.debug() << "some msg";
piMSleep(50);
log.info() << "information";
piMSleep(50); piMSleep(50);
log.warning() << "another!"; log.warning() << "another!";
piMSleep(50); piMSleep(50);
log.error() << "blahblahblag"; log.error(&log) << "critical!";
// log.stop(); // log.stop();
return 0; return 0;

View File

@@ -420,7 +420,7 @@ int main(int argc, char * argv[]) {
MainMenu * menu = new MainMenu(*daemon); MainMenu * menu = new MainMenu(*daemon);
if (sapp) CONNECTU(sapp, messageReceived, menu, messageFromApp); if (sapp) CONNECTU(sapp, messageReceived, menu, messageFromApp);
if (cli.hasArgument("silent")) { if (cli.hasArgument("silent")) {
PICout::setOutputDevices(PICout::StdOut); PICout::setOutputDevices(PICout::Console);
PIKbdListener ls; PIKbdListener ls;
ls.enableExitCapture(PIKbdListener::F10); ls.enableExitCapture(PIKbdListener::F10);
ls.start(); ls.start();