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
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
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
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
00400 if (_input_line.size()>=2 && offset <= (_input_line.size()-2)) {
00401 substr = _input_line.substr( offset, 2);
00402
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
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
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
00742
00743
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
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
00834
00835
00836
00837
00838
00839
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
00873 Parents.push_back( eat_back_white( _input_line, " "));
00874 }
00875 }
00876
00877
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
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
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
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
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
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
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
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 }