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