Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/columns is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_columns
0005 #define tools_columns
0006 
0007 #include "vmanip"
0008 
0009 #include "forit"
0010 #include "sout"
0011 #include "schar"
0012 
0013 #ifdef TOOLS_MEM
0014 #include "mem"
0015 #include "S_STRING"
0016 #endif
0017 
0018 namespace tools {
0019 namespace columns {
0020 
0021 class tree {
0022 #ifdef TOOLS_MEM
0023   TOOLS_SCLASS(tools::columns::tree)
0024 #endif
0025 public:
0026   tree(tree* a_parent,const std::string& a_dcl):m_parent(a_parent),m_dcl(a_dcl){
0027 #ifdef TOOLS_MEM
0028     mem::increment(s_class().c_str());
0029 #endif
0030     if(a_parent) a_parent->m_sub.push_back(this);
0031   }
0032   virtual ~tree(){
0033     clear();
0034 #ifdef TOOLS_MEM
0035     mem::decrement(s_class().c_str());
0036 #endif
0037   }
0038 protected:
0039   tree(const tree&) {}
0040   tree& operator=(const tree&) {return *this;}
0041 public:
0042   void clear() {
0043     m_dcl.clear();
0044     safe_reverse_clear(m_sub);
0045   }
0046   void dump_tree(std::ostream& a_out,const std::string& a_margin) {
0047     if(m_dcl.size()) a_out << a_margin << m_dcl << std::endl;
0048    {tools_vforit(tree*,m_sub,it) {
0049       (*it)->dump_tree(a_out,a_margin+"  ");
0050     }}
0051   }
0052 public:
0053   tree* m_parent;
0054   std::string m_dcl;
0055   std::vector<tree*> m_sub;
0056 };
0057 
0058 }}
0059 
0060 #include "strip"
0061 
0062 namespace tools {
0063 namespace columns {
0064 
0065 class parser {
0066 public:
0067   parser():m_top(0,""){}
0068   virtual ~parser(){m_top.clear();}
0069 protected:
0070   parser(const parser&):m_top(0,"") {}
0071   parser& operator=(const parser&){return *this;}
0072 public:
0073   bool parse(const std::string& a_s){
0074     m_top.clear();
0075     tree* prev = &m_top;
0076    {std::string _s;
0077     for(std::string::const_iterator it=a_s.begin();;++it) {
0078       if(it==a_s.end()) {
0079         if(_s.size()) {
0080           new tree(prev,_s);
0081           _s.clear();
0082         }
0083         break;
0084       } else {
0085         const char& c = *it;
0086         if(c==',') {
0087           if(_s.size()) {
0088             new tree(prev,_s);
0089             _s.clear();
0090           }
0091         } else if(c=='{') {
0092           tree* _tree = new tree(prev,_s);
0093           _s.clear();
0094 
0095           prev = _tree;
0096         } else if(c=='}') {
0097           if(_s.size()) {
0098             new tree(prev,_s);
0099             _s.clear();
0100           }
0101           prev = prev->m_parent;
0102           if(!prev) return false; //should not happen.
0103         } else {
0104           _s += c;
0105         }
0106       }
0107     }}
0108     return true;
0109   }
0110 
0111   void dump(std::ostream& a_out) {m_top.dump_tree(a_out,"");}
0112 protected:
0113   tree m_top;
0114 };
0115 
0116 }}
0117 
0118 #include "words"
0119 #include "value"
0120 
0121 namespace tools {
0122 namespace columns {
0123 
0124 inline void delete_columns(std::vector<value>& a_vars) {
0125   tools_vforit(value,a_vars,it) {
0126     if((*it).type()==value::VOID_STAR) {
0127       std::vector<value>* vars =
0128         (std::vector<value>*)(*it).get_void_star();
0129       delete_columns(*vars);
0130       delete vars;
0131     }
0132   }
0133   a_vars.clear();
0134 }
0135 
0136 inline void copy_columns(const std::vector<value>& a_from,std::vector<value>& a_to) {
0137   std::vector<value>::const_iterator it;
0138   for(it=a_from.begin();it!=a_from.end();++it) {
0139     if((*it).type()==value::VOID_STAR) {
0140       std::vector<value>* vars = new std::vector<value>();
0141       value v((void*)vars);
0142       v.set_label((*it).label());
0143       a_to.push_back(v);
0144       std::vector<value>* p =
0145         (std::vector<value>*)(*it).get_void_star();
0146       copy_columns(*p,*vars);
0147     } else {
0148       a_to.push_back(*it);
0149     }
0150   }
0151 }
0152 
0153 inline void dump_columns(std::ostream& a_out,const std::vector<value>& a_vars,const std::string& a_margin = "") {
0154   std::vector<value>::const_iterator it;
0155   for(it=a_vars.begin();it!=a_vars.end();++it) {
0156     if((*it).type()==value::VOID_STAR) {
0157       a_out << a_margin
0158             << "ITuple : " << (*it).label() << " : begin "
0159             << std::endl;
0160       std::vector<value>* vars = (std::vector<value>*)(*it).get_void_star();
0161       dump_columns(a_out,*vars,a_margin+"  ");
0162       //a_out << a_margin
0163       //      << "ITuple : " << (*it).label() << " : end "
0164       //      << std::endl;
0165     } else {
0166       std::string stype;
0167       (*it).s_type(stype);
0168       std::string sval;
0169       (*it).tos(sval);
0170 
0171       a_out << a_margin
0172             << stype << " : "
0173             << (*it).label() << " : "
0174             << sval
0175             << std::endl;
0176     }
0177   }
0178 }
0179 
0180 class finder : public columns::parser {
0181   typedef columns::parser parent;
0182 public:
0183   finder(std::ostream& a_out,const std::string& a_script)
0184   :m_out(a_out)
0185   ,m_script(a_script)
0186   //,fSuccess(false)
0187   ,m_cur_type(value::NONE)
0188   {}
0189   virtual ~finder() {clear();}
0190 protected:
0191   finder(const finder& a_from):parent(a_from),m_out(a_from.m_out){}
0192   finder& operator=(const finder&){return *this;}
0193 public:
0194   //void setScript(const std::string& a_string) { m_script = a_string;}
0195   bool find_variables() {
0196     clear();
0197     if(m_script.empty()) return false; //keep old version logic.
0198     if(!parse(m_script)) return false;
0199     //dump(m_out);
0200     //analyse m_top :
0201     if(!analyse(m_top,m_stack)) {clear();return false;}
0202     return true;
0203   }
0204 
0205   void result(std::vector<value>& a_vars) const {
0206     a_vars.clear();
0207     copy_columns(m_stack,a_vars);
0208   }
0209 
0210   void clear() {
0211     m_top.clear();
0212     delete_columns(m_stack);
0213     m_cur_type = value::NONE;
0214   }
0215 /*
0216   const std::string& script() const { return m_script;}
0217   //bool isSuccess() const { return fSuccess;}
0218   std::ostream& out() const {return m_out;}
0219 */
0220 protected:
0221   bool analyse(columns::tree& a_tree,std::vector<value>& a_stack) {
0222     if(a_tree.m_dcl.empty()) { //top
0223       //std::cout << "debug : dcl empty" << std::endl;
0224       tools_vforit(columns::tree*,a_tree.m_sub,it) {
0225         if(!analyse(*(*it),a_stack)) return false;
0226       }
0227     } else {
0228       //std::cout << "debug : dcl not empty" << std::endl;
0229       if(is_spaces(a_tree.m_dcl)) return true;
0230       value* v = analyse_dcl(a_tree.m_dcl);
0231       if(!v) return false;
0232       //std::cout << "debug : dcl label " << v->label() << std::endl;
0233       if(a_tree.m_sub.size()) {
0234         if(v->type()!=value::VOID_STAR) {
0235           m_out << "tools::columns::finder::analyse :"
0236                 << " Expect a VOID_STAR."
0237                 << std::endl;
0238           delete v;
0239           return false;
0240         }
0241         m_cur_type = value::NONE;
0242         std::vector<value>* stk = new std::vector<value>();
0243         tools_vforit(columns::tree*,a_tree.m_sub,it) {
0244           if(!analyse(*(*it),*stk)) {
0245             delete v;
0246             return false;
0247           }
0248         }
0249         v->set((void*)stk);
0250       } else {
0251         m_cur_type = v->type();
0252       }
0253       a_stack.push_back(*v);
0254       delete v;
0255     }
0256     return true;
0257   }
0258   value* analyse_dcl(const std::string& a_s) {
0259     std::vector<std::string> ws;
0260     words(a_s,"=",false,ws);
0261     if(ws.size()==2) { //<type> <name>=<value>
0262       std::vector<std::string> swords;
0263       words(ws[0]," ",false,swords);
0264       if(swords.size()==2) {
0265 
0266         strip(swords[0]);
0267         strip(swords[1]);
0268 
0269         if(swords[0]=="ITuple") {
0270 
0271           //create a value::VOID_STAR :
0272           value* v = new value((void*)0);
0273           v->set_label(swords[1]);
0274           return v;
0275 
0276         } else {
0277 
0278           value::e_type type;
0279           if(!s2type(swords[0],type)){
0280             m_out << "tools::columns::finder::analyse_dcl :"
0281                   << " s2type failed for " << sout(swords[0]) << "."
0282                   << std::endl;
0283             return 0;
0284           }
0285 
0286           strip(ws[1]);
0287           value* v = new_value(type,ws[1]);
0288           if(!v) {
0289             m_out << "tools::columns::finder::analyse_dcl :"
0290                   << " syntax error in " << sout(a_s) << "."
0291                   << " new_value() failed."
0292                   << std::endl;
0293             return 0;
0294           }
0295           v->set_label(swords[1]);
0296           return v;
0297 
0298         }
0299 
0300       } else if(swords.size()==1) {
0301         if(m_cur_type==value::NONE) {
0302           m_out << "tools::columns::finder::analyse_dcl :"
0303                 << " (1) current type is NONE."
0304                 << std::endl;
0305           return 0;
0306         }
0307 
0308         strip(ws[1]);
0309         value* v = new_value(m_cur_type,ws[1]);
0310         if(!v) {
0311           m_out << "tools::columns::finder::analyse_dcl :"
0312                 << " syntax error in " << sout(a_s) << "."
0313                 << " Bad value " << sout(ws[1]) << "."
0314                 << std::endl;
0315           return 0;
0316         }
0317         v->set_label(swords[0]);
0318         return v;
0319 
0320       } else {
0321         m_out << "tools::columns::finder::analyse_dcl :"
0322               << " syntax error in " << sout(a_s)
0323               << ". Case 1."
0324               << std::endl;
0325         return 0;
0326       }
0327 
0328     } else if(ws.size()==1) {
0329       //<type> <name>
0330       //<type> <name>={
0331       std::vector<std::string> swords;
0332       words(ws[0]," ",false,swords);
0333       if(swords.size()==2) {
0334         strip(swords[0]);
0335         strip(swords[1]);
0336 
0337         if(swords[0]=="ITuple") {
0338 
0339           //create a value::VOID_STAR :
0340           value* v = new value((void*)0);
0341           v->set_label(swords[1]);
0342           return v;
0343 
0344         } else {
0345           value::e_type type;
0346           if(!s2type(swords[0],type)){
0347             m_out << "tools::columns::finder::analyse_dcl :"
0348                   << " s2type failed for " << sout(swords[0]) << "."
0349                   << std::endl;
0350             return 0;
0351           }
0352 
0353           value* v = new_value(type,"");
0354           if(!v) {
0355             m_out << "tools::columns::finder::analyse_dcl :"
0356                   << " (2) syntax error in " << sout(ws[0]) << "."
0357                   << " Unknown type " << sout(swords[0]) << "."
0358                   << std::endl;
0359             return 0;
0360           }
0361           v->set_label(swords[1]);
0362           return v;
0363         }
0364 
0365       } else if(swords.size()==1) {
0366 
0367         if(m_cur_type==value::NONE) {
0368           m_out << "tools::columns::finder::analyse_dcl :"
0369                 << " (1) current type is NONE."
0370                 << std::endl;
0371           return 0;
0372         }
0373 
0374         value* v = new value();
0375         v->set_type(m_cur_type);
0376         v->set_label(swords[0]);
0377         return v;
0378 
0379       } else {
0380         m_out << "tools::columns::finder::analyse_dcl :"
0381               << " syntax error in " << sout(a_s)
0382               << ". Case 2."
0383               << std::endl;
0384         return 0;
0385       }
0386 
0387     } else {
0388       m_out << "tools::columns::finder::analyse_dcl :"
0389             << " syntax error in " << sout(a_s)
0390             << ". Case 3."
0391             << std::endl;
0392       return 0;
0393     }
0394   }
0395 protected:
0396   static bool s2type(const std::string& a_s,value::e_type& a_type){
0397            if(a_s=="float") {
0398       a_type = value::FLOAT;
0399     } else if(a_s=="double") {
0400       a_type = value::DOUBLE;
0401     //} else if(a_s=="char") {
0402     //  a_type = value::CHAR;
0403     } else if(a_s=="short") {
0404       a_type = value::SHORT;
0405     } else if(a_s=="int") {
0406       a_type = value::INT;
0407     } else if(a_s=="long") {
0408       a_type = value::INT64;
0409     } else if((a_s=="bool")||(a_s=="boolean")) {
0410       a_type = value::BOOL;
0411     } else if((a_s=="string")||(a_s=="java.lang.String")){
0412       a_type = value::STRING;
0413     //} else if(a_s=="byte") {
0414     //  a_type = value::UNSIGNED_CHAR;
0415 
0416     } else if(a_s=="float[]") {
0417       a_type = value::ARRAY_FLOAT;
0418     } else if(a_s=="double[]") {
0419       a_type = value::ARRAY_DOUBLE;
0420     //} else if(a_s=="char[]") {
0421     //  a_type = value::ARRAY_CHAR;
0422     //} else if(a_s=="byte[]") {
0423     //  a_type = value::ARRAY_UNSIGNED_CHAR;
0424     } else if(a_s=="short[]") {
0425       a_type = value::ARRAY_SHORT;
0426     } else if(a_s=="int[]") {
0427       a_type = value::ARRAY_INT;
0428     } else if(a_s=="long[]") {
0429       a_type = value::ARRAY_INT64;
0430     } else if((a_s=="bool[]")||(a_s=="boolean[]")) {
0431       a_type = value::ARRAY_BOOL;
0432     } else if((a_s=="string[]")||(a_s=="java.lang.String[]")){
0433       a_type = value::ARRAY_STRING;
0434 
0435     // not AIDA :
0436     //} else if(a_s=="uchar") {
0437     //  a_type = value::UNSIGNED_CHAR;
0438     } else if(a_s=="ushort") {
0439       a_type = value::UNSIGNED_SHORT;
0440     } else if(a_s=="uint") {
0441       a_type = value::UNSIGNED_INT;
0442     } else if(a_s=="ulong") {
0443       a_type = value::UNSIGNED_INT64;
0444     } else {
0445       return false;
0446     }
0447     return true;
0448   }
0449   static value* new_value(value::e_type a_type,const std::string& a_v) {
0450            if(a_type==value::FLOAT) {
0451       float v = 0;
0452       if(a_v.size()) {if(!to<float>(a_v,v)) return 0;}
0453       return new value(v);
0454     } else if(a_type==value::DOUBLE) {
0455       double v = 0;
0456       if(a_v.size()) {if(!to<double>(a_v,v)) return 0;}
0457       return new value(v);
0458     //} else if(a_type==value::CHAR) {
0459     //  char v = 0;
0460     //  if(a_v.size()) {if(!to<char>(a_v,v)) return 0;}
0461     //  return new value(v);
0462     } else if(a_type==value::SHORT) {
0463       short v = 0;
0464       if(a_v.size()) {if(!to<short>(a_v,v)) return 0;}
0465       return new value(v);
0466     } else if(a_type==value::INT) {
0467       int v = 0;
0468       if(a_v.size()) {if(!to<int>(a_v,v)) return 0;}
0469       return new value(v);
0470 
0471     } else if(a_type==value::INT64) {
0472       int64 v = 0;
0473       if(a_v.size()) {if(!to<int64>(a_v,v)) return 0;}
0474       return new value(v);
0475     } else if(a_type==value::BOOL) {
0476       bool v = false;
0477       if(a_v.size()) {if(!to(a_v,v)) return 0;}
0478       return new value(v);
0479 
0480     } else if(a_type==value::STRING) {
0481       if( (a_v.size()>=2) && (a_v[0]=='"') && (a_v[a_v.size()-1]=='"') ){
0482         return new value(a_v.substr(1,a_v.size()-2));
0483       } else {
0484         return new value(a_v);
0485       }
0486 
0487     //} else if(a_type==value::UNSIGNED_CHAR) {
0488     //  unsigned short v = 0;
0489     //  if(a_v.size()) {if(!to<unsigned short>(a_v,v)) return 0;}
0490     //  return new value((unsigned char)v);
0491 
0492     } else if(a_type==value::UNSIGNED_SHORT) {
0493       unsigned short v = 0;
0494       if(a_v.size()) {if(!to<unsigned short>(a_v,v)) return 0;}
0495       return new value(v);
0496     } else if(a_type==value::UNSIGNED_INT) {
0497       unsigned int v = 0;
0498       if(a_v.size()) {if(!to<unsigned int>(a_v,v)) return 0;}
0499       return new value(v);
0500 
0501     } else if(a_type==value::UNSIGNED_INT64) {
0502       uint64 v = 0;
0503       if(a_v.size()) {if(!to<uint64>(a_v,v)) return 0;}
0504       return new value(v);
0505 
0506     } else if(a_type==value::ARRAY_FLOAT) {
0507       if(a_v.size()) return 0;
0508       value* v = new value();
0509       v->set_type(value::ARRAY_FLOAT);
0510       return v;
0511     } else if(a_type==value::ARRAY_DOUBLE) {
0512       if(a_v.size()) return 0;
0513       value* v = new value();
0514       v->set_type(value::ARRAY_DOUBLE);
0515       return v;
0516     //} else if(a_type==value::ARRAY_UNSIGNED_CHAR) {
0517     //  if(a_v.size()) return 0;
0518     //  value* v = new value();
0519     //  v->set_type(value::ARRAY_UNSIGNED_CHAR);
0520     //  return v;
0521     //} else if(a_type==value::ARRAY_CHAR) {
0522     //  if(a_v.size()) return 0;
0523     //  value* v = new value();
0524     //  v->set_type(value::ARRAY_CHAR);
0525     //  return v;
0526     } else if(a_type==value::ARRAY_SHORT) {
0527       if(a_v.size()) return 0;
0528       value* v = new value();
0529       v->set_type(value::ARRAY_SHORT);
0530       return v;
0531     } else if(a_type==value::ARRAY_INT) {
0532       if(a_v.size()) return 0;
0533       value* v = new value();
0534       v->set_type(value::ARRAY_INT);
0535       return v;
0536     } else if(a_type==value::ARRAY_INT64) {
0537       if(a_v.size()) return 0;
0538       value* v = new value();
0539       v->set_type(value::ARRAY_INT64);
0540       return v;
0541     } else if(a_type==value::ARRAY_BOOL) {
0542       if(a_v.size()) return 0;
0543       value* v = new value();
0544       v->set_type(value::ARRAY_BOOL);
0545       return v;
0546     } else if(a_type==value::ARRAY_STRING) {
0547       if(a_v.size()) return 0;
0548       value* v = new value();
0549       v->set_type(value::ARRAY_STRING);
0550       return v;
0551     } else {
0552       return 0;
0553     }
0554   }
0555 public:
0556   std::ostream& m_out;
0557   std::string m_script;
0558   std::vector<value> m_stack;
0559   value::e_type m_cur_type;
0560   //bool fSuccess;
0561 };
0562 
0563 }}
0564 
0565 #endif