Patch level : 2.0 nopatch
Files correlati : omnia0.exe omnia.xml Ricompilazione Demo : [ ] Commento : Ultimissima verisione dell'acqua tutte le cose. git-svn-id: svn://10.65.10.50/trunk@11735 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
b321753a69
commit
e15b71e0e0
185
omnia/Omnia0.cpp
185
omnia/Omnia0.cpp
@ -1,49 +1,133 @@
|
||||
#include <windows.h>
|
||||
#include <fstream.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "date.h"
|
||||
#include "expr.h"
|
||||
#include "utility.h"
|
||||
#include "xml.h"
|
||||
|
||||
class TExpr_omnia : public TExpression
|
||||
{
|
||||
enum { _date2k, _periodlastday, _recno };
|
||||
|
||||
static int _curr_recno;
|
||||
|
||||
protected:
|
||||
virtual int parse_user_func(const char* name, int nparms) const;
|
||||
virtual void evaluate_user_func(int index, int nparms, TEval_stack& stack, TTypeexp type) const;
|
||||
|
||||
public:
|
||||
static void set_curr_recno(int n) { _curr_recno = n; }
|
||||
|
||||
TExpr_omnia(const char* exp) { set(exp, _strexpr); }
|
||||
};
|
||||
|
||||
int TExpr_omnia::_curr_recno = 0;
|
||||
|
||||
int TExpr_omnia::parse_user_func(const char* name, int nparms) const
|
||||
{
|
||||
if (strcmp(name, "DATE2K") == 0)
|
||||
return nparms == 1 ? _date2k : -1;
|
||||
|
||||
if (strcmp(name, "PERIODLASTDAY") == 0)
|
||||
return nparms == 1 ? _periodlastday : -1;
|
||||
|
||||
if (strcmp(name, "RECNO") == 0)
|
||||
return nparms == 0 ? _recno : -1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TExpr_omnia::evaluate_user_func(int index, int nparms, TEval_stack& stack, TTypeexp type) const
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case _date2k: // Acqua Omnia Only
|
||||
{
|
||||
TString& str = stack.peek_string();
|
||||
TToken_string tok(str, '/');
|
||||
const int d = tok.get_int(0);
|
||||
const int m = tok.get_int();
|
||||
int y = tok.get_int();
|
||||
if (d > 0 && m > 0 && y < 100)
|
||||
{
|
||||
y += 2000;
|
||||
const TDate milleniumbug(d, m, y);
|
||||
str = milleniumbug.string(full, '/');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case _periodlastday: // Acqua Omnia Only
|
||||
{
|
||||
TString& period = stack.peek_string();
|
||||
char m1[4], m2[4];
|
||||
int year = 0;
|
||||
sscanf(period, "%3s-%3s/%d", m1, m2, &year);
|
||||
|
||||
const TString4 strMonth = m2;
|
||||
for (int month = 12; month > 0; month--)
|
||||
{
|
||||
if (strMonth.compare(itom(month), 3, true) == 0)
|
||||
break;
|
||||
}
|
||||
if (month > 0)
|
||||
{
|
||||
TDate day(1, month, year);
|
||||
day.set_end_month();
|
||||
period = day.string(full, '/');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case _recno:
|
||||
stack.push(_curr_recno);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TTextRecord
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TTextRecord : public TString_array
|
||||
{
|
||||
const TXmlItem* m_trc;
|
||||
const TXmlItem* m_inrec;
|
||||
const TXmlItem* m_outrec;
|
||||
int m_nLines, m_nColumns;
|
||||
TString m_str;
|
||||
|
||||
protected:
|
||||
char* GetLineBuffer(int i, int size);
|
||||
const TString& GetFieldValue(const TXmlItem& field) const;
|
||||
const TXmlItem* FindField(const TString& name) const;
|
||||
const TXmlItem* FindInputField(const TString& name) const;
|
||||
|
||||
public:
|
||||
void SetTrc(const TXmlItem& trc);
|
||||
bool Read(istream& input);
|
||||
|
||||
const TString& GetValue(const TString& name) const;
|
||||
const TString& Evaluate(TExpression& exp) const;
|
||||
const TString& Evaluate(TExpr_omnia& exp) const;
|
||||
|
||||
TTextRecord() : m_trc(NULL), m_nLines(0), m_nColumns(0) { }
|
||||
TTextRecord(const TXmlItem& trc) : m_trc(&trc) { }
|
||||
TTextRecord() : m_nLines(0), m_nColumns(0) { }
|
||||
TTextRecord(const TXmlItem& trc) { SetTrc(trc); }
|
||||
};
|
||||
|
||||
void TTextRecord::SetTrc(const TXmlItem& trc)
|
||||
{
|
||||
m_trc = &trc;
|
||||
|
||||
m_nLines = trc.GetIntAttr("Lines");
|
||||
const TXmlItem& input = *trc.FindFirst("Input");
|
||||
m_nLines = input.GetIntAttr("Lines");
|
||||
if (m_nLines <= 0)
|
||||
m_nLines = 1;
|
||||
|
||||
m_nColumns = trc.GetIntAttr("Columns");
|
||||
m_nColumns = input.GetIntAttr("Columns");
|
||||
|
||||
m_inrec = trc.FindFirst("Record");
|
||||
m_inrec = input.FindFirst("Record");
|
||||
CHECK(m_inrec, "Null input record");
|
||||
|
||||
m_outrec = trc.FindFirst("Output")->FindFirst("Record");
|
||||
CHECK(m_outrec, "Null output record");
|
||||
}
|
||||
|
||||
char* TTextRecord::GetLineBuffer(int i, int size)
|
||||
@ -64,23 +148,27 @@ char* TTextRecord::GetLineBuffer(int i, int size)
|
||||
|
||||
bool TTextRecord::Read(istream& input)
|
||||
{
|
||||
bool ok = true;
|
||||
if (m_nLines <= 1 && m_nColumns > 0) // Record a lunghezza fissa
|
||||
bool ok = !input.eof();
|
||||
if (ok)
|
||||
{
|
||||
char* buff = GetLineBuffer(0, m_nColumns);
|
||||
input.read(buff, m_nColumns);
|
||||
buff[m_nColumns] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
int size = m_nColumns;
|
||||
if (size <= 0)
|
||||
size = 1024*16;
|
||||
for (int i = 0; i < m_nLines; i++)
|
||||
if (m_nLines <= 1 && m_nColumns > 0) // Record a lunghezza fissa
|
||||
{
|
||||
char* buff = GetLineBuffer(i, size);
|
||||
input.getline(buff, size);
|
||||
buff[size] = '\0';
|
||||
char* buff = GetLineBuffer(0, m_nColumns);
|
||||
input.read(buff, m_nColumns);
|
||||
buff[m_nColumns] = '\0';
|
||||
ok = *buff != '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
int size = m_nColumns;
|
||||
if (size <= 0)
|
||||
size = 1024*16;
|
||||
for (int i = 0; i < m_nLines; i++)
|
||||
{
|
||||
char* buff = GetLineBuffer(i, size);
|
||||
input.getline(buff, size);
|
||||
buff[size] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
@ -114,7 +202,7 @@ const TString& TTextRecord::GetFieldValue(const TXmlItem& field) const
|
||||
return str;
|
||||
}
|
||||
|
||||
const TXmlItem* TTextRecord::FindField(const TString& name) const
|
||||
const TXmlItem* TTextRecord::FindInputField(const TString& name) const
|
||||
{
|
||||
for (int i = 0; i < m_inrec->GetChildren(); i++)
|
||||
{
|
||||
@ -127,25 +215,19 @@ const TXmlItem* TTextRecord::FindField(const TString& name) const
|
||||
|
||||
const TString& TTextRecord::GetValue(const TString& name) const
|
||||
{
|
||||
const TXmlItem* f = FindField(name);
|
||||
const TXmlItem* f = FindInputField(name);
|
||||
if (f != NULL)
|
||||
return GetFieldValue(*f);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
const TString& TTextRecord::Evaluate(TExpression& exp) const
|
||||
const TString& TTextRecord::Evaluate(TExpr_omnia& exp) const
|
||||
{
|
||||
TString& str = (TString&)m_str;
|
||||
|
||||
str = exp.string();
|
||||
if (str.starts_with("BEFORE(AFTER"))
|
||||
{
|
||||
int i = 0;
|
||||
i++;
|
||||
}
|
||||
|
||||
const int nv = exp.numvar();
|
||||
if (nv > 0)
|
||||
if (nv > 0 || strchr(exp.string(), '(') != NULL)
|
||||
{
|
||||
for (int i = nv-1; i >= 0; i--)
|
||||
{
|
||||
@ -169,11 +251,14 @@ class TScrittore : public TObject
|
||||
{
|
||||
private:
|
||||
ofstream* _out;
|
||||
int _recno;
|
||||
|
||||
public:
|
||||
ofstream& OutStream() { return *_out; }
|
||||
int inc_recno() { _recno++; return _recno; }
|
||||
int recno() const { return _recno; }
|
||||
|
||||
TScrittore(const char* name) { _out = new ofstream(name); }
|
||||
TScrittore(const char* name) : _recno(0) { _out = new ofstream(name); }
|
||||
virtual~ TScrittore() { delete _out; }
|
||||
};
|
||||
|
||||
@ -187,12 +272,12 @@ class TCasaEditrice : public TAssoc_array
|
||||
const TXmlItem& m_trc;
|
||||
TString m_strPrefix, m_strExt;
|
||||
|
||||
TExpression* m_exprSuffix;
|
||||
TExpr_omnia* m_exprSuffix;
|
||||
|
||||
TString m_strRecHead, m_strRecFoot, m_strFldHead, m_strFldFoot;
|
||||
|
||||
protected:
|
||||
ofstream& OutStream(const char* suffix);
|
||||
TScrittore& Scrittore(const char* suffix);
|
||||
void WriteHeader(ostream& output) const;
|
||||
void WriteFooter(ostream& output) const;
|
||||
|
||||
@ -262,7 +347,7 @@ void TCasaEditrice::WriteFooter(ostream& output) const
|
||||
}
|
||||
}
|
||||
|
||||
ofstream& TCasaEditrice::OutStream(const char* suffix)
|
||||
TScrittore& TCasaEditrice::Scrittore(const char* suffix)
|
||||
{
|
||||
TScrittore* s = (TScrittore*)objptr(suffix);
|
||||
if (s == NULL)
|
||||
@ -275,7 +360,7 @@ ofstream& TCasaEditrice::OutStream(const char* suffix)
|
||||
add(suffix, s);
|
||||
WriteHeader(s->OutStream());
|
||||
}
|
||||
return s->OutStream();
|
||||
return *s;
|
||||
}
|
||||
|
||||
ofstream& TCasaEditrice::ChooseOutput(const TTextRecord& rec)
|
||||
@ -283,7 +368,10 @@ ofstream& TCasaEditrice::ChooseOutput(const TTextRecord& rec)
|
||||
TString16 strSuffix;
|
||||
if (m_exprSuffix != NULL)
|
||||
strSuffix = rec.Evaluate(*m_exprSuffix);
|
||||
return OutStream(strSuffix);
|
||||
|
||||
TScrittore& s = Scrittore(strSuffix);
|
||||
TExpr_omnia::set_curr_recno(s.inc_recno());
|
||||
return s.OutStream();
|
||||
}
|
||||
|
||||
TCasaEditrice::TCasaEditrice(const TXmlItem& trc, const char* name) : m_trc(trc), m_exprSuffix(NULL)
|
||||
@ -307,7 +395,7 @@ TCasaEditrice::TCasaEditrice(const TXmlItem& trc, const char* name) : m_trc(trc)
|
||||
|
||||
const TString strSuffix = pOutFile->GetAttr("Suffix");
|
||||
if (strSuffix.not_empty())
|
||||
m_exprSuffix = new TExpression(strSuffix, _strexpr);
|
||||
m_exprSuffix = new TExpr_omnia(strSuffix);
|
||||
|
||||
TXmlItem* pRecOut = pOutFile->FindFirst("Record");
|
||||
CHECK(pRecOut, "NULL output record");
|
||||
@ -365,7 +453,7 @@ bool TLettore::load_trc(const char* t)
|
||||
|
||||
const TString& TLettore::evaluate(int index) const
|
||||
{
|
||||
TExpression& exp = (TExpression&)_expressions[index];
|
||||
TExpr_omnia& exp = (TExpr_omnia&)_expressions[index];
|
||||
return _curr.Evaluate(exp);
|
||||
}
|
||||
|
||||
@ -405,7 +493,7 @@ int TLettore::convert(const TFilename& src, const TFilename& trc, const TFilenam
|
||||
return 4;
|
||||
}
|
||||
|
||||
_curr.SetTrc(*infile);
|
||||
_curr.SetTrc(_trc);
|
||||
|
||||
const int inmode = infile->GetIntAttr("Binary") != 0 ? (ios::in|ios::binary) : ios::in;
|
||||
ifstream input(src, inmode);
|
||||
@ -417,17 +505,16 @@ int TLettore::convert(const TFilename& src, const TFilename& trc, const TFilenam
|
||||
{
|
||||
const TXmlItem* outfield = recout->GetChild(i);
|
||||
outfield->GetEnclosedText(expr);
|
||||
_expressions.add(new TExpression(expr, _strexpr));
|
||||
_expressions.add(new TExpr_omnia(expr));
|
||||
}
|
||||
|
||||
while (!input.eof())
|
||||
while (_curr.Read(input))
|
||||
{
|
||||
_curr.Read(input);
|
||||
ofstream& output = mondadori.ChooseOutput(_curr);
|
||||
output << mondadori.RecHead();
|
||||
for (int i = 0; i < recout->GetChildren(); i++)
|
||||
{
|
||||
const TXmlItem* outfield = recout->GetChild(i);
|
||||
TXmlItem* outfield = recout->GetChild(i);
|
||||
outfield->GetEnclosedText(expr);
|
||||
const TString& val = evaluate(i);
|
||||
output << mondadori.FldHead() << val << mondadori.FldFoot();
|
||||
|
@ -717,7 +717,7 @@ void TExpression::eval()
|
||||
const TString& s1 = evalstack.pop_string();
|
||||
TString& s2 = evalstack.peek_string();
|
||||
const int pos = s2.find(s1);
|
||||
if (pos > 0)
|
||||
if (pos >= 0)
|
||||
s2 = s2.mid(pos+s1.len());
|
||||
else
|
||||
s2.cut(0);
|
||||
@ -732,6 +732,22 @@ void TExpression::eval()
|
||||
s2.cut(pos);
|
||||
}
|
||||
break;
|
||||
case _between:
|
||||
{
|
||||
const TString& end = evalstack.pop_string();
|
||||
const TString& start = evalstack.pop_string();
|
||||
TString& str = evalstack.peek_string();
|
||||
int from = str.find(start);
|
||||
if (from >= 0)
|
||||
{
|
||||
from += start.len();
|
||||
const int to = str.find(end, from);
|
||||
str = str.sub(from , to);
|
||||
}
|
||||
else
|
||||
str.cut(0);
|
||||
}
|
||||
break;
|
||||
case _rfind:
|
||||
{
|
||||
const TString& s1 = evalstack.pop_string();
|
||||
@ -759,22 +775,22 @@ HIDDEN char _tok[81];
|
||||
|
||||
TCodesym TExpression::tok2fun(const char* tok) const
|
||||
{
|
||||
const int MAX_TOK = 31;
|
||||
HIDDEN const char* fnstr[MAX_TOK] = { "AFTER", "ANSI", "BEFORE", "CEIL",
|
||||
"COS", "EXP", "EXP10", "IF", "LEFT",
|
||||
"LEN", "LOG", "LOG10", "MAX", "MID",
|
||||
"MIN", "NUM", "PERC", "POW", "RFIND",
|
||||
"RIGHT", "ROUND", "SCORP", "SIN", "SQR",
|
||||
"SQRT", "STR", "SUBSTR", "TAN", "TRIM",
|
||||
"TRUNC", "UPPER" };
|
||||
const int MAX_TOK = 32;
|
||||
HIDDEN const char* fnstr[MAX_TOK] = { "AFTER", "ANSI", "BEFORE", "BETWEEN", "CEIL",
|
||||
"COS", "EXP", "EXP10", "IF",
|
||||
"LEFT", "LEN", "LOG", "LOG10",
|
||||
"MAX", "MID", "MIN", "NUM", "PERC", "POW",
|
||||
"RFIND", "RIGHT", "ROUND", "SCORP", "SIN", "SQR",
|
||||
"SQRT", "STR", "SUBSTR", "TAN", "TRIM",
|
||||
"TRUNC", "UPPER" };
|
||||
|
||||
HIDDEN TCodesym fntok[MAX_TOK] = { _after, _ansi, _before, _ceil,
|
||||
_cos, _exp, _exp10, _if, _left,
|
||||
_len, _log, _log10, _max, _mid,
|
||||
_min, _num, _perc, _pow, _rfind,
|
||||
_right, _round, _scorp, _sin, _sqr,
|
||||
_sqrt, _str, _substr, _tan, _trim,
|
||||
_trunc, _upper };
|
||||
HIDDEN TCodesym fntok[MAX_TOK] = { _after, _ansi, _before, _between, _ceil,
|
||||
_cos, _exp, _exp10, _if,
|
||||
_left, _len, _log, _log10,
|
||||
_max, _mid, _min, _num, _perc, _pow,
|
||||
_rfind, _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)
|
||||
@ -1100,6 +1116,7 @@ TCodesym TExpression::__factor(TCodesym startsym)
|
||||
break;
|
||||
case _mid:
|
||||
case _substr:
|
||||
case _between:
|
||||
sym = __function(3, true, nparms_found);
|
||||
_code.add(startsym);
|
||||
break;
|
||||
@ -1133,7 +1150,6 @@ TCodesym TExpression::__term(TCodesym startsym)
|
||||
return sym;
|
||||
}
|
||||
|
||||
|
||||
TCodesym TExpression::__expression(TCodesym startsym)
|
||||
{
|
||||
TCodesym sym;
|
||||
|
@ -71,6 +71,7 @@ enum TCodesym {
|
||||
_trim, // @emem Elimina spazi iniziali e finali di una stringa
|
||||
_before, // @emem Estrae la parte precedente una stringa fissa data
|
||||
_after, // @emem Estrae la parte seguente una stringa fissa data
|
||||
_between, // @emem Estrae la parte tra due stringhe fisse date
|
||||
_rfind, // @emem Cerca una stringa all'indietro
|
||||
};
|
||||
// @doc INTERNAL
|
||||
|
@ -21,7 +21,12 @@
|
||||
<Field Name="Destinazione" X="52" Length="20" />
|
||||
<Field Name="QuotaFissaContatore" X="3255" Length="91" />
|
||||
<Field Name="Anticipo" X="206" Length="9" />
|
||||
<Field Name="DataLettura" X="258" Length="39" />
|
||||
<Field Name="Periodo" X="137" Length="12" />
|
||||
<Field Name="LetturaPre" X="258" Length="39" />
|
||||
<Field Name="LetturaAtt" X="388" Length="39" />
|
||||
<Field Name="Consumo" X="312" Length="9" />
|
||||
<Field Name="ConsumoFatturato" X="443" Length="9" />
|
||||
<Field Name="TipoLettura" X="454" Length="64" />
|
||||
<Field Name="Imponibile" X="6932" Length="16" />
|
||||
</Record>
|
||||
</Input>
|
||||
@ -34,9 +39,9 @@
|
||||
<Field Name="Zona">Impianto</Field>
|
||||
<Field Name="Mastro">1</Field>
|
||||
<Field Name="CodiceTecnico">000000</Field>
|
||||
<Field Name="Giro">"RECNO()"</Field>
|
||||
<Field Name="Giro">RECNO()</Field>
|
||||
<Field Name="Via">BEFORE(Indirizzo, ",")</Field>
|
||||
<Field Name="Civico">BEFORE(AFTER(Indirizzo, ","), "/")</Field>
|
||||
<Field Name="Civico">BETWEEN(Indirizzo, ",", "/")</Field>
|
||||
<Field Name="LetteraCivico">AFTER(Indirizzo, "/")</Field>
|
||||
<Field Name="InternoCivico" />
|
||||
<Field Name="LetteraInterno" />
|
||||
@ -58,7 +63,7 @@
|
||||
<Field Name="ImpiantoTecnico">Impianto</Field>
|
||||
<Field Name="MastroTecnico">1</Field>
|
||||
<Field Name="SubMastroTecnico">1</Field>
|
||||
<Field Name="GiroTecnico">"RECNO()"</Field>
|
||||
<Field Name="GiroTecnico">RECNO()</Field>
|
||||
<Field Name="DataCreazione" />
|
||||
<Field Name="Impianto2">Impianto</Field>
|
||||
<Field Name="Progressivo">Progressivo</Field>
|
||||
@ -95,7 +100,7 @@
|
||||
<Field Name="Minimi5" />
|
||||
<Field Name="CategoriaUso5" />
|
||||
<Field Name="Tipologia" />
|
||||
<Field Name="QuotaFissaContatore">BEFORE(AFTER(QuotaFissaContatore, "E/ms."),"=")</Field>
|
||||
<Field Name="QuotaFissaContatore">BETWEEN(QuotaFissaContatore, "E/ms.", "=")</Field>
|
||||
<Field Name="Antincendio">"NO"</Field>
|
||||
<Field Name="Perodicita">4</Field>
|
||||
<Field Name="NumeroContratto">Contratto</Field>
|
||||
@ -109,16 +114,16 @@
|
||||
<Field Name="Penale">"SI"</Field>
|
||||
<Field Name="Mora">"SI"</Field>
|
||||
<Field Name="Note2" />
|
||||
<Field Name="Data1">BEFORE(AFTER(DataLettura, "DEL"),"mc.")</Field>
|
||||
<Field Name="Lettura1">AFTER(DataLettura, "mc.")</Field>
|
||||
<Field Name="DataLetturaPrec">DATE2K(BETWEEN(LetturaPre, "DEL "," mc."))</Field>
|
||||
<Field Name="LetturaPrec">AFTER(LetturaPre, "mc. ")</Field>
|
||||
<Field Name="Consumo1">0</Field>
|
||||
<Field Name="TipoLettura1">10</Field>
|
||||
<Field Name="CodicePlacca1">CodicePlacca</Field>
|
||||
<Field Name="LetturaFatturata1">"SI"</Field>
|
||||
<Field Name="Data2">"???"</Field>
|
||||
<Field Name="Lettura2">"???"</Field>
|
||||
<Field Name="Consumo2">"???"</Field>
|
||||
<Field Name="TipoLettura2">"???"</Field>
|
||||
<Field Name="DataLeturaAtt">IF(BETWEEN(LetturaAtt, " DEL ", " mc.")=" /==/==", PERIODLASTDAY(Periodo), DATE2K(BETWEEN(LetturaAtt, " DEL ", " mc.")))</Field>
|
||||
<Field Name="LetturaAtt">IF(AFTER(LetturaAtt,"mc. ")="========", AFTER(LetturaPre, "mc. "), AFTER(LetturaAtt, "mc. "))</Field>
|
||||
<Field Name="Consumo2">IF(MID(TipoLettura, 1, 13)="Lettura reale", Consumo, ConsumoFatturato)</Field>
|
||||
<Field Name="TipoLettura2">IF(MID(TipoLettura, 1, 13)="Lettura reale", 0, 3)</Field>
|
||||
<Field Name="CodicePlacca2" />
|
||||
<Field Name="LetturaFatturata2">"SI"</Field>
|
||||
<Field Name="Data3" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user