Files correlati : Omnia0.exe Ricompilazione Demo : [ ] Commento : Prima versione del traduttore universale git-svn-id: svn://10.65.10.50/trunk@11690 c028cbd2-c16b-5b4b-a496-9718f37d4682
240 lines
5.3 KiB
C++
Executable File
240 lines
5.3 KiB
C++
Executable File
#include <windows.h>
|
|
#include <fstream.h>
|
|
|
|
#include "utility.h"
|
|
#include "xml.h"
|
|
|
|
class TLettore : public TObject
|
|
{
|
|
TXmlItem _trc;
|
|
|
|
int _lines, _chars;
|
|
TString _rseparator, _fseparator;
|
|
TString_array _curr;
|
|
|
|
protected:
|
|
bool load_trc(const char* trc);
|
|
|
|
char* get_line_buffer(int i, int size);
|
|
bool read_record(istream& input);
|
|
const TString& get_field(const TXmlItem& field) const;
|
|
const TXmlItem* find_field(const TXmlItem& record, const TString& name) const;
|
|
void evaluate(const TString& expr, const TXmlItem& recin, TString& val) const;
|
|
void smart_trim(TString& val, int mode) const;
|
|
|
|
public:
|
|
int convert(const TFilename& src, const TFilename& trc, const TFilename& dst);
|
|
int convert(const char* cmd);
|
|
};
|
|
|
|
bool TLettore::load_trc(const char* t)
|
|
{
|
|
const TFilename trc = t;
|
|
bool ok = trc.exist();
|
|
if (ok)
|
|
{
|
|
ifstream in(trc);
|
|
ok = _trc.Read(in);
|
|
}
|
|
_curr.destroy(); // reset line sizes
|
|
return ok;
|
|
}
|
|
|
|
char* TLettore::get_line_buffer(int i, int size)
|
|
{
|
|
TToken_string* str = (TToken_string*)_curr.objptr(i);
|
|
if (str == NULL)
|
|
{
|
|
str = new TToken_string(size);
|
|
_curr.add(str, i);
|
|
}
|
|
char* buff = str->get_buffer(size);
|
|
*buff = '\0';
|
|
return buff;
|
|
}
|
|
|
|
bool TLettore::read_record(istream& input)
|
|
{
|
|
bool ok = true;
|
|
if (_lines <= 1 && _chars > 0) // Record a lunghezza fissa
|
|
{
|
|
char* buff = get_line_buffer(0, _chars);
|
|
input.read(buff, _chars);
|
|
buff[_chars] = '\0';
|
|
}
|
|
else
|
|
{
|
|
int size = _chars;
|
|
if (size <= 0)
|
|
size = 1024;
|
|
for (int i = 0; i < _lines; i++)
|
|
{
|
|
char* buff = get_line_buffer(i, size);
|
|
input.getline(buff, size);
|
|
buff[size] = '\0';
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
const TString& TLettore::get_field(const TXmlItem& field) const
|
|
{
|
|
int y = field.GetIntAttr("Y" ) - 1;
|
|
if (y < 0) y = 0;
|
|
|
|
int x = field.GetIntAttr("X" ) - 1;
|
|
if (x < 0) x = 0;
|
|
|
|
int l = field.GetIntAttr("Length");
|
|
|
|
const TString& str = _curr.row(y).mid(x, l);
|
|
return str;
|
|
}
|
|
|
|
void TLettore::smart_trim(TString& val, int mode) const
|
|
{
|
|
switch (mode)
|
|
{
|
|
case 1: val.rtrim(); break;
|
|
case 2: val.ltrim(); break;
|
|
case 3: val.trim(); break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
const TXmlItem* TLettore::find_field(const TXmlItem& record, const TString& name) const
|
|
{
|
|
for (int i = 0; i < record.GetChildren(); i++)
|
|
{
|
|
const TXmlItem* field = record.GetChild(i);
|
|
if (field->GetAttr("Name") == name)
|
|
return field;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void TLettore::evaluate(const TString& expr, const TXmlItem& recin, TString& val) const
|
|
{
|
|
TToken_string expression(expr, '+');
|
|
val.cut(0);
|
|
TString str;
|
|
FOR_EACH_TOKEN(expression, tok)
|
|
{
|
|
str = tok; str.trim();
|
|
if (str[0] == '\'' || str[0] == '"')
|
|
{
|
|
str.rtrim(1); str.ltrim(1);
|
|
val << str;
|
|
}
|
|
else
|
|
{
|
|
bool trim = false;
|
|
if (str.starts_with("TRIM("))
|
|
{
|
|
str.ltrim(5); str.rtrim(1);
|
|
str.trim();
|
|
trim = true;
|
|
}
|
|
|
|
const TXmlItem* infield = find_field(recin, str);
|
|
if (infield != NULL)
|
|
{
|
|
str = get_field(*infield);
|
|
if (trim)
|
|
str.trim();
|
|
val << str;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int TLettore::convert(const TFilename& src, const TFilename& trc, const TFilename& dst)
|
|
{
|
|
if (!src.exist())
|
|
{
|
|
error_box("Non esiste il file di input\n%s", (const char*)src);
|
|
return 1;
|
|
}
|
|
|
|
if (!load_trc(trc))
|
|
{
|
|
error_box("Non esiste il tracciato record\n%s", (const char*)trc);
|
|
return 2;
|
|
}
|
|
|
|
if (dst.blank())
|
|
{
|
|
error_box("File di output non valido:\n%s", (const char*)dst);
|
|
return 3;
|
|
}
|
|
|
|
const TXmlItem* infile = _trc.FindFirst("Input");
|
|
const TXmlItem* outfile = _trc.FindFirst("Output");
|
|
if (infile == NULL || outfile == NULL)
|
|
{
|
|
error_box("Tracciato record non valido:\nNon esiste il tag <Input> o <Output>");
|
|
return 4;
|
|
}
|
|
|
|
const TXmlItem* recin = infile->FindFirst("Record");
|
|
const TXmlItem* recout = outfile->FindFirst("Record");
|
|
if (recin == NULL || recout == NULL)
|
|
{
|
|
error_box("Tracciato record non valido:\nNon esiste il tag <Record>");
|
|
return 4;
|
|
}
|
|
|
|
_lines = recin->GetIntAttr("Lines");
|
|
if (_lines <= 0)
|
|
_lines = 1;
|
|
|
|
_chars = recin->GetIntAttr("Chars");
|
|
|
|
_rseparator = esc(outfile->GetAttr("RecordSeparator"));
|
|
_fseparator = esc(recout->GetAttr("FieldSeparator"));
|
|
|
|
const int inmode = infile->GetIntAttr("Binary") != 0 ? (ios::in|ios::binary) : ios::in;
|
|
ifstream input(src, inmode);
|
|
|
|
const int outmode = outfile->GetIntAttr("Binary") != 0 ? (ios::out|ios::binary) : ios::out;
|
|
ofstream output(dst, outmode);
|
|
|
|
TString expr, val;
|
|
while (!input.eof())
|
|
{
|
|
read_record(input);
|
|
for (int i = 0; i < recout->GetChildren(); i++)
|
|
{
|
|
const TXmlItem* outfield = recout->GetChild(i);
|
|
outfield->GetEnclosedText(expr);
|
|
if (expr.empty())
|
|
expr = outfield->GetAttr("Name");
|
|
evaluate(expr, *recin, val);
|
|
smart_trim(val, outfield->GetIntAttr("Trim"));
|
|
if (i > 0)
|
|
output << _fseparator;
|
|
output << val;
|
|
}
|
|
output << _rseparator;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int TLettore::convert(const char* cmd)
|
|
{
|
|
TToken_string str(cmd, ' ');
|
|
str.strip_d_spaces();
|
|
const TFilename src = str.get();
|
|
const TFilename trc = str.get();
|
|
const TFilename dst = str.get();
|
|
return convert(src, trc, dst);
|
|
}
|
|
|
|
|
|
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR lpCmdLine, int)
|
|
{
|
|
TLettore app;
|
|
const int err = app.convert(lpCmdLine);
|
|
return err;
|
|
} |