class_definition.cpp

Go to the documentation of this file.
00001 
00002 
00003 #include <iomanip>
00004 #include <fstream>
00005 #include <sstream>
00006 #include "clssdf.h"
00007 
00008 using namespace std;
00009 
00010 #define TRACK 0
00011 #define USE_GETLINE 0
00012 
00013 void trap( const char *note = "") {
00014   cerr << "in trap, note = " << note << endl;
00015 }
00016 
00017 namespace class_def {
00018 
00019   const char *get_tag( int argc, const char* argv[], int argmask[], const char* tag, const char* dvalue) {
00020     if (tag[0] == '-') ++tag;
00021     int j, taglen = strlen( tag);
00022     const char *pargv;
00023 
00024     for (j=1; j<argc; ++j) {
00025       pargv = argv[j];
00026       if (pargv[0] == '-') ++pargv;
00027       if (strlen( pargv) > (size_t)taglen && memcmp( pargv, tag, taglen)==0) {
00028         argmask[j] = 1;
00029         const char *last = pargv + taglen;
00030         if (*last == '=') return last + 1;
00031         return last;
00032       }
00033     }
00034     return dvalue;
00035   }
00036 
00037   const char *find_tag( 
00038                        int argc, 
00039                        const char *argv[], 
00040                        int *argmask, 
00041                        const char *tag) 
00042   {
00043     for (int i=1; i<argc; ++i) {
00044       if (argmask[i]==0 && strcmp( argv[i], tag)==0) {
00045         argmask[i] = 1;
00046         return argv[i];
00047       }
00048     }
00049     return 0;
00050   }
00051 
00052   vector<class_definition*>  class_definition::_univ;
00053 
00054   string laststr;
00055 
00056   string substr;
00057   long lineno = 1;
00058 
00059   std::string eat_back_white( const std::string& str, const std::string& seps)
00060   {
00061     if (str.empty()) return str;
00062 
00063     std::string retval("");
00064     int found = 0;
00065     size_t i;
00066 
00067     for (i=str.size()-1;i>=0;i--) {
00068       if (seps.find_first_not_of( str[i]) < seps.size()) {
00069         found = 1;
00070         break;
00071       }
00072     }
00073     
00074     if (found) {
00075       retval = str.substr( 0, i+1);
00076     }
00077     
00078     return retval;
00079   }
00080   
00081   void Getline( istream& in, string& str) {
00082 #ifdef linux
00083     string seps(" \n\r\t");
00084     str.clear();
00085     do {
00086       if (in.eof()) {
00087         throw end_of_input();
00088       }
00089       std::getline( (istream&)in, str);
00090       str = eat_back_white( str, seps);
00091     } while (str.empty());
00092 #else
00093     const char *seps = " \n\r\t";
00094     do {
00095 #if TRACK
00096       cerr << "reading line " << lineno << endl;
00097 #endif
00098       
00099       if (in.eof()) {
00100         throw end_of_input();
00101       }
00102       getline( in, str);
00103       laststr = str;
00104       if (!str.empty()) {
00105         if (str[str.size()-1]=='\r') {
00106           str = str.substr( 0, str.size()-1);
00107         }
00108         lineno++;
00109       }
00110     } while (str.empty() || str.find_first_not_of(seps)>=str.size());
00111 #endif
00112   }
00113 
00114   string rep_spc( int n) {
00115     string retval;
00116     int i;
00117 
00118     for (i=0;i<n;i++) retval += ' ';
00119     return retval;
00120   } 
00121 
00122   string class_definition::_input_line;
00123   vector<string> class_definition::_arg_vect;
00124   vector<string> class_definition::_com_vect;
00125   const vector<string> attribute::_empty_string_vector;
00126 
00127   void class_definition::set_null() {
00128     if (_class_qualifiers.size())
00129       _class_qualifiers.erase( _class_qualifiers.begin(), _class_qualifiers.end());
00130 
00131     _name = "";
00132     _inheritance = 0;
00133   
00134     if (_parents.size())
00135       _parents.erase( _parents.begin(), _parents.end());
00136   
00137     if (_key_attributes.size())
00138       _key_attributes.erase( _key_attributes.begin(), _key_attributes.end());
00139 
00140     if (_functional_attributes.size())
00141       _functional_attributes.erase( 
00142         _functional_attributes.begin(), 
00143         _functional_attributes.end());
00144 
00145     if (_derived_attributes.size())
00146       _derived_attributes.erase( 
00147         _derived_attributes.begin(), 
00148         _derived_attributes.end());
00149 
00150     if (_other_lines_at_begining.size())
00151       _other_lines_at_begining.erase( 
00152         _other_lines_at_begining.begin(), 
00153         _other_lines_at_begining.end());
00154 
00155     if (_row_attributes.size())
00156       _row_attributes.erase( 
00157         _row_attributes.begin(), 
00158         _row_attributes.end());
00159 
00160     if (_other_lines_at_end.size())
00161       _other_lines_at_end.erase( 
00162         _other_lines_at_end.begin(), 
00163         _other_lines_at_end.end());
00164   }
00165 
00166   void class_definition::init(
00167               const std::string&                        Name                   ,
00168               int                                       Inheritance            ,
00169               const std::vector<std::string>&           Class_qualifiers       ,
00170               const std::vector<std::string>&           Parents                ,
00171               const std::vector<key_attribute>&         Key_attributes         ,
00172               const std::vector<functional_attribute>&  Functional_attributes  ,
00173               const std::vector<derived_attribute>&     Derived_attributes     ,
00174               const std::vector<std::string>&           other_lines_at_begining,
00175               const std::vector<enum_constant>&         Enum_constants         ,
00176               const std::vector<static_constant>&       Static_constants       ,
00177               const std::vector<std::string>&           other_lines_at_end     ,
00178               bool                                      Protected_constructor  ,
00179               bool                                      Singleton              )
00180   {
00181     set_null();
00182 
00183     _name                    = Name;
00184     _inheritance             = Inheritance;
00185     _class_qualifiers        = Class_qualifiers;
00186     _parents                 = Parents;
00187     _key_attributes          = Key_attributes;
00188     _functional_attributes   = Functional_attributes;
00189     _derived_attributes      = Derived_attributes;
00190     _other_lines_at_begining = other_lines_at_begining;
00191     _enum_constants          = Enum_constants;
00192     _static_constants        = Static_constants;
00193     _other_lines_at_end      = other_lines_at_end;
00194     _protected_constructor   = Protected_constructor;
00195     _singleton               = Singleton;
00196     
00197     init_calc_derived_attributes();
00198   }
00199   
00200   void class_definition::init_calc_derived_attributes() {
00201     int i, j, k, l;
00202     attribute *pattr;
00203     
00204     //trap( "starting init_calc_derived_attributes");
00205     
00206     if (_defined_attributes.size()) {
00207       _defined_attributes.erase( 
00208                                 _defined_attributes.begin(), 
00209                                 _defined_attributes.end());
00210     }
00211     
00212     if (_non_key_attributes.size()) {
00213       _non_key_attributes.erase( 
00214                                 _non_key_attributes.begin(), 
00215                                 _non_key_attributes.end());
00216     }
00217     
00218     if (_all_key_attributes.size()) {
00219       _all_key_attributes.erase( 
00220                                 _all_key_attributes.begin(), 
00221                                 _all_key_attributes.end());
00222     }
00223     
00224     if (_all_functional_attributes.size()) {
00225       _all_functional_attributes.erase( 
00226                                        _all_functional_attributes.begin(), 
00227                                        _all_functional_attributes.end());
00228     }
00229     
00230     if (_all_functional_attributes.size()) {
00231       _all_functional_attributes.erase( 
00232                                        _all_functional_attributes.begin(), 
00233                                        _all_functional_attributes.end());
00234     }
00235     
00236     if (_all_derived_attributes.size()) {
00237       _all_derived_attributes.erase( 
00238                                     _all_derived_attributes.begin(), 
00239                                     _all_derived_attributes.end());
00240     }
00241     
00242     if (_all_functional_attributes.size()) {
00243       _all_functional_attributes.erase( 
00244                                        _all_functional_attributes.begin(), 
00245                                        _all_functional_attributes.end());
00246     }
00247     
00248     if (_all_derived_attributes.size()) {
00249       _all_derived_attributes.erase( 
00250                                     _all_derived_attributes.begin(), 
00251                                     _all_derived_attributes.end());
00252     }
00253     
00254     if (_all_defined_attributes.size()) {
00255       _all_defined_attributes.erase( 
00256                                     _all_defined_attributes.begin(), 
00257                                     _all_defined_attributes.end());
00258     }
00259     
00260     if (_all_row_attributes.size()) {
00261       _all_row_attributes.erase( 
00262                                 _all_row_attributes.begin(), 
00263                                 _all_row_attributes.end());
00264     }
00265     
00266     if (_all_non_key_attributes.size()) {
00267       _all_non_key_attributes.erase( 
00268                                     _all_non_key_attributes.begin(), 
00269                                     _all_non_key_attributes.end());
00270     }
00271     
00272     for (i=0;i<_key_attributes.size();i++) {
00273       _defined_attributes.push_back( &_key_attributes[i]);
00274     }
00275     
00276     
00277     for (i=0;i<_functional_attributes.size();i++) {
00278       _defined_attributes.push_back( &_functional_attributes[i]);
00279       _non_key_attributes.push_back( &_functional_attributes[i]);
00280     }
00281     
00282     _row_attributes = _defined_attributes;
00283     for (i=0;i<_derived_attributes.size();i++) {
00284       _row_attributes.push_back( &_derived_attributes[i]);
00285       _non_key_attributes.push_back( &_derived_attributes[i]);
00286     }
00287     
00288     //********* concat key, functional and derived attributes *************
00289     if (_inheritance) {
00290       for (j=0;j<_parents.size();j++) {
00291         for (k=0;k<_univ.size();k++) { 
00292 #if 0
00293           cerr << "_parents[j=" << j << "]     = " << _parents[j] << endl;
00294           cerr << "_univ[k=" << k << "]->_name = " << _univ[k]->_name << endl;
00295           cerr << "strcmp = " << strcmp( _parents[j].c_str(), _univ[k]->_name.c_str()) << endl;
00296 #endif
00297           if (_parents[j] == _univ[k]->_name) {
00298             for (l=0;l<_univ[k]->_all_key_attributes.size();l++) {
00299               _all_key_attributes.push_back( _univ[k]->_all_key_attributes[l]);
00300             }
00301           }
00302         }
00303       }
00304     }
00305     for (i=0;i<_key_attributes.size();i++) {
00306       _all_key_attributes.push_back( &_key_attributes[i]);
00307     }
00308     
00309     if (_inheritance) {
00310       for (j=0;j<_parents.size();j++) {
00311         for (k=0;k<_univ.size();k++) {
00312           if (_parents[j] == _univ[k]->_name) {
00313             for (l=0;l<_univ[k]->_all_functional_attributes.size();l++) {
00314               _all_functional_attributes.push_back( 
00315                                                    _univ[k]->_all_functional_attributes[l]);
00316             }
00317           }
00318         }
00319       }
00320     }
00321     for (i=0;i<_functional_attributes.size();i++) {
00322       _all_functional_attributes.push_back( &_functional_attributes[i]);
00323     }
00324     
00325     if (_inheritance) {
00326       for (j=0;j<_parents.size();j++) {
00327         for (k=0;k<_univ.size();k++) {
00328           if (_parents[j] == _univ[k]->_name) {
00329             for (l=0;l<_univ[k]->_all_derived_attributes.size();l++) {
00330               _all_derived_attributes.push_back( 
00331                                                 _univ[k]->_all_derived_attributes[l]);
00332             }
00333           }
00334         }
00335       }
00336     }
00337     for (i=0;i<_derived_attributes.size();i++) {
00338       _all_derived_attributes.push_back( &_derived_attributes[i]);
00339     }
00340     
00341     //****************** concat defined, non_key, row attributes **********
00342     for (i=0;i<_all_key_attributes.size();i++) {
00343       _all_defined_attributes.push_back( _all_key_attributes[i]);
00344     }
00345     
00346     
00347     for (i=0;i<_all_functional_attributes.size();i++) {
00348       _all_defined_attributes.push_back( _all_functional_attributes[i]);
00349       _all_non_key_attributes.push_back( _all_functional_attributes[i]);
00350     }
00351     
00352     _all_row_attributes = _all_defined_attributes;
00353     for (i=0;i<_all_derived_attributes.size();i++) {
00354       pattr = _all_derived_attributes[i];
00355       _all_row_attributes.push_back( pattr);
00356       _all_non_key_attributes.push_back( pattr);
00357     }
00358   }  
00359   
00360   int class_definition::is_white( char c) {
00361     static int is_first = 1, length_seps=0;
00362     static char seps[] = " \t\r\n ";
00363     int i;
00364     
00365     if (is_first) {
00366       length_seps = strlen( seps);
00367       seps[length_seps-1]=EOF;
00368       is_first = 0;
00369     }
00370     
00371     for (i=0;i<length_seps;i++) {
00372       if (seps[i]==c) {
00373         return 1;
00374       }
00375     }
00376     
00377     return 0;
00378   }
00379   
00380   void class_definition::get_arg_vect( 
00381                                       istream& in, 
00382                                       vector<string>& strvect,
00383                                       vector<string>& comments) 
00384   {
00385     unsigned offset;
00386     
00387     if (comments.size()>0) comments.erase( comments.begin(), comments.end());
00388     if (strvect.size()>0)   strvect.erase( strvect.begin(), strvect.end());
00389     
00390     do {
00391       Getline( in, _input_line);
00392       
00393       if (_input_line[0]=='#') {
00394         substr = _input_line.substr( 1, _input_line.size());
00395         throw comment( substr);
00396       } 
00397       
00398       offset = _input_line.find_first_not_of( " \t");
00399       //cerr << "offset = " << offset << endl;
00400       if (_input_line.size()>=2 && offset <= (_input_line.size()-2)) {
00401         substr = _input_line.substr( offset, 2);
00402         //cerr << "substr = " << substr << endl;
00403       } else {
00404         substr = "";
00405       }
00406       if (substr == "//") {
00407         comments.push_back( _input_line);
00408       }
00409     } while (substr == "//" || _input_line.empty());
00410     
00411     string str;
00412     
00413     istringstream instr( _input_line);
00414     
00415     while (instr >> str) {
00416       
00417       // remove comments from end of line
00418       if (str.size()>=2) {
00419         substr = str.substr( 0, 2);
00420         if (substr == "//") {
00421           break;
00422         }
00423       }
00424       
00425       strvect.push_back( str);
00426     }
00427   }
00428   
00429   void class_definition::read_num_param( 
00430                                         istream&    from, 
00431                                         const char *param_name,
00432                                         int&        param)
00433   {
00434     const char *funcname = "read_num_param";
00435     
00436     get_arg_vect( from, _arg_vect, _com_vect);
00437     if (_arg_vect.size()!=1) {
00438       cerr << param_name << " is not defined correctly" << endl;
00439       cerr << "line = {" << _input_line << "}" << endl;
00440       throw ( std::invalid_argument( error_message( 
00441                                       _class_name(), 
00442                                       funcname, 
00443                                       __FILE__,
00444                                       _error_msg,
00445                                       __LINE__, 
00446                                       _erno   ,
00447                                       lineno  ).what()));
00448     }
00449     param = atol( _arg_vect[0].c_str());
00450     if (param < 0) {
00451       cerr << param_name << " is < 0" << endl;
00452       cerr << "line = {" << _input_line << "}" << endl;
00453       throw ( std::invalid_argument( error_message( 
00454                                       _class_name(), 
00455                                       funcname, 
00456                                       __FILE__,
00457                                       _error_msg,
00458                                       __LINE__, 
00459                                       _erno   ,
00460                                       lineno  ).what()));
00461     }
00462   }
00463   
00464   istream& operator >> ( istream& from, class_definition& class_def)
00465   {
00466     class_def.Read( from);
00467     return from;
00468   }
00469   
00470   istream& operator >> ( istream& from, attribute& attr)
00471   {
00472     const char *funcname = "istream& operator >> "
00473       "( istream& from, attribute& attr)";
00474     string Type, name, null_value;
00475     int Reference, Max_length;
00476     
00477     class_definition::get_arg_vect( from, class_definition::_arg_vect, class_definition::_com_vect);
00478     
00479     if (class_definition::_arg_vect.size()<3 ||
00480         class_definition::_arg_vect.size()>5 )
00481       {
00482         cerr << "wrong # of arguments in line = {" <<
00483           class_definition::_input_line << "} in function " << funcname << endl;
00484         throw ( std::invalid_argument( error_message(  
00485                                                          attr.get_class_name(), 
00486                                                          funcname, 
00487                                                          __FILE__,
00488                                                          "wrong # of arguments",
00489                                                          __LINE__, 
00490                                                          1       ,
00491                                                          lineno  ).what()));
00492       }
00493     
00494     Type      = class_definition::_arg_vect[0];
00495     Reference = atol( class_definition::_arg_vect[1].c_str());
00496     name      = class_definition::_arg_vect[2];
00497     
00498     if (class_definition::_arg_vect.size() >= 4) {
00499       null_value = class_definition::_arg_vect[3];
00500     }
00501     
00502     if (class_definition::_arg_vect.size() == 5 && Type=="string") {
00503       Max_length = ::atol( class_definition::_arg_vect[4].c_str());
00504     } else if (class_definition::_arg_vect.size() == 5 && Type!="string") {
00505       cerr << "Too many arguments, max_length only" <<
00506         " allowed for string = {" <<
00507         class_definition::_input_line  << 
00508         "} in function " << funcname   << endl;
00509       throw ( std::invalid_argument( error_message(  
00510                                                        attr.get_class_name(), 
00511                                                        funcname, 
00512                                                        __FILE__,
00513                                                        "wrong # of arguments",
00514                                                        __LINE__, 
00515                                                        1       ,
00516                                                        lineno  ).what()));
00517     } else {
00518       Max_length = 0;
00519     }
00520     
00521     
00522     // trap();
00523     
00524     attr.init( Type, Reference, name, null_value, Max_length, class_definition::_com_vect);
00525     
00526     return from;
00527   }
00528   
00529   istream& operator >> ( istream& from, derived_attribute& attr)
00530   {
00531     const char *funcname = "istream& operator >> "
00532       "( istream& from, derived_attribute& attr)";
00533     string Type, name, null_value;
00534     int Max_length;
00535     
00536     class_definition::get_arg_vect( from, class_definition::_arg_vect, class_definition::_com_vect);
00537     
00538     if (class_definition::_arg_vect.size()<2 ||
00539         class_definition::_arg_vect.size()>4 )
00540       {
00541         cerr << "wrong # of arguments in line = {" <<
00542           class_definition::_input_line << "} in function " << funcname << endl;
00543         throw ( std::invalid_argument( error_message(  
00544                                                          attr.get_class_name(), 
00545                                                          funcname, 
00546                                                          __FILE__,
00547                                                          "wrong # of arguments",
00548                                                          __LINE__, 
00549                                                          1       ,
00550                                                          lineno  ).what()));
00551       }
00552     
00553     Type = class_definition::_arg_vect[0];
00554     name = class_definition::_arg_vect[1];
00555     
00556     if (class_definition::_arg_vect.size() >= 3) {
00557       null_value = class_definition::_arg_vect[2];
00558     }
00559     if (class_definition::_arg_vect.size() == 4 && Type=="string") {
00560       Max_length = ::atol( class_definition::_arg_vect[3].c_str());
00561     } else 
00562       if (class_definition::_arg_vect.size() == 4 && Type!="string") {
00563         cerr << "Too many arguments, max_length only" <<
00564           " allowed for string = {" <<
00565           class_definition::_input_line  << 
00566           "} in function " << funcname   << endl;
00567         throw ( std::invalid_argument( error_message( 
00568                                         attr.get_class_name(), 
00569                                         funcname, 
00570                                         __FILE__,
00571                                         "wrong # of arguments",
00572                                         __LINE__, 
00573                                         1       ,
00574                                         lineno  ).what()));
00575       } else {
00576         Max_length = 0;
00577       }
00578     
00579     attr.init( Type, 0, name, null_value, Max_length, class_definition::_com_vect);
00580     
00581     return from;
00582   }
00583   
00584   istream& operator >> ( istream& from, enum_constant& attr)
00585   {
00586     const char *funcname = "istream& operator >> "
00587       "( istream& from, enum_constant& attr)";
00588     string name, null_value;
00589     
00590     class_definition::get_arg_vect( from, class_definition::_arg_vect, class_definition::_com_vect);
00591     
00592     if (class_definition::_arg_vect.size()!=2)
00593       {
00594         cerr << "wrong # of arguments in line = {" <<
00595           class_definition::_input_line << "} in function " << funcname << endl;
00596         throw  ( std::invalid_argument( error_message( 
00597                                                           attr.get_class_name(), 
00598                                                           funcname, 
00599                                                           __FILE__,
00600                                                           "wrong # of arguments",
00601                                                           __LINE__, 
00602                                                           1       ,
00603                                                           lineno  ).what()));
00604       }
00605     
00606     name       = class_definition::_arg_vect[0];
00607     null_value = class_definition::_arg_vect[1];
00608     
00609     attr.init( "int", 0, name, null_value, 0, class_definition::_com_vect);
00610     
00611     return from;
00612   }
00613   
00614   istream& operator >> ( istream& from, static_constant& attr)
00615   {
00616     const char *funcname = "istream& operator >> "
00617       "( istream& from, static_constant& attr)";
00618     string Type, name, null_value;
00619     
00620     class_definition::get_arg_vect( from, class_definition::_arg_vect, class_definition::_com_vect);
00621     
00622     if (class_definition::_arg_vect.size()!=3 && class_definition::_arg_vect.size()!=2)
00623       {
00624         cerr << "wrong # of arguments in line = {" <<
00625           class_definition::_input_line << "} in function " << funcname << endl;
00626         throw ( std::invalid_argument( error_message( 
00627                                                          attr.get_class_name()    , 
00628                                                          funcname, 
00629                                                          __FILE__,
00630                                                          "wrong # of arguments",
00631                                                          __LINE__, 
00632                                                          1       ,
00633                                                          lineno  ).what()));
00634       }
00635     
00636     Type = class_definition::_arg_vect[0];
00637     name = class_definition::_arg_vect[1];
00638     if (class_definition::_arg_vect.size()==3) {
00639       null_value = class_definition::_arg_vect[2];
00640     } else {
00641       null_value = "no null value";
00642     }
00643     
00644     attr.init( Type, 0, name, null_value, 0, class_definition::_com_vect);
00645     
00646     return from;
00647   }
00648   
00649   int attribute::_allow_custom_classes = 0;
00650   int attribute::_copy_constructor = 1;
00651   int attribute::_check_attributes = 1;
00652   
00653   void attribute::put_allow_custom_classes( int newval) {
00654     _allow_custom_classes = newval;
00655   }
00656   
00657   int attribute::get_allow_custom_classes() {
00658     return _allow_custom_classes;
00659   }
00660   
00661   void attribute::put_copy_constructor( int newval) {
00662     _copy_constructor = newval;
00663   }
00664   
00665   void attribute::put_check_attributes( int newval) {
00666     _check_attributes = newval;
00667   }
00668   
00669   int attribute::get_copy_constructor() {
00670     return _copy_constructor;
00671   }
00672   
00673   int attribute::get_check_attributes() {
00674     return _check_attributes;
00675   }
00676   
00677   string attribute::get_Name() const {
00678     string retval(_name);
00679     retval[0] = toupper(retval[0]);
00680     return retval;
00681   }
00682   
00683   int attribute::is_custom_class() const {
00684     
00685     if (_type.size()>11 && (_type.substr(0,11)=="vector" || _type.substr(0,10)=="my::vector"))
00686       return 0;
00687     
00688     if (_type.size()>0 && 
00689         _type!="bool" && 
00690         _type!="char" && 
00691         _type!="int" && 
00692         _type!="long" &&
00693         _type!="string" && 
00694         _type!="double" &&
00695         _type!="size_t" &&
00696         _type!="uint8_t" &&
00697         _type!="uint16_t" &&
00698         _type!="uint32_t" &&
00699         _type!="uint64_t" &&
00700         _type!="uint8_t" &&
00701         _type!="uint16_t" &&
00702         _type!="uint32_t" &&
00703         _type!="uint64_t" &&
00704         _type!="uint8_t*" &&
00705         _type!="uint16_t*" &&
00706         _type!="uint32_t*" &&
00707         _type!="uint64_t*" &&
00708         _type!="uint8_t*" &&
00709         _type!="uint16_t*" &&
00710         _type!="uint32_t*" &&
00711         _type!="uint64_t*" &&
00712         _type!="int8_t" &&
00713         _type!="int16_t" &&
00714         _type!="int32_t" &&
00715         _type!="int64_t" &&
00716         _type!="int8_t" &&
00717         _type!="int16_t" &&
00718         _type!="int32_t" &&
00719         _type!="int64_t" &&
00720         _type!="int8_t*" &&
00721         _type!="int16_t*" &&
00722         _type!="int32_t*" &&
00723         _type!="int64_t*" &&
00724         _type!="int8_t*" &&
00725         _type!="int16_t*" &&
00726         _type!="int32_t*" &&
00727         _type!="int64_t*" )
00728       {
00729         return 1;
00730       }
00731     
00732     return 0;
00733   }
00734   
00735   string attribute::input_format_of_name() const {
00736     string retval;
00737     string Name( _name);
00738     
00739     Name[0] = toupper( Name[0]);
00740     
00741     //bool is_const = _reference == const_reference || _type=="string" || 
00742     //  _type.substr(0,11)=="vector" || 
00743     //  _type.substr(0,10)=="my::vector"  || is_custom_class();
00744     
00745     bool is_const = _reference == const_reference;
00746     
00747     if (is_const) 
00748       {
00749         retval = "const " + _type + "& " + Name;
00750       } else if (_reference == value) {
00751       retval = _type + " " + Name;
00752     }
00753     
00754     return retval;
00755   }
00756   
00757   string attribute::storage_format_of_name() const {
00758     return "_" + _name;
00759   }
00760   
00761   string class_definition::_output_format = "";
00762   bool class_definition::_lower_case_mysql_names = false;
00763   int class_definition::_error_function = 0;
00764   int class_definition::_domain_error = 0;
00765   int class_definition::_back_white = 0;
00766   
00767   ostream& operator<<( ostream& os, const class_definition& clssdf) {
00768     clssdf.print( os);
00769     return os;
00770   }
00771   
00772   ostream& operator<<( ostream& s, const attribute& atr) {
00773     s << "{" ;
00774     s << atr._type       << ", ";
00775     s << atr._reference  << ", ";
00776     s << atr._name       << ", ";
00777     s << atr._null_value << ", ";
00778     s << atr._max_length << "}";
00779     
00780     return s;
00781   }
00782   
00783   ostream& operator<<( ostream& s, const derived_attribute& atr) {
00784     s << "{" ;
00785     s << atr._type       << ", ";
00786     s << atr._reference  << ", ";
00787     s << atr._name       << ", ";
00788     s << atr._max_length << "}";
00789     
00790     return s;
00791   }
00792   
00793   ostream& operator<<( ostream& s, const enum_constant& atr) {
00794     s << "{" ;
00795     s << atr._name      << ", ";
00796     s << atr._null_value<< "}";
00797     
00798     return s;
00799   }
00800   
00801   ostream& operator<<( ostream& s, const static_constant& atr) {
00802     s << "{" ;
00803     s << atr._type      << ", ";
00804     s << atr._name      << ", ";
00805     s << atr._null_value<< "}";
00806     
00807     return s;
00808   }
00809   
00810   int class_definition::_erno = 0;
00811   const char * class_definition::_error_msg = "";
00812   
00813   
00814   void class_definition::Read( istream &from)
00815   {
00816     int i;
00817     const char *funcname = "void class_definition::Read( istream &from)";
00818     
00819     string Class_name;
00820     int Inheritance;
00821     vector<string> Class_qualifiers;
00822     bool Protected_constructor = false;
00823     bool Singleton = false;
00824     
00825     // read class name
00826     get_arg_vect( from, _arg_vect, _com_vect);
00827     if (_arg_vect.size() < 2)
00828       {
00829         _error_msg = "first line of class definition must have at least 2 argments";
00830         cerr << "input line = {" << _input_line << "}" << endl;
00831         cerr << "input line number = " << lineno << endl;
00832         exit(1);
00833         /*throw std::invalid_argument( error_message( 
00834                                             get_class_name(),
00835                                              funcname, 
00836                                              _error_msg,
00837                                              __FILE__, 
00838                                              __LINE__, 
00839                                              1       ).what());*/
00840       }
00841     Class_name = _arg_vect[0];
00842     Inheritance = atol( _arg_vect[1].c_str());
00843     
00844     if (_arg_vect.size()>2) {
00845       Class_qualifiers.push_back( _arg_vect[2]);
00846       
00847       if (_arg_vect.size()>3) {
00848         if (_arg_vect[3] == "protected_constructor") {
00849           Protected_constructor = true;
00850         } else if (_arg_vect[3] == "singleton") {
00851           Protected_constructor = true;
00852           Singleton = true;
00853         } else {
00854           cerr << "class qualifer = " << _arg_vect[3] << " is not recognized" << endl;
00855           exit(1);
00856         }
00857       }
00858     }
00859     
00860     try {  
00861       
00862       vector<string> Parents;
00863       if (Inheritance) {
00864         int number_parents;
00865         
00866         read_num_param(
00867                        from,
00868                        "number_parents",
00869                        number_parents);
00870         for (i=0;i<number_parents;i++) {
00871           Getline( from, _input_line);
00872           //Parents.push_back( eat_white( _input_line, " "));
00873           Parents.push_back( eat_back_white( _input_line, " "));
00874         }
00875       }
00876       
00877       // read key attributes
00878       int number_of_key_attributes;
00879       read_num_param( 
00880                      from, 
00881                      "number_of_key_attributes", 
00882                      number_of_key_attributes);
00883       vector<key_attribute> Key_attributes(number_of_key_attributes);
00884       for (i=0;i<number_of_key_attributes;i++) {
00885         from >> Key_attributes[i];
00886       }
00887       
00888       
00889       // read functional attributes
00890       int number_of_functional_attributes;
00891       read_num_param( 
00892                      from,
00893                      "number_of_functional_attributes",
00894                      number_of_functional_attributes);
00895       
00896       vector<functional_attribute> 
00897         Functional_attributes(number_of_functional_attributes);
00898       for (i=0;i<number_of_functional_attributes;i++) {
00899         from >> Functional_attributes[i];
00900       }
00901       
00902       // read derived attributes
00903       int number_of_derived_attributes;
00904       read_num_param( 
00905                      from,
00906                      "number_of_derived_attributes",
00907                      number_of_derived_attributes);
00908       
00909       vector<derived_attribute> 
00910         Derived_attributes(number_of_derived_attributes);
00911       for (i=0;i<number_of_derived_attributes;i++) {
00912         from >> Derived_attributes[i];
00913       }
00914       
00915       // read # of other lines at begining
00916       int number_of_other_lines_at_begining;
00917       read_num_param(
00918                      from,
00919                      "number_of_other_lines_at_begining",
00920                      number_of_other_lines_at_begining);
00921       vector<string> 
00922         other_lines_at_begining(number_of_other_lines_at_begining);
00923       for (i=0;i<number_of_other_lines_at_begining;i++) {
00924         Getline( from, other_lines_at_begining[i]);
00925       }
00926       
00927       // read enum constants
00928       int number_of_enum_constants;
00929       read_num_param( 
00930                      from,
00931                      "number_of_enum_constants",
00932                      number_of_enum_constants);
00933       
00934       vector<enum_constant> 
00935         Enum_constants(number_of_enum_constants);
00936       for (i=0;i<number_of_enum_constants;i++) {
00937         from >> Enum_constants[i];
00938       }
00939       
00940       // read static constants
00941       int number_of_static_constants;
00942       read_num_param( 
00943                      from,
00944                      "number_of_static_constants",
00945                      number_of_static_constants);
00946       
00947       vector<static_constant> 
00948         Static_constants(number_of_static_constants);
00949       for (i=0;i<number_of_static_constants;i++) {
00950         from >> Static_constants[i];
00951       }
00952       
00953       // read # of other lines
00954       int number_of_other_lines_at_end;
00955       read_num_param(
00956                      from,
00957                      "number_of_other_lines_at_end",
00958                      number_of_other_lines_at_end);
00959       vector<string> 
00960         other_lines_at_end(number_of_other_lines_at_end);
00961       for (i=0;i<number_of_other_lines_at_end;i++) {
00962         Getline( from, other_lines_at_end[i]);
00963       }
00964       
00965       init(
00966            Class_name           ,
00967            Inheritance          ,
00968            Class_qualifiers     ,
00969            Parents              ,
00970            Key_attributes       ,
00971            Functional_attributes,
00972            Derived_attributes   ,
00973            other_lines_at_begining,
00974            Enum_constants       ,
00975            Static_constants     ,
00976            other_lines_at_end   ,
00977            Protected_constructor,
00978            Singleton);
00979     } catch (...) {
00980       cerr << "error in reading class" << endl;
00981       exit( -1);
00982     }
00983   }
00984   
00985   int attribute::_erno = 0;
00986   const char *attribute::_error_msg = "";
00987   
00988   int attribute::check_attributes(
00989                                   const string& Type,
00990                                   int                Reference,
00991                                   const string& Name,
00992                                   const string& Null_value,
00993                                   int                Max_length,
00994                                   const vector<string>& Comments)
00995   {
00996     _erno = 0;
00997     _error_msg = "";
00998     
00999     if (Type.size()>0 && !_allow_custom_classes &&
01000         !(Type=="char" || Type=="int" || Type=="long" || Type=="double" || 
01001           Type=="string" || Type=="std::string" ||Type.substr(0,11)=="vector" || 
01002           Type.substr(0,10)=="my::vector")) {
01003       cerr << "Type = " << Type << " is not recognized" << endl;
01004       _error_msg = "Type has an illegal value";
01005       _erno = __LINE__;
01006     }
01007     
01008     if (Reference < value || Reference > const_reference) {
01009       _error_msg = "Reference out of range";
01010       _erno = __LINE__;
01011     }
01012     
01013     if (Max_length<0) {
01014       _error_msg = "Max_length<0";
01015       _erno = __LINE__;
01016     }
01017     
01018     return _erno;
01019   }
01020   
01021   void attribute::init_calc_derived_attributes() {
01022     if (_null_value.size()==0 && _type.size()>0) {
01023       if (_type=="char" || _type=="long" || _type=="int" || _type=="double") {
01024         _null_value = "0";
01025       } else if (_type=="string" || _type.substr(0,11)=="vector") {
01026         _null_value = "\"\"";
01027       } else {
01028         cerr << "null value must be specified for custom classes" << endl;
01029         error();
01030       }
01031     }
01032   }
01033   
01034   void class_definition::print_throw_message(
01035                                              const string& funcname,
01036                                              int nspc,
01037                                              ostream& os) const
01038   {
01039     if (_error_function) {
01040       os << rep_spc( nspc) << "error( " << "\"error_message={%s}, erno=%ld in function=%s, file=%s, line=%ld\\n\"," << endl;
01041       os << rep_spc( nspc+2) <<" _error_msg, (int)_erno, funcname, __FILE__, (int)__LINE__);" << endl;
01042     } else if (_domain_error) {
01043       os << rep_spc(nspc  ) <<  "std::cerr << _error_msg << std::endl;" << endl;
01044       os << rep_spc(nspc  ) <<  "throw std::domain_error( stringify(" << endl;
01045       os << rep_spc(nspc+2) <<  "funcname," << endl;
01046       os << rep_spc(nspc+2) <<  "__FILE__," << endl;
01047       os << rep_spc(nspc+2) <<  "_error_msg," << endl;
01048       os << rep_spc(nspc+2) <<  "__LINE__," << endl;
01049       os << rep_spc(nspc+2) <<  "_erno   ));"<< endl;
01050     }
01051   }
01052   
01053   void class_definition::print( ostream& os) const {
01054     int format_found = 0;
01055     if (_output_format == "simple_output") {
01056       format_found = 1;
01057       print_simple_output( os); 
01058     } else if (_output_format == "header_output") {
01059       format_found = 1;
01060       print_header_output( os);
01061     }
01062     
01063     if (format_found) return;
01064     
01065     const char *p;
01066     if (::strstr( _output_format.c_str(), "init_static_attributes")!=NULL) {
01067       format_found = 1;
01068       print_init_static_attributes( os);
01069     }
01070     if ((p = ::strstr( _output_format.c_str(), "exists"))!=NULL) {
01071       if (p ==_output_format.c_str() || p[-1] != '_') {
01072         format_found = 1;
01073         print_exists( os);
01074       }
01075     }
01076     if ((p = ::strstr( _output_format.c_str(), "singleton_select"))!=NULL) {
01077       if (p ==_output_format.c_str() || p[-1] != '_') {
01078         format_found = 1;
01079         print_singleton_select( os);
01080       }
01081     }
01082     if ((p = ::strstr( _output_format.c_str(), "insert"))!=NULL) {
01083       if (p ==_output_format.c_str() || p[-1] != '_') {
01084         format_found = 1;
01085         print_insert( os);
01086       }
01087     }
01088     
01089     if ((p = ::strstr( _output_format.c_str(), "update"))!=NULL) {
01090       if (p ==_output_format.c_str() || p[-1] != '_') {
01091         format_found = 1;
01092         print_update( os);
01093       }
01094     }
01095 
01096     if (::strstr( _output_format.c_str(), "mysql_exists")!=NULL) {
01097       format_found = 1;
01098       print_mysql_exists( os);
01099     }
01100     
01101     if (::strstr( _output_format.c_str(), "mysql_delete")!=NULL) {
01102       format_found = 1;
01103       print_mysql_delete( os);
01104     }
01105     
01106     if (::strstr( _output_format.c_str(), "mysql_create_table")!=NULL) {
01107       format_found = 1;
01108       print_mysql_create_table( os);
01109     }
01110     
01111     if (::strstr( _output_format.c_str(), "mysql_insert")!=NULL) {
01112       format_found = 1;
01113       print_mysql_insert( os);
01114     }
01115     
01116     if (::strstr( _output_format.c_str(), "mysql_update")!=NULL) {
01117       format_found = 1;
01118       print_mysql_update( os);
01119     }
01120 
01121     if (::strstr( _output_format.c_str(), "mysql_insert_or_update")!=NULL) {
01122       format_found = 1;
01123       print_mysql_insert_or_update( os);
01124     }
01125 
01126     if (::strstr( _output_format.c_str(), "mysql_singleton_select")!=NULL) {
01127       format_found = 1;
01128       print_mysql_singleton_select( os);
01129     }
01130     
01131     if (::strstr( _output_format.c_str(), "read_binary")!=NULL) {
01132       format_found = 1;
01133       print_read_binary( os);
01134     }
01135     if (::strstr( _output_format.c_str(), "write_binary")!=NULL) {
01136       format_found = 1;
01137       print_write_binary( os);
01138     }
01139     if (::strstr( _output_format.c_str(), "recv_binary")!=NULL) {
01140       format_found = 1;
01141       print_recv_binary( os);
01142     }
01143     if (::strstr( _output_format.c_str(), "send_binary")!=NULL) {
01144       format_found = 1;
01145       print_send_binary( os);
01146     }
01147     if (::strstr( _output_format.c_str(), "map_by_offset")!=NULL) {
01148       format_found = 1;
01149       print_map_by_offset( os);
01150     }
01151     
01152     
01153     if (!format_found) {
01154       cerr << "format = " << _output_format << " is not recognized" << endl;
01155       error();
01156     }
01157   }
01158   
01159   void error() {
01160     cerr << "function class_def::error is calling exit(1)" << endl;
01161     cerr << "lineno  = " << lineno << endl;
01162     cerr << "laststr = {" << laststr << "}" << endl;
01163     exit(1);
01164   }
01165   
01166   string print_stringify() {
01167     ostringstream oss;
01168     
01169     oss << "#ifndef stringify_defined" << endl;
01170     oss << "#define stringify_defined" << endl;
01171     oss << "#include <iostream>" << endl;
01172     oss << "#include <sstream>" << endl;
01173     oss << "#include <string>" << endl;
01174     oss << "#include <stdexcept>" << endl;
01175     oss << "" << endl;
01176     oss << "inline std::string stringify(" << endl;
01177     oss << "                 const char *funcname," << endl;
01178     oss << "                 const char* _file," << endl;
01179     oss << "                 const char *_error_msg," << endl;
01180     oss << "                 int _line," << endl;
01181     oss << "                 int _erno)" << endl;
01182     oss << "{" << endl;
01183     oss << "  std::ostringstream o;" << endl;
01184     oss << "  o << _error_msg " << endl;
01185     oss << "    <<  \" in function \" " << endl;
01186     oss << "    << funcname " << endl;
01187     oss << "    << \" at line \" " << endl;
01188     oss << "    << _line << " << endl;
01189     oss << "    \" of file \" " << endl;
01190     oss << "    << _file;" << endl;
01191     oss << "" << endl;
01192     oss << "  return o.str();" << endl;
01193     oss << "}" << endl;
01194     oss << "#endif" << endl;
01195     
01196     return oss.str();
01197   }
01198 
01199   std::string class_definition::eat_white( const std::string& str, const std::string& seps)
01200   {
01201     std::string retval;
01202     size_t i, j;
01203     
01204 #if BUG
01205     std::cerr << "seps = {" << seps << "}" << endl;
01206 #endif
01207     
01208     for (i=0;i<str.size();i++) {
01209       j = seps.find_first_of( str[i]);
01210       
01211 #if BUG
01212       std::cerr << "str[i]={" << str[i] << "} j=" << j << endl;
01213 #endif
01214       
01215       if (j>=seps.size()) {
01216         // < seps.size()
01217         retval += str[i];
01218       }
01219     }
01220     
01221     return retval;
01222   }
01223  
01224   std::string class_definition::eat_back_white( const std::string& str, const std::string& seps)
01225   {
01226     if (str.empty()) return str;
01227 
01228     std::string retval("");
01229     int found = 0;
01230     size_t i;
01231     
01232     for (i=str.size()-1;i>=0;i--) {
01233       if (seps.find_first_not_of( str[i]) < seps.size()) {
01234         found = 1;
01235         break;
01236       }
01237     }
01238     
01239     if (found) {
01240       retval = str.substr( 0, i+1);
01241     }
01242     
01243     return retval;
01244   }
01245 
01246   int class_definition::stricmp( const char *lhs, const char *rhs) {
01247     int diff;
01248     for (;;) {
01249       diff = toupper( *lhs) - toupper( *rhs);
01250       if (diff) return diff;
01251       if (*lhs == 0) break;
01252       lhs++;
01253       rhs++;
01254     }
01255     return 0;
01256   }
01257 
01258   bool class_definition::is_string( const char * str) {
01259     if (stricmp( str, "string")==0 ||
01260         stricmp( str, "std::string")==0)
01261       {
01262         return true;
01263       }
01264     return false;
01265   }
01266   
01267   const char *class_definition::int_alias[] = {
01268     "int",
01269     "long",
01270     "size_t",
01271     "uint",
01272     "ulong",
01273     "long long",
01274     "int8_t",
01275     "int16_t",
01276     "int32_t",
01277     "int64_t",
01278     "uint8_t",
01279     "uint16_t",
01280     "uint32_t",
01281     "uint64_t",
01282     ""
01283   };
01284 
01285   bool class_definition::is_int( const char *str) {
01286     for (size_t i=0; int_alias[i][0]!=0; ++i) {
01287       if (stricmp( str, int_alias[i]) == 0) return true;
01288     }
01289     return false;
01290   }
01291 
01292   const char *class_definition::double_alias[] = {
01293     "double",
01294     "long double",
01295     "float",
01296     "real",
01297     ""
01298   };
01299 
01300   bool class_definition::is_double( const char *str) {
01301     for (size_t i=0; double_alias[i][0]!=0; ++i) {
01302       if (stricmp( str, double_alias[i]) == 0) return true;
01303     }
01304     return false;
01305   }
01306 
01307   void class_definition::print_mysql_create_table( std::ostream& os) const {
01308     os << "DROP TABLE IF EXISTS `" << _name << "`;" << endl;
01309     os << endl;
01310     os << "create table " << _name << " (" << endl;
01311     
01312     std::vector<attribute*>::const_iterator pap = _all_defined_attributes.begin();
01313     int width = 0;
01314 
01315     for (;pap != _all_defined_attributes.end(); ++pap) {
01316       if ((*pap)->get_name().size() > width) {
01317         width = (*pap)->get_name().size();
01318       }
01319     }
01320     width += 3;
01321 
01322     bool first_row = true;
01323 
01324     std::vector<attribute*>::const_iterator pa = _all_key_attributes.begin();
01325 
01326     for (; pa != _all_key_attributes.end(); ++pa) {
01327       if (first_row) {
01328         first_row = false;
01329       } else {
01330         os << "," << endl;
01331       }
01332 
01333       os << "   " << setiosflags(ios::left) << setw(width) << (*pa)->get_name() << "   ";
01334      
01335       if (is_int( (*pa)->get_type().c_str())) {
01336         os << "integer        NOT NULL";
01337       }
01338 
01339       if (is_double( (*pa)->get_type().c_str())) {
01340         os << "real           NOT NULL";
01341       }
01342 
01343       if (is_string( (*pa)->get_type().c_str())) {
01344         os << "varchar(255) NOT NULL";
01345       }
01346     }
01347 
01348     if (!_all_functional_attributes.empty()) {
01349 
01350       pa  = _all_functional_attributes.begin();
01351       for (; pa != _all_functional_attributes.end(); ++pa) {
01352 
01353         if (first_row) {
01354           first_row = false;
01355         } else {
01356           os << "," << endl;
01357         }
01358 
01359         if (!_all_key_attributes.empty() && pa == _all_functional_attributes.begin()) {
01360           os << endl;
01361         }
01362 
01363         os << "   " << setiosflags(ios::left) << setw(width) << (*pa)->get_name() << "   ";
01364      
01365         if (is_int( (*pa)->get_type().c_str())) {
01366           os << "integer        default   " << (*pa)->get_null_value();
01367         }
01368 
01369         if (is_double( (*pa)->get_type().c_str())) {
01370           os << "real           default   " << (*pa)->get_null_value();
01371         }
01372 
01373         if (is_string( (*pa)->get_type().c_str())) {
01374           os << "varchar(255) default   " << (*pa)->get_null_value() << "";
01375         }
01376       }
01377     }   
01378 
01379     if (!_all_key_attributes.empty()) {    
01380       os << "," << endl << endl;
01381 
01382       os << "   primary key( ";
01383 
01384       pa = _all_key_attributes.begin();
01385       
01386       for (; pa != _all_key_attributes.end();) {
01387         os << (*pa)->get_name();
01388         ++pa;
01389         if (pa == _all_key_attributes.end()) break;
01390         os << ", ";
01391       }
01392       os << ")" << endl;
01393     }
01394     os << ") Engine=MyISAM;" << endl << endl;
01395   }  
01396 
01397   void class_definition::print_map_by_offset( std::ostream& os ) const {
01398     print_tag( os, "map_by_offset", "cstio::", "");
01399   }   
01400 }

Generated on Tue Jul 14 12:22:31 2009 for cstpp by  doxygen 1.5.1