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
#include <expr.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()
{
@ -18,10 +45,13 @@ void TCodearray::add(TCodesym sym, const TValue& val)
TArray::insert(new TCode(sym, val), last());
}
TObject * TCode::dup() const
///////////////////////////////////////////////////////////
// TCode
///////////////////////////////////////////////////////////
TObject* TCode::dup() const
{
TCode * o = new TCode(*this);
return o;
return new TCode(*this);
}
TCode& TCode::operator =(const TCode& b)
@ -31,94 +61,96 @@ TCode& TCode::operator =(const TCode& b)
return *this;
}
TObject * TVar::dup() const
///////////////////////////////////////////////////////////
// TVar
///////////////////////////////////////////////////////////
TObject* TVar::dup() const
{
TVar * o = new TVar(*this);
return o;
return new TVar(*this);
}
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)
{
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)
{
for (int i = last(); i >= 0; i--)
{
TVar* var = (TVar*)objptr(i);
if (var->getname() == name)
{
*var = val;
return;
}
}
NFCHECK("Variabile non trovata: %s", name);
TVar* v = find(name);
if (v != NULL)
*v = val;
}
void TVararray::set(const char* name, const char* val)
{
for (int i = last(); i >= 0; i--)
{
TVar* var = (TVar*)objptr(i);
if (var->getname() == name)
{
*var = val;
return;
}
}
NFCHECK("Variabile non trovata: %s", name);
TVar* v = find(name);
if (v != NULL)
*v = val;
}
const real& TVararray::getnum(const char* name)
{
for (int i = items()-1; i >= 0; i--)
{
TVar* var = (TVar*)objptr(i);
if (var->getname() == name)
return var->number();
}
NFCHECK("Unknown variable: %s", name);
TVar* v = find(name);
if (v != NULL)
return v->number();
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)
{
for (int i = last(); i >= 0; i--)
{
TVar* var = (TVar*)objptr(i);
if (var->getname() == name)
return var->string();
}
NFCHECK("Unknown variable : %s", name);
TVar* v = find(name);
if (v != NULL)
return v->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
///////////////////////////////////////////////////////////
@ -296,7 +328,7 @@ void TExpression::setvar(const char* varname, const char* val)
if (_var.getstring(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)
{
_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);
}
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()
{
TEval_stack evalstack;
@ -715,6 +761,55 @@ void TExpression::eval()
if (type == _strexpr)
evalstack.peek_string();
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:
NFCHECK("operazione non valida %d", (int) instr.getsym());
break;
@ -734,23 +829,25 @@ HIDDEN char _tok[81];
TCodesym TExpression::tok2fun(const char* tok) const
{
const int MAX_TOK = 28;
HIDDEN const char* fnstr[MAX_TOK] = { "ANSI", "CEIL", "COS", "EXP", "EXP10",
"IF", "LEFT", "LEN", "LOG", "LOG10",
"MAX", "MID", "MIN", "NUM", "PERC",
"POW", "RIGHT", "ROUND", "SCORP", "SIN",
"SQR", "SQRT", "STR", "SUBSTR","TAN",
"TRIM", "TRUNC", "UPPER"};
const int MAX_TOK = 31;
HIDDEN const char* fnstr[MAX_TOK] = { "ANSI", "BETWEEN","CEIL", "CF_CHECK","COS",
"EXP", "EXP10", "IF", "LEFT", "LEN",
"LOG", "LOG10", "MAX", "MID", "MIN",
"NUM", "PERC", "PI_CHECK","POW", "RIGHT",
"ROUND", "SCORP", "SIN", "SQR", "SQRT",
"STR", "SUBSTR", "TAN", "TRIM", "TRUNC",
"UPPER" };
HIDDEN TCodesym fntok[MAX_TOK] = { _ansi, _ceil, _cos, _exp, _exp10,
_if, _left, _len, _log, _log10,
_max, _mid, _min, _num, _perc,
_pow, _right, _round, _scorp, _sin,
_sqr, _sqrt, _str, _substr, _tan,
_trim, _trunc, _upper};
HIDDEN TCodesym fntok[MAX_TOK] = { _ansi, _between, _ceil, _cfcheck, _cos,
_exp, _exp10, _if, _left, _len,
_log, _log10, _max, _mid, _min,
_num, _perc, _picheck, _pow, _right,
_round, _scorp, _sin, _sqr, _sqrt,
_str, _substr, _tan, _trim, _trunc,
_upper };
int f = 0, l = MAX_TOK-1, i = MAX_TOK/2;
while (TRUE)
for (;;)
{
// i = (f+l)>>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 _perc:
case _scorp:
case _cfcheck:
case _picheck:
sym = __function(2);
_code.add(startsym);
break;
case _between:
case _mid:
case _substr:
sym = __function(3);

View File

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

View File

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

View File

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

View File

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