Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/xml/tree

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/g4tools/include/tools/xml/tree (Version 11.3.0) and /externals/g4tools/include/tools/xml/tree (Version 11.0.p2)


  1 // Copyright (C) 2010, Guy Barrand. All rights      1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.            2 // See the file tools.license for terms.
  3                                                     3 
  4 #ifndef tools_xml_tree                              4 #ifndef tools_xml_tree
  5 #define tools_xml_tree                              5 #define tools_xml_tree
  6                                                     6 
  7 #include "element"                                  7 #include "element"
  8                                                     8 
  9 #include "../sout"                                  9 #include "../sout"
 10 #include "../strip"                                10 #include "../strip"
 11 #include "../S_STRING"                             11 #include "../S_STRING"
 12 #include "../forit"                                12 #include "../forit"
 13                                                    13 
 14 #include <list>                                    14 #include <list>
 15 #include <ostream>                                 15 #include <ostream>
 16                                                    16 
 17 namespace tools {                                  17 namespace tools {
 18 namespace xml {                                    18 namespace xml {
 19                                                    19 
 20 //  A tree is :                                    20 //  A tree is :
 21 //    <tree atb1="" atb2="" ...>                   21 //    <tree atb1="" atb2="" ...>
 22 //      ...                                        22 //      ...
 23 //      <tree...>                                  23 //      <tree...>
 24 //      </tree>                                    24 //      </tree>
 25 //      ...                                        25 //      ...
 26 //      <element atb1="" atb2="" ...> value </     26 //      <element atb1="" atb2="" ...> value </element>
 27 //      ...                                        27 //      ...
 28 //    </tree>                                      28 //    </tree>
 29 //                                                 29 //
 30 //   tree.attribute_value(<name>,s)                30 //   tree.attribute_value(<name>,s)
 31 //     retrieve the value of atb <name> of a <     31 //     retrieve the value of atb <name> of a <tag>
 32 //   tree.attribute_value(<element>,<name>,s)      32 //   tree.attribute_value(<element>,<name>,s)
 33 //     retrieve the value of an atb <name> of      33 //     retrieve the value of an atb <name> of a <element> of a <tree>
 34 //                                                 34 //
 35                                                    35 
 36 class tree;                                        36 class tree;
 37                                                    37 
 38 class factory {                                    38 class factory {
 39 public:                                            39 public:
 40   virtual ~factory(){}                             40   virtual ~factory(){}
 41 public:                                            41 public:
 42   typedef std::pair<std::string,std::string> a     42   typedef std::pair<std::string,std::string> atb;
 43 public:                                            43 public:
 44   virtual tree* create(const std::string& a_ta     44   virtual tree* create(const std::string& a_tag_name,const std::vector<atb>& a_atbs,tree* a_parent) = 0;
 45 };                                                 45 };
 46                                                    46 
 47 class tree : public virtual ielem {                47 class tree : public virtual ielem {
 48 public:                                            48 public:
 49   TOOLS_SCLASS(tools::xml::tree)                   49   TOOLS_SCLASS(tools::xml::tree)
 50 public:                                            50 public:
 51   static cid id_class() {return 1;}                51   static cid id_class() {return 1;}
 52   virtual void* cast(cid a_class) const {          52   virtual void* cast(cid a_class) const {
 53     if(void* p = cmp_cast<tree>(this,a_class))     53     if(void* p = cmp_cast<tree>(this,a_class)) {return p;}
 54     else return 0;                                 54     else return 0;
 55   }                                                55   }
 56 public:                                            56 public:
 57   typedef std::pair<std::string,std::string> a     57   typedef std::pair<std::string,std::string> atb;
 58   typedef bool (*exec_func)(tree&,void*);          58   typedef bool (*exec_func)(tree&,void*);
 59   enum copy_what { copy_attributes, copy_eleme     59   enum copy_what { copy_attributes, copy_elements, copy_children, copy_all };
 60 public:                                            60 public:
 61   tree(const std::string& a_tag_name,factory&      61   tree(const std::string& a_tag_name,factory& a_factory,tree* a_parent)
 62   :m_tag_name(a_tag_name)                          62   :m_tag_name(a_tag_name)
 63   ,m_factory(a_factory)                            63   ,m_factory(a_factory)
 64   ,m_parent(a_parent)                              64   ,m_parent(a_parent)
 65   ,m_save(true)                                    65   ,m_save(true)
 66   ,m_data_1(0)                                     66   ,m_data_1(0)
 67   ,m_data_2(0)                                     67   ,m_data_2(0)
 68   ,m_data_int(0)                                   68   ,m_data_int(0)
 69   ,m_depth(0)                                      69   ,m_depth(0)
 70   {                                                70   {
 71 #ifdef TOOLS_MEM                                   71 #ifdef TOOLS_MEM
 72     mem::increment(s_class().c_str());             72     mem::increment(s_class().c_str());
 73 #endif                                             73 #endif
 74   }                                                74   }
 75                                                    75 
 76   virtual ~tree(){                                 76   virtual ~tree(){
 77     clear();                                       77     clear();
 78 #ifdef TOOLS_MEM                                   78 #ifdef TOOLS_MEM
 79     mem::decrement(s_class().c_str());             79     mem::decrement(s_class().c_str());
 80 #endif                                             80 #endif
 81   }                                                81   }
 82                                                    82 
 83 protected:                                         83 protected:
 84   tree(const tree& a_from)                         84   tree(const tree& a_from)
 85   :ielem(a_from)                                   85   :ielem(a_from)
 86   ,m_tag_name(a_from.m_tag_name)                   86   ,m_tag_name(a_from.m_tag_name)
 87   ,m_factory(a_from.m_factory)                     87   ,m_factory(a_from.m_factory)
 88   ,m_parent(0)                                     88   ,m_parent(0)
 89   ,m_save(0)                                       89   ,m_save(0)
 90   ,m_data_1(0)                                     90   ,m_data_1(0)
 91   ,m_data_2(0)                                     91   ,m_data_2(0)
 92   ,m_data_int(0)                                   92   ,m_data_int(0)
 93   ,m_depth(0)                                      93   ,m_depth(0)
 94   {                                                94   {
 95 #ifdef TOOLS_MEM                                   95 #ifdef TOOLS_MEM
 96     mem::increment(s_class().c_str());             96     mem::increment(s_class().c_str());
 97 #endif                                             97 #endif
 98   }                                                98   }
 99                                                    99 
100   tree& operator=(const tree&){return *this;}     100   tree& operator=(const tree&){return *this;}
101                                                   101 
102 public:                                           102 public:
103   virtual bool invalidate() {return true;}        103   virtual bool invalidate() {return true;}
104                                                   104 
105   const std::list<ielem*>& childs() const {ret    105   const std::list<ielem*>& childs() const {return m_childs;}
106                                                   106 
107   ////////////////////////////////////////////    107   ///////////////////////////////////////////////////////
108   /// attributes /////////////////////////////    108   /// attributes ////////////////////////////////////////
109   ////////////////////////////////////////////    109   ///////////////////////////////////////////////////////
110   const std::vector<atb>& attributes() const {    110   const std::vector<atb>& attributes() const {return m_atbs;}
111                                                   111 
112   void add_attribute(const std::string& a_name    112   void add_attribute(const std::string& a_name,const std::string& a_value){
113     // No check is done about an existing a_na    113     // No check is done about an existing a_name.
114     m_atbs.push_back(atb(a_name,a_value));        114     m_atbs.push_back(atb(a_name,a_value));
115   }                                               115   }
116                                                   116 
117   bool is_attribute(const std::string& a_name)    117   bool is_attribute(const std::string& a_name) const {
118     size_t number = m_atbs.size();                118     size_t number = m_atbs.size();
119     for(size_t index=0;index<number;index++) {    119     for(size_t index=0;index<number;index++) {
120       if(m_atbs[index].first==a_name) return t    120       if(m_atbs[index].first==a_name) return true;
121     }                                             121     }
122     return false;                                 122     return false;
123   }                                               123   }
124                                                   124 
125   void set_attributes(const std::vector<atb>&     125   void set_attributes(const std::vector<atb>& a_atbs) {
126     m_atbs = a_atbs;                              126     m_atbs = a_atbs;
127   }                                               127   }
128   const std::string& tag_name() const {return     128   const std::string& tag_name() const {return m_tag_name;}
129                                                   129 
130   bool attribute_value(const std::string& a_at    130   bool attribute_value(const std::string& a_atb,std::string& a_value) const {
131     a_value.clear();                              131     a_value.clear();
132     size_t linen = m_atbs.size();                 132     size_t linen = m_atbs.size();
133     for(size_t count=0;count<linen;count++) {     133     for(size_t count=0;count<linen;count++) {
134       if(m_atbs[count].first==a_atb) {            134       if(m_atbs[count].first==a_atb) {
135         a_value = m_atbs[count].second;           135         a_value = m_atbs[count].second;
136         return true;                              136         return true;
137       }                                           137       }
138     }                                             138     }
139     return false;                                 139     return false;
140   }                                               140   }
141                                                   141 
142   template <class T>                              142   template <class T>
143   bool attribute_value(const std::string& a_at    143   bool attribute_value(const std::string& a_atb,T& a_value) const {
144     std::string sv;                               144     std::string sv;
145     if(!attribute_value(a_atb,sv)) {a_value=T(    145     if(!attribute_value(a_atb,sv)) {a_value=T();return false;}
146     return to<T>(sv,a_value);                     146     return to<T>(sv,a_value);
147   }                                               147   }
148                                                   148 
149   void remove_attributes(const std::string& a_    149   void remove_attributes(const std::string& a_atb) {
150     std::vector<atb>::iterator it;                150     std::vector<atb>::iterator it;
151     for(it=m_atbs.begin();it!=m_atbs.end();) {    151     for(it=m_atbs.begin();it!=m_atbs.end();) {
152       if((*it).first==a_atb) {                    152       if((*it).first==a_atb) {
153         it = m_atbs.erase(it);                    153         it = m_atbs.erase(it);
154       } else {                                    154       } else {
155         ++it;                                     155         ++it;
156       }                                           156       }
157     }                                             157     }
158   }                                               158   }
159                                                   159 
160   bool remove_attribute(const std::string& a_n    160   bool remove_attribute(const std::string& a_name){
161     //TOOLS_STL : to be checked :                 161     //TOOLS_STL : to be checked :
162     std::vector<atb>::iterator it = m_atbs.beg    162     std::vector<atb>::iterator it = m_atbs.begin();
163     size_t linen = m_atbs.size();                 163     size_t linen = m_atbs.size();
164     for(size_t count=0;count<linen;count++,++i    164     for(size_t count=0;count<linen;count++,++it) {
165       if(m_atbs[count].first==a_name) {           165       if(m_atbs[count].first==a_name) {
166         m_atbs.erase(it);                         166         m_atbs.erase(it);
167         return true; //Found and removed.         167         return true; //Found and removed.
168       }                                           168       }
169     }                                             169     }
170     return false; //Not found.                    170     return false; //Not found.
171   }                                               171   }
172                                                   172 
173   ////////////////////////////////////////////    173   ///////////////////////////////////////////////////////
174   /// elements ///////////////////////////////    174   /// elements //////////////////////////////////////////
175   ////////////////////////////////////////////    175   ///////////////////////////////////////////////////////
176   void add_element(const std::string& a_name,c    176   void add_element(const std::string& a_name,const std::vector<atb>& a_atbs,const std::string& a_value){
177     m_childs.push_back(new element(a_name,a_at    177     m_childs.push_back(new element(a_name,a_atbs,a_value));
178   }                                               178   }
179                                                   179 
180   bool element_value(const std::string& a_name    180   bool element_value(const std::string& a_name,std::string& a_value) const {
181     tools_lforcit(ielem*,m_childs,it) {           181     tools_lforcit(ielem*,m_childs,it) {
182       if(element* _elem = id_cast<ielem,elemen    182       if(element* _elem = id_cast<ielem,element>(*(*it))) {
183         if(a_name==_elem->name()) {               183         if(a_name==_elem->name()) {
184           a_value = _elem->value();               184           a_value = _elem->value();
185           return true;                            185           return true;
186         }                                         186         }
187       }                                           187       }
188     }                                             188     }
189     a_value.clear();                              189     a_value.clear();
190     return false;                                 190     return false;
191   }                                               191   }
192                                                   192 
193 /*                                                193 /*
194   //NOTE : print is a Python keyword.             194   //NOTE : print is a Python keyword.
195   void dump(std::ostream& a_out){                 195   void dump(std::ostream& a_out){
196     a_out << "dump :"                             196     a_out << "dump :"
197           << " -----> " << this << " parent :     197           << " -----> " << this << " parent : " << m_parent << std::endl;
198     a_out << " data1 : " << m_data_1              198     a_out << " data1 : " << m_data_1
199           << " data2 : " << m_data_2              199           << " data2 : " << m_data_2
200           << " dataInt : " << m_data_int          200           << " dataInt : " << m_data_int
201           << std::endl;                           201           << std::endl;
202                                                   202 
203    {size_t atbn = m_atbs.size();                  203    {size_t atbn = m_atbs.size();
204     for(size_t index=0;index<atbn;index++) {      204     for(size_t index=0;index<atbn;index++) {
205       a_out << " attribute : " << sout(m_atbs[    205       a_out << " attribute : " << sout(m_atbs[index].first) << " "
206             << sout(m_atbs[index].second) << s    206             << sout(m_atbs[index].second) << std::endl;
207     }}                                            207     }}
208                                                   208 
209    {tools_lforit(element*,m_elems,it) {           209    {tools_lforit(element*,m_elems,it) {
210       a_out << " element : \"" << (*it)->name(    210       a_out << " element : \"" << (*it)->name() << "\" \""
211             << (*it)->value() << "\"" << std::    211             << (*it)->value() << "\"" << std::endl;
212     }}                                            212     }}
213                                                   213 
214    {tools_lforit(tree*,m_children,it) {           214    {tools_lforit(tree*,m_children,it) {
215       (*it)->dump(a_out);                         215       (*it)->dump(a_out);
216     }}                                            216     }}
217   }                                               217   }
218                                                   218 
219   const std::list<element*>& elements() const     219   const std::list<element*>& elements() const {return m_elems;}
220                                                   220 
221 */                                                221 */
222                                                   222 
223   bool element_atb_value(const std::string& a_    223   bool element_atb_value(const std::string& a_elem,const std::string& a_atb,std::string& a_value) const {
224     a_value.clear();                              224     a_value.clear();
225     tools_lforcit(ielem*,m_childs,it) {           225     tools_lforcit(ielem*,m_childs,it) {
226       if(element* _elem = id_cast<ielem,elemen    226       if(element* _elem = id_cast<ielem,element>(*(*it))) {
227         if(a_elem==_elem->name()) {               227         if(a_elem==_elem->name()) {
228           if(_elem->attribute_value(a_atb,a_va    228           if(_elem->attribute_value(a_atb,a_value)) return true;
229         }                                         229         }
230       }                                           230       }
231     }                                             231     }
232     return false;                                 232     return false;
233   }                                               233   }
234                                                   234 
235   template <class T>                              235   template <class T>
236   bool element_atb_value(const std::string& a_    236   bool element_atb_value(const std::string& a_elem,const std::string& a_atb,T& a_value) const {
237     std::string sv;                               237     std::string sv;
238     if(!element_atb_value(a_elem,a_atb,sv)) {a    238     if(!element_atb_value(a_elem,a_atb,sv)) {a_value=T();return false;}
239     return to<T>(sv,a_value);                     239     return to<T>(sv,a_value);
240   }                                               240   }
241                                                   241 
242   ////////////////////////////////////////////    242   //////////////////////////////////////////////////
243   /// for osc ////////////////////////////////    243   /// for osc //////////////////////////////////////
244   ////////////////////////////////////////////    244   //////////////////////////////////////////////////
245   bool is_element(const std::string& a_name) c    245   bool is_element(const std::string& a_name) const {
246     tools_lforcit(ielem*,m_childs,it) {           246     tools_lforcit(ielem*,m_childs,it) {
247       if(element* _elem = id_cast<ielem,elemen    247       if(element* _elem = id_cast<ielem,element>(*(*it))) {
248         if(a_name==_elem->name()) return true;    248         if(a_name==_elem->name()) return true;
249       }                                           249       }
250     }                                             250     }
251     return false;                                 251     return false;
252   }                                               252   }
253                                                   253 
254   bool set_element_value(const std::string& a_    254   bool set_element_value(const std::string& a_name,const std::string& a_value,int a_index = 0){
255     int index = 0;                                255     int index = 0;
256     tools_lforcit(ielem*,m_childs,it) {           256     tools_lforcit(ielem*,m_childs,it) {
257       if(element* _elem = id_cast<ielem,elemen    257       if(element* _elem = id_cast<ielem,element>(*(*it))) {
258         if(a_name==_elem->name()) {               258         if(a_name==_elem->name()) {
259           if(index==a_index) {                    259           if(index==a_index) {
260             _elem->set_value(a_value);            260             _elem->set_value(a_value);
261             return true;                          261             return true;
262           } else {                                262           } else {
263             index ++;                             263             index ++;
264           }                                       264           }
265         }                                         265         }
266       }                                           266       }
267     }                                             267     }
268     // Not found, add one :                       268     // Not found, add one :
269     std::vector<atb> atts;                        269     std::vector<atb> atts;
270     add_element(a_name,atts,a_value);             270     add_element(a_name,atts,a_value);
271     return true;                                  271     return true;
272   }                                               272   }
273                                                   273 
274   bool set_attribute_value(const std::string&     274   bool set_attribute_value(const std::string& a_atb,const std::string& a_value) {
275     tools_vforit(atb,m_atbs,it) {                 275     tools_vforit(atb,m_atbs,it) {
276       if((*it).first==a_atb) {                    276       if((*it).first==a_atb) {
277         (*it).second = a_value;                   277         (*it).second = a_value;
278         return true;                              278         return true;
279       }                                           279       }
280     }                                             280     }
281     // Not found, add one :                       281     // Not found, add one :
282     m_atbs.push_back(atb(a_atb,a_value));         282     m_atbs.push_back(atb(a_atb,a_value));
283     return true;                                  283     return true;
284   }                                               284   }
285                                                   285 
286   bool has_empty_attribute_value(std::ostream&    286   bool has_empty_attribute_value(std::ostream& a_out) const{
287     empty_visitor visitor(a_out);                 287     empty_visitor visitor(a_out);
288     visitor.m_status = true;                      288     visitor.m_status = true;
289     const_cast<tree*>(this)->post_execute(chec    289     const_cast<tree*>(this)->post_execute(check_item,&visitor);
290     return visitor.m_status;                      290     return visitor.m_status;
291   }                                               291   }
292                                                   292 
293   class empty_visitor {                           293   class empty_visitor {
294   public:                                         294   public:
295     empty_visitor(std::ostream& a_out)            295     empty_visitor(std::ostream& a_out)
296     :f_out(a_out),m_status(true){}                296     :f_out(a_out),m_status(true){}
297   public:                                         297   public:
298     std::ostream& f_out;                          298     std::ostream& f_out;
299     bool m_status;                                299     bool m_status;
300   };                                              300   };
301                                                   301 
302   void post_execute(exec_func a_function,void*    302   void post_execute(exec_func a_function,void* a_tag) {
303     if(!a_function) return;                       303     if(!a_function) return;
304                                                   304 
305     if(!a_function(*this,a_tag)) return;          305     if(!a_function(*this,a_tag)) return;
306                                                   306 
307     tools_lforcit(ielem*,m_childs,it) {           307     tools_lforcit(ielem*,m_childs,it) {
308       if(tree* _tree = id_cast<ielem,tree>(*(*    308       if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
309         _tree->post_execute(a_function,a_tag);    309         _tree->post_execute(a_function,a_tag);
310       }                                           310       }
311     }                                             311     }
312   }                                               312   }
313                                                   313 
314   static bool check_item(tree& a_tree,void* a_    314   static bool check_item(tree& a_tree,void* a_tag){
315     empty_visitor* visitor = (empty_visitor*)a    315     empty_visitor* visitor = (empty_visitor*)a_tag;
316                                                   316 
317    {const std::vector<atb>& atbs = a_tree.attr    317    {const std::vector<atb>& atbs = a_tree.attributes();
318     size_t atbn = atbs.size();                    318     size_t atbn = atbs.size();
319     for(size_t index=0;index<atbn;index++) {      319     for(size_t index=0;index<atbn;index++) {
320       const std::string& _atb = atbs[index].fi    320       const std::string& _atb = atbs[index].first;
321       const std::string& atbv = atbs[index].se    321       const std::string& atbv = atbs[index].second;
322       if(atbv.empty()) {                          322       if(atbv.empty()) {
323         visitor->f_out << "check_item :"          323         visitor->f_out << "check_item :"
324             << " for XML item " << sout(a_tree    324             << " for XML item " << sout(a_tree.tag_name())
325             << ", attribute " << sout(_atb) <<    325             << ", attribute " << sout(_atb) << " has an empty value."
326             << std::endl;                         326             << std::endl;
327         visitor->m_status = false;                327         visitor->m_status = false;
328       }                                           328       }
329     }}                                            329     }}
330                                                   330 
331    {tools_lforcit(ielem*,a_tree.m_childs,it) {    331    {tools_lforcit(ielem*,a_tree.m_childs,it) {
332     if(element* _elem = id_cast<ielem,element>    332     if(element* _elem = id_cast<ielem,element>(*(*it))) {
333       const std::vector<atb>& atbs = _elem->at    333       const std::vector<atb>& atbs = _elem->attributes();
334       size_t atbn = atbs.size();                  334       size_t atbn = atbs.size();
335       for(size_t index=0;index<atbn;index++) {    335       for(size_t index=0;index<atbn;index++) {
336         const std::string& _atb = atbs[index].    336         const std::string& _atb = atbs[index].first;
337         const std::string& atbv = atbs[index].    337         const std::string& atbv = atbs[index].second;
338         if(atbv.empty()) {                        338         if(atbv.empty()) {
339           visitor->f_out << "ItemM::check_item    339           visitor->f_out << "ItemM::check_item :"
340               << " for XML item " << sout(a_tr    340               << " for XML item " << sout(a_tree.tag_name())
341               << ", attribute " << sout(_atb)     341               << ", attribute " << sout(_atb) << " has an empty value."
342               << std::endl;                       342               << std::endl;
343           visitor->m_status = false;              343           visitor->m_status = false;
344         }                                         344         }
345       }                                           345       }
346     }}}                                           346     }}}
347                                                   347 
348     return true;                                  348     return true;
349   }                                               349   }
350                                                   350 
351   static void collect_by_tag(tree& a_tree,cons    351   static void collect_by_tag(tree& a_tree,const std::string& a_tag,std::vector<tree*>& a_items) {
352     if(a_tree.tag_name()==a_tag) a_items.push_    352     if(a_tree.tag_name()==a_tag) a_items.push_back(&a_tree);
353     tools_lforcit(ielem*,a_tree.m_childs,it) {    353     tools_lforcit(ielem*,a_tree.m_childs,it) {
354       if(tree* _tree = id_cast<ielem,tree>(*(*    354       if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
355         collect_by_tag(*_tree,a_tag,a_items);     355         collect_by_tag(*_tree,a_tag,a_items);
356       }                                           356       }
357     }                                             357     }
358   }                                               358   }
359                                                   359 
360   tree* find_by_tag(const std::string& a_tag)     360   tree* find_by_tag(const std::string& a_tag) const {
361     if(tag_name()==a_tag) return const_cast<tr    361     if(tag_name()==a_tag) return const_cast<tree*>(this);
362     // Look children :                            362     // Look children :
363     tools_lforcit(ielem*,m_childs,it) {           363     tools_lforcit(ielem*,m_childs,it) {
364     if(tree* _tree = id_cast<ielem,tree>(*(*it    364     if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
365       tree* itemML = _tree->find_by_tag(a_tag)    365       tree* itemML = _tree->find_by_tag(a_tag);
366       if(itemML) return itemML;                   366       if(itemML) return itemML;
367     }}                                            367     }}
368     return 0;                                     368     return 0;
369   }                                               369   }
370                                                   370 
371   static void unique(std::vector<tree*>& a_ite    371   static void unique(std::vector<tree*>& a_items) {
372     std::vector<tree*> items2;                    372     std::vector<tree*> items2;
373                                                   373 
374     tools_vforcit(tree*,a_items,it) {             374     tools_vforcit(tree*,a_items,it) {
375       std::string name;                           375       std::string name;
376       if(!(*it)->attribute_value("name",name))    376       if(!(*it)->attribute_value("name",name)) continue;
377       if(name.empty()) continue;                  377       if(name.empty()) continue;
378                                                   378 
379       bool found = false;                         379       bool found = false;
380      {tools_vforit(tree*,items2,it2) {            380      {tools_vforit(tree*,items2,it2) {
381         std::string name2;                        381         std::string name2;
382         (*it2)->attribute_value("name",name2);    382         (*it2)->attribute_value("name",name2);
383         if(name2==name) {                         383         if(name2==name) {
384           found = true;                           384           found = true;
385           break;                                  385           break;
386         }                                         386         }
387       }}                                          387       }}
388       if(!found) {                                388       if(!found) {
389         items2.push_back(*it);                    389         items2.push_back(*it);
390       }                                           390       }
391     }                                             391     }
392                                                   392 
393     a_items = items2;                             393     a_items = items2;
394   }                                               394   }
395                                                   395 
396   tree* find_item(const std::string& a_name) c    396   tree* find_item(const std::string& a_name) const {
397    {size_t linen = m_atbs.size();                 397    {size_t linen = m_atbs.size();
398     for(unsigned int count=0;count<linen;count    398     for(unsigned int count=0;count<linen;count++) {
399       if(m_atbs[count].first=="name") {           399       if(m_atbs[count].first=="name") {
400         if(m_atbs[count].second==a_name) retur    400         if(m_atbs[count].second==a_name) return const_cast<tree*>(this);
401         break;                                    401         break;
402       }                                           402       }
403     }}                                            403     }}
404                                                   404 
405     // Look children :                            405     // Look children :
406     tools_lforcit(ielem*,m_childs,it) {           406     tools_lforcit(ielem*,m_childs,it) {
407     if(tree* _tree = id_cast<ielem,tree>(*(*it    407     if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
408       tree* item = _tree->find_item(a_name);      408       tree* item = _tree->find_item(a_name);
409       if(item) return item;                       409       if(item) return item;
410     }}                                            410     }}
411     return 0;                                     411     return 0;
412   }                                               412   }
413                                                   413 
414   tree* find_item_with_tag(const std::string&     414   tree* find_item_with_tag(const std::string& a_tag,
415                            const std::string&     415                            const std::string& a_name) const {
416     if(a_tag==tag_name()) {                       416     if(a_tag==tag_name()) {
417       std::string _s;                          << 417       std::string s;
418       attribute_value("name",_s);              << 418       attribute_value("name",s);
419       if(a_name==_s) return const_cast<tree*>( << 419       if(a_name==s) return const_cast<tree*>(this);
420     }                                             420     }
421                                                   421 
422     // Look children :                            422     // Look children :
423     tools_lforcit(ielem*,m_childs,it) {           423     tools_lforcit(ielem*,m_childs,it) {
424     if(tree* _tree = id_cast<ielem,tree>(*(*it    424     if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
425       tree* item = _tree->find_item_with_tag(a    425       tree* item = _tree->find_item_with_tag(a_tag,a_name);
426       if(item) return item;                       426       if(item) return item;
427     }}                                            427     }}
428     return 0;                                     428     return 0;
429   }                                               429   }
430                                                   430 
431   void remove_elements(const std::string& a_na    431   void remove_elements(const std::string& a_name){
432     // TOOLS_STL : to be checked :                432     // TOOLS_STL : to be checked :
433     std::list<ielem*>::iterator it;               433     std::list<ielem*>::iterator it;
434     for(it=m_childs.begin();it!=m_childs.end()    434     for(it=m_childs.begin();it!=m_childs.end();) {
435       if(element* _elem = id_cast<ielem,elemen    435       if(element* _elem = id_cast<ielem,element>(*(*it))) {
436         if(a_name==_elem->name()) {               436         if(a_name==_elem->name()) {
437           it = m_childs.erase(it);                437           it = m_childs.erase(it);
438           delete _elem;                           438           delete _elem;
439         } else {                                  439         } else {
440           ++it;                                   440           ++it;
441         }                                         441         }
442       } else {                                    442       } else {
443         ++it;                                     443         ++it;
444       }                                           444       }
445     }                                             445     }
446   }                                               446   }
447                                                   447 
448   void add_child(tree* a_tree) {m_childs.push_    448   void add_child(tree* a_tree) {m_childs.push_back(a_tree);}
449                                                   449 
450   tree* create_copy(tree* a_parent) {             450   tree* create_copy(tree* a_parent) {
451     tree* itemML = m_factory.create(m_tag_name    451     tree* itemML = m_factory.create(m_tag_name,m_atbs,a_parent);
452     if(!itemML) return 0;                         452     if(!itemML) return 0;
453     itemML->m_atbs = m_atbs;                      453     itemML->m_atbs = m_atbs;
454     //FIXME : m_save                              454     //FIXME : m_save
455                                                   455 
456    {tools_lforcit(ielem*,m_childs,it) {           456    {tools_lforcit(ielem*,m_childs,it) {
457     if(element* _elem = id_cast<ielem,element>    457     if(element* _elem = id_cast<ielem,element>(*(*it))) {
458       itemML->m_childs.push_back(new element(*    458       itemML->m_childs.push_back(new element(*_elem));
459     }}}                                           459     }}}
460                                                   460 
461    {tools_lforcit(ielem*,m_childs,it) {           461    {tools_lforcit(ielem*,m_childs,it) {
462     if(tree* _tree = id_cast<ielem,tree>(*(*it    462     if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
463       //FIXME : could we have mismatch parent/    463       //FIXME : could we have mismatch parent/child ?
464       tree* obj = _tree->create_copy(itemML);     464       tree* obj = _tree->create_copy(itemML);
465       if(!obj) {                                  465       if(!obj) {
466         delete itemML;                            466         delete itemML;
467         return 0;                                 467         return 0;
468       }                                           468       }
469       itemML->add_child(obj);                     469       itemML->add_child(obj);
470     }}}                                           470     }}}
471                                                   471 
472     return itemML;                                472     return itemML;
473   }                                               473   }
474                                                   474 
475   bool copy(const tree& a_from,                   475   bool copy(const tree& a_from,
476             copy_what a_what = copy_all,          476             copy_what a_what = copy_all,
477             bool a_clear = true){                 477             bool a_clear = true){
478                                                   478 
479     // Copy data (atbs, propertis, children) o    479     // Copy data (atbs, propertis, children) of a_from onto this.
480     if((a_what==copy_all)||(a_what==copy_attri    480     if((a_what==copy_all)||(a_what==copy_attributes)) {
481       if(a_clear) m_atbs.clear();                 481       if(a_clear) m_atbs.clear();
482       tools_vforcit(atb,a_from.m_atbs,it) m_at    482       tools_vforcit(atb,a_from.m_atbs,it) m_atbs.push_back(*it);
483     }                                             483     }
484                                                   484 
485     if((a_what==copy_all)||(a_what==copy_eleme    485     if((a_what==copy_all)||(a_what==copy_elements)) {
486       if(a_clear) delete_sub_elems();             486       if(a_clear) delete_sub_elems();
487       tools_lforcit(ielem*,a_from.m_childs,it)    487       tools_lforcit(ielem*,a_from.m_childs,it) {
488         if(element* _elem = id_cast<ielem,elem    488         if(element* _elem = id_cast<ielem,element>(*(*it))) {
489           m_childs.push_back(new element(*_ele    489           m_childs.push_back(new element(*_elem));
490         }                                         490         }
491       }                                           491       }
492     }                                             492     }
493                                                   493 
494     if((a_what==copy_all)||(a_what==copy_child    494     if((a_what==copy_all)||(a_what==copy_children)) {
495       if(a_clear) delete_sub_trees();             495       if(a_clear) delete_sub_trees();
496       tools_lforcit(ielem*,a_from.m_childs,it)    496       tools_lforcit(ielem*,a_from.m_childs,it) {
497         if(tree* _tree = id_cast<ielem,tree>(*    497         if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
498           //FIXME : could we have mismatch par    498           //FIXME : could we have mismatch parent/child ?
499           tree* obj = _tree->create_copy(this)    499           tree* obj = _tree->create_copy(this);
500           if(!obj) {                              500           if(!obj) {
501             // Something wrong, cleanup this.     501             // Something wrong, cleanup this.
502             clear();                              502             clear();
503             return false;                         503             return false;
504           }                                       504           }
505           add_child(obj);                         505           add_child(obj);
506         }                                         506         }
507       }                                           507       }
508     }                                             508     }
509                                                   509 
510     //FIXME : m_save                              510     //FIXME : m_save
511                                                   511 
512     return true;                                  512     return true;
513   }                                               513   }
514                                                   514 
515                                                   515 
516   void replace(const std::string& a_old,const     516   void replace(const std::string& a_old,const std::string& a_new) {
517     // Used by the obuild template system.        517     // Used by the obuild template system.
518    {size_t atbn = m_atbs.size();                  518    {size_t atbn = m_atbs.size();
519     for(size_t index=0;index<atbn;index++) {      519     for(size_t index=0;index<atbn;index++) {
520       std::string& value = m_atbs[index].secon    520       std::string& value = m_atbs[index].second;
521       replace_(value,a_old,a_new);                521       replace_(value,a_old,a_new);
522     }}                                            522     }}
523                                                   523 
524     tools_lforit(ielem*,m_childs,it) {            524     tools_lforit(ielem*,m_childs,it) {
525       if(tree* _tree = id_cast<ielem,tree>(*(*    525       if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
526         _tree->replace(a_old,a_new);              526         _tree->replace(a_old,a_new);
527       } else if(element* _elem = id_cast<ielem    527       } else if(element* _elem = id_cast<ielem,element>(*(*it))) {
528         _elem->replace(a_old,a_new);              528         _elem->replace(a_old,a_new);
529       }                                           529       }
530     }                                             530     }
531   }                                               531   }
532                                                   532 
533   static void collect_by_attribute(tree& a_tre    533   static void collect_by_attribute(tree& a_tree,
534                                    const std::    534                                    const std::string& a_tag,
535                                    std::vector    535                                    std::vector<tree*>& a_items) {
536     std::string value;                            536     std::string value;
537     if(a_tree.attribute_value(a_tag,value)) a_    537     if(a_tree.attribute_value(a_tag,value)) a_items.push_back(&a_tree);
538     tools_lforcit(ielem*,a_tree.m_childs,it) {    538     tools_lforcit(ielem*,a_tree.m_childs,it) {
539       if(tree* _tree = id_cast<ielem,tree>(*(*    539       if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
540         collect_by_attribute(*_tree,a_tag,a_it    540         collect_by_attribute(*_tree,a_tag,a_items);
541       }                                           541       }
542     }                                             542     }
543   }                                               543   }
544                                                   544 
545   bool element_values(const std::string& a_nam    545   bool element_values(const std::string& a_name,
546                       std::vector<std::string>    546                       std::vector<std::string>& a_values) const {
547     a_values.clear();                             547     a_values.clear();
548     tools_lforcit(ielem*,m_childs,it) {           548     tools_lforcit(ielem*,m_childs,it) {
549       if(element* _elem = id_cast<ielem,elemen    549       if(element* _elem = id_cast<ielem,element>(*(*it))) {
550         if(a_name==_elem->name()) {               550         if(a_name==_elem->name()) {
551           a_values.push_back(_elem->value());     551           a_values.push_back(_elem->value());
552         }                                         552         }
553       }                                           553       }
554     }                                             554     }
555     return true;                                  555     return true;
556   }                                               556   }
557                                                   557 
558   void post_execute_backward(exec_func a_funct    558   void post_execute_backward(exec_func a_function,void* a_tag){
559     if(!a_function) return;                       559     if(!a_function) return;
560     tools_lforcit(ielem*,m_childs,it) {           560     tools_lforcit(ielem*,m_childs,it) {
561       if(tree* _tree = id_cast<ielem,tree>(*(*    561       if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
562         _tree->post_execute_backward(a_functio    562         _tree->post_execute_backward(a_function,a_tag);
563       }                                           563       }
564     }                                             564     }
565     if(!a_function(*this,a_tag)) return;          565     if(!a_function(*this,a_tag)) return;
566   }                                               566   }
567                                                   567 
568   tree* find_by_attribute(const std::string& a    568   tree* find_by_attribute(const std::string& a_atb,const std::string& a_value,
569                         bool a_up_down = true,    569                         bool a_up_down = true,bool a_left_right = true) const {
570     if(a_up_down) {                               570     if(a_up_down) {
571       std::string _s;                          << 571       std::string s;
572       attribute_value(a_atb,_s);               << 572       attribute_value(a_atb,s);
573       if(_s==a_value) return const_cast<tree*> << 573       if(s==a_value) return const_cast<tree*>(this);
574                                                   574 
575       if(a_left_right) {                          575       if(a_left_right) {
576         tools_lforcit(ielem*,m_childs,it) {       576         tools_lforcit(ielem*,m_childs,it) {
577           if(tree* _tree = id_cast<ielem,tree>    577           if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
578             tree* itemML =                        578             tree* itemML =
579               _tree->find_by_attribute(a_atb,a    579               _tree->find_by_attribute(a_atb,a_value,a_up_down,a_left_right);
580             if(itemML) return itemML;             580             if(itemML) return itemML;
581           }                                       581           }
582         }                                         582         }
583       } else {                                    583       } else {
584         std::list<ielem*>::const_reverse_itera    584         std::list<ielem*>::const_reverse_iterator it;
585         for(it=m_childs.rbegin();it!=m_childs.    585         for(it=m_childs.rbegin();it!=m_childs.rend();++it) {
586         if(tree* _tree = id_cast<ielem,tree>(*    586         if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
587           tree* itemML =                          587           tree* itemML =
588             _tree->find_by_attribute(a_atb,a_v    588             _tree->find_by_attribute(a_atb,a_value,a_up_down,a_left_right);
589           if(itemML) return itemML;               589           if(itemML) return itemML;
590         }}                                        590         }}
591       }                                           591       }
592     } else {                                      592     } else {
593       if(a_left_right) {                          593       if(a_left_right) {
594         tools_lforcit(ielem*,m_childs,it) {       594         tools_lforcit(ielem*,m_childs,it) {
595         if(tree* _tree = id_cast<ielem,tree>(*    595         if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
596           tree* itemML =                          596           tree* itemML =
597             _tree->find_by_attribute(a_atb,a_v    597             _tree->find_by_attribute(a_atb,a_value,a_up_down,a_left_right);
598           if(itemML) return itemML;               598           if(itemML) return itemML;
599         }}                                        599         }}
600       } else {                                    600       } else {
601         std::list<ielem*>::const_reverse_itera    601         std::list<ielem*>::const_reverse_iterator it;
602         for(it=m_childs.rbegin();it!=m_childs.    602         for(it=m_childs.rbegin();it!=m_childs.rend();++it) {
603         if(tree* _tree = id_cast<ielem,tree>(*    603         if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
604           tree* itemML =                          604           tree* itemML =
605             _tree->find_by_attribute(a_atb,a_v    605             _tree->find_by_attribute(a_atb,a_value,a_up_down,a_left_right);
606           if(itemML) return itemML;               606           if(itemML) return itemML;
607         }}                                        607         }}
608       }                                           608       }
609                                                   609 
610       std::string _s;                          << 610       std::string s;
611       attribute_value(a_atb,_s);               << 611       attribute_value(a_atb,s);
612       if(_s==a_value) return const_cast<tree*> << 612       if(s==a_value) return const_cast<tree*>(this);
613                                                   613 
614     }                                             614     }
615     return 0;                                     615     return 0;
616   }                                               616   }
617                                                   617 
618   void dump_xml(std::ostream& a_out,const std:    618   void dump_xml(std::ostream& a_out,const std::string& a_spaces = "") {
619                                                   619 
620     // begin tag :                                620     // begin tag :
621     a_out << a_spaces << "<" << m_tag_name;       621     a_out << a_spaces << "<" << m_tag_name;
622    {size_t atbn = m_atbs.size();                  622    {size_t atbn = m_atbs.size();
623     for(size_t index=0;index<atbn;index++) {      623     for(size_t index=0;index<atbn;index++) {
624       a_out << " " << m_atbs[index].first << "    624       a_out << " " << m_atbs[index].first << "="
625             << sout(m_atbs[index].second);        625             << sout(m_atbs[index].second);
626     }}                                            626     }}
627     a_out << ">" << std::endl;                    627     a_out << ">" << std::endl;
628                                                   628 
629    {tools_lforcit(ielem*,m_childs,it) {           629    {tools_lforcit(ielem*,m_childs,it) {
630     if(element* _elem = id_cast<ielem,element>    630     if(element* _elem = id_cast<ielem,element>(*(*it))) {
631                                                   631 
632       const std::vector<atb>& atbs = _elem->at    632       const std::vector<atb>& atbs = _elem->attributes();
633                                                   633 
634       bool isCallback = false;                    634       bool isCallback = false;
635                                                   635 
636       a_out << a_spaces << "  <" << _elem->nam    636       a_out << a_spaces << "  <" << _elem->name();
637       size_t atbn = atbs.size();                  637       size_t atbn = atbs.size();
638       for(size_t index=0;index<atbn;index++) {    638       for(size_t index=0;index<atbn;index++) {
639         a_out << " " << atbs[index].first << "    639         a_out << " " << atbs[index].first << "="
640               << sout(atbs[index].second);        640               << sout(atbs[index].second);
641         if(atbs[index].first=="exec") isCallba    641         if(atbs[index].first=="exec") isCallback = true;
642       }                                           642       }
643       if(_elem->value().empty()) {                643       if(_elem->value().empty()) {
644         a_out << "/>" << std::endl;               644         a_out << "/>" << std::endl;
645       } else {                                    645       } else {
646         a_out << ">";                             646         a_out << ">";
647         std::string value = to_xml(_elem->valu    647         std::string value = to_xml(_elem->value());
648         if(isCallback) {                          648         if(isCallback) {
649           if(value.find("\\n\\")==std::string:    649           if(value.find("\\n\\")==std::string::npos) {
650             a_out << value;                       650             a_out << value;
651           } else {                                651           } else {
652             a_out << std::endl;                   652             a_out << std::endl;
653             replace_(value,"\\n\\","@OnX@");      653             replace_(value,"\\n\\","@OnX@");
654             replace_(value,"@OnX@","\\n\\\n");    654             replace_(value,"@OnX@","\\n\\\n");
655             strip(value,trailing,' ');            655             strip(value,trailing,' ');
656             a_out << value;                       656             a_out << value;
657             size_t l = value.size();              657             size_t l = value.size();
658             if(l && value[l-1]!='\n') a_out <<    658             if(l && value[l-1]!='\n') a_out << std::endl;
659             a_out << a_spaces << "  ";            659             a_out << a_spaces << "  ";
660           }                                       660           }
661         } else {                                  661         } else {
662           a_out << value;                         662           a_out << value;
663         }                                         663         }
664         a_out << "</" << _elem->name() << ">"     664         a_out << "</" << _elem->name() << ">" << std::endl;
665       }                                           665       }
666     }}}                                           666     }}}
667                                                   667 
668     // End tag :                                  668     // End tag :
669     a_out << a_spaces << "</" << m_tag_name <<    669     a_out << a_spaces << "</" << m_tag_name << ">" << std::endl;
670   }                                               670   }
671                                                   671 
672   bool set_element_atb_value(const std::string    672   bool set_element_atb_value(const std::string& a_elem,
673                             const std::string&    673                             const std::string& a_atb,
674                             const std::string&    674                             const std::string& a_value,int a_index = 0){
675     if(a_elem.empty()) {                          675     if(a_elem.empty()) {
676       size_t linen = m_atbs.size();               676       size_t linen = m_atbs.size();
677       for(size_t count=0;count<linen;count++)     677       for(size_t count=0;count<linen;count++) {
678         if(m_atbs[count].first==a_atb) {          678         if(m_atbs[count].first==a_atb) {
679           m_atbs[count].second = a_value;         679           m_atbs[count].second = a_value;
680           return true;                            680           return true;
681         }                                         681         }
682       }                                           682       }
683       // Not found, add it :                      683       // Not found, add it :
684       m_atbs.push_back(atb(a_atb,a_value));       684       m_atbs.push_back(atb(a_atb,a_value));
685       return true;                                685       return true;
686     } else {                                      686     } else {
687       int index = 0;                              687       int index = 0;
688       tools_lforcit(ielem*,m_childs,it) {         688       tools_lforcit(ielem*,m_childs,it) {
689       if(element* _elem = id_cast<ielem,elemen    689       if(element* _elem = id_cast<ielem,element>(*(*it))) {
690         if(a_elem==_elem->name()) {               690         if(a_elem==_elem->name()) {
691           if(index==a_index) {                    691           if(index==a_index) {
692             _elem->set_attribute_value(a_atb,a    692             _elem->set_attribute_value(a_atb,a_value);
693             return true;                          693             return true;
694           } else {                                694           } else {
695             index++;                              695             index++;
696           }                                       696           }
697         }                                         697         }
698       }}                                          698       }}
699       return false;                               699       return false;
700     }                                             700     }
701   }                                               701   }
702                                                   702 
703   // NOTE : used in osc. Should be removed.       703   // NOTE : used in osc. Should be removed.
704   void sub_trees(std::list<tree*>& a_list) con    704   void sub_trees(std::list<tree*>& a_list) const {
705     a_list.clear();                               705     a_list.clear();
706     tools_lforcit(ielem*,m_childs,it) {           706     tools_lforcit(ielem*,m_childs,it) {
707     if(tree* _tree = id_cast<ielem,tree>(*(*it    707     if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
708       a_list.push_back(_tree);                    708       a_list.push_back(_tree);
709     }}                                            709     }}
710   }                                               710   }
711   void sub_elems(std::list<element*>& a_list)     711   void sub_elems(std::list<element*>& a_list) const {
712     a_list.clear();                               712     a_list.clear();
713     tools_lforcit(ielem*,m_childs,it) {           713     tools_lforcit(ielem*,m_childs,it) {
714     if(element* _elem = id_cast<ielem,element>    714     if(element* _elem = id_cast<ielem,element>(*(*it))) {
715       a_list.push_back(_elem);                    715       a_list.push_back(_elem);
716     }}                                            716     }}
717   }                                               717   }
718                                                   718 
719   bool replace_child(tree* a_old,tree* a_new)     719   bool replace_child(tree* a_old,tree* a_new) {
720     tools_lforit(ielem*,m_childs,it) {            720     tools_lforit(ielem*,m_childs,it) {
721     if(tree* _tree = id_cast<ielem,tree>(*(*it    721     if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
722       if(_tree==a_old) {                          722       if(_tree==a_old) {
723         (*it) = a_new;                            723         (*it) = a_new;
724         return true; //replacement done.          724         return true; //replacement done.
725       }                                           725       }
726     }}                                            726     }}
727     return false; //no replacement done.          727     return false; //no replacement done.
728   }                                               728   }
729                                                   729 
730   // used in OnX/Widget.                          730   // used in OnX/Widget.
731   virtual void* cast(const std::string& a_clas    731   virtual void* cast(const std::string& a_class) const {
732     if(void* p = cmp_cast<tree>(this,a_class))    732     if(void* p = cmp_cast<tree>(this,a_class)) {return p;}
733     else return 0;                                733     else return 0;
734   }                                               734   }
735                                                   735 
736   void delete_element(const std::string& a_nam    736   void delete_element(const std::string& a_name) {
737     tools_lforit(ielem*,m_childs,it) {            737     tools_lforit(ielem*,m_childs,it) {
738     if(element* _elem = id_cast<ielem,element>    738     if(element* _elem = id_cast<ielem,element>(*(*it))) {
739       if(a_name==_elem->name()) {                 739       if(a_name==_elem->name()) {
740         m_childs.erase(it);                       740         m_childs.erase(it);
741         delete _elem;                             741         delete _elem;
742         break;                                    742         break;
743       }                                           743       }
744     }}                                            744     }}
745   }                                               745   }
746                                                   746 
747   void delete_element(element* a_element) {       747   void delete_element(element* a_element) {
748     tools_lforit(ielem*,m_childs,it) {            748     tools_lforit(ielem*,m_childs,it) {
749     if(element* _elem = id_cast<ielem,element>    749     if(element* _elem = id_cast<ielem,element>(*(*it))) {
750       if(_elem==a_element) {                      750       if(_elem==a_element) {
751         m_childs.erase(it);                       751         m_childs.erase(it);
752         delete _elem;                             752         delete _elem;
753         break;                                    753         break;
754       }                                           754       }
755     }}                                            755     }}
756   }                                               756   }
757                                                   757 
758   void delete_sub_trees(){                        758   void delete_sub_trees(){
759     std::list<ielem*>::iterator it;               759     std::list<ielem*>::iterator it;
760     for(it=m_childs.begin();it!=m_childs.end()    760     for(it=m_childs.begin();it!=m_childs.end();) {
761        if(tree* _tree = id_cast<ielem,tree>(*(    761        if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
762          it = m_childs.erase(it);                 762          it = m_childs.erase(it);
763          delete _tree;                            763          delete _tree;
764        } else {                                   764        } else {
765          it++;                                    765          it++;
766        }                                          766        }
767     }                                             767     }
768   }                                               768   }
769                                                   769 
770   void delete_sub_elems(){                        770   void delete_sub_elems(){
771     std::list<ielem*>::iterator it;               771     std::list<ielem*>::iterator it;
772     for(it=m_childs.begin();it!=m_childs.end()    772     for(it=m_childs.begin();it!=m_childs.end();) {
773       if(element* _elem = id_cast<ielem,elemen    773       if(element* _elem = id_cast<ielem,element>(*(*it))) {
774         it = m_childs.erase(it);                  774         it = m_childs.erase(it);
775         delete _elem;                             775         delete _elem;
776       } else {                                    776       } else {
777         it++;                                     777         it++;
778       }                                           778       }
779     }                                             779     }
780   }                                               780   }
781                                                   781 
782   const tree* find_by_element_in_same_level(co    782   const tree* find_by_element_in_same_level(const std::string& a_name,
783                                             co    783                                             const std::string& a_value) const {
784     // Look children :                            784     // Look children :
785     tools_lforcit(ielem*,m_childs,it) {           785     tools_lforcit(ielem*,m_childs,it) {
786     if(tree* _tree = id_cast<ielem,tree>(*(*it    786     if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
787       std::string _s;                          << 787       std::string s;
788       if(_tree->element_value(a_name,_s) && (a << 788       if(_tree->element_value(a_name,s) && (a_value==s)) return _tree;
789     }}                                            789     }}
790     return 0;                                     790     return 0;
791   }                                               791   }
792                                                   792 
793   bool element_value_boolean(const std::string    793   bool element_value_boolean(const std::string& a_name,bool& a_value) const {
794     std::string value;                            794     std::string value;
795     if(!element_value(a_name,value)) return fa    795     if(!element_value(a_name,value)) return false;
796     return to(value,a_value);                     796     return to(value,a_value);
797   }                                               797   }
798                                                   798 
799   void update_tree(const tree& a_old) {           799   void update_tree(const tree& a_old) {
800     // We map the opened elements in the old t    800     // We map the opened elements in the old tree within this tree.
801     // Algorithm based on the existence of a "    801     // Algorithm based on the existence of a "label" element.
802     tools_lforit(ielem*,m_childs,it) {            802     tools_lforit(ielem*,m_childs,it) {
803     if(tree* _tree = id_cast<ielem,tree>(*(*it    803     if(tree* _tree = id_cast<ielem,tree>(*(*it))) {
804       std::string slabel;                         804       std::string slabel;
805       if(_tree->element_value("label",slabel))    805       if(_tree->element_value("label",slabel)) {
806         // Try to find a same label in the sam    806         // Try to find a same label in the same level :
807         const tree* item =                        807         const tree* item =
808           a_old.find_by_element_in_same_level(    808           a_old.find_by_element_in_same_level("label",slabel);
809         if(item) {                                809         if(item) {
810           bool sopened;                           810           bool sopened;
811           if(item->element_value_boolean("open    811           if(item->element_value_boolean("opened",sopened) && sopened) {
812             _tree->set_element_value("opened",    812             _tree->set_element_value("opened","true");
813           }                                       813           }
814           if(a_old.number_of_trees()) _tree->u    814           if(a_old.number_of_trees()) _tree->update_tree(*item);
815         }                                         815         }
816       }                                           816       }
817     }}                                            817     }}
818   }                                               818   }
819                                                   819 
820   ////////////////////////////////////////////    820   //////////////////////////////////////////////////
821   /// end osc ////////////////////////////////    821   /// end osc //////////////////////////////////////
822   ////////////////////////////////////////////    822   //////////////////////////////////////////////////
823                                                   823 
824   ////////////////////////////////////////////    824   ///////////////////////////////////////////////////////
825   /// sub trees //////////////////////////////    825   /// sub trees /////////////////////////////////////////
826   ////////////////////////////////////////////    826   ///////////////////////////////////////////////////////
827                                                   827 
828   tree* parent() const {return m_parent;}         828   tree* parent() const {return m_parent;}
829                                                   829 
830   void set_parent(tree* a_parent) {m_parent =     830   void set_parent(tree* a_parent) {m_parent = a_parent;}
831                                                   831 
832   unsigned int number_of_trees() const {          832   unsigned int number_of_trees() const {
833     unsigned int number = 0;                      833     unsigned int number = 0;
834     tools_lforcit(ielem*,m_childs,it) {           834     tools_lforcit(ielem*,m_childs,it) {
835       if(id_cast<ielem,tree>(*(*it))) number++    835       if(id_cast<ielem,tree>(*(*it))) number++;
836     }                                             836     }
837     return number;                                837     return number;
838   }                                               838   }
839                                                   839 
840   void remove_child(tree*& a_tree,bool a_delet    840   void remove_child(tree*& a_tree,bool a_delete = true){
841     m_childs.remove(a_tree);                      841     m_childs.remove(a_tree);
842     if(a_delete) {                                842     if(a_delete) {
843       delete a_tree;                              843       delete a_tree;
844       a_tree = 0;                                 844       a_tree = 0;
845     }                                             845     }
846   }                                               846   }
847                                                   847 
848 /*                                                848 /*
849                                                   849 
850   bool is_first_child(const tree& a_tree) {       850   bool is_first_child(const tree& a_tree) {
851     if(m_children.empty()) return false;          851     if(m_children.empty()) return false;
852     return ( (*(m_children.begin()))==&a_tree)    852     return ( (*(m_children.begin()))==&a_tree) ? true : false;
853   }                                               853   }
854                                                   854 
855   bool is_last_child(const tree& a_tree) {        855   bool is_last_child(const tree& a_tree) {
856     if(m_children.empty()) return false;          856     if(m_children.empty()) return false;
857     return ( m_children.back()==&a_tree) ? tru    857     return ( m_children.back()==&a_tree) ? true : false;
858   }                                               858   }
859 */                                                859 */
860                                                   860 
861 /* TOOLS_STL : no std::list::insert.              861 /* TOOLS_STL : no std::list::insert.
862   void add_after(tree* a_tree,tree* a_entry){     862   void add_after(tree* a_tree,tree* a_entry){
863     tools_lforit(tree*,m_children,it) {           863     tools_lforit(tree*,m_children,it) {
864       if((*it)==a_tree) {                         864       if((*it)==a_tree) {
865         m_children.insert(it,a_entry);            865         m_children.insert(it,a_entry);
866         return;                                   866         return;
867       }                                           867       }
868     }                                             868     }
869   }                                               869   }
870                                                   870 
871   //TOOLS_STL : no std::list::iterator::operat    871   //TOOLS_STL : no std::list::iterator::operator--.
872                                                   872 
873   tree* previous_child(const tree& a_tree){       873   tree* previous_child(const tree& a_tree){
874     tools_lforit(tree*,m_children,it) {           874     tools_lforit(tree*,m_children,it) {
875       if((*it)==&a_tree) {                        875       if((*it)==&a_tree) {
876         if(it==m_children.begin()) return 0;      876         if(it==m_children.begin()) return 0;
877         --it;                                     877         --it;
878         return *it;                               878         return *it;
879       }                                           879       }
880     }                                             880     }
881     return 0;                                     881     return 0;
882   }                                               882   }
883                                                   883 
884   tree* next_child(const tree& a_tree){           884   tree* next_child(const tree& a_tree){
885     tools_lforit(tree*,m_children,it) {           885     tools_lforit(tree*,m_children,it) {
886       if((*it)==&a_tree) {                        886       if((*it)==&a_tree) {
887         std::list<tree*>::iterator last = m_ch    887         std::list<tree*>::iterator last = m_children.end();
888         --last;                                   888         --last;
889         if(it==last) return 0;                    889         if(it==last) return 0;
890         ++it;                                     890         ++it;
891         return *it;                               891         return *it;
892       }                                           892       }
893     }                                             893     }
894     return 0;                                     894     return 0;
895   }                                               895   }
896 */                                                896 */
897                                                   897 
898   void set_data(void* a_data_1,void* a_data_2,    898   void set_data(void* a_data_1,void* a_data_2,int a_data_int) {
899     m_data_1 = a_data_1;                          899     m_data_1 = a_data_1;
900     m_data_2 = a_data_2;                          900     m_data_2 = a_data_2;
901     m_data_int = a_data_int;                      901     m_data_int = a_data_int;
902   }                                               902   }
903   void get_data(void*& a_data_1,void*& a_data_    903   void get_data(void*& a_data_1,void*& a_data_2,int& a_data_int) const {
904     a_data_1 = m_data_1;                          904     a_data_1 = m_data_1;
905     a_data_2 = m_data_2;                          905     a_data_2 = m_data_2;
906     a_data_int = m_data_int;                      906     a_data_int = m_data_int;
907   }                                               907   }
908   void* get_data1() const {return m_data_1;}      908   void* get_data1() const {return m_data_1;}
909   void* get_data2() const {return m_data_2;}      909   void* get_data2() const {return m_data_2;}
910   int get_data_int() const {return m_data_int;    910   int get_data_int() const {return m_data_int;}
911   void set_depth(unsigned int a_depth) {m_dept    911   void set_depth(unsigned int a_depth) {m_depth = a_depth;}
912   unsigned int depth() const {return m_depth;}    912   unsigned int depth() const {return m_depth;}
913   void set_save_flag(bool a_value) {m_save = a    913   void set_save_flag(bool a_value) {m_save = a_value;}
914   bool save_flag() const {return m_save;}         914   bool save_flag() const {return m_save;}
915   void set_file(const std::string& a_file) {m_    915   void set_file(const std::string& a_file) {m_file = a_file;}
916   const std::string& file() const {return m_fi    916   const std::string& file() const {return m_file;}
917                                                   917 
918 protected:                                        918 protected:
919   void clear(){                                   919   void clear(){
920     m_atbs.clear();                               920     m_atbs.clear();
921                                                   921 
922    // TOOLS_STL : no std::list::erase.            922    // TOOLS_STL : no std::list::erase.
923    //{std::list<tree*>::iterator it;              923    //{std::list<tree*>::iterator it;
924    // for(it=m_children.begin();                  924    // for(it=m_children.begin();
925    //     it!=m_children.end();                   925    //     it!=m_children.end();
926    //     it = m_children.erase(it))              926    //     it = m_children.erase(it))
927    //   delete (*it);}                            927    //   delete (*it);}
928    //                                             928    //
929    //{std::list<element*>::iterator it;           929    //{std::list<element*>::iterator it;
930    // for(it=m_elems.begin();it!=m_elems.end()    930    // for(it=m_elems.begin();it!=m_elems.end();it = m_elems.erase(it))
931    //   delete (*it);}                            931    //   delete (*it);}
932                                                   932 
933     while(!m_childs.empty()) {                    933     while(!m_childs.empty()) {
934       ielem* item = m_childs.front();             934       ielem* item = m_childs.front();
935       m_childs.remove(item);                      935       m_childs.remove(item);
936       delete item;                                936       delete item;
937     }                                             937     }
938   }                                               938   }
939                                                   939 
940 protected:                                        940 protected:
941   std::string m_tag_name;                         941   std::string m_tag_name;
942   factory& m_factory;                             942   factory& m_factory;
943   tree* m_parent;                                 943   tree* m_parent;
944   //std::list<tree*> m_children;                  944   //std::list<tree*> m_children;
945   //std::list<element*> m_elems;                  945   //std::list<element*> m_elems;
946   std::list<ielem*> m_childs;                     946   std::list<ielem*> m_childs;
947   std::vector<atb> m_atbs;                        947   std::vector<atb> m_atbs;
948   std::string m_file;                             948   std::string m_file;
949   bool m_save;                                    949   bool m_save;
950   void* m_data_1;                                 950   void* m_data_1;
951   void* m_data_2;                                 951   void* m_data_2;
952   int m_data_int;                                 952   int m_data_int;
953   int m_depth;                                    953   int m_depth;
954 };                                                954 };
955                                                   955 
956 class looper {                                    956 class looper {
957 public:                                           957 public:
958   looper(const tree& a_tree)                      958   looper(const tree& a_tree)
959   :m_it(a_tree.childs().begin())                  959   :m_it(a_tree.childs().begin())
960   ,m_end(a_tree.childs().end())                   960   ,m_end(a_tree.childs().end())
961   {}                                              961   {}
962   virtual ~looper(){}                             962   virtual ~looper(){}
963 protected:                                        963 protected:
964   looper(const looper& a_from)                    964   looper(const looper& a_from)
965   :m_it(a_from.m_it)                              965   :m_it(a_from.m_it)
966   ,m_end(a_from.m_end)                            966   ,m_end(a_from.m_end)
967   {}                                              967   {}
968   looper& operator=(const looper&){return *thi    968   looper& operator=(const looper&){return *this;}
969 public:                                           969 public:
970   tree* next_tree() {                             970   tree* next_tree() {
971     for(;m_it!=m_end;++m_it) {                    971     for(;m_it!=m_end;++m_it) {
972       tree* _tree = id_cast<ielem,tree>(*(*m_i    972       tree* _tree = id_cast<ielem,tree>(*(*m_it));
973       if(_tree) {m_it++;return _tree;}            973       if(_tree) {m_it++;return _tree;}
974     }                                             974     }
975     return 0;                                     975     return 0;
976   }                                               976   }
977   element* next_element() {                       977   element* next_element() {
978     for(;m_it!=m_end;++m_it) {                    978     for(;m_it!=m_end;++m_it) {
979       element* _elem = id_cast<ielem,element>(    979       element* _elem = id_cast<ielem,element>(*(*m_it));
980       if(_elem) {m_it++;return _elem;}            980       if(_elem) {m_it++;return _elem;}
981     }                                             981     }
982     return 0;                                     982     return 0;
983   }                                               983   }
984 protected:                                        984 protected:
985   std::list<ielem*>::const_iterator m_it;         985   std::list<ielem*>::const_iterator m_it;
986   std::list<ielem*>::const_iterator m_end;        986   std::list<ielem*>::const_iterator m_end;
987 };                                                987 };
988                                                   988 
989 class default_factory : public virtual factory    989 class default_factory : public virtual factory {
990 #ifdef TOOLS_MEM                                  990 #ifdef TOOLS_MEM
991   TOOLS_SCLASS(tools::xml::default_factory)       991   TOOLS_SCLASS(tools::xml::default_factory)
992 #endif                                            992 #endif
993 public:                                           993 public:
994   virtual tree* create(const std::string& a_ta    994   virtual tree* create(const std::string& a_tag_name,const std::vector<tree::atb>& a_atbs,tree* a_parent) {
995     // It does not add the new tree in parent.    995     // It does not add the new tree in parent.
996     tree* itemML = new tree(a_tag_name,*this,a    996     tree* itemML = new tree(a_tag_name,*this,a_parent);
997     itemML->set_attributes(a_atbs);               997     itemML->set_attributes(a_atbs);
998     return itemML;                                998     return itemML;
999   }                                               999   }
1000 public:                                          1000 public:
1001   default_factory(){                             1001   default_factory(){
1002 #ifdef TOOLS_MEM                                 1002 #ifdef TOOLS_MEM
1003     mem::increment(s_class().c_str());           1003     mem::increment(s_class().c_str());
1004 #endif                                           1004 #endif
1005   }                                              1005   }
1006   virtual ~default_factory(){                    1006   virtual ~default_factory(){
1007 #ifdef TOOLS_MEM                                 1007 #ifdef TOOLS_MEM
1008     mem::decrement(s_class().c_str());           1008     mem::decrement(s_class().c_str());
1009 #endif                                           1009 #endif
1010   }                                              1010   }
1011 public:                                          1011 public:
1012   default_factory(const default_factory& a_fr    1012   default_factory(const default_factory& a_from)
1013   :factory(a_from){                              1013   :factory(a_from){
1014 #ifdef TOOLS_MEM                                 1014 #ifdef TOOLS_MEM
1015     mem::increment(s_class().c_str());           1015     mem::increment(s_class().c_str());
1016 #endif                                           1016 #endif
1017   }                                              1017   }
1018   default_factory& operator=(const default_fa    1018   default_factory& operator=(const default_factory&){return *this;}
1019 };                                               1019 };
1020                                                  1020 
1021 }}                                               1021 }}
1022                                                  1022 
1023 #endif                                           1023 #endif