1325 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1325 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <relapp.h>
 | ||
| #include <tabutil.h>
 | ||
| #include <recarray.h>
 | ||
| #include <assoc.h>
 | ||
| #include <checks.h>
 | ||
| #include <defmask.h>
 | ||
| 
 | ||
| #include "mglib01.h"
 | ||
| #include "..\cg\cglib.h"
 | ||
| 
 | ||
| // **************************************
 | ||
| // **************************************
 | ||
| // **************************************
 | ||
| // *** classi per la libreria 
 | ||
| // ***
 | ||
| //*****
 | ||
| // THead_lines_record 
 | ||
| // metodi protected
 | ||
| void THead_lines_record::renum_key(const char * kfield,const char * val)
 | ||
| {
 | ||
|   TRectype::renum_key(kfield, val);       // Aggiorna testata
 | ||
|   _rows->renum_key(kfield, val); // Aggiorna righe  
 | ||
| }
 | ||
| 
 | ||
| TRectype & THead_lines_record::row(int index) const  // riga del corpo
 | ||
| {
 | ||
|   if (index > _rows->rows() || index < 0)
 | ||
|     CHECKD(FALSE, "Riga non esistente ", index);
 | ||
|   return _rows->row(index, FALSE);
 | ||
| }
 | ||
| 
 | ||
| void THead_lines_record::put_str(const char* fieldname, const char* val)
 | ||
| {          
 | ||
|   TString v(val);
 | ||
|   // cambio 
 | ||
|   //if (strcmp(fieldname, "TIPODOC") == 0 && TRectype::get("TIPODOC") != v)
 | ||
|   //{
 | ||
|   //  TAuto_variable_rectype::put_str(fieldname, v);
 | ||
|   //  reset_fields(*this);
 | ||
|   //  set_fields(*this);
 | ||
|   //}
 | ||
|   //else          
 | ||
|   {
 | ||
|     TAuto_variable_rectype::put_str(fieldname, v);
 | ||
|     dirty_fields();                                
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| //*****
 | ||
| // metodi public
 | ||
| THead_lines_record::THead_lines_record(int hfn, int rfn,const char *numfield):
 | ||
|   TAuto_variable_rectype(hfn),
 | ||
|   _file(hfn),
 | ||
|   _rfile(rfn),
 | ||
|   _numfield(numfield)
 | ||
| {
 | ||
|   _rows= new TRecord_array(rfn,numfield); // inizializza il record array delle righe
 | ||
| }
 | ||
| 
 | ||
| THead_lines_record::THead_lines_record(const TBaseisamfile* i,int rfn,const char *numfield):
 | ||
|   TAuto_variable_rectype(i),
 | ||
|   _numfield(numfield)
 | ||
| {
 | ||
|   _rows= new TRecord_array(rfn,numfield); // inizializza il record array delle righe
 | ||
| }
 | ||
| 
 | ||
| THead_lines_record::THead_lines_record(const TRectype & r,int rfn,const char *numfield):
 | ||
|   TAuto_variable_rectype(r),
 | ||
|   _numfield(numfield)
 | ||
| {
 | ||
|   _rows= new TRecord_array(rfn,numfield); // inizializza il record array delle righe
 | ||
| }
 | ||
| 
 | ||
| // @doc INTERNAL
 | ||
| 
 | ||
| // @mfunc costruttore di copia
 | ||
| THead_lines_record::THead_lines_record(const THead_lines_record& r):
 | ||
|   TAuto_variable_rectype((TAuto_variable_rectype &)r)
 | ||
| {
 | ||
|   // copia..
 | ||
|   _rows= new TRecord_array(* r._rows); // inizializza il record array delle righe
 | ||
|   _nuovo=r._nuovo;
 | ||
|   _file=r._file;    // file principale  
 | ||
|   _rfile=r._rfile;    // file delle righe
 | ||
|   _numfield=r._numfield; 
 | ||
| }
 | ||
| 
 | ||
| THead_lines_record::~THead_lines_record() 
 | ||
| {
 | ||
|   delete _rows;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // setta a dirty i campi
 | ||
| void THead_lines_record::dirty_fields()
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| TRectype & THead_lines_record::operator =(const TRectype & r) 
 | ||
| {
 | ||
|   TRectype::operator=(r); 
 | ||
|   reset_fields(*this);
 | ||
|   set_fields(*this);
 | ||
|   return *this;
 | ||
| }
 | ||
|                                    
 | ||
| TRectype & THead_lines_record::operator =(const char * r) 
 | ||
| {
 | ||
|   TRectype::operator=(r); 
 | ||
|   reset_fields(*this);
 | ||
|   set_fields(*this);
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| void THead_lines_record::zero(const char * fieldname)
 | ||
| {
 | ||
|   // resetta il record righe solo se .....
 | ||
| //  if (strcmp(fieldname, "TIPODOC") == 0)
 | ||
|     reset_fields(*this);
 | ||
|   TAuto_variable_rectype::zero(fieldname);
 | ||
|   dirty_fields();
 | ||
| }
 | ||
| 
 | ||
| void THead_lines_record::zero(char c)
 | ||
| {
 | ||
|   reset_fields(*this);
 | ||
|   TAuto_variable_rectype::zero(c);
 | ||
| }
 | ||
|                                    
 | ||
| 
 | ||
| // settaggio campi variabili
 | ||
| void THead_lines_record::set_fields(TAuto_variable_rectype & rec)
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| int THead_lines_record::read(TBaseisamfile& f, word op, word lockop)
 | ||
| {
 | ||
|   TRectype line_key(_rfile);
 | ||
| 
 | ||
|   copy_linekey(head(),line_key);
 | ||
|   
 | ||
|   int err = TRectype::read(f,op,lockop);
 | ||
|   if (err == NOERR)
 | ||
|   {
 | ||
|     _nuovo = FALSE;
 | ||
|     _rows->read(line_key); //ok
 | ||
|   }  
 | ||
|   else
 | ||
|   {
 | ||
|     // nuovo oggetto: resetta tutto
 | ||
|     _nuovo = TRUE;
 | ||
|     destroy_rows();
 | ||
|     _rows->set_key((TRectype *)(line_key.dup()));  // ok
 | ||
|   }
 | ||
|   return err;
 | ||
| }
 | ||
| 
 | ||
| /*int THead_lines_record::read(const TRectype& rec)
 | ||
| {
 | ||
|   head() = rec;  
 | ||
|   TRectype line_key(_rows->key());
 | ||
| 
 | ||
|   copy_linekey(head(),line_key);
 | ||
|   
 | ||
|   TLocalisamfile afile(_file);        
 | ||
|   int err = TRectype::read(afile);
 | ||
|   if (err == NOERR)
 | ||
|   {
 | ||
|     _nuovo = FALSE;
 | ||
|     _rows->read(line_key); //ok
 | ||
|   }  
 | ||
|   else
 | ||
|   {
 | ||
|     // nuovo oggetto: resetta tutto
 | ||
|     _nuovo = TRUE;
 | ||
|     head() = rec;
 | ||
|     destroy_rows();
 | ||
|     _rows->set_key(&line_key);  // ok
 | ||
|   }
 | ||
|   return err;
 | ||
| } 
 | ||
| */
 | ||
| int THead_lines_record::write(TBaseisamfile& f) const 
 | ||
| {
 | ||
|   return write_rewrite(f,FALSE);
 | ||
| }
 | ||
| int THead_lines_record::rewrite(TBaseisamfile& f) const 
 | ||
| {
 | ||
|   return write_rewrite(f,TRUE);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| int THead_lines_record::write_rewrite(TBaseisamfile& f,bool re ) const 
 | ||
| {              
 | ||
|   const bool nuovo = _nuovo;  // E' nuovo di zecca!
 | ||
|   if (nuovo && re)                             // quindi ...
 | ||
|     re = FALSE;                                // ... non fare la rewrite
 | ||
| 
 | ||
|   int err = NOERR;
 | ||
|   if (re)
 | ||
|   {
 | ||
|     // rewrite:
 | ||
|     err = _rows->write(re); 
 | ||
|     if (err == NOERR)
 | ||
|     {
 | ||
|       err = TRectype::rewrite(f);
 | ||
|       if (err != NOERR)
 | ||
|         err = TRectype::write(f);
 | ||
|     }    
 | ||
|   }
 | ||
|   else
 | ||
|   {             
 | ||
|     // write:
 | ||
|     if (nuovo)
 | ||
|     {         
 | ||
|       //THead_lines_record &myself=*this;
 | ||
|       //if (numero() <= 0)
 | ||
|       //  myself.renum();
 | ||
|       do
 | ||
|       {
 | ||
|         err = TRectype::write(f);
 | ||
|         if (err == _isreinsert) // usa il flag _nuovo per decidere se 
 | ||
|           ((THead_lines_record *)this)->renum();
 | ||
|       } while (err == _isreinsert);
 | ||
|       ((THead_lines_record *)this)->_nuovo = FALSE;
 | ||
|     }
 | ||
|     else 
 | ||
|     {
 | ||
|       err = TRectype::write(f);
 | ||
|       if (err != NOERR)
 | ||
|         err = TRectype::rewrite(f);
 | ||
|     }    
 | ||
|     if (err == NOERR)
 | ||
|       err = _rows->write(re);
 | ||
|   }
 | ||
|   return err;  
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| int THead_lines_record::remove(TBaseisamfile& f) const 
 | ||
| {
 | ||
|   int err = _rows->remove();
 | ||
|   if (err == NOERR)
 | ||
|     err = TRectype::remove(f);
 | ||
|   return err;  
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // @doc INTERNAL
 | ||
| 
 | ||
| // @mfunc costruttore di copia
 | ||
| TTimed_box::TTimed_box(const char * header,const char * message,int seconds,short button_id,int x,int y)
 | ||
|   : TMask(header,1,x,y)
 | ||
| {
 | ||
|   // costruisce una maschera run time
 | ||
|   add_memo(FIRST_FIELD, 0, "", 1, 0,-1,-3);
 | ||
|   set(FIRST_FIELD, message);
 | ||
| 
 | ||
|   // setta il timer per l'evento
 | ||
|   _timer_delay=seconds  *1000+1;
 | ||
|   _timer_id=XVT_TIMER_ERROR;
 | ||
|   _button_id=button_id;
 | ||
| }
 | ||
| 
 | ||
| void TTimed_box::start_run()
 | ||
| {
 | ||
|   if (_timer_id!=XVT_TIMER_ERROR)
 | ||
|     xvt_timer_destroy(_timer_id);
 | ||
|   _timer_id=xvt_timer_create(win(),_timer_delay);
 | ||
|   TMask::start_run();
 | ||
| }
 | ||
| 
 | ||
| void TTimed_box::handler(WINDOW win, EVENT* ep)
 | ||
| {   
 | ||
|   if (ep->type == E_TIMER && ep->v.timer.id==_timer_id)
 | ||
|   {
 | ||
|     send_key(K_SPACE,DLG_OK);
 | ||
|   }
 | ||
|   TMask::handler(win, ep);
 | ||
| }
 | ||
| 
 | ||
| class TTimed_breakbox: public TTimed_box
 | ||
| {
 | ||
| public:
 | ||
|   TTimed_breakbox(const char * message,int seconds,int x=40,int y=10);
 | ||
| };
 | ||
| 
 | ||
| TTimed_breakbox::TTimed_breakbox(const char * message,int seconds,int x,int y)
 | ||
|   : TTimed_box("Richiesta di interruzione",message,seconds,DLG_OK,x,y)
 | ||
| {
 | ||
|   add_button(DLG_CANCEL, 0, "Interrompi", -22, -1, 12, 2,"",0);
 | ||
|   add_button(DLG_OK,     0, "Riprova", -12, -1, 12, 2,"",0);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| //    **********************************
 | ||
| //   **********************************
 | ||
| //  **********************************
 | ||
| // **********************************
 | ||
| // fine classi per la libreria
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| // **************************
 | ||
| // classe livelli giacenze
 | ||
| TMag_livelli:: TMag_livelli(const char *tabname)
 | ||
| { 
 | ||
|   TTable _tabformato(tabname);  
 | ||
|   int e;
 | ||
|   
 | ||
|   _last_level=0;
 | ||
|   e=_tabformato.first();
 | ||
|   for (int i=0; i<  MANY_MAG_LEV; i++) {
 | ||
|     _enabled[i]=(e==NOERR);
 | ||
|     if (_enabled[i]) {
 | ||
|       _name[i]=_tabformato.get("S0");
 | ||
|       _code_lenght[i]=atoi(_tabformato.get("I0"));
 | ||
|       _picture[i]=_tabformato.get("S1");
 | ||
|       _last_level=i+1;
 | ||
|     } else {
 | ||
|       _name[i]="";
 | ||
|       _code_lenght[i]=0;
 | ||
|       _picture[i]="";
 | ||
|     }
 | ||
|     e=_tabformato.next();
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| const bool TMag_livelli::enabled(int levnum)
 | ||
| {
 | ||
|   if (levnum<=MANY_MAG_LEV &&  levnum>0)
 | ||
|     return(_enabled[levnum-1]);
 | ||
|   else
 | ||
|     return(FALSE) ;
 | ||
| }
 | ||
| 
 | ||
| const int TMag_livelli::code_lenght(int levnum)
 | ||
| {
 | ||
|   if (levnum<=MANY_MAG_LEV &&  levnum>0)
 | ||
|     return(_code_lenght[levnum-1]);
 | ||
|   else
 | ||
|     return(0) ;
 | ||
| }
 | ||
| 
 | ||
| const TString & TMag_livelli::name(int levnum)
 | ||
| {
 | ||
|   if (levnum<=MANY_MAG_LEV &&  levnum>0)
 | ||
|     return(_name[levnum-1]);
 | ||
|   else
 | ||
|     return(""); 
 | ||
| }
 | ||
| 
 | ||
| const TString & TMag_livelli::picture(int levnum)
 | ||
| {
 | ||
|   if (levnum<=MANY_MAG_LEV &&  levnum>0)
 | ||
|     return(_picture[levnum-1]);
 | ||
|   else
 | ||
|     return(""); 
 | ||
| }
 | ||
| 
 | ||
| void TMag_livelli::pack_grpcode(TString & pc, const TString &codlev, const int levnum)
 | ||
| {
 | ||
|       
 | ||
|   int start=0;
 | ||
|   for (int i=1; i<levnum; i++) 
 | ||
|     start+= _code_lenght[i-1];
 | ||
|   pc.overwrite(codlev.left(_code_lenght[levnum-1]),start);        
 | ||
| }
 | ||
| 
 | ||
| TString TMag_livelli::unpack_grpcode(const TString & pc, const int levnum)
 | ||
| {
 | ||
|   int start=0;
 | ||
|   for (int i=1; i<levnum; i++) 
 | ||
|     start+= _code_lenght[i-1];
 | ||
|   if (start>=pc.len())
 | ||
|     return("");
 | ||
|   else   {
 | ||
|     if (levnum != _last_level && !_enabled[levnum-1])
 | ||
|       return("");
 | ||
|     return(pc.mid(start,levnum == _last_level ? -1 : _code_lenght[levnum-1]));
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // *******************************
 | ||
| // *******************************
 | ||
| 
 | ||
| // *******************************
 | ||
| TStateset::TStateset()
 | ||
| { 
 | ||
|   empty();
 | ||
| }
 | ||
| 
 | ||
| TStateset & TStateset::empty()
 | ||
| { _current=0;
 | ||
|   for (int i= 0; i< MAXSTATES; _container[i++]=0);
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| TStateset & TStateset::enclose(int el)
 | ||
| { if (el< MAXSTATES && el>=0)
 | ||
|     _container[el]=1;
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| TStateset & TStateset::singleton(int el)
 | ||
| { empty();
 | ||
|   _container[el]=1;
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| TStateset & TStateset::cap(TStateset & s)
 | ||
| {
 | ||
|   for (int i= 0; i< MAXSTATES; i++)
 | ||
|     _container[i]|=s._container[i];
 | ||
|   return *this;
 | ||
| }
 | ||
|   
 | ||
| bool TStateset::is_empty() const
 | ||
| { 
 | ||
|   for (int i= 0; i< MAXSTATES; i++) {
 | ||
|     if (_container[i]) return FALSE;
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TStateset::is_member(int e)    const
 | ||
| { 
 | ||
|   return ((e< MAXSTATES && e>=0)?  _container[e] : FALSE );
 | ||
| }
 | ||
| 
 | ||
| int TStateset::get_first()
 | ||
| {
 | ||
|   _current=-1;
 | ||
|   return(get_next());
 | ||
| }
 | ||
| 
 | ||
| int TStateset::get_next()
 | ||
| {
 | ||
|   while (_current+1 < MAXSTATES)  {
 | ||
|     if (_container[++_current])
 | ||
|       return _current;
 | ||
|   } 
 | ||
|   return (-1);  
 | ||
| }
 | ||
| 
 | ||
| // *******************************
 | ||
| // *******************************
 | ||
| // automa per il riconoscimento di metacaratteri
 | ||
| #define EPSILON 0
 | ||
| #define FIRST_STATE 1
 | ||
| #define FIRST_NEMPTY_SYMBOL 1
 | ||
| 
 | ||
| // labels and states
 | ||
| bool TR_automa::is_state(int statenum)
 | ||
| {
 | ||
|   return(statenum<=_maxstate && statenum>0);
 | ||
| }
 | ||
| 
 | ||
| // restituisce il numero dello stato con quella etichetta
 | ||
| int TR_automa::label2state(const char *label)
 | ||
| {
 | ||
|   for (int s=0; s<_maxstate;s++) {
 | ||
|     if (*(st[s]._label)==label)
 | ||
|       return(s+1);
 | ||
|   }
 | ||
|   return(0);  
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // resetta uno stato dell'automa (senza eliminarlo)
 | ||
| TR_automa & TR_automa::reset_state(int statenum)
 | ||
| {
 | ||
|   int _from,_to;
 | ||
|   if (statenum>0 && statenum<=_maxstate) {
 | ||
|     _from=statenum;
 | ||
|     _to=statenum;
 | ||
|   } else {
 | ||
|     _maxstate=0;
 | ||
|     _isdeterministic=TRUE;
 | ||
|     _from=1;
 | ||
|     _to=MAXSTATES;
 | ||
|   } 
 | ||
|   {
 | ||
|     for (int i=_from; i<=_to;i++) {
 | ||
|       set_label(i,"");
 | ||
|       set_final(i,FALSE);
 | ||
|       for (int j=0; j<MAXSIMBOLS;j++) {
 | ||
|         del_trans(i,j); 
 | ||
|       }
 | ||
|     }     
 | ||
|   }
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| // aggiunge una label
 | ||
| int TR_automa::add_state(const char * label)
 | ||
| {
 | ||
|   _maxstate++;
 | ||
|   reset_state(_maxstate);
 | ||
|   set_label(_maxstate,label);
 | ||
|   return _maxstate;
 | ||
| }
 | ||
| 
 | ||
| TR_automa & TR_automa::set_label(int statenum, const char * name)
 | ||
| {
 | ||
|   (*(st[statenum-1]._label))=name;
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| const char * TR_automa::label(int statenum)
 | ||
| {
 | ||
|   return (*(st[statenum-1]._label));
 | ||
| }
 | ||
| 
 | ||
| bool TR_automa::is_final(int statenum) const
 | ||
| { 
 | ||
|   return (st[statenum-1]._final);
 | ||
| }
 | ||
| 
 | ||
| bool TR_automa::is_final(TStateset ss ) const
 | ||
| { 
 | ||
|   bool retv=FALSE;
 | ||
|   int statenum=ss.get_first();
 | ||
|   do {
 | ||
|     retv=retv || is_final(statenum);
 | ||
|   } while ((statenum=ss.get_next())>0);
 | ||
|     
 | ||
|   return retv;
 | ||
| }
 | ||
| 
 | ||
| TR_automa & TR_automa::set_final(int statenum,bool v)
 | ||
| {
 | ||
|   st[statenum-1]._final=v;
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| //*******************
 | ||
| // bows
 | ||
| void TR_automa::add_tran(int statenum, unsigned char symbol,int next)
 | ||
| {
 | ||
|   st[statenum-1]._transaction[symbol]=next;   
 | ||
|   if (symbol==EPSILON)
 | ||
|     _isdeterministic=FALSE;
 | ||
| }
 | ||
| 
 | ||
| void TR_automa::del_trans(int statenum, unsigned char symbol)
 | ||
| {
 | ||
|   st[statenum-1]._transaction[symbol]=0;
 | ||
| }
 | ||
| 
 | ||
| int TR_automa::trans_to(int statenum, unsigned char symbol)
 | ||
| {
 | ||
|   return (st[statenum-1]._transaction[symbol]);   
 | ||
| }
 | ||
| 
 | ||
| // costruttore che crea un automa non deterministico 
 | ||
| // (transazioni Epsilon ma nessuna transazione multipla)
 | ||
| // eventualmente duplica un automa (e lo rende deterministico)
 | ||
| TR_automa::TR_automa(TR_automa * aa,bool makedet) 
 | ||
| {
 | ||
|   TStateset arrival;
 | ||
|   TStateset newstateset;
 | ||
|   TString16  tmplabel;
 | ||
|   int curr_new_state;
 | ||
| 
 | ||
|   for (int i=0; i<MAXSTATES;i++) {
 | ||
|     st[i]._label = new TString16;
 | ||
|   }     
 | ||
|   if (aa==NULL) {
 | ||
|     reset_state();
 | ||
|     return;
 | ||
|   }
 | ||
|   if (makedet) {
 | ||
|     reset_state();
 | ||
|     // crea il primo stato nell'automa deterministico
 | ||
|     set2label(aa->union_of_closures(newstateset.singleton(FIRST_STATE)),tmplabel);
 | ||
|     add_state(tmplabel);
 | ||
|     curr_new_state=FIRST_STATE;
 | ||
|     while (is_state(curr_new_state)) {
 | ||
|       // determina l'insieme degli stati dell'automa non deterministico
 | ||
|       // che corrispondono a questo stato dell'automa deterministico
 | ||
|       label2set(label(curr_new_state),newstateset);
 | ||
|       // lo stato <20> finale se include stati finali dell'automa non det.
 | ||
|       set_final(curr_new_state,aa->is_final(newstateset));
 | ||
|       // determina tutte le transazioni 
 | ||
|       for (short symbol=FIRST_NEMPTY_SYMBOL; symbol<MAXSIMBOLS; symbol++) {
 | ||
|         // determina lo stato di arrivo nell'automa det.:
 | ||
|         // esso <20> pari all'insieme degli stati raggiunti col questo simbolo 
 | ||
|         // dal sottoinsieme degli stati dell'automa non det. che etichetta il nuovo stato nell'automa det.
 | ||
|         arrival.empty();
 | ||
|         int new_next,old_next;
 | ||
|         int old_state=newstateset.get_first() ;
 | ||
|         do {
 | ||
|           if (old_next=aa->trans_to(old_state,symbol))
 | ||
|             arrival.enclose(old_next);
 | ||
|         } while ((old_state=newstateset.get_next())>0);
 | ||
|         if (!arrival.is_empty()) {
 | ||
|             // crea il nuovo arco nell'automa deterministico
 | ||
|           set2label(aa->union_of_closures(arrival),tmplabel);
 | ||
|           if (!(new_next=label2state(tmplabel))) {
 | ||
|           new_next=add_state(tmplabel);
 | ||
|           } 
 | ||
|           add_tran(curr_new_state,symbol,new_next);
 | ||
|         }
 | ||
|       }
 | ||
|       curr_new_state++;
 | ||
|     }
 | ||
|     _isdeterministic=TRUE;
 | ||
|   } // fine  conversione
 | ||
|   else 
 | ||
|   {
 | ||
|     *this=*aa;
 | ||
|     for (int i=0; i<MAXSTATES;i++) {
 | ||
|       st[i]._label= aa->st[i]._label;
 | ||
|     }     
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| TR_automa::~TR_automa()
 | ||
| { 
 | ||
|   for (int i=0; i<MAXSTATES;i++) {
 | ||
|     delete (st[i]._label);
 | ||
|   }     
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| void TR_automa::set2label(const TStateset ss,TString16 & label)
 | ||
| {
 | ||
|   char coded[MAXSTATES];
 | ||
|   char c=0;
 | ||
|   for (int i= 0; i< MAXSTATES; i++) {
 | ||
|     if (ss.is_member(i)) 
 | ||
|       coded[c++]=(char)(i+'0');
 | ||
|   }
 | ||
|   coded[c]='\0';
 | ||
|   label=coded;    
 | ||
| }
 | ||
| 
 | ||
| void TR_automa::label2set(const TString16 & label,TStateset & ss)
 | ||
| {
 | ||
|   ss.empty();
 | ||
|   for (int i= 0; i<= label.len();i++)
 | ||
|     ss.enclose(int(label[i]-'0'));
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // costruisce l'unione delle epslilon closures
 | ||
| TStateset TR_automa::union_of_closures(TStateset &start_set)
 | ||
| {
 | ||
|   TStateset u_of_clo,clo;
 | ||
|   int _state,_next;
 | ||
|   bool toadd;
 | ||
|   
 | ||
|   
 | ||
|   u_of_clo.empty();
 | ||
|   _state=start_set.get_first() ;
 | ||
|   do {
 | ||
|     // la chiusura <20> composta dallo stato e tutte le sue transazioni epsilon
 | ||
|     clo.singleton(_state);
 | ||
|     do {
 | ||
|       int _state2=clo.get_first();
 | ||
|       do {
 | ||
|         toadd=((_next=trans_to(_state2,EPSILON)) && (!clo.is_member(_next)));
 | ||
|         if (toadd)
 | ||
|           clo.enclose(_next);
 | ||
|       } while ((_state2=clo.get_next())>0);
 | ||
|     } while (toadd) ;
 | ||
|     u_of_clo.cap(clo);
 | ||
|   } while ((_state=start_set.get_next())>0);
 | ||
|   return u_of_clo;
 | ||
| }
 | ||
| 
 | ||
| // tenta di riconoscere la stringa passata
 | ||
| bool TR_automa::recognized(const char * t_str) 
 | ||
| {
 | ||
|   if (_isdeterministic) {
 | ||
|     // ricoNosce la stringa di token
 | ||
|     int curr_state=FIRST_STATE;
 | ||
|     for (int i=0; t_str[i]; i++) {
 | ||
|       if (!(curr_state=trans_to(curr_state,t_str[i])))
 | ||
|         // fine per mancanza di trasizioni
 | ||
|         return FALSE; 
 | ||
|     }
 | ||
|     // fine per mancanza di caratteri di input della stringa
 | ||
|     return (is_final(curr_state));
 | ||
|   } else {
 | ||
|     //    
 | ||
|     return FALSE;
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // *******************************
 | ||
| // gestione di stringhe di metacaratteri
 | ||
| // *******************************
 | ||
| #define C_ESCAPEMETA '\\'
 | ||
| #define S_BLANK 1
 | ||
| #define S_DIGIT 2
 | ||
| #define S_LETTER 3
 | ||
| #define S_ANY 4
 | ||
| 
 | ||
| bool TMetachar::recognized(const char * s)
 | ||
| {
 | ||
|   return(_au->recognized(s));
 | ||
| }
 | ||
|         
 | ||
| void TMetachar::add_tran(int s,unsigned char metasymbol, int nextstate)
 | ||
| {
 | ||
|     unsigned char c;
 | ||
|     switch (metasymbol) {
 | ||
|       case EPSILON:// blank
 | ||
|         _au->add_tran(s,EPSILON,nextstate);
 | ||
|       break;
 | ||
|       case S_BLANK:// blank
 | ||
|         _au->add_tran(s,' ',nextstate);
 | ||
|       break;
 | ||
|       case S_DIGIT:// cifra 
 | ||
|         for (c='0';c<='9';c++)
 | ||
|           _au->add_tran(s,c,nextstate);
 | ||
|       break;
 | ||
|       case S_LETTER: // lettera 
 | ||
|         for (c='a';c<='z';c++)
 | ||
|           _au->add_tran(s,c,nextstate);
 | ||
|         for (c='A';c<='Z';c++)
 | ||
|           _au->add_tran(s,c,nextstate);
 | ||
|       break;
 | ||
|       case S_ANY: // qualsiasi carattere 
 | ||
|         for (c=MAXSIMBOLS-1;c>=FIRST_NEMPTY_SYMBOL;c--)
 | ||
|           _au->add_tran(s,c,nextstate);
 | ||
|       break;
 | ||
|       default:
 | ||
|           _au->add_tran(s,metasymbol,nextstate);
 | ||
|       break;
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| // restituisce la stringa di metacaratteri del linguaggio riconosciuto
 | ||
| const char * TMetachar::language() const
 | ||
| {
 | ||
|   return(_language);
 | ||
| }
 | ||
| 
 | ||
| void TMetachar::set_language(const char * language)
 | ||
| {
 | ||
|   int s;
 | ||
|   bool escaped_char=FALSE;
 | ||
|   TString16 label("-"),nextlabel("-");
 | ||
|   
 | ||
|   // crea gli insiemi di metacaratteri standard
 | ||
|   strcpy(_metach_mand,"0LA&");
 | ||
|   strcpy(_metach_opz,"#9?ac");
 | ||
| 
 | ||
|   
 | ||
|   _language=language;
 | ||
|   // crea l'automa 
 | ||
|   _au->reset_state();
 | ||
|   for (int i=0; language[i]; i++) {
 | ||
|     label[0]='a'+i;
 | ||
|     nextlabel[0]='a'+i+1;
 | ||
|     if (language[i]!=C_ESCAPEMETA) {
 | ||
|       if (!escaped_char)
 | ||
|       {
 | ||
|       // meta-caratteri e literal fuori set
 | ||
|         s=_au->add_state(label);
 | ||
|         switch (language[i]) {
 | ||
|           case '#':// cifra o blank opzionale
 | ||
|             add_tran(s,S_BLANK,s+1);
 | ||
|             add_tran(s,'-',s+1);
 | ||
|             add_tran(s,'+',s+1);
 | ||
|           case '9':// cifra opzionale
 | ||
|             add_tran(s,EPSILON,s+1);
 | ||
|           case '0':// cifra obbligatoria
 | ||
|             add_tran(s,S_DIGIT,s+1);
 | ||
|           break;
 | ||
|           case '?': // lettera opzionale
 | ||
|             add_tran(s,EPSILON,s+1);
 | ||
|           case 'L': // lettera obbligatoria
 | ||
|             add_tran(s,S_LETTER,s+1);
 | ||
|           break;
 | ||
|           case 'a': // lettera o numero opzionale
 | ||
|             add_tran(s,EPSILON,s+1);
 | ||
|           case 'A': // lettera o numero obbligatorio
 | ||
|             add_tran(s,S_LETTER,s+1);
 | ||
|             add_tran(s,S_DIGIT,s+1);
 | ||
|           break;
 | ||
|           case 'c': // qualsiasi carattere opzionale
 | ||
|             add_tran(s,EPSILON,s+1);
 | ||
|           case '&': // qualsiasi carattere obbligatorio
 | ||
|             add_tran(s,S_ANY,s+1);
 | ||
|           break;
 | ||
|           default:
 | ||
|             _au->add_tran(s,language[i],s+1);
 | ||
|           break;
 | ||
|         }
 | ||
|       } else {
 | ||
|       // escaped char
 | ||
|           s=_au->add_state(label);
 | ||
|         _au->add_tran(s,language[i],s+1);
 | ||
|       }
 | ||
|     }
 | ||
|     escaped_char=(language[i]==C_ESCAPEMETA);
 | ||
|   } // end of loop
 | ||
|   // aggiunge lo stato finale
 | ||
|   s=_au->add_state(nextlabel);
 | ||
|   _au->set_final(s);
 | ||
| 
 | ||
| }
 | ||
| 
 | ||
| // ricerca caratteri del set opzionale
 | ||
| bool TMetachar::has_opzchars(const char * pattern)
 | ||
| {
 | ||
|   int i=0; 
 | ||
|   bool next_literal=FALSE;
 | ||
|   
 | ||
|   while (pattern[i]) {           
 | ||
|     if (!next_literal && strchr(_metach_opz,pattern[i]))
 | ||
|       return(TRUE);
 | ||
|     next_literal=(!next_literal && pattern[i]==C_ESCAPEMETA);
 | ||
|     i++;
 | ||
|   }
 | ||
|   return(FALSE);
 | ||
| }
 | ||
| 
 | ||
| // ricerca caratteri del set opzionale
 | ||
| bool TMetachar::has_mandchars(const char * pattern)
 | ||
| {
 | ||
|   int i=0; 
 | ||
|   bool next_literal=FALSE;
 | ||
|   
 | ||
|   while (pattern[i]) {
 | ||
|     if (next_literal || strchr(_metach_mand,pattern[i]))
 | ||
|       return(TRUE);
 | ||
|     next_literal=(!next_literal && pattern[i]==C_ESCAPEMETA);
 | ||
|     i++;
 | ||
|   }
 | ||
|   return(FALSE);
 | ||
| }
 | ||
| 
 | ||
| // stabilisce la lunghezza della stringa di metacaratteri
 | ||
| int TMetachar::maxstrlen(const char * pattern) const
 | ||
| {
 | ||
|   int i=0,l=0; 
 | ||
|   bool next_literal=FALSE;
 | ||
|   
 | ||
|   while (pattern[i]) {
 | ||
|     if (!next_literal)
 | ||
|       l++;
 | ||
|     next_literal=(!next_literal && pattern[i]==C_ESCAPEMETA);
 | ||
|     i++;
 | ||
|   }
 | ||
|   return(l);
 | ||
| }
 | ||
| 
 | ||
| // costruttore e distruttore
 | ||
| TMetachar::TMetachar ()
 | ||
| {
 | ||
|   _au = new TR_automa;       
 | ||
|   set_language("");
 | ||
| }
 | ||
| 
 | ||
| TMetachar::TMetachar (const char * metastr)
 | ||
| {
 | ||
|   // crea l'automa e lo trasforma in deterministico
 | ||
| //  TR_automa auxau;
 | ||
| //  set_language(&auxau,metastr);
 | ||
|   _au=new TR_automa;
 | ||
|   set_language(metastr);
 | ||
|   if (!_au->is_deterministic()) {
 | ||
|     TR_automa * auxau = new TR_automa(_au,TRUE);       
 | ||
|     delete _au;
 | ||
|     _au=auxau;
 | ||
|   } 
 | ||
| }
 | ||
| 
 | ||
| TMetachar::~TMetachar ()
 | ||
| {
 | ||
|   delete _au;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // **************************************
 | ||
| // **************************************
 | ||
| // **************************************
 | ||
| // *** classi per il magazzino
 | ||
| // ***
 | ||
| long giac_last_item(const char * annoes, const char *codart) 
 | ||
| {
 | ||
|   long r=0;
 | ||
|   TLocalisamfile mag(LF_MAG);
 | ||
|   mag.put("ANNOES",annoes);
 | ||
|   mag.put("CODART",codart);
 | ||
|   mag.put("NRIGA",1);
 | ||
|   if (mag.read()==NOERR) 
 | ||
|   {
 | ||
|     do  {
 | ||
|       r=mag.get_long("NRIGA");
 | ||
|     } while (mag.next()==NOERR && mag.get("CODART")==codart);
 | ||
|   }
 | ||
|   return r;
 | ||
| }
 | ||
| 
 | ||
| // *********************
 | ||
| // movimenti di magazzino
 | ||
| 
 | ||
| // causali 
 | ||
| 
 | ||
| int TCausale_magazzino::sgn(TTipo_saldomag tiposaldo) 
 | ||
| {
 | ||
|   switch (tiposaldo) {
 | ||
|   case s_giac:
 | ||
|     return get_int("I0");
 | ||
|   case s_acq:
 | ||
|     return get_int("I1");
 | ||
|   case s_ent:
 | ||
|     return get_int("I2");
 | ||
|   case s_ven:
 | ||
|     return get_int("I3");
 | ||
|   case s_usc:
 | ||
|     return get_int("I4");
 | ||
|   case s_ordc:
 | ||
|     return get_int("I5");
 | ||
|   case s_ordf:
 | ||
|     return get_int("I6");
 | ||
|   case s_incl:
 | ||
|     return get_int("I7");
 | ||
|   case s_acl:
 | ||
|     return get_int("I8");
 | ||
|   case s_prodc:
 | ||
|     return get_int("I9");
 | ||
|   case s_prodf:
 | ||
|     return get_int("I10");
 | ||
|   case s_rim:
 | ||
|     return get_int("I11");
 | ||
|   case s_scart:
 | ||
|     return get_int("I12");
 | ||
|   case s_label:
 | ||
|     return get_int("I13");
 | ||
|   default:
 | ||
|   return 0;
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| TCausale_magazzino::TCausale_magazzino(const char * codice):
 | ||
|   TRectype(LF_TAB)
 | ||
| {
 | ||
|   TTable f("CAU");
 | ||
|   f.put("CODTAB",codice);
 | ||
|   if (f.read() != NOERR)
 | ||
|     zero();   
 | ||
|   else
 | ||
|     *this=(TCausale_magazzino &)f.curr();
 | ||
| }
 | ||
| 
 | ||
| // movimenti
 | ||
| TLine_movmag ::TLine_movmag(const TLine_movmag &l)
 | ||
| {
 | ||
|   um=l.um;
 | ||
|   quant=l.quant;
 | ||
|   prezzo=l.prezzo;
 | ||
| }
 | ||
| 
 | ||
| int TLine_movmag::operator==(TLine_movmag &l)
 | ||
| {
 | ||
|   return (um==l.um)&&(quant==l.quant)&&(prezzo==l.prezzo);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| TMov_mag::TMov_mag() : 
 | ||
|   THead_lines_record(LF_MOVMAG,LF_RMOVMAG,"NRIG"),
 | ||
|   lines_to_add(), lines_to_subtract()
 | ||
| {   
 | ||
| }
 | ||
| 
 | ||
| TMov_mag::~TMov_mag() 
 | ||
| {   
 | ||
| }
 | ||
| //void TMov_mag::dirty_fields()
 | ||
| //{
 | ||
| //}
 | ||
| 
 | ||
| // rinumerazione automatica: numdoc>=0
 | ||
| // (con creazione nuova chiave)
 | ||
| long TMov_mag::renum(long numdoc)
 | ||
| {
 | ||
|   if (numdoc <= 0)
 | ||
|     numdoc  = atoi(get_next_key());
 | ||
|   char num[16]; sprintf(num, "%ld", numdoc);
 | ||
|   renum_key("NUMREG", num);       // Aggiorna testata
 | ||
|   return numdoc;
 | ||
| }
 | ||
| 
 | ||
| // copia la chiave dal file principale a quello delle righe
 | ||
| void TMov_mag::copy_linekey(const TRectype & headrec, TRectype  & linesrec)
 | ||
| {
 | ||
|   // ...qui basta una put tra Rectype....
 | ||
|   linesrec.put("NUMREG",headrec.get("NUMREG"))  ;
 | ||
| } 
 | ||
| 
 | ||
| int TMov_mag::read(TBaseisamfile& f, word op , word lockop)
 | ||
| {
 | ||
|   TToken_string l_key;
 | ||
|   TLine_movmag l_data;
 | ||
|   
 | ||
|   int res=THead_lines_record::read(f,op,lockop);
 | ||
|   // reset delle strutture per il controlli delle variazioni dei saldi
 | ||
|   _codcaus=get("CODCAUS");
 | ||
|   _annoes=get("ANNOES");
 | ||
|   lines_to_add.destroy();   
 | ||
|   lines_to_subtract.destroy();
 | ||
|   for (int i=0; i<rows(); i++) {
 | ||
|     l_key=line2key(i+1);
 | ||
|     l_data=line2data(i+1);
 | ||
|     delete_line(l_key,l_data);    
 | ||
|   }
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| int TMov_mag::remove(TBaseisamfile& f) const 
 | ||
| {
 | ||
|   int res;
 | ||
|   if ((res=THead_lines_record::remove(f))==NOERR ) 
 | ||
|     // effettua la variazione dei saldi
 | ||
|     res=update_balances();  
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| int TMov_mag::write(TBaseisamfile& f) const 
 | ||
| {
 | ||
|   int res;
 | ||
|   TToken_string l_key;
 | ||
|   TLine_movmag l_data;
 | ||
|   // memorizza le variazioni
 | ||
|   for (int i=0; i<rows(); i++) {
 | ||
|     l_key=line2key(i+1);
 | ||
|     l_data=line2data(i+1);
 | ||
|     ((TMov_mag *)this)->insert_line(l_key,l_data);    
 | ||
|   }
 | ||
|   if ((res=THead_lines_record::write(f))==NOERR ) 
 | ||
|     // effettua la variazione dei saldi
 | ||
|     res=update_balances();  
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| int TMov_mag::rewrite(TBaseisamfile& f) const 
 | ||
| {
 | ||
|   int res;
 | ||
|   TToken_string l_key;
 | ||
|   TLine_movmag l_data;
 | ||
|   // memorizza le variazioni
 | ||
|   for (int i=0; i<rows(); i++) {
 | ||
|     l_key=line2key(i+1);
 | ||
|     l_data=line2data(i+1);
 | ||
|     ((TMov_mag *)this)->insert_line(l_key,l_data);    
 | ||
|   }
 | ||
|   if ((res=THead_lines_record::rewrite(f))==NOERR ) 
 | ||
|     // effettua la variazione dei saldi
 | ||
|     res=update_balances();  
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| const char *TMov_mag::get_next_key()  
 | ||
| {
 | ||
|   TLocalisamfile f(LF_MOVMAG);
 | ||
|   f.last();
 | ||
|   int a=atoi(f.get("NUMREG"))+1;
 | ||
|   return _nextcod.format("%d",a);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // settaggio campi variabili
 | ||
| //void TMov_mag::set_fields(TAuto_variable_rectype & rec)
 | ||
| //{
 | ||
| //}
 | ||
| 
 | ||
| 
 | ||
| //*******
 | ||
| // gestione delle variazione dei saldi
 | ||
| //
 | ||
| //
 | ||
| TLine_movmag TMov_mag::line2data(int numriga) const
 | ||
| {
 | ||
|     TLine_movmag    rest;
 | ||
|     rest.um=row(numriga).get("UM");
 | ||
|     rest.quant=(const char *)row(numriga).get("QUANT");
 | ||
|     rest.prezzo=(const char *)row(numriga).get("PREZZO");
 | ||
|     return rest;
 | ||
| }
 | ||
| 
 | ||
| TToken_string TMov_mag::line2key(int numriga) const
 | ||
| {
 | ||
|     TToken_string key;
 | ||
|     key.add(row(numriga).get("CODART"));
 | ||
|     key.add(row(numriga).get("CODMAG"));
 | ||
|     key.add(row(numriga).get("LIVGIAC"));
 | ||
|     return key;
 | ||
| }
 | ||
| 
 | ||
| TString TMov_mag::key2field(TToken_string &key,const char *fieldname) 
 | ||
| {
 | ||
|     if (strcmp(fieldname,"CODART")==0)
 | ||
|       return key.get(0);
 | ||
|     if (strcmp(fieldname,"CODMAG")==0)
 | ||
|       return key.get(1);
 | ||
|     if (strcmp(fieldname,"LIVGIAC")==0)
 | ||
|       return key.get(2);
 | ||
|     CHECKS(FALSE, "Nome di campo non appartenente al file righe mov ", fieldname);
 | ||
|   return "";
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| int TMov_mag::insert_line(TToken_string &k,TLine_movmag &r)
 | ||
| {
 | ||
|   if (_codcaus != get("CODCAUS") || _annoes != get("ANNOES")) {
 | ||
|     lines_to_add.add(k,r);
 | ||
|   } else {
 | ||
|     if (lines_to_subtract.is_key(k)&& (TLine_movmag &)lines_to_subtract[k]==r)
 | ||
|       // modifica annullata
 | ||
|       lines_to_subtract.remove(k);
 | ||
|     else      
 | ||
|       // linea modificata
 | ||
|       lines_to_add.add(k,r);
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| int TMov_mag::delete_line(TToken_string &k,TLine_movmag &r)
 | ||
| {
 | ||
|   if (_codcaus != get("CODCAUS") || _annoes != get("ANNOES")) {
 | ||
|     lines_to_subtract.add(k,r);
 | ||
|   } else {
 | ||
|     if (lines_to_add.is_key(k)&& r==(TLine_movmag &)lines_to_add[k] )
 | ||
|       // modifica annullata
 | ||
|       lines_to_add.remove(k); 
 | ||
|     else
 | ||
|       // linea modificata
 | ||
|       lines_to_subtract.add(k,r);
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| bool TMov_mag::unlock_anamag(const char *codart) 
 | ||
| {
 | ||
|   TLocalisamfile anamag(LF_ANAMAG);
 | ||
|   anamag.put("CODART",codart);
 | ||
|   return (anamag.read(_isequal,_unlock)==NOERR);
 | ||
| }
 | ||
| 
 | ||
| bool TMov_mag::lock_anamag(const char *codart) 
 | ||
| {
 | ||
|   TLocalisamfile anamag(LF_ANAMAG);
 | ||
|   anamag.put("CODART",codart);
 | ||
|   bool insert_new=TRUE;
 | ||
|   TString mess;
 | ||
|   mess << "Il record di anagrafica dell'articolo ''"<< codart << "'' risulta essere gi<67> in uso.\n Interrompo ?";
 | ||
|   TTimed_breakbox bbox((const char *)mess,10);
 | ||
|   do {
 | ||
|     if (anamag.read(_isequal,_testandlock)==NOERR) 
 | ||
|       return TRUE;
 | ||
|   } while (bbox.run()!=K_ESC);
 | ||
|   return FALSE;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| void TMov_mag::giac_putkey2(TLocalisamfile & mag,TString16 annoes,TToken_string curr_key) 
 | ||
| {
 | ||
|   mag.zero(' ');    
 | ||
|   mag.put("ANNOES",annoes);
 | ||
|   mag.put("CODMAG",key2field(curr_key,"CODMAG"));
 | ||
|   mag.put("CODART",key2field(curr_key,"CODART"));
 | ||
|   mag.put("LIVELLO",key2field(curr_key,"LIVGIAC"));
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // aggiorna tutti i saldi in base alle modifiche fatte.
 | ||
| //      il lock su anagrafica dovrebbe garantire il lock su tutte le 
 | ||
| //      giacenze dell'articolo
 | ||
| int TMov_mag::update_balances() const 
 | ||
| {
 | ||
|   bool updated_bal=TRUE;
 | ||
|   TLocalisamfile mag(LF_MAG);
 | ||
|   mag.setkey(2);
 | ||
| 
 | ||
| 
 | ||
|   TString_array keys_to_add,keys_to_remove;
 | ||
|   ((TMov_mag *)this)->lines_to_add.get_keys(keys_to_add);
 | ||
|   ((TMov_mag *)this)->lines_to_subtract.get_keys(keys_to_remove);
 | ||
| 
 | ||
|   // aggiunge i saldi nuovi
 | ||
|   keys_to_add.sort();
 | ||
|   TToken_string * curr_key=(TToken_string *)keys_to_add.first_item();
 | ||
| 
 | ||
|   while (curr_key) {
 | ||
|     if (lock_anamag(key2field(*curr_key,"CODART"))) {
 | ||
|       // lock gained
 | ||
|       giac_putkey2(mag,get("ANNOES"),*curr_key);
 | ||
|       if (mag.read()!=NOERR) {
 | ||
|         // non trovato: aggiungo
 | ||
|         giac_putkey2(mag,get("ANNOES"),*curr_key);
 | ||
|         mag.put("NRIGA",giac_last_item(get("ANNOES"),key2field(*curr_key,"CODART"))+1);
 | ||
|         mag.write();
 | ||
|       } 
 | ||
|       // modifica questo record (e lo sblocca)
 | ||
|       update_balances(mag.curr(),(TLine_movmag &)lines_to_add[*curr_key],get("CODCAUS"),+1);
 | ||
|       /*// ottimizzazione :(cerca di sfruttare la lettura fatta per un eventuale saldo vecchio)
 | ||
|       // ci<63> causa la modifica dell'oggetto TMov_mag (il metodo non <20> pi<70> const)
 | ||
|       if (_annoes == get("ANNOES") 
 | ||
|           && lines_to_subtract.is_key(*curr_key)) {
 | ||
|         update_balances(mag.curr(),(TLine_movmag &)lines_to_subtract[*curr_key],_codcaus,-1);
 | ||
|         ((TMov_mag *)this)->lines_to_add.remove(*curr_key);
 | ||
|         ((TMov_mag *)this)->lines_to_subtract.remove(*curr_key);
 | ||
|       }*/
 | ||
|       mag.rewrite();
 | ||
|       // conclude la TRANSAZIONE prima di sbloccare il record dell'articolo
 | ||
|       TToken_string *rem_key=(TToken_string *)keys_to_remove.first_item();
 | ||
|       while ( rem_key) {
 | ||
|         if (key2field(*rem_key,"CODART")==key2field(*curr_key,"CODART")) {
 | ||
|           giac_putkey2(mag,_annoes,*rem_key);
 | ||
|           if (mag.read()==NOERR) {
 | ||
|             update_balances(mag.curr(),(TLine_movmag &)lines_to_subtract[*rem_key],_codcaus,-1);
 | ||
|             mag.rewrite();
 | ||
|           } 
 | ||
|           keys_to_remove.remove_item();
 | ||
|         }       
 | ||
|         rem_key=(TToken_string *)keys_to_remove.succ_item();
 | ||
|       } 
 | ||
|       unlock_anamag(key2field(*curr_key,"CODART"));
 | ||
|     } else {
 | ||
|       updated_bal=FALSE;
 | ||
|     }
 | ||
|     curr_key=(TToken_string *)keys_to_add.succ_item();
 | ||
|   } 
 | ||
|   // togli i saldi vecchi
 | ||
|   curr_key=(TToken_string *)keys_to_remove.first_item();
 | ||
| 
 | ||
|   while (curr_key) {
 | ||
|     if (lock_anamag(key2field(*curr_key,"CODART"))) {
 | ||
|       giac_putkey2(mag,_annoes,*curr_key);
 | ||
|       // modifica questo record (e lo sblocca)
 | ||
|       if (mag.read()==NOERR) {
 | ||
|         update_balances(mag.curr(),(TLine_movmag &)lines_to_subtract[*curr_key],_codcaus,-1);
 | ||
|         mag.rewrite();
 | ||
|       } 
 | ||
|       unlock_anamag(key2field(*curr_key,"CODART"));
 | ||
|     } else {
 | ||
|       updated_bal=FALSE;
 | ||
|     }
 | ||
|     curr_key=(TToken_string *)keys_to_remove.succ_item();
 | ||
|   }
 | ||
|   if (!updated_bal) {
 | ||
|     // saldi non aggiornati
 | ||
|     warning_box("I saldi di magazzino non sono stati del tutto aggiornati. \nProcedere ad una operazione di ''Ricostruzione saldi''");
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| // aggiorna i saldi del record corrente 
 | ||
| // in base alla causale e alla modifica fatta (con segno + o -)
 | ||
| int TMov_mag::update_balances(TRectype & magrec, const TLine_movmag &l,TString16 codcaus,int rett_sign) const
 | ||
| {
 | ||
|   TCausale_magazzino caus(codcaus);
 | ||
|   TLocalisamfile anamag(LF_ANAMAG);
 | ||
|   TLocalisamfile umart(LF_UMART);
 | ||
|   real diff,diff_val;
 | ||
|   umart.put("CODART",magrec.get("CODART"));
 | ||
|   umart.put("UM",l.um);
 | ||
|   umart.read();
 | ||
|   real fc=umart.get_real("FC");
 | ||
| 
 | ||
|   diff=fc*rett_sign*l.quant;
 | ||
|   diff_val=diff*l.prezzo;
 | ||
|   update_balance(magrec,"GIAC",diff*caus.sgn(s_giac)); // update ..
 | ||
|   update_balance(magrec,"ACQ",diff*caus.sgn(s_acq)); // update ..
 | ||
|   update_balance(magrec,"VALACQ",diff_val*caus.sgn(s_acq)); // update ..
 | ||
|   update_balance(magrec,"ENT",diff*caus.sgn(s_ent));
 | ||
|   update_balance(magrec,"VALENT",diff_val*caus.sgn(s_ent));
 | ||
|   update_balance(magrec,"VEN",diff*caus.sgn(s_ven));
 | ||
|   update_balance(magrec,"VALVEN",diff_val*caus.sgn(s_ven));
 | ||
|   update_balance(magrec,"USC",diff*caus.sgn(s_usc));
 | ||
|   update_balance(magrec,"VALUSC",diff_val*caus.sgn(s_usc));
 | ||
|   update_balance(magrec,"ORDC",diff*caus.sgn(s_ordc));
 | ||
|   update_balance(magrec,"VALORDC",diff_val*caus.sgn(s_ordc));
 | ||
|   update_balance(magrec,"ORDF",diff*caus.sgn(s_ordf));
 | ||
|   update_balance(magrec,"VALORDF",diff_val*caus.sgn(s_ordf));
 | ||
|   update_balance(magrec,"RIM",diff*caus.sgn(s_rim));
 | ||
|   update_balance(magrec,"VALRIM",diff_val*caus.sgn(s_rim));
 | ||
|   update_balance(magrec,"SCARTI",diff*caus.sgn(s_scart));
 | ||
|   update_balance(magrec,"VALSCARTI",diff_val*caus.sgn(s_scart));
 | ||
|   update_balance(magrec,"INCL",diff*caus.sgn(s_incl));
 | ||
|   update_balance(magrec,"ACL",diff*caus.sgn(s_acl));
 | ||
|   update_balance(magrec,"PRODCOMP",diff*caus.sgn(s_prodc));
 | ||
|   update_balance(magrec,"PRODFIN",diff*caus.sgn(s_prodf));
 | ||
|   update_balance(magrec,"NLABEL",diff*caus.sgn(s_label));
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| void TMov_mag::update_balance(TRectype & magrec, const char * fieldname, real diff) const
 | ||
| {
 | ||
|   magrec.put(fieldname,magrec.get_int(fieldname)+diff);
 | ||
| }
 | ||
| 
 | ||
| HIDDEN TEsercizi_contabili _esercizi;
 | ||
| 
 | ||
| int TMov_mag::codice_esercizio(TDate &d)
 | ||
| {
 | ||
|   return _esercizi.date2esc(d);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 |