Patch level : 4.0

Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
Aggiunte funzioni BETWEEN,CF_CHECK e PI_CHECK alle espressioni


git-svn-id: svn://10.65.10.50/trunk@14547 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 2006-11-28 11:33:54 +00:00
parent 14e5030651
commit 175d2417b5
5 changed files with 240 additions and 150 deletions

View File

@ -1,11 +1,38 @@
#include <xvt.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#define __EXPR_CPP #define __EXPR_CPP
#include <expr.h> #include <expr.h>
#include <date.h> #include <date.h>
#include <validate.h>
///////////////////////////////////////////////////////////
// TValue
///////////////////////////////////////////////////////////
real& TValue::number()
{
if (_t == _strexpr)
{
if (TDate::isdate(_s))
_r = TDate(_s).date2ansi();
else
_r = real(_s);
_t = _numexpr;
}
return _r;
}
TString& TValue::string()
{
if (_t == _numexpr)
{
_s = _r.string();
_t = _strexpr;
}
return _s;
}
///////////////////////////////////////////////////////////
// TCodearray
///////////////////////////////////////////////////////////
void TCodearray::clear() void TCodearray::clear()
{ {
@ -18,10 +45,13 @@ void TCodearray::add(TCodesym sym, const TValue& val)
TArray::insert(new TCode(sym, val), last()); TArray::insert(new TCode(sym, val), last());
} }
TObject * TCode::dup() const ///////////////////////////////////////////////////////////
// TCode
///////////////////////////////////////////////////////////
TObject* TCode::dup() const
{ {
TCode * o = new TCode(*this); return new TCode(*this);
return o;
} }
TCode& TCode::operator =(const TCode& b) TCode& TCode::operator =(const TCode& b)
@ -31,94 +61,96 @@ TCode& TCode::operator =(const TCode& b)
return *this; return *this;
} }
TObject * TVar::dup() const ///////////////////////////////////////////////////////////
// TVar
///////////////////////////////////////////////////////////
TObject* TVar::dup() const
{ {
TVar * o = new TVar(*this); return new TVar(*this);
return o;
} }
int TVar::compare(const TSortable& s) const
{
const TVar& v = (const TVar&)s;
return _name.compare(v._name);
}
///////////////////////////////////////////////////////////
// TVararray
///////////////////////////////////////////////////////////
void TVararray::add(const char* name, const TValue& val) void TVararray::add(const char* name, const TValue& val)
{ {
TArray::add(new TVar(name, val)); _vars.add(new TVar(name, val));
_vars.sort(); // Brutto, ma per ora va bene qui;
}
TVar* TVararray::find(int i) const
{
TVar* v = (TVar*)_vars.objptr(i);
CHECKD(v, "Variabile non trovata:", i);
return v;
}
TVar* TVararray::find(const char* name) const
{
int mi = 0, ma = _vars.last(), i = 0;
while(mi <= ma)
{
i = (mi+ma)/2;
TVar* v = find(i);
const int cmp = v->getname().compare(name);
if (cmp == 0)
return v;
if (cmp < 0)
mi = i+1;
else
ma = i-1;
}
for (i = _vars.last(); i >= 0; i--)
{
TVar* v = find(i);
if (v->getname() == name)
return v; // Se passa di qua ... m'incazzo
}
CHECKS(NULL, "Variabile non trovata:", name);
return NULL;
} }
void TVararray::set(const char* name, const real& val) void TVararray::set(const char* name, const real& val)
{ {
for (int i = last(); i >= 0; i--) TVar* v = find(name);
{ if (v != NULL)
TVar* var = (TVar*)objptr(i); *v = val;
if (var->getname() == name)
{
*var = val;
return;
}
}
NFCHECK("Variabile non trovata: %s", name);
} }
void TVararray::set(const char* name, const char* val) void TVararray::set(const char* name, const char* val)
{ {
for (int i = last(); i >= 0; i--) TVar* v = find(name);
{ if (v != NULL)
TVar* var = (TVar*)objptr(i); *v = val;
if (var->getname() == name)
{
*var = val;
return;
}
}
NFCHECK("Variabile non trovata: %s", name);
} }
const real& TVararray::getnum(const char* name) const real& TVararray::getnum(const char* name)
{ {
for (int i = items()-1; i >= 0; i--) TVar* v = find(name);
{ if (v != NULL)
TVar* var = (TVar*)objptr(i); return v->number();
if (var->getname() == name)
return var->number();
}
NFCHECK("Unknown variable: %s", name);
return ZERO; return ZERO;
} }
const real& TVararray::getnum(int varnum)
{
if (varnum < 0 || varnum >= items())
{
NFCHECK("Invalid variable number : %d", varnum);
return ZERO;
}
return ((TVar*)objptr(varnum))->number();
}
const TString& TVararray::getstring(const char* name) const TString& TVararray::getstring(const char* name)
{ {
for (int i = last(); i >= 0; i--) TVar* v = find(name);
{ if (v != NULL)
TVar* var = (TVar*)objptr(i); return v->string();
if (var->getname() == name)
return var->string();
}
NFCHECK("Unknown variable : %s", name);
return EMPTY_STRING; return EMPTY_STRING;
} }
const TString& TVararray::getstring(int varnum)
{
TVar* var = (TVar*)objptr(varnum);
if (var == NULL)
{
NFCHECK("Invalid variable number : %d", varnum);
return EMPTY_STRING;
}
return var->string();
}
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// TEval_stack // TEval_stack
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -296,7 +328,7 @@ void TExpression::setvar(const char* varname, const char* val)
if (_var.getstring(varname) != val) if (_var.getstring(varname) != val)
{ {
_var.set(varname, val); _var.set(varname, val);
_dirty = TRUE; _dirty = true;
} }
} }
@ -306,7 +338,7 @@ void TExpression::setvar(int varnum, const char* val)
if (_var.getstring(varnum) != val) if (_var.getstring(varnum) != val)
{ {
_var.set(varnum, val); _var.set(varnum, val);
_dirty = TRUE; _dirty = true;
} }
} }
@ -315,6 +347,20 @@ bool TExpression::print_error(const char* msg) const
return yesnofatal_box("%s", msg); return yesnofatal_box("%s", msg);
} }
static bool str2date(const TString& s, TDate& d)
{
if (s.blank() || s == "0")
return true;
if (TDate::isdate(s))
{
d = s;
return true;
}
return false;
}
void TExpression::eval() void TExpression::eval()
{ {
TEval_stack evalstack; TEval_stack evalstack;
@ -715,6 +761,55 @@ void TExpression::eval()
if (type == _strexpr) if (type == _strexpr)
evalstack.peek_string(); evalstack.peek_string();
break; break;
case _between:
{
const TString& s3 = evalstack.pop_string();
const TString& s2 = evalstack.pop_string();
const TString& s1 = evalstack.pop_string();
bool good = true;
if (s2.full() || s3.full())
{
bool done = false;
if (TDate::isdate(s1))
{
TDate d2, d3;
done = str2date(s2, d2) && str2date(s3, d3);
if (done)
{
const TDate d1(s1);
good = (d1 >= d2) && (!d3.ok() || d1 <= d3);
}
}
if (!done)
{
if (type == _strexpr)
good = s1 >= s2 && (s3.empty() || s1 <= s3);
else
{
const real r1(s1), r2(s2), r3(s3);
good = (s2.empty() || r1 >= r2) && (s3.empty() || r1 <= r3);
}
}
}
evalstack.push(good ? UNO : ZERO);
}
break;
case _cfcheck:
{
const TString& s1 = evalstack.pop_string();
const TString& s2 = evalstack.pop_string();
const bool good = s1.len() < s2.len() ? cf_check(s1, s2) : cf_check(s2, s1);
evalstack.push(good ? UNO : ZERO);
}
break;
case _picheck:
{
const TString& s1 = evalstack.pop_string();
const TString& s2 = evalstack.pop_string();
const bool good = s1.len() < s2.len() ? pi_check(s1, s2) : pi_check(s2, s1);
evalstack.push(good ? UNO : ZERO);
}
break;
default: default:
NFCHECK("operazione non valida %d", (int) instr.getsym()); NFCHECK("operazione non valida %d", (int) instr.getsym());
break; break;
@ -734,23 +829,25 @@ HIDDEN char _tok[81];
TCodesym TExpression::tok2fun(const char* tok) const TCodesym TExpression::tok2fun(const char* tok) const
{ {
const int MAX_TOK = 28; const int MAX_TOK = 31;
HIDDEN const char* fnstr[MAX_TOK] = { "ANSI", "CEIL", "COS", "EXP", "EXP10", HIDDEN const char* fnstr[MAX_TOK] = { "ANSI", "BETWEEN","CEIL", "CF_CHECK","COS",
"IF", "LEFT", "LEN", "LOG", "LOG10", "EXP", "EXP10", "IF", "LEFT", "LEN",
"MAX", "MID", "MIN", "NUM", "PERC", "LOG", "LOG10", "MAX", "MID", "MIN",
"POW", "RIGHT", "ROUND", "SCORP", "SIN", "NUM", "PERC", "PI_CHECK","POW", "RIGHT",
"SQR", "SQRT", "STR", "SUBSTR","TAN", "ROUND", "SCORP", "SIN", "SQR", "SQRT",
"TRIM", "TRUNC", "UPPER"}; "STR", "SUBSTR", "TAN", "TRIM", "TRUNC",
"UPPER" };
HIDDEN TCodesym fntok[MAX_TOK] = { _ansi, _ceil, _cos, _exp, _exp10, HIDDEN TCodesym fntok[MAX_TOK] = { _ansi, _between, _ceil, _cfcheck, _cos,
_if, _left, _len, _log, _log10, _exp, _exp10, _if, _left, _len,
_max, _mid, _min, _num, _perc, _log, _log10, _max, _mid, _min,
_pow, _right, _round, _scorp, _sin, _num, _perc, _picheck, _pow, _right,
_sqr, _sqrt, _str, _substr, _tan, _round, _scorp, _sin, _sqr, _sqrt,
_trim, _trunc, _upper}; _str, _substr, _tan, _trim, _trunc,
_upper };
int f = 0, l = MAX_TOK-1, i = MAX_TOK/2; int f = 0, l = MAX_TOK-1, i = MAX_TOK/2;
while (TRUE) for (;;)
{ {
// i = (f+l)>>1; // i = (f+l)>>1;
i = f + (toupper(*tok) - *fnstr[f]) * (l - f + 1) / (*fnstr[l] - *fnstr[f] + 1); i = f + (toupper(*tok) - *fnstr[f]) * (l - f + 1) / (*fnstr[l] - *fnstr[f] + 1);
@ -1067,9 +1164,12 @@ TCodesym TExpression::__factor(TCodesym startsym)
case _trunc: case _trunc:
case _perc: case _perc:
case _scorp: case _scorp:
case _cfcheck:
case _picheck:
sym = __function(2); sym = __function(2);
_code.add(startsym); _code.add(startsym);
break; break;
case _between:
case _mid: case _mid:
case _substr: case _substr:
sym = __function(3); sym = __function(3);

View File

@ -69,6 +69,9 @@ enum TCodesym {
_substr, // @emem Estrae una sottostringa _substr, // @emem Estrae una sottostringa
_len, // @emem Lunghezza di una stringa _len, // @emem Lunghezza di una stringa
_trim, // @emem Elimina spazi iniziali e finali di una stringa _trim, // @emem Elimina spazi iniziali e finali di una stringa
_between, // @emem controlla se il primo argomento e' compreso tra gli altri due
_cfcheck, // @emem controlla il codice fiscale (+stato)
_picheck // @emem controlla la partita IVA (+stato)
}; };
// @doc INTERNAL // @doc INTERNAL
@ -101,44 +104,31 @@ public:
TValue& operator =(const TValue& val) TValue& operator =(const TValue& val)
{ _s = val._s; _r = val._r; _t = val._t; return *this; } { _s = val._s; _r = val._r; _t = val._t; return *this; }
// @cmember Assegnamento di una stringa // @cmember Assegnamento di una stringa
TValue& operator =(const TString& s) TValue& operator =(const TString& s) { set(s); return *this; }
{ _s = s; _t = _strexpr; return *this; }
// @cmember Assegnamento di un numero // @cmember Assegnamento di un numero
TValue& operator =(const real& r) TValue& operator =(const real& r) { set(r); return *this; }
{ _r = r; _t = _numexpr; return *this; }
// @cmember Ritorna il valore numerico // @cmember Ritorna il valore numerico
real& number() real& number();
{ if (_t == _strexpr) { _r = real(_s); _t = _numexpr; } return _r; }
// @cmember Ritorna il valore come stringa // @cmember Ritorna il valore come stringa
TString& string() TString& string();
{ if (_t == _numexpr) { _s = _r.string(); _t = _strexpr; } return _s; } void set(const real& val) { _r = val; _t = _numexpr; }
// @cmember Setta il valore passato come real void set(const char* val) { _s = val; _t = _strexpr; }
void set(const real& val)
{ _r = val; _t = _numexpr; }
// @cmember Setta il valore passato come stringa
void set(const char* val)
{ _s = val; _t = _strexpr; }
// @cmember Setta il valore passato come stringa // @cmember Setta il valore passato come stringa
TTypeexp type() const { return _t; } TTypeexp type() const { return _t; }
// @cmember Costruttore. Inizializza TValue con un reale
TValue(const real& val)
{ _r = val; _t = _numexpr; }
// @cmember Costruttore. Inizializza TValue con una stringa
TValue(const char* val)
{ _s = val; _t = _strexpr; }
// @cmember Costruttore. Inizializza TValue con una stringa
TValue(const TString& val)
{ _s = val; _t = _strexpr; }
// @cmember Costruttore. Inizializza TValue con un altro TValue
TValue(const TValue& val)
{ *this = val; }
// @cmember Costruttore. Inizializza TValue a 0,0 e "" // @cmember Costruttore. Inizializza TValue a 0,0 e ""
TValue() TValue() { }
{ } // @cmember Costruttore. Inizializza TValue con un reale
TValue(const real& val) { set(val); }
// @cmember Costruttore. Inizializza TValue con una stringa
TValue(const char* val) { set(val); }
// @cmember Costruttore. Inizializza TValue con una stringa
TValue(const TString& val){ set(val); }
// @cmember Costruttore. Inizializza TValue con un altro TValue
TValue(const TValue& val) { _s = val._s; _r = val._r; _t = val._t; }
// @cmember Distruttore // @cmember Distruttore
virtual ~TValue() virtual ~TValue() {}
{}
}; };
@ -158,7 +148,7 @@ extern TValue nulltvalue;
// @base public | TObject // @base public | TObject
class TCode : public TObject class TCode : public TObject
// @author:(INTERNAL) Sandro // @author:(INTERNAL) Alex
// @access:(INTERNAL) Private Member // @access:(INTERNAL) Private Member
{ {
@ -211,7 +201,7 @@ public:
// @base public | TArray // @base public | TArray
class TCodearray : public TArray class TCodearray : public TArray
// @author:(INTERNAL) Sandro // @author:(INTERNAL) Alex
// @access:(INTERNAL) Private Member // @access:(INTERNAL) Private Member
{ {
@ -251,9 +241,9 @@ public:
// @class TVar | Classe per la definizione delle variabile delle espressioni // @class TVar | Classe per la definizione delle variabile delle espressioni
// //
// @base public | TObject // @base public | TObject
class TVar : public TObject class TVar : public TSortable
// @author:(INTERNAL) Sandro // @author:(INTERNAL) Alex
// @access:(INTERNAL) Private Member // @access:(INTERNAL) Private Member
{ {
@ -267,6 +257,7 @@ class TVar : public TObject
public: public:
// @cmember Duplica la variabile // @cmember Duplica la variabile
virtual TObject* dup() const; virtual TObject* dup() const;
virtual int compare(const TSortable& s) const;
// @cmember Assegnamento di una stringa all'oggetto Tval // @cmember Assegnamento di una stringa all'oggetto Tval
const char* operator =(const char* val) const char* operator =(const char* val)
@ -319,26 +310,29 @@ public:
// @class TVararray | Classe per la definizione di un array di variabili da // @class TVararray | Classe per la definizione di un array di variabili da
// valutare nell'esspressione // valutare nell'esspressione
// //
// @base public | TArray class TVararray
class TVararray : public TArray
// @author:(INTERNAL) Sandro // @author:(INTERNAL) Alex
// @access:(INTERNAL) Private Member // @access:(INTERNAL) Private Member
{ {
TArray _vars;
protected:
TVar* find(const char* name) const;
TVar* find(const int varnum) const;
// @access Public Member // @access Public Member
public: public:
// @cmember Cancella il contenuto dell'array // @cmember Cancella il contenuto dell'array
void clear() void clear() { _vars.destroy(); }
{ destroy();}
// @cmember Aggiunge un oggetto TVar // @cmember Aggiunge un oggetto TVar
void add(const TVar& var); void add(const TVar& var);
// @cmember Aggiunge un nome di variabile e il suo valore // @cmember Aggiunge un nome di variabile e il suo valore
void add(const char* name, const TValue& val = nulltvalue); void add(const char* name, const TValue& val = nulltvalue);
// @cmember Ritorna il nome della variabile di posto varnum // @cmember Ritorna il nome della variabile di posto varnum
const char* varname(int varnum) const const char* varname(int varnum) const
{ return varnum < items() ? (const char *)((TVar *) objptr(varnum))->getname() : "";} //verificare { return find(varnum)->getname();}
// @cmember Setta l'oggetto TVararray con il nome e il valore della variabile // @cmember Setta l'oggetto TVararray con il nome e il valore della variabile
void set(const char* varname, const real& val); void set(const char* varname, const real& val);
@ -347,30 +341,28 @@ public:
void set(const char* varname, const char* val); void set(const char* varname, const char* val);
// @cmember Setta l'elemnto dell varaibile <p varnum>-esima al valore passato // @cmember Setta l'elemnto dell varaibile <p varnum>-esima al valore passato
void set(int varnum, const real& val) void set(int varnum, const real& val)
{ if (varnum < items()) *((TVar *) objptr(varnum)) = val;} { *find(varnum) = val;}
// @cmember Setta l'elemnto dell varaibile <p varnum>-esima al valore passato // @cmember Setta l'elemento dell variabile <p varnum>-esima al valore passato
// come stringa // come stringa
void set(int varnum, const char* val) void set(int varnum, const char* val)
{ if (varnum < items()) *((TVar *) objptr(varnum)) = val;} { *find(varnum) = val;}
// @cmember Ritorna il valore della variabile con nome <p varname> // @cmember Ritorna il valore della variabile con nome <p varname>
const real& getnum(const char* varname); const real& getnum(const char* varname);
// @cmember Ritorna il valore della variabile di posto <p varnum>-esimo // @cmember Ritorna il valore della variabile di posto <p varnum>-esimo
const real& getnum(int varnum); const real& getnum(int varnum) { return find(varnum)->number(); }
// @cmember Ritorna il nome della variabile con nome <p varname> // @cmember Ritorna il nome della variabile con nome <p varname>
const TString& getstring(const char* varname); const TString& getstring(const char* varname);
// @cmember Ritorna il nome della variabile di posto <p varnum>-esimo // @cmember Ritorna il nome della variabile di posto <p varnum>-esimo
const TString& getstring(int varnum); const TString& getstring(int varnum) { return find(varnum)->string(); }
// @cmember Ritorna il numero di variabili utilizzate // @cmember Ritorna il numero di variabili utilizzate
int numvar() const int numvar() const { return _vars.items();}
{ return items();}
// @cmember Costruttore // @cmember Costruttore
TVararray(int size = 10) : TArray(size) {} TVararray(int size = 16) : _vars(size) {}
// @cmember Distruttore // @cmember Distruttore
virtual ~TVararray() virtual ~TVararray() {}
{}
}; };
class TEval_stack : public TStack class TEval_stack : public TStack
@ -396,7 +388,7 @@ public:
// @base public | TObject // @base public | TObject
class TExpression : public TObject class TExpression : public TObject
// @author:(INTERNAL) Sandro // @author:(INTERNAL) Alex
// @access:(INTERNAL) Private Member // @access:(INTERNAL) Private Member
{ {

View File

@ -894,7 +894,8 @@ bool TSQLite::set_dbf_time(const TString& table, long last)
{ {
TString sql; TString sql;
sql << "REPLACE INTO " << DBF_TIMES_TABLE << " VALUES(" sql << "REPLACE INTO " << DBF_TIMES_TABLE << " VALUES("
<< '\'' << table << "','" << last << "');"; << '\'' << table << "','" << last << "')"
<< "\nWHERE name='" << table << "';";
return exec(sql); return exec(sql);
} }

View File

@ -1372,10 +1372,10 @@ void TCursor::filter(
const char * vn = _fexpr->varname(i); //occhio const char * vn = _fexpr->varname(i); //occhio
if (vn[0] != '#') if (vn[0] != '#')
{ {
TFieldref f(vn, 0); const TFieldref f(vn, 0);
const TString & id = f.id(); const TString & id = f.id();
if (!id.empty()) if (id.full())
{ {
_filter_update = true; _filter_update = true;
const int file_id = _if->name2ind(id); const int file_id = _if->name2ind(id);

View File

@ -1,10 +1,7 @@
#include <ctype.h>
#include <diction.h> #include <diction.h>
#include <expr.h> #include <expr.h>
#include <isam.h> #include <isam.h>
#include <mask.h> #include <mask.h>
#include <prefix.h>
#include <validate.h> #include <validate.h>
#include <defmask.h> #include <defmask.h>
@ -177,11 +174,11 @@ HIDDEN bool _pi_val(TMask_field& f, KEY)
} }
HIDDEN bool __cf_check (const char * codcf) HIDDEN bool __cf_check (const char* codcf)
{ {
const TString16 cf (codcf); const TFixed_string cf(codcf);
if (cf.len() != 16) return FALSE; if (cf.len() != 16)
return false;
const TFixed_string tab("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); const TFixed_string tab("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
int tot = 0, y; int tot = 0, y;
@ -248,9 +245,9 @@ bool cf_check (
const char* stato, // @parm Stato di assegnazione del Codice Fiscale const char* stato, // @parm Stato di assegnazione del Codice Fiscale
const char* codcf) // @parm Codice Fiscale da controllare const char* codcf) // @parm Codice Fiscale da controllare
{ {
TString16 cf (codcf); const TFixed_string cf (codcf);
if (cf.empty()) if (cf.blank())
return TRUE; return true;
const bool ok = (cf.len() == 11 && isdigit(cf[0])) ? pi_check(stato, cf) : __cf_check(cf); const bool ok = (cf.len() == 11 && isdigit(cf[0])) ? pi_check(stato, cf) : __cf_check(cf);
return ok; return ok;
} }