// gestione livelli di giacenza e articoli // oggetto movimento di magazzino // funzione di ricostruzione saldi #include #include #include #include #include #include #include "mglib.h" #include "anamag.h" #include "umart.h" #include "mag.h" // ************************** // 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 int TMag_livelli::packed_lenght(int levnum) { int start=0; for (int i=1; i<=levnum && levnum<=MANY_MAG_LEV; i++) start+= _code_lenght[i-1]; return start; } 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) { pc.overwrite(codlev.left(_code_lenght[levnum-1]),packed_lenght(levnum-1)); } TString TMag_livelli::unpack_grpcode(const TString & pc, const int levnum) { int start=0; for (int i=1; i=pc.len()) return(""); else { if (levnum != _last_level && !_enabled[levnum-1]) return(""); return(pc.mid(start,levnum == _last_level ? -1 : _code_lenght[levnum-1])); } } TString TMag_livelli::build_tabcode(const TString & pc, const int levnum) { TString valore; valore << levnum; valore << unpack_grpcode(pc,levnum); if (valore.len()>1) return valore; else return ""; } // ******************************* // ******************************* #define MAXSIMBOLS 256 #define MAXSTATES 25 class TStateset { unsigned char _container[MAXSTATES]; int _current; public: TStateset & empty(); TStateset & enclose(int e); TStateset & singleton(int e); TStateset & cap(TStateset & s); int get_first() ; int get_next() ; bool is_empty() const; bool is_member(int e) const; TStateset(); ~TStateset() {}; }; struct TAutoma_state { short _transaction[MAXSIMBOLS]; TString16 * _label; bool _final; }; // ******************************* // ******************************* // automa per il riconoscimento di metacaratteri class TR_automa { TAutoma_state st[MAXSTATES]; short _maxstate; protected: TStateset union_of_closures(TStateset &s); bool is_final(int statenum) const; bool is_final(TStateset states) const; TR_automa & set_label(int statenum, const char *label); bool is_state(int statenum); const char *label(int statenum); int label2state(const char * label); void del_trans(int statenum,unsigned char symbol); int trans_to(int statenum,unsigned char symbol); bool _isdeterministic; public: TR_automa & reset_state(int statenum=-1); void add_tran(int statenum,unsigned char symbol,int next);// aggiunge una transizione int add_state(const char * label);// aggiunge uno stato TR_automa & set_final(int statenum,bool v=TRUE); // pone lo stato come finale bool is_deterministic() {return _isdeterministic;}; // bool recognized(const char * s); // tenta di riconoscere la stringa passata TR_automa(TR_automa *a=NULL,bool makedet=FALSE); // duplica un automa (e lo rende deterministico) ~TR_automa(); static void set2label(const TStateset ss,TString16 & label); static void label2set(const TString16 & label,TStateset & ss); }; // ******************************* 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; j0); 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; iunion_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 è 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; symboltrans_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; ist[i]._label; } } } TR_automa::~TR_automa() { for (int i=0; i0); } 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 // ***