Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 3.1 patch 766 git-svn-id: svn://10.65.10.50/trunk@14628 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1302 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1302 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <codeb.h>
 | |
| #include <diction.h>
 | |
| #include <extcdecl.h>
 | |
| #include <currency.h>
 | |
| #include <prefix.h>
 | |
| #include <progind.h>
 | |
| #include <scanner.h>
 | |
| #include <tabutil.h>
 | |
| #include <utility.h>
 | |
| 
 | |
| #include <nditte.h>
 | |
| 
 | |
| // Definita in isam.cpp
 | |
| extern int get_error(int);
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // extern variables are NO-NO!
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| HIDDEN TPrefix* _prefhndl = NULL;
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Inizializza (crea) un nuovo file "prefix.txt"
 | |
| //
 | |
| // @rdesc Ritorna l'oggetto <c TPrefix> creato
 | |
| TPrefix& prefix_init()
 | |
| {
 | |
|   CHECK(_prefhndl == NULL, "Can't create two prefix objects");
 | |
|   _prefhndl = new TPrefix;
 | |
|   return *_prefhndl;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Determina se il prefix e' stato inizializzato
 | |
| //
 | |
| // @rdesc Ritorna TRUE o FALSE
 | |
| bool prefix_valid()
 | |
| {
 | |
|   return _prefhndl != NULL;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Legge il file "prefix.txt"
 | |
| //
 | |
| // @rdesc Ritorna l'oggetto <c TPrefix> letto
 | |
| TPrefix& prefix()
 | |
| {
 | |
|   CHECK(_prefhndl, "Can't access null prefix");
 | |
|   return *_prefhndl;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Distrugge l'oggett <c TPrefix> in memoria
 | |
| void prefix_destroy()
 | |
| {
 | |
|   if (_prefhndl != NULL)
 | |
|   {
 | |
|     delete _prefhndl;
 | |
|     _prefhndl = NULL;
 | |
|   }  
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TFile_manager
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TRecord_info : public TObject
 | |
| {
 | |
|   RecDes _recdes;
 | |
|   TDirtype _dirtype;
 | |
|   int _len;
 | |
| 
 | |
| protected:
 | |
|   void translate_key(TToken_string& t) const;
 | |
|   void compute_len();
 | |
|   
 | |
|   bool create(TTrec& rec, TToken_string& keys);
 | |
| 
 | |
| public: // TObject
 | |
|   virtual bool ok() const;
 | |
| 
 | |
| public:
 | |
|   operator const RecDes&() const { return _recdes; }
 | |
|   int len() const { return _len; }
 | |
| 
 | |
|   TDirtype dir_type() const { return _dirtype; }
 | |
|   bool mutable_dir() const { return _dirtype <= _studir; }
 | |
|   bool fixed_dir() const { return _dirtype > _studir; }
 | |
| 
 | |
|   TRecord_info(int logicnum);
 | |
|   TRecord_info(const char* name);
 | |
|   TRecord_info(TTrec& rec, TToken_string& keys);
 | |
|   virtual ~TRecord_info() { }
 | |
| };
 | |
| 
 | |
| void TRecord_info::translate_key(TToken_string& t) const// Traduce l'espressione chiave di CodeBase
 | |
| {
 | |
|   // Trasforma l'espressione
 | |
|   TToken_string k(t.get(0),'+');
 | |
|   TToken_string range("",',');
 | |
|   TString ws;
 | |
|   const bool is_dup = t.get(1)[0] == 'X';
 | |
|   const int items = k.items();
 | |
|   t = "";
 | |
|   for (int i = 0; i<items; i++) // scorre i campi dell'espressione
 | |
|   {
 | |
|     ws = k.get(i); // Primo campo
 | |
|     const bool is_upper = ws.find("UPPER")  >= 0;
 | |
|     const bool is_sub   = ws.find("SUBSTR") >= 0;
 | |
|     int   paren1        = ws.find('('); // Trova la prima parentesi aperta
 | |
|     int   paren2,last,from = 0,to = 0;
 | |
|     
 | |
|     if (paren1 >= 0 && is_sub && is_upper)
 | |
|       paren1 = ws.find('('); // Trova la seconda parentesi (in questo caso c'e' per forza)
 | |
| 
 | |
|     if (paren1 >= 0) // Trova la prima virgola o parentesi chiusa (per qualsiasi espressione)
 | |
|     {
 | |
|       paren2 = ws.find(',');
 | |
|       if (paren2 == -1) // se non ci sono virgole trova la parentesi chiusa
 | |
|         paren2 = ws.find(')');
 | |
|       CHECK(paren2 > paren1,"Something wrong happened translating CodeBase expressions.");
 | |
|       if (is_sub) // Se e' una sottostringa estrae i campi DA e A
 | |
|       {
 | |
|         range = ws;
 | |
|         last = ws.find(')');
 | |
|         range.sub(paren2,last); // dalla virgola alla parentesi
 | |
|         from = range.get_int(0);
 | |
|         to   = range.get_int(1);
 | |
|       }
 | |
|       ws = ws.sub(paren1+1,paren2); // Nome del campo pulito pulito
 | |
|       ws.upper();
 | |
|     }
 | |
|     
 | |
|     if (is_upper)
 | |
|       t << "UPPER(";
 | |
|     
 | |
|     t << ws; // aggiunge il nome del campo
 | |
| 
 | |
|     if (is_sub)
 | |
|     {
 | |
|       t << "[";
 | |
|       t << from << ",";
 | |
|       t << to << "]";
 | |
|     }
 | |
|     if (is_upper)
 | |
|       t << ")";
 | |
|     t << '+';
 | |
|   }
 | |
|   t.rtrim(1); // Toglie il + in piu'
 | |
|   t.add(is_dup ? "X" : " "); 
 | |
| }
 | |
| 
 | |
| bool TRecord_info::ok() const 
 | |
| { 
 | |
|   return _recdes.NFields > 0 &&
 | |
|          _recdes.NKeys > 0 && _recdes.NKeys < MaxKeys;
 | |
| }
 | |
| 
 | |
| void TRecord_info::compute_len()
 | |
| {
 | |
|   _len = 0;
 | |
|   for (int f = _recdes.NFields-1; f >= 0; f--)
 | |
|     _len += _recdes.Fd[f].Len;
 | |
|   if (_len > 0)
 | |
|     _len++;
 | |
| }
 | |
| 
 | |
| TRecord_info::TRecord_info(int logicnum)
 | |
| {
 | |
|   memset(&_recdes, 0, sizeof(_recdes));
 | |
| 
 | |
|   FileDes fd; memset(&fd, 0, sizeof(fd));
 | |
|   CGetFile(logicnum, &fd, _nolock, _nordir);
 | |
|   if (fd.SysName[0])
 | |
|   {
 | |
|     _dirtype = fd.SysName[0] != '$' ? _comdir : _nordir;
 | |
|     CGetRec(logicnum, &_recdes, _dirtype);
 | |
|   }
 | |
|   if (ok())
 | |
|     compute_len();
 | |
| }
 | |
| 
 | |
| bool TRecord_info::create(TTrec& rec, TToken_string& keys)
 | |
| {
 | |
|   rec.rehash(); 
 | |
|   const int num_keys = rec.keys();
 | |
| 
 | |
|   TToken_string trans;
 | |
|   for (int i = 0; i < num_keys; i++)
 | |
|   {
 | |
|     trans = keys.get(i);
 | |
|     translate_key(trans); // Traduce l'espressione chiave di CodeBase
 | |
|     rec.update_keydef(i, trans); 
 | |
|   }
 | |
|   memcpy(&_recdes, rec.rec(), sizeof(RecDes));
 | |
|   compute_len();
 | |
|   return _len > 0;
 | |
| }
 | |
| 
 | |
| TRecord_info::TRecord_info(TTrec& rec, TToken_string& keys) 
 | |
|             : _dirtype(_extdir) 
 | |
| { 
 | |
|   create(rec, keys); 
 | |
| }
 | |
| 
 | |
| TRecord_info::TRecord_info(const char* name)
 | |
|             : _dirtype(_extdir)
 | |
| {
 | |
|   TFilename fname(name); fname.ext("dbf");
 | |
|   if (fname.exist())
 | |
|   {
 | |
|     TToken_string keys(256*MaxKeys, '$');
 | |
| 
 | |
|     fname.ext("");
 | |
|     FileDes fd;
 | |
|     TTrec rec;
 | |
|     int err = DB_recinfo(fname, &fd, rec.rec(), keys.get_buffer());
 | |
|     if (err != NOERR)
 | |
|       create(rec, keys); 
 | |
|     else
 | |
|       memset(&_recdes, 0, sizeof(_recdes));
 | |
|   }
 | |
|   else
 | |
|     memset(&_recdes, 0, sizeof(_recdes));
 | |
| }
 | |
| 
 | |
| 
 | |
| class TFile_info : public TObject
 | |
| {
 | |
|   TFilename _name;
 | |
|   int _ref_count;
 | |
| 
 | |
|   int _num;
 | |
|   int _handle;
 | |
|   clock_t _last_access, _last_change;
 | |
|   bool _locked, _exclusive;
 | |
|   TDirtype _dir;
 | |
|   FileDes _filedes;
 | |
| 
 | |
|   int _last_key;
 | |
| 
 | |
| protected:
 | |
|   int open_low(bool exclusive, bool index);
 | |
|   int close_low();
 | |
| 
 | |
| public:  // TObject
 | |
|   virtual bool ok() const { return _name.not_empty(); }
 | |
| 
 | |
| public:
 | |
|   const TFilename& pathname() const { return _name; }
 | |
|   int num() const { return _num; }
 | |
|   int handle() const { return _handle; }
 | |
|   bool is_open() const { return _handle >= 0; }
 | |
|   clock_t last_access() const { return _last_access; }
 | |
|   clock_t last_change() const { return _last_change; }
 | |
|   bool is_exclusive() const { return _exclusive; }
 | |
|   bool is_locked() const { return _locked; }
 | |
|   int ref_count() const { return _ref_count; }
 | |
|   int last_key() const { return _last_key; }
 | |
|   void touch() { _last_access = clock(); }
 | |
|   void set_dirty() { _last_change = clock(); }
 | |
| 
 | |
|   TDirtype dir_type() const { return _dir; }
 | |
|   bool mutable_dir() const { return _dir <= _studir; }
 | |
|   bool fixed_dir() const { return _dir > _studir; }
 | |
| 
 | |
|   int open(bool exclusive, bool index);
 | |
|   int close();
 | |
|   const TFilename& load_filedes();
 | |
| 
 | |
|   void lock_record(TRecnotype rec);
 | |
|   void unlock_record(TRecnotype rec);
 | |
| 
 | |
|   int auto_open(int key);
 | |
|   void auto_close();
 | |
| 
 | |
|   operator const FileDes&() const { return _filedes; }
 | |
|   TFile_info(int logicnum, TFilename& name);
 | |
|   virtual ~TFile_info();
 | |
| };
 | |
| 
 | |
| 
 | |
| int TFile_info::open_low(bool exclusive, bool index)
 | |
| {
 | |
|   if (_handle < 0)
 | |
|     _handle = DB_open(_name, exclusive, index);
 | |
| #ifdef DBG
 | |
|   else
 | |
|     error_box("You shouldn't reopen file %s", (const char*)_name);
 | |
| #endif
 | |
|   int err = NOERR;
 | |
|   if (_handle >= 0)
 | |
|   {
 | |
|     if (num() < LF_EXTERNAL && (_dir == _nordir || _dir == _comdir))
 | |
|     {
 | |
|       TRecnotype n = DB_reccount(_handle);
 | |
|       TDir d;
 | |
|       d.get(num(),_nolock,_dir,_sysdirop);
 | |
|       _filedes.EOD = d.eod() = n;
 | |
|       _filedes.EOX = d.eox() = n; 
 | |
|       d.put(num(),_dir,_sysdirop); 
 | |
|     }
 | |
| 
 | |
|     if (index)
 | |
|       err = DB_tagselect(_handle, _last_key = 1);
 | |
|     else
 | |
|       _last_key = 0;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     err = get_error(_handle);
 | |
|   }
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| int TFile_info::close_low()
 | |
| {
 | |
|   int err = NOERR;
 | |
|   if (_handle >= 0)
 | |
|   {
 | |
|     DB_close(_handle);
 | |
|     _handle = -1;
 | |
|     _last_key = -1;
 | |
|     _exclusive = _locked = FALSE; 
 | |
|   }
 | |
|   else
 | |
|   {
 | |
| #ifdef DBG
 | |
|     error_box("You shouldn't reclose file %s", (const char*)_name);
 | |
| #endif
 | |
|     err = _isnotopen;
 | |
|   }
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| int TFile_info::open(bool exclusive, bool index)
 | |
| {
 | |
|   int err = NOERR;
 | |
|   if (exclusive || !index)
 | |
|   {
 | |
|     if (_ref_count > 0 || is_open())  
 | |
|     {
 | |
| #ifdef DBG            
 | |
|       if (_ref_count > 0)
 | |
|         error_box("You shouldn't reopen file %d exclusively", num());
 | |
| #endif
 | |
|       close_low();
 | |
|     }
 | |
|     _exclusive = _locked = TRUE;
 | |
|     err = open_low(exclusive, index);
 | |
|   }
 | |
|   touch();  // Memorizza ora apertura del file
 | |
|   _ref_count++;
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| int TFile_info::close()
 | |
| {
 | |
|   int err = NOERR;
 | |
|   if (_ref_count > 0)
 | |
|   {
 | |
|     _ref_count--;
 | |
|     if (_ref_count == 0)
 | |
|     {
 | |
|       if (is_open()) 
 | |
|       {
 | |
|         // Chiudi fisicamente solo se necessario
 | |
|         if (_locked || _exclusive || dir_type() == _extdir)
 | |
|           err = close_low();
 | |
|       }  
 | |
|       _locked = _exclusive = FALSE;
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|     err = _isnotopen;
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| void TFile_info::auto_close()
 | |
| {
 | |
|   const bool yes = is_open() && !(is_locked() || is_exclusive());
 | |
|   if (yes)
 | |
|     close_low();
 | |
|   else
 | |
|     NFCHECK("Can't auto_close file '%s'", (const char*)_name);
 | |
| }
 | |
| 
 | |
| int TFile_info::auto_open(int key)
 | |
| {
 | |
|   if (_handle < 0)
 | |
|     open_low(FALSE, TRUE);
 | |
| 
 | |
|   if (_handle >= 0)
 | |
|   {
 | |
|     if (key > 0 && key != _last_key)
 | |
|     {
 | |
|       const int err = DB_tagselect(_handle, _last_key = key);
 | |
|       if (err != NOERR)
 | |
|       {
 | |
| #ifdef DBG
 | |
|         NFCHECK("Can't set key %d on file %d", key, num());
 | |
| #endif
 | |
|         return err;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return _handle;
 | |
| }
 | |
| 
 | |
| void TFile_info::lock_record(TRecnotype) 
 | |
| { _locked = TRUE; }
 | |
| 
 | |
| void TFile_info::unlock_record(TRecnotype) 
 | |
| { _locked = FALSE; }
 | |
| 
 | |
| const TFilename& TFile_info::load_filedes()
 | |
| {
 | |
|   memset(&_filedes, 0, sizeof(_filedes));
 | |
|   CGetFile(num(), &_filedes, _nolock, _nordir);
 | |
|   if (_filedes.SysName[0])
 | |
|   {
 | |
|     if (_filedes.SysName[0] != '$')
 | |
|       _dir = _comdir;
 | |
|     else
 | |
|       _dir = _nordir;
 | |
|     COpenFile(num(), &_filedes, _nolock, _dir);
 | |
|     _name = _filedes.SysName;
 | |
|   }
 | |
|   else
 | |
|     _name.cut(0);
 | |
|   return _name;
 | |
| }
 | |
| 
 | |
| TFile_info::TFile_info(int logicnum, TFilename& name)
 | |
| : _ref_count(0), _num(logicnum), _handle(-1),
 | |
|   _last_access(0), 
 | |
|   _last_change(0), _locked(FALSE), _exclusive(FALSE), _last_key(-1)
 | |
| {
 | |
|   if (logicnum < LF_EXTERNAL)
 | |
|   {
 | |
|     load_filedes();
 | |
|     if (name.not_empty())
 | |
|     {
 | |
|       // File dati temporaneo
 | |
|       _dir = _extdir;
 | |
|       _name = name;
 | |
|       _name.ext("");
 | |
|     }
 | |
|     else
 | |
|       name = _name;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     // File dati esterno
 | |
|     _dir = _extdir;
 | |
|     _name = name;
 | |
|     _name.ext("dbf");
 | |
|     if (_name.exist())
 | |
|     {
 | |
|       TToken_string keys(256*MaxKeys, '$');
 | |
| 
 | |
|       _name.ext("");
 | |
|       TTrec rec;
 | |
|       int err = DB_recinfo(_name, &_filedes, rec.rec(), keys.get_buffer());
 | |
|       if (err == NOERR && prefix().add_recdes(logicnum, rec, keys))
 | |
|       {
 | |
|         strncpy(_filedes.SysName, _name, 40);
 | |
|         _filedes.SysName[41] = '\0';
 | |
|       }
 | |
|       else
 | |
|         _name.cut(0);
 | |
|     }
 | |
|     else
 | |
|       _name.cut(0);
 | |
|   }
 | |
| }
 | |
| 
 | |
| TFile_info::~TFile_info()
 | |
| {
 | |
|   if (is_open())
 | |
|     close_low();
 | |
| }
 | |
| 
 | |
| TFile_info& TFile_manager::fileinfo(TIsam_handle num) const
 | |
| {
 | |
|   TFile_info* i = (TFile_info*)_fileinfo.objptr(num);
 | |
|   if (i == NULL && num > 0 && num < LF_EXTERNAL)
 | |
|   {                    
 | |
|     TFilename name;
 | |
|     i = new TFile_info(num, name);
 | |
|     if (i->ok())
 | |
|       ((TFile_manager*)this)->_fileinfo.add(i, num);
 | |
|     else  
 | |
|     {          
 | |
|       delete i;
 | |
|       i = NULL;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   CHECKD(i, "Unknown file ", num);
 | |
|   return *i;
 | |
| }
 | |
| 
 | |
| TRecord_info& TFile_manager::recinfo(int logicnum) const
 | |
| {
 | |
|   TRecord_info* i = (TRecord_info*)_recinfo.objptr(logicnum);
 | |
|   if (i == NULL)
 | |
|   {
 | |
|     i = new TRecord_info(logicnum);
 | |
|     ((TFile_manager*)this)->_recinfo.add(i, logicnum);
 | |
|   }
 | |
|   return *i;
 | |
| }
 | |
| 
 | |
| bool TFile_manager::add_recdes(int logicnum, TTrec& rec, TToken_string& keys)
 | |
| {
 | |
|   TRecord_info* i = (TRecord_info*)_recinfo.objptr(logicnum);
 | |
|   if (i == NULL)
 | |
|   {
 | |
|     if (logicnum < LF_EXTERNAL)
 | |
|       i = new TRecord_info(logicnum);
 | |
|     else
 | |
|       i = new TRecord_info(rec, keys);
 | |
|     if (i->ok())
 | |
|       _recinfo.add(i, logicnum);
 | |
|     else
 | |
|     {
 | |
|       delete i;
 | |
|       i = NULL;
 | |
|     }
 | |
|   }
 | |
|   return i != NULL;
 | |
| }
 | |
| 
 | |
| 
 | |
| bool TFile_manager::close_oldest()
 | |
| {
 | |
|   int oldest = 0;
 | |
|   clock_t age = 0;
 | |
|   _open_files = 0;  // Intanto ricalcolo il numero di file veramente aperti
 | |
|   for (int n = _fileinfo.last(); n > 0; n = _fileinfo.pred(n))
 | |
|   {
 | |
|     TFile_info& i = (TFile_info&)_fileinfo[n];
 | |
|     if (i.is_open())
 | |
|     {
 | |
|       _open_files++;
 | |
|       if (!i.is_locked() && !i.is_exclusive())
 | |
|       {
 | |
|         if (oldest == 0 || i.last_access() < age)
 | |
|         {
 | |
|           oldest = n;
 | |
|           age = i.last_access();
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   if (oldest)
 | |
|   {
 | |
|     TFile_info& i = (TFile_info&)_fileinfo[oldest];
 | |
|     i.auto_close();
 | |
|     _open_files--;
 | |
|   }
 | |
|   
 | |
|   return oldest != 0; //verificare
 | |
| }
 | |
| 
 | |
| // name    : nome del file
 | |
| TIsam_handle TFile_manager::get_handle(TFilename& name)
 | |
| {
 | |
| 	
 | |
|   TFile_info* i = NULL;
 | |
| 	TFilename fname(name); fname.ext("");
 | |
| 	int num;
 | |
| 	
 | |
|   for (num = LF_EXTERNAL; (i = (TFile_info*)_fileinfo.objptr(num)) != NULL; num++)
 | |
|   {
 | |
|     if (i->pathname() == fname)
 | |
|       break;
 | |
|   }
 | |
| 	if (i == NULL)
 | |
| 	{
 | |
|     i = new TFile_info(num, name);
 | |
|     if (!i->ok())
 | |
|     {
 | |
|       delete i;
 | |
|       return -60;
 | |
|     }
 | |
|     _fileinfo.add(i, num);
 | |
| 	}
 | |
| 			
 | |
|   return num;
 | |
| }
 | |
| 
 | |
| // name    : nome del file (vuoto per i file normali viene riempito automaticamente)
 | |
| // logicnum: numero logico del file (LF_EXTERNAL per gli esterni viene generato automaticamente)
 | |
| TIsam_handle TFile_manager::open(int& logicnum, TFilename& name, bool exclusive, bool index)
 | |
| {
 | |
|   TIsam_handle num = logicnum;
 | |
|   if (name.not_empty())
 | |
|   {
 | |
| 		num = get_handle(name);
 | |
|     if (logicnum >= LF_EXTERNAL)
 | |
|       logicnum = num;
 | |
|   }
 | |
|   
 | |
|   TFile_info* i = (TFile_info*)_fileinfo.objptr(num);
 | |
|   if (i == NULL)
 | |
|   {
 | |
|     i = new TFile_info(logicnum, name);
 | |
|     if (!i->ok())
 | |
|     {
 | |
|       delete i;
 | |
|       return -60;
 | |
|     }
 | |
|     _fileinfo.add(i, num);
 | |
|   }
 | |
|   i->open(exclusive, index);
 | |
|   name = i->pathname();
 | |
|   return num;
 | |
| }
 | |
| 
 | |
| int TFile_manager::close(TIsam_handle& name)
 | |
| {
 | |
|   int err = _isnotopen;
 | |
| 
 | |
|   TFile_info* i = (TFile_info*)_fileinfo.objptr(name);
 | |
|   if (i != NULL)
 | |
|   {
 | |
|     const bool was_open = i->is_open();
 | |
|     err = i->close();
 | |
|     // Se chiuso veramente ... (Per efficienza non chiude sempre)
 | |
|     if (err == NOERR && !i->is_open()) 
 | |
|     {
 | |
|       if (was_open)
 | |
|         _open_files--;
 | |
|       if (name >= LF_EXTERNAL && i->ref_count() <= 0)
 | |
|       {
 | |
|         _fileinfo.remove(name);
 | |
|         _recinfo.remove(name);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   name = 0;
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| TCodeb_handle TFile_manager::get_handle(TIsam_handle name, int key)
 | |
| {
 | |
|   TFile_info& i = fileinfo(name);
 | |
|   if (i.ref_count() == 0)
 | |
|     NFCHECK("Can't use closed file %d", i.num());
 | |
| 
 | |
|   TCodeb_handle handle = i.handle();
 | |
|   if (handle < 0)
 | |
|   {
 | |
|     if (_open_files >= _max_open_files)
 | |
|       close_oldest();
 | |
| 
 | |
|     // Se ho passato key = -1 mi va bene la chiave principale
 | |
|     if (key < 0) 
 | |
|       key = 1;
 | |
|     
 | |
|     handle = i.auto_open(key);
 | |
|     if (handle >= 0)
 | |
|       _open_files++;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     // Se ho passato key = -1 mi va bene la chiave corrente
 | |
|     if (key >= 0 && i.last_key() != key)
 | |
|       handle = i.auto_open(key);
 | |
|   }
 | |
| //  i.touch();  // Memorizza troppo spesso l'accesso
 | |
|   return handle;
 | |
| }
 | |
| 
 | |
| void TFile_manager::lock_record(TIsam_handle num, TRecnotype rec)
 | |
| {
 | |
|   TFile_info& i = fileinfo(num);
 | |
|   i.lock_record(rec);
 | |
| }
 | |
| 
 | |
| void TFile_manager::unlock_record(TIsam_handle num, TRecnotype rec)
 | |
| {
 | |
|   TFile_info& i = fileinfo(num);
 | |
|   i.unlock_record(rec);
 | |
| }
 | |
| 
 | |
| const RecDes& TFile_manager::get_recdes(int logicnum) const
 | |
| {
 | |
|   const TRecord_info& i = recinfo(logicnum);
 | |
|   return i;
 | |
| }
 | |
| 
 | |
| const RecDes& TFile_manager::update_recdes(int logicnum)
 | |
| {
 | |
|   _recinfo.destroy(logicnum);
 | |
|   return get_recdes(logicnum);
 | |
| }
 | |
| 
 | |
| int TFile_manager::get_reclen(int logicnum)
 | |
| {
 | |
|   const TRecord_info& i = recinfo(logicnum);
 | |
|   return i.ok() ? i.len() : 0;
 | |
| }
 | |
| 
 | |
| TDirtype TFile_manager::get_dirtype(int logicnum)
 | |
| {
 | |
|   const TRecord_info& i = recinfo(logicnum);
 | |
|   return i.dir_type();
 | |
| }
 | |
| 
 | |
| void TFile_manager::notify_change(TIsam_handle name)
 | |
| {
 | |
|   TFile_info& i = fileinfo(name);
 | |
|   i.set_dirty();
 | |
| }
 | |
| 
 | |
| long TFile_manager::last_change(TIsam_handle name) const
 | |
| {
 | |
|   TFile_info& i = fileinfo(name);
 | |
|   return i.last_change();
 | |
| }
 | |
| 
 | |
| int TFile_manager::close_closeable()
 | |
| {
 | |
|   _open_files = 0;
 | |
|   for (TIsam_handle n = _fileinfo.last(); n > 0; n = _fileinfo.pred(n))
 | |
|   {
 | |
|     TFile_info& i = fileinfo(n);
 | |
|     if (i.is_open())
 | |
|     {
 | |
|       if (!i.is_exclusive())
 | |
|         i.auto_close();
 | |
|       else
 | |
|         _open_files++;
 | |
|     }
 | |
|     if (i.ref_count() <= 0)
 | |
|       _fileinfo.destroy(n);
 | |
|   }
 | |
|   return _open_files;
 | |
| }
 | |
| 
 | |
| void TFile_manager::close_all()
 | |
| {
 | |
|   const int zoccolo_duro = close_closeable();
 | |
| #ifdef DBG
 | |
|   if (zoccolo_duro > 0)
 | |
|     NFCHECK("%d files refuse can't be closed!", zoccolo_duro);
 | |
| #endif
 | |
|   
 | |
|   for (int n = _recinfo.last(); n > 0; n = _recinfo.pred(n))
 | |
|   {
 | |
|     const TRecord_info& r = recinfo(n);
 | |
|     if (r.mutable_dir())
 | |
|       _recinfo.destroy(n);
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TFile_manager::open_all()
 | |
| {
 | |
|   for (TIsam_handle n = _fileinfo.last(); n > 0; n = _fileinfo.pred(n))
 | |
|   {
 | |
|     TFile_info& i = fileinfo(n);
 | |
|     if (!i.is_exclusive())
 | |
|     {
 | |
|       if (i.mutable_dir())
 | |
|         i.load_filedes();
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| const FileDes& TFile_manager::get_filedes(TIsam_handle id) const
 | |
| {
 | |
|   TFile_info& i = fileinfo(id);
 | |
|   return i;
 | |
| }
 | |
| 
 | |
| const TFilename& TFile_manager::get_filename(TIsam_handle id) const
 | |
| {
 | |
|   TFile_info& i = fileinfo(id);
 | |
|   return i.pathname();
 | |
| }
 | |
| 
 | |
| 
 | |
| TFile_manager::TFile_manager()
 | |
|              : _open_files(0)
 | |
| {
 | |
|   TConfig prawin(CONFIG_INSTALL, "Main");
 | |
|   _max_open_files = prawin.get_int("MaxHandles", NULL, -1, 16);
 | |
|   if (_max_open_files < 16)
 | |
|     _max_open_files = 16;
 | |
|   else
 | |
|     if (_max_open_files > 64)
 | |
|       _max_open_files = 64;
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TFirm
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| bool TFirm::read(long cod)
 | |
| {
 | |
|   int err = NOERR;
 | |
|   if (cod < 0L)
 | |
|     cod = prefix().get_codditta();
 | |
|   _rec.destroy();
 | |
|   TLocalisamfile ditte(LF_NDITTE);
 | |
|   if (cod > 0L)
 | |
|   {           
 | |
|     ditte.put("CODDITTA", cod);
 | |
|     err = ditte.read();
 | |
|   }
 | |
|   else
 | |
|     err = ditte.first();
 | |
|   if (err == NOERR)
 | |
| 	{
 | |
|     const TRectype& ditta = ditte.curr();   
 | |
|     for (int f = ditta.items()-1; f >= 0; f--)
 | |
|     {
 | |
|       const char* name = ditta.fieldname(f);
 | |
|       _rec.add(name, ditta.get(name));
 | |
|     }
 | |
| 	}
 | |
| 	else
 | |
|     NFCHECK("Can't read firm %ld: error %d", cod, err);
 | |
| 
 | |
|   return _rec.items() > 0;
 | |
| }
 | |
| 
 | |
| const TString& TFirm::get(const char* attr) const
 | |
| {
 | |
|   const TString* str = (const TString*)_rec.objptr(attr);
 | |
|   if (str == NULL)
 | |
|     str = &EMPTY_STRING;
 | |
|   return *str;
 | |
| }
 | |
| 
 | |
| long TFirm::get_long(const char* attr) const
 | |
| { return atol(get(attr)); }
 | |
| 
 | |
| long TFirm::codice() const
 | |
| {
 | |
|   return get_long(NDT_CODDITTA);
 | |
| }
 | |
| 
 | |
| const TString& TFirm::codice_valuta() const
 | |
| {          
 | |
|   const TString& codval = get(NDT_VALUTA);
 | |
|   if (codval.empty())
 | |
|     return TCurrency::get_base_val();
 | |
|   return codval;
 | |
| }
 | |
| 
 | |
| const TString& TFirm::ragione_sociale() const
 | |
| {          
 | |
|   return get(NDT_RAGSOC);
 | |
| }
 | |
| 
 | |
| 
 | |
| TFirm::TFirm(long code)
 | |
| {
 | |
|   read(code);
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TPrefix
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| TPrefix::TPrefix() : _filelevel(0), _stdlevel(0), _items(0), _firm(NULL)
 | |
| {
 | |
|   _prefix = ".";
 | |
|   CGetPref();
 | |
|   
 | |
|   if (!fexist(__ptprf) || strchr(__ptprf, ' ') != NULL)
 | |
|     fatal_box(FR("Percorso dati non valido: '%s'"), __ptprf);
 | |
| 
 | |
|   const TFilename dir(cprefix);
 | |
|   const long primaditta = atol(dir.name());
 | |
|   if (primaditta > 0L && !exist(primaditta))
 | |
|     set_codditta(0L, TRUE);
 | |
| 
 | |
|   DB_init();
 | |
| 
 | |
|   set("");    // Dati standard
 | |
|   _stdlevel = filelevel();
 | |
|   set("DEF"); // Ditta corrente
 | |
| }
 | |
| 
 | |
| TPrefix::~TPrefix()
 | |
| {
 | |
|   set();
 | |
|   if (_firm)
 | |
|     delete _firm;
 | |
|   _manager.close_all();
 | |
|   DB_exit();
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Riapre tutti gli archivi della ditta attiva
 | |
| void TPrefix::reopen() const
 | |
| {
 | |
|   if (_prefix != ".")
 | |
|   {
 | |
|     ((TPrefix*)this)->_manager.close_all();
 | |
|     ((TPrefix*)this)->_manager.open_all();
 | |
|   }
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Setta la ditta corrente                 
 | |
| void TPrefix::set(
 | |
|   const char* name, // @parm Nome del direttorio dati da attivare (default NULL)
 | |
|   bool force,       // @parm Permette di settarla anche se non esiste (default FALSE)
 | |
|   TFilelock mode)   // @parm Permette di aprire la ditta in modo esclusivo (default _manulock)
 | |
|   
 | |
|   // @comm Il parametro <p name> puo' assumere i seguenti valori:
 | |
|   //
 | |
|   // @flag NULL | Chiude tutti i files
 | |
|   // @flag COM | Apre il direttorio con i dati comuni
 | |
|   // @flag DEF | Riapre la ditta indicata nel file prefix.txt
 | |
|   // @flag codice ditta | Apre la ditta indicata
 | |
| {                 
 | |
|   if (name == NULL)
 | |
|   {
 | |
|     close_closeable_isamfiles();
 | |
|     CCloseDir(NORDIR);
 | |
|     CCloseDir(COMDIR);
 | |
|     CCloseRecDir(NORDIR);
 | |
|     CCloseRecDir(COMDIR);
 | |
|     _prefix = ".";
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (_prefix == name) 
 | |
|     return;
 | |
|   if (!force && !test(name)) 
 | |
|     return;
 | |
|   if (_prefix != ".")
 | |
|   {
 | |
|     _manager.close_all();
 | |
|     CCloseDir(NORDIR);
 | |
|     CCloseDir(COMDIR);
 | |
|     CCloseRecDir(NORDIR);
 | |
|     CCloseRecDir(COMDIR);
 | |
|   }
 | |
| 
 | |
|   if (strcmp(name, "DEF") == 0)
 | |
|   {
 | |
|     CGetPref();
 | |
|     xvt_fsys_parse_pathname(cprefix, NULL, NULL, _prefix.get_buffer(), NULL, NULL);
 | |
|   }
 | |
|   else
 | |
|   {      
 | |
|     _prefix = name;
 | |
|    if (*name) 
 | |
|      xvt_fsys_build_pathname(cprefix, NULL, __ptprf, name, NULL, NULL);
 | |
|    else 
 | |
|      strcpy(cprefix, "");
 | |
|   }
 | |
| 
 | |
|   if (!test(_prefix)) 
 | |
|     fatal_box("Impossibile utilizzare la ditta %s", name);
 | |
| 
 | |
|   COpenDir((int) mode, NORDIR);
 | |
|   COpenDir((int) mode, COMDIR);
 | |
|   COpenRecDir((int) mode, NORDIR);
 | |
|   COpenRecDir((int) mode, COMDIR);
 | |
|   if (_prefix != ".")
 | |
|   {    
 | |
|     FileDes d;
 | |
|     CGetFile(LF_DIR, &d, _nolock, NORDIR);
 | |
|     _filelevel = d.Flags;
 | |
|     _items = (int)d.EOD;
 | |
|     _manager.open_all();
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool TPrefix::exist(long codditta) const
 | |
| {
 | |
|   if (codditta > 0L && codditta < 100000L)
 | |
|   {
 | |
|     TFilename s(firm2dir(codditta)); 
 | |
|     s.add("dir.gen");
 | |
|     if (s.exist())
 | |
|     {
 | |
|       s = s.path();
 | |
|       s.add("trc.gen");
 | |
|       return s.exist();
 | |
|     }
 | |
|   }
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| bool TPrefix::test(const char* s) const
 | |
| {
 | |
|   if (s && *s && strcmp(s, "DEF") != 0)
 | |
|   {
 | |
|     TFilename s1(__ptprf);
 | |
|     s1.add(s);
 | |
|     s1.add("dir.gen");
 | |
|     
 | |
|     if (s1.exist())
 | |
|     {
 | |
|       if (xvt_fsys_access(s1, 0x2) != 0)
 | |
|         return error_box(FR("Impossibile accedere in lettura/scrittura al file '%s'"), (const char*)s1);
 | |
|     }
 | |
|     else
 | |
|       return error_box(FR("Impossibile trovare il file '%s'"), (const char*)s1);
 | |
|   }
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| void TPrefix::lock_record(TIsam_handle num, TRecnotype rec)
 | |
| {
 | |
|   _manager.lock_record(num, rec);
 | |
| }
 | |
| 
 | |
| void TPrefix::unlock_record(TIsam_handle num, TRecnotype rec)
 | |
| {
 | |
|   _manager.unlock_record(num, rec);
 | |
| }
 | |
| 
 | |
| bool TPrefix::test(long codditta) const
 | |
| {
 | |
|   TString8 s("com");
 | |
|   if (codditta > 0L)
 | |
|     s.format("%05lda", codditta);
 | |
|   return test(s);
 | |
| }
 | |
| 
 | |
| 
 | |
| long TPrefix::get_codditta() const
 | |
| {
 | |
|   const long codditta = atol(_prefix);
 | |
|   return codditta;
 | |
| }
 | |
| 
 | |
| bool TPrefix::set_codditta(long codditta, bool force)
 | |
| {
 | |
|   if (force || test(codditta))
 | |
|   {
 | |
|     TString8 s("com");
 | |
|     if (codditta > 0L) 
 | |
|       s.format("%05lda", codditta); 
 | |
|     set(s, force);
 | |
|     CPutPref(_prefix);
 | |
|     if (_firm) 
 | |
|       _firm->read(codditta);
 | |
|     return TRUE;
 | |
|   }
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| const char* TPrefix::get_studio() const
 | |
| {
 | |
|   return __ptprf;
 | |
| }
 | |
| 
 | |
| bool TPrefix::set_studio(const char* study, long ditta)
 | |
| {             
 | |
|   TFilename dirtest(study);
 | |
|   if (!dirtest.exist() || dirtest.find(' ') >= 0)
 | |
|     return FALSE;
 | |
| 
 | |
|   dirtest.add("com/dir.gen");
 | |
|   if (!dirtest.exist())
 | |
|     return FALSE;
 | |
| 
 | |
|   // Chiudi tutti i files!
 | |
|   _manager.close_all();
 | |
| 
 | |
|   const TString old_study(__ptprf);
 | |
|   const TString old_firm(_prefix);
 | |
|   
 | |
|   strcpy(__ptprf, study);
 | |
|   const word len = strlen(__ptprf);
 | |
|   if (len > 0 && __ptprf[len-1] != '\\' && __ptprf[len-1] != '/')
 | |
|   {
 | |
|     __ptprf[len] = SLASH;
 | |
|     __ptprf[len+1] = '\0';
 | |
|   }
 | |
|   if (!test(ditta))
 | |
|     ditta = 0L;
 | |
|   
 | |
|   bool ok = set_codditta(ditta, TRUE);
 | |
|   if (!ok)
 | |
|   {
 | |
|     strcpy(__ptprf, old_study);
 | |
|     set(old_firm, TRUE);
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Ritorna la descrizione del file passato
 | |
| const char* TPrefix::description(
 | |
|   const char* cod) const // @parm Nome del file di cui si vuole conoscere la descrizione
 | |
| 
 | |
|   // @syntax const char* description(const char* cod);
 | |
|   // @syntax const char* description(int cod);
 | |
|   //                    
 | |
|   // @comm Il parametro <p cod> puo' indicare anche il nome di una tabella. In questo caso ne
 | |
|   //       ritorna la descrizione.
 | |
|   //             <nl>Passando il nome di una tabella in <p cod> si ottiene la stessa cosa della
 | |
|   //             funzione <mf TDir::Tab_des>, ma viene cercato la descrizione nel titolo della maschera.
 | |
| {
 | |
|   TString& n = get_tmp_string();
 | |
|   n = cod;
 | |
| 
 | |
|   if (n[0] == '%') 
 | |
|     n.ltrim(1);
 | |
|   
 | |
|   const int logicnum = atoi(n);
 | |
|   if (logicnum == 0)
 | |
|   {
 | |
|     TTable t(cod);
 | |
|     n = t.description();
 | |
|   }  
 | |
|   else
 | |
|   {
 | |
|     if (logicnum > 0 && logicnum < items())
 | |
|     { 
 | |
|       TBaseisamfile f(logicnum);
 | |
|       n = f.description();
 | |
|     } 
 | |
|     else n.cut(0);
 | |
|   }  
 | |
|   
 | |
|   return n;
 | |
| }
 | |
| 
 | |
| const char* TPrefix::description(int cod) const
 | |
| {
 | |
|   TString8 n; n << cod;
 | |
|   return description(n);
 | |
| }
 | |
| 
 | |
| const TFirm& TPrefix::firm()
 | |
| {
 | |
|   if (_firm == NULL)
 | |
| 	  _firm = new TFirm;
 | |
|   return *_firm;
 | |
| }
 | |
| 
 | |
| 
 | |
| // Certified 90%
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @func Converte il numero di una ditta nella sua directory dati
 | |
| //
 | |
| // @rdesc Restituisce il nome di una directory dati
 | |
| const char* firm2dir(
 | |
|       long codditta) // @parm Codice ditta da convertire
 | |
| {                  
 | |
|   TString8 firm;
 | |
|   switch (codditta)
 | |
|   {
 | |
|   case -2:                                     // Dati generali campione
 | |
|   case -1:                                     // Dati di studio
 | |
|     firm = ""; break;
 | |
|   case  0:                                     // Dati comuni
 | |
|     firm = "com"; break;
 | |
|   default:                                     // Dati ditta
 | |
|     firm.format("%05lda", codditta); break;
 | |
|   }    
 | |
| 
 | |
|   TString& path = get_tmp_string(256);
 | |
|   xvt_fsys_build_pathname(path.get_buffer(), NULL, __ptprf, firm, NULL, NULL);
 | |
|   return path;
 | |
| }                      
 | |
| 
 | |
| int safely_close_closeable_isamfiles()
 | |
| {
 | |
|   int f = 0;
 | |
|   if (_prefhndl)
 | |
|     f = _prefhndl->close_closeable_isamfiles();
 | |
|   return f;
 | |
| }
 | |
| 
 | |
| bool TPrefix::build_firm_data(long codditta, bool flagcom)
 | |
| {
 | |
|   const char* const ndir = "dir.gen";
 | |
|   const char* const ntrc = "trc.gen";
 | |
|   TFilename  s(firm2dir(codditta)); s.add(ndir);
 | |
|   bool exist = s.exist();
 | |
|   
 | |
|   if (!exist)
 | |
|   {
 | |
|     s = s.path(); s.add(ntrc);
 | |
|     exist = s.exist();
 | |
|   }
 | |
|   if (exist)
 | |
|     return message_box("Direttorio dati danneggiato, impossibile attivare la ditta %ld", codditta);
 | |
|   if (!yesno_box("Gli archivi della ditta %ld non esistono: si desidera generarli?", codditta))
 | |
|     return FALSE;         
 | |
|   
 | |
|   TLocalisamfile ditte(LF_NDITTE);
 | |
|   ditte.zero();
 | |
|   ditte.put(NDT_CODDITTA,codditta);   
 | |
|   if (ditte.read(_isequal,_testandlock) == _islocked)
 | |
|   {
 | |
|     message_box("Archivi della ditta %ld in fase di creazione da parte di un altro utente.",codditta);
 | |
|     return FALSE;
 | |
|   }
 | |
|   
 | |
|   set_autoload_new_files(yesno_box("Si desidera precaricare gli archivi standard"));
 | |
|   s = s.path(); s.rtrim(1);
 | |
|   
 | |
|   if (!s.exist() && !make_dir(s))
 | |
|     return error_box("Impossibile creare il direttorio della ditta %ld (%s)",
 | |
|                      codditta, (const char*)s);
 | |
|   
 | |
|   s.add(ndir);
 | |
|   if (!fcopy(ndir, s))
 | |
|     return error_box("Impossibile copiare il file %s della ditta %ld",
 | |
|                      ndir, codditta);
 | |
|   s = s.path(); s.add(ntrc);
 | |
|   if (!fcopy(ntrc, s))
 | |
|     return error_box("Impossibile copiare il file %s della ditta %ld",
 | |
|                      ntrc, codditta);
 | |
| 
 | |
|   TDir dir, dir1;
 | |
|   TTrec rec;
 | |
| 
 | |
|   set("");
 | |
|   dir1.get(LF_DIR, _nolock, _nordir, _sysdirop);
 | |
|   const long maxeod0 = dir1.eod();
 | |
| 
 | |
|   set_codditta(codditta);
 | |
|   dir.get(LF_DIR, _nolock, _nordir, _sysdirop);
 | |
|   if (dir.eod() == 0)
 | |
|   {
 | |
|     dir1.eod() = 1L;
 | |
|     dir1.put(LF_DIR, _nordir, _sysdirop);
 | |
|     dir.get(LF_DIR, _nolock, _nordir, _sysdirop);
 | |
|   }
 | |
|   const long    maxeod1 = dir.eod();
 | |
| 
 | |
|   if (maxeod0 > maxeod1)
 | |
|   {
 | |
|     dir.get(LF_DIR, _nolock, _nordir, _sysdirop);
 | |
|     dir.eod() = maxeod0;
 | |
|     dir.put(LF_DIR, _nordir, _sysdirop);
 | |
|     rec.zero();
 | |
|   }
 | |
|   TString mess("Generazione archivi della ditta "); mess << codditta;
 | |
|   TProgind p(maxeod0 ? maxeod0 : 1, mess, FALSE, TRUE);
 | |
| 
 | |
|   for (int i = LF_DIR + 1; i <= maxeod0; i++)
 | |
|   {
 | |
|     p.addstatus(1);
 | |
|     set("");
 | |
|     dir.get(i, _nolock, _nordir, _sysdirop);
 | |
|     rec.get(i);
 | |
|     bool create_now = dir.is_active();
 | |
|     
 | |
|     prefix().set_codditta(codditta);
 | |
|     dir.put(i, _nordir, _sysdirop);
 | |
|     rec.put(i);
 | |
|     dir.flags() = 0L;
 | |
|     create_now = create_now && (flagcom ? dir.is_com() : dir.is_firm());
 | |
|     
 | |
|     if (dir.is_valid() && create_now)
 | |
|     {
 | |
|       TSystemisamfile f(i);
 | |
|       f.build(30);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       dir.put(i, _nordir, _sysdirop);
 | |
|       rec.put(i);
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   TConfig c(CONFIG_STUDIO, "cg");
 | |
|   if (c.get_bool("StiReg"))
 | |
|   {
 | |
|     TTable reg("REG");
 | |
|     for (reg.first(_lock); reg.good(); reg.next(_lock))
 | |
|     {
 | |
|       reg.put("B9", "X");
 | |
|       reg.rewrite();
 | |
|     }
 | |
|   } 
 | |
|   ditte.reread(_unlock);
 | |
|   
 | |
|   set_codditta(codditta);
 | |
|   set_autoload_new_files(TRUE);
 | |
|   
 | |
|   return TRUE;
 | |
| }
 | |
| 
 |