diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fa514c0..8eab44c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,11 @@ project(pip) cmake_minimum_required(VERSION 2.6) include_directories(${CMAKE_CURRENT_SOURCE_DIR} .) file(GLOB CPPS "pi*.cpp") -add_definitions(-O2 -g3 -Wall) +if (${WIN32}) + add_definitions(-Wall -O2) +else (${WIN32}) + add_definitions(-Wall -O2 -g3) +endif (${WIN32}) add_library(pip SHARED ${CPPS}) if (${WIN32}) target_link_libraries(pip pthread ws2_32) @@ -11,7 +15,7 @@ else (${WIN32}) endif (${WIN32}) add_executable(pip_test "main.cpp") if (${WIN32}) - target_link_libraries(pip_test pip pthread ws2_32) + target_link_libraries(pip_test pthread ws2_32 pip) else (${WIN32}) - target_link_libraries(pip_test pip pthread rt) + target_link_libraries(pip_test pthread rt pip) endif (${WIN32}) diff --git a/core b/core new file mode 100644 index 00000000..b3c23d6b Binary files /dev/null and b/core differ diff --git a/main.cpp b/main.cpp index 5abab5a7..d0a88abe 100644 --- a/main.cpp +++ b/main.cpp @@ -1,21 +1,54 @@ #include -int main(int argc, char * argv[]) { - PIString s("sos№⚒№хуй"/*☢⚒SOŮ*/); - /*cout << s << endl; - cout << s.length() << endl; - cout << s.stdWString().length() << endl;*/ - //system("cd /"); - PIProcess p; - //p.setWorkingDirectory("/"); - //p.setEnvironmentVariable("PWD", "/"); - //cout << p.environment().join("\n") << endl; - p.exec("cd"); - p.waitForFinish(); - - //cout << s << endl; - /*wchar_t wc; - cout << (int)(uchar)("№"[0]) << ", " << (int)(uchar)("№"[1]) << endl; - cout << isascii("№"[0]) << endl; - cout << mbtowc(&wc, "№", 4) << endl;*/ +class Prot: public PIProtocol { +public: + Prot(): PIProtocol() { + setName("test"); + ba.resize(1024); + setReceiverAddress("127.0.0.1", 3003, true); + setReceiverData(ba.data(), ba.size_s()); + setSenderAddress("127.0.0.2", 3003, true); + setSenderData(ba.data(), ba.size_s()); + setExpectedFrequency(100); + //setSenderFrequency(); + //startReceive(100); + startSend(10); + }; + PIByteArray ba; +}; + +class MProt: public PIMultiProtocol { +public: + MProt() {cor = incor = 0;} + + int cor, incor; + + virtual void received(PIProtocol * prot, bool corrected, char * data, int size) {if (corrected) cor++; else incor++; if (prot->name() == "test" && corrected) prot->send();} + + +}; + +PIConsole c(false); +//Prot p; + +int main(int argc, char * argv[]) { + MProt mp; + Prot p; + PIRepeater r("protocols.conf", "r", 1024); + mp.addProtocol(p); + c.addVariable("rec : " + mp[0]->receiverDeviceName() + ":", mp[0]->receiverDeviceState_ptr()); + c.addVariable("send: " + mp[0]->senderDeviceName() + ":", mp[0]->senderDeviceState_ptr()); + c.addVariable("freq", mp[0]->immediateFrequency_ptr()); + c.addVariable("sent ", mp[0]->sendCount_ptr()); + c.addVariable("ok ", mp[0]->receiveCount_ptr()); + c.addVariable("wrong", mp[0]->wrongCount_ptr()); + c.addEmptyLine(); + c.addVariable("mp_corr", &mp.cor); + c.addVariable("mp_incr", &mp.incor); + c.addVariable(r.firstChannelName() + ", rec ", r.receiveCount_ptr()); + c.addVariable(r.secondChannelName() + ", send", r.sendCount_ptr()); + c.enableExitCapture(); + mp.start(); + c.start(false); + c.waitForFinish(); }; diff --git a/make_install.sh b/make_install.sh index 195f1dc5..9e65aa38 100755 --- a/make_install.sh +++ b/make_install.sh @@ -1,8 +1,5 @@ #! /bin/bash cmake . -make -j3 -if [ $@ != "" ] ; then - chown -v $@ /usr/lib/ /usr/include/ -fi +make $@ cp -vf *.h /usr/include/ -cp -vf libpip.so /usr/lib/libpip.so +cp -vf lib*.so /usr/lib/ diff --git a/pichar.h b/pichar.h index 008c2d05..c1132237 100644 --- a/pichar.h +++ b/pichar.h @@ -66,13 +66,13 @@ public: inline const wchar_t toWChar() const {return ch;} inline char toAscii() const {return ch % 256;} inline int unicode16Code() const {wchar_t wc; if (mbtowc(&wc, toCharPtr(), 4) > 0) return wc; return 0;} -#ifdef WINDOWS - inline PIChar toUpper() const __attribute__ ((optimize(0))) {return PIChar(toupper(ch));} - inline PIChar toLower() const __attribute__ ((optimize(0))) {return PIChar(tolower(ch));} -#else +//#ifdef WINDOWS +// inline PIChar toUpper() const __attribute__ ((optimize(0))) {return PIChar(toupper(ch));} +// inline PIChar toLower() const __attribute__ ((optimize(0))) {return PIChar(tolower(ch));} +//#else inline PIChar toUpper() const {return PIChar(toupper(ch));} inline PIChar toLower() const {return PIChar(tolower(ch));} -#endif +//#endif private: wchar_t ch; diff --git a/picli.cpp b/picli.cpp index 722a59e4..49c95397 100644 --- a/picli.cpp +++ b/picli.cpp @@ -21,7 +21,7 @@ void PICLI::parse() { if (cra.left(2) == _prefix_full) { last = 0; full = cra.right(cra.length() - 2); - piForeachA (a, _args) { + piForeach (Argument & a, _args) { if (a.full_key == full) { a.found = true; last = &a; @@ -32,7 +32,7 @@ void PICLI::parse() { if (cra.left(1) == _prefix_short) { last = 0; for (int j = 1; j < cra.length(); ++j) { - piForeachA (a, _args) { + piForeach (Argument & a, _args) { if (a.short_key == cra[j]) { a.found = true; last = &a; diff --git a/picli.h b/picli.h index 73f01210..d6050b7e 100644 --- a/picli.h +++ b/picli.h @@ -21,10 +21,10 @@ public: inline const PIStringList & mandatoryArguments() const {return _args_mand;} inline const PIStringList & optionalArguments() const {return _args_opt;} inline const PIString programCommand() const {return _args_raw.size() > 0 ? _args_raw.front() : PIString();} - inline bool hasArgument(const PIString & name) {parse(); piForeachA (i, _args) if (i.name == name && i.found) return true; return false;} - inline PIString argumentValue(const PIString & name) {parse(); piForeachA (i, _args) if (i.name == name && i.found) return i.value; return PIString();} - inline PIString argumentShortKey(const PIString & name) {piForeachA (i, _args) if (i.name == name) return i.short_key; return PIString();} - inline PIString argumentFullKey(const PIString & name) {piForeachA (i, _args) if (i.name == name) return i.full_key; return PIString();} + inline bool hasArgument(const PIString & name) {parse(); piForeach (Argument & i, _args) if (i.name == name && i.found) return true; return false;} + inline PIString argumentValue(const PIString & name) {parse(); piForeach (Argument &i, _args) if (i.name == name && i.found) return i.value; return PIString();} + inline PIString argumentShortKey(const PIString & name) {piForeach (Argument &i, _args) if (i.name == name) return i.short_key; return PIString();} + inline PIString argumentFullKey(const PIString & name) {piForeach (Argument &i, _args) if (i.name == name) return i.full_key; return PIString();} inline const PIString & shortKeyPrefix() const {return _prefix_short;} inline const PIString & fullKeyPrefix() const {return _prefix_full;} diff --git a/piconfig.cpp b/piconfig.cpp index 965efed1..b72bc521 100644 --- a/piconfig.cpp +++ b/piconfig.cpp @@ -8,7 +8,7 @@ PIConfig::Entry PIConfig::Entry::_empty; PIConfig::Branch PIConfig::Branch::allLeaves() { Branch b; b.delim = delim; - piForeachCA (i, *this) { + piForeach (Entry * i, *this) { if (i->isLeaf()) b << i; else allLeaves(b, i); } @@ -27,7 +27,7 @@ PIConfig::Entry & PIConfig::Branch::getValue(const PIString & vname, const PIStr PIString name = tree.front(); tree.pop_front(); Entry * ce = 0; - piForeachCA (i, *this) + piForeach (Entry * i, *this) if (i->_name == name) { ce = i; break; @@ -39,7 +39,7 @@ PIConfig::Entry & PIConfig::Branch::getValue(const PIString & vname, const PIStr if (exist != 0) *exist = false; return _empty; } - piForeachCA (i, tree) { + piForeach (PIString & i, tree) { ce = ce->findChild(i); if (ce == 0) { _empty._name = vname; @@ -57,12 +57,12 @@ PIConfig::Entry & PIConfig::Branch::getValue(const PIString & vname, const PIStr PIConfig::Branch PIConfig::Branch::getValues(const PIString & name) { Branch b; b.delim = delim; - piForeachA (i, *this) { + piForeach (Entry * i, *this) { if (i->isLeaf()) { if (i->_name.find(name) >= 0) b << i; } else { - piForeachA (j, i->_children) + piForeach (Entry * j, i->_children) if (j->_name.find(name) >= 0) b << j; } @@ -74,7 +74,7 @@ PIConfig::Branch PIConfig::Branch::getValues(const PIString & name) { PIConfig::Branch PIConfig::Branch::getLeaves() { Branch b; b.delim = delim; - piForeachA (i, *this) + piForeach (Entry * i, *this) if (i->isLeaf()) b << i; return b; @@ -84,7 +84,7 @@ PIConfig::Branch PIConfig::Branch::getLeaves() { PIConfig::Branch PIConfig::Branch::getBranches() { Branch b; b.delim = delim; - piForeachA (i, *this) + piForeach (Entry * i, *this) if (!i->isLeaf()) b << i; return b; @@ -107,7 +107,7 @@ bool PIConfig::Branch::entryExists(const Entry * e, const PIString & name) const if (e->_name == name) return true; else return false; } - piForeachCA (i, e->_children) + piForeachC (Entry * i, e->_children) if (entryExists(i, name)) return true; return false; } @@ -116,7 +116,7 @@ bool PIConfig::Branch::entryExists(const Entry * e, const PIString & name) const PIConfig::Entry & PIConfig::Entry::getValue(const PIString & vname, const PIString & def, bool * exist) { PIStringList tree = vname.split(delim); Entry * ce = this; - piForeachCA (i, tree) { + piForeach (PIString & i, tree) { ce = ce->findChild(i); if (ce == 0) { _empty._name = vname; @@ -134,7 +134,7 @@ PIConfig::Entry & PIConfig::Entry::getValue(const PIString & vname, const PIStri PIConfig::Branch PIConfig::Entry::getValues(const PIString & vname) { Branch b; b.delim = delim; - piForeachA (i, _children) + piForeach (Entry * i, _children) if (i->_name.find(vname) >= 0) b << i; return b; @@ -146,7 +146,7 @@ bool PIConfig::Entry::entryExists(const Entry * e, const PIString & name) const if (e->_name == name) return true; else return false; } - piForeachCA (i, e->_children) + piForeachC (Entry * i, e->_children) if (entryExists(i, name)) return true; return false; } @@ -166,7 +166,7 @@ PIConfig::PIConfig(const PIString & path, PIFlags mode): PIFile(path, mode PIConfig::Entry & PIConfig::getValue(const PIString & vname, const PIString & def, bool * exist) { PIStringList tree = vname.split(delim); Entry * ce = &root; - piForeachCA (i, tree) { + piForeach (PIString & i, tree) { ce = ce->findChild(i); if (ce == 0) { if (exist != 0) *exist = false; @@ -184,7 +184,7 @@ PIConfig::Entry & PIConfig::getValue(const PIString & vname, const PIString & de PIConfig::Branch PIConfig::getValues(const PIString & vname) { Branch b; b.delim = delim; - piForeachA (i, root._children) + piForeach (Entry * i, root._children) if (i->_name.find(vname) >= 0) b << i; return b; @@ -200,7 +200,7 @@ void PIConfig::addEntry(const PIString & name, const PIString & value, const PIS tree.pop_back(); Entry * te, * ce, * entry = &root; if (tree.isEmpty()) toRoot = true; - piForeachA (i, tree) { + piForeach (PIString & i, tree) { te = entry->findChild(i); if (te == 0) { ce = new Entry(); @@ -270,7 +270,7 @@ void PIConfig::setValue(const PIString & name, const PIString & value, const PIS int PIConfig::entryIndex(const PIString & name) { PIStringList tree = name.split(delim); Entry * ce = &root; - piForeachCA (i, tree) { + piForeach (PIString & i, tree) { ce = ce->findChild(i); if (ce == 0) return -1; @@ -395,7 +395,7 @@ bool PIConfig::entryExists(const Entry * e, const PIString & name) const { if (e->_name == name) return true; else return false; } - piForeachCA (i, e->_children) + piForeachC (Entry * i, e->_children) if (entryExists(i, name)) return true; return false; } @@ -436,7 +436,7 @@ void PIConfig::parse() { name = tree.back(); tree.pop_back(); entry = &root; - piForeachA (i, tree) { + piForeach (PIString & i, tree) { te = entry->findChild(i); if (te == 0) { ce = new Entry(); @@ -471,4 +471,5 @@ void PIConfig::parse() { lines++; } setEntryDelim(&root, delim); + buildFullNames(&root); } diff --git a/piconfig.h b/piconfig.h index 8fb4505d..2edafd77 100644 --- a/piconfig.h +++ b/piconfig.h @@ -42,15 +42,15 @@ public: Branch getLeaves(); Branch getBranches(); Branch & filter(const PIString & f); - inline bool isEntryExists(const PIString & name) const {piForeachCA (i, *this) if (entryExists(i, name)) return true; return false;} + inline bool isEntryExists(const PIString & name) const {piForeachC (Entry * i, *this) if (entryExists(i, name)) return true; return false;} inline int indexOf(const Entry * e) {for (int i = 0; i < size_s(); ++i) if (at(i) == e) return i; return -1;} - inline void clear() {piForeachA (i, *this) delete i; PIVector::clear();} + inline void clear() {piForeach (Entry * i, *this) delete i; PIVector::clear();} private: bool entryExists(const Entry * e, const PIString & name) const; - inline void allLeaves(Branch & b, Entry * e) {piForeachCA (i, e->_children) {if (i->isLeaf()) b << i; else allLeaves(b, i);}} - inline void coutt(std::ostream & s, const PIString & p) const {piForeachCA (i, *this) i->coutt(s, p);} + inline void allLeaves(Branch & b, Entry * e) {piForeach (Entry * i, e->_children) {if (i->isLeaf()) b << i; else allLeaves(b, i);}} + inline void coutt(std::ostream & s, const PIString & p) const {piForeachC (Entry * i, *this) i->coutt(s, p);} static Entry _empty; PIString delim; @@ -67,14 +67,15 @@ public: inline int childCount() {return _children.size_s();} inline Branch & children() {_children.delim = delim; return _children;} inline Entry * child(const int index) const {return _children[index];} - inline Entry * findChild(const PIString & name) {piForeachCA (i, _children) if (i->_name == name) return i; return 0;} - inline const Entry * findChild(const PIString & name) const {piForeachCA (i, _children) if (i->_name == name) return i; return 0;} + inline Entry * findChild(const PIString & name) {piForeach (Entry * i, _children) if (i->_name == name) return i; return 0;} + inline const Entry * findChild(const PIString & name) const {piForeachC (Entry * i, _children) if (i->_name == name) return i; return 0;} inline bool isLeaf() const {return _children.isEmpty();} inline const PIString & name() const {return _name;} inline const PIString & value() const {return _value;} inline const PIString & type() const {return _type;} inline const PIString & comment() const {return _comment;} + inline const PIString & fullName() const {return _full_name;} inline Entry & setName(const PIString & value) {_name = value; return *this;} inline Entry & setType(const PIString & value) {_type = value; return *this;} @@ -120,7 +121,7 @@ public: bool entryExists(const Entry * e, const PIString & name) const; inline void buildLine() {_all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment;} inline void clear() {_children.clear(); _name = _value = _type = _comment = _all = PIString(); _line = 0; _parent = 0;} - inline void coutt(std::ostream & s, const PIString & p) const {PIString nl = p + " "; if (!_value.isEmpty()) s << p << _name << " = " << _value << endl; else cout << p << _name << endl; piForeachCA (i, _children) i->coutt(s, nl);} + inline void coutt(std::ostream & s, const PIString & p) const {PIString nl = p + " "; if (!_value.isEmpty()) s << p << _name << " = " << _value << endl; else cout << p << _name << endl; piForeachC (Entry * i, _children) i->coutt(s, nl);} static Entry _empty; Entry * _parent; @@ -159,7 +160,7 @@ public: inline int entriesCount() const {return childCount(&root);} inline bool isEntryExists(const PIString & name) const {return entryExists(&root, name);} - inline Branch allTree() {Branch b; piForeachCA (i, root._children) b << i; return b;} + inline Branch allTree() {Branch b; piForeach (Entry * i, root._children) b << i; return b;} inline Branch allLeaves() {Branch b; allLeaves(b, &root); std::sort(b.begin(), b.end(), Entry::compare); return b;} int entryIndex(const PIString & name); @@ -184,11 +185,11 @@ public: void setDelimiter(const PIString & d) {delim = d; setEntryDelim(&root, d); readAll();} private: - int childCount(const Entry * e) const {int c = 0; piForeachCA (i, e->_children) c += childCount(i); c += e->_children.size_s(); return c;} + int childCount(const Entry * e) const {int c = 0; piForeachC (Entry * i, e->_children) c += childCount(i); c += e->_children.size_s(); return c;} bool entryExists(const Entry * e, const PIString & name) const; - void buildFullNames(Entry * e) {piForeachCA (i, e->_children) {if (e != &root) i->_full_name = e->_full_name + delim + i->_name; else i->_full_name = i->_name; buildFullNames(i);}} - void allLeaves(Branch & b, Entry * e) {piForeachCA (i, e->_children) {if ((!i->_value.isEmpty() && !i->isLeaf()) || i->isLeaf()) b << i; allLeaves(b, i);}} - void setEntryDelim(Entry * e, const PIString & d) {piForeachCA (i, e->_children) setEntryDelim(i, d); e->delim = d;} + void buildFullNames(Entry * e) {piForeach (Entry * i, e->_children) {if (e != &root) i->_full_name = e->_full_name + delim + i->_name; else i->_full_name = i->_name; buildFullNames(i);}} + void allLeaves(Branch & b, Entry * e) {piForeach (Entry * i, e->_children) {if ((!i->_value.isEmpty() && !i->isLeaf()) || i->isLeaf()) b << i; allLeaves(b, i);}} + void setEntryDelim(Entry * e, const PIString & d) {piForeach (Entry * i, e->_children) setEntryDelim(i, d); e->delim = d;} inline Entry & entryByIndex(const int index) {Branch b = allLeaves(); if (index < 0 || index >= b.size_s()) return empty; return *(b[index]);} void removeEntry(Branch & b, Entry * e); void parse(); diff --git a/piconsole.cpp b/piconsole.cpp index b8766dfb..adfb5e83 100644 --- a/piconsole.cpp +++ b/piconsole.cpp @@ -27,11 +27,11 @@ PIConsole::~PIConsole() { if (isRunning()) stop(); clearTabs(false); + delete listener; #ifdef WINDOWS SetConsoleMode(hOut, smode); SetConsoleTextAttribute(hOut, dattr); #endif - delete listener; } @@ -44,7 +44,7 @@ int PIConsole::addTab(const PIString & name, char bind_key) { void PIConsole::removeTab(uint index) { if (index >= tabs.size()) return; - tabs.erase(vector::iterator(&tabs[index])); + tabs.remove(index); if (cur_tab >= tabs.size()) cur_tab = tabs.size() - 1; } @@ -211,12 +211,12 @@ PIString PIConsole::fstr(PIFlags f) { #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 lliprint(x) switch (num_format) {case (1): return printf("0x%.16llX", x); break; case (2): return printf("%llo", x); break; default: return printf("%lld", x); break;} #define cuprint(x) switch (num_format) {case (1): return printf("0x%.2X", x); break; case (2): return printf("%o", x); break; default: return printf("%u", 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 lluprint(x) switch (num_format) {case (1): return printf("0x%.16llX", x); break; case (2): return printf("%llo", x); break; default: return printf("%llu", 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;} @@ -271,7 +271,7 @@ void PIConsole::run() { cx = col_wid * i; toUpperLeft(); if (my < vars()[i].size()) my = vars()[i].size(); - piForeachCA (tv, vars()[i]) { + piForeachC (Variable & tv, vars()[i]) { moveRight(cx); if (tv.type == 0 && tv.s == 0) { newLine(); @@ -279,20 +279,20 @@ void PIConsole::run() { } 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 0: clen = printValue(tv.s != 0 ? *tv.s : "", tv.format); break; + case 1: clen = printValue(tv.b != 0 ? *tv.b : false, tv.format); break; + case 2: clen = printValue(tv.i != 0 ? *tv.i : 0, tv.format); break; + case 3: clen = printValue(tv.l != 0 ? *tv.l : 0l, tv.format); break; + case 4: clen = printValue(tv.c != 0 ? *tv.c : 0, tv.format); break; + case 5: clen = printValue(tv.f != 0 ? *tv.f : 0.f, tv.format); break; + case 6: clen = printValue(tv.d != 0 ? *tv.d : 0., tv.format); break; + case 7: clen = printValue(tv.sh != 0 ? *tv.sh : 0, tv.format); break; + case 8: clen = printValue(tv.ui != 0 ? *tv.ui : 0u, tv.format); break; + case 9: clen = printValue(tv.ul != 0 ? *tv.ul : 0ul, tv.format); break; + case 10: clen = printValue(tv.ush != 0 ? *tv.ush : 0u, tv.format); break; + case 11: clen = printValue(tv.uc != 0 ? *tv.uc : 0u, tv.format); break; + case 12: clen = printValue(tv.ll != 0 ? *tv.ll : 0l, tv.format); break; + case 13: clen = printValue(tv.ull != 0 ? *tv.ull : 0ull, tv.format); break; case 14: clen = printValue(bitsValue(tv.ptr, tv.bitFrom, tv.bitCount), tv.format); break; } if (clen + tv.offset < (uint)col_wid) { @@ -443,27 +443,21 @@ void PIConsole::addEmptyLine(int column, uint count) { PIString PIConsole::getString(int x, int y) { bool run = isRunning(); if (run) PIThread::stop(true); - listener->terminate(); - msleep(10); listener->setActive(false); moveTo(x, y); showCursor(); PIByteArray ba(4096); - fflush(0); - scanf("%s", ba.data()); - //fflush(0); - listener->start(); - msleep(10); - if (run) start(); - msleep(10); + int ret = scanf(" %s", ba.data()); listener->setActive(true); - return PIString(ba); + if (run) start(); + if (ret >= 1) return PIString(ba); + else return PIString(); } PIString PIConsole::getString(const PIString & name) { - piForeachCA (i, tabs[cur_tab].variables) - piForeachCA (j, i) + piForeachC (PIVector & i, tabs[cur_tab].variables) + piForeachC (Variable & j, i) if (j.name == name) return getString(j.nx + 1, j.ny); return PIString(); diff --git a/piconsole.h b/piconsole.h index 18b2b4d0..ee19e542 100644 --- a/piconsole.h +++ b/piconsole.h @@ -88,7 +88,7 @@ public: void clearVariables(bool clearScreen = true) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} vars().clear();} inline void waitForFinish() {WAIT_FOR_EXIT} - inline void start() {PIThread::start(40);} + inline void start(bool wait = false) {PIThread::start(40); if (wait) waitForFinish();} void stop(bool clear = false); PIString fstr(PIFlags f); diff --git a/picontainers.h b/picontainers.h index 35aa65fd..53ac4787 100644 --- a/picontainers.h +++ b/picontainers.h @@ -3,6 +3,8 @@ #include "piincludes.h" +#ifdef CC_GCC + template class _PIForeachC { public: @@ -29,19 +31,24 @@ public: inline void operator ++() {if (_inv) _rit++; else _it++; _break = false;} }; -#define piForTimes(c) for(int i = 0; i < c; ++i) - -#define piForeach(i,c) for(_PIForeach _for(c); !_for.isEnd(); ++_for) for(i = *_for._it; !_for._break; _for._break = true) -#define piForeachR(i,c) for(_PIForeach _for(c, true); !_for.isEnd(); ++_for) for(i = *_for._rit; !_for._break; _for._break = true) -#define piForeachA(i,c) for(_PIForeach _for(c); !_for.isEnd(); ++_for) for(typeof(_for._var) & i(*_for._it); !_for._break; _for._break = true) -#define piForeachAR(i,c) for(_PIForeach _for(c, true); !_for.isEnd(); ++_for) for(typeof(_for._var) & i(*_for._rit); !_for._break; _for._break = true) -#define piForeachC(i,c) for(_PIForeachC _for(c); !_for.isEnd(); ++_for) for(const i = *_for._it; !_for._break; _for._break = true) -#define piForeachCR(i,c) for(_PIForeachC _for(c, true); !_for.isEnd(); ++_for) for(const i = *_for._rit; !_for._break; _for._break = true) -#define piForeachCA(i,c) for(_PIForeachC _for(c); !_for.isEnd(); ++_for) for(const typeof(_for._var) & i(*_for._it); !_for._break; _for._break = true) -#define piForeachCAR(i,c) for(_PIForeachC _for(c, true); !_for.isEnd(); ++_for) for(const typeof(_for._var) & i(*_for._rit); !_for._break; _for._break = true) +#define piForeach(i,c) for(_PIForeach _for(c); !_for.isEnd(); ++_for) \ + for(i = *_for._it; !_for._break; _for._break = true) +#define piForeachR(i,c) for(_PIForeach _for(c, true); !_for.isEnd(); ++_for) \ + for(i = *_for._rit; !_for._break; _for._break = true) +#define piForeachA(i,c) for(_PIForeach _for(c); !_for.isEnd(); ++_for) \ + for(typeof(_for._var) & i(*_for._it); !_for._break; _for._break = true) +#define piForeachAR(i,c) for(_PIForeach _for(c, true); !_for.isEnd(); ++_for) \ + for(typeof(_for._var) & i(*_for._rit); !_for._break; _for._break = true) +#define piForeachC(i,c) for(_PIForeachC _for(c); !_for.isEnd(); ++_for) \ + for(const i = *_for._it; !_for._break; _for._break = true) +#define piForeachCR(i,c) for(_PIForeachC _for(c, true); !_for.isEnd(); ++_for) \ + for(const i = *_for._rit; !_for._break; _for._break = true) +#define piForeachCA(i,c) for(_PIForeachC _for(c); !_for.isEnd(); ++_for) \ + for(const typeof(_for._var) & i(*_for._it); !_for._break; _for._break = true) +#define piForeachCAR(i,c) for(_PIForeachC _for(c, true); !_for.isEnd(); ++_for) \ + for(const typeof(_for._var) & i(*_for._rit); !_for._break; _for._break = true) #define piForeachRA piForeachAR -#define piForeachRC piForeachCR #define piForeachAC piForeachCA #define piForeachCRA piForeachCAR #define piForeachARC piForeachCAR @@ -49,6 +56,57 @@ public: #define piForeachRCA piForeachCAR #define piForeachRAC piForeachCAR +#else + +struct _PIForeachBase {mutable bool _break;}; + +template +class _PIForeach: public _PIForeachBase { +public: + inline _PIForeach(Type & t, bool i = false): _t(t), _inv(i) {if (_inv) _rit = _t.rbegin(); else _it = _t.begin(); _break = false;} + mutable typename Type::value_type _var; + mutable typename Type::iterator _it; + mutable typename Type::reverse_iterator _rit; + Type & _t; + bool _inv; + inline bool isEnd() {if (_inv) return _rit == _t.rend(); else return _it == _t.end();} + inline void operator ++() {if (_inv) _rit++; else _it++; _break = false;} +}; + +template +class _PIForeachC: public _PIForeachBase { +public: + inline _PIForeachC(const Type & t, bool i = false): _t(t), _inv(i) {if (_inv) _rit = _t.rbegin(); else _it = _t.begin(); _break = false;} + mutable typename Type::value_type _var; + mutable typename Type::const_iterator _it; + mutable typename Type::const_reverse_iterator _rit; + const Type & _t; + bool _inv; + inline bool isEnd() {if (_inv) return _rit == _t.rend(); else return _it == _t.end();} + inline void operator ++() {if (_inv) _rit++; else _it++; _break = false;} +}; + +template inline _PIForeach _PIForeachNew(T & t, bool i = false) {return _PIForeach(t, i);} +template inline _PIForeach * _PIForeachCast(_PIForeachBase & c, T & ) {return static_cast<_PIForeach * >(&c);} + +template inline _PIForeachC _PIForeachNewC(const T & t, bool i = false) {return _PIForeachC(t, i);} +template inline _PIForeachC * _PIForeachCastC(_PIForeachBase & c, const T & ) {return static_cast<_PIForeachC * >(&c);} + +#define piForeach(i,c) for(_PIForeachBase & _for = _PIForeachNew(c); !_PIForeachCast(_for, c)->isEnd(); ++(*_PIForeachCast(_for, c))) \ + for(i = *(_PIForeachCast(_for, c)->_it); !_for._break; _for._break = true) +#define piForeachR(i,c) for(_PIForeachBase & _for = _PIForeachNew(c, true); !_PIForeachCast(_for, c)->isEnd(); ++(*_PIForeachCast(_for, c))) \ + for(i = *(_PIForeachCast(_for, c)->_rit); !_for._break; _for._break = true) +#define piForeachC(i,c) for(_PIForeachBase & _for = _PIForeachNewC(c); !_PIForeachCastC(_for, c)->isEnd(); ++(*_PIForeachCastC(_for, c))) \ + for(const i = *(_PIForeachCastC(_for, c)->_it); !_for._break; _for._break = true) +#define piForeachCR(i,c) for(_PIForeachBase & _for = _PIForeachNewC(c, false); !_PIForeachCastC(_for, c)->isEnd(); ++(*_PIForeachCastC(_for, c))) \ + for(const i = *(_PIForeachCastC(_for, c)->_rit); !_for._break; _for._break = true) + +#endif + +#define piForeachRC piForeachCR + +#define piForTimes(c) for(int i = 0; i < c; ++i) + template class PIFlags { public: @@ -102,6 +160,7 @@ public: inline _CVector & remove(const Type & t) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) {_stlc::erase(i); --i;} return *this;} inline _CVector & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;} inline _CVector & operator <<(const Type & t) {_stlc::push_back(t); return *this;} + inline _CVector & operator <<(const _CVector & t) {piForeachCA (i, t) _stlc::push_back(i); return *this;} inline bool contain(const Type & v) const {for (uint i = 0; i < _stlc::size(); ++i) if (v == at(i)) return true; return false;} }; diff --git a/piethernet.cpp b/piethernet.cpp index f2c8dcb4..490ed38d 100644 --- a/piethernet.cpp +++ b/piethernet.cpp @@ -50,7 +50,7 @@ void PIEthernet::terminate() { if (!receiverInitialized()) return; if (isRunning()) { stop(); - pthread_cancel(thread); + PIThread::terminate(); } tries = 0; /*if (sock != -1) { @@ -74,7 +74,7 @@ void PIEthernet::begin() { void PIEthernet::run() { #ifdef WINDOWS - int addr_len = sizeof(sockaddr_storage); + int addr_len = sizeof(sockaddr); #else socklen_t addr_len = sizeof(sockaddr_storage); #endif @@ -107,6 +107,7 @@ bool PIEthernet::init() { #endif sock = socket(PF_INET, SOCK_DGRAM, 0); if (bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) { + tries++; if (tries < 10) { if (init()) { tries = 0; @@ -128,6 +129,7 @@ bool PIEthernet::initSend() { #endif sock_s = socket(PF_INET, SOCK_DGRAM, 0); if (sock_s == -1) { + tries++; if (tries < 10) { if (init()) { tries = 0; diff --git a/piethernet.h b/piethernet.h index ac920d38..d0e12f7a 100644 --- a/piethernet.h +++ b/piethernet.h @@ -4,12 +4,17 @@ #include "pithread.h" #include "pistring.h" #ifndef WINDOWS -# include -# include -# include +#include +#include +#include #else -# include -# define SHUT_RDWR SD_BOTH +# ifdef CC_VC +#include +# define SHUT_RDWR 2 +# else +#include +# define SHUT_RDWR SD_BOTH +# endif #endif #define BUFFER_SIZE 4096 diff --git a/pievaluator.cpp b/pievaluator.cpp index 2f6206e2..1e61eb0e 100644 --- a/pievaluator.cpp +++ b/pievaluator.cpp @@ -1011,7 +1011,8 @@ inline bool PIEvaluator::execInstructions() { break; } } - out = value(instructions.back().out); + if (!instructions.isEmpty()) + out = value(instructions.back().out); return true; } diff --git a/pifile.cpp b/pifile.cpp index 64d009cf..41a5c76f 100644 --- a/pifile.cpp +++ b/pifile.cpp @@ -42,6 +42,7 @@ PIByteArray PIFile::readAll() { int PIFile::size() { + if (!stream.is_open()) return -1; int s, cp = stream.tellg(); stream.seekg(0, fstream::end); s = stream.tellg(); diff --git a/pifile.h b/pifile.h index c66ccd72..a3a53f97 100644 --- a/pifile.h +++ b/pifile.h @@ -44,7 +44,7 @@ public: int pos(); bool isOpened() {return stream.is_open();} bool isEnd() {return stream.eof();} - bool isEmpty() {return (size() == 0);} + bool isEmpty() {return (size() <= 0);} PIFile & writeData(const void * data, int size_) {stream.write((char * )data, size_); return *this;} PIFile & readData(void * data, int size_) {stream.read((char * )data, size_); return *this;} diff --git a/pigeometry.h b/pigeometry.h index 138d9ec0..0e33f6d4 100644 --- a/pigeometry.h +++ b/pigeometry.h @@ -12,27 +12,28 @@ public: PIPoint() {x = y = 0;}; PIPoint(Type x_, Type y_) {set(x_, y_);} - inline PIPoint & set(Type x_, Type y_) {x = x_; y = y_; return *this;} - inline PIPoint & move(Type x_, Type y_) {x += x_; y += y_; return *this;} - inline PIPoint & move(const PIPoint & p) {x += p.x; y += p.y; return *this;} - inline double angleRad() const {return atan2(y, x);} - inline int angleDeg() const {return round(atan2(y, x) * 180. / M_PI);} - inline PIPoint toPolar(bool isDeg = false) const {return PIPoint(sqrt(x*x + y*y), isDeg ? angleDeg() : angleRad());} - inline static PIPoint fromPolar(const PIPoint & p) {return PIPoint(p.y * cos(p.x), p.y * sin(p.x));} + PIPoint & set(Type x_, Type y_) {x = x_; y = y_; return *this;} + PIPoint & move(Type x_, Type y_) {x += x_; y += y_; return *this;} + PIPoint & move(const PIPoint & p) {x += p.x; y += p.y; return *this;} + double angleRad() const {return atan2(y, x);} + int angleDeg() const {return round(atan2(y, x) * 180. / M_PI);} + PIPoint toPolar(bool isDeg = false) const {return PIPoint(sqrt(x*x + y*y), isDeg ? angleDeg() : angleRad());} + static PIPoint fromPolar(const PIPoint & p) {return PIPoint(p.y * cos(p.x), p.y * sin(p.x));} + + PIPoint operator +(const PIPoint & p) {return PIPoint(x + p.x, y + p.y);} + PIPoint operator +(const Type & p) {return PIPoint(x + p, y + p);} + PIPoint operator -(const PIPoint & p) {return PIPoint(x - p.x, y - p.y);} + PIPoint operator -(const Type & p) {return PIPoint(x - p, y - p);} + PIPoint operator -() {return PIPoint(-x, -y);} + PIPoint operator *(const Type & d) {return PIPoint(x * d, y * d);} + PIPoint operator /(const Type & d) {return PIPoint(x / d, y / d);} + bool operator ==(const PIPoint & p) const {return (x == p.x && y == p.y);} + bool operator !=(const PIPoint & p) const {return (x != p.x || y != p.y);} - inline PIPoint operator +(const PIPoint & p) {return PIPoint(x + p.x, y + p.y);} - inline PIPoint operator +(const Type & p) {return PIPoint(x + p, y + p);} - inline PIPoint operator -(const PIPoint & p) {return PIPoint(x - p.x, y - p.y);} - inline PIPoint operator -(const Type & p) {return PIPoint(x - p, y - p);} - inline PIPoint operator -() {return PIPoint(-x, -y);} - inline PIPoint operator *(const Type & d) {return PIPoint(x * d, y * d);} - inline PIPoint operator /(const Type & d) {return PIPoint(x / d, y / d);} - inline bool operator ==(const PIPoint & p) const {return (x == p.x && y == p.y);} - inline bool operator !=(const PIPoint & p) const {return (x != p.x || y != p.y);} }; template -inline std::ostream & operator <<(std::ostream & s, const PIPoint & v) {s << '{' << v.x << ", " << v.y << '}'; return s;} +std::ostream & operator <<(std::ostream & s, const PIPoint & v) {s << '{' << v.x << ", " << v.y << '}'; return s;} template class PIRect { @@ -48,58 +49,61 @@ public: PIRect(const PIPoint & p0, const PIPoint & p1, const PIPoint & p2) {set(piMin(p0.x, p1.x, p2.x), piMin(p0.y, p1.y, p2.y), piMax(p0.x, p1.x, p2.x), piMax(p0.y, p1.y, p2.y));} - inline PIRect & set(Type x, Type y, Type w, Type h) {x0 = x; y0 = y; x1 = x + w; y1 = y + h; return *this;} - inline bool pointIn(Type x, Type y) const {return (x <= x1 && x >= x0 && y <= y1 && y >= y0);} - inline bool pointIn(const PIPoint & p) const {return pointIn(p.x, p.y);} - inline bool isEmpty() const {return (x1 - x0 == 0 && y1 - y0 == 0);} - inline PIRect & translate(Type x, Type y) {x0 += x; x1 += x; y0 += y; y1 += y; return *this;} - inline PIRect & translate(const PIPoint & p) {x0 += p.x; x1 += p.x; y0 += p.y; y1 += p.y; return *this;} - inline PIRect translated(Type x, Type y) {PIRect r(*this); r.translate(x, y); return r;} - inline PIRect translated(const PIPoint & p) {PIRect r(*this); r.translate(p); return r;} - inline PIRect & scale(Type x, Type y) {setWidth(width() * x); setHeight(height() * y); return *this;} - inline PIRect & scale(const PIPoint & p) {setWidth(width() * p.x); setHeight(height() * p.y); return *this;} - inline PIRect scaled(Type x, Type y) {PIRect r(*this); r.scale(x, y); return r;} - inline PIRect scaled(const PIPoint & p) {PIRect r(*this); r.scale(p); return r;} - inline PIRect & normalize() {if (x0 > x1) piSwap(x0, x1); if (y0 > y1) piSwap(y0, y1); return *this;} - inline PIRect normalized() {PIRect r(*this); r.normalize(); return r;} - inline PIRect & unite(const PIRect & r) {x0 = piMin(x0, r.x0); y0 = piMin(y0, r.y0); x1 = piMax(x1, r.x1); y1 = piMax(y1, r.y1); return *this;} - inline PIRect united(const PIRect & rect) {PIRect r(*this); r.unite(rect); return r;} - inline PIRect & intersect(const PIRect & r) {x0 = piMax(x0, r.x0); y0 = piMax(y0, r.y0); x1 = piMin(x1, r.x1); y1 = piMin(y1, r.y1); if (x0 > x1 || y0 > y1) x0 = x1 = y0 = y1 = Type(0); return *this;} - inline PIRect intersected(const PIRect & rect) {PIRect r(*this); r.intersect(rect); return r;} - inline Type top() const {return y0;} - inline Type left() const {return x0;} - inline Type right() const {return x1;} - inline Type bottom() const {return y1;} - inline Type width() const {return x1 - x0;} - inline Type height() const {return y1 - y0;} - inline PIPoint topLeft() {return PIPoint(x0, y0);} - inline PIPoint topRigth() {return PIPoint(x1, y0);} - inline PIPoint bottomLeft() {return PIPoint(x0, y1);} - inline PIPoint bottomRight() {return PIPoint(x1, y1);} - inline void setTop(Type v) {y0 = v;} - inline void setLeft(Type v) {x0 = v;} - inline void setRigth(Type v) {x1 = v;} - inline void setBottom(Type v) {y1 = v;} - inline void setWidth(Type v) {x1 = x0 + v;} - inline void setHeight(Type v) {y1 = y0 + v;} + PIRect & set(Type x, Type y, Type w, Type h) {x0 = x; y0 = y; x1 = x + w; y1 = y + h; return *this;} + bool pointIn(Type x, Type y) const {return (x <= x1 && x >= x0 && y <= y1 && y >= y0);} + bool pointIn(const PIPoint & p) const {return pointIn(p.x, p.y);} + bool isEmpty() const {return (x1 - x0 == 0 && y1 - y0 == 0);} + PIRect & translate(Type x, Type y) {x0 += x; x1 += x; y0 += y; y1 += y; return *this;} + PIRect & translate(const PIPoint & p) {x0 += p.x; x1 += p.x; y0 += p.y; y1 += p.y; return *this;} + PIRect translated(Type x, Type y) {PIRect r(*this); r.translate(x, y); return r;} + PIRect translated(const PIPoint & p) {PIRect r(*this); r.translate(p); return r;} + PIRect & scale(Type x, Type y) {setWidth(width() * x); setHeight(height() * y); return *this;} + PIRect & scale(const PIPoint & p) {setWidth(width() * p.x); setHeight(height() * p.y); return *this;} + PIRect scaled(Type x, Type y) {PIRect r(*this); r.scale(x, y); return r;} + PIRect scaled(const PIPoint & p) {PIRect r(*this); r.scale(p); return r;} + PIRect & normalize() {if (x0 > x1) piSwap(x0, x1); if (y0 > y1) piSwap(y0, y1); return *this;} + PIRect normalized() {PIRect r(*this); r.normalize(); return r;} + PIRect & unite(const PIRect & r) {x0 = piMin(x0, r.x0); y0 = piMin(y0, r.y0); x1 = piMax(x1, r.x1); y1 = piMax(y1, r.y1); return *this;} + PIRect united(const PIRect & rect) {PIRect r(*this); r.unite(rect); return r;} + PIRect & intersect(const PIRect & r) {x0 = piMax(x0, r.x0); y0 = piMax(y0, r.y0); x1 = piMin(x1, r.x1); y1 = piMin(y1, r.y1); if (x0 > x1 || y0 > y1) x0 = x1 = y0 = y1 = Type(0); return *this;} + PIRect intersected(const PIRect & rect) {PIRect r(*this); r.intersect(rect); return r;} + Type top() const {return y0;} + Type left() const {return x0;} + Type right() const {return x1;} + Type bottom() const {return y1;} + Type width() const {return x1 - x0;} + Type height() const {return y1 - y0;} + PIPoint topLeft() {return PIPoint(x0, y0);} + PIPoint topRigth() {return PIPoint(x1, y0);} + PIPoint bottomLeft() {return PIPoint(x0, y1);} + PIPoint bottomRight() {return PIPoint(x1, y1);} + void setTop(Type v) {y0 = v;} + void setLeft(Type v) {x0 = v;} + void setRigth(Type v) {x1 = v;} + void setBottom(Type v) {y1 = v;} + void setWidth(Type v) {x1 = x0 + v;} + void setHeight(Type v) {y1 = y0 + v;} + + PIRect operator -() {return PIRect(-x0, -y0, -width(), -height());} + void operator +=(Type x) {translate(x, x);} + void operator +=(const PIPoint & p) {translate(p);} + void operator -=(Type x) {translate(-x, -x);} + void operator -=(const PIPoint & p) {translate(-p);} + void operator *=(Type p) {x0 *= p; x1 *= p; y0 *= p; y1 *= p;} + void operator /=(Type p) {x0 /= p; x1 /= p; y0 /= p; y1 /= p;} + void operator |=(const PIRect & r) {unite(r);} + void operator &=(const PIRect & r) {intersect(r);} + PIRect operator +(const PIPoint & p) {return PIRect(*this).translated(p);} + PIRect operator -(const PIPoint & p) {return PIRect(*this).translated(-p);} + PIRect operator |(const PIRect & r) {return PIRect(*this).united(r);} + PIRect operator &(const PIRect & r) {return PIRect(*this).intersected(r);} + bool operator ==(const PIRect & r) const {return (x0 == r.x0 && y0 == r.y0 && x1 == r.x1 && y1 == r.y10);} + bool operator !=(const PIRect & r) const {return (x0 != r.x0 || y0 != r.y0 || x1 != r.x1 || y1 != r.y10);} - inline PIRect operator -() {return PIRect(-x0, -y0, -width(), -height());} - inline void operator +=(Type x) {translate(x, x);} - inline void operator +=(const PIPoint & p) {translate(p);} - inline void operator -=(Type x) {translate(-x, -x);} - inline void operator -=(const PIPoint & p) {translate(-p);} - inline void operator *=(Type p) {x0 *= p; x1 *= p; y0 *= p; y1 *= p;} - inline void operator /=(Type p) {x0 /= p; x1 /= p; y0 /= p; y1 /= p;} - inline void operator |=(const PIRect & r) {unite(r);} - inline void operator &=(const PIRect & r) {intersect(r);} - inline PIRect operator +(const PIPoint & p) {return PIRect(*this).translated(p);} - inline PIRect operator -(const PIPoint & p) {return PIRect(*this).translated(-p);} - inline PIRect operator |(const PIRect & r) {return PIRect(*this).united(r);} - inline PIRect operator &(const PIRect & r) {return PIRect(*this).intersected(r);} }; template -inline std::ostream & operator <<(std::ostream & s, const PIRect & v) {s << '{' << v.x0 << ", " << v.y0 << "; " << v.x1 - v.x0 << ", " << v.y1 - v.y0 << '}'; return s;} +std::ostream & operator <<(std::ostream & s, const PIRect & v) {s << '{' << v.x0 << ", " << v.y0 << "; " << v.x1 - v.x0 << ", " << v.y1 - v.y0 << '}'; return s;} typedef PIPoint PIPointi; typedef PIPoint PIPointu; diff --git a/piincludes.h b/piincludes.h index c0d39887..10f4f0d9 100644 --- a/piincludes.h +++ b/piincludes.h @@ -1,29 +1,44 @@ #ifndef PIINCLUDES_H #define PIINCLUDES_H -#if __WIN32__ || __WIN64__ +#if __WIN32__ || __WIN64__ || WIN32 || WIN64 # define WINDOWS #endif -#if __QNX__ +#if __QNX__ || __QNXNTO__ # define QNX #endif #ifndef WINDOWS -# ifndef QNX -# define LINUX -# endif +# ifndef QNX +# define LINUX +# endif +#endif +#if __GNUC__ +# define CC_GCC +#elif _MSC_VER +# define CC_VC +#endif + +#ifdef WINDOWS +# ifdef CC_GCC +# define typeof __typeof +# endif +#else +# define typeof __typeof__ #endif #include +#ifdef CC_GCC #include +#endif #include #include #ifndef QNX -# include -# include -# include +#include +#include +#include #else -# include -# include +#include +#include #endif #include #include @@ -40,11 +55,10 @@ #include #include #include - #ifdef WINDOWS -# include -# include -# include +#include +#include +#include #endif #define FOREVER for (;;) @@ -71,9 +85,9 @@ using std::set; using std::string; #ifndef QNX using std::wstring; -# ifndef WINDOWS +# ifndef WINDOWS static locale_t currentLocale_t = 0; -# endif +# endif #else typedef std::basic_string wstring; #endif @@ -103,43 +117,76 @@ public: static piInit __pi_init; static lconv * currentLocale = std::localeconv(); -inline const char * errorString() {return strerror(errno);} + +#ifdef CC_VC +inline string errorString() {char buff[1024]; strerror_s(buff, 1024, GetLastError()); return string(buff);} +#else +inline string errorString() {return string(strerror(errno));} +#endif #ifdef WINDOWS inline int random() {return rand();} +# ifdef CC_VC +inline double round(const double & v) {return floor(v + 0.5);} +# endif #endif template inline void piSwap(Type & f, Type & s) {Type t = f; f = s; s = t;} template inline Type piMin(const Type & f, const Type & s) {return (f > s) ? s : f;} -template inline Type piMax(const Type & f, const Type & s) {return (f < s) ? s : f;} template inline Type piMin(const Type & f, const Type & s, const Type & t) {return (f < s && f < t) ? f : ((s < t) ? s : t);} +template inline Type piMax(const Type & f, const Type & s) {return (f < s) ? s : f;} template inline Type piMax(const Type & f, const Type & s, const Type & t) {return (f > s && f > t) ? f : ((s > t) ? s : t);} +template inline Type piClamp(const Type & v, const Type & min, const Type & max) {return (v > max ? max : (v < min ? min : v));} inline ushort letobe_s(ushort v) {return v = (v << 8) | (v >> 8);} inline bool atob(const string & str) { return str == "1" ? true : false;}; inline string btos(const bool num) { return num ? "0" : "1";}; inline string itos(const int num) { char ch[256]; +#ifndef CC_VC sprintf(ch, "%d", num); +#else + sprintf_s(ch, 256, "%d", num); +#endif return string(ch); }; inline string ltos(const long num) { char ch[256]; +#ifndef CC_VC sprintf(ch, "%ld", num); +#else + sprintf_s(ch, 256, "%ld", num); +#endif return string(ch); }; inline string uitos(const uint num) { char ch[256]; +#ifndef CC_VC sprintf(ch, "%ud", num); +#else + sprintf_s(ch, 256, "%ud", num); +#endif return string(ch); }; inline string ultos(const ulong num) { char ch[256]; +#ifndef CC_VC sprintf(ch, "%lud", num); +#else + sprintf_s(ch, 256, "%lud", num); +#endif return string(ch); }; inline string ftos(const float num) { char ch[256]; +#ifndef CC_VC sprintf(ch, "%g", num); +#else + sprintf_s(ch, 256, "%g", num); +#endif return string(ch); }; inline string dtos(const double num) { char ch[256]; +#ifndef CC_VC sprintf(ch, "%g", num); +#else + sprintf_s(ch, 256, "%g", num); +#endif return string(ch); }; #endif // PIINCLUDES_H diff --git a/pikbdlistener.cpp b/pikbdlistener.cpp index cf7bafbc..ccd9e73d 100644 --- a/pikbdlistener.cpp +++ b/pikbdlistener.cpp @@ -4,7 +4,7 @@ bool PIKbdListener::exiting; PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() { -#ifdef __WIN32__ +#ifdef WINDOWS hIn = GetStdHandle(STD_INPUT_HANDLE); GetConsoleMode(hIn, &smode); #else @@ -22,35 +22,55 @@ PIKbdListener::PIKbdListener(KBFunc slot, void * data_): PIThread() { void PIKbdListener::begin() { //cout << "list begin" << endl; -#ifdef __WIN32__ +#ifdef WINDOWS hIn = GetStdHandle(STD_INPUT_HANDLE); GetConsoleMode(hIn, &smode); + tmode = smode; SetConsoleMode(hIn, ENABLE_PROCESSED_INPUT); #else struct termios term; tcgetattr(0, &term); term.c_lflag &= ~(ECHO | ICANON) | NOFLSH; + tterm = term; tcsetattr(0, TCSAFLUSH, &term); #endif } void PIKbdListener::run() { -#ifdef __WIN32__ +#ifdef WINDOWS ReadConsole(hIn, &rc, 1, &ret, 0); #else ret = read(0, &rc, 1); #endif if (exit_enabled && rc == exit_key) PIKbdListener::exiting = true; - if (ret_func != 0 && ret > 0 && is_active) ret_func(rc, data); + if (ret_func != 0 && ret > 0) ret_func(rc, data); } void PIKbdListener::end() { //cout << "list end" << endl; -#ifdef __WIN32__ +#ifdef WINDOWS SetConsoleMode(hIn, smode); #else tcsetattr(0, TCSANOW, &sterm); #endif } + + +void PIKbdListener::setActive(bool yes) { + is_active = yes; + if (is_active) { +#ifdef WINDOWS + SetConsoleMode(hIn, tmode); +#else + tcsetattr(0, TCSANOW, &tterm); +#endif + } else { +#ifdef WINDOWS + SetConsoleMode(hIn, smode); +#else + tcsetattr(0, TCSANOW, &sterm); +#endif + } +} diff --git a/pikbdlistener.h b/pikbdlistener.h index 59dfe1d3..e5b566ce 100644 --- a/pikbdlistener.h +++ b/pikbdlistener.h @@ -2,8 +2,8 @@ #define PIKBDLISTENER_H #include "pithread.h" -#ifndef __WIN32__ -# include +#ifndef WINDOWS +#include #endif #define WAIT_FOR_EXIT while (!PIKbdListener::exiting) msleep(1); @@ -17,12 +17,12 @@ public: PIKbdListener(KBFunc slot = 0, void * data = 0); ~PIKbdListener() {terminate(); end();} - inline void enableExitCapture(char key = 'Q') {exit_enabled = true; exit_key = key;} - inline void disableExitCapture() {exit_enabled = false;} - inline bool exitCaptured() const {return exit_enabled;} - inline char exitKey() const {return exit_key;} - inline bool isActive() {return is_active;} - inline void setActive(bool yes = true) {is_active = yes;} + void enableExitCapture(char key = 'Q') {exit_enabled = true; exit_key = key;} + void disableExitCapture() {exit_enabled = false;} + bool exitCaptured() const {return exit_enabled;} + char exitKey() const {return exit_key;} + bool isActive() {return is_active;} + void setActive(bool yes = true); static bool exiting; @@ -35,13 +35,13 @@ private: char rc, exit_key, is_active; bool exit_enabled; void * data; -#ifdef __WIN32__ +#ifdef WINDOWS DWORD ret; void * hIn; - DWORD smode; + DWORD smode, tmode; #else int ret; - struct termios sterm; + struct termios sterm, tterm; #endif }; diff --git a/pimath.h b/pimath.h index 57a6769f..d8dd26d6 100644 --- a/pimath.h +++ b/pimath.h @@ -9,6 +9,9 @@ # include # include #endif +#ifdef CC_VC +#define M_PI 3.14159265358979323846 +#endif #define M_2PI 6.28318530717958647692 #define M_PI_3 1.04719755119659774615 @@ -693,7 +696,7 @@ public: void solveABM3(double u, double h); void solveABM4(double u, double h); void solvePA(double u, double h, uint deg); - inline void solvePA2(double u, double h) {if (step > 0) solvePA(u, h, 2); else solvePA(u, h, 1);} + inline void solvePA2(double u, double h) {if (step > 0) solvePA(u, h, 2); else solveEyler1(u, h);} inline void solvePA3(double u, double h) {if (step > 1) solvePA(u, h, 3); else solvePA2(u, h);} inline void solvePA4(double u, double h) {if (step > 2) solvePA(u, h, 4); else solvePA3(u, h);} inline void solvePA5(double u, double h) {if (step > 3) solvePA(u, h, 5); else solvePA4(u, h);} diff --git a/pimultiprotocol.h b/pimultiprotocol.h new file mode 100644 index 00000000..1c0876d0 --- /dev/null +++ b/pimultiprotocol.h @@ -0,0 +1,78 @@ +#ifndef PIMULTIPROTOCOL_H +#define PIMULTIPROTOCOL_H + +#include "piprotocol.h" + +class PIMultiProtocol: public PIMultiProtocolBase +{ +public: + PIMultiProtocol() {;} + virtual ~PIMultiProtocol() {clear();} + + void addProtocol(PIProtocol & prot) {prots.push_back(&prot); prot.setMultiProtocolOwner(this); prot.new_mp_prot = false;} + void addProtocol(PIProtocol * prot) {prots.push_back(prot); prot->setMultiProtocolOwner(this); prot->new_mp_prot = false;} + void addProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0, + void * recDataPtr = 0, int recDataSize = 0, void * sendDataPtr = 0, int sendDataSize = 0) {; + prots.push_back(new PIProtocol(config, name, recHeaderPtr, recHeaderSize, recDataPtr, recDataSize, sendDataPtr, sendDataSize)); + prots.back()->setMultiProtocolOwner(this); + prots.back()->new_mp_prot = true; + } + PIProtocol * protocol(const PIString & name) {piForeach (PIProtocol * i, prots) if (i->name() == name) return i; return 0;} + PIProtocol * protocol(const int index) {return prots[index];} + PIProtocol * operator [](const int index) {return prots[index];} + + void startSend() {piForeach (PIProtocol * i, prots) i->startSend();} + void startReceive() {piForeach (PIProtocol * i, prots) i->startReceive();} + void start() {piForeach (PIProtocol * i, prots) i->start();} + + void stopSend() {piForeach (PIProtocol * i, prots) i->stopSend();} + void stopReceive() {piForeach (PIProtocol * i, prots) i->stopReceive();} + void stop() {piForeach (PIProtocol * i, prots) i->stop();} + + PIProtocol::Quality worseQuality() const {PIProtocol::Quality cq = PIProtocol::Good; piForeachC (PIProtocol * i, prots) if (cq > i->quality()) cq = i->quality(); return cq;} + PIProtocol::Quality bestQuality() const {PIProtocol::Quality cq = PIProtocol::Unknown; piForeachC (PIProtocol * i, prots) if (cq < i->quality()) cq = i->quality(); return cq;} + + int count() const {return prots.size_s();} + void clear() {stop(); piForeach (PIProtocol * i, prots) if (i->new_mp_prot) delete i; prots.clear();} + +private: + PIVector prots; + +}; + +class PIRepeater: public PIMultiProtocol { +public: + PIRepeater(const PIString & config, const PIString & name, int data_size) { + ba_f.resize(data_size); + ba_s.resize(data_size); + PIConfig conf(config, PIFile::Read); + if (!conf.isOpened()) { + cout << "[PIRepeater \"" << name << "\"] Can`t open \"" << config << "\"!" << endl; + return; + } + PIConfig::Entry b = conf.getValue(name); + if (b.childCount() != 2) { + cout << "[PIRepeater \"" << name << "\"] \"" << config << "\" should consist 2 nodes!" << endl; + return; + } + addProtocol(config, b.child(0)->fullName(), 0, 0, ba_f.data(), data_size, ba_s.data(), data_size); + addProtocol(config, b.child(1)->fullName(), 0, 0, ba_s.data(), data_size, ba_f.data(), data_size); + start(); + } + + PIString firstChannelName() {if (count() == 2) return protocol(0)->receiverDeviceName() + " -> " + protocol(1)->senderDeviceName(); return "Config error";} + PIString secondChannelName() {if (count() == 2) return protocol(1)->receiverDeviceName() + " -> " + protocol(0)->senderDeviceName(); return "Config error";} + + ullong receiveCount() {if (count() == 2) return protocol(0)->receiveCount(); return 0;} + ullong * receiveCount_ptr() {if (count() == 2) return protocol(0)->receiveCount_ptr(); return 0;} + ullong sendCount() {if (count() == 2) return protocol(0)->sendCount(); return 0;} + ullong * sendCount_ptr() {if (count() == 2) return protocol(0)->sendCount_ptr(); return 0;} + +private: + void received(PIProtocol * prot, bool , char * , int ) {if (prot == protocol(0)) protocol(1)->send(); else protocol(0)->send();} + + PIByteArray ba_f, ba_s; + +}; + +#endif // PIMULTIPROTOCOL_H diff --git a/pimutex.h b/pimutex.h index e6f63c2a..05111ddc 100644 --- a/pimutex.h +++ b/pimutex.h @@ -1,27 +1,42 @@ #ifndef PIMUTEX_H #define PIMUTEX_H -#include +#ifdef CC_GCC +#include +#endif #include "piincludes.h" class PIMutex { public: +#ifndef WINDOWS PIMutex() { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_PROCESS_SHARED); - //pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); pthread_mutex_init(&mutex, &attr); pthread_mutexattr_destroy(&attr); } ~PIMutex() {pthread_mutex_destroy(&mutex);} + void lock() {pthread_mutex_lock(&mutex);} void unlock() {pthread_mutex_unlock(&mutex);} bool tryLock() {return (pthread_mutex_trylock(&mutex) == 0);} +#else + PIMutex() {mutex = CreateMutex(0, false, 0);} + ~PIMutex() {CloseHandle(mutex);} + + void lock() {WaitForSingleObject(mutex, INFINITE);} + void unlock() {ReleaseMutex(mutex);} + bool tryLock() {return (WaitForSingleObject(mutex, 0) == WAIT_OBJECT_0);} +#endif private: +#ifndef WINDOWS pthread_mutex_t mutex; +#else + void * mutex; +#endif }; diff --git a/pip.h b/pip.h index afb03fb8..72fd39a9 100644 --- a/pip.h +++ b/pip.h @@ -3,5 +3,6 @@ #include "piconsole.h" #include "picli.h" #include "pievaluator.h" -#include "piprotocol.h" +#include "pimultiprotocol.h" #include "picodec.h" +#include "pisignals.h" diff --git a/piprocess.cpp b/piprocess.cpp index 8ac7f2cd..ca3509c8 100644 --- a/piprocess.cpp +++ b/piprocess.cpp @@ -1,124 +1,173 @@ -#include "piprocess.h" - - -PIProcess::PIProcess(): PIThread() { - exit_code = -1; - pid = 0; - is_exec = false; - g_in = g_out = g_err = false; - t_in = t_out = t_err = false; - env = PIProcess::currentEnvironment(); -} - - -PIProcess::~PIProcess() { - if (t_in) f_in.remove(); - if (t_out) f_out.remove(); - if (t_err) f_err.remove(); -} - - -void PIProcess::exec_() { - is_exec = false; - startOnce(); - //cout << "exec wait" << endl; - while (!is_exec) - msleep(1); - //cout << "exec end" << endl; -} - - -void PIProcess::run() { - //cout << "run" << endl; - string str; - /// arguments convertion - char * a[args.size_s() + 1]; - for (int i = 0; i < args.size_s(); ++i) { - str = args[i].stdString(); - a[i] = new char[str.size() + 1]; - memcpy(a[i], str.c_str(), str.size()); - a[i][str.size()] = 0; - //cout << a[i] << endl; - } - a[args.size_s()] = 0; - /// environment convertion - char * e[env.size_s() + 1]; - for (int i = 0; i < env.size_s(); ++i) { - str = env[i].stdString(); - e[i] = new char[str.size() + 1]; - memcpy(e[i], str.c_str(), str.size()); - e[i][str.size()] = 0; - //cout << e[i] << endl; - } - e[env.size_s()] = 0; - /// files for stdin/out/err - t_in = t_out = t_err = false; - if (f_in.path().isEmpty()) { - f_in = PIFile::openTemporary(PIFile::New | PIFile::Read); - t_in = true; - } - f_in.open(PIFile::New | PIFile::Read); f_in.close(); - if (f_out.path().isEmpty()) { - f_out = PIFile::openTemporary(PIFile::New | PIFile::Write); - t_out = true; - } - f_out.open(PIFile::New | PIFile::Write); f_out.close(); - if (f_err.path().isEmpty()) { - f_err = PIFile::openTemporary(PIFile::New | PIFile::Write); - t_err = true; - } - f_err.open(PIFile::New | PIFile::Write); f_err.close(); - - str = args.front().stdString(); - is_exec = true; - pid = fork(); - if (pid == 0) { - FILE * tf; - //cout << "exec" << endl; - //cout << f_out.path() << endl; - if (g_in) tf = freopen(f_in.path().data(), "r", stdin); - if (g_out) tf = freopen(f_out.path().data(), "w", stdout); - if (g_err) tf = freopen(f_err.path().data(), "w", stderr); - if (!wd.isEmpty()) system(("cd " + wd).data()); - if (execvpe(str.c_str(), a, e) < 0) - cout << "[PIProcess] \"execvpe\" error, " << errorString() << endl; - } else { - msleep(1); - //cout << "wait" << endl; - wait(&exit_code); - pid = 0; - //cout << "wait done" << endl; - } - is_exec = false; - for (int i = 0; i < env.size_s(); ++i) - delete e[i]; - for (int i = 0; i < args.size_s(); ++i) - delete a[i]; - //cout << "end" << endl; -} - - -void PIProcess::removeEnvironmentVariable(const PIString & variable) { - PIString s; - for (int i = 0; i < env.size_s(); ++i) { - s = env[i]; - if (s.left(s.find("=")).trimmed() == variable) { - env.remove(i); - --i; - } - } -} - - -void PIProcess::setEnvironmentVariable(const PIString & variable, const PIString & value) { - PIString s, v; - for (int i = 0; i < env.size_s(); ++i) { - s = env[i]; - v = s.left(s.find("=")).trimmed(); - if (v == variable) { - env[i] = v + "=" + value; - return; - } - } - env << variable + "=" + value; -} +#include "piprocess.h" + + +PIProcess::PIProcess(): PIThread() { + exit_code = -1; +#ifdef WINDOWS + pi.dwProcessId = 0; +#else + pid = 0; +#endif + is_exec = false; + g_in = g_out = g_err = false; + t_in = t_out = t_err = false; + env = PIProcess::currentEnvironment(); +} + + +PIProcess::~PIProcess() { + if (t_in) f_in.remove(); + if (t_out) f_out.remove(); + if (t_err) f_err.remove(); +} + + +void PIProcess::exec_() { + is_exec = false; + startOnce(); + //cout << "exec wait" << endl; + while (!is_exec) + msleep(1); + //cout << "exec end" << endl; +} + + +void PIProcess::run() { + //cout << "run" << endl; + string str; + /// arguments convertion + int as = 0; +#ifdef WINDOWS + //args.pop_front(); + piForeachC (PIString & i, args) + as += i.stdString().length() + 1; + char * a = new char[as]; + memset(a, ' ', as - 1); + as = 0; + for (int i = 0; i < args.size_s(); ++i) { + str = args[i].stdString(); + memcpy(&a[as], str.c_str(), str.size()); + as += str.length() + 1; + } + a[as - 1] = 0; +#else + char * a[args.size_s() + 1]; + for (int i = 0; i < args.size_s(); ++i) { + str = args[i].stdString(); + a[i] = new char[str.size() + 1]; + memcpy(a[i], str.c_str(), str.size()); + a[i][str.size()] = 0; + //cout << a[i] << endl; + } + a[args.size_s()] = 0; +#endif + /// environment convertion + char ** e = new char*[env.size_s() + 1]; + for (int i = 0; i < env.size_s(); ++i) { + str = env[i].stdString(); + e[i] = new char[str.size() + 1]; + memcpy(e[i], str.c_str(), str.size()); + e[i][str.size()] = 0; + //cout << e[i] << endl; + } + e[env.size_s()] = 0; + /// files for stdin/out/err + t_in = t_out = t_err = false; + if (f_in.path().isEmpty()) { + f_in = PIFile::openTemporary(PIFile::New | PIFile::Read); + t_in = true; + } + f_in.open(PIFile::New | PIFile::Read); f_in.close(); + if (f_out.path().isEmpty()) { + f_out = PIFile::openTemporary(PIFile::New | PIFile::Write); + t_out = true; + } + f_out.open(PIFile::New | PIFile::Write); f_out.close(); + if (f_err.path().isEmpty()) { + f_err = PIFile::openTemporary(PIFile::New | PIFile::Write); + t_err = true; + } + f_err.open(PIFile::New | PIFile::Write); f_err.close(); + + str = args.front().stdString(); + is_exec = true; +#ifndef WINDOWS + pid = fork(); + if (pid == 0) { +#endif + FILE * tf; + //cout << "exec" << endl; + //cout << f_out.path() << endl; + if (g_in) tf = freopen(f_in.path().data(), "r", stdin); + if (g_out) tf = freopen(f_out.path().data(), "w", stdout); + if (g_err) tf = freopen(f_err.path().data(), "w", stderr); +#ifndef WINDOWS + if (!wd.isEmpty()) as = chdir(wd.data()); +#endif +#ifdef WINDOWS + GetStartupInfoA(&si); + memset(&pi, 0, sizeof(pi)); + if(CreateProcessA(0, // No module name (use command line) + a, // Command line + 0, // Process handle not inheritable + 0, // Thread handle not inheritable + false, // Set handle inheritance to FALSE + 0, // No creation flags + 0,//e, // Use environment + wd.isEmpty() ? 0 : wd.data(), // Use working directory + &si, // Pointer to STARTUPINFO structure + &pi)) // Pointer to PROCESS_INFORMATION structure + { + WaitForSingleObject(pi.hProcess, INFINITE); + CloseHandle(pi.hProcess); + } else + cout << "[PIProcess] \"CreateProcess\" error, " << errorString() << endl; +#else + if (execvpe(str.c_str(), a, e) < 0) + cout << "[PIProcess] \"execvpe\" error, " << errorString() << endl; + } else { + msleep(1); + //cout << "wait" << endl; + wait(&exit_code); + pid = 0; + //cout << "wait done" << endl; + } +#endif + is_exec = false; + for (int i = 0; i < env.size_s(); ++i) + delete e[i]; + delete e; +#ifdef WINDOWS + delete a; +#else + for (int i = 0; i < args.size_s(); ++i) + delete a[i]; +#endif + //cout << "end" << endl; +} + + +void PIProcess::removeEnvironmentVariable(const PIString & variable) { + PIString s; + for (int i = 0; i < env.size_s(); ++i) { + s = env[i]; + if (s.left(s.find("=")).trimmed() == variable) { + env.remove(i); + --i; + } + } +} + + +void PIProcess::setEnvironmentVariable(const PIString & variable, const PIString & value) { + PIString s, v; + for (int i = 0; i < env.size_s(); ++i) { + s = env[i]; + v = s.left(s.find("=")).trimmed(); + if (v == variable) { + env[i] = v + "=" + value; + return; + } + } + env << variable + "=" + value; +} diff --git a/piprocess.h b/piprocess.h index 5f6cac31..3cb728cb 100644 --- a/piprocess.h +++ b/piprocess.h @@ -1,62 +1,77 @@ -#ifndef PIPROCESS_H -#define PIPROCESS_H - -#include "pithread.h" -#include "pifile.h" -#include - -/// TODO workind dir - -class PIProcess: private PIThread -{ -public: - PIProcess(); - ~PIProcess(); - - int exitCode() const {return exit_code;} - int pID() const {return pid;} - - void setGrabInput(bool yes) {g_in = yes;} - void setGrabOutput(bool yes) {g_out = yes;} - void setGrabError(bool yes) {g_err = yes;} - void setInputFile(const PIString & path) {f_in.setPath(path);} - void setOutputFile(const PIString & path) {f_out.setPath(path);} - void setErrorFile(const PIString & path) {f_err.setPath(path);} - void unsetInputFile() {f_in.setPath("");} - void unsetOutputFile() {f_out.setPath("");} - void unsetErrorFile() {f_err.setPath("");} - void setWorkingDirectory(const PIString & path) {wd = path;} - void resetWorkingDirectory() {wd.clear();} - void exec(const PIString & program) {args.clear(); args << program; exec_();} - void exec(const PIString & program, const PIString & arg) {args.clear(); args << program << arg; exec_();} - void exec(const PIString & program, const PIString & arg1, const PIString & arg2) {args.clear(); args << program << arg1 << arg2; exec_();} - void exec(const PIString & program, const PIString & arg1, const PIString & arg2, const PIString & arg3) {args.clear(); args << program << arg1 << arg2 << arg3; exec_();} - void exec(const PIString & program, const PIStringList & args_) {args = args_; exec_();} - void terminate() {if (is_exec) ::kill(pid, SIGKILL); pid = 0;} - bool waitForFinish(int timeout_msecs = 60000) {return PIThread::waitForFinish(timeout_msecs);} - PIByteArray readOutput() {f_out.open(PIFile::Read); return f_out.readAll();} - PIByteArray readError() {f_err.open(PIFile::Read); return f_err.readAll();} - - PIStringList environment() {return env;} - void clearEnvironment() {env.clear();} - void removeEnvironmentVariable(const PIString & variable); - void setEnvironmentVariable(const PIString & variable, const PIString & value); - - static PIStringList currentEnvironment() {PIStringList l; int i = 0; while (environ[i] != 0) {l << environ[i]; ++i;} return l;} - -private: - virtual void run(); - void exec_(); - - PIStringList args, env; - PIString wd; - PIByteArray out; - PIFile f_in, f_out, f_err; - bool g_in, g_out, g_err, t_in, t_out, t_err; - pid_t pid; - int exit_code, sz; - bool is_exec; - -}; - -#endif // PIPROCESS_H +#ifndef PIPROCESS_H +#define PIPROCESS_H + +#include "pithread.h" +#include "pifile.h" +#ifdef WINDOWS +//# include <.h> +#else +# include +#endif + +class PIProcess: private PIThread +{ +public: + PIProcess(); + ~PIProcess(); + + int exitCode() const {return exit_code;} +#ifdef WINDOWS + int pID() const {return pi.dwProcessId;} +#else + int pID() const {return pid;} +#endif + + void setGrabInput(bool yes) {g_in = yes;} + void setGrabOutput(bool yes) {g_out = yes;} + void setGrabError(bool yes) {g_err = yes;} + void setInputFile(const PIString & path) {f_in.setPath(path);} + void setOutputFile(const PIString & path) {f_out.setPath(path);} + void setErrorFile(const PIString & path) {f_err.setPath(path);} + void unsetInputFile() {f_in.setPath("");} + void unsetOutputFile() {f_out.setPath("");} + void unsetErrorFile() {f_err.setPath("");} + void setWorkingDirectory(const PIString & path) {wd = path;} + void resetWorkingDirectory() {wd.clear();} + void exec(const PIString & program) {args.clear(); args << program; exec_();} + void exec(const PIString & program, const PIString & arg) {args.clear(); args << program << arg; exec_();} + void exec(const PIString & program, const PIString & arg1, const PIString & arg2) {args.clear(); args << program << arg1 << arg2; exec_();} + void exec(const PIString & program, const PIString & arg1, const PIString & arg2, const PIString & arg3) {args.clear(); args << program << arg1 << arg2 << arg3; exec_();} + void exec(const PIString & program, const PIStringList & args_) {args = args_; exec_();} +#ifdef WINDOWS + void terminate() {if (is_exec) if (!TerminateProcess(pi.hProcess, 0)) return; pi.dwProcessId = 0;} +#else + void terminate() {if (is_exec) kill(pid, SIGKILL); pid = 0;} +#endif + bool waitForFinish(int timeout_msecs = 60000) {return PIThread::waitForFinish(timeout_msecs);} + PIByteArray readOutput() {f_out.open(PIFile::Read); return f_out.readAll();} + PIByteArray readError() {f_err.open(PIFile::Read); return f_err.readAll();} + + PIStringList environment() {return env;} + void clearEnvironment() {env.clear();} + void removeEnvironmentVariable(const PIString & variable); + void setEnvironmentVariable(const PIString & variable, const PIString & value); + + static PIStringList currentEnvironment() {PIStringList l; int i = 0; while (environ[i] != 0) {l << environ[i]; ++i;} return l;} + +private: + virtual void run(); + void exec_(); + + PIStringList args, env; + PIString wd; + PIByteArray out; + PIFile f_in, f_out, f_err; + bool g_in, g_out, g_err, t_in, t_out, t_err; +#ifdef WINDOWS + STARTUPINFOA si; + PROCESS_INFORMATION pi; +#else + pid_t pid; +#endif + int exit_code, sz; + bool is_exec; + +}; + +#endif // PIPROCESS_H diff --git a/piprotocol.cpp b/piprotocol.cpp index 2d3447b9..6e1ad2e3 100644 --- a/piprotocol.cpp +++ b/piprotocol.cpp @@ -3,6 +3,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr, int recHeaderSize, void * recDataPtr, int recDataSize, void * sendDataPtr_, int sendDataSize_) { init(); + protName = name; PIConfig conf(config, PIFile::Read); if (!conf.isOpened()) { cout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl; @@ -27,14 +28,13 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok) { ps = rb.getValue("port", 0, &ok); if (!ok) { - type_rec = PIProtocol::None; cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".receiver.port\" in \"" << config << "\"!" << endl; devReceiverState = "Config error"; return; } type_rec = PIProtocol::Ethernet; eth = new PIEthernet(dev, ps, this, receiveEvent); - devReceiverName = dev + ":" + PIString::fromNumber(ps); + setReceiverAddress(dev, ps); } dev = rb.getValue("device", "", &ok); if (ok) { @@ -47,12 +47,15 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (rb.getValue("parity", false)) pp |= PISerial::ParityControl; if (rb.getValue("twoStopBits", false)) pp |= PISerial::TwoStopBits; type_rec = PIProtocol::Serial; + type_send = PIProtocol::Serial; ser = new PISerial(dev, this, receiveEvent); + setReceiverDevice(dev, (PISerial::Speed)ps); + setSenderDevice(dev, (PISerial::Speed)ps); ser->setInSpeed((PISerial::Speed)ps); ser->setParameters(pp); ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize); - devReceiverName = dev; } + setExpectedFrequency(rb.getValue("frequency", -1.f)); /// sender section if (sb.isEntryExists("ip") && sb.isEntryExists("device")) { @@ -64,7 +67,6 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (ok) { ps = sb.getValue("port", 0, &ok); if (!ok) { - type_send = PIProtocol::None; cout << "[PIProtocol \"" << name << "\"] Can`t find \"" << name << ".sender.port\" in \"" << config << "\"!" << endl; devSenderState = "Config error"; return; @@ -72,7 +74,6 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re type_send = PIProtocol::Ethernet; if (eth == 0) eth = new PIEthernet(dev, ps, this, receiveEvent); setSenderAddress(dev, ps); - devSenderName = dev + ":" + PIString::fromNumber(ps); } dev = sb.getValue("device", "", &ok); if (ok) { @@ -86,16 +87,13 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re if (sb.getValue("twoStopBits", false)) pp |= PISerial::TwoStopBits; type_send = PIProtocol::Serial; if (ser == 0) ser = new PISerial(dev, this, receiveEvent); + setSenderDevice(dev, (PISerial::Speed)ps); ser->setOutSpeed((PISerial::Speed)ps); ser->setParameters(pp); ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize); - devSenderName = dev; } + setSenderFrequency(sb.getValue("frequency", -1.f)); - float fr = rb.getValue("frequency", 0.f, &ok); - if (ok) setExpectedFrequency(fr); - fr = sb.getValue("frequency", 0.f, &ok); - if (ok) setSenderFrequency(fr); headerPtr = (uchar * )recHeaderPtr; headerSize = recHeaderSize; dataPtr = (uchar * )recDataPtr; @@ -113,6 +111,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re PIProtocol::~PIProtocol() { + //cout << "prot " << protName << " delete\n"; delete diagTimer; delete sendTimer; if (packet != 0) delete packet; @@ -122,8 +121,9 @@ PIProtocol::~PIProtocol() { void PIProtocol::init() { - work = false; + work = new_mp_prot = false; ret_func = 0; + mp_owner = 0; net_diag = PIProtocol::Unknown; cur_pckt = 0; diagTimer = 0; @@ -131,19 +131,23 @@ void PIProtocol::init() { sendTimer = new PITimer(sendEvent, this); diagTimer = new PITimer(diagEvent, this); wrong_count = receive_count = send_count = 0; - send_freq = -1.f; - immediateFreq = integralFreq = exp_freq = 0.f; + immediateFreq = integralFreq = 0.f; headerPtr = dataPtr = sendDataPtr = 0; headerSize = dataSize = sendDataSize = 0; eth = 0; ser = 0; type_rec = type_send = PIProtocol::None; devSenderState = devReceiverState = "Unknown"; + devSenderName = devReceiverName = "no device"; } -void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed speed) { - if (type_rec == PIProtocol::Serial) { +void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force) { + if (force) { + type_rec = PIProtocol::Serial; + if (ser == 0) ser = new PISerial("", this, receiveEvent); + } + if (type_rec == PIProtocol::Serial && ser != 0) { ser->setDevice(device); ser->setSpeed(speed); devReceiverName = device; @@ -151,16 +155,25 @@ void PIProtocol::setReceiverDevice(const PIString & device, PISerial::Speed spee } -void PIProtocol::setReceiverDevice(const PIString & ip, int port) { - if (type_rec == PIProtocol::Ethernet) { +void PIProtocol::setReceiverAddress(const PIString & ip, int port, bool force) { + if (force) { + type_rec = PIProtocol::Ethernet; + if (eth == 0) eth = new PIEthernet("", 0, this, receiveEvent); + } + if (type_rec == PIProtocol::Ethernet && eth != 0) { eth->setReadAddress(ip, port); - devReceiverName = ip + ":" + PIString::fromNumber(port); + if (ip.trimmed().isEmpty()) devReceiverName = "no ip"; + else devReceiverName = ip + ":" + PIString::fromNumber(port); } } -void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed) { - if (type_send == PIProtocol::Serial) { +void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed, bool force) { + if (force) { + type_send = PIProtocol::Serial; + if (ser == 0) ser = new PISerial("", this, receiveEvent); + } + if (type_send == PIProtocol::Serial && ser != 0) { ser->setDevice(device); ser->setSpeed(speed); devSenderName = device; @@ -168,10 +181,15 @@ void PIProtocol::setSenderDevice(const PIString & device, PISerial::Speed speed) } -void PIProtocol::setSenderDevice(const PIString & ip, int port) { - if (type_send == PIProtocol::Ethernet) { - eth->setReadAddress(ip, port); - devSenderName = ip + ":" + PIString::fromNumber(port); +void PIProtocol::setSenderAddress(const PIString & ip, int port, bool force) { + if (force) { + type_send = PIProtocol::Ethernet; + if (eth == 0) eth = new PIEthernet("", 0, this, receiveEvent); + } + if (type_send == PIProtocol::Ethernet && eth != 0) { + eth->setSendAddress(ip, port); + if (ip.isEmpty()) devSenderName = "no ip"; + else devSenderName = ip + ":" + PIString::fromNumber(port); } } @@ -220,10 +238,12 @@ bool PIProtocol::receiveEvent(void * t, char * data, int size) { p->receive_count++; p->cur_pckt = 1; if (p->ret_func != 0) p->ret_func(p); + if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, true, data, size); return true; } //p->unlock(); p->wrong_count++; + if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, false, data, size); return false; } @@ -247,7 +267,7 @@ void PIProtocol::calc_diag() { pckt_cnt++; } else { packets[(int)last_packets.back()]--; - last_packets.pop_back(); + if (!last_packets.isEmpty()) last_packets.pop_back(); last_packets.push_front(cur_pckt); } packets[(int)cur_pckt]++; @@ -277,25 +297,21 @@ void PIProtocol::calc_freq() { void PIProtocol::check_state() { - if (type_send == PIProtocol::Serial) { - if (ser->initialized()) devSenderState = "Initialized"; - else devSenderState = "Uninitialized"; - return; - } - if (type_send == PIProtocol::Ethernet) { - if (eth->senderInitialized()) devSenderState = "Initialized"; - else devSenderState = "Uninitialized"; - return; - } if (type_rec == PIProtocol::Serial) { if (ser->initialized()) devReceiverState = "Initialized"; else devReceiverState = "Uninitialized"; - return; } if (type_rec == PIProtocol::Ethernet) { if (eth->receiverInitialized()) devReceiverState = "Initialized"; else devReceiverState = "Uninitialized"; - return; + } + if (type_send == PIProtocol::Serial) { + if (ser->initialized()) devSenderState = "Initialized"; + else devSenderState = "Uninitialized"; + } + if (type_send == PIProtocol::Ethernet) { + if (eth->senderInitialized()) devSenderState = "Initialized"; + else devSenderState = "Uninitialized"; } } @@ -303,10 +319,10 @@ void PIProtocol::check_state() { void PIProtocol::send(const void * data, int size) { if (data == 0 || size == 0) return; if (!aboutSend()) return; - if (type_rec == PIProtocol::Serial) + if (type_send == PIProtocol::Serial) if (ser->send((char * )data, size)) send_count++; - if (type_rec == PIProtocol::Ethernet) + if (type_send == PIProtocol::Ethernet) if (eth->send((char * )data, size)) send_count++; } @@ -318,10 +334,10 @@ void PIProtocol::send() { //unlock(); if (sendDataPtr == 0 || sendDataSize == 0) return; if (!aboutSend()) return; - if (type_rec == PIProtocol::Serial) + if (type_send == PIProtocol::Serial) if (ser->send((char * )sendDataPtr, sendDataSize)) send_count++; - if (type_rec == PIProtocol::Ethernet) + if (type_send == PIProtocol::Ethernet) if (eth->send((char * )sendDataPtr, sendDataSize)) send_count++; } diff --git a/piprotocol.h b/piprotocol.h index 7d2552a7..cedc34d2 100644 --- a/piprotocol.h +++ b/piprotocol.h @@ -7,14 +7,36 @@ #include "piconfig.h" #include "math.h" +class PIProtocol; + +class PIMultiProtocolBase +{ + friend class PIProtocol; +public: + PIMultiProtocolBase() {;} + ~PIMultiProtocolBase() {;} + +protected: + virtual void received(PIProtocol * prot, bool corrected, char * data, int size) {;} + +private: + static void receiveEvent(PIMultiProtocolBase * p, PIProtocol * prot, bool corrected, char * data, int size) {p->mutex_receive.lock(); p->received(prot, corrected, data, size); p->mutex_receive.unlock();} + + PIMutex mutex_receive; + +}; + typedef void (*ReceiveFunc)(void * ); class PIProtocol { + friend class PIMultiProtocolBase; + friend class PIMultiProtocol; enum Type {None, Serial, Ethernet}; enum Quality {Unknown = 1, Failure = 2, Bad = 3, Average = 4, Good = 5}; public: + PIProtocol() {init();} PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0, void * recDataPtr = 0, int recDataSize = 0, void * sendDataPtr = 0, int sendDataSize = 0); // from config ~PIProtocol(); @@ -22,42 +44,44 @@ public: void startReceive(float exp_frequency = -1.f); // if "frequency = -1" used last passed value void stopReceive(); void setExpectedFrequency(float frequency); // for connection quality diagnostic - void setReceiverDevice(const PIString & device, PISerial::Speed speed); // for Serial - void setReceiverDevice(const PIString & ip, int port); // for Ethernet + void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize;} - void setReceiverAddress(const PIString & ip, int port) {if (type_send == PIProtocol::Ethernet && eth != 0) eth->setSendAddress(ip, port);} // for Ethernet + void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet void setReceiverParameters(PIFlags parameters) {if (type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;} void startSend(float frequency = -1.f); // if "frequency = -1" used last passed value void stopSend() {sendTimer->stop();} void setSenderFrequency(float frequency) {send_freq = frequency;} - void setSenderDevice(const PIString & device, PISerial::Speed speed); // for Serial - void setSenderDevice(const PIString & ip, int port); // for Ethernet + void setSenderDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial void setSenderData(void * dataPtr, int dataSize) {sendDataPtr = (uchar * )dataPtr; sendDataSize = dataSize;} - void setSenderAddress(const PIString & ip, int port) {if (type_send == PIProtocol::Ethernet && eth != 0) eth->setSendAddress(ip, port);} // for Ethernet + void setSenderAddress(const PIString & ip, int port, bool force = false); // for Ethernet void setSenderParameters(PIFlags parameters) {if (type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial + void start() {startReceive(); startSend();} + void stop() {stopReceive(); stopSend();} void send(); void send(const void * data, int size); - float immediateFrequency() {return immediateFreq;} - float integralFrequency() {return integralFreq;} + void setName(const PIString & name) {protName = name;} + PIString name() const {return protName;} + float immediateFrequency() const {return immediateFreq;} + float integralFrequency() const {return integralFreq;} float * immediateFrequency_ptr() {return &immediateFreq;} float * integralFrequency_ptr() {return &integralFreq;} - ullong receiveCount() {return receive_count;} + ullong receiveCount() const {return receive_count;} ullong * receiveCount_ptr() {return &receive_count;} - ullong wrongCount() {return wrong_count;} + ullong wrongCount() const {return wrong_count;} ullong * wrongCount_ptr() {return &wrong_count;} - ullong sendCount() {return send_count;} + ullong sendCount() const {return send_count;} ullong * sendCount_ptr() {return &send_count;} - PIProtocol::Quality quality() {return net_diag;} // receive quality + PIProtocol::Quality quality() const {return net_diag;} // receive quality int * quality_ptr() {return (int * )&net_diag;} // receive quality pointer - PIString receiverDeviceName() {return devReceiverName;} - PIString senderDeviceName() {return devSenderName;} - PIString receiverDeviceState() {return devReceiverState;} + PIString receiverDeviceName() const {return devReceiverName;} + PIString senderDeviceName() const {cout << devSenderName << endl; return devSenderName;} + PIString receiverDeviceState() const {return devReceiverState;} PIString * receiverDeviceState_ptr() {return &devReceiverState;} - PIString senderDeviceState() {return devSenderState;} + PIString senderDeviceState() const {return devSenderState;} PIString * senderDeviceState_ptr() {return &devSenderState;} protected: @@ -93,19 +117,25 @@ private: static void sendEvent(void * e) {((PIProtocol * )e)->send();} static bool receiveEvent(void * t, char * data, int size); static void diagEvent(void * t); + + void setMultiProtocolOwner(PIMultiProtocolBase * mp) {mp_owner = mp;} + PIMultiProtocolBase * multiProtocolOwner() const {return mp_owner;} + ReceiveFunc ret_func; PITimer * diagTimer, * sendTimer; + PIMultiProtocolBase * mp_owner; PIProtocol::Type type_send, type_rec; PIProtocol::Quality net_diag; - deque last_freq; - deque last_packets; - PIString devReceiverName, devReceiverState, devSenderName, devSenderState; - bool work; + PIDeque last_freq; + PIDeque last_packets; + PIString protName, devReceiverName, devReceiverState, devSenderName, devSenderState; + bool work, new_mp_prot; float exp_freq, send_freq, immediateFreq, integralFreq, tf; int packets[2]; uint pckt_cnt, pckt_cnt_max; char * packet, cur_pckt; ullong wrong_count, receive_count, send_count; + }; #endif // PIPROTOCOL_H diff --git a/piserial.cpp b/piserial.cpp index d5639784..e7370f92 100644 --- a/piserial.cpp +++ b/piserial.cpp @@ -8,9 +8,8 @@ PISerial::PISerial(PIString name, void * data_, SerialFunc slot): PIThread() { fd = -1; dataSize = headerSize = 0; headerPtr = 0; + hbuffer = pbuffer = 0; ret_func = slot; - //buffer = new char[BUFFER_SIZE]; - //sbuffer = new char[BUFFER_SIZE]; #ifdef WINDOWS hCom = 0; #endif @@ -20,10 +19,6 @@ PISerial::PISerial(PIString name, void * data_, SerialFunc slot): PIThread() { PISerial::~PISerial() { terminate(); - /*if (buffer != 0) delete buffer; - buffer = 0; - if (sbuffer != 0) delete sbuffer; - sbuffer = 0;*/ } @@ -31,7 +26,7 @@ void PISerial::terminate() { if (!initialized()) return; if (isRunning()) { stop(); - pthread_cancel(thread); + PIThread::terminate(); } #ifdef WINDOWS if (fd != -1) { @@ -174,8 +169,14 @@ void PISerial::run() { void PISerial::end() { terminate(); - delete pbuffer; - delete hbuffer; + if (pbuffer != 0) { + delete pbuffer; + pbuffer = 0; + } + if (hbuffer != 0) { + delete hbuffer; + hbuffer = 0; + } } @@ -206,7 +207,10 @@ bool PISerial::init() { desc.DCBlength = sizeof(desc); desc.BaudRate = convertSpeed(ispeed); desc.ByteSize = 8; - desc.fParity = params[PISerial::IgnoreParityControl] ? 0 : 1; + if (params[PISerial::ParityControl]) { + desc.fParity = 1; + desc.Parity = params[PISerial::ParityOdd] ? 1 : 2; + } desc.StopBits = params[PISerial::TwoStopBits] ? TWOSTOPBITS : ONESTOPBIT; if (SetCommState(hCom, &desc) == -1) { cout << "[PISerial] Unable to set comm state for \"" << devName << "\"" << endl; @@ -227,10 +231,10 @@ bool PISerial::init() { desc.c_iflag = desc.c_oflag = desc.c_lflag = 0; desc.c_cflag = CLOCAL | CREAD | CSIZE; if (params[PISerial::TwoStopBits]) desc.c_cflag |= CSTOPB; - if (!params[PISerial::ParityControl]) { + if (params[PISerial::ParityControl]) { desc.c_iflag |= INPCK; desc.c_cflag |= PARENB; - if (!params[PISerial::ParityOdd]) desc.c_cflag |= PARODD; + if (params[PISerial::ParityOdd]) desc.c_cflag |= PARODD; } desc.c_cc[VMIN] = 0; desc.c_cc[VTIME] = 1; diff --git a/pisignals.cpp b/pisignals.cpp new file mode 100644 index 00000000..79396579 --- /dev/null +++ b/pisignals.cpp @@ -0,0 +1,92 @@ +#include "pisignals.h" + +PISignals::SignalEvent PISignals::ret_func; + + +void PISignals::grabSignals(PIFlags signals_) { + if (signals_[PISignals::Interrupt]) signal(signalCode(PISignals::Interrupt), PISignals::signal_event); + if (signals_[PISignals::Illegal]) signal(signalCode(PISignals::Illegal), PISignals::signal_event); + if (signals_[PISignals::Abort]) signal(signalCode(PISignals::Abort), PISignals::signal_event); + if (signals_[PISignals::FPE]) signal(signalCode(PISignals::FPE), PISignals::signal_event); + if (signals_[PISignals::SegFault]) signal(signalCode(PISignals::SegFault), PISignals::signal_event); + if (signals_[PISignals::Termination]) signal(signalCode(PISignals::Termination), PISignals::signal_event); +#ifndef WINDOWS + if (signals_[PISignals::Hangup]) signal(signalCode(PISignals::Hangup), PISignals::signal_event); + if (signals_[PISignals::Quit]) signal(signalCode(PISignals::Quit), PISignals::signal_event); + if (signals_[PISignals::Kill]) signal(signalCode(PISignals::Kill), PISignals::signal_event); + if (signals_[PISignals::BrokenPipe]) signal(signalCode(PISignals::BrokenPipe), PISignals::signal_event); + if (signals_[PISignals::Timer]) signal(signalCode(PISignals::Timer), PISignals::signal_event); + if (signals_[PISignals::UserDefined1]) signal(signalCode(PISignals::UserDefined1), PISignals::signal_event); + if (signals_[PISignals::UserDefined2]) signal(signalCode(PISignals::UserDefined2), PISignals::signal_event); + if (signals_[PISignals::ChildStopped]) signal(signalCode(PISignals::ChildStopped), PISignals::signal_event); + if (signals_[PISignals::Continue]) signal(signalCode(PISignals::Continue), PISignals::signal_event); + if (signals_[PISignals::StopProcess]) signal(signalCode(PISignals::StopProcess), PISignals::signal_event); + if (signals_[PISignals::StopTTY]) signal(signalCode(PISignals::StopTTY), PISignals::signal_event); + if (signals_[PISignals::StopTTYInput]) signal(signalCode(PISignals::StopTTYInput), PISignals::signal_event); + if (signals_[PISignals::StopTTYOutput]) signal(signalCode(PISignals::StopTTYOutput), PISignals::signal_event); +#endif +} + + +int PISignals::signalCode(PISignals::Signal signal) { + switch (signal) { + case PISignals::Interrupt: return SIGINT; + case PISignals::Illegal: return SIGILL; + case PISignals::Abort: return SIGABRT; + case PISignals::FPE: return SIGFPE; + case PISignals::SegFault: return SIGSEGV; + case PISignals::Termination: return SIGTERM; +#ifndef WINDOWS + case PISignals::Hangup: return SIGHUP; + case PISignals::Quit: return SIGQUIT; + case PISignals::Kill: return SIGKILL; + case PISignals::BrokenPipe: return SIGPIPE; + case PISignals::Timer: return SIGALRM; + case PISignals::UserDefined1: return SIGUSR1; + case PISignals::UserDefined2: return SIGUSR2; + case PISignals::ChildStopped: return SIGCHLD; + case PISignals::Continue: return SIGCONT; + case PISignals::StopProcess: return SIGSTOP; + case PISignals::StopTTY: return SIGTSTP; + case PISignals::StopTTYInput: return SIGTTIN; + case PISignals::StopTTYOutput:return SIGTTOU; +#endif + default:; + } + return 0; +} + + +PISignals::Signal PISignals::signalFromCode(int signal) { + switch (signal) { + case SIGINT: return PISignals::Interrupt; + case SIGILL: return PISignals::Illegal; + case SIGABRT: return PISignals::Abort; + case SIGFPE: return PISignals::FPE; + case SIGSEGV: return PISignals::SegFault; + case SIGTERM: return PISignals::Termination; +#ifndef WINDOWS + case SIGHUP: return PISignals::Hangup; + case SIGQUIT: return PISignals::Quit; + case SIGKILL: return PISignals::Kill; + case SIGPIPE: return PISignals::BrokenPipe; + case SIGALRM: return PISignals::Timer; + case SIGUSR1: return PISignals::UserDefined1; + case SIGUSR2: return PISignals::UserDefined2; + case SIGCHLD: return PISignals::ChildStopped; + case SIGCONT: return PISignals::Continue; + case SIGSTOP: return PISignals::StopProcess; + case SIGTSTP: return PISignals::StopTTY; + case SIGTTIN: return PISignals::StopTTYInput; + case SIGTTOU: return PISignals::StopTTYOutput; +#endif + default:; + } + return PISignals::Termination; +} + + +void PISignals::signal_event(int signal) { + if (PISignals::ret_func == 0) return; + PISignals::ret_func(PISignals::signalFromCode(signal)); +} diff --git a/pisignals.h b/pisignals.h new file mode 100644 index 00000000..e216f981 --- /dev/null +++ b/pisignals.h @@ -0,0 +1,54 @@ +#ifndef PISIGNALS_H +#define PISIGNALS_H + +#include "picontainers.h" +#include + +class PISignals +{ +public: + enum Signal { + Interrupt = 0x01, // Term Interrupt from keyboard + Illegal = 0x02, // Core Illegal Instruction + Abort = 0x04, // Core Abort signal from abort + FPE = 0x08, // Core Floating point exception + SegFault = 0x10, // Core Invalid memory reference + Termination = 0x20, // Term Termination signal +#ifndef WINDOWS + Hangup = 0x40, // Term Hangup detected on controlling terminal or death of controlling process + Quit = 0x80, // Core Quit from keyboard + Kill = 0x100, // Term Kill signal + BrokenPipe = 0x200, // Term Broken pipe: write to pipe with no readers + Timer = 0x400, // Term Timer signal from alarm + UserDefined1 = 0x800, // Term User-defined signal 1 + UserDefined2 = 0x1000, // Term User-defined signal 2 + ChildStopped = 0x2000, // Ign Child stopped or terminated + Continue = 0x4000, // Cont Continue if stopped + StopProcess = 0x8000, // Stop Stop process + StopTTY = 0x10000, // Stop Stop typed at tty + StopTTYInput = 0x20000, // Stop tty input for background process + StopTTYOutput = 0x40000, // Stop tty output for background process +#endif + All = 0xFFFFF + }; + + typedef void (*SignalEvent)(PISignals::Signal); + + static void setSlot(SignalEvent slot) {ret_func = slot;} + static void grabSignals(PIFlags signals_); + static void raiseSignal(PISignals::Signal signal) {raise(signalCode(signal));} + +private: + PISignals() {ret_func = 0;} + ~PISignals() {} + + static int signalCode(PISignals::Signal signal); + static PISignals::Signal signalFromCode(int signal); + static void signal_event(int signal); + + static SignalEvent ret_func; + +}; + + +#endif // PISIGNALS_H diff --git a/pistring.cpp b/pistring.cpp index 6b16db2a..36b9c755 100644 --- a/pistring.cpp +++ b/pistring.cpp @@ -5,11 +5,12 @@ void PIString::appendFromChars(const char * c, int s) { int sz; wchar_t wc; for (int i = 0; i < s; ++i) { - if (isascii(c[i])) { + if (/*isascii(c[i])*/c[i] >= 0) { push_back(PIChar(c[i])); continue; } sz = mbtowc(&wc, &c[i], 4); + //cout << sz << endl; switch (sz) { case 4: push_back(PIChar(*(int*)&(c[i]))); @@ -40,6 +41,34 @@ PIString & PIString::operator +=(const char * str) { } +PIString & PIString::operator +=(const wchar_t * str) { + //cout << "wc" << endl; + int l = 0, sz; + char * c = new char[MB_CUR_MAX]; + while (str[l] != 0) ++l; + for (int i = 0; i < l; ++i) { + sz = wctomb(c, str[i]); + switch (sz) { + case 4: + push_back(PIChar(*(int*)c)); + continue; + case 3: + push_back(PIChar(*(int*)c)); + back().ch &= 0xFFFFFF; + continue; + case 2: + push_back(PIChar(*(short * )c)); + continue; + default: + push_back(PIChar(c[0])); + break; + } + } + delete c; + return *this; +} + + PIString & PIString::operator +=(const wstring & str) { uint l = str.size(); for (uint i = 0; i < l; ++i) push_back(str[i]); @@ -285,18 +314,17 @@ char PIString::toChar() const { short PIString::toShort() const { - PIString s(trimmed().toNativeDecimalPoints()); - int i; + PIString s(trimmed().toLowerCase().toNativeDecimalPoints()); short v; - if (s.left(2) == "0x") {sscanf(s.data(), "%x", &i); return (short)i;} - if (s.left(1) == "0") {sscanf(s.data(), "%o", &i); return (short)i;} + if (s.left(2) == "0x") {sscanf(s.data(), "%hx", &v); return v;} + if (s.left(1) == "0") {sscanf(s.data(), "%ho", &v); return v;} sscanf(s.data(), "%hd", &v); return v; } int PIString::toInt() const { - PIString s(trimmed().toNativeDecimalPoints()); + PIString s(trimmed().toLowerCase().toNativeDecimalPoints()); int v; if (s.left(2) == "0x") {sscanf(s.data(), "%x", &v); return v;} if (s.left(1) == "0") {sscanf(s.data(), "%o", &v); return v;} @@ -306,23 +334,21 @@ int PIString::toInt() const { long PIString::toLong() const { - PIString s(trimmed().toNativeDecimalPoints()); - int i; + PIString s(trimmed().toLowerCase().toNativeDecimalPoints()); long v; - if (s.left(2) == "0x") {sscanf(s.data(), "%x", &i); return (long)i;} - if (s.left(1) == "0") {sscanf(s.data(), "%o", &i); return (long)i;} + if (s.left(2) == "0x") {sscanf(s.data(), "%lx", &v); return v;} + if (s.left(1) == "0") {sscanf(s.data(), "%lo", &v); return v;} sscanf(s.data(), "%ld", &v); return v; } llong PIString::toLLong() const { - PIString s(trimmed().toNativeDecimalPoints()); - int i; + PIString s(trimmed().toLowerCase().toNativeDecimalPoints()); llong v; - if (s.left(2) == "0x") {sscanf(s.data(), "%x", &i); return (llong)i;} - if (s.left(1) == "0") {sscanf(s.data(), "%o", &i); return (llong)i;} - sscanf(s.data(), "%Ld", &v); + if (s.left(2) == "0x") {sscanf(s.data(), "%llx", &v); return v;} + if (s.left(1) == "0") {sscanf(s.data(), "%llo", &v); return v;} + sscanf(s.data(), "%lld", &v); return v; } diff --git a/pistring.h b/pistring.h index 557ac732..ccff777e 100644 --- a/pistring.h +++ b/pistring.h @@ -14,6 +14,7 @@ public: //inline PIString & operator +=(const char c) {push_back(c); return *this;} PIString & operator +=(const PIChar c) {push_back(c); return *this;} PIString & operator +=(const char * str); + PIString & operator +=(const wchar_t * str); PIString & operator +=(const string & str) {appendFromChars(str.c_str(), str.length()); return *this;} PIString & operator +=(const PIByteArray & ba) {appendFromChars((const char * )ba.data(), ba.size_s()); return *this;} PIString & operator +=(const PIString & str); @@ -22,21 +23,18 @@ public: //PIString(const char c) {*this += c;} PIString(const PIChar c) {*this += c;} PIString(const char * str) {*this += str;} + PIString(const wchar_t * str) {*this += str;} PIString(const string & str) {*this += str;} PIString(const wstring & str) {*this += str;} - PIString(const PIString & str) {*this += str;} PIString(const PIByteArray & ba) {*this += ba;} PIString(const char * str, const int len) {*this += string(str, len);} PIString(const int len, const char c) {for (int i = 0; i < len; ++i) push_back(c);} PIString(const int len, const PIChar & c) {for (int i = 0; i < len; ++i) push_back(c);} + PIString(const PIString & str) {*this += str;} operator const char*() {return data();} operator const string() {if (size() == 0) return string(); string s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toAscii()); return s;} -#ifdef WINDOWS - PIChar operator [](const int pos) const __attribute__ ((optimize(0))) {return at(pos);} -#else PIChar operator [](const int pos) const {return at(pos);} -#endif PIChar & operator [](const int pos) {return at(pos);} bool operator ==(const PIString & str) const; @@ -79,6 +77,7 @@ public: //inline PIString & operator <<(const char c) {*this += c; return *this;} PIString & operator <<(const PIChar c) {*this += c; return *this;} PIString & operator <<(const char * str) {*this += str; return *this;} + PIString & operator <<(const wchar_t * str) {*this += str; return *this;} PIString & operator <<(const string & str) {*this += str; return *this;} PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;} PIString & operator <<(const short & num) {*this += PIString::fromNumber(num); return *this;} @@ -107,10 +106,10 @@ public: PIString & expandRightTo(const int len, const PIChar & c) {if (len > length()) resize(len, c); return *this;} PIString & expandLeftTo(const int len, const PIChar & c) {if (len > length()) insert(0, PIString(len - length(), c)); return *this;} - const char * data() {std_string = convertToStd(); return std_string.c_str();} + const char * data() {return convertToStd().c_str();} const string stdString() const {return convertToStd();} wstring stdWString() const {return convertToWString();} - PIByteArray toByteArray() {convertToStd(); return PIByteArray(std_string.c_str(), std_string.length());} + PIByteArray toByteArray() {string s(convertToStd()); return PIByteArray(s.c_str(), s.length());} PIStringList split(const PIString & delim) const; PIString toUpperCase() const; @@ -162,7 +161,7 @@ private: string convertToStd() const; wstring convertToWString() const {wstring s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toWChar()); return s;} - string std_string; + //string std_string; }; @@ -198,6 +197,7 @@ public: uint contentSize() {uint s = 0; for (uint i = 0; i < size(); ++i) s += at(i).size(); return s;} PIStringList & operator <<(const PIString & str) {push_back(str); return *this;} + PIStringList & operator <<(const PIStringList & sl) {piForeachC (PIString & i, sl) push_back(i); return *this;} //inline PIStringList & operator <<(const char c) {push_back(PIString(c)); return *this;} PIStringList & operator <<(const char * str) {push_back(PIString(str)); return *this;} PIStringList & operator <<(const string & str) {push_back(str); return *this;} diff --git a/pithread.cpp b/pithread.cpp index ddd04853..fe3e61e1 100644 --- a/pithread.cpp +++ b/pithread.cpp @@ -8,38 +8,73 @@ PIThread::PIThread(bool startNow, int timer_delay) { if (startNow) start(timer_delay); } +#ifndef WINDOWS +#else +#endif PIThread::~PIThread() { if (!running) return; +#ifndef WINDOWS pthread_cancel(thread); +#else + CloseHandle(thread); +#endif } bool PIThread::start(int timer_delay) { - pthread_attr_t attr; terminating = running = false; timer = timer_delay; +#ifndef WINDOWS + pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setschedparam(&attr, &sparam); if (pthread_create(&thread, &attr, thread_function, this) == 0) { running = true; return true; } +#else + thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, this, 0, 0); + if (thread == 0) + return false; + setPriority(priority_); +#endif return false; } bool PIThread::startOnce() { - pthread_attr_t attr; terminating = running = false; +#ifndef WINDOWS + pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setschedparam(&attr, &sparam); if (pthread_create(&thread, &attr, thread_function_once, this) == 0) return true; +#else + thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function_once, this, 0, 0); + if (thread == 0) + return false; + setPriority(priority_); +#endif return false; } +void PIThread::terminate(bool hard) { + if (thread == 0) return; + running = false; +#ifndef WINDOWS + if (hard) kill(thread, SIGKILL); + else pthread_cancel(thread); +#else + CloseHandle(thread); +#endif + thread = 0; + end(); +} + + void * PIThread::thread_function(void * t) { PIThread * ct = (PIThread * )t; ct->running = true; @@ -53,7 +88,11 @@ void * PIThread::thread_function(void * t) { ct->end(); ct->running = false; //cout << "thread " << t << " exiting ... " << endl; +#ifndef WINDOWS pthread_exit(0); +#else + ExitThread(0); +#endif return 0; } @@ -68,21 +107,30 @@ void * PIThread::thread_function_once(void * t) { ct->end(); ct->running = false; //cout << "thread " << t << " exiting ... " << endl; +#ifndef WINDOWS pthread_exit(0); +#else + ExitThread(0); +#endif return 0; } void PIThread::setPriority(PIThread::Priority prior) { priority_ = prior; -#ifndef LINUX +#ifndef WINDOWS +# ifndef LINUX sparam.sched_priority = (int)priority_; -#else +# else sparam.__sched_priority = (int)priority_; -#endif +# endif if (!running) return; pthread_getschedparam(thread, &policy, &sparam); pthread_setschedparam(thread, policy, &sparam); +#else + if (!running) return; + SetThreadPriority(thread, -(int)priority_); +#endif } diff --git a/pithread.h b/pithread.h index e161b8ed..91b02cbc 100644 --- a/pithread.h +++ b/pithread.h @@ -1,7 +1,6 @@ #ifndef PITHREAD_H #define PITHREAD_H -#include #include #include "pimutex.h" @@ -33,7 +32,7 @@ public: bool start(int timer_delay = -1); bool startOnce(); void stop(bool wait = false) {terminating = true; if (wait) waitForFinish();} - void terminate() {kill(thread, SIGKILL); end(); running = false;} + void terminate(bool hard = false); void setPriority(PIThread::Priority prior); PIThread::Priority priority() const {return priority_;} bool isRunning() const {return running;} @@ -55,10 +54,14 @@ protected: volatile bool terminating, running, lockRun; int timer, policy; - pthread_t thread; PIMutex mutex_; - sched_param sparam; PIThread::Priority priority_; +#ifndef WINDOWS + pthread_t thread; + sched_param sparam; +#else + void * thread; +#endif }; diff --git a/pitimer.h b/pitimer.h index eaf866ed..0e76a5f9 100644 --- a/pitimer.h +++ b/pitimer.h @@ -28,6 +28,9 @@ class PITimer public: PITimer(TimerEvent slot = 0, void * data = 0); ~PITimer() {stop();} + + void setData(void * data_) {data = data_;} + void setSlot(TimerEvent slot_) {ret_func = slot_;} #ifdef WINDOWS void reset() {t_st = GetCurrentTime();} #else diff --git a/protocols.conf b/protocols.conf new file mode 100644 index 00000000..6c81b8a2 --- /dev/null +++ b/protocols.conf @@ -0,0 +1,52 @@ +gas.receiver.ip = 127.0.0.1 +gas.receiver.port = 0x2401 +gas.receiver.frequency = 105 +gas.sender.ip = 127.0.0.1 +gas.sender.port = 0x1001 +gas.sender.frequency = 10 +gas.writeHistory = false + +mcp1.receiver.ip = 127.0.0.1 +mcp1.receiver.port = 4012 +mcp1.receiver.frequency = 20 +mcp1.sender.ip = 192.168.0.190 +mcp1.sender.port = 4013 +mcp1.sender.frequency = 20 +mcp1.writeHistory = false + +#slk.receiver.device = /dev/ttyS0 +slk.receiver.speed = 19200 +slk.receiver.parity = false +slk.receiver.twoStopBits = false +slk.receiver.frequency = 10 +slk.sender.frequency = 10 +slk.writeHistory = false + +#ts.receiver.device = /dev/ttyS0 +#ts.receiver.speed = 57600 +#ts.receiver.parity = false +#ts.receiver.twoStopBits = false +ts.receiver.ip = 192.168.0.190 +ts.receiver.port = 4023 +ts.receiver.frequency = 23 +ts.sender.ip = 192.168.0.175 +ts.sender.port = 4023 +#ts.sender.frequency = 23 +ts.writeHistory = false +ts_mcp1.receiver.ip = 192.168.0.190 +ts_mcp1.receiver.port = 4022 +ts_mcp1.sender.ip = 192.168.0.175 +ts_mcp1.sender.port = 4022 + +r.mv2.receiver.ip = 127.0.0.2 +r.mv2.receiver.port = 3003 +r.mv2.receiver.frequency = 20 +r.mv2.sender.ip = 127.0.0.1 +r.mv2.sender.port = 3003 +r.mv2.sender.frequency = 20 +r.mv1.receiver.ip = 127.0.0.4 +r.mv1.receiver.port = 3003 +r.mv1.receiver.frequency = 20 +r.mv1.sender.ip = 127.0.0.3 +r.mv1.sender.port = 3003 +r.mv1.sender.frequency = 20 diff --git a/Описание.odt b/Описание.odt new file mode 100644 index 00000000..7d6880f3 Binary files /dev/null and b/Описание.odt differ