Files correlati : Ricompilazione Demo : [ ] Commento : controls.cpp Corretta gestione list box aperti durante la chiusura default.url Aggiunto BMP_STOP dongle.cpp Gestito utente GUEST expr.cpp Aggiunto errore su radice negativa files.cpp Tolti spazi inutili isam.cpp Migliorata conversione git-svn-id: svn://10.65.10.50/trunk@6851 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			731 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			731 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <stdio.h>
 | 
						|
 | 
						|
#include <files.h>
 | 
						|
#include <utility.h>
 | 
						|
#include <config.h>
 | 
						|
 | 
						|
#ifndef FOXPRO
 | 
						|
#include <expr.h>
 | 
						|
#include <applicat.h>
 | 
						|
#else
 | 
						|
#include <strings.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <extcdecl.h>
 | 
						|
#include <lffiles.h>
 | 
						|
 | 
						|
#define BLOCKLEN 512
 | 
						|
#define INVFLD    255
 | 
						|
 | 
						|
HIDDEN char _files_tmp_string[256];
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Apre il file specificato
 | 
						|
void TFile::open (
 | 
						|
  const char *name,   // @parm Nome del file da aprire
 | 
						|
  TFilelock lockmode) // @parm Tipo di lock da attivare durante l'apertura del file
 | 
						|
  //       (default _manulock)
 | 
						|
{
 | 
						|
  COpen (_file, (char *) name, _len, _base, lockmode);
 | 
						|
}
 | 
						|
 | 
						|
bool TFile::verify (const char *name)
 | 
						|
 | 
						|
{
 | 
						|
  CVerify (_file, (char *) name);
 | 
						|
  return _file->IOR == NOERR;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Crea il file specificato
 | 
						|
void TFile::create (
 | 
						|
  const char *name,   // @parm Nome del file da creare
 | 
						|
  TRecnotype nrecord) // @parm Numero di recird che deve avere il file al momento
 | 
						|
  //              della creazione (default 0)
 | 
						|
  
 | 
						|
  // @comm Il file creato avra' dimensioni sufficienti a contenere <p nrecord> record
 | 
						|
 | 
						|
{
 | 
						|
  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);
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Legge un record dal file
 | 
						|
void TFile::read (
 | 
						|
  char *record,      // @parm Record letto
 | 
						|
  TRecnotype recnum, // @parm Numero del record da leggere
 | 
						|
  TReclock lock)     // @parm Tipo di blocco da attivare durante la letture (default _nolock)
 | 
						|
 | 
						|
{
 | 
						|
  _file->LenRec = _len;
 | 
						|
  _file->BaseFil = _base;
 | 
						|
  CRead (_file, record, recnum, lock);
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Scrive un record sul file
 | 
						|
void TFile::write (
 | 
						|
  char *record,      // @parm Record da scrivere
 | 
						|
  TRecnotype recnum, // @parm Numero del record da scrivere
 | 
						|
  TReclock lock)     // @parm Tipo di blocco da attivare durante la letture (default _nolock)
 | 
						|
 | 
						|
{
 | 
						|
  _file->LenRec = _len;
 | 
						|
  _file->BaseFil = _base;
 | 
						|
  CWrite (_file, record, recnum, lock);
 | 
						|
}
 | 
						|
 | 
						|
int TFile::status () const
 | 
						|
 | 
						|
{
 | 
						|
  return _file->IOR;
 | 
						|
}
 | 
						|
 | 
						|
TDir::TDir () : _num(-1), _com(FALSE)
 | 
						|
 | 
						|
{
 | 
						|
  _dir = new FileDes;
 | 
						|
  if (_dir == NULL)
 | 
						|
    fatal_box ("Can't allocate dir");
 | 
						|
  zero ();
 | 
						|
}
 | 
						|
 | 
						|
TDir::TDir(const TDir & d) 
 | 
						|
{             
 | 
						|
  _dir = new FileDes;
 | 
						|
  *_dir = *d._dir;
 | 
						|
  _num = d._num;
 | 
						|
  _com = d._com;  
 | 
						|
}
 | 
						|
 | 
						|
TDir::~TDir ()
 | 
						|
{
 | 
						|
  delete _dir;
 | 
						|
}
 | 
						|
 | 
						|
const char *TDir::name () const
 | 
						|
{ 
 | 
						|
  return _dir->SysName;
 | 
						|
}
 | 
						|
 | 
						|
const char *TDir::filename () const
 | 
						|
{ 
 | 
						|
  strcpy(_files_tmp_string, CAddPref(_dir->SysName)); 
 | 
						|
  for (int i=strlen(_files_tmp_string); i>0; i--)
 | 
						|
  {
 | 
						|
    const char c = _files_tmp_string[i-1];
 | 
						|
    if (c == '\\' || c == '/')
 | 
						|
    {
 | 
						|
      strcat(_files_tmp_string, ".dbf");
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      if (c == '.') 
 | 
						|
        break;
 | 
						|
  }
 | 
						|
  return _files_tmp_string;
 | 
						|
}
 | 
						|
 | 
						|
void TDir::set_name (const char * name)
 | 
						|
{                       
 | 
						|
  CHECK(name != NULL, "NULL Filename");     
 | 
						|
  CHECK(strlen(name) < 42, "Name too long");
 | 
						|
 | 
						|
  for (int i=strlen(name); i>0; i--)
 | 
						|
  {
 | 
						|
    char c = name[i-1];
 | 
						|
    if (c == '\\' || c == '/')
 | 
						|
      break;
 | 
						|
    else
 | 
						|
      if (c == '.') 
 | 
						|
        c = '\0';
 | 
						|
        break;
 | 
						|
  }
 | 
						|
 | 
						|
  strncpy(_dir->SysName, name, 42);
 | 
						|
  _dir->SysName[41] = '\0';
 | 
						|
}
 | 
						|
 | 
						|
const char *TDir::des () const
 | 
						|
{           
 | 
						|
  return _dir->Des;
 | 
						|
}
 | 
						|
 | 
						|
const char* TDir::tab_des(const char* tab)
 | 
						|
{                                         
 | 
						|
  const char* t = tab; if (t[0] == '$' || t[0] == '%') t++;
 | 
						|
 | 
						|
  TString256 tmp;          
 | 
						|
  tmp << DESCDIR << "/d" << t << ".des";  
 | 
						|
 | 
						|
#ifndef FOXPRO  
 | 
						|
  TConfig cnf(tmp, DESCTAB);
 | 
						|
  t = cnf.get("Description", NULL, -1, tab);
 | 
						|
#endif
 | 
						|
  
 | 
						|
  return strcpy(__tmp_string, t);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
const char *TDir::expr () const
 | 
						|
{
 | 
						|
  return _dir->FCalc;
 | 
						|
}
 | 
						|
 | 
						|
TRecnotype & TDir::eod () const
 | 
						|
 | 
						|
{
 | 
						|
  return _dir->EOD;
 | 
						|
}
 | 
						|
 | 
						|
TRecnotype & TDir::eox () const
 | 
						|
 | 
						|
{
 | 
						|
  return _dir->EOX;
 | 
						|
}
 | 
						|
 | 
						|
long& TDir::flags () const
 | 
						|
 | 
						|
{
 | 
						|
  return _dir->Flags;
 | 
						|
}
 | 
						|
 | 
						|
word & TDir::len () const
 | 
						|
 | 
						|
{
 | 
						|
  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));
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Aggiorna l'oggetto TDir con i parametri del file  
 | 
						|
void TDir::get (
 | 
						|
  int nfile,         // @parm Numero del file con cui aggiornare l'oggetto
 | 
						|
  TReclock lock,     // @parm Tipo di blocco (default _nolock)
 | 
						|
  TDirtype dirtype,  // @parm Direttorio nella quale e' contenuto il file (default _nordir)
 | 
						|
  TDirop op)         // @parm Tipo di operazioni effettuabili sul file (default _nordirop)
 | 
						|
 | 
						|
{
 | 
						|
  int whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
 | 
						|
 | 
						|
  if (op == _nordirop)
 | 
						|
    COpenFile (nfile, _dir, int(lock), whichdir);
 | 
						|
  else
 | 
						|
    CGetFile (nfile, _dir, int(lock), whichdir);
 | 
						|
  _num = nfile;
 | 
						|
  _com = _dir->SysName[0] != '$';
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Aggiorna il file indicato con i parametri passati
 | 
						|
void TDir::put (
 | 
						|
  int nfile,         // @parm Numero del file da aggiornare
 | 
						|
  TDirtype dirtype,  // @parm Direttorio nella quale e' contenuto il file (default _nordir)
 | 
						|
  TDirop op)         // @parm Tipo di operazioni effettuabili sul file (default _nordirop)
 | 
						|
{
 | 
						|
  CHECKD(nfile > 0, "Bad file number ", nfile);
 | 
						|
 | 
						|
  const int whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
 | 
						|
 | 
						|
  if (op == _nordirop)
 | 
						|
    CCloseFile (nfile, _dir, whichdir);
 | 
						|
  else
 | 
						|
    CPutFile (nfile, _dir, whichdir);
 | 
						|
}
 | 
						|
 | 
						|
void TDir::zero ()
 | 
						|
 | 
						|
{
 | 
						|
  zerofdes (_dir);
 | 
						|
}
 | 
						|
 | 
						|
void TDir::print_on (ostream & out) const
 | 
						|
 | 
						|
{
 | 
						|
  CHECK(_dir,"Can't print a NULL _dir");
 | 
						|
  out << _num << '\n';
 | 
						|
  out << (int)_com << '\n';
 | 
						|
  out << _dir->SysName << '|';
 | 
						|
  out << _dir->EOD << '|';
 | 
						|
  out << _dir->EOX << '|';
 | 
						|
  out << _dir->LenR << '|';
 | 
						|
  out << _dir->Flags << '|';
 | 
						|
  out << _dir->Des << '|';
 | 
						|
  out << _dir->FCalc << '|';
 | 
						|
  out << _dir->GenPrompt << '|' << '\n';
 | 
						|
}
 | 
						|
 | 
						|
void TDir::read_from (istream & in)
 | 
						|
 | 
						|
{
 | 
						|
  CHECK(_dir,"Can't read into a NULL _dir");
 | 
						|
  in.getline (_files_tmp_string, sizeof (_files_tmp_string), '\n');
 | 
						|
  _num = atoi(_files_tmp_string);
 | 
						|
  in.getline (_files_tmp_string, sizeof (_files_tmp_string), '\n');
 | 
						|
  _com = atoi(_files_tmp_string) != 0;
 | 
						|
  in.getline (_files_tmp_string, sizeof (_files_tmp_string), '\n');
 | 
						|
  TToken_string line(_files_tmp_string,'|');
 | 
						|
  line.restart();
 | 
						|
  strcpy(_dir->SysName,line.get());
 | 
						|
  _dir->EOD = line.get_long();
 | 
						|
  _dir->EOX = line.get_long();
 | 
						|
  _dir->LenR = line.get_int();
 | 
						|
  _dir->Flags = line.get_long();
 | 
						|
  strcpy(_dir->Des,line.get());
 | 
						|
  strcpy(_dir->FCalc,line.get());
 | 
						|
  strcpy(_dir->GenPrompt,line.get());
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Ritorna il numero di file presenti nella directory <p dirtype>
 | 
						|
//
 | 
						|
// @rdesc Ritorna il numero di file presenti
 | 
						|
int TDir::items (
 | 
						|
    TDirtype dirtype) const  // @parm Directory della quale contare i file
 | 
						|
 | 
						|
{
 | 
						|
  FileDes f;
 | 
						|
  int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
 | 
						|
 | 
						|
  CGetFile (1, &f, _nolock, _whichdir);
 | 
						|
  return (int) f.EOD;
 | 
						|
}
 | 
						|
 | 
						|
TTrec::TTrec ()
 | 
						|
     : _des(NULL), _tab("")
 | 
						|
 | 
						|
{
 | 
						|
  _rec = new RecDes;
 | 
						|
  zero ();
 | 
						|
  _num = -1;
 | 
						|
}
 | 
						|
 | 
						|
TTrec::TTrec(const TTrec & r)
 | 
						|
     : _des(NULL), _tab("")
 | 
						|
{             
 | 
						|
  _rec = new RecDes;
 | 
						|
  *_rec = *r._rec;
 | 
						|
  _num = r._num;
 | 
						|
}
 | 
						|
 | 
						|
TTrec::~TTrec ()
 | 
						|
 | 
						|
{
 | 
						|
  delete _rec;
 | 
						|
}
 | 
						|
 | 
						|
int TTrec::compare(const TSortable & a) const
 | 
						|
{
 | 
						|
  const TTrec & r = (const TTrec &) a;
 | 
						|
  int res = 0;
 | 
						|
  
 | 
						|
  if (_rec->NFields != r._rec->NFields || _rec->NKeys != r._rec->NKeys)  // Confronta prima il numero dei campi o il numero delle chiavi
 | 
						|
    res = 1;
 | 
						|
  else
 | 
						|
  {
 | 
						|
    const int nkeys = _rec->NKeys;
 | 
						|
    for (int i=0; i<nkeys && res==0; i++) // scorre la lista delle chiavi (sono meno del numero di campi)
 | 
						|
    {
 | 
						|
      const KeyDes& k1 = _rec->Ky[i];
 | 
						|
      const KeyDes& k2 = r._rec->Ky[i];
 | 
						|
      if (k1.DupKeys != k2.DupKeys || k1.NkFields != k2.NkFields)
 | 
						|
        res = 1;
 | 
						|
      else
 | 
						|
        for (int j=0; j<k1.NkFields && res==0; j++)
 | 
						|
          if (k1.FieldSeq[j] != k2.FieldSeq[j] || k1.FromCh[j] != k2.FromCh[j]
 | 
						|
              || (k1.FromCh[j] != INVFLD && k1.ToCh[j] != k2.ToCh[j]))
 | 
						|
              res = 1;
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (res == 0) // se sono ancora uguali confronta tutti i campi
 | 
						|
    {
 | 
						|
      const int nflds = _rec->NFields;
 | 
						|
      for (int n=0; n<nflds && res==0; n++)
 | 
						|
      {
 | 
						|
        const RecFieldDes& r1 = _rec->Fd[n];
 | 
						|
        const RecFieldDes& r2 = r._rec->Fd[n];
 | 
						|
        if (r1.TypeF != r2.TypeF || r1.Len != r2.Len || r1.Dec != r2.Dec)
 | 
						|
          res = 1;
 | 
						|
        else
 | 
						|
          if (strcmp(r1.Name,r2.Name) != 0) 
 | 
						|
            res = 1;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return res; 
 | 
						|
}
 | 
						|
 | 
						|
void TTrec::rehash()
 | 
						|
{
 | 
						|
  int  pos, tmppos, nf, i;
 | 
						|
  
 | 
						|
  for (i = 0; i < MaxFields; i++) _rec->SortFd[i] = INVFLD; 
 | 
						|
  if (_rec->NFields)
 | 
						|
  {
 | 
						|
    for (i = 0; i < _rec->NFields; i++) 
 | 
						|
    { 
 | 
						|
      nf = i; 
 | 
						|
      pos = hashfun(_rec->Fd[nf].Name);
 | 
						|
      while (TRUE)
 | 
						|
      { 
 | 
						|
        if (_rec->SortFd[pos] == INVFLD) 
 | 
						|
        { 
 | 
						|
          _rec->SortFd[pos] = (byte) nf; 
 | 
						|
          break; 
 | 
						|
        } 
 | 
						|
        else 
 | 
						|
        { 
 | 
						|
          if (strcmp(_rec->Fd[_rec->SortFd[pos]].Name, _rec->Fd[nf].Name) <= 0) 
 | 
						|
          { 
 | 
						|
            pos++;
 | 
						|
            if (pos >= MaxFields)
 | 
						|
              pos = 0; 
 | 
						|
          } 
 | 
						|
          else 
 | 
						|
          { 
 | 
						|
            tmppos = _rec->SortFd[pos]; 
 | 
						|
            _rec->SortFd[pos] = (byte) nf; 
 | 
						|
            nf = tmppos; 
 | 
						|
          } 
 | 
						|
        } 
 | 
						|
      } 
 | 
						|
    }
 | 
						|
    _rec->Fd[0].RecOff = 1; 
 | 
						|
    for (i = 1; i < _rec->NFields; i++) 
 | 
						|
      _rec->Fd[i].RecOff = _rec->Fd[i - 1].RecOff + _rec->Fd[i - 1].Len; 
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TTrec & TTrec::operator = (const TTrec & b)
 | 
						|
{
 | 
						|
  _num = b._num;
 | 
						|
  memcpy (_rec, b._rec, sizeof (*_rec));
 | 
						|
  return *this;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Assegna all'oggetto TTrec il tracciato record del file indicato
 | 
						|
void TTrec::get (
 | 
						|
  int nfile,        // @parm Numero del file da cui estrarre il tracciato record
 | 
						|
  TDirtype dirtype) // @parm Direttorio nella quale e' contenuto il file (default _nordir)
 | 
						|
 | 
						|
{
 | 
						|
  int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
 | 
						|
 | 
						|
  CGetRec (nfile, _rec, _whichdir);
 | 
						|
  _num = nfile;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Setta il file indicato con il tracciato record dell'oggetto                                
 | 
						|
void TTrec::put (
 | 
						|
  int nfile,        // @parm Numero del file di cui settare il tracciato record
 | 
						|
  TDirtype dirtype) // @parm Direttorio nella quale e' contenuto il file (default _nordir)
 | 
						|
 | 
						|
{
 | 
						|
  int _whichdir = (dirtype == _nordir ? NORDIR : COMDIR);
 | 
						|
 | 
						|
  if (nfile <= 0)
 | 
						|
    fatal_box ("Bad file number %d", nfile);
 | 
						|
  CPutRec (nfile, _rec, _whichdir);
 | 
						|
}
 | 
						|
 | 
						|
void TTrec::zero ()
 | 
						|
 | 
						|
{
 | 
						|
  _rec->NFields = 0; 
 | 
						|
  for (int i = 0; i < MaxFields; i++) 
 | 
						|
  { 
 | 
						|
    strcpy(_rec->Fd[i].Name, ""); 
 | 
						|
    _rec->Fd[i].TypeF = _nullfld;
 | 
						|
    _rec->Fd[i].Len = 0; 
 | 
						|
    _rec->Fd[i].Dec = 0; 
 | 
						|
    _rec->Fd[i].RecOff = 0;
 | 
						|
    _rec->SortFd[i] = INVFLD; 
 | 
						|
  } 
 | 
						|
  _rec->NKeys = 0; 
 | 
						|
  for (i = 1; i < MaxKeys; i++) 
 | 
						|
  { 
 | 
						|
    _rec->Ky[i].DupKeys = FALSE; 
 | 
						|
    _rec->Ky[i].NkFields = 0; 
 | 
						|
    for (int j = 0; j < MKFields; j++)
 | 
						|
    {
 | 
						|
      _rec->Ky[i].FieldSeq[j] = INVFLD; 
 | 
						|
      _rec->Ky[i].FromCh[j] = INVFLD; 
 | 
						|
      _rec->Ky[i].ToCh[j] = INVFLD; 
 | 
						|
    }
 | 
						|
  } 
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#ifndef FOXPRO
 | 
						|
 | 
						|
bool TDir::is_active () const
 | 
						|
{
 | 
						|
  const int module = abs((int)flags());
 | 
						|
  return main_app().has_module(module, CHK_DONGLE);
 | 
						|
}
 | 
						|
 | 
						|
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))
 | 
						|
  {                          
 | 
						|
    const char * dup = s.get();
 | 
						|
    _rec->Ky[key].DupKeys = (dup && *dup != ' ');
 | 
						|
    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].ToCh[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] = (int)inst.number().integer() - 1;
 | 
						|
          inst = c.step ();
 | 
						|
          _rec->Ky[key].ToCh[n] = _rec->Ky[key].FromCh[n] + (int)inst.number ().integer () - 1;
 | 
						|
          inst = c.step ();
 | 
						|
        }
 | 
						|
        else
 | 
						|
          c.backtrace ();
 | 
						|
        n++;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    _rec->Ky[key].NkFields = n;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TTrec::print_on (ostream & out) const
 | 
						|
 | 
						|
{
 | 
						|
  const int n = num();
 | 
						|
  out << n;
 | 
						|
  if (_des && n>=LF_TABGEN && n<=LF_TAB && _tab.not_empty()) // Solo se e' una tabella...
 | 
						|
    out << "|" << _tab;
 | 
						|
  out << '\n';
 | 
						|
  const int nfields = fields ();
 | 
						|
  TToken_string s (80);
 | 
						|
 | 
						|
  out << nfields << '\n';
 | 
						|
  for (int i = 0; i < nfields; i++)
 | 
						|
  {
 | 
						|
    s = fielddef (i);
 | 
						|
    out << s ;
 | 
						|
    if (_des)
 | 
						|
      out << "|" << _des->get(_rec->Fd[i].Name);
 | 
						|
    out << '\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;
 | 
						|
  const int n = num();
 | 
						|
 | 
						|
  in.getline (_files_tmp_string, sizeof (_files_tmp_string), '\n');
 | 
						|
  if (_des && n>=LF_TABGEN && n<=LF_TAB)
 | 
						|
  {
 | 
						|
    TString t(_files_tmp_string);
 | 
						|
 | 
						|
    if (t.find('|')>-1) 
 | 
						|
    {
 | 
						|
      TString tabname(t.right(3));
 | 
						|
      strcpy(_files_tmp_string,t.left(t.len()-4)); // Toglie il nome della tabella
 | 
						|
      if (_tab != tabname && !yesno_box("Descrizione relativa alla tabella %s.\n Continuo ?",(const char*) tabname))
 | 
						|
        return;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  ln = atoi (_files_tmp_string);
 | 
						|
  if (ln != n && !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);
 | 
						|
  TToken_string t;
 | 
						|
  for (int i = 0; i < nfields; i++)
 | 
						|
  {
 | 
						|
    in.getline (_files_tmp_string, sizeof (_files_tmp_string), '\n');
 | 
						|
    t = _files_tmp_string;
 | 
						|
    const int itms = t.items();
 | 
						|
    
 | 
						|
    update_fielddef (i, _files_tmp_string);
 | 
						|
    if (_des && itms == 5) // La descrizione viene caricata solo se esiste
 | 
						|
      _des->set(_rec->Fd[i].Name, t.get(itms-1));
 | 
						|
  }
 | 
						|
  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 ();
 | 
						|
  _des = NULL;
 | 
						|
  _tab = "";
 | 
						|
}
 | 
						|
 | 
						|
#endif // FOXPRO
 |