mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
+Ole: SAFEARRAY constructor helpers
+TCore: SQL-style extensions to calculator parser git-svn-id: svn://ultimatepp.org/upp/trunk@2546 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
0a4c6b19d4
commit
b8050edebb
6 changed files with 217 additions and 66 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -247,12 +247,24 @@ ValueArray SAFEARRAYToValueArray(SAFEARRAY *array)
|
|||
return SAFEARRAYToValueArrayPart(array, indices.Begin(), ndims - 1);
|
||||
}
|
||||
|
||||
SAFEARRAY * ValueArrayToSAFEARRAY(const ValueArray& varray)
|
||||
Vector<WString> SAFEARRAYToWStringVector(SAFEARRAY *array)
|
||||
{
|
||||
SAFEARRAYBOUND rgsabound;
|
||||
rgsabound.lLbound = 0;
|
||||
rgsabound.cElements = varray.GetCount();
|
||||
SAFEARRAY *a = SafeArrayCreate(VT_VARIANT, 1, &rgsabound);
|
||||
Vector<WString> out;
|
||||
out.SetCount(array->rgsabound[0].cElements);
|
||||
Vector<long> 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<WString>& 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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<WString> SAFEARRAYToWStringVector(SAFEARRAY *array);
|
||||
SAFEARRAY *ToSAFEARRAY(const ValueArray& varray);
|
||||
SAFEARRAY *ToSAFEARRAY(const Vector<WString>& varray);
|
||||
void ReturnSAFEARRAY(SAFEARRAY *dest, const ValueArray& array);
|
||||
void ReturnSAFEARRAY(SAFEARRAY *dest, const Vector<WString>& array);
|
||||
HRESULT CheckReturnSAFEARRAY(SAFEARRAY *dest, const ValueArray& array);
|
||||
HRESULT CheckReturnSAFEARRAY(SAFEARRAY *dest, const Vector<WString>& array);
|
||||
|
||||
class OleSafeArray {
|
||||
public:
|
||||
OleSafeArray() : array(NULL) {}
|
||||
OleSafeArray(const ValueArray& va) { array = ToSAFEARRAY(va); }
|
||||
OleSafeArray(const Vector<WString>& 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<WString> () 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 T>
|
||||
class IRefBase : Moveable< IRefBase<T> >
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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<CalcNodePtr> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -407,7 +407,7 @@ struct CalcType<CalcNodePtr> : public CalcRawType<CalcNodePtr>
|
|||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue