diff --git a/include/assoc.cpp b/include/assoc.cpp index 0d5b3d267..17c2132cb 100755 --- a/include/assoc.cpp +++ b/include/assoc.cpp @@ -239,9 +239,10 @@ TObject* TAssoc_array::objptr( // @flag FALSE | Se la chiave non esiste bool TAssoc_array::is_key( const char* key) const // @parm Chiave da cercarne l'esistenza - { - return objptr(key) != NULL; + bool isnew = FALSE; + THash_object* o = ((TAssoc_array *)this)->_lookup(key,isnew); + return o != NULL; } // @doc EXTERNAL diff --git a/include/assoc.h b/include/assoc.h index 7f759b8f1..d56364b0a 100755 --- a/include/assoc.h +++ b/include/assoc.h @@ -35,8 +35,8 @@ public: TObject& obj() const { return *_obj; } - // @cmember Costruttore (inizializza la chiave) - THash_object(const char* k) : _key(k), _obj(NULL) + // @cmember Costruttore (inizializza la chiave ed opzionalmente l'oggetto) + THash_object(const char* k, TObject* o = NULL) : _key(k), _obj(o) {} // @cmember Distruttore ~THash_object() diff --git a/include/expr.cpp b/include/expr.cpp index 3099fc7f9..f9889b083 100755 --- a/include/expr.cpp +++ b/include/expr.cpp @@ -1,4 +1,5 @@ #include +#include #include #define __EXPR_CPP @@ -126,6 +127,58 @@ const char* TVararray::getstring(int varnum) const TVar* var = (const TVar*)objptr(varnum); CHECKD(var, "Variabile nulla: ", varnum); return var->string(); +} + +/////////////////////////////////////////////////////////// +// TEval_stack +/////////////////////////////////////////////////////////// + +real& TEval_stack::pop_real() +{ + TObject& o = pop(); + if (o.class_id() == CLASS_STRING) + { + real* r = new real((TString&)o); + push(r); + return (real&)pop(); + } + return (real&)o; +} + +real& TEval_stack::peek_real() +{ + TObject& o = peek(0); + if (o.class_id() == CLASS_STRING) + { + pop(); + real* r = new real((TString&)o); + push(r); + return *r; + } + return (real&)o; +} + +TString& TEval_stack::pop_string() +{ + TObject& o = pop(); + if (o.class_id() == CLASS_STRING) + return (TString&)o; + + TString* s = new TString(((real&)o).string()); + push(s); + return (TString&)pop(); +} + +TString& TEval_stack::peek_string() +{ + TObject& o = peek(); + if (o.class_id() == CLASS_STRING) + return (TString&)o; + + pop(); + TString* s = new TString(((real&)o).string()); + push(s); + return *s; } @@ -134,13 +187,13 @@ const char* TVararray::getstring(int varnum) /////////////////////////////////////////////////////////// TExpression::TExpression(const char* expression, TTypeexp type) -: _original(expression) + : _original(expression) { _val = real(0.0); _dirty = TRUE; _type = type; - if (!compile(expression, type)) + if (!compile(_original, type)) { error_box("Wrong expression : %s", expression); _code.clear(); @@ -149,8 +202,7 @@ TExpression::TExpression(const char* expression, TTypeexp type) TExpression::TExpression(TTypeexp type) -: _original("") - + : _original("") { _val = real(0.0); _dirty = FALSE; @@ -162,7 +214,6 @@ TExpression::TExpression(const TExpression & expr) : _code(expr._code), _var(expr._var), _val(expr._val), _dirty(expr._dirty), _type(expr._type), _original(expr._original) - { } @@ -173,7 +224,6 @@ TObject* TExpression::dup() const } TExpression::operator const real&() - { if (user_func_dirty() || _dirty) eval(); _dirty = FALSE; @@ -182,20 +232,25 @@ TExpression::operator const real&() TExpression::operator const char*() - { if (user_func_dirty() || _dirty) eval(); _dirty = FALSE; return _val.string(); } +TExpression::operator bool() +{ + if (user_func_dirty() || _dirty) eval(); + _dirty = FALSE; + return !_val.number().is_zero(); +} void TExpression::print_on(ostream& out) const { out << _original; } -void TExpression::evaluate_user_func(int index, int nparms, TStack & stack, TTypeexp type) const +void TExpression::evaluate_user_func(int index, int nparms, TEval_stack& stack, TTypeexp curtype) const { - CHECKD(FALSE, "Unknown function ", index); + NFCHECK("Unknown function %d.", index); for ( int i = nparms ; i > 0; i--) stack.pop(); if (curtype == _numexpr) @@ -204,15 +259,6 @@ void TExpression::evaluate_user_func(int index, int nparms, TStack & stack, TTyp stack.push(TString("")); } -TExpression::operator bool() - -{ - if (user_func_dirty() || _dirty) eval(); - _dirty = FALSE; - return !_val.number().is_zero(); -} - - void TExpression::setvar(const char* varname, const real& val) { @@ -261,12 +307,12 @@ bool TExpression::print_error(const char* msg) const void TExpression::eval() { - TStack evalstack(50); - TBit_array types; - int type_pointer = 0; - TCode instr; - real o1, o2; - TString s1, s2; + TEval_stack evalstack; + TBit_array types; + int type_pointer = 0; + TCode instr; + real o1, o2; + TString s1, s2; types.set(type_pointer, (_type == _numexpr)); @@ -303,161 +349,171 @@ void TExpression::eval() break; case _plus: if (type == _strexpr) - { - s2 = (TString&) evalstack.pop(); - s1 = (TString&) evalstack.pop(); + { +/* + s2 = evalstack.pop_string(); + s1 = evalstack.pop_string(); s1 << s2; evalstack.push(s1); +*/ + // Non unire le seguenti righe + const TString& s = evalstack.pop_string(); + evalstack.peek_string() << s; } else { - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); +/* + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(real(o1 + o2)); +*/ + // Non unire le seguenti righe + const real& r = evalstack.pop_real(); + evalstack.peek_real() += r; } break; case _minus: - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(real(o1 - o2)); break; case _multiply: - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(real(o1 * o2)); break; case _divide: - o2 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); if (o2.is_zero()) { print_error("Divisione per zero!"); o2 = 1.0; } - o1 = (real&) evalstack.pop(); + o1 = evalstack.pop_real(); evalstack.push(real(o1 / o2)); break; case _chgs: - o1 = (real&) evalstack.pop(); + o1 = evalstack.pop_real(); evalstack.push(-o1); break; case _and: if (type == _strexpr) { - o2 = real((const char*)(TString&)evalstack.pop()); - o1 = real((const char*)(TString&)evalstack.pop()); + o2 = real((const char*)evalstack.pop_string()); + o1 = real((const char*)evalstack.pop_string()); evalstack.push(TString((o1 != ZERO && o2 != ZERO) ? "1" : "0")); } else { - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(real((o1 != ZERO && o2 != ZERO) ? 1.0 : 0.0)); } break; case _or: if (type == _strexpr) { - o2 = real((const char*) (TString&)evalstack.pop()); - o1 = real((const char*) (TString&)evalstack.pop()); + o2 = real((const char*) evalstack.pop_string()); + o1 = real((const char*) evalstack.pop_string()); evalstack.push(TString((o1 != ZERO || o2 != ZERO) ? "1" : "0")); } else { - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(real((o1 != ZERO || o2 != ZERO) ? 1.0 : 0.0)); } break; case _not: - o1 = (real&) evalstack.pop(); + o1 = evalstack.pop_real(); evalstack.push(real((o1 == ZERO) ? 1.0 : 0.0)); break; case _equal: if (type == _strexpr) { - s2 = (TString&) evalstack.pop(); - s1 = (TString&) evalstack.pop(); + s2 = evalstack.pop_string(); + s1 = evalstack.pop_string(); evalstack.push(TString((s1 == s2) ? "1" : "0")); } else { - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(real((o1 == o2) ? 1.0 : 0.0)); } break; case _match: - s2 = (TString&) evalstack.pop(); - s1 = (TString&) evalstack.pop(); + s2 = evalstack.pop_string(); + s1 = evalstack.pop_string(); evalstack.push(TString((s1.match(s2)) ? "1" : "0")); break; case _noteq: if (type == _strexpr) { - s2 = (TString&) evalstack.pop(); - s1 = (TString&) evalstack.pop(); + s2 = evalstack.pop_string(); + s1 = evalstack.pop_string(); evalstack.push(TString(s1 != s2 ? "1" : "0")); } else { - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(real((o1 != o2) ? 1.0 : 0.0)); } break; case _lt: if (type == _strexpr) { - s2 = (TString&) evalstack.pop(); - s1 = (TString&) evalstack.pop(); + s2 = evalstack.pop_string(); + s1 = evalstack.pop_string(); evalstack.push(TString((s1 < (const char*)s2) ? "1" : "0")); } else { - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(real((o1 < o2) ? 1.0 : 0.0)); } break; case _gt: if (type == _strexpr) { - s2 = (TString&) evalstack.pop(); - s1 = (TString&) evalstack.pop(); + s2 = evalstack.pop_string(); + s1 = evalstack.pop_string(); evalstack.push(TString((s1 > (const char*)s2) ? "1" : "0")); } else { - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(real((o1 > o2) ? 1.0 : 0.0)); } break; case _lteq: if (type == _strexpr) { - s2 = (TString&) evalstack.pop(); - s1 = (TString&) evalstack.pop(); + s2 = evalstack.pop_string(); + s1 = evalstack.pop_string(); evalstack.push(TString((s1 <= (const char*)s2) ? "1" : "0")); } else { - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(real((o1 <= o2) ? 1.0 : 0.0)); } break; case _gteq: if (type == _strexpr) { - s2 = (TString&) evalstack.pop(); - s1 = (TString&) evalstack.pop(); + s2 = evalstack.pop_string(); + s1 = evalstack.pop_string(); evalstack.push(TString((s1 >= (const char*)s2) ? "1" : "0")); } else { - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(real((o1 >= o2) ? 1.0 : 0.0)); } break; @@ -470,41 +526,41 @@ void TExpression::eval() } break; case _sqrt: - evalstack.push(real(sqrt((real&) evalstack.pop()))); + evalstack.push(real(sqrt(evalstack.pop_real()))); break; case _sqr: - evalstack.push(real(sqr((real&) evalstack.pop()))); + evalstack.push(real(sqr(evalstack.pop_real()))); break; case _exp10: - evalstack.push(real(exp10((real&) evalstack.pop()))); + evalstack.push(real(exp10(evalstack.pop_real()))); break; case _exp: - evalstack.push(real(exp((real&) evalstack.pop()))); + evalstack.push(real(exp(evalstack.pop_real()))); break; case _log10: - evalstack.push(real(log10((real&) evalstack.pop()))); + evalstack.push(real(log10(evalstack.pop_real()))); break; case _log: - evalstack.push(real(log((real&) evalstack.pop()))); + evalstack.push(real(log(evalstack.pop_real()))); break; case _sin: - evalstack.push(real(sin((real&) evalstack.pop()))); + evalstack.push(real(sin(evalstack.pop_real()))); break; case _cos: - evalstack.push(real(cos((real&) evalstack.pop()))); + evalstack.push(real(cos(evalstack.pop_real()))); break; case _tan: - evalstack.push(real(tan((real&) evalstack.pop()))); + evalstack.push(real(tan(evalstack.pop_real()))); break; case _left: - o2 = (real&) evalstack.pop(); - s2 = (TString&) evalstack.pop(); + o2 = evalstack.pop_real(); + s2 = evalstack.pop_string(); s1 = s2.left((int)o2.integer()); evalstack.push(s1); break; case _right: - o2 = (real&) evalstack.pop(); - s2 = (TString&) evalstack.pop(); + o2 = evalstack.pop_real(); + s2 = evalstack.pop_string(); s1 = s2.right((int)o2.integer()); evalstack.push(s1); break; @@ -512,7 +568,8 @@ void TExpression::eval() { int count = (int)((const real&)evalstack.pop()).integer(); if (count == 0) count--; - const int from = (int)((const real&)evalstack.pop()).integer() - 1; + int from = (int)((const real&)evalstack.pop()).integer() - 1; + if (from < 0) from = 0; const TString& s = ((const TString&)evalstack.pop()).mid(from, count); evalstack.push(s); } @@ -520,59 +577,63 @@ void TExpression::eval() case _substr: { const int to = (int)((const real&)evalstack.pop()).integer(); - const int from = (int)((const real&)evalstack.pop()).integer() - 1; + int from = (int)((const real&)evalstack.pop()).integer() - 1; + if (from < 0) from = 0; const TString& s = ((const TString&)evalstack.pop()).sub(from, to); evalstack.push(s); } break; case _pow: - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); evalstack.push(real(pow(o1, o2))); break; case _min: o2 = (real&)evalstack.pop(); o1 = (real&)evalstack.pop(); - evalstack.push(real(fnc_min(o1, o2))); + evalstack.push(o1 < o2 ? o1 : o2); break; case _max: - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); - evalstack.push(real(fnc_max(o1, o2))); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); + evalstack.push(o1 > o2 ? o1 : o2); break; case _upper: - s1 = (TString&) evalstack.pop(); +/* + s1 = evalstack.pop_string(); s1.upper(); evalstack.push(s1); +*/ + evalstack.peek_string().upper(); break; case _round: { - const int ndec = (int)((real&) evalstack.pop()).integer(); - o1 = (real&) evalstack.pop(); + const int ndec = (int)(evalstack.pop_real()).integer(); + o1 = evalstack.pop_real(); o1.round(ndec); evalstack.push(o1); } break; case _trunc: { - const int ndec = (int)((real&) evalstack.pop()).integer(); - o1 = (real&) evalstack.pop(); + const int ndec = (int)(evalstack.pop_real()).integer(); + o1 = evalstack.pop_real(); o1.trunc(ndec); evalstack.push(o1); } break; case _ceil: { - const int ndec = (int)((real&) evalstack.pop()).integer(); - o1 = (real&) evalstack.pop(); + const int ndec = (int)(evalstack.pop_real()).integer(); + o1 = evalstack.pop_real(); o1.ceil(ndec); evalstack.push(o1); } break; case _perc: { - o2 = (real&) evalstack.pop(); - o1 = (real&) evalstack.pop(); + o2 = evalstack.pop_real(); + o1 = evalstack.pop_real(); const real val = real(o1 * o2 / 100.0); evalstack.push(val); } @@ -589,16 +650,16 @@ void TExpression::eval() { if (type == _strexpr) { - s1 = (TString&)evalstack.pop(); - s2 = (TString&)evalstack.pop(); - const real cond = (real) (TString&) evalstack.pop();; + s1 = evalstack.pop_string(); + s2 = evalstack.pop_string(); + const real cond(evalstack.pop_string()); evalstack.push(cond.is_zero() ? s1 : s2); } else { o1 = (real&)evalstack.pop(); o2 = (real&)evalstack.pop(); - const real cond = (real&) evalstack.pop();; + const real cond = (real&)evalstack.pop(); evalstack.push(cond.is_zero() ? o1 : o2); } } @@ -636,11 +697,17 @@ void TExpression::eval() break; } } - - if (_type == _strexpr) - _val = (TString&)evalstack.pop(); + + // L'espressione non e' vuota + if (_code.items() > 1) + { + if (_type == _strexpr) + _val = evalstack.pop_string(); + else + _val = evalstack.pop_real(); + } else - _val = (real&)evalstack.pop(); + _val = ZERO; } @@ -667,42 +734,49 @@ TCodesym TExpression::tok2fun(const char* tok) const int f = 0, l = MAX_TOK-1, i; while (TRUE) { - i = (f+l)>>1; +// i = (f+l)>>1; + i = (toupper(*tok) - *fnstr[f]) * (l-f+1) / (*fnstr[l] - *fnstr[f] + 1); + if (i < f || i > l) + return _invalid; + const int cmp = stricmp(tok, fnstr[i]); if (cmp == 0) break; if (cmp > 0) f = i+1; else l = i-1; + if (f > l) - { - i = -1; - break; - } - } - return i >= 0 ? fntok[i] : _invalid; + return _invalid; + } + CHECKD(i >= 0 && i < MAX_TOK, "Invalid function index ", i); + return fntok[i]; } -TCodesym TExpression::__gettoken(bool reduct) +TCodesym TExpression::__gettoken(bool /* reduct */) { TCodesym sym = _invalid; - int i = 0; + int i = 0; _tok[0] = '\0'; while (isspace(*_s)) _s++; if (!*_s) return _endsym; + +/* if ((reduct) && (*_s == ',')) { _s++; return _comma; } - if (isdigit(*_s) || (*_s == '.') || (*_s == ',')) +*/ + + if (isdigit(*_s) || (*_s == '.') /* || (*_s == ',') */) { sym = _number; - while (isalpha(*_s) || isdigit(*_s) || (*_s == '-') || (*_s == '[') || + while (isalnum(*_s) || (*_s == '-') || (*_s == '[') || (*_s == ']') || (*_s == '.') || (*_s == ':') || - (!reduct && (*_s == ','))) + (*_s == '_') || (sym == _variable && (*_s == ','))) { if (*_s == '-') { @@ -714,19 +788,22 @@ TCodesym TExpression::__gettoken(bool reduct) else { if (sym == _number) - if ((isalpha(*_s)) ||(*_s == '[') || (*_s == ']') || - (*_s == ',') || (*_s == ':')) sym = _variable; + { + if (isalpha(*_s) || (*_s == '[') || (*_s == ']') || + (*_s == ',') || (*_s == ':') || (*_s == '_')) + sym = _variable; + } _tok[i++] = *(_s++); } } _tok[i] = '\0'; return sym; } - if (isalpha(*_s) || (*_s == '#')) + if (isalpha(*_s) || (*_s == '#') || (*_s == '_')) { _tok[i++] = *(_s++); - while (isalpha(*_s) || isdigit(*_s) || (*_s == '-') || (*_s == '[') || - (*_s == ']') || (*_s == ':') || (!reduct && (*_s == ','))) + while (isalnum(*_s) || (*_s == '-') || (*_s == '[') || + (*_s == ']') || (*_s == ':') || (*_s == ',') || (*_s == '_')) { if (*_s == '-') { @@ -760,7 +837,8 @@ TCodesym TExpression::__gettoken(bool reduct) return _string; } case ',' : - _s++; + _tok[i++] = *(_s++); + _tok[i] = '\0'; return _comma; case '(' : _tok[i++] = *(_s++); @@ -854,18 +932,38 @@ TCodesym TExpression::__factor(TCodesym startsym) case _lpar: sym = __gettoken(); sym = __expression(sym); - if (sym == _rpar) sym = __gettoken(); + if (sym == _rpar) sym = __gettoken(); + else sym = _invalid; break; case _variable: + { + int from = 1, to = 0; + char* quadra = strchr(_tok, '['); + if (quadra) + { + if (sscanf(quadra, "[%d,%d]", &from, &to) == 0) + { + sym = _invalid; + break; + } + *quadra = '\0'; + } + _code.add(_variable, _tok); + if (quadra) + { + _code.add(_number, real(from)); + _code.add(_number, real(to > from ? to-from+1 : 0)); + _code.add(_mid); + } + for (int i = numvar()-1 ; i >= 0; i--) + if (strcmp(_tok, varname(i)) == 0) break; + if (i < 0) _var.add(_tok); + sym = __gettoken(TRUE); + } + break; case _number: case _string: _code.add(startsym, _tok); - if (startsym == _variable) - { - for (int i = 0 ; i < numvar(); i++) - if (strcmp(_tok, varname(i)) == 0) break; - if (i == numvar()) _var.add(_tok); - } sym = __gettoken(TRUE); break; case _userfunc: @@ -901,6 +999,8 @@ TCodesym TExpression::__factor(TCodesym startsym) sym = __gettoken(TRUE); } } + else + sym = _invalid; } } break; @@ -926,8 +1026,7 @@ TCodesym TExpression::__factor(TCodesym startsym) sym = __gettoken(); if (sym == _lpar) sym = __gettoken(); else break; - if ((sym == _string) || (sym == _variable)) sym = __expression(sym); - else break; + sym = __expression(sym); if (sym == _rpar) sym = __gettoken(); else break; _code.add(startsym); @@ -958,8 +1057,7 @@ TCodesym TExpression::__factor(TCodesym startsym) sym = __gettoken(); if (sym == _lpar) sym = __gettoken(TRUE); else break; - if ((sym == _string) || (sym == _variable)) sym = __expression(sym); - else break; + sym = __expression(sym); if (sym == _comma) sym = __gettoken(TRUE); else break; sym = __expression(sym); @@ -1005,29 +1103,25 @@ TCodesym TExpression::__factor(TCodesym startsym) TCodesym TExpression::__term(TCodesym startsym) { - TCodesym sym; - - sym = __factor(startsym); - while ((sym != _endsym) && ((sym == _multiply) || (sym == _divide))) + TCodesym sym = __factor(startsym); + while (sym == _multiply || sym == _divide) { - TCodesym savedsym = sym; + const TCodesym savedsym = sym; sym = __gettoken(); sym = __factor(sym); _code.add(savedsym); } - return sym; } TCodesym TExpression::__expression(TCodesym startsym) - { TCodesym sym; - if ((startsym == _minus) || (startsym == _not) || (startsym == _plus)) sym =__gettoken(); - else sym = startsym; + else + sym = startsym; sym = __term(sym); if ((startsym == _minus) || (startsym == _not)) _code.add(startsym == _not ? startsym : _chgs); @@ -1050,18 +1144,20 @@ bool TExpression::set(const char* expression, TTypeexp type) _original = expression; _type = type; _dirty = TRUE; - return compile(expression, type); + return compile(_original, type); } bool TExpression::compile(const char* expression, TTypeexp type) { - TString sc(256); TCodesym currsym; _user_func_defined = FALSE; _s = expression; - _type = type; + _type = type; + +/* + TString sc(256); while (((currsym = __gettoken()) != _endsym) && (currsym != _invalid)) { if (currsym == _variable) @@ -1102,14 +1198,17 @@ bool TExpression::compile(const char* expression, TTypeexp type) else sc << " " << _tok; } _s = sc; +*/ _val = real(0.0); _code.clear(); - if (!*_s) return TRUE; - if ((currsym = __gettoken()) == _invalid) return FALSE; + if (*_s == '\0') + return TRUE; + if ((currsym = __gettoken()) == _invalid) + return FALSE; return __expression(currsym) == _endsym; } -const char* TExpression::last_compiled_token() const +const char* TExpression::last_token() const { return _tok; } diff --git a/include/expr.h b/include/expr.h index d06905baf..5f2dbed49 100755 --- a/include/expr.h +++ b/include/expr.h @@ -1,14 +1,15 @@ #ifndef __EXPR_H #define __EXPR_H -#ifndef __STRINGS_H -#include -#endif - #ifndef __REAL_H #include #endif +#ifndef __STACK_H +#include +#endif + + // @doc INTERNAL // @enum TCodesym | Lista di simboli/istruzioni possibili @@ -363,7 +364,14 @@ public: {} }; -class TStack; +class TEval_stack : public TStack +{ +public: + real& pop_real(); + real& peek_real(); + TString& pop_string(); + TString& peek_string(); +}; // @doc EXTERNAL @@ -396,7 +404,7 @@ class TExpression : public TObject // @access Protected Member protected: // @cmember funzione utente da ricalcolare - virtual bool user_func_dirty() { return _user_func_defined;} + virtual bool user_func_dirty() const { return _user_func_defined; } // @cmember stampa un messaggio d'errore virtual bool print_error(const char* msg) const; // @cmember Valuta (calcola) l'espressione @@ -418,7 +426,7 @@ protected: protected: // TObject // @cmember Stampa l'espressione su

(serve per implementare l'insertore) virtual void print_on(ostream& out) const ; - virtual void evaluate_user_func(int index, int nparms, TStack & stack, TTypeexp type) const; + virtual void evaluate_user_func(int index, int nparms, TEval_stack& stack, TTypeexp type) const; virtual int parse_user_func(const char * name, int nparms) const { return -1; } // @access Public Member @@ -460,7 +468,7 @@ public: { _type = type; } // @cmember Setta l'espressione e la compila (ritorna il risultato della compilazione) bool set(const char* expression, TTypeexp type = _numexpr); - const char* last_compiled_token() const; + const char* last_token() const; // @cmember Ritorna l'espressione originale const char * string() const { return _original; } diff --git a/include/printapp.cpp b/include/printapp.cpp index a146c5ab8..5a424e6c6 100755 --- a/include/printapp.cpp +++ b/include/printapp.cpp @@ -886,7 +886,7 @@ void TPrint_application::set_row ( if (ch == 't' || ch == 'a') t << 's'; else if (ch == 'r') -#ifdef __LONGDOUBLE +#ifdef __LONGDOUBLE__ t << "Lf"; #else t << 't'; diff --git a/include/progind.cpp b/include/progind.cpp index 3119b39e3..2399be421 100755 --- a/include/progind.cpp +++ b/include/progind.cpp @@ -28,14 +28,9 @@ TIndwin::TIndwin(long max, const char* txt, bool cancel, bool bar, int div) word maxlen = div; const word lines = measure_text(testo, maxlen); - int ver = lines+3; int hor = maxlen+3; if (hor > 78) hor = 78; - - if (bar) - { - _bar = ver * CHARY; - ver += 2; - } + int ver = lines+3; + ver += bar ? 2 : 0; ver += cancel ? 2 : 0; set_win(create_interface(TASK_WIN, -1, -1, hor, ver, TITLE_TEXT, this, FALSE)); @@ -45,6 +40,12 @@ TIndwin::TIndwin(long max, const char* txt, bool cancel, bool bar, int div) testo.replace('\n', '\r'); _text->set_caption(testo); + if (bar) + { + RCT r; _text->get_rect(r); + _bar = r.bottom + CHARY; + } + if (cancel) { _cancel = new TPushbutton_control(win(), DLG_CANCEL, -11, -1, 10, 2, "", "Annulla", BMP_CANCEL); diff --git a/include/rectypes.h b/include/rectypes.h index 3a242c6cf..040fc8457 100755 --- a/include/rectypes.h +++ b/include/rectypes.h @@ -43,7 +43,7 @@ enum TDirop { // @enum TFieldtypes | Elenco tipi di campi enum TFieldtypes { - _nullfld, // @emem Campo vuoto + _nullfld, // @emem Campo non definito _alfafld, // @emem Campo di tipo alfanumerico _intfld, // @emem Campo di tipo intero _longfld, // @emem Campo di tipo intero lungo diff --git a/include/relation.cpp b/include/relation.cpp index 69f6f3632..112232848 100755 --- a/include/relation.cpp +++ b/include/relation.cpp @@ -1271,7 +1271,7 @@ TRecnotype TCursor::readrec() // @rdesc Ritorna il numero di errore che si verifica nel porre il lock (NOERR) se // non si verificano errori int TCursor::lock( - TReclock l) // @parm Tipo di locke da porre sul record (vedi ) + TReclock l) // @parm Tipo di lock da porre sul record (vedi ) { int rt=NOERR; switch(l) @@ -1685,8 +1685,10 @@ TFieldref& TFieldref::operator =( _fileid = pos = 0; } - int par = s.find('[', pos); - _name = s.sub(pos, par); _name.strip(" "); + int par = s.find('[', pos); // Cerca la fine del nome del campo + _name = s.sub(pos, par); // Estrae il nome del campo + _name.strip(" "); // Elimina eventuali spazi superflui + _name.upper(); // Converte in maiuscolo il nome del campo if (par > 0) { diff --git a/include/sheet.cpp b/include/sheet.cpp index 970670909..224279e30 100755 --- a/include/sheet.cpp +++ b/include/sheet.cpp @@ -1081,8 +1081,11 @@ bool TBrowse_sheet::browse_field_handler(TMask_field& f, KEY k) c.set(f.get()); TBrowse* b = e.browse(); - b->do_input(FALSE); - rec = b->cursor()->read(_isgteq); + if (b) + { + b->do_input(FALSE); + rec = b->cursor()->read(_isgteq); + } } else if (k == K_F2) rec = 0; @@ -1125,7 +1128,8 @@ bool TBrowse_sheet::last_browse_field_handler(TMask_field& f, KEY k) TBrowse_sheet::TBrowse_sheet(TCursor* cursor, const char* fields, const char* title, const char* head, byte buttons, TEdit_field* f, TToken_string& sibling) - : TCursor_sheet(cursor, fields, title, head, buttons, f->browse()->input_fields()), + : TCursor_sheet(cursor, fields, title, head, buttons, + f->browse() ? f->browse()->input_fields() : 1), _field(f), _sel(0) { TToken_string ca; // Tag buttons @@ -1143,11 +1147,15 @@ TBrowse_sheet::TBrowse_sheet(TCursor* cursor, const char* fields, if (n > 0) add_tag_button(0, ca, _sel); + TBrowse* browse = f->browse(); + if (browse == NULL) + return; + TToken_string tids = head; TToken_string tfns = fields; - TToken_string ids = f->browse()->get_input_fields(); - TToken_string fns = f->browse()->get_input_field_names(); - + TToken_string ids = browse->get_input_fields(); + TToken_string fns = browse->get_input_field_names(); + TEditable_field* e = NULL; short y = 0; for (const char* i = ids.get(0); i; i = ids.get()) diff --git a/include/stack.cpp b/include/stack.cpp index 7836228ba..9f7f16c80 100755 --- a/include/stack.cpp +++ b/include/stack.cpp @@ -15,12 +15,12 @@ void TStack::push(TObject* o) TObject& TStack::pop() { - CHECK(count() > 0, "Stack underflow!"); + CHECK(_sp > 0, "Stack underflow!"); return (*this)[--_sp]; } TObject& TStack::peek(int depth) const { - CHECK(depth > _sp, "Stack underflow!"); + CHECKD(depth >= 0 && depth < _sp, "Stack depth error: ", depth); return (*this)[_sp-depth-1]; } diff --git a/include/strings.cpp b/include/strings.cpp index e6dbd942c..d8d27e1c0 100755 --- a/include/strings.cpp +++ b/include/strings.cpp @@ -402,7 +402,7 @@ const TString& TString::mid( #ifdef DBG if (from < 0) { - yesnofatal_box("Ivalid MID parameter: from = %d", from); + NFCHECK("Ivalid MID parameter: from = %d", from); from = 0; } #endif @@ -435,11 +435,9 @@ TString& TString::cut(int n) CHECKD(n >= 0, "Invalid TString::cut position ", n); if (n <= _size) _str[n] = '\0'; -#ifdef DBG else - yesnofatal_box("Hai tagliato a %d la stringa '%s' lunga %d(%d)", - n, _str, len(), size()); -#endif + NFCHECK("Hai tagliato a %d la stringa '%s' lunga %d(%d)", + n, _str, len(), size()); return *this; } diff --git a/include/text.h b/include/text.h index bbce14092..6408b10fc 100755 --- a/include/text.h +++ b/include/text.h @@ -198,7 +198,7 @@ public: // @cmember Costruttore TTextfile(const char* file = NULL, int pagesize = DEFAULT_PAGESIZE, direction preferred = updown, bool interactive = TRUE); - // @cmember DIstruttore + // @cmember Distruttore virtual ~TTextfile(); }; diff --git a/include/viswin.cpp b/include/viswin.cpp index de393102e..44a68a0c3 100755 --- a/include/viswin.cpp +++ b/include/viswin.cpp @@ -667,8 +667,8 @@ void TViswin::paint_screen () xvt_dwin_draw_set_pos (win (), b); xvt_dwin_draw_line (win (), e); set_brush (COLOR_DKGRAY); - bar (X_OFFSET-1, (int)(j+(long)Y_OFFSET-origin().y),(int)columns(), - (int)(rows()-(long)BUTTONROW_SIZE)); + bar (X_OFFSET-1, (int)(j+(long)Y_OFFSET-origin().y), + (int)columns()+1, (int)(rows()-(long)BUTTONROW_SIZE)); autoscroll (TRUE); break; #endif @@ -2524,7 +2524,10 @@ TViswin::TViswin(const char *fname, // load info from config on buttons and rulers TConfig cnf(CONFIG_USER, "Visualizzazione"); _showbuts = cnf.get_bool("Bottoni", NULL, -1,TRUE); - _rulers = cnf.get_bool("Righelli", NULL, -1,TRUE); + + // Se rulers vale 3 allora leggi dal config il vero valore + if (_rulers != FALSE && _rulers != TRUE) + _rulers = cnf.get_bool("Righelli", NULL, -1,TRUE); } const int larg = 76; diff --git a/include/viswin.h b/include/viswin.h index 562858f3c..a77f89345 100755 --- a/include/viswin.h +++ b/include/viswin.h @@ -328,11 +328,11 @@ public: void find_next(); // @cmember void | TViswin | const char* fname=NULL, const char* title=NULL, - // bool editbutton=TRUE, int width=0, bool rulers=TRUE, + // bool editbutton=TRUE, int width=0, bool rulers=3, // WINDOW parent=NULL_WIN, TBrowsefile_field*=NULL | Costruttore TViswin(const char* fname=NULL, const char* title=NULL, bool editbutton=TRUE, bool printbutton=TRUE, bool linkbutton=TRUE, int x=-1, int y=-1, int height=0, - int width=0, bool rulers=TRUE, WINDOW parent=NULL_WIN, TBrowsefile_field* =NULL); + int width=0, bool rulers=3, WINDOW parent=NULL_WIN, TBrowsefile_field* =NULL); // @cmember Distruttore virtual ~TViswin (); };