diff --git a/uppsrc/Ole/Ctrl/util.cpp b/uppsrc/Ole/Ctrl/util.cpp index 8fd9ae46b..ba8063983 100644 --- a/uppsrc/Ole/Ctrl/util.cpp +++ b/uppsrc/Ole/Ctrl/util.cpp @@ -258,7 +258,7 @@ bool OcxTypeInfo::CanUnload() const RDUMP(object_count); RDUMP(refcount); RDUMP(lock_count); - return object_count == 0 && refcount <= 1 && lock_count <= 0; + return object_count == 0 && refcount <= 2 && lock_count <= 0; } int OcxTypeInfo::IncRef() @@ -718,10 +718,16 @@ void ExeRunServer() } LOGSYSOCX("-> registration OK"); - MSG msg; - while(GetMessage(&msg, 0, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); + int ms = msecs(); + bool quit = false; + while(!quit) { + if(msecs(ms) >= 2000) { + if(OcxTypeLib::Get().CanUnload()) + break; + ms = msecs(); + } + if(!Ctrl::ProcessEvent(&quit)) + Sleep(10); } LOGSYSOCX("end of message loop"); OcxTypeLib::Get().RevokeObjects(); diff --git a/uppsrc/Ole/util.cpp b/uppsrc/Ole/util.cpp index 42d9d0bc1..be500dccf 100644 --- a/uppsrc/Ole/util.cpp +++ b/uppsrc/Ole/util.cpp @@ -247,12 +247,24 @@ ValueArray SAFEARRAYToValueArray(SAFEARRAY *array) return SAFEARRAYToValueArrayPart(array, indices.Begin(), ndims - 1); } -SAFEARRAY * ValueArrayToSAFEARRAY(const ValueArray& varray) +Vector SAFEARRAYToWStringVector(SAFEARRAY *array) { - SAFEARRAYBOUND rgsabound; - rgsabound.lLbound = 0; - rgsabound.cElements = varray.GetCount(); - SAFEARRAY *a = SafeArrayCreate(VT_VARIANT, 1, &rgsabound); + Vector out; + out.SetCount(array->rgsabound[0].cElements); + Vector indices; + indices.SetCount(array->cDims, 0); + for(int i = 0; i < out.GetCount(); i++) { + OleBstr s; + indices[0] = i; + HRESULT hr = SafeArrayGetElement(array, indices.Begin(), s.Set()); + out[i] = s; + } + return out; +} + +SAFEARRAY *ToSAFEARRAY(const ValueArray& varray) +{ + SAFEARRAY *a = SafeArrayCreateVector(VT_VARIANT, 0, varray.GetCount()); if(!a) return NULL; for(long index = 0; index < varray.GetCount(); index++) { @@ -262,6 +274,18 @@ SAFEARRAY * ValueArrayToSAFEARRAY(const ValueArray& varray) return a; } +SAFEARRAY *ToSAFEARRAY(const Vector& vstr) +{ + SAFEARRAY *a = SafeArrayCreateVector(VT_BSTR, 0, vstr.GetCount()); + if(!a) + return NULL; + for(long index = 0; index < vstr.GetCount(); index++) { + OleBstr var = vstr[(int)index]; + SafeArrayPutElement(a, &index, ~var); + } + return a; +} + ////////////////////////////////////////////////////////////////////// // special types diff --git a/uppsrc/Ole/util.h b/uppsrc/Ole/util.h index 1b135142c..603a38fc0 100644 --- a/uppsrc/Ole/util.h +++ b/uppsrc/Ole/util.h @@ -84,6 +84,24 @@ inline String AsString(const Guid& guid) { return Format(~guid); } inline bool operator == (const Guid& a, const Guid& b) { return ~a == ~b; } inline bool operator != (const Guid& a, const Guid& b) { return ~a != ~b; } +class OleExc : public Exc +{ +public: + OleExc(HRESULT hresult); + OleExc(HRESULT hresult, const char *text); + +public: + HRESULT hresult; +}; + +HRESULT LogResult(HRESULT hr); +HRESULT LogError(HRESULT hr); + +inline void OleVerify(HRESULT hr) { if(FAILED(hr)) throw OleExc(hr); } +inline void OleVerify(HRESULT hr, const char *text) { if(FAILED(hr)) throw OleExc(hr, text); } + +#define OLE_VERIFY(c) OleVerify(c, #c) + class OleVariant : public VARIANT { public: @@ -124,9 +142,29 @@ void ReturnWString(BSTR *dest, WString s); HRESULT CheckReturnWString(BSTR *bstr, WString s); ValueArray SAFEARRAYToValueArray(SAFEARRAY *array); -SAFEARRAY *ValueArrayToSAFEARRAY(const ValueArray& varray); -void ReturnValueArray(SAFEARRAY *dest, const ValueArray& array); -HRESULT CheckReturnString(BSTR *bstr, String s); +Vector SAFEARRAYToWStringVector(SAFEARRAY *array); +SAFEARRAY *ToSAFEARRAY(const ValueArray& varray); +SAFEARRAY *ToSAFEARRAY(const Vector& varray); +void ReturnSAFEARRAY(SAFEARRAY *dest, const ValueArray& array); +void ReturnSAFEARRAY(SAFEARRAY *dest, const Vector& array); +HRESULT CheckReturnSAFEARRAY(SAFEARRAY *dest, const ValueArray& array); +HRESULT CheckReturnSAFEARRAY(SAFEARRAY *dest, const Vector& array); + +class OleSafeArray { +public: + OleSafeArray() : array(NULL) {} + OleSafeArray(const ValueArray& va) { array = ToSAFEARRAY(va); } + OleSafeArray(const Vector& vs) { array = ToSAFEARRAY(vs); } + OleSafeArray(const OleSafeArray& a) { array = NULL; if(a.array) OleVerify(SafeArrayCopy(a.array, &array)); } + ~OleSafeArray() { if(array) SafeArrayDestroy(array); } + + operator ValueArray () const { return SAFEARRAYToValueArray(array); } + operator Vector () const { return SAFEARRAYToWStringVector(array); } + SAFEARRAY *operator ~ () const { return array; } + +private: + SAFEARRAY *array; +}; class OleBstr { @@ -157,24 +195,6 @@ Color PackColor(long rgb); long UnpackColor(Color c); HRESULT CheckReturnColor(long *ptr, Color c); -class OleExc : public Exc -{ -public: - OleExc(HRESULT hresult); - OleExc(HRESULT hresult, const char *text); - -public: - HRESULT hresult; -}; - -HRESULT LogResult(HRESULT hr); -HRESULT LogError(HRESULT hr); - -inline void OleVerify(HRESULT hr) { if(FAILED(hr)) throw OleExc(hr); } -inline void OleVerify(HRESULT hr, const char *text) { if(FAILED(hr)) throw OleExc(hr, text); } - -#define OLE_VERIFY(c) OleVerify(c, #c) - template class IRefBase : Moveable< IRefBase > { diff --git a/uppsrc/TCore/CalcNode.cpp b/uppsrc/TCore/CalcNode.cpp index 2bcaabae1..fb37ddf05 100644 --- a/uppsrc/TCore/CalcNode.cpp +++ b/uppsrc/TCore/CalcNode.cpp @@ -1108,9 +1108,10 @@ void CalcFunctionNode::ScanArgs(CalcPacket& packet) const ////////////////////////////////////////////////////////////////////// // CalcParser:: -CalcParser::CalcParser() +CalcParser::CalcParser(bool sql_style_) : start(0), pos(0) , op_begin(0), op_end(0), op_last(OP_NONE) +, sql_style(sql_style_) { } @@ -1322,8 +1323,7 @@ CalcNodePtr CalcParser::ScanSequence() CalcNodePtr CalcParser::ScanSelect() { CalcNodePtr node = ScanLogOr(); - if(Check(OP_QUESTION)) - { // ?: + if(Check(OP_QUESTION)) { // ?: CalcNodePtr when1 = ScanSelect(); Force(OP_COLON, ":"); CalcNodePtr when0 = ScanSelect(); @@ -1372,8 +1372,52 @@ CalcNodePtr CalcParser::ScanCompare() node = new CalcFunctionNode("<", node, ScanBitOr()); else if(Check(OP_GT)) node = new CalcFunctionNode(">", node, ScanBitOr()); - else - return node; + else { + bool isnot = Check(OP_SQL_NOT); + bool isbtw = Check(OP_SQL_BETWEEN); + bool isin = !isbtw && Check(OP_SQL_IN); + bool islike = !isbtw && !isin && Check(OP_SQL_LIKE); + bool isis = !isbtw && !isin && Check(OP_SQL_IS); + + CalcNodePtr out_node; + if(isbtw) { + CalcNodePtr lbound = ScanBitOr(); + Force(OP_LOG_AND, "and"); + CalcNodePtr ubound = ScanBitOr(); + out_node = new CalcLogAndNode( + new CalcFunctionNode(">=", node, lbound), + new CalcFunctionNode("<=", node, ubound)); + } + else if(isin) { + Vector lov; + if(Check(OP_LPAR)) { + do + lov.Add() = ScanSelect(); + while(Check(OP_COMMA)); + Force(OP_RPAR, ")"); + out_node = new CalcFunctionNode("in", node, + new CalcFunctionNode("[,,]", lov)); + } + else + out_node = new CalcConstNode(Value()); + } + else if(islike) { + CalcNodePtr lexpr = ScanSelect(); + out_node = new CalcFunctionNode("like", node, lexpr); + } + else if(isis) { + Force(OP_SQL_NULL, "NULL"); + out_node = new CalcFunctionNode("is_null", node); + } + else if(isnot) + throw Exc(t_("expected 'between', 'in' or 'like'")); + else + return node; + + if(!isnot) + return out_node; + return new CalcFunctionNode("!", out_node); + } } CalcNodePtr CalcParser::ScanBitOr() @@ -1562,34 +1606,87 @@ int CalcParser::GetOperator() return op_last; Skip(); op_begin = op_end = pos; - switch(*op_end++) - { - case '?': op_last = OP_QUESTION; break; - case ':': op_last = OP_COLON; break; - case ';': op_last = OP_SEMICOLON; break; - case '&': op_last = (*op_end == '&' ? op_end++, OP_LOG_AND : OP_BIT_AND); break; - case '|': op_last = (*op_end == '|' ? op_end++, OP_LOG_OR : OP_BIT_OR); break; - case '^': op_last = OP_BIT_XOR; break; - case '<': op_last = (*op_end == '=' ? op_end++, OP_LE : *op_end == '<' ? op_end++, OP_LSHIFT : OP_LT); break; - case '>': op_last = (*op_end == '=' ? op_end++, OP_GE : *op_end == '>' ? op_end++, OP_RSHIFT : OP_GT); break; - case '!': op_last = (*op_end == '=' ? op_end++, OP_NE : OP_LOG_NOT); break; - case '=': op_last = (*op_end == '=' ? op_end++, OP_EQ : (op_end--, OP_NONE)); break; - case '+': op_last = OP_ADD; break; - case '-': op_last = OP_SUB; break; - case '*': op_last = (*op_end == '*' ? op_end++, OP_POW : OP_MUL); break; - case '/': op_last = OP_DIV; break; - case '%': op_last = OP_MOD; break; - case '~': op_last = OP_BIT_NOT; break; - case '#': op_last = OP_LAMBDA; break; - case '(': op_last = OP_LPAR; break; - case ')': op_last = OP_RPAR; break; - case '[': op_last = OP_LBRACKET; break; - case ']': op_last = OP_RBRACKET; break; - case '{': op_last = OP_LBRACE; break; - case '}': op_last = OP_RBRACE; break; - case ',': op_last = OP_COMMA; break; - case '.': op_last = (*op_end == '.' ? op_end++, OP_DOTS : OP_DOT); break; - default: op_end--; op_last = OP_NONE; break; + switch(*op_end++) { + case '?': op_last = OP_QUESTION; break; + case ':': op_last = OP_COLON; break; + case ';': op_last = OP_SEMICOLON; break; + case '&': op_last = (*op_end == '&' ? op_end++, OP_LOG_AND : OP_BIT_AND); break; + case '|': op_last = (*op_end == '|' ? op_end++, OP_LOG_OR : OP_BIT_OR); break; + case '^': op_last = OP_BIT_XOR; break; + case '<': { + if(*op_end == '=') { + op_end++; + op_last = OP_LE; + } + else if(*op_end == '<') { + op_end++; + op_last = OP_LSHIFT; + } + else if(sql_style && *op_end == '>') { + op_end++; + op_last = OP_NE; + } + else + op_last = OP_LT; + break; + } + case '>': op_last = (*op_end == '=' ? op_end++, OP_GE : *op_end == '>' ? op_end++, OP_RSHIFT : OP_GT); break; + case '!': op_last = (*op_end == '=' ? op_end++, OP_NE : OP_LOG_NOT); break; + case '=': { + if(*op_end == '=') { + op_end++; + op_last = OP_EQ; + } + else if(sql_style) + op_last = OP_EQ; + else { + op_end--; + op_last = OP_NONE; + } + break; + } + case '+': op_last = OP_ADD; break; + case '-': op_last = OP_SUB; break; + case '*': op_last = (*op_end == '*' ? op_end++, OP_POW : OP_MUL); break; + case '/': op_last = OP_DIV; break; + case '%': op_last = OP_MOD; break; + case '~': op_last = OP_BIT_NOT; break; + case '#': op_last = OP_LAMBDA; break; + case '(': op_last = OP_LPAR; break; + case ')': op_last = OP_RPAR; break; + case '[': op_last = OP_LBRACKET; break; + case ']': op_last = OP_RBRACKET; break; + case '{': op_last = OP_LBRACE; break; + case '}': op_last = OP_RBRACE; break; + case ',': op_last = OP_COMMA; break; + case '.': op_last = (*op_end == '.' ? op_end++, OP_DOTS : OP_DOT); break; + default: { + op_end--; + op_last = OP_NONE; + if(sql_style && IsAlpha(*op_end)) { + const char *b = op_end; + while(IsAlNum(*++op_end) || *op_end == '_') + op_end++; + int len = (int)(op_end - b); + if(len == 3 && !MemICmp(b, "and", 3)) + op_last = OP_LOG_AND; + else if(len == 2 && !MemICmp(b, "or", 2)) + op_last = OP_LOG_OR; + else if(len == 7 && !MemICmp(b, "between", 7)) + op_last = OP_SQL_BETWEEN; + else if(len == 2 && !MemICmp(b, "in", 2)) + op_last = OP_SQL_IN; + else if(len == 4 && !MemICmp(b, "like", 4)) + op_last = OP_SQL_LIKE; + else if(len == 3 && !MemICmp(b, "not", 3)) + op_last = OP_SQL_NOT; + else if(len == 2 && !MemICmp(b, "is", 2)) + op_last = OP_SQL_IS; + else + op_end = b; + } + break; + } } return op_last; } diff --git a/uppsrc/TCore/CalcNode.h b/uppsrc/TCore/CalcNode.h index fc7fa3d6f..984c862b3 100644 --- a/uppsrc/TCore/CalcNode.h +++ b/uppsrc/TCore/CalcNode.h @@ -407,7 +407,7 @@ struct CalcType : public CalcRawType class CalcParser { public: - CalcParser(); + CalcParser(bool sql_style = false); virtual CalcNodePtr Scan(const char *text); virtual CalcNodePtr ScanVoid(const char *text); @@ -460,6 +460,8 @@ protected: OP_LBRACE, OP_RBRACE, OP_COMMA, OP_DOT, OP_DOTS, + OP_SQL_BETWEEN, OP_SQL_IN, OP_SQL_LIKE, + OP_SQL_IS, OP_SQL_NOT, OP_SQL_NULL, OP_LAST, }; @@ -470,6 +472,8 @@ protected: bool Force(int op, const char *expect); protected: + bool sql_style; + const char *start; const char *pos; diff --git a/uppsrc/TCore/init b/uppsrc/TCore/init index 635fc0e1c..548365a0f 100644 --- a/uppsrc/TCore/init +++ b/uppsrc/TCore/init @@ -3,7 +3,7 @@ #include "Core/init" #include "Web/init" #include "plugin\dbf/init" -#define BLITZ_INDEX__ FD099C670A4F9F921B7251BA8CFD143CC +#define BLITZ_INDEX__ F86AECB90B8BCD14D16E5FB9629D58AB4 #include "TCore_init.icpp" #undef BLITZ_INDEX__ #endif