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