00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "interrogateDatabase.h"
00016 #include "config_interrogatedb.h"
00017 #include "indexRemapper.h"
00018 #include "interrogate_datafile.h"
00019
00020 InterrogateDatabase *InterrogateDatabase::_global_ptr = NULL;
00021 int InterrogateDatabase::_file_major_version = 0;
00022 int InterrogateDatabase::_file_minor_version = 0;
00023 int InterrogateDatabase::_current_major_version = 2;
00024 int InterrogateDatabase::_current_minor_version = 2;
00025
00026
00027
00028
00029
00030
00031 InterrogateDatabase::
00032 InterrogateDatabase() {
00033 _error_flag = false;
00034 _next_index = 1;
00035 _lookups_fresh = 0;
00036 }
00037
00038
00039
00040
00041
00042
00043
00044 InterrogateDatabase *InterrogateDatabase::
00045 get_ptr() {
00046 if (_global_ptr == (InterrogateDatabase *)NULL) {
00047 if (interrogatedb_cat->is_debug()) {
00048 interrogatedb_cat->debug()
00049 << "Creating interrogate database\n";
00050 }
00051 _global_ptr = new InterrogateDatabase;
00052 }
00053 return _global_ptr;
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 void InterrogateDatabase::
00066 request_module(InterrogateModuleDef *def) {
00067 if (interrogatedb_cat->is_debug()) {
00068 if (def->library_name == (const char *)NULL) {
00069 interrogatedb_cat->debug()
00070 << "Got interrogate data for anonymous module\n";
00071 } else {
00072 interrogatedb_cat->debug()
00073 << "Got interrogate data for module " << def->library_name << "\n";
00074 }
00075 }
00076
00077 int num_indices = def->next_index - def->first_index;
00078 if (num_indices > 0) {
00079
00080
00081 def->first_index = _next_index;
00082 _next_index += num_indices;
00083 def->next_index = _next_index;
00084
00085
00086
00087
00088 _modules.push_back(def);
00089 }
00090
00091 if (def->num_unique_names > 0 && def->library_name != (const char *)NULL) {
00092
00093
00094 _modules_by_hash[def->library_hash_name] = def;
00095 }
00096
00097 if (def->database_filename != (const char *)NULL) {
00098 _requests.push_back(def);
00099 }
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 bool InterrogateDatabase::
00111 get_error_flag() {
00112 return _error_flag;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 int InterrogateDatabase::
00126 get_num_global_types() {
00127 check_latest();
00128 return _global_types.size();
00129 }
00130
00131
00132
00133
00134
00135
00136
00137 TypeIndex InterrogateDatabase::
00138 get_global_type(int n) {
00139 check_latest();
00140 if (n >= 0 && n < (int)_global_types.size()) {
00141 return _global_types[n];
00142 }
00143 return 0;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 int InterrogateDatabase::
00155 get_num_all_types() {
00156 check_latest();
00157 return _all_types.size();
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 TypeIndex InterrogateDatabase::
00167 get_all_type(int n) {
00168 check_latest();
00169 if (n >= 0 && n < (int)_all_types.size()) {
00170 return _all_types[n];
00171 }
00172 return 0;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 int InterrogateDatabase::
00184 get_num_global_functions() {
00185 check_latest();
00186 return _global_functions.size();
00187 }
00188
00189
00190
00191
00192
00193
00194
00195 FunctionIndex InterrogateDatabase::
00196 get_global_function(int n) {
00197 check_latest();
00198 if (n >= 0 && n < (int)_global_functions.size()) {
00199 return _global_functions[n];
00200 }
00201 return 0;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 int InterrogateDatabase::
00213 get_num_all_functions() {
00214 check_latest();
00215 return _all_functions.size();
00216 }
00217
00218
00219
00220
00221
00222
00223
00224 FunctionIndex InterrogateDatabase::
00225 get_all_function(int n) {
00226 check_latest();
00227 if (n >= 0 && n < (int)_all_functions.size()) {
00228 return _all_functions[n];
00229 }
00230 return 0;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 int InterrogateDatabase::
00240 get_num_global_manifests() {
00241 check_latest();
00242 return _global_manifests.size();
00243 }
00244
00245
00246
00247
00248
00249
00250
00251 ManifestIndex InterrogateDatabase::
00252 get_global_manifest(int n) {
00253 check_latest();
00254 if (n >= 0 && n < (int)_global_manifests.size()) {
00255 return _global_manifests[n];
00256 }
00257 return 0;
00258 }
00259
00260
00261
00262
00263
00264
00265
00266 int InterrogateDatabase::
00267 get_num_global_elements() {
00268 check_latest();
00269 return _global_elements.size();
00270 }
00271
00272
00273
00274
00275
00276
00277
00278 ElementIndex InterrogateDatabase::
00279 get_global_element(int n) {
00280 check_latest();
00281 if (n >= 0 && n < (int)_global_elements.size()) {
00282 return _global_elements[n];
00283 }
00284 return 0;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293 const InterrogateType &InterrogateDatabase::
00294 get_type(TypeIndex type) {
00295 static InterrogateType bogus_type;
00296
00297 check_latest();
00298 TypeMap::const_iterator ti;
00299 ti = _type_map.find(type);
00300 if (ti == _type_map.end()) {
00301 return bogus_type;
00302 }
00303 return (*ti).second;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312 const InterrogateFunction &InterrogateDatabase::
00313 get_function(FunctionIndex function) {
00314 static InterrogateFunction bogus_function;
00315
00316 check_latest();
00317 FunctionMap::const_iterator fi;
00318 fi = _function_map.find(function);
00319 if (fi == _function_map.end()) {
00320 return bogus_function;
00321 }
00322 return *(*fi).second;
00323 }
00324
00325
00326
00327
00328
00329
00330
00331 const InterrogateFunctionWrapper &InterrogateDatabase::
00332 get_wrapper(FunctionWrapperIndex wrapper) {
00333 static InterrogateFunctionWrapper bogus_wrapper;
00334
00335 check_latest();
00336 FunctionWrapperMap::const_iterator wi;
00337 wi = _wrapper_map.find(wrapper);
00338 if (wi == _wrapper_map.end()) {
00339 return bogus_wrapper;
00340 }
00341 return (*wi).second;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350 const InterrogateManifest &InterrogateDatabase::
00351 get_manifest(ManifestIndex manifest) {
00352 static InterrogateManifest bogus_manifest;
00353
00354 check_latest();
00355 ManifestMap::const_iterator mi;
00356 mi = _manifest_map.find(manifest);
00357 if (mi == _manifest_map.end()) {
00358 return bogus_manifest;
00359 }
00360 return (*mi).second;
00361 }
00362
00363
00364
00365
00366
00367
00368
00369 const InterrogateElement &InterrogateDatabase::
00370 get_element(ElementIndex element) {
00371 static InterrogateElement bogus_element;
00372
00373 check_latest();
00374 ElementMap::const_iterator ei;
00375 ei = _element_map.find(element);
00376 if (ei == _element_map.end()) {
00377 return bogus_element;
00378 }
00379 return (*ei).second;
00380 }
00381
00382
00383
00384
00385
00386
00387
00388 const InterrogateMakeSeq &InterrogateDatabase::
00389 get_make_seq(MakeSeqIndex make_seq) {
00390 static InterrogateMakeSeq bogus_make_seq;
00391
00392 check_latest();
00393 MakeSeqMap::const_iterator si;
00394 si = _make_seq_map.find(make_seq);
00395 if (si == _make_seq_map.end()) {
00396 return bogus_make_seq;
00397 }
00398 return (*si).second;
00399 }
00400
00401
00402
00403
00404
00405
00406 void InterrogateDatabase::
00407 remove_type(TypeIndex type) {
00408 _type_map.erase(type);
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 void *InterrogateDatabase::
00420 get_fptr(FunctionWrapperIndex wrapper) {
00421 InterrogateModuleDef *def;
00422 int module_index;
00423 if (find_module(wrapper, def, module_index)) {
00424 if (module_index >= 0 && module_index < def->num_fptrs) {
00425 return def->fptrs[module_index];
00426 }
00427 }
00428 return (void *)NULL;
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 FunctionWrapperIndex InterrogateDatabase::
00440 get_wrapper_by_unique_name(const string &unique_name) {
00441
00442
00443
00444
00445 string library_hash_name = unique_name.substr(0, 4);
00446 string wrapper_hash_name = unique_name.substr(4);
00447
00448
00449 ModulesByHash::const_iterator mi;
00450 mi = _modules_by_hash.find(library_hash_name);
00451 if (mi == _modules_by_hash.end()) {
00452 return 0;
00453 }
00454
00455 InterrogateModuleDef *def = (*mi).second;
00456 int index_offset =
00457 binary_search_wrapper_hash(def->unique_names,
00458 def->unique_names + def->num_unique_names,
00459 wrapper_hash_name);
00460 if (index_offset >= 0) {
00461 return def->first_index + index_offset;
00462 }
00463
00464 return 0;
00465 }
00466
00467
00468
00469
00470
00471
00472
00473 int InterrogateDatabase::
00474 get_file_major_version() {
00475 return _file_major_version;
00476 }
00477
00478
00479
00480
00481
00482
00483
00484 int InterrogateDatabase::
00485 get_file_minor_version() {
00486 return _file_minor_version;
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496 int InterrogateDatabase::
00497 get_current_major_version() {
00498 return _current_major_version;
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508 int InterrogateDatabase::
00509 get_current_minor_version() {
00510 return _current_minor_version;
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520 void InterrogateDatabase::
00521 set_error_flag(bool error_flag) {
00522 _error_flag = error_flag;
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532 int InterrogateDatabase::
00533 get_next_index() {
00534 return _next_index++;
00535 }
00536
00537
00538
00539
00540
00541
00542
00543 void InterrogateDatabase::
00544 add_type(TypeIndex index, const InterrogateType &type) {
00545 assert(index != 0);
00546 bool inserted =
00547 _type_map.insert(TypeMap::value_type(index, type)).second;
00548
00549 if (!inserted) {
00550
00551
00552
00553 InterrogateType &old_type = _type_map[index];
00554 assert(!old_type.is_fully_defined());
00555
00556
00557 old_type.merge_with(type);
00558 }
00559
00560 if (type.is_global()) {
00561 _global_types.push_back(index);
00562 }
00563 _all_types.push_back(index);
00564 }
00565
00566
00567
00568
00569
00570
00571
00572 void InterrogateDatabase::
00573 add_function(FunctionIndex index, InterrogateFunction *function) {
00574 bool inserted =
00575 _function_map.insert(FunctionMap::value_type(index, function)).second;
00576 assert(inserted);
00577
00578 if (function->is_global()) {
00579 _global_functions.push_back(index);
00580 }
00581 _all_functions.push_back(index);
00582 }
00583
00584
00585
00586
00587
00588
00589
00590 void InterrogateDatabase::
00591 add_wrapper(FunctionWrapperIndex index,
00592 const InterrogateFunctionWrapper &wrapper) {
00593 bool inserted =
00594 _wrapper_map.insert(FunctionWrapperMap::value_type(index, wrapper)).second;
00595 assert(inserted);
00596 }
00597
00598
00599
00600
00601
00602
00603
00604 void InterrogateDatabase::
00605 add_manifest(ManifestIndex index, const InterrogateManifest &manifest) {
00606 bool inserted =
00607 _manifest_map.insert(ManifestMap::value_type(index, manifest)).second;
00608 assert(inserted);
00609
00610 _global_manifests.push_back(index);
00611 }
00612
00613
00614
00615
00616
00617
00618
00619 void InterrogateDatabase::
00620 add_element(ElementIndex index, const InterrogateElement &element) {
00621 bool inserted =
00622 _element_map.insert(ElementMap::value_type(index, element)).second;
00623 assert(inserted);
00624
00625 if (element.is_global()) {
00626 _global_elements.push_back(index);
00627 }
00628 }
00629
00630
00631
00632
00633
00634
00635
00636 void InterrogateDatabase::
00637 add_make_seq(MakeSeqIndex index, const InterrogateMakeSeq &make_seq) {
00638 bool inserted =
00639 _make_seq_map.insert(MakeSeqMap::value_type(index, make_seq)).second;
00640 assert(inserted);
00641 }
00642
00643
00644
00645
00646
00647
00648
00649 InterrogateType &InterrogateDatabase::
00650 update_type(TypeIndex type) {
00651 assert(type != 0);
00652 check_latest();
00653 return _type_map[type];
00654 }
00655
00656
00657
00658
00659
00660
00661
00662 InterrogateFunction &InterrogateDatabase::
00663 update_function(FunctionIndex function) {
00664 check_latest();
00665 return *_function_map[function];
00666 }
00667
00668
00669
00670
00671
00672
00673
00674 InterrogateFunctionWrapper &InterrogateDatabase::
00675 update_wrapper(FunctionWrapperIndex wrapper) {
00676 check_latest();
00677 return _wrapper_map[wrapper];
00678 }
00679
00680
00681
00682
00683
00684
00685
00686 InterrogateManifest &InterrogateDatabase::
00687 update_manifest(ManifestIndex manifest) {
00688 check_latest();
00689 return _manifest_map[manifest];
00690 }
00691
00692
00693
00694
00695
00696
00697
00698 InterrogateElement &InterrogateDatabase::
00699 update_element(ElementIndex element) {
00700 check_latest();
00701 return _element_map[element];
00702 }
00703
00704
00705
00706
00707
00708
00709
00710 InterrogateMakeSeq &InterrogateDatabase::
00711 update_make_seq(MakeSeqIndex make_seq) {
00712 check_latest();
00713 return _make_seq_map[make_seq];
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725 int InterrogateDatabase::
00726 remap_indices(int first_index) {
00727 IndexRemapper remap;
00728 return remap_indices(first_index, remap);
00729 }
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 int InterrogateDatabase::
00741 remap_indices(int first_index, IndexRemapper &remap) {
00742 remap.clear();
00743
00744
00745
00746
00747
00748 FunctionWrapperMap new_wrapper_map;
00749 FunctionWrapperMap::iterator wi;
00750 for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
00751 remap.add_mapping((*wi).first, first_index);
00752 new_wrapper_map[first_index] = (*wi).second;
00753 first_index++;
00754 }
00755
00756
00757 FunctionMap new_function_map;
00758 FunctionMap::iterator fi;
00759 for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
00760 remap.add_mapping((*fi).first, first_index);
00761 new_function_map[first_index] = (*fi).second;
00762 first_index++;
00763 }
00764
00765 TypeMap new_type_map;
00766 TypeMap::iterator ti;
00767 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
00768 assert((*ti).first != 0);
00769 remap.add_mapping((*ti).first, first_index);
00770 new_type_map[first_index] = (*ti).second;
00771 first_index++;
00772 }
00773
00774 ManifestMap new_manifest_map;
00775 ManifestMap::iterator mi;
00776 for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
00777 remap.add_mapping((*mi).first, first_index);
00778 new_manifest_map[first_index] = (*mi).second;
00779 first_index++;
00780 }
00781
00782 ElementMap new_element_map;
00783 ElementMap::iterator ei;
00784 for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
00785 remap.add_mapping((*ei).first, first_index);
00786 new_element_map[first_index] = (*ei).second;
00787 first_index++;
00788 }
00789
00790 MakeSeqMap new_make_seq_map;
00791 MakeSeqMap::iterator si;
00792 for (si = _make_seq_map.begin(); si != _make_seq_map.end(); ++si) {
00793 remap.add_mapping((*si).first, first_index);
00794 new_make_seq_map[first_index] = (*si).second;
00795 first_index++;
00796 }
00797
00798 _next_index = first_index;
00799
00800 _wrapper_map.swap(new_wrapper_map);
00801 _function_map.swap(new_function_map);
00802 _type_map.swap(new_type_map);
00803 _manifest_map.swap(new_manifest_map);
00804 _element_map.swap(new_element_map);
00805 _make_seq_map.swap(new_make_seq_map);
00806
00807
00808 for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
00809 (*wi).second.remap_indices(remap);
00810 }
00811 for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
00812 (*fi).second->remap_indices(remap);
00813 }
00814 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
00815 (*ti).second.remap_indices(remap);
00816 }
00817 for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
00818 (*mi).second.remap_indices(remap);
00819 }
00820 for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
00821 (*ei).second.remap_indices(remap);
00822 }
00823 for (si = _make_seq_map.begin(); si != _make_seq_map.end(); ++si) {
00824 (*si).second.remap_indices(remap);
00825 }
00826 GlobalFunctions::iterator gfi;
00827 for (gfi = _global_functions.begin(); gfi != _global_functions.end(); ++gfi) {
00828 (*gfi) = remap.map_from(*gfi);
00829 }
00830 for (gfi = _all_functions.begin(); gfi != _all_functions.end(); ++gfi) {
00831 (*gfi) = remap.map_from(*gfi);
00832 }
00833 GlobalTypes::iterator gti;
00834 for (gti = _global_types.begin(); gti != _global_types.end(); ++gti) {
00835 (*gti) = remap.map_from(*gti);
00836 }
00837 for (gti = _all_types.begin(); gti != _all_types.end(); ++gti) {
00838 (*gti) = remap.map_from(*gti);
00839 }
00840 GlobalManifests::iterator gmi;
00841 for (gmi = _global_manifests.begin(); gmi != _global_manifests.end(); ++gmi) {
00842 (*gmi) = remap.map_from(*gmi);
00843 }
00844 GlobalElements::iterator gei;
00845 for (gei = _global_elements.begin(); gei != _global_elements.end(); ++gei) {
00846 (*gei) = remap.map_from(*gei);
00847 }
00848
00849 return _next_index;
00850 }
00851
00852
00853
00854
00855
00856
00857
00858 void InterrogateDatabase::
00859 write(ostream &out, InterrogateModuleDef *def) const {
00860
00861 out << def->file_identifier << "\n"
00862 << _current_major_version << " " << _current_minor_version << "\n";
00863
00864
00865 idf_output_string(out, def->library_name);
00866 idf_output_string(out, def->library_hash_name);
00867 idf_output_string(out, def->module_name);
00868 out << "\n";
00869
00870
00871
00872 out << _function_map.size() << "\n";
00873 FunctionMap::const_iterator fi;
00874 for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
00875 out << (*fi).first << " " << *(*fi).second << "\n";
00876 }
00877
00878 out << _wrapper_map.size() << "\n";
00879 FunctionWrapperMap::const_iterator wi;
00880 for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
00881 out << (*wi).first << " " << (*wi).second << "\n";
00882 }
00883
00884 out << _type_map.size() << "\n";
00885 TypeMap::const_iterator ti;
00886 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
00887 out << (*ti).first << " " << (*ti).second << "\n";
00888 }
00889
00890 out << _manifest_map.size() << "\n";
00891 ManifestMap::const_iterator mi;
00892 for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
00893 out << (*mi).first << " " << (*mi).second << "\n";
00894 }
00895
00896 out << _element_map.size() << "\n";
00897 ElementMap::const_iterator ei;
00898 for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
00899 out << (*ei).first << " " << (*ei).second << "\n";
00900 }
00901
00902 out << _make_seq_map.size() << "\n";
00903 MakeSeqMap::const_iterator si;
00904 for (si = _make_seq_map.begin(); si != _make_seq_map.end(); ++si) {
00905 out << (*si).first << " " << (*si).second << "\n";
00906 }
00907 }
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922 bool InterrogateDatabase::
00923 read(istream &in, InterrogateModuleDef *def) {
00924 InterrogateDatabase temp;
00925 if (!temp.read_new(in, def)) {
00926 return false;
00927 }
00928
00929 if (def->first_index == 0 && def->next_index == 0) {
00930 _next_index = temp.remap_indices(_next_index);
00931
00932 } else {
00933 int next = temp.remap_indices(def->first_index);
00934 if (next != def->next_index) {
00935 interrogatedb_cat->error()
00936 << "Module database file " << def->database_filename
00937 << " is out of date.\n";
00938 return false;
00939 }
00940 }
00941
00942 merge_from(temp);
00943 return true;
00944 }
00945
00946
00947
00948
00949
00950
00951 void InterrogateDatabase::
00952 load_latest() {
00953 const DSearchPath &searchpath = interrogatedb_path;
00954
00955 Requests copy_requests;
00956 copy_requests.swap(_requests);
00957
00958 Requests::const_iterator ri;
00959 for (ri = copy_requests.begin(); ri != copy_requests.end(); ++ri) {
00960 InterrogateModuleDef *def = (*ri);
00961
00962 if (def->database_filename != (char *)NULL) {
00963 Filename filename = def->database_filename;
00964 Filename pathname = filename;
00965 if (!pathname.empty() && pathname[0] != '/') {
00966 pathname = searchpath.find_file(pathname);
00967 }
00968
00969 if (pathname.empty()) {
00970 interrogatedb_cat->error()
00971 << "Unable to find " << filename << " on " << searchpath << "\n";
00972 set_error_flag(true);
00973
00974 } else {
00975
00976 pifstream input;
00977 pathname.set_text();
00978 if (!pathname.open_read(input)) {
00979 interrogatedb_cat->error() << "Unable to read " << pathname << ".\n";
00980 set_error_flag(true);
00981
00982 } else {
00983 int file_identifier;
00984 input >> file_identifier
00985 >> _file_major_version >> _file_minor_version;
00986
00987 if (def->file_identifier != 0 &&
00988 file_identifier != def->file_identifier) {
00989 interrogatedb_cat->warning()
00990 << "Interrogate data in " << pathname
00991 << " is out of sync with the compiled-in data"
00992 << " (" << file_identifier << " != " << def->file_identifier << ").\n";
00993 set_error_flag(true);
00994 }
00995
00996 if (_file_major_version != _current_major_version ||
00997 _file_minor_version > _current_minor_version) {
00998 interrogatedb_cat->error()
00999 << "Cannot read interrogate data in " << pathname
01000 << "; database is version " << _file_major_version << "."
01001 << _file_minor_version << " while we are expecting "
01002 << _current_major_version << "." << _current_minor_version
01003 << ".\n";
01004 set_error_flag(true);
01005
01006 } else {
01007 if (interrogatedb_cat->is_debug()) {
01008 interrogatedb_cat->debug()
01009 << "Reading " << filename << "\n";
01010 }
01011 if (!read(input, def)) {
01012 interrogatedb_cat->error()
01013 << "Error reading " << pathname << ".\n";
01014 set_error_flag(true);
01015 }
01016 }
01017 }
01018 }
01019 }
01020 }
01021
01022 _requests.clear();
01023 }
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033 bool InterrogateDatabase::
01034 read_new(istream &in, InterrogateModuleDef *def) {
01035
01036 idf_input_string(in, def->library_name);
01037 idf_input_string(in, def->library_hash_name);
01038 idf_input_string(in, def->module_name);
01039
01040
01041
01042 {
01043 int num_functions;
01044 in >> num_functions;
01045 if (in.fail()) {
01046 return false;
01047 }
01048
01049 while (num_functions > 0) {
01050 FunctionIndex index;
01051 InterrogateFunction *function = new InterrogateFunction(def);
01052 in >> index >> *function;
01053 if (in.fail()) {
01054 delete function;
01055 return false;
01056 }
01057
01058 add_function(index, function);
01059 num_functions--;
01060 }
01061 }
01062
01063 {
01064 int num_wrappers;
01065 in >> num_wrappers;
01066 if (in.fail()) {
01067 return false;
01068 }
01069
01070 while (num_wrappers > 0) {
01071 FunctionWrapperIndex index;
01072 InterrogateFunctionWrapper wrapper(def);
01073 in >> index >> wrapper;
01074 if (in.fail()) {
01075 return false;
01076 }
01077
01078 add_wrapper(index, wrapper);
01079 num_wrappers--;
01080 }
01081 }
01082
01083 {
01084 int num_types;
01085 in >> num_types;
01086 if (in.fail()) {
01087 return false;
01088 }
01089
01090 while (num_types > 0) {
01091 TypeIndex index;
01092 InterrogateType type(def);
01093 in >> index >> type;
01094 if (in.fail()) {
01095 return false;
01096 }
01097
01098 add_type(index, type);
01099 num_types--;
01100 }
01101 }
01102
01103 {
01104 int num_manifests;
01105 in >> num_manifests;
01106 if (in.fail()) {
01107 return false;
01108 }
01109
01110 while (num_manifests > 0) {
01111 ManifestIndex index;
01112 InterrogateManifest manifest(def);
01113 in >> index >> manifest;
01114 if (in.fail()) {
01115 return false;
01116 }
01117
01118 add_manifest(index, manifest);
01119 num_manifests--;
01120 }
01121 }
01122
01123 {
01124 int num_elements;
01125 in >> num_elements;
01126 if (in.fail()) {
01127 return false;
01128 }
01129
01130 while (num_elements > 0) {
01131 ElementIndex index;
01132 InterrogateElement element(def);
01133 in >> index >> element;
01134 if (in.fail()) {
01135 return false;
01136 }
01137
01138 add_element(index, element);
01139 num_elements--;
01140 }
01141 }
01142
01143 {
01144 int num_make_seqs;
01145 in >> num_make_seqs;
01146 if (in.fail()) {
01147 return false;
01148 }
01149
01150 while (num_make_seqs > 0) {
01151 MakeSeqIndex index;
01152 InterrogateMakeSeq make_seq(def);
01153 in >> index >> make_seq;
01154 if (in.fail()) {
01155 return false;
01156 }
01157
01158 add_make_seq(index, make_seq);
01159 num_make_seqs--;
01160 }
01161 }
01162
01163 return true;
01164 }
01165
01166
01167
01168
01169
01170
01171
01172
01173 void InterrogateDatabase::
01174 merge_from(const InterrogateDatabase &other) {
01175
01176 IndexRemapper remap;
01177
01178
01179
01180 map<string, TypeIndex> types_by_name;
01181
01182 TypeMap::const_iterator ti;
01183 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01184 const InterrogateType &type = (*ti).second;
01185 if (type.has_true_name()) {
01186 types_by_name[type.get_true_name()] = (*ti).first;
01187 }
01188 }
01189
01190
01191
01192 for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
01193 TypeIndex other_type_index = (*ti).first;
01194 const InterrogateType &other_type = (*ti).second;
01195
01196 if (other_type.has_name()) {
01197 map<string, TypeIndex>::iterator ni;
01198 ni = types_by_name.find(other_type.get_true_name());
01199 if (ni != types_by_name.end()) {
01200
01201
01202 TypeIndex this_type_index = (*ni).second;
01203 remap.add_mapping(other_type_index, this_type_index);
01204 }
01205 }
01206 }
01207
01208
01209
01210 for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
01211 TypeIndex other_type_index = (*ti).first;
01212 const InterrogateType &other_type = (*ti).second;
01213
01214 if (!remap.in_map(other_type_index)) {
01215
01216 add_type(other_type_index, other_type);
01217 update_type(other_type_index).remap_indices(remap);
01218
01219 } else {
01220
01221 TypeIndex this_type_index = remap.map_from(other_type_index);
01222
01223 InterrogateType &this_type = update_type(this_type_index);
01224 if (!this_type.is_global() && other_type.is_global()) {
01225
01226
01227 _global_types.push_back(this_type_index);
01228 }
01229
01230 InterrogateType merge_type = other_type;
01231 merge_type.remap_indices(remap);
01232 this_type.merge_with(merge_type);
01233 }
01234 }
01235
01236
01237 FunctionMap::const_iterator fi;
01238 for (fi = other._function_map.begin();
01239 fi != other._function_map.end();
01240 ++fi) {
01241 FunctionIndex other_function_index = (*fi).first;
01242 InterrogateFunction *other_function = (*fi).second;
01243 add_function(other_function_index, other_function);
01244 update_function(other_function_index).remap_indices(remap);
01245 }
01246
01247 FunctionWrapperMap::const_iterator wi;
01248 for (wi = other._wrapper_map.begin();
01249 wi != other._wrapper_map.end();
01250 ++wi) {
01251 FunctionWrapperIndex other_wrapper_index = (*wi).first;
01252 const InterrogateFunctionWrapper &other_wrapper = (*wi).second;
01253 add_wrapper(other_wrapper_index, other_wrapper);
01254 update_wrapper(other_wrapper_index).remap_indices(remap);
01255 }
01256
01257 ManifestMap::const_iterator mi;
01258 for (mi = other._manifest_map.begin();
01259 mi != other._manifest_map.end();
01260 ++mi) {
01261 ManifestIndex other_manifest_index = (*mi).first;
01262 const InterrogateManifest &other_manifest = (*mi).second;
01263 add_manifest(other_manifest_index, other_manifest);
01264 update_manifest(other_manifest_index).remap_indices(remap);
01265 }
01266
01267 ElementMap::const_iterator ei;
01268 for (ei = other._element_map.begin();
01269 ei != other._element_map.end();
01270 ++ei) {
01271 ElementIndex other_element_index = (*ei).first;
01272 const InterrogateElement &other_element = (*ei).second;
01273 add_element(other_element_index, other_element);
01274 update_element(other_element_index).remap_indices(remap);
01275 }
01276
01277 MakeSeqMap::const_iterator si;
01278 for (si = other._make_seq_map.begin();
01279 si != other._make_seq_map.end();
01280 ++si) {
01281 MakeSeqIndex other_make_seq_index = (*si).first;
01282 const InterrogateMakeSeq &other_make_seq = (*si).second;
01283 add_make_seq(other_make_seq_index, other_make_seq);
01284 update_make_seq(other_make_seq_index).remap_indices(remap);
01285 }
01286
01287 _lookups_fresh = 0;
01288 }
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302 bool InterrogateDatabase::
01303 find_module(FunctionWrapperIndex wrapper, InterrogateModuleDef *&def,
01304 int &module_index) {
01305 if (_modules.empty()) {
01306 return false;
01307 }
01308
01309 int mi = binary_search_module(0, _modules.size(), wrapper);
01310 assert(mi >= 0 && mi < (int)_modules.size());
01311 def = _modules[mi];
01312 module_index = wrapper - def->first_index;
01313
01314 return (wrapper < def->next_index);
01315 }
01316
01317
01318
01319
01320
01321
01322
01323 int InterrogateDatabase::
01324 binary_search_module(int begin, int end, FunctionIndex function) {
01325 int mid = begin + (end - begin) / 2;
01326 if (mid == begin) {
01327 return mid;
01328 }
01329
01330 int index = _modules[mid]->first_index;
01331 if (index <= function) {
01332 return binary_search_module(mid, end, function);
01333
01334 } else {
01335 return binary_search_module(begin, mid, function);
01336 }
01337 }
01338
01339
01340
01341
01342
01343
01344
01345
01346 int InterrogateDatabase::
01347 binary_search_wrapper_hash(InterrogateUniqueNameDef *begin,
01348 InterrogateUniqueNameDef *end,
01349 const string &wrapper_hash_name) {
01350 if (end <= begin) {
01351 return -1;
01352 }
01353
01354 InterrogateUniqueNameDef *mid = begin + (end - begin) / 2;
01355 string name = mid->name;
01356 if (name < wrapper_hash_name) {
01357 return binary_search_wrapper_hash(mid, end, wrapper_hash_name);
01358
01359 } else if (wrapper_hash_name < name) {
01360 return binary_search_wrapper_hash(begin, mid, wrapper_hash_name);
01361
01362 } else {
01363 return mid->index_offset;
01364 }
01365 }
01366
01367
01368
01369
01370
01371
01372 void InterrogateDatabase::
01373 freshen_types_by_name() {
01374 _types_by_name.clear();
01375 TypeMap::const_iterator ti;
01376 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01377 _types_by_name[(*ti).second.get_name()] = (*ti).first;
01378 }
01379 }
01380
01381
01382
01383
01384
01385
01386 void InterrogateDatabase::
01387 freshen_types_by_scoped_name() {
01388 _types_by_scoped_name.clear();
01389 TypeMap::const_iterator ti;
01390 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01391 _types_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
01392 }
01393 }
01394
01395
01396
01397
01398
01399
01400 void InterrogateDatabase::
01401 freshen_types_by_true_name() {
01402 _types_by_true_name.clear();
01403 TypeMap::const_iterator ti;
01404 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
01405 _types_by_true_name[(*ti).second.get_true_name()] = (*ti).first;
01406 }
01407 }
01408
01409
01410
01411
01412
01413
01414 void InterrogateDatabase::
01415 freshen_manifests_by_name() {
01416 _manifests_by_name.clear();
01417 ManifestMap::const_iterator ti;
01418 for (ti = _manifest_map.begin(); ti != _manifest_map.end(); ++ti) {
01419 _manifests_by_name[(*ti).second.get_name()] = (*ti).first;
01420 }
01421 }
01422
01423
01424
01425
01426
01427
01428 void InterrogateDatabase::
01429 freshen_elements_by_name() {
01430 _elements_by_name.clear();
01431 ElementMap::const_iterator ti;
01432 for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
01433 _elements_by_name[(*ti).second.get_name()] = (*ti).first;
01434 }
01435 }
01436
01437
01438
01439
01440
01441
01442 void InterrogateDatabase::
01443 freshen_elements_by_scoped_name() {
01444 _elements_by_scoped_name.clear();
01445 ElementMap::const_iterator ti;
01446 for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
01447 _elements_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
01448 }
01449 }
01450
01451
01452
01453
01454
01455
01456
01457
01458 int InterrogateDatabase::
01459 lookup(const string &name, Lookup &lookup, LookupType type,
01460 void (InterrogateDatabase::*freshen)()) {
01461 if ((_lookups_fresh & (int)type) == 0) {
01462
01463 (this->*freshen)();
01464 _lookups_fresh |= (int)type;
01465 }
01466
01467 Lookup::const_iterator li;
01468 li = lookup.find(name);
01469 if (li != lookup.end()) {
01470 return (*li).second;
01471 }
01472 return 0;
01473 }