inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/columns
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines