inlib
1.2.0
|
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved. 00002 // See the file inlib.license for terms. 00003 00004 #ifndef inlib_columns 00005 #define inlib_columns 00006 00007 #include <vector> 00008 #include <ostream> 00009 00010 #ifdef INLIB_MEM 00011 #include "mem" 00012 #endif 00013 00014 namespace inlib { 00015 namespace columns { 00016 00017 class tree { 00018 static const std::string& s_class() { 00019 static const std::string s_v("inlib::columns::tree"); 00020 return s_v; 00021 } 00022 public: 00023 #ifdef ANDROID_NDK 00024 tree():m_parent(0){} //Android : for inlib STL. 00025 #endif 00026 tree(tree* a_parent):m_parent(a_parent){ 00027 #ifdef INLIB_MEM 00028 mem::increment(s_class().c_str()); 00029 #endif 00030 } 00031 virtual ~tree(){ 00032 #ifdef INLIB_MEM 00033 mem::decrement(s_class().c_str()); 00034 #endif 00035 } 00036 public: 00037 tree(const tree& a_from) 00038 :m_dcl(a_from.m_dcl) 00039 ,m_sub(a_from.m_sub) 00040 ,m_parent(a_from.m_parent) 00041 { 00042 #ifdef INLIB_MEM 00043 mem::increment(s_class().c_str()); 00044 #endif 00045 } 00046 tree& operator=(const tree& a_from) { 00047 m_dcl = a_from.m_dcl; 00048 m_sub = a_from.m_sub; 00049 m_parent = a_from.m_parent; 00050 return *this; 00051 } 00052 public: 00053 void clear(){ 00054 m_dcl.clear(); 00055 {std::vector<tree>::iterator it; 00056 for(it=m_sub.begin();it!=m_sub.end();++it) { 00057 (*it).clear(); 00058 }} 00059 } 00060 void dump_tree(std::ostream& a_out,const std::string& a_margin) { 00061 if(m_dcl.size()) a_out << a_margin << m_dcl << std::endl; 00062 {std::vector<tree>::iterator it; 00063 for(it=m_sub.begin();it!=m_sub.end();++it) { 00064 (*it).dump_tree(a_out,a_margin+" "); 00065 }} 00066 } 00067 public: 00068 std::string m_dcl; 00069 std::vector<tree> m_sub; 00070 tree* m_parent; 00071 }; 00072 00073 }} 00074 00075 #include <inlib/smanip> 00076 00077 namespace inlib { 00078 namespace columns { 00079 00080 class parser { 00081 public: 00082 parser():m_top(0){} 00083 virtual ~parser(){m_top.clear();} 00084 protected: 00085 parser(const parser& a_from):m_top(a_from.m_top){} 00086 private: 00087 parser& operator=(const parser&){return *this;} 00088 public: 00089 bool parse(const std::string& a_s){ 00090 m_top.clear(); 00091 tree* prev = &m_top; 00092 {tree tmp(0); 00093 std::string s; 00094 for(std::string::const_iterator it=a_s.begin();;++it) { 00095 if(it==a_s.end()) { 00096 if(s.size()) { 00097 tmp.m_dcl = s; 00098 tmp.m_parent = prev; 00099 prev->m_sub.push_back(tmp); 00100 s.clear(); 00101 } 00102 tmp.clear(); 00103 break; 00104 } else { 00105 const char& c = *it; 00106 if(c==',') { 00107 if(s.size()) { 00108 tmp.m_dcl = s; 00109 tmp.m_parent = prev; 00110 prev->m_sub.push_back(tmp); 00111 s.clear(); 00112 } 00113 tmp.clear(); 00114 } else if(c=='{') { 00115 tmp.clear(); 00116 if(s.size()) { 00117 tmp.m_dcl = s; 00118 s.clear(); 00119 } 00120 tmp.m_parent = prev; 00121 prev->m_sub.push_back(tmp); 00122 prev = &(prev->m_sub.back()); 00123 } else if(c=='}') { 00124 if(s.size()) { 00125 tmp.m_dcl = s; 00126 tmp.m_parent = prev; 00127 prev->m_sub.push_back(tmp); 00128 s.clear(); 00129 } 00130 tmp.clear(); 00131 prev = prev->m_parent; 00132 if(!prev) return false; //should not happen. 00133 } else { 00134 s += c; 00135 } 00136 } 00137 }} 00138 return true; 00139 } 00140 00141 void dump(std::ostream& a_out) {m_top.dump_tree(a_out,"");} 00142 protected: 00143 tree m_top; 00144 }; 00145 00146 }} 00147 00148 #include <inlib/words> 00149 #include <inlib/value> 00150 00151 namespace inlib { 00152 namespace columns { 00153 00154 inline void delete_columns(std::vector<inlib::value>& a_vars) { 00155 std::vector<inlib::value>::iterator it; 00156 for(it=a_vars.begin();it!=a_vars.end();++it) { 00157 if((*it).type()==inlib::value::VOID_STAR) { 00158 std::vector<inlib::value>* vars = 00159 (std::vector<inlib::value>*)(*it).get_void_star(); 00160 delete_columns(*vars); 00161 delete vars; 00162 } 00163 } 00164 a_vars.clear(); 00165 } 00166 00167 inline void copy_columns(const std::vector<inlib::value>& a_from, 00168 std::vector<inlib::value>& a_to) { 00169 std::vector<inlib::value>::const_iterator it; 00170 for(it=a_from.begin();it!=a_from.end();++it) { 00171 if((*it).type()==inlib::value::VOID_STAR) { 00172 std::vector<inlib::value>* vars = new std::vector<inlib::value>(); 00173 inlib::value v((void*)vars); 00174 v.set_label((*it).label()); 00175 a_to.push_back(v); 00176 std::vector<inlib::value>* p = 00177 (std::vector<inlib::value>*)(*it).get_void_star(); 00178 copy_columns(*p,*vars); 00179 } else { 00180 a_to.push_back(*it); 00181 } 00182 } 00183 } 00184 00185 inline void dump_columns(std::ostream& a_out, 00186 const std::vector<inlib::value>& a_vars, 00187 const std::string& a_margin = "") { 00188 std::vector<inlib::value>::const_iterator it; 00189 for(it=a_vars.begin();it!=a_vars.end();++it) { 00190 if((*it).type()==inlib::value::VOID_STAR) { 00191 a_out << a_margin 00192 << "ITuple : " << (*it).label() << " : begin " 00193 << std::endl; 00194 std::vector<inlib::value>* vars = 00195 (std::vector<inlib::value>*)(*it).get_void_star(); 00196 dump_columns(a_out,*vars,a_margin+" "); 00197 //a_out << a_margin 00198 // << "ITuple : " << (*it).label() << " : end " 00199 // << std::endl; 00200 } else { 00201 //(*it).print(a_out); 00202 std::string stype; 00203 (*it).s_type(stype); 00204 std::string sval; 00205 (*it).tos(sval); 00206 00207 a_out << a_margin 00208 << stype << " : " 00209 << (*it).label() << " : " 00210 << sval 00211 << std::endl; 00212 } 00213 } 00214 } 00215 00216 class finder : public inlib::columns::parser { 00217 public: 00218 finder(std::ostream& a_out,const std::string& a_script) 00219 :m_out(a_out) 00220 ,m_script(a_script) 00221 //,fSuccess(false) 00222 ,m_cur_type(inlib::value::NONE) 00223 {} 00224 virtual ~finder() {clear();} 00225 private: 00226 finder(const finder& a_from):parser(a_from),m_out(a_from.m_out){} 00227 finder& operator=(const finder&){return *this;} 00228 public: 00229 //void setScript(const std::string& a_string) { m_script = a_string;} 00230 bool find_variables() { 00231 clear(); 00232 if(m_script.empty()) return false; //keep old version logic. 00233 if(!parse(m_script)) return false; 00234 //dump(m_out); 00235 //analyse m_top : 00236 if(!analyse(m_top,m_stack)) {clear();return false;} 00237 return true; 00238 } 00239 00240 std::vector<inlib::value> result() const { 00241 std::vector<inlib::value> vars; 00242 copy_columns(m_stack,vars); 00243 return vars; 00244 } 00245 00246 void clear() { 00247 m_top.clear(); 00248 delete_columns(m_stack); 00249 m_cur_type = inlib::value::NONE; 00250 } 00251 /* 00252 const std::string& script() const { return m_script;} 00253 std::string script() { return m_script;} 00254 //bool isSuccess() const { return fSuccess;} 00255 std::ostream& out() const {return m_out;} 00256 */ 00257 private: 00258 bool analyse(inlib::columns::tree& a_tree, 00259 std::vector<inlib::value>& a_stack) { 00260 if(a_tree.m_dcl.empty()) { //top 00261 //std::cout << "debug : dcl empty" << std::endl; 00262 std::vector<inlib::columns::tree>::iterator it; 00263 for(it=a_tree.m_sub.begin();it!=a_tree.m_sub.end();++it) { 00264 if(!analyse(*it,a_stack)) return false; 00265 } 00266 } else { 00267 //std::cout << "debug : dcl not empty" << std::endl; 00268 inlib::value* v = analyse_dcl(a_tree.m_dcl); 00269 if(!v) return false; 00270 //std::cout << "debug : dcl label " << v->label() << std::endl; 00271 if(a_tree.m_sub.size()) { 00272 if(v->type()!=inlib::value::VOID_STAR) { 00273 m_out << "inlib::columns::finder::analyse :" 00274 << " Expect a VOID_STAR." 00275 << std::endl; 00276 delete v; 00277 return false; 00278 } 00279 m_cur_type = inlib::value::NONE; 00280 std::vector<inlib::value>* stk = new std::vector<inlib::value>(); 00281 std::vector<inlib::columns::tree>::iterator it; 00282 for(it=a_tree.m_sub.begin();it!=a_tree.m_sub.end();++it) { 00283 if(!analyse(*it,*stk)) { 00284 delete v; 00285 return false; 00286 } 00287 } 00288 v->set((void*)stk); 00289 } else { 00290 m_cur_type = v->type(); 00291 } 00292 a_stack.push_back(*v); 00293 delete v; 00294 } 00295 return true; 00296 } 00297 inlib::value* analyse_dcl(const std::string& a_s) { 00298 std::vector<std::string> words; 00299 inlib::words(a_s,"=",false,words); 00300 if(words.size()==2) { //<type> <name>=<value> 00301 std::vector<std::string> swords; 00302 inlib::words(words[0]," ",false,swords); 00303 if(swords.size()==2) { 00304 00305 inlib::strip(swords[0]); 00306 inlib::strip(swords[1]); 00307 00308 if(swords[0]=="ITuple") { 00309 00310 //create a inlib::value::VOID_STAR : 00311 inlib::value* v = new inlib::value((void*)0); 00312 v->set_label(swords[1]); 00313 return v; 00314 00315 } else { 00316 00317 inlib::value::e_type type; 00318 if(!s2type(swords[0],type)){ 00319 m_out << "inlib::columns::finder::analyse_dcl :" 00320 << " s2type failed for " << inlib::sout(swords[0]) << "." 00321 << std::endl; 00322 return 0; 00323 } 00324 00325 inlib::strip(words[1]); 00326 inlib::value* v = new_value(type,words[1]); 00327 if(!v) { 00328 m_out << "inlib::columns::finder::analyse_dcl :" 00329 << " syntax error in " << inlib::sout(a_s) << "." 00330 << " new_value() failed." 00331 << std::endl; 00332 return 0; 00333 } 00334 v->set_label(swords[1]); 00335 return v; 00336 00337 } 00338 00339 } else if(swords.size()==1) { 00340 if(m_cur_type==inlib::value::NONE) { 00341 m_out << "inlib::columns::finder::analyse_dcl :" 00342 << " (1) current type is NONE." 00343 << std::endl; 00344 return 0; 00345 } 00346 00347 inlib::strip(words[1]); 00348 inlib::value* v = new_value(m_cur_type,words[1]); 00349 if(!v) { 00350 m_out << "inlib::columns::finder::analyse_dcl :" 00351 << " syntax error in " << inlib::sout(a_s) << "." 00352 << " Bad value " << inlib::sout(words[1]) << "." 00353 << std::endl; 00354 return 0; 00355 } 00356 v->set_label(swords[0]); 00357 return v; 00358 00359 } else { 00360 m_out << "inlib::columns::finder::analyse_dcl :" 00361 << " syntax error in " << inlib::sout(a_s) 00362 << ". Case 1." 00363 << std::endl; 00364 return 0; 00365 } 00366 00367 } else if(words.size()==1) { 00368 //<type> <name> 00369 //<type> <name>={ 00370 std::vector<std::string> swords; 00371 inlib::words(words[0]," ",false,swords); 00372 if(swords.size()==2) { 00373 inlib::strip(swords[0]); 00374 inlib::strip(swords[1]); 00375 00376 if(swords[0]=="ITuple") { 00377 00378 //create a inlib::value::VOID_STAR : 00379 inlib::value* v = new inlib::value((void*)0); 00380 v->set_label(swords[1]); 00381 return v; 00382 00383 } else { 00384 inlib::value::e_type type; 00385 if(!s2type(swords[0],type)){ 00386 m_out << "inlib::columns::finder::analyse_dcl :" 00387 << " s2type failed for " << inlib::sout(swords[0]) << "." 00388 << std::endl; 00389 return 0; 00390 } 00391 00392 inlib::value* v = new_value(type,""); 00393 if(!v) { 00394 m_out << "inlib::columns::finder::analyse_dcl :" 00395 << " (2) syntax error in " << inlib::sout(words[0]) << "." 00396 << " Unknown type " << inlib::sout(swords[0]) << "." 00397 << std::endl; 00398 return 0; 00399 } 00400 v->set_label(swords[1]); 00401 return v; 00402 } 00403 00404 } else if(swords.size()==1) { 00405 00406 if(m_cur_type==inlib::value::NONE) { 00407 m_out << "inlib::columns::finder::analyse_dcl :" 00408 << " (1) current type is NONE." 00409 << std::endl; 00410 return 0; 00411 } 00412 00413 inlib::value* v = new inlib::value(); 00414 v->set_type(m_cur_type); 00415 v->set_label(swords[0]); 00416 return v; 00417 00418 } else { 00419 m_out << "inlib::columns::finder::analyse_dcl :" 00420 << " syntax error in " << inlib::sout(a_s) 00421 << ". Case 2." 00422 << std::endl; 00423 return 0; 00424 } 00425 00426 } else { 00427 m_out << "inlib::columns::finder::analyse_dcl :" 00428 << " syntax error in " << inlib::sout(a_s) 00429 << ". Case 3." 00430 << std::endl; 00431 return 0; 00432 } 00433 } 00434 private: 00435 static bool s2type(const std::string& a_s, 00436 inlib::value::e_type& a_type){ 00437 if(a_s=="float") { 00438 a_type = inlib::value::FLOAT; 00439 } else if(a_s=="double") { 00440 a_type = inlib::value::DOUBLE; 00441 //} else if(a_s=="char") { 00442 // a_type = inlib::value::CHAR; 00443 } else if(a_s=="short") { 00444 a_type = inlib::value::SHORT; 00445 } else if(a_s=="int") { 00446 a_type = inlib::value::INT; 00447 } else if(a_s=="long") { 00448 a_type = inlib::value::INT64; 00449 } else if((a_s=="bool")||(a_s=="boolean")) { 00450 a_type = inlib::value::BOOL; 00451 } else if((a_s=="string")||(a_s=="java.lang.String")){ 00452 a_type = inlib::value::STRING; 00453 //} else if(a_s=="byte") { 00454 // a_type = inlib::value::UNSIGNED_CHAR; 00455 00456 } else if(a_s=="float[]") { 00457 a_type = inlib::value::ARRAY_FLOAT; 00458 } else if(a_s=="double[]") { 00459 a_type = inlib::value::ARRAY_DOUBLE; 00460 //} else if(a_s=="char[]") { 00461 // a_type = inlib::value::ARRAY_CHAR; 00462 //} else if(a_s=="byte[]") { 00463 // a_type = inlib::value::ARRAY_UNSIGNED_CHAR; 00464 } else if(a_s=="short[]") { 00465 a_type = inlib::value::ARRAY_SHORT; 00466 } else if(a_s=="int[]") { 00467 a_type = inlib::value::ARRAY_INT; 00468 } else if(a_s=="long[]") { 00469 a_type = inlib::value::ARRAY_INT64; 00470 } else if((a_s=="bool[]")||(a_s=="boolean[]")) { 00471 a_type = inlib::value::ARRAY_BOOL; 00472 } else if((a_s=="string[]")||(a_s=="java.lang.String[]")){ 00473 a_type = inlib::value::ARRAY_STRING; 00474 00475 // not AIDA : 00476 //} else if(a_s=="uchar") { 00477 // a_type = inlib::value::UNSIGNED_CHAR; 00478 } else if(a_s=="ushort") { 00479 a_type = inlib::value::UNSIGNED_SHORT; 00480 } else if(a_s=="uint") { 00481 a_type = inlib::value::UNSIGNED_INT; 00482 } else if(a_s=="ulong") { 00483 a_type = inlib::value::UNSIGNED_INT64; 00484 } else { 00485 return false; 00486 } 00487 return true; 00488 } 00489 static inlib::value* new_value(inlib::value::e_type a_type, 00490 const std::string& a_v) { 00491 if(a_type==inlib::value::FLOAT) { 00492 float v = 0; 00493 if(a_v.size()) {if(!inlib::to<float>(a_v,v)) return 0;} 00494 return new inlib::value(v); 00495 } else if(a_type==inlib::value::DOUBLE) { 00496 double v = 0; 00497 if(a_v.size()) {if(!inlib::to<double>(a_v,v)) return 0;} 00498 return new inlib::value(v); 00499 //} else if(a_type==inlib::value::CHAR) { 00500 // char v = 0; 00501 // if(a_v.size()) {if(!inlib::to<char>(a_v,v)) return 0;} 00502 // return new inlib::value(v); 00503 } else if(a_type==inlib::value::SHORT) { 00504 short v = 0; 00505 if(a_v.size()) {if(!inlib::to<short>(a_v,v)) return 0;} 00506 return new inlib::value(v); 00507 } else if(a_type==inlib::value::INT) { 00508 int v = 0; 00509 if(a_v.size()) {if(!inlib::to<int>(a_v,v)) return 0;} 00510 return new inlib::value(v); 00511 00512 } else if(a_type==inlib::value::INT64) { 00513 int64 v = 0; 00514 if(a_v.size()) {if(!inlib::to<int64>(a_v,v)) return 0;} 00515 return new inlib::value(v); 00516 } else if(a_type==inlib::value::BOOL) { 00517 bool v = false; 00518 if(a_v.size()) {if(!inlib::to(a_v,v)) return 0;} 00519 return new inlib::value(v); 00520 00521 } else if(a_type==inlib::value::STRING) { 00522 if( (a_v.size()>=2) && (a_v[0]=='"') && (a_v[a_v.size()-1]=='"') ){ 00523 return new inlib::value(a_v.substr(1,a_v.size()-2)); 00524 } else { 00525 return new inlib::value(a_v); 00526 } 00527 00528 //} else if(a_type==inlib::value::UNSIGNED_CHAR) { 00529 // unsigned short v = 0; 00530 // if(a_v.size()) {if(!inlib::to<unsigned short>(a_v,v)) return 0;} 00531 // return new inlib::value((unsigned char)v); 00532 00533 } else if(a_type==inlib::value::UNSIGNED_SHORT) { 00534 unsigned short v = 0; 00535 if(a_v.size()) {if(!inlib::to<unsigned short>(a_v,v)) return 0;} 00536 return new inlib::value(v); 00537 } else if(a_type==inlib::value::UNSIGNED_INT) { 00538 unsigned int v = 0; 00539 if(a_v.size()) {if(!inlib::to<unsigned int>(a_v,v)) return 0;} 00540 return new inlib::value(v); 00541 00542 } else if(a_type==inlib::value::UNSIGNED_INT64) { 00543 uint64 v = 0; 00544 if(a_v.size()) {if(!inlib::to<uint64>(a_v,v)) return 0;} 00545 return new inlib::value(v); 00546 00547 } else if(a_type==inlib::value::ARRAY_FLOAT) { 00548 if(a_v.size()) return 0; 00549 inlib::value* v = new inlib::value(); 00550 v->set_type(inlib::value::ARRAY_FLOAT); 00551 return v; 00552 } else if(a_type==inlib::value::ARRAY_DOUBLE) { 00553 if(a_v.size()) return 0; 00554 inlib::value* v = new inlib::value(); 00555 v->set_type(inlib::value::ARRAY_DOUBLE); 00556 return v; 00557 //} else if(a_type==inlib::value::ARRAY_UNSIGNED_CHAR) { 00558 // if(a_v.size()) return 0; 00559 // inlib::value* v = new inlib::value(); 00560 // v->set_type(inlib::value::ARRAY_UNSIGNED_CHAR); 00561 // return v; 00562 //} else if(a_type==inlib::value::ARRAY_CHAR) { 00563 // if(a_v.size()) return 0; 00564 // inlib::value* v = new inlib::value(); 00565 // v->set_type(inlib::value::ARRAY_CHAR); 00566 // return v; 00567 } else if(a_type==inlib::value::ARRAY_SHORT) { 00568 if(a_v.size()) return 0; 00569 inlib::value* v = new inlib::value(); 00570 v->set_type(inlib::value::ARRAY_SHORT); 00571 return v; 00572 } else if(a_type==inlib::value::ARRAY_INT) { 00573 if(a_v.size()) return 0; 00574 inlib::value* v = new inlib::value(); 00575 v->set_type(inlib::value::ARRAY_INT); 00576 return v; 00577 } else if(a_type==inlib::value::ARRAY_INT64) { 00578 if(a_v.size()) return 0; 00579 inlib::value* v = new inlib::value(); 00580 v->set_type(inlib::value::ARRAY_INT64); 00581 return v; 00582 } else if(a_type==inlib::value::ARRAY_BOOL) { 00583 if(a_v.size()) return 0; 00584 inlib::value* v = new inlib::value(); 00585 v->set_type(inlib::value::ARRAY_BOOL); 00586 return v; 00587 } else if(a_type==inlib::value::ARRAY_STRING) { 00588 if(a_v.size()) return 0; 00589 inlib::value* v = new inlib::value(); 00590 v->set_type(inlib::value::ARRAY_STRING); 00591 return v; 00592 } else { 00593 return 0; 00594 } 00595 } 00596 public: 00597 std::ostream& m_out; 00598 std::string m_script; 00599 std::vector<inlib::value> m_stack; 00600 inlib::value::e_type m_cur_type; 00601 //bool fSuccess; 00602 }; 00603 00604 }} 00605 00606 #endif