413 lines
15 KiB
C++
413 lines
15 KiB
C++
#include "piconsole.h"
|
|
|
|
|
|
PIConsole::PIConsole(bool startNow, KeyFunc slot): PIThread() {
|
|
setPriority(piLow);
|
|
needLockRun(true);
|
|
ret_func = slot;
|
|
num_format = 0;
|
|
cur_tab = width = height = my = 0;
|
|
#ifdef WINDOWS
|
|
ulcoord.X = ulcoord.Y = 0;
|
|
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
GetConsoleScreenBufferInfo(hOut, &sbi);
|
|
dattr = sbi.wAttributes;
|
|
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
|
height = sbi.srWindow.Bottom - sbi.srWindow.Top;
|
|
GetConsoleMode(hOut, &smode);
|
|
GetConsoleCursorInfo(hOut, &curinfo);
|
|
#endif
|
|
addTab(string("main"));
|
|
listener = new PIKbdListener(key_event, this);
|
|
if (startNow) start(40);
|
|
}
|
|
|
|
|
|
PIConsole::~PIConsole() {
|
|
if (isRunning()) {
|
|
stop();
|
|
waitForFinish();
|
|
moveTo(0, my + 4);
|
|
showCursor();
|
|
}
|
|
delete listener;
|
|
clearTabs(false);
|
|
#ifdef WINDOWS
|
|
SetConsoleMode(hOut, smode);
|
|
SetConsoleTextAttribute(hOut, dattr);
|
|
#endif
|
|
}
|
|
|
|
|
|
int PIConsole::addTab(string name, char bind_key) {
|
|
tabs.push_back(Tab(name, bind_key));
|
|
cur_tab = tabs.size() - 1;
|
|
return tabs.size();
|
|
}
|
|
|
|
|
|
void PIConsole::removeTab(uint index) {
|
|
if (index >= tabs.size()) return;
|
|
tabs.erase(vector<Tab>::iterator(&tabs[index]));
|
|
if (cur_tab >= tabs.size()) cur_tab = tabs.size() - 1;
|
|
}
|
|
|
|
|
|
void PIConsole::removeTab(string name) {
|
|
uint index = tabs.size() + 1;
|
|
for (uint i = 0; i < tabs.size(); ++i) {
|
|
if (tabs[i].name == name) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
removeTab(index);
|
|
}
|
|
|
|
|
|
bool PIConsole::setTab(uint index) {
|
|
if (index >= tabs.size() || index < 0)
|
|
return false;
|
|
cur_tab = index;
|
|
if (!isRunning()) return true;
|
|
lock();
|
|
clearScreen();
|
|
fillLabels();
|
|
unlock();
|
|
return true;
|
|
}
|
|
|
|
|
|
bool PIConsole::setTab(string name) {
|
|
uint index = tabs.size() + 1;
|
|
for (uint i = 0; i < tabs.size(); ++i) {
|
|
if (tabs[i].name == name) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return setTab(index);
|
|
}
|
|
|
|
|
|
bool PIConsole::setTabBindKey(uint index, char bind_key) {
|
|
if (index < 0 || index >= tabs.size())
|
|
return false;
|
|
tabs[index].key = bind_key;
|
|
return true;
|
|
}
|
|
|
|
|
|
bool PIConsole::setTabBindKey(string name, char bind_key) {
|
|
uint index =tabs.size() + 1;
|
|
for (uint i = 0; i < tabs.size(); ++i) {
|
|
if (tabs[i].name == name) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return setTabBindKey(index, bind_key);
|
|
}
|
|
|
|
|
|
void PIConsole::key_event(void * t, char key) {
|
|
PIConsole * p = (PIConsole * )t;
|
|
for (uint i = 0; i < p->tabsCount(); ++i) {
|
|
if (p->tabs[i].key == key) {
|
|
p->setTab(i);
|
|
return;
|
|
}
|
|
}
|
|
if (p->ret_func != 0) p->ret_func(t, key);
|
|
}
|
|
|
|
|
|
string PIConsole::fstr(Flags<PIConsole::Format> f) {
|
|
if (f[PIConsole::Dec]) num_format = 0;
|
|
if (f[PIConsole::Hex]) num_format = 1;
|
|
if (f[PIConsole::Oct]) num_format = 2;
|
|
if (f[PIConsole::Scientific]) num_format = 3;
|
|
|
|
#ifdef WINDOWS
|
|
WORD attr = dattr;
|
|
|
|
if (f[PIConsole::Inverse]) {
|
|
if (f[PIConsole::Red]) attr |= BACKGROUND_RED;
|
|
if (f[PIConsole::Green]) attr |= BACKGROUND_GREEN;
|
|
if (f[PIConsole::Blue]) attr |= BACKGROUND_BLUE;
|
|
if (f[PIConsole::Yellow]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN);
|
|
if (f[PIConsole::Magenta]) attr |= (BACKGROUND_RED | BACKGROUND_BLUE);
|
|
if (f[PIConsole::Cyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE);
|
|
if (f[PIConsole::White]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
|
|
attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
|
} else {
|
|
if (f[PIConsole::Red]) attr |= FOREGROUND_RED;
|
|
if (f[PIConsole::Green]) attr |= FOREGROUND_GREEN;
|
|
if (f[PIConsole::Blue]) attr |= FOREGROUND_BLUE;
|
|
if (f[PIConsole::Yellow]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN);
|
|
if (f[PIConsole::Magenta]) attr |= (FOREGROUND_RED | FOREGROUND_BLUE);
|
|
if (f[PIConsole::Cyan]) attr |= (FOREGROUND_GREEN | FOREGROUND_BLUE);
|
|
if (f[PIConsole::White]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
|
}
|
|
if (f[PIConsole::Bold]) attr |= FOREGROUND_INTENSITY;
|
|
|
|
SetConsoleTextAttribute(hOut, attr);
|
|
return "";
|
|
#else
|
|
string ts = "\e[0";
|
|
|
|
if (f[PIConsole::Bold]) ts += ";1";
|
|
if (f[PIConsole::Faint]) ts += ";2";
|
|
if (f[PIConsole::Italic]) ts += ";3";
|
|
if (f[PIConsole::Underline]) ts += ";4";
|
|
if (f[PIConsole::Blink]) ts += ";5";
|
|
if (f[PIConsole::Inverse]) ts += ";7";
|
|
|
|
if (f[PIConsole::Black]) ts += ";30";
|
|
if (f[PIConsole::Red]) ts += ";31";
|
|
if (f[PIConsole::Green]) ts += ";32";
|
|
if (f[PIConsole::Yellow]) ts += ";33";
|
|
if (f[PIConsole::Blue]) ts += ";34";
|
|
if (f[PIConsole::Magenta]) ts += ";35";
|
|
if (f[PIConsole::Cyan]) ts += ";36";
|
|
if (f[PIConsole::White]) ts += ";37";
|
|
|
|
return ts + "m";
|
|
#endif
|
|
}
|
|
|
|
#define siprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; default: return printf("%hd", x); break;}
|
|
#define iprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; default: return printf("%d", x); break;}
|
|
#define liprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; default: return printf("%ld", x); break;}
|
|
#define lliprint(x) switch (num_format) {case (1): return printf("0x%.16LX", x); break; case (2): return printf("%Lo", x); break; default: return printf("%Ld", x); break;}
|
|
#define suprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; default: return printf("%hd", x); break;}
|
|
#define uprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; default: return printf("%u", x); break;}
|
|
#define luprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; default: return printf("%lu", x); break;}
|
|
#define lluprint(x) switch (num_format) {case (1): return printf("0x%.16LX", x); break; case (2): return printf("%Lo", x); break; default: return printf("%Lu", x); break;}
|
|
#define fprint(x) switch (num_format) {case (3): return printf("%e", x); break; default: return printf("%.5g", x); break;}
|
|
#define dprint(x) switch (num_format) {case (3): return printf("%le", x); break; default: return printf("%.5lg", x); break;}
|
|
|
|
inline int PIConsole::couts(string v) {return printf("%s", v.c_str());}
|
|
inline int PIConsole::couts(char * v) {return printf("%s", v);}
|
|
inline int PIConsole::couts(bool v) {return (v ? printf("true") : printf("false"));}
|
|
inline int PIConsole::couts(char v) {return printf("%c", v);}
|
|
inline int PIConsole::couts(short v) {siprint(v);}
|
|
inline int PIConsole::couts(int v) {iprint(v);}
|
|
inline int PIConsole::couts(long v) {liprint(v);}
|
|
inline int PIConsole::couts(llong v) {lliprint(v);}
|
|
inline int PIConsole::couts(uchar v) {uprint(v);}
|
|
inline int PIConsole::couts(ushort v) {suprint(v);}
|
|
inline int PIConsole::couts(uint v) {uprint(v);}
|
|
inline int PIConsole::couts(ulong v) {luprint(v);}
|
|
inline int PIConsole::couts(ullong v) {lluprint(v);}
|
|
inline int PIConsole::couts(float v) {fprint(v);}
|
|
inline int PIConsole::couts(double v) {dprint(v);}
|
|
|
|
|
|
void PIConsole::begin() {
|
|
#ifdef WINDOWS
|
|
SetConsoleMode(hOut, ENABLE_WRAP_AT_EOL_OUTPUT);
|
|
#endif
|
|
clearScreen();
|
|
hideCursor();
|
|
fillLabels();
|
|
}
|
|
|
|
|
|
void PIConsole::run() {
|
|
uint cx, clen = 0;
|
|
#ifdef WINDOWS
|
|
GetConsoleScreenBufferInfo(hOut, &sbi);
|
|
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
|
height = sbi.srWindow.Bottom - sbi.srWindow.Top;
|
|
#else
|
|
winsize ws;
|
|
ioctl(0, TIOCGWINSZ, &ws);
|
|
width = ws.ws_col;
|
|
height = ws.ws_row;
|
|
#endif
|
|
col_cnt = vars().size();
|
|
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
|
for (uint i = 0; i < col_cnt; ++i) {
|
|
cx = col_wid * i;
|
|
toUpperLeft();
|
|
for (uint j = 0; j < vars()[i].size(); ++j) {
|
|
if (my < j) my = j;
|
|
tv = vars()[i][j];
|
|
moveRight(cx);
|
|
if (tv.name.size() == 0) {
|
|
newLine();
|
|
continue;
|
|
}
|
|
if (tv.type == 0 && tv.s == 0) {
|
|
newLine();
|
|
continue;
|
|
}
|
|
moveRight(tv.offset);
|
|
switch (tv.type) {
|
|
case 0: clen = printValue(*tv.s, tv.format); break;
|
|
case 1: clen = printValue(*tv.b, tv.format); break;
|
|
case 2: clen = printValue(*tv.i, tv.format); break;
|
|
case 3: clen = printValue(*tv.l, tv.format); break;
|
|
case 4: clen = printValue(*tv.c, tv.format); break;
|
|
case 5: clen = printValue(*tv.f, tv.format); break;
|
|
case 6: clen = printValue(*tv.d, tv.format); break;
|
|
case 7: clen = printValue(*tv.sh, tv.format); break;
|
|
case 8: clen = printValue(*tv.ui, tv.format); break;
|
|
case 9: clen = printValue(*tv.ul, tv.format); break;
|
|
case 10: clen = printValue(*tv.ush, tv.format); break;
|
|
case 11: clen = printValue(*tv.uc, tv.format); break;
|
|
case 12: clen = printValue(*tv.ll, tv.format); break;
|
|
case 13: clen = printValue(*tv.ull, tv.format); break;
|
|
case 14: clen = printValue(bitsValue(tv.uc, tv.bitFrom, tv.bitCount), tv.format); break;
|
|
}
|
|
if (clen + tv.offset < (uint)col_wid)
|
|
printf("%s", string(col_wid - clen - tv.offset, ' ').c_str());
|
|
newLine();
|
|
}
|
|
}
|
|
fflush(0);
|
|
}
|
|
|
|
|
|
void PIConsole::fillLabels() {
|
|
uint cx, my = 0;
|
|
#ifdef WINDOWS
|
|
GetConsoleScreenBufferInfo(hOut, &sbi);
|
|
width = sbi.srWindow.Right - sbi.srWindow.Left;
|
|
height = sbi.srWindow.Bottom - sbi.srWindow.Top;
|
|
#else
|
|
winsize ws;
|
|
ioctl(0, TIOCGWINSZ, &ws);
|
|
width = ws.ws_col;
|
|
height = ws.ws_row;
|
|
#endif
|
|
col_cnt = vars().size();
|
|
col_wid = (col_cnt > 0) ? width / col_cnt : width;
|
|
for (uint i = 0; i < col_cnt; ++i) {
|
|
cx = col_wid * i;
|
|
toUpperLeft();
|
|
for (uint j = 0; j < vars()[i].size(); ++j) {
|
|
if (my < j) my = j;
|
|
moveRight(cx);
|
|
tv = vars()[i][j];
|
|
if (tv.name.size() == 0) {
|
|
newLine();
|
|
continue;
|
|
}
|
|
clearLine();
|
|
if (tv.type == 0 && tv.s == 0) {
|
|
printLine(tv.name, cx, tv.format);
|
|
newLine();
|
|
continue;
|
|
}
|
|
vars()[i][j].offset = printValue(tv.name + ": ", tv.format);
|
|
newLine();
|
|
}
|
|
}
|
|
moveTo(0, my + 2);
|
|
if (tabs[cur_tab].status.length() > 0) {
|
|
printValue(tabs[cur_tab].status);
|
|
newLine();
|
|
}
|
|
status();
|
|
//fflush(0);
|
|
}
|
|
|
|
|
|
void PIConsole::status() {
|
|
Tab * ctab;
|
|
//clearLine();
|
|
for (uint i = 0; i < tabsCount(); ++i) {
|
|
ctab = &tabs[i];
|
|
if (ctab->key == 0) continue;
|
|
printValue(ctab->key, PIConsole::Bold);
|
|
printValue(ctab->name + " ", PIConsole::Cyan | PIConsole::Inverse);
|
|
printValue(string(" "), PIConsole::Normal);
|
|
}
|
|
newLine();
|
|
}
|
|
|
|
|
|
int PIConsole::bitsValue(unsigned char * src, int offset, int count) {
|
|
int ret = 0, stbyte = offset / 8, cbit = offset - stbyte * 8;
|
|
char cbyte = src[stbyte];
|
|
for (int i = 0; i < count; i++) {
|
|
ret |= ((cbyte >> cbit & 1) << i);
|
|
cbit++;
|
|
if (cbit == 8) {
|
|
cbit = 0;
|
|
stbyte++;
|
|
cbyte = src[stbyte];
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#define ADD_VAR_BODY tv.name = name; tv.bitFrom = tv.bitCount = 0; tv.format = format; checkColumn(column);
|
|
|
|
void PIConsole::addString(string name, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 0; tv.s = 0; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, string* ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 0; tv.s = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, bool * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 1; tv.b = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, int * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 2; tv.i = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, long * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 3; tv.l = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, char * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 4; tv.c = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, float * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 5; tv.f = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, double * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 6; tv.d = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, short * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 7; tv.sh = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, uint * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 8; tv.ui = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, ulong * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 9; tv.ul = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, ushort * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 10; tv.ush = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, uchar * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 11; tv.uc = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, llong * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 12; tv.ll = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addVariable(string name, ullong * ptr, int column, Flags<PIConsole::Format> format) {
|
|
ADD_VAR_BODY tv.type = 13; tv.ull = ptr; vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addBitVariable(string name, uchar * ptr, int fromBit, int bitCount, int column, Flags<PIConsole::Format> format) {
|
|
tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.uc = ptr; tv.format = format;
|
|
checkColumn(column); vars()[column - 1].push_back(tv);}
|
|
void PIConsole::addEmptyLine(int column) {
|
|
tv.name = ""; tv.type = 0; tv.d = 0; tv.format = Normal;
|
|
checkColumn(column); vars()[column - 1].push_back(tv);}
|
|
|
|
#define PRINT_VAR_BODY couts(fstr(format)); int ret = couts(value); fstr(PIConsole::Dec); return ret;
|
|
|
|
void PIConsole::printLine(string value, int dx, Flags<PIConsole::Format> format) {
|
|
int i = width - value.length() - dx;
|
|
#ifdef QNX
|
|
--i;
|
|
#endif
|
|
couts(fstr(format));
|
|
if (i >= 0) couts(value + string(i, ' '));
|
|
else couts(string(value, 0, value.length() + i));
|
|
couts(fstr(Dec));
|
|
}
|
|
int PIConsole::printValue(string value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(char * value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(bool value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(int value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(long value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(llong value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(float value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(double value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(char value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(short value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(uchar value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(ushort value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(uint value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(ulong value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|
|
int PIConsole::printValue(ullong value, Flags<PIConsole::Format> format) {PRINT_VAR_BODY}
|