Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/columns

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 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_columns
  5 #define tools_columns
  6 
  7 #include "vmanip"
  8 
  9 #include "forit"
 10 #include "sout"
 11 #include "schar"
 12 
 13 #ifdef TOOLS_MEM
 14 #include "mem"
 15 #include "S_STRING"
 16 #endif
 17 
 18 namespace tools {
 19 namespace columns {
 20 
 21 class tree {
 22 #ifdef TOOLS_MEM
 23   TOOLS_SCLASS(tools::columns::tree)
 24 #endif
 25 public:
 26   tree(tree* a_parent,const std::string& a_dcl):m_parent(a_parent),m_dcl(a_dcl){
 27 #ifdef TOOLS_MEM
 28     mem::increment(s_class().c_str());
 29 #endif
 30     if(a_parent) a_parent->m_sub.push_back(this);
 31   }
 32   virtual ~tree(){
 33     clear();
 34 #ifdef TOOLS_MEM
 35     mem::decrement(s_class().c_str());
 36 #endif
 37   }
 38 protected:
 39   tree(const tree&) {}
 40   tree& operator=(const tree&) {return *this;}
 41 public:
 42   void clear() {
 43     m_dcl.clear();
 44     safe_reverse_clear(m_sub);
 45   }
 46   void dump_tree(std::ostream& a_out,const std::string& a_margin) {
 47     if(m_dcl.size()) a_out << a_margin << m_dcl << std::endl;
 48    {tools_vforit(tree*,m_sub,it) {
 49       (*it)->dump_tree(a_out,a_margin+"  ");
 50     }}
 51   }
 52 public:
 53   tree* m_parent;
 54   std::string m_dcl;
 55   std::vector<tree*> m_sub;
 56 };
 57 
 58 }}
 59 
 60 #include "strip"
 61 
 62 namespace tools {
 63 namespace columns {
 64 
 65 class parser {
 66 public:
 67   parser():m_top(0,""){}
 68   virtual ~parser(){m_top.clear();}
 69 protected:
 70   parser(const parser&):m_top(0,"") {}
 71   parser& operator=(const parser&){return *this;}
 72 public:
 73   bool parse(const std::string& a_s){
 74     m_top.clear();
 75     tree* prev = &m_top;
 76    {std::string _s;
 77     for(std::string::const_iterator it=a_s.begin();;++it) {
 78       if(it==a_s.end()) {
 79         if(_s.size()) {
 80           new tree(prev,_s);
 81           _s.clear();
 82         }
 83         break;
 84       } else {
 85         const char& c = *it;
 86         if(c==',') {
 87           if(_s.size()) {
 88             new tree(prev,_s);
 89             _s.clear();
 90           }
 91         } else if(c=='{') {
 92           tree* _tree = new tree(prev,_s);
 93           _s.clear();
 94 
 95           prev = _tree;
 96         } else if(c=='}') {
 97           if(_s.size()) {
 98             new tree(prev,_s);
 99             _s.clear();
100           }
101           prev = prev->m_parent;
102           if(!prev) return false; //should not happen.
103         } else {
104           _s += c;
105         }
106       }
107     }}
108     return true;
109   }
110 
111   void dump(std::ostream& a_out) {m_top.dump_tree(a_out,"");}
112 protected:
113   tree m_top;
114 };
115 
116 }}
117 
118 #include "words"
119 #include "value"
120 
121 namespace tools {
122 namespace columns {
123 
124 inline void delete_columns(std::vector<value>& a_vars) {
125   tools_vforit(value,a_vars,it) {
126     if((*it).type()==value::VOID_STAR) {
127       std::vector<value>* vars =
128         (std::vector<value>*)(*it).get_void_star();
129       delete_columns(*vars);
130       delete vars;
131     }
132   }
133   a_vars.clear();
134 }
135 
136 inline void copy_columns(const std::vector<value>& a_from,std::vector<value>& a_to) {
137   std::vector<value>::const_iterator it;
138   for(it=a_from.begin();it!=a_from.end();++it) {
139     if((*it).type()==value::VOID_STAR) {
140       std::vector<value>* vars = new std::vector<value>();
141       value v((void*)vars);
142       v.set_label((*it).label());
143       a_to.push_back(v);
144       std::vector<value>* p =
145         (std::vector<value>*)(*it).get_void_star();
146       copy_columns(*p,*vars);
147     } else {
148       a_to.push_back(*it);
149     }
150   }
151 }
152 
153 inline void dump_columns(std::ostream& a_out,const std::vector<value>& a_vars,const std::string& a_margin = "") {
154   std::vector<value>::const_iterator it;
155   for(it=a_vars.begin();it!=a_vars.end();++it) {
156     if((*it).type()==value::VOID_STAR) {
157       a_out << a_margin
158             << "ITuple : " << (*it).label() << " : begin "
159             << std::endl;
160       std::vector<value>* vars = (std::vector<value>*)(*it).get_void_star();
161       dump_columns(a_out,*vars,a_margin+"  ");
162       //a_out << a_margin
163       //      << "ITuple : " << (*it).label() << " : end "
164       //      << std::endl;
165     } else {
166       std::string stype;
167       (*it).s_type(stype);
168       std::string sval;
169       (*it).tos(sval);
170 
171       a_out << a_margin
172             << stype << " : "
173             << (*it).label() << " : "
174             << sval
175             << std::endl;
176     }
177   }
178 }
179 
180 class finder : public columns::parser {
181   typedef columns::parser parent;
182 public:
183   finder(std::ostream& a_out,const std::string& a_script)
184   :m_out(a_out)
185   ,m_script(a_script)
186   //,fSuccess(false)
187   ,m_cur_type(value::NONE)
188   {}
189   virtual ~finder() {clear();}
190 protected:
191   finder(const finder& a_from):parent(a_from),m_out(a_from.m_out){}
192   finder& operator=(const finder&){return *this;}
193 public:
194   //void setScript(const std::string& a_string) { m_script = a_string;}
195   bool find_variables() {
196     clear();
197     if(m_script.empty()) return false; //keep old version logic.
198     if(!parse(m_script)) return false;
199     //dump(m_out);
200     //analyse m_top :
201     if(!analyse(m_top,m_stack)) {clear();return false;}
202     return true;
203   }
204 
205   void result(std::vector<value>& a_vars) const {
206     a_vars.clear();
207     copy_columns(m_stack,a_vars);
208   }
209 
210   void clear() {
211     m_top.clear();
212     delete_columns(m_stack);
213     m_cur_type = value::NONE;
214   }
215 /*
216   const std::string& script() const { return m_script;}
217   //bool isSuccess() const { return fSuccess;}
218   std::ostream& out() const {return m_out;}
219 */
220 protected:
221   bool analyse(columns::tree& a_tree,std::vector<value>& a_stack) {
222     if(a_tree.m_dcl.empty()) { //top
223       //std::cout << "debug : dcl empty" << std::endl;
224       tools_vforit(columns::tree*,a_tree.m_sub,it) {
225         if(!analyse(*(*it),a_stack)) return false;
226       }
227     } else {
228       //std::cout << "debug : dcl not empty" << std::endl;
229       if(is_spaces(a_tree.m_dcl)) return true;
230       value* v = analyse_dcl(a_tree.m_dcl);
231       if(!v) return false;
232       //std::cout << "debug : dcl label " << v->label() << std::endl;
233       if(a_tree.m_sub.size()) {
234         if(v->type()!=value::VOID_STAR) {
235           m_out << "tools::columns::finder::analyse :"
236                 << " Expect a VOID_STAR."
237                 << std::endl;
238           delete v;
239           return false;
240         }
241         m_cur_type = value::NONE;
242         std::vector<value>* stk = new std::vector<value>();
243         tools_vforit(columns::tree*,a_tree.m_sub,it) {
244           if(!analyse(*(*it),*stk)) {
245             delete v;
246             return false;
247           }
248         }
249         v->set((void*)stk);
250       } else {
251         m_cur_type = v->type();
252       }
253       a_stack.push_back(*v);
254       delete v;
255     }
256     return true;
257   }
258   value* analyse_dcl(const std::string& a_s) {
259     std::vector<std::string> ws;
260     words(a_s,"=",false,ws);
261     if(ws.size()==2) { //<type> <name>=<value>
262       std::vector<std::string> swords;
263       words(ws[0]," ",false,swords);
264       if(swords.size()==2) {
265 
266         strip(swords[0]);
267         strip(swords[1]);
268 
269         if(swords[0]=="ITuple") {
270 
271           //create a value::VOID_STAR :
272           value* v = new value((void*)0);
273           v->set_label(swords[1]);
274           return v;
275 
276         } else {
277 
278           value::e_type type;
279           if(!s2type(swords[0],type)){
280             m_out << "tools::columns::finder::analyse_dcl :"
281                   << " s2type failed for " << sout(swords[0]) << "."
282                   << std::endl;
283             return 0;
284           }
285 
286           strip(ws[1]);
287           value* v = new_value(type,ws[1]);
288           if(!v) {
289             m_out << "tools::columns::finder::analyse_dcl :"
290                   << " syntax error in " << sout(a_s) << "."
291                   << " new_value() failed."
292                   << std::endl;
293             return 0;
294           }
295           v->set_label(swords[1]);
296           return v;
297 
298         }
299 
300       } else if(swords.size()==1) {
301         if(m_cur_type==value::NONE) {
302           m_out << "tools::columns::finder::analyse_dcl :"
303                 << " (1) current type is NONE."
304                 << std::endl;
305           return 0;
306         }
307 
308         strip(ws[1]);
309         value* v = new_value(m_cur_type,ws[1]);
310         if(!v) {
311           m_out << "tools::columns::finder::analyse_dcl :"
312                 << " syntax error in " << sout(a_s) << "."
313                 << " Bad value " << sout(ws[1]) << "."
314                 << std::endl;
315           return 0;
316         }
317         v->set_label(swords[0]);
318         return v;
319 
320       } else {
321         m_out << "tools::columns::finder::analyse_dcl :"
322               << " syntax error in " << sout(a_s)
323               << ". Case 1."
324               << std::endl;
325         return 0;
326       }
327 
328     } else if(ws.size()==1) {
329       //<type> <name>
330       //<type> <name>={
331       std::vector<std::string> swords;
332       words(ws[0]," ",false,swords);
333       if(swords.size()==2) {
334         strip(swords[0]);
335         strip(swords[1]);
336 
337         if(swords[0]=="ITuple") {
338 
339           //create a value::VOID_STAR :
340           value* v = new value((void*)0);
341           v->set_label(swords[1]);
342           return v;
343 
344   } else {
345           value::e_type type;
346           if(!s2type(swords[0],type)){
347             m_out << "tools::columns::finder::analyse_dcl :"
348                   << " s2type failed for " << sout(swords[0]) << "."
349                   << std::endl;
350             return 0;
351           }
352 
353           value* v = new_value(type,"");
354           if(!v) {
355             m_out << "tools::columns::finder::analyse_dcl :"
356                   << " (2) syntax error in " << sout(ws[0]) << "."
357                   << " Unknown type " << sout(swords[0]) << "."
358                   << std::endl;
359             return 0;
360           }
361           v->set_label(swords[1]);
362           return v;
363         }
364 
365       } else if(swords.size()==1) {
366 
367         if(m_cur_type==value::NONE) {
368           m_out << "tools::columns::finder::analyse_dcl :"
369                 << " (1) current type is NONE."
370                 << std::endl;
371           return 0;
372         }
373 
374         value* v = new value();
375         v->set_type(m_cur_type);
376         v->set_label(swords[0]);
377         return v;
378 
379       } else {
380         m_out << "tools::columns::finder::analyse_dcl :"
381               << " syntax error in " << sout(a_s)
382               << ". Case 2."
383               << std::endl;
384         return 0;
385       }
386 
387     } else {
388       m_out << "tools::columns::finder::analyse_dcl :"
389             << " syntax error in " << sout(a_s)
390             << ". Case 3."
391             << std::endl;
392       return 0;
393     }
394   }
395 protected:
396   static bool s2type(const std::string& a_s,value::e_type& a_type){
397            if(a_s=="float") {
398       a_type = value::FLOAT;
399     } else if(a_s=="double") {
400       a_type = value::DOUBLE;
401     //} else if(a_s=="char") {
402     //  a_type = value::CHAR;
403     } else if(a_s=="short") {
404       a_type = value::SHORT;
405     } else if(a_s=="int") {
406       a_type = value::INT;
407     } else if(a_s=="long") {
408       a_type = value::INT64;
409     } else if((a_s=="bool")||(a_s=="boolean")) {
410       a_type = value::BOOL;
411     } else if((a_s=="string")||(a_s=="java.lang.String")){
412       a_type = value::STRING;
413     //} else if(a_s=="byte") {
414     //  a_type = value::UNSIGNED_CHAR;
415 
416     } else if(a_s=="float[]") {
417       a_type = value::ARRAY_FLOAT;
418     } else if(a_s=="double[]") {
419       a_type = value::ARRAY_DOUBLE;
420     //} else if(a_s=="char[]") {
421     //  a_type = value::ARRAY_CHAR;
422     //} else if(a_s=="byte[]") {
423     //  a_type = value::ARRAY_UNSIGNED_CHAR;
424     } else if(a_s=="short[]") {
425       a_type = value::ARRAY_SHORT;
426     } else if(a_s=="int[]") {
427       a_type = value::ARRAY_INT;
428     } else if(a_s=="long[]") {
429       a_type = value::ARRAY_INT64;
430     } else if((a_s=="bool[]")||(a_s=="boolean[]")) {
431       a_type = value::ARRAY_BOOL;
432     } else if((a_s=="string[]")||(a_s=="java.lang.String[]")){
433       a_type = value::ARRAY_STRING;
434 
435     // not AIDA :
436     //} else if(a_s=="uchar") {
437     //  a_type = value::UNSIGNED_CHAR;
438     } else if(a_s=="ushort") {
439       a_type = value::UNSIGNED_SHORT;
440     } else if(a_s=="uint") {
441       a_type = value::UNSIGNED_INT;
442     } else if(a_s=="ulong") {
443       a_type = value::UNSIGNED_INT64;
444     } else {
445       return false;
446     }
447     return true;
448   }
449   static value* new_value(value::e_type a_type,const std::string& a_v) {
450            if(a_type==value::FLOAT) {
451       float v = 0;
452       if(a_v.size()) {if(!to<float>(a_v,v)) return 0;}
453       return new value(v);
454     } else if(a_type==value::DOUBLE) {
455       double v = 0;
456       if(a_v.size()) {if(!to<double>(a_v,v)) return 0;}
457       return new value(v);
458     //} else if(a_type==value::CHAR) {
459     //  char v = 0;
460     //  if(a_v.size()) {if(!to<char>(a_v,v)) return 0;}
461     //  return new value(v);
462     } else if(a_type==value::SHORT) {
463       short v = 0;
464       if(a_v.size()) {if(!to<short>(a_v,v)) return 0;}
465       return new value(v);
466     } else if(a_type==value::INT) {
467       int v = 0;
468       if(a_v.size()) {if(!to<int>(a_v,v)) return 0;}
469       return new value(v);
470 
471     } else if(a_type==value::INT64) {
472       int64 v = 0;
473       if(a_v.size()) {if(!to<int64>(a_v,v)) return 0;}
474       return new value(v);
475     } else if(a_type==value::BOOL) {
476       bool v = false;
477       if(a_v.size()) {if(!to(a_v,v)) return 0;}
478       return new value(v);
479 
480     } else if(a_type==value::STRING) {
481       if( (a_v.size()>=2) && (a_v[0]=='"') && (a_v[a_v.size()-1]=='"') ){
482         return new value(a_v.substr(1,a_v.size()-2));
483       } else {
484         return new value(a_v);
485       }
486 
487     //} else if(a_type==value::UNSIGNED_CHAR) {
488     //  unsigned short v = 0;
489     //  if(a_v.size()) {if(!to<unsigned short>(a_v,v)) return 0;}
490     //  return new value((unsigned char)v);
491 
492     } else if(a_type==value::UNSIGNED_SHORT) {
493       unsigned short v = 0;
494       if(a_v.size()) {if(!to<unsigned short>(a_v,v)) return 0;}
495       return new value(v);
496     } else if(a_type==value::UNSIGNED_INT) {
497       unsigned int v = 0;
498       if(a_v.size()) {if(!to<unsigned int>(a_v,v)) return 0;}
499       return new value(v);
500 
501     } else if(a_type==value::UNSIGNED_INT64) {
502       uint64 v = 0;
503       if(a_v.size()) {if(!to<uint64>(a_v,v)) return 0;}
504       return new value(v);
505 
506     } else if(a_type==value::ARRAY_FLOAT) {
507       if(a_v.size()) return 0;
508       value* v = new value();
509       v->set_type(value::ARRAY_FLOAT);
510       return v;
511     } else if(a_type==value::ARRAY_DOUBLE) {
512       if(a_v.size()) return 0;
513       value* v = new value();
514       v->set_type(value::ARRAY_DOUBLE);
515       return v;
516     //} else if(a_type==value::ARRAY_UNSIGNED_CHAR) {
517     //  if(a_v.size()) return 0;
518     //  value* v = new value();
519     //  v->set_type(value::ARRAY_UNSIGNED_CHAR);
520     //  return v;
521     //} else if(a_type==value::ARRAY_CHAR) {
522     //  if(a_v.size()) return 0;
523     //  value* v = new value();
524     //  v->set_type(value::ARRAY_CHAR);
525     //  return v;
526     } else if(a_type==value::ARRAY_SHORT) {
527       if(a_v.size()) return 0;
528       value* v = new value();
529       v->set_type(value::ARRAY_SHORT);
530       return v;
531     } else if(a_type==value::ARRAY_INT) {
532       if(a_v.size()) return 0;
533       value* v = new value();
534       v->set_type(value::ARRAY_INT);
535       return v;
536     } else if(a_type==value::ARRAY_INT64) {
537       if(a_v.size()) return 0;
538       value* v = new value();
539       v->set_type(value::ARRAY_INT64);
540       return v;
541     } else if(a_type==value::ARRAY_BOOL) {
542       if(a_v.size()) return 0;
543       value* v = new value();
544       v->set_type(value::ARRAY_BOOL);
545       return v;
546     } else if(a_type==value::ARRAY_STRING) {
547       if(a_v.size()) return 0;
548       value* v = new value();
549       v->set_type(value::ARRAY_STRING);
550       return v;
551     } else {
552       return 0;
553     }
554   }
555 public:
556   std::ostream& m_out;
557   std::string m_script;
558   std::vector<value> m_stack;
559   value::e_type m_cur_type;
560   //bool fSuccess;
561 };
562 
563 }}
564 
565 #endif