1994-08-16 16:35:22 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <memory.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <strings.h>
|
|
|
|
|
|
|
|
#include <files.h>
|
|
|
|
#include <expr.h>
|
|
|
|
#ifndef __EXTCDECL_H
|
|
|
|
#include <extcdecl.h>
|
|
|
|
#endif
|
|
|
|
#include <utility.h>
|
|
|
|
|
|
|
|
|
|
|
|
#define BLOCKLEN 512
|
|
|
|
#define INVFLD 255
|
|
|
|
|
|
|
|
HIDDEN char _files_tmp_string[128];
|
|
|
|
|
|
|
|
TFile::TFile(int lenrec, int base)
|
|
|
|
|
|
|
|
{
|
|
|
|
_file = new SecDef;
|
|
|
|
if (_file == NULL) fatal_box("Can't allocate record file ");
|
|
|
|
_file->IOR = NOERR;
|
|
|
|
_len = lenrec;
|
|
|
|
_base = base;
|
|
|
|
_file->LockMode = _manulock;
|
|
|
|
_file->lpos = -1;
|
|
|
|
_file->name[0] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TFile::~TFile()
|
|
|
|
|
|
|
|
{
|
|
|
|
delete _file;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TFile::open(const char* name, TFilelock lockmode)
|
|
|
|
|
|
|
|
{
|
|
|
|
COpen(_file, (char*) name, _len, _base, lockmode);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TFile::verify(const char* name)
|
|
|
|
|
|
|
|
{
|
|
|
|
CVerify(_file, (char*) name);
|
|
|
|
return _file->IOR == NOERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TFile::create(const char* name, TRecnotype nrecord)
|
|
|
|
|
|
|
|
{
|
|
|
|
CCreate(_file, (char*) name, _len, _base, (nrecord * _len) /BLOCKLEN + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TFile::chsize(const char* name, TRecnotype nrecord)
|
|
|
|
|
|
|
|
{
|
|
|
|
CChsize(_file, (char*) name, _len, _base, (nrecord * _len) /BLOCKLEN + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TFile::close()
|
|
|
|
|
|
|
|
{
|
|
|
|
CClose(_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TFile::unlink(const char* name)
|
|
|
|
|
|
|
|
{
|
|
|
|
CDelete(_file, (char*) name);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TFile::read(char* record, TRecnotype recnum, TReclock lock)
|
|
|
|
|
|
|
|
{
|
|
|
|
_file->LenRec = _len;
|
|
|
|
_file->BaseFil = _base;
|
|
|
|
CRead(_file, record, recnum, lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TFile::write(char* record, TRecnotype recnum, TReclock lock)
|
|
|
|
|
|
|
|
{
|
|
|
|
_file->LenRec = _len;
|
|
|
|
_file->BaseFil = _base;
|
|
|
|
CWrite(_file, record, recnum, lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int TFile::status() const
|
|
|
|
|
|
|
|
{
|
|
|
|
return _file->IOR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TDir::TDir()
|
|
|
|
|
|
|
|
{
|
|
|
|
_dir = new FileDes;
|
|
|
|
if (_dir == NULL)
|
|
|
|
fatal_box("Can't allocate dir");
|
|
|
|
zero();
|
|
|
|
_num = - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TDir::~TDir()
|
|
|
|
|
|
|
|
{
|
|
|
|
delete _dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char* TDir::name() const
|
|
|
|
|
|
|
|
{
|
|
|
|
return _dir->SysName;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char* TDir::des() const
|
|
|
|
|
|
|
|
{
|
|
|
|
return _dir->Des;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char* TDir::expr() const
|
|
|
|
|
|
|
|
{
|
|
|
|
return _dir->FCalc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TRecnotype& TDir::eod() const
|
|
|
|
|
|
|
|
{
|
|
|
|
return _dir->EOD;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TRecnotype& TDir::eox() const
|
|
|
|
|
|
|
|
{
|
|
|
|
return _dir->EOX;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TRecnotype& TDir::flags() const
|
|
|
|
|
|
|
|
{
|
|
|
|
return _dir->Flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
word& TDir::len()
|
|
|
|
|
|
|
|
{
|
|
|
|
return (word&) _dir->LenR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int TDir::status(TDirtype dirop) const
|
|
|
|
|
|
|
|
{
|
|
|
|
return fdir[dirop].IOR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TDir::set_len(const UINT16 len)
|
|
|
|
{
|
|
|
|
_dir->LenR = len;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TDir::set_eox(const RecNoType eox)
|
|
|
|
{
|
|
|
|
_dir->EOX = eox;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TDir::set(const char * name, const RecNoType eod, const RecNoType flag, const char * des, const char * calc)
|
|
|
|
{
|
|
|
|
strncpy (_dir->SysName, name, sizeof(_dir->SysName));
|
|
|
|
_dir->EOD = eod;
|
|
|
|
_dir->Flags = flag;
|
|
|
|
strncpy (_dir->Des, des, sizeof(_dir->Des));
|
|
|
|
strncpy (_dir->FCalc, calc, sizeof(_dir->FCalc));
|
|
|
|
}
|
|
|
|
|
|
|
|
void TDir::get(int nfile, TReclock lock, TDirtype dirtype, TDirop op)
|
|
|
|
|
|
|
|
{
|
|
|
|
int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
|
|
|
|
|
|
|
|
if (op == _nordirop)
|
|
|
|
COpenFile(nfile, _dir, int(lock), _whichdir);
|
|
|
|
else
|
|
|
|
CGetFile(nfile, _dir, int(lock), _whichdir);
|
|
|
|
_num = nfile;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TDir::put(int nfile, TDirtype dirtype, TDirop op)
|
|
|
|
|
|
|
|
{
|
|
|
|
int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
|
|
|
|
|
|
|
|
if (nfile <= 0)
|
|
|
|
fatal_box("Bad file number %d", nfile);
|
|
|
|
if (op == _nordirop)
|
|
|
|
CCloseFile(nfile, _dir, _whichdir);
|
|
|
|
else
|
|
|
|
CPutFile(nfile, _dir, _whichdir);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TDir::zero()
|
|
|
|
|
|
|
|
{
|
|
|
|
zerofdes(_dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int TDir::items(TDirtype dirtype) const
|
|
|
|
|
|
|
|
{
|
|
|
|
FileDes f;
|
|
|
|
int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
|
|
|
|
|
|
|
|
CGetFile(1, &f, _nolock, _whichdir);
|
|
|
|
return (int)f.EOD;
|
|
|
|
}
|
|
|
|
|
|
|
|
TTrec::TTrec()
|
|
|
|
|
|
|
|
{
|
|
|
|
_rec = new RecDes;
|
|
|
|
if (_rec == NULL)
|
|
|
|
fatal_box("Can't allocate record description");
|
|
|
|
zero();
|
|
|
|
_num = - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TTrec::~TTrec()
|
|
|
|
|
|
|
|
{
|
|
|
|
delete _rec;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int TTrec::compare(const TSortable& a) const
|
|
|
|
|
|
|
|
{
|
|
|
|
const TTrec& r = (const TTrec&)a;
|
|
|
|
const int res = memcmp((const void*)_rec, (const void*)r._rec, sizeof(*_rec));
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TTrec::rehash()
|
|
|
|
|
|
|
|
{
|
|
|
|
setrdes(_rec);
|
|
|
|
}
|
|
|
|
|
|
|
|
TTrec& TTrec::operator =(const TTrec& b)
|
|
|
|
|
|
|
|
{
|
|
|
|
_num = b._num;
|
|
|
|
memcpy(_rec, b._rec, sizeof(*_rec));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TTrec::get(int nfile, TDirtype dirtype)
|
|
|
|
|
|
|
|
{
|
|
|
|
int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
|
|
|
|
|
|
|
|
CGetRec(nfile, _rec, _whichdir);
|
|
|
|
_num = nfile;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TTrec::put(int nfile, TDirtype dirtype)
|
|
|
|
|
|
|
|
{
|
|
|
|
int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
|
|
|
|
|
|
|
|
if (nfile <= 0)
|
|
|
|
fatal_box("Bad file number %d", nfile);
|
|
|
|
CPutRec(nfile, _rec, _whichdir);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TTrec::zero()
|
|
|
|
|
|
|
|
{
|
|
|
|
zerordes(_rec);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int TTrec::status(TDirtype dirop) const
|
|
|
|
|
|
|
|
{
|
|
|
|
return rdir[dirop].IOR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int TTrec::field(const char* name) const
|
|
|
|
|
|
|
|
{
|
|
|
|
return findfld(_rec, (char*) name);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* TTrec::fielddef(int fld) const
|
|
|
|
|
|
|
|
{
|
|
|
|
sprintf(_files_tmp_string, "%s|%d|%d|%d", _rec->Fd[fld].Name,
|
|
|
|
(int) _rec->Fd[fld].TypeF, (int) _rec->Fd[fld].Len,
|
|
|
|
(int) _rec->Fd[fld].Dec);
|
|
|
|
return _files_tmp_string;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* TTrec::keydef(int key) const
|
|
|
|
|
|
|
|
{
|
|
|
|
TFixed_string s(_files_tmp_string, 128);
|
|
|
|
|
|
|
|
s = "";
|
|
|
|
for (int j = 0 ; j < _rec->Ky[key].NkFields; j++)
|
|
|
|
{
|
|
|
|
const bool upper = _rec->Ky[key].FieldSeq[j] > MaxFields;
|
|
|
|
const int nfld = _rec->Ky[key].FieldSeq[j] - (upper ? MaxFields : 0);
|
|
|
|
|
|
|
|
if (j) s << "+";
|
|
|
|
if (upper) s << "UPPER(";
|
|
|
|
s << _rec->Fd[nfld].Name;
|
|
|
|
if (_rec->Ky[key].FromCh[j] < INVFLD)
|
|
|
|
s << format("[%d,%d]", _rec->Ky[key].FromCh[j] + 1,
|
|
|
|
_rec->Ky[key].ToCh[j] + 1);
|
|
|
|
if (upper) s << ")";
|
|
|
|
}
|
|
|
|
s << (_rec->Ky[key].DupKeys ? "|X" : "| ");
|
|
|
|
return (const char*) s;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TTrec::update_fielddef(int nfld, const char* desc)
|
|
|
|
|
|
|
|
{
|
|
|
|
TToken_string s(desc);
|
|
|
|
strcpy(_rec->Fd[nfld].Name, s.get());
|
|
|
|
_rec->Fd[nfld].TypeF = s.get_int();
|
|
|
|
_rec->Fd[nfld].Len = s.get_int();
|
|
|
|
_rec->Fd[nfld].Dec = s.get_int();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TTrec::update_keydef(int key, const char* desc)
|
|
|
|
|
|
|
|
{
|
|
|
|
TExpression expr("", _strexpr);
|
|
|
|
TToken_string s(desc);
|
|
|
|
TString ke(s.get());
|
|
|
|
|
|
|
|
if (expr.set((const char*) ke, _strexpr))
|
|
|
|
{
|
|
|
|
_rec->Ky[key].DupKeys = (*s.get() != ' ');
|
|
|
|
TCodearray& c = expr.code();
|
|
|
|
c.begin();
|
|
|
|
int n = 0;
|
|
|
|
while (!c.end())
|
|
|
|
{
|
|
|
|
TCode& inst = c.step();
|
|
|
|
TCodesym sym = inst.getsym();
|
|
|
|
|
|
|
|
if (sym == _variable)
|
|
|
|
{
|
|
|
|
const char* s = inst.string();
|
|
|
|
|
|
|
|
for (int i = 0; i <_rec->NFields; i++)
|
|
|
|
if (strcmp(_rec->Fd[i].Name, s) == 0) break;
|
|
|
|
|
|
|
|
_rec->Ky[key].FieldSeq[n] = i;
|
|
|
|
_rec->Ky[key].FromCh[n] = INVFLD;
|
|
|
|
_rec->Ky[key].FromCh[n] = INVFLD;
|
|
|
|
inst = c.step();
|
|
|
|
sym = inst.getsym();
|
|
|
|
if (sym == _upper)
|
|
|
|
_rec->Ky[key].FieldSeq[n] += MaxFields;
|
|
|
|
else
|
|
|
|
if (sym == _number)
|
|
|
|
{
|
|
|
|
_rec->Ky[key].FromCh[n] = inst.number().integer() - 1;
|
|
|
|
inst = c.step();
|
|
|
|
_rec->Ky[key].ToCh[n] = _rec->Ky[key].FromCh[n] + inst.number().integer() - 1;
|
|
|
|
inst = c.step();
|
|
|
|
}
|
|
|
|
else c.backtrace();
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_rec->Ky[key].NkFields = n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TTrec::print_on(ostream& out) const
|
|
|
|
|
|
|
|
{
|
|
|
|
out << num() << '\n';
|
|
|
|
const int nfields = fields();
|
|
|
|
TToken_string s(80);
|
|
|
|
|
|
|
|
out << nfields << '\n';
|
|
|
|
for (int i = 0; i < nfields; i++)
|
|
|
|
{
|
|
|
|
s = fielddef(i);
|
|
|
|
out << s << '\n';
|
|
|
|
}
|
|
|
|
const int nkeys = keys();
|
|
|
|
|
|
|
|
out << nkeys << '\n';
|
|
|
|
for (i = 0; i < nkeys; i++)
|
|
|
|
{
|
|
|
|
s = keydef(i);
|
|
|
|
out << s << '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TTrec::read_from(istream& in)
|
|
|
|
|
|
|
|
{
|
|
|
|
int ln;
|
|
|
|
|
|
|
|
in.getline(_files_tmp_string, sizeof(_files_tmp_string), '\n');
|
|
|
|
ln = atoi(_files_tmp_string);
|
|
|
|
if (ln != num() && !yesno_box("Descrizione relativa al file n.ro %d.\n Continuo ?", ln))
|
|
|
|
return;
|
|
|
|
int nfields;
|
|
|
|
|
|
|
|
in.getline(_files_tmp_string, sizeof(_files_tmp_string), '\n');
|
|
|
|
nfields = atoi(_files_tmp_string);
|
|
|
|
set_fields(nfields);
|
|
|
|
for (int i = 0; i < nfields; i++)
|
|
|
|
{
|
|
|
|
in.getline(_files_tmp_string, sizeof(_files_tmp_string), '\n');
|
|
|
|
update_fielddef(i, _files_tmp_string);
|
|
|
|
}
|
|
|
|
int nkeys;
|
|
|
|
|
|
|
|
in.getline(_files_tmp_string, sizeof(_files_tmp_string), '\n');
|
|
|
|
nkeys = atoi(_files_tmp_string);
|
|
|
|
set_keys(nkeys);
|
|
|
|
for (i = 0; i < nkeys; i++)
|
|
|
|
{
|
|
|
|
in.getline(_files_tmp_string, sizeof(_files_tmp_string), '\n');
|
|
|
|
update_keydef(i, _files_tmp_string);
|
|
|
|
}
|
|
|
|
rehash();
|
|
|
|
}
|
|
|
|
|
|
|
|
|