473 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			473 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <stdio.h>
 | |
| #include <memory.h>
 | |
| #include <stdlib.h>
 | |
| 
 | |
| #include <files.h>
 | |
| 
 | |
| #ifndef FOXPRO
 | |
| #include <expr.h>
 | |
| #endif
 | |
| 
 | |
| #ifndef __EXTCDECL_H
 | |
| #include <extcdecl.h>
 | |
| #endif
 | |
| 
 | |
| #ifndef __APPLICAT_H
 | |
| #include <applicat.h>
 | |
| #endif
 | |
| 
 | |
| #ifndef __STRINGS_H
 | |
| #include <strings.h>
 | |
| 
 | |
| #endif
 | |
| 
 | |
| #ifndef __UTILITY_H
 | |
| #include <utility.h>
 | |
| #endif
 | |
| 
 | |
| #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 () : _num(-1), _com(FALSE)
 | |
| 
 | |
| {
 | |
|   _dir = new FileDes;
 | |
|   if (_dir == NULL)
 | |
|     fatal_box ("Can't allocate dir");
 | |
|   zero ();
 | |
| }
 | |
| 
 | |
| 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;
 | |
|   _com = _dir->SysName[0] != '$';
 | |
| }
 | |
| 
 | |
| 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;
 | |
| }
 | |
| 
 | |
| bool TDir::is_active () const
 | |
| 
 | |
| {
 | |
|   int module = (int) flags();
 | |
|   if (module < 0) module = -module;
 | |
|   return main_app().has_module(module, CHK_DONGLE);
 | |
| }
 | |
| 
 | |
| 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;
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifndef FOXPRO
 | |
| 
 | |
| 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] = (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
 | |
| 
 | |
| {
 | |
|   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 ();
 | |
| }
 | |
| 
 | |
| #endif // FOXPRO
 |