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