Panda3D

interrogateDatabase.cxx
Go to the documentation of this file.
1 /**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file interrogateDatabase.cxx
10 * @author drose
11 * @date 2000-08-01
12 */
13
14 #include "interrogateDatabase.h"
15 #include "config_interrogatedb.h"
16 #include "indexRemapper.h"
17 #include "interrogate_datafile.h"
18
19 using std::map;
20 using std::string;
21
22 InterrogateDatabase *InterrogateDatabase::_global_ptr = nullptr;
23 int InterrogateDatabase::_file_major_version = 0;
24 int InterrogateDatabase::_file_minor_version = 0;
25 int InterrogateDatabase::_current_major_version = 3;
26 int InterrogateDatabase::_current_minor_version = 3;
27
28 /**
29 *
30 */
31 InterrogateDatabase::
32 InterrogateDatabase() {
33 _error_flag = false;
34 _next_index = 1;
35 _lookups_fresh = 0;
36 }
37
38 /**
39 * Returns the global pointer to the one InterrogateDatabase.
40 */
41 InterrogateDatabase *InterrogateDatabase::
42 get_ptr() {
43 if (_global_ptr == nullptr) {
44 if (interrogatedb_cat->is_debug()) {
45 interrogatedb_cat->debug()
46 << "Creating interrogate database\n";
47 }
48 _global_ptr = new InterrogateDatabase;
49 }
50 return _global_ptr;
51 }
52
53 /**
54 * Requests that the interrogate data for the given module be made available.
55 * The function pointers will be made available immediately, while the
56 * database file will be read later, the next time someone asks for
57 * interrogate data that requires it.
58 */
59 void InterrogateDatabase::
60 request_module(InterrogateModuleDef *def) {
61 if (interrogatedb_cat->is_debug()) {
62 if (def->library_name == nullptr) {
63 interrogatedb_cat->debug()
64 << "Got interrogate data for anonymous module\n";
65 } else {
66 interrogatedb_cat->debug()
67 << "Got interrogate data for module " << def->library_name << "\n";
68 }
69 }
70
71 int num_indices = def->next_index - def->first_index;
72 if (num_indices > 0) {
73 // If the module def has any definitions--any index numbers used--assign
74 // it to its own unique range of index numbers.
75 def->first_index = _next_index;
76 _next_index += num_indices;
77 def->next_index = _next_index;
78
79 // Assign a reference to the module def by index number. When we need to
80 // look up a function by its index number, we'll be able to use this.
81 _modules.push_back(def);
82 }
83
84 if (def->num_unique_names > 0 && def->library_name != nullptr) {
85 // Define a lookup by hash for this module, mainly so we can look up
86 // functions by their unique names.
87 _modules_by_hash[def->library_hash_name] = def;
88 }
89
90 if (def->database_filename != nullptr) {
91 _requests.push_back(def);
92 }
93 }
94
95 /**
96 * Returns the global error flag. This will be set true if there was some
97 * problem importing the database (e.g. cannot find an .in file), or false if
98 * everything is ok.
99 */
100 bool InterrogateDatabase::
101 get_error_flag() {
102 return _error_flag;
103 }
104
105 /**
106 * Returns the total number of "global" types known to the interrogate
107 * database. These are types defined at the global level that should be
108 * considered for exporting, but not the incidental types (like pointers,
109 * etc.) that must be defined to support these.
110 */
111 int InterrogateDatabase::
112 get_num_global_types() {
113 check_latest();
114 return _global_types.size();
115 }
116
117 /**
118 * Returns the index of the nth global type known to the interrogate database.
119 */
120 TypeIndex InterrogateDatabase::
121 get_global_type(int n) {
122 check_latest();
123 if (n >= 0 && n < (int)_global_types.size()) {
124 return _global_types[n];
125 }
126 return 0;
127 }
128
129 /**
130 * Returns the total number of types known to the interrogate database. This
131 * includes all known types, global as well as incidental. See also
132 * get_num_global_types().
133 */
134 int InterrogateDatabase::
135 get_num_all_types() {
136 check_latest();
137 return _all_types.size();
138 }
139
140 /**
141 * Returns the index of the nth type known to the interrogate database.
142 */
143 TypeIndex InterrogateDatabase::
144 get_all_type(int n) {
145 check_latest();
146 if (n >= 0 && n < (int)_all_types.size()) {
147 return _all_types[n];
148 }
149 return 0;
150 }
151
152 /**
153 * Returns the total number of global functions known to the interrogate
154 * database. These are functions defined at the global level, e.g. non-
155 * member functions.
156 */
157 int InterrogateDatabase::
158 get_num_global_functions() {
159 check_latest();
160 return _global_functions.size();
161 }
162
163 /**
164 * Returns the index of the nth global function known to the interrogate
165 * database.
166 */
167 FunctionIndex InterrogateDatabase::
168 get_global_function(int n) {
169 check_latest();
170 if (n >= 0 && n < (int)_global_functions.size()) {
171 return _global_functions[n];
172 }
173 return 0;
174 }
175
176 /**
177 * Returns the total number of functions known to the interrogate database.
178 * This includes all known functions, global, method, or synthesized. See
179 * also get_num_global_functions().
180 */
181 int InterrogateDatabase::
182 get_num_all_functions() {
183 check_latest();
184 return _all_functions.size();
185 }
186
187 /**
188 * Returns the index of the nth function known to the interrogate database.
189 */
190 FunctionIndex InterrogateDatabase::
191 get_all_function(int n) {
192 check_latest();
193 if (n >= 0 && n < (int)_all_functions.size()) {
194 return _all_functions[n];
195 }
196 return 0;
197 }
198
199 /**
200 * Returns the total number of global manifest constants known to the
201 * interrogate database.
202 */
203 int InterrogateDatabase::
204 get_num_global_manifests() {
205 check_latest();
206 return _global_manifests.size();
207 }
208
209 /**
210 * Returns the index of the nth global manifest constant known to the
211 * interrogate database.
212 */
213 ManifestIndex InterrogateDatabase::
214 get_global_manifest(int n) {
215 check_latest();
216 if (n >= 0 && n < (int)_global_manifests.size()) {
217 return _global_manifests[n];
218 }
219 return 0;
220 }
221
222 /**
223 * Returns the total number of global data elements known to the interrogate
224 * database.
225 */
226 int InterrogateDatabase::
227 get_num_global_elements() {
228 check_latest();
229 return _global_elements.size();
230 }
231
232 /**
233 * Returns the index of the nth global data element known to the interrogate
234 * database.
235 */
236 ElementIndex InterrogateDatabase::
237 get_global_element(int n) {
238 check_latest();
239 if (n >= 0 && n < (int)_global_elements.size()) {
240 return _global_elements[n];
241 }
242 return 0;
243 }
244
245 /**
246 * Returns the type associated with the given TypeIndex, if there is one.
247 */
248 const InterrogateType &InterrogateDatabase::
249 get_type(TypeIndex type) {
250 static InterrogateType bogus_type;
251
252 check_latest();
253 TypeMap::const_iterator ti;
254 ti = _type_map.find(type);
255 if (ti == _type_map.end()) {
256 return bogus_type;
257 }
258 return (*ti).second;
259 }
260
261 /**
262 * Returns the function associated with the given FunctionIndex, if there is
263 * one.
264 */
265 const InterrogateFunction &InterrogateDatabase::
266 get_function(FunctionIndex function) {
267 static InterrogateFunction bogus_function;
268
269 check_latest();
270 FunctionMap::const_iterator fi;
271 fi = _function_map.find(function);
272 if (fi == _function_map.end()) {
273 return bogus_function;
274 }
275 return *(*fi).second;
276 }
277
278 /**
279 * Returns the function wrapper associated with the given
280 * FunctionWrapperIndex, if there is one.
281 */
282 const InterrogateFunctionWrapper &InterrogateDatabase::
283 get_wrapper(FunctionWrapperIndex wrapper) {
284 static InterrogateFunctionWrapper bogus_wrapper;
285
286 check_latest();
287 FunctionWrapperMap::const_iterator wi;
288 wi = _wrapper_map.find(wrapper);
289 if (wi == _wrapper_map.end()) {
290 return bogus_wrapper;
291 }
292 return (*wi).second;
293 }
294
295 /**
296 * Returns the manifest constant associated with the given ManifestIndex, if
297 * there is one.
298 */
299 const InterrogateManifest &InterrogateDatabase::
300 get_manifest(ManifestIndex manifest) {
301 static InterrogateManifest bogus_manifest;
302
303 check_latest();
304 ManifestMap::const_iterator mi;
305 mi = _manifest_map.find(manifest);
306 if (mi == _manifest_map.end()) {
307 return bogus_manifest;
308 }
309 return (*mi).second;
310 }
311
312 /**
313 * Returns the data element associated with the given ElementIndex, if there
314 * is one.
315 */
316 const InterrogateElement &InterrogateDatabase::
317 get_element(ElementIndex element) {
318 static InterrogateElement bogus_element;
319
320 check_latest();
321 ElementMap::const_iterator ei;
322 ei = _element_map.find(element);
323 if (ei == _element_map.end()) {
324 return bogus_element;
325 }
326 return (*ei).second;
327 }
328
329 /**
330 * Returns the make_seq associated with the given MakeSeqIndex, if there is
331 * one.
332 */
333 const InterrogateMakeSeq &InterrogateDatabase::
334 get_make_seq(MakeSeqIndex make_seq) {
335 static InterrogateMakeSeq bogus_make_seq;
336
337 check_latest();
338 MakeSeqMap::const_iterator si;
339 si = _make_seq_map.find(make_seq);
340 if (si == _make_seq_map.end()) {
341 return bogus_make_seq;
342 }
343 return (*si).second;
344 }
345
346 /**
347 * Erases the type from the database.
348 */
349 void InterrogateDatabase::
350 remove_type(TypeIndex type) {
351 _type_map.erase(type);
352 }
353
354 /**
355 * Returns the function pointer associated with the given function wrapper, if
356 * it has a pointer available. Returns NULL if the pointer is not available.
357 */
358 void *InterrogateDatabase::
359 get_fptr(FunctionWrapperIndex wrapper) {
360 InterrogateModuleDef *def;
361 int module_index;
362 if (find_module(wrapper, def, module_index)) {
363 if (module_index >= 0 && module_index < def->num_fptrs) {
364 return def->fptrs[module_index];
365 }
366 }
367 return nullptr;
368 }
369
370 /**
371 * Looks up the function wrapper corresponding to the given unique name, if
372 * available. Returns the corresponding wrapper index, or 0 if no such
373 * wrapper is found.
374 */
375 FunctionWrapperIndex InterrogateDatabase::
376 get_wrapper_by_unique_name(const string &unique_name) {
377 // First, split the unique_name into a library_hash_name and a
378 // wrapper_hash_name.
379
380 // The first four characters are always the library_name.
381 string library_hash_name = unique_name.substr(0, 4);
382 string wrapper_hash_name = unique_name.substr(4);
383
384 // Is the library_name defined?
385 ModulesByHash::const_iterator mi;
386 mi = _modules_by_hash.find(library_hash_name);
387 if (mi == _modules_by_hash.end()) {
388 return 0;
389 }
390
391 InterrogateModuleDef *def = (*mi).second;
392 int index_offset =
393 binary_search_wrapper_hash(def->unique_names,
394 def->unique_names + def->num_unique_names,
395 wrapper_hash_name);
396 if (index_offset >= 0) {
397 return def->first_index + index_offset;
398 }
399
400 return 0;
401 }
402
403 /**
404 * Returns the major version number of the interrogate database file currently
405 * being read.
406 */
407 int InterrogateDatabase::
408 get_file_major_version() {
409 return _file_major_version;
410 }
411
412 /**
413 * Returns the minor version number of the interrogate database file currently
414 * being read.
415 */
416 int InterrogateDatabase::
417 get_file_minor_version() {
418 return _file_minor_version;
419 }
420
421 /**
422 * Returns the major version number currently expected in interrogate database
423 * files generated by this code base.
424 */
425 int InterrogateDatabase::
426 get_current_major_version() {
427 return _current_major_version;
428 }
429
430 /**
431 * Returns the minor version number currently expected in interrogate database
432 * files generated by this code base.
433 */
434 int InterrogateDatabase::
435 get_current_minor_version() {
436 return _current_minor_version;
437 }
438
439 /**
440 * Sets the global error flag. This should be set true if there was some
441 * problem importing the database (e.g. cannot find an .in file).
442 */
443 void InterrogateDatabase::
444 set_error_flag(bool error_flag) {
445 _error_flag = error_flag;
446 }
447
448 /**
449 * Returns a new index number suitable for the next thing, that will not be
450 * shared with any other index numbers.
451 */
452 int InterrogateDatabase::
453 get_next_index() {
454 return _next_index++;
455 }
456
457 /**
458 * Adds the indicated type to the database at the given index number.
459 */
460 void InterrogateDatabase::
461 add_type(TypeIndex index, const InterrogateType &type) {
462 assert(index != 0);
463 bool inserted =
464 _type_map.insert(TypeMap::value_type(index, type)).second;
465
466 if (!inserted) {
467 // If there was already a type at that index, maybe it was a forward
468 // reference. If its _fully_defined bit isn't set, then it's ok.
469 InterrogateType &old_type = _type_map[index];
470 assert(!old_type.is_fully_defined());
471
472 // It was a forward reference. Merge it with the new one.
473 old_type.merge_with(type);
474 }
475
476 if (type.is_global()) {
477 _global_types.push_back(index);
478 }
479 _all_types.push_back(index);
480 }
481
482 /**
483 * Adds the indicated function to the database at the given index number.
484 */
485 void InterrogateDatabase::
486 add_function(FunctionIndex index, InterrogateFunction *function) {
487 bool inserted =
488 _function_map.insert(FunctionMap::value_type(index, function)).second;
489 assert(inserted);
490
491 if (function->is_global()) {
492 _global_functions.push_back(index);
493 }
494 _all_functions.push_back(index);
495 }
496
497 /**
498 * Adds the indicated function wrapper to the database at the given index
499 * number.
500 */
501 void InterrogateDatabase::
502 add_wrapper(FunctionWrapperIndex index,
503 const InterrogateFunctionWrapper &wrapper) {
504 bool inserted =
505 _wrapper_map.insert(FunctionWrapperMap::value_type(index, wrapper)).second;
506 assert(inserted);
507 }
508
509 /**
510 * Adds the indicated manifest constant to the database at the given index
511 * number.
512 */
513 void InterrogateDatabase::
514 add_manifest(ManifestIndex index, const InterrogateManifest &manifest) {
515 bool inserted =
516 _manifest_map.insert(ManifestMap::value_type(index, manifest)).second;
517 assert(inserted);
518
519 _global_manifests.push_back(index);
520 }
521
522 /**
523 * Adds the indicated data element to the database at the given index number.
524 */
525 void InterrogateDatabase::
526 add_element(ElementIndex index, const InterrogateElement &element) {
527 bool inserted =
528 _element_map.insert(ElementMap::value_type(index, element)).second;
529 assert(inserted);
530
531 if (element.is_global()) {
532 _global_elements.push_back(index);
533 }
534 }
535
536 /**
537 * Adds the indicated make_seq to the database at the given index number.
538 */
539 void InterrogateDatabase::
540 add_make_seq(MakeSeqIndex index, const InterrogateMakeSeq &make_seq) {
541 bool inserted =
542 _make_seq_map.insert(MakeSeqMap::value_type(index, make_seq)).second;
543 assert(inserted);
544 }
545
546 /**
547 * Returns a non-const reference to the indicated type, allowing the user to
548 * update it.
549 */
550 InterrogateType &InterrogateDatabase::
551 update_type(TypeIndex type) {
552 assert(type != 0);
553 check_latest();
554 return _type_map[type];
555 }
556
557 /**
558 * Returns a non-const reference to the indicated function, allowing the user
559 * to update it.
560 */
561 InterrogateFunction &InterrogateDatabase::
562 update_function(FunctionIndex function) {
563 check_latest();
564 return *_function_map[function];
565 }
566
567 /**
568 * Returns a non-const reference to the indicated function wrapper, allowing
569 * the user to update it.
570 */
571 InterrogateFunctionWrapper &InterrogateDatabase::
572 update_wrapper(FunctionWrapperIndex wrapper) {
573 check_latest();
574 return _wrapper_map[wrapper];
575 }
576
577 /**
578 * Returns a non-const reference to the indicated manifest constant, allowing
579 * the user to update it.
580 */
581 InterrogateManifest &InterrogateDatabase::
582 update_manifest(ManifestIndex manifest) {
583 check_latest();
584 return _manifest_map[manifest];
585 }
586
587 /**
588 * Returns a non-const reference to the indicated data element, allowing the
589 * user to update it.
590 */
591 InterrogateElement &InterrogateDatabase::
592 update_element(ElementIndex element) {
593 check_latest();
594 return _element_map[element];
595 }
596
597 /**
598 * Returns a non-const reference to the indicated make_seq, allowing the user
599 * to update it.
600 */
601 InterrogateMakeSeq &InterrogateDatabase::
602 update_make_seq(MakeSeqIndex make_seq) {
603 check_latest();
604 return _make_seq_map[make_seq];
605 }
606
607 /**
608 * Resequences all of the various index numbers so that all of the functions
609 * start at first_index and increment consecutively from there, and then all
610 * of the types follow. Returns the next available index number.
611 */
612 int InterrogateDatabase::
613 remap_indices(int first_index) {
614 IndexRemapper remap;
615 return remap_indices(first_index, remap);
616 }
617
618 /**
619 * This flavor of remap_indices() accepts a map that should be empty on
620 * initial call, and will be filled with the mapping of old index number to
621 * new index number. This allows the caller to update its own data structures
622 * to match the new index numbers.
623 */
624 int InterrogateDatabase::
625 remap_indices(int first_index, IndexRemapper &remap) {
626 remap.clear();
627
628 // First, build up the complete map.
629
630 // Get the wrapper indices first. This is important, because the
631 // InterrogateBuilder wants these to be first, and consecutive.
632 FunctionWrapperMap new_wrapper_map;
633 FunctionWrapperMap::iterator wi;
634 for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
635 remap.add_mapping((*wi).first, first_index);
636 new_wrapper_map[first_index] = (*wi).second;
637 first_index++;
638 }
639
640 // Everything else can follow; it doesn't matter so much.
641 FunctionMap new_function_map;
642 FunctionMap::iterator fi;
643 for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
644 remap.add_mapping((*fi).first, first_index);
645 new_function_map[first_index] = (*fi).second;
646 first_index++;
647 }
648
649 TypeMap new_type_map;
650 TypeMap::iterator ti;
651 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
652 assert((*ti).first != 0);
653 remap.add_mapping((*ti).first, first_index);
654 new_type_map[first_index] = (*ti).second;
655 first_index++;
656 }
657
658 ManifestMap new_manifest_map;
659 ManifestMap::iterator mi;
660 for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
661 remap.add_mapping((*mi).first, first_index);
662 new_manifest_map[first_index] = (*mi).second;
663 first_index++;
664 }
665
666 ElementMap new_element_map;
667 ElementMap::iterator ei;
668 for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
669 remap.add_mapping((*ei).first, first_index);
670 new_element_map[first_index] = (*ei).second;
671 first_index++;
672 }
673
674 MakeSeqMap new_make_seq_map;
675 MakeSeqMap::iterator si;
676 for (si = _make_seq_map.begin(); si != _make_seq_map.end(); ++si) {
677 remap.add_mapping((*si).first, first_index);
678 new_make_seq_map[first_index] = (*si).second;
679 first_index++;
680 }
681
682 _next_index = first_index;
683
684 _wrapper_map.swap(new_wrapper_map);
685 _function_map.swap(new_function_map);
686 _type_map.swap(new_type_map);
687 _manifest_map.swap(new_manifest_map);
688 _element_map.swap(new_element_map);
689 _make_seq_map.swap(new_make_seq_map);
690
691 // Then, go back through and update all of the internal references.
692 for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
693 (*wi).second.remap_indices(remap);
694 }
695 for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
696 (*fi).second->remap_indices(remap);
697 }
698 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
699 (*ti).second.remap_indices(remap);
700 }
701 for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
702 (*mi).second.remap_indices(remap);
703 }
704 for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
705 (*ei).second.remap_indices(remap);
706 }
707 for (si = _make_seq_map.begin(); si != _make_seq_map.end(); ++si) {
708 (*si).second.remap_indices(remap);
709 }
710 GlobalFunctions::iterator gfi;
711 for (gfi = _global_functions.begin(); gfi != _global_functions.end(); ++gfi) {
712 (*gfi) = remap.map_from(*gfi);
713 }
714 for (gfi = _all_functions.begin(); gfi != _all_functions.end(); ++gfi) {
715 (*gfi) = remap.map_from(*gfi);
716 }
717 GlobalTypes::iterator gti;
718 for (gti = _global_types.begin(); gti != _global_types.end(); ++gti) {
719 (*gti) = remap.map_from(*gti);
720 }
721 for (gti = _all_types.begin(); gti != _all_types.end(); ++gti) {
722 (*gti) = remap.map_from(*gti);
723 }
724 GlobalManifests::iterator gmi;
725 for (gmi = _global_manifests.begin(); gmi != _global_manifests.end(); ++gmi) {
726 (*gmi) = remap.map_from(*gmi);
727 }
728 GlobalElements::iterator gei;
729 for (gei = _global_elements.begin(); gei != _global_elements.end(); ++gei) {
730 (*gei) = remap.map_from(*gei);
731 }
732
733 return _next_index;
734 }
735
736 /**
737 * Writes the database to the indicated stream for later reading.
738 */
739 void InterrogateDatabase::
740 write(std::ostream &out, InterrogateModuleDef *def) const {
741 // Write out the file header.
742 out << def->file_identifier << "\n"
743 << _current_major_version << " " << _current_minor_version << "\n";
744
745 // Write out the module definition.
746 idf_output_string(out, def->library_name);
747 idf_output_string(out, def->library_hash_name);
748 idf_output_string(out, def->module_name);
749 out << "\n";
750
751 // Now write out the components.
752
753 out << _function_map.size() << "\n";
754 FunctionMap::const_iterator fi;
755 for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
756 out << (*fi).first << " " << *(*fi).second << "\n";
757 }
758
759 out << _wrapper_map.size() << "\n";
760 FunctionWrapperMap::const_iterator wi;
761 for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
762 out << (*wi).first << " " << (*wi).second << "\n";
763 }
764
765 out << _type_map.size() << "\n";
766 TypeMap::const_iterator ti;
767 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
768 out << (*ti).first << " " << (*ti).second << "\n";
769 }
770
771 out << _manifest_map.size() << "\n";
772 ManifestMap::const_iterator mi;
773 for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
774 out << (*mi).first << " " << (*mi).second << "\n";
775 }
776
777 out << _element_map.size() << "\n";
778 ElementMap::const_iterator ei;
779 for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
780 out << (*ei).first << " " << (*ei).second << "\n";
781 }
782
783 out << _make_seq_map.size() << "\n";
784 MakeSeqMap::const_iterator si;
785 for (si = _make_seq_map.begin(); si != _make_seq_map.end(); ++si) {
786 out << (*si).first << " " << (*si).second << "\n";
787 }
788 }
789
790 /**
791 * Reads a database from the indicated stream, associated with the indicated
792 * module definition and merges it with any existing data in the database,
793 * according to the expected index numbers specified in the module def. The
794 * header information has already been read.
795 *
796 * Returns true if the file is read successfully, false if there is an error.
797 */
798 bool InterrogateDatabase::
799 read(std::istream &in, InterrogateModuleDef *def) {
800 InterrogateDatabase temp;
801 if (!temp.read_new(in, def)) {
802 return false;
803 }
804
805 if (def->first_index == 0 && def->next_index == 0) {
806 _next_index = temp.remap_indices(_next_index);
807
808 } else {
809 int next = temp.remap_indices(def->first_index);
810 if (next != def->next_index) {
811 interrogatedb_cat->error()
812 << "Module database file " << def->database_filename
813 << " is out of date.\n";
814 return false;
815 }
816 }
817
818 merge_from(temp);
819 return true;
820 }
821
822 /**
823 * Reads in the latest interrogate data.
824 */
825 void InterrogateDatabase::
826 load_latest() {
827 const DSearchPath &searchpath = interrogatedb_path;
828
829 Requests copy_requests;
830 copy_requests.swap(_requests);
831
832 Requests::const_iterator ri;
833 for (ri = copy_requests.begin(); ri != copy_requests.end(); ++ri) {
834 InterrogateModuleDef *def = (*ri);
835
836 if (def->database_filename != nullptr) {
837 Filename filename = def->database_filename;
838 Filename pathname = filename;
839 if (!pathname.empty() && pathname[0] != '/') {
840 pathname = searchpath.find_file(pathname);
841 }
842
843 if (pathname.empty()) {
844 interrogatedb_cat->error()
845 << "Unable to find " << filename << " on " << searchpath << "\n";
846 set_error_flag(true);
847
848 } else {
849
850 pifstream input;
851 pathname.set_text();
852 if (!pathname.open_read(input)) {
853 interrogatedb_cat->error() << "Unable to read " << pathname << ".\n";
854 set_error_flag(true);
855
856 } else {
857 int file_identifier;
858 input >> file_identifier
859 >> _file_major_version >> _file_minor_version;
860
861 if (def->file_identifier != 0 &&
862 file_identifier != def->file_identifier) {
863 interrogatedb_cat->warning()
864 << "Interrogate data in " << pathname
865 << " is out of sync with the compiled-in data"
866 << " (" << file_identifier << " != " << def->file_identifier << ").\n";
867 set_error_flag(true);
868 }
869
870 if (_file_major_version != _current_major_version ||
871 _file_minor_version > _current_minor_version) {
872 interrogatedb_cat->error()
873 << "Cannot read interrogate data in " << pathname
874 << "; database is version " << _file_major_version << "."
875 << _file_minor_version << " while we are expecting "
876 << _current_major_version << "." << _current_minor_version
877 << ".\n";
878 set_error_flag(true);
879
880 } else {
881 if (interrogatedb_cat->is_debug()) {
882 interrogatedb_cat->debug()
883 << "Reading " << filename << "\n";
884 }
885 if (!read(input, def)) {
886 interrogatedb_cat->error()
887 << "Error reading " << pathname << ".\n";
888 set_error_flag(true);
889 }
890 }
891 }
892 }
893 }
894 }
895
896 _requests.clear();
897 }
898
899 /**
900 * Reads from the indicated stream (the header information has already been
901 * read) into the newly-created database. It is an error if the database
902 * already has some data in it.
903 */
904 bool InterrogateDatabase::
905 read_new(std::istream &in, InterrogateModuleDef *def) {
906 // We've already read the header. Read the module definition.
907 idf_input_string(in, def->library_name);
908 idf_input_string(in, def->library_hash_name);
909 idf_input_string(in, def->module_name);
910
911 // Now read all of the components.
912
913 { // Functions.
914 int num_functions;
915 in >> num_functions;
916 if (in.fail()) {
917 return false;
918 }
919
920 while (num_functions > 0) {
921 FunctionIndex index;
922 InterrogateFunction *function = new InterrogateFunction(def);
923 in >> index >> *function;
924 if (in.fail()) {
925 delete function;
926 return false;
927 }
928
929 add_function(index, function);
930 num_functions--;
931 }
932 }
933
934 { // Wrappers.
935 int num_wrappers;
936 in >> num_wrappers;
937 if (in.fail()) {
938 return false;
939 }
940
941 while (num_wrappers > 0) {
942 FunctionWrapperIndex index;
943 InterrogateFunctionWrapper wrapper(def);
944 in >> index >> wrapper;
945 if (in.fail()) {
946 return false;
947 }
948
949 add_wrapper(index, wrapper);
950 num_wrappers--;
951 }
952 }
953
954 { // Types.
955 int num_types;
956 in >> num_types;
957 if (in.fail()) {
958 return false;
959 }
960
961 while (num_types > 0) {
962 TypeIndex index;
963 InterrogateType type(def);
964 in >> index >> type;
965 if (in.fail()) {
966 return false;
967 }
968
969 add_type(index, type);
970 num_types--;
971 }
972 }
973
974 { // Manifests.
975 int num_manifests;
976 in >> num_manifests;
977 if (in.fail()) {
978 return false;
979 }
980
981 while (num_manifests > 0) {
982 ManifestIndex index;
983 InterrogateManifest manifest(def);
984 in >> index >> manifest;
985 if (in.fail()) {
986 return false;
987 }
988
989 add_manifest(index, manifest);
990 num_manifests--;
991 }
992 }
993
994 { // Elements.
995 int num_elements;
996 in >> num_elements;
997 if (in.fail()) {
998 return false;
999 }
1000
1001 while (num_elements > 0) {
1002 ElementIndex index;
1003 InterrogateElement element(def);
1004 in >> index >> element;
1005 if (in.fail()) {
1006 return false;
1007 }
1008
1009 add_element(index, element);
1010 num_elements--;
1011 }
1012 }
1013
1014 { // MakeSeqs.
1015 int num_make_seqs;
1016 in >> num_make_seqs;
1017 if (in.fail()) {
1018 return false;
1019 }
1020
1021 while (num_make_seqs > 0) {
1022 MakeSeqIndex index;
1023 InterrogateMakeSeq make_seq(def);
1024 in >> index >> make_seq;
1025 if (in.fail()) {
1026 return false;
1027 }
1028
1029 add_make_seq(index, make_seq);
1030 num_make_seqs--;
1031 }
1032 }
1033
1034 return true;
1035 }
1036
1037 /**
1038 * Copies all the data from the indicated database into this one. It is an
1039 * error if any index numbers are shared between the two databases.
1040 */
1041 void InterrogateDatabase::
1042 merge_from(const InterrogateDatabase &other) {
1043 // We want to collapse shared types together.
1044 IndexRemapper remap;
1045
1046 // First, we need to build a set of types by name, so we know what types we
1047 // already have.
1048 map<string, TypeIndex> types_by_name;
1049
1050 TypeMap::const_iterator ti;
1051 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
1052 const InterrogateType &type = (*ti).second;
1053 if (type.has_true_name()) {
1054 types_by_name[type.get_true_name()] = (*ti).first;
1055 }
1056 }
1057
1058 // Now go through the other set of types and determine the mapping into this
1059 // set.
1060 for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
1061 TypeIndex other_type_index = (*ti).first;
1062 const InterrogateType &other_type = (*ti).second;
1063
1064 if (other_type.has_name()) {
1065 map<string, TypeIndex>::iterator ni;
1066 ni = types_by_name.find(other_type.get_true_name());
1067 if (ni != types_by_name.end()) {
1068 // Here's a type that we seem to have in common! We'll have to merge
1069 // them.
1070 TypeIndex this_type_index = (*ni).second;
1071 remap.add_mapping(other_type_index, this_type_index);
1072 }
1073 }
1074 }
1075
1076 // Now that we know the full type-to-type mapping, we can copy the new
1077 // types, one at a time.
1078 for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
1079 TypeIndex other_type_index = (*ti).first;
1080 const InterrogateType &other_type = (*ti).second;
1081
1082 if (!remap.in_map(other_type_index)) {
1083 // Here's a new type.
1084 add_type(other_type_index, other_type);
1085 update_type(other_type_index).remap_indices(remap);
1086
1087 } else {
1088 // Here's a type to merge.
1089 TypeIndex this_type_index = remap.map_from(other_type_index);
1090
1091 InterrogateType &this_type = update_type(this_type_index);
1092 if (!this_type.is_global() && other_type.is_global()) {
1093 // If the type is about to become global, we need to add it to our
1094 // global_types list.
1095 _global_types.push_back(this_type_index);
1096 }
1097
1098 InterrogateType merge_type = other_type;
1099 merge_type.remap_indices(remap);
1100 this_type.merge_with(merge_type);
1101 }
1102 }
1103
1104 // And copy all of the functions, wrappers, manifests, and elements.
1105 FunctionMap::const_iterator fi;
1106 for (fi = other._function_map.begin();
1107 fi != other._function_map.end();
1108 ++fi) {
1109 FunctionIndex other_function_index = (*fi).first;
1110 InterrogateFunction *other_function = (*fi).second;
1111 add_function(other_function_index, other_function);
1112 update_function(other_function_index).remap_indices(remap);
1113 }
1114
1115 FunctionWrapperMap::const_iterator wi;
1116 for (wi = other._wrapper_map.begin();
1117 wi != other._wrapper_map.end();
1118 ++wi) {
1119 FunctionWrapperIndex other_wrapper_index = (*wi).first;
1120 const InterrogateFunctionWrapper &other_wrapper = (*wi).second;
1121 add_wrapper(other_wrapper_index, other_wrapper);
1122 update_wrapper(other_wrapper_index).remap_indices(remap);
1123 }
1124
1125 ManifestMap::const_iterator mi;
1126 for (mi = other._manifest_map.begin();
1127 mi != other._manifest_map.end();
1128 ++mi) {
1129 ManifestIndex other_manifest_index = (*mi).first;
1130 const InterrogateManifest &other_manifest = (*mi).second;
1131 add_manifest(other_manifest_index, other_manifest);
1132 update_manifest(other_manifest_index).remap_indices(remap);
1133 }
1134
1135 ElementMap::const_iterator ei;
1136 for (ei = other._element_map.begin();
1137 ei != other._element_map.end();
1138 ++ei) {
1139 ElementIndex other_element_index = (*ei).first;
1140 const InterrogateElement &other_element = (*ei).second;
1141 add_element(other_element_index, other_element);
1142 update_element(other_element_index).remap_indices(remap);
1143 }
1144
1145 MakeSeqMap::const_iterator si;
1146 for (si = other._make_seq_map.begin();
1147 si != other._make_seq_map.end();
1148 ++si) {
1149 MakeSeqIndex other_make_seq_index = (*si).first;
1150 const InterrogateMakeSeq &other_make_seq = (*si).second;
1151 add_make_seq(other_make_seq_index, other_make_seq);
1152 update_make_seq(other_make_seq_index).remap_indices(remap);
1153 }
1154
1155 _lookups_fresh = 0;
1156 }
1157
1158 /**
1159 * Looks up the wrapper definition in the set of module defs that are loaded
1160 * in at runtime and represent the part of the interrogate database that's
1161 * compiled in.
1162 *
1163 * If the wrapper definition is not found, returns false. If it is found,
1164 * returns true and sets def and module_index to the particular module and the
1165 * index within the module where the wrapper is defined.
1166 */
1167 bool InterrogateDatabase::
1168 find_module(FunctionWrapperIndex wrapper, InterrogateModuleDef *&def,
1169 int &module_index) {
1170 if (_modules.empty()) {
1171 return false;
1172 }
1173
1174 int mi = binary_search_module(0, _modules.size(), wrapper);
1175 assert(mi >= 0 && mi < (int)_modules.size());
1176 def = _modules[mi];
1177 module_index = wrapper - def->first_index;
1178
1179 return (wrapper < def->next_index);
1180 }
1181
1182 /**
1183 * Searches for the function module that includes the given function index by
1184 * binary search.
1185 */
1186 int InterrogateDatabase::
1187 binary_search_module(int begin, int end, FunctionIndex function) {
1188 int mid = begin + (end - begin) / 2;
1189 if (mid == begin) {
1190 return mid;
1191 }
1192
1193 int index = _modules[mid]->first_index;
1194 if (index <= function) {
1195 return binary_search_module(mid, end, function);
1196
1197 } else {
1198 return binary_search_module(begin, mid, function);
1199 }
1200 }
1201
1202 /**
1203 * Searches for the particular function wrapper's hash name within a given
1204 * module. Returns the index number local to the module, or -1 if it is not
1205 * found.
1206 */
1207 int InterrogateDatabase::
1208 binary_search_wrapper_hash(InterrogateUniqueNameDef *begin,
1209 InterrogateUniqueNameDef *end,
1210 const string &wrapper_hash_name) {
1211 if (end <= begin) {
1212 return -1;
1213 }
1214
1215 InterrogateUniqueNameDef *mid = begin + (end - begin) / 2;
1216 string name = mid->name;
1217 if (name < wrapper_hash_name) {
1218 return binary_search_wrapper_hash(mid, end, wrapper_hash_name);
1219
1220 } else if (wrapper_hash_name < name) {
1221 return binary_search_wrapper_hash(begin, mid, wrapper_hash_name);
1222
1223 } else {
1224 return mid->index_offset;
1225 }
1226 }
1227
1228 /**
1229 * Builds up the lookup of types by name.
1230 */
1231 void InterrogateDatabase::
1232 freshen_types_by_name() {
1233 _types_by_name.clear();
1234 TypeMap::const_iterator ti;
1235 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
1236 _types_by_name[(*ti).second.get_name()] = (*ti).first;
1237 }
1238 }
1239
1240 /**
1241 * Builds up the lookup of types by scoped name.
1242 */
1243 void InterrogateDatabase::
1244 freshen_types_by_scoped_name() {
1245 _types_by_scoped_name.clear();
1246 TypeMap::const_iterator ti;
1247 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
1248 _types_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
1249 }
1250 }
1251
1252 /**
1253 * Builds up the lookup of types by true name.
1254 */
1255 void InterrogateDatabase::
1256 freshen_types_by_true_name() {
1257 _types_by_true_name.clear();
1258 TypeMap::const_iterator ti;
1259 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
1260 _types_by_true_name[(*ti).second.get_true_name()] = (*ti).first;
1261 }
1262 }
1263
1264 /**
1265 * Builds up the lookup of manifests by name.
1266 */
1267 void InterrogateDatabase::
1268 freshen_manifests_by_name() {
1269 _manifests_by_name.clear();
1270 ManifestMap::const_iterator ti;
1271 for (ti = _manifest_map.begin(); ti != _manifest_map.end(); ++ti) {
1272 _manifests_by_name[(*ti).second.get_name()] = (*ti).first;
1273 }
1274 }
1275
1276 /**
1277 * Builds up the lookup of elements by name.
1278 */
1279 void InterrogateDatabase::
1280 freshen_elements_by_name() {
1281 _elements_by_name.clear();
1282 ElementMap::const_iterator ti;
1283 for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
1284 _elements_by_name[(*ti).second.get_name()] = (*ti).first;
1285 }
1286 }
1287
1288 /**
1289 * Builds up the lookup of elements by scoped name.
1290 */
1291 void InterrogateDatabase::
1292 freshen_elements_by_scoped_name() {
1293 _elements_by_scoped_name.clear();
1294 ElementMap::const_iterator ti;
1295 for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
1296 _elements_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
1297 }
1298 }
1299
1300 /**
1301 * Looks up a type, manifest, or element in the indicated lookup table by
1302 * name. This is an internal support function.
1303 */
1304 int InterrogateDatabase::
1305 lookup(const string &name, Lookup &lookup, LookupType type,
1306 void (InterrogateDatabase::*freshen)()) {
1307 if ((_lookups_fresh & (int)type) == 0) {
1308 // The lookup table isn't fresh; we need to freshen it.
1309 (this->*freshen)();
1310 _lookups_fresh |= (int)type;
1311 }
1312
1313 Lookup::const_iterator li;
1314 li = lookup.find(name);
1315 if (li != lookup.end()) {
1316 return (*li).second;
1317 }
1318 return 0;
1319 }
DSearchPath
This class stores a list of directories that can be searched, in order, to locate a particular file.
Definition: dSearchPath.h:28
DSearchPath::find_file
Filename find_file(const Filename &filename) const
Searches all the directories in the search list for the indicated file, in order.
Definition: dSearchPath.cxx:244
Filename
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
Filename::open_read
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
Definition: filename.cxx:1863
Filename::set_text
void set_text()
Indicates that the filename represents a text file.
Definition: filename.I:424
IndexRemapper
This class manages a mapping of integers to integers.
Definition: indexRemapper.h:29
IndexRemapper::in_map
bool in_map(int from) const
Returns true if the given 'from' integer has been assigned a mapping, false if it has not.
Definition: indexRemapper.cxx:52
IndexRemapper::add_mapping
void add_mapping(int from, int to)
Adds a mapping from the integer 'from' to 'to'.
Definition: indexRemapper.cxx:43
IndexRemapper::clear
void clear()
Removes all mappings from the object.
Definition: indexRemapper.cxx:35
IndexRemapper::map_from
int map_from(int from) const
Returns the integer that the given 'from' integer had been set to map to, or the same integer if noth...
Definition: indexRemapper.cxx:61
InterrogateDatabase
This stores all of the interrogate data and handles reading the data from a disk file when necessary.
Definition: interrogateDatabase.h:36
InterrogateDatabase::get_num_global_types
int get_num_global_types()
Returns the total number of "global" types known to the interrogate database.
Definition: interrogateDatabase.cxx:112
InterrogateDatabase::remove_type
void remove_type(TypeIndex type)
Erases the type from the database.
Definition: interrogateDatabase.cxx:350
InterrogateDatabase::request_module
void request_module(InterrogateModuleDef *def)
Requests that the interrogate data for the given module be made available.
Definition: interrogateDatabase.cxx:60
InterrogateDatabase::get_global_manifest
ManifestIndex get_global_manifest(int n)
Returns the index of the nth global manifest constant known to the interrogate database.
Definition: interrogateDatabase.cxx:214
InterrogateDatabase::get_function
const InterrogateFunction & get_function(FunctionIndex function)
Returns the function associated with the given FunctionIndex, if there is one.
Definition: interrogateDatabase.cxx:266
InterrogateDatabase::update_function
InterrogateFunction & update_function(FunctionIndex function)
Returns a non-const reference to the indicated function, allowing the user to update it.
Definition: interrogateDatabase.cxx:562
InterrogateDatabase::get_current_minor_version
static int get_current_minor_version()
Returns the minor version number currently expected in interrogate database files generated by this c...
Definition: interrogateDatabase.cxx:435
InterrogateDatabase::update_type
InterrogateType & update_type(TypeIndex type)
Returns a non-const reference to the indicated type, allowing the user to update it.
Definition: interrogateDatabase.cxx:551
InterrogateDatabase::get_num_all_functions
int get_num_all_functions()
Returns the total number of functions known to the interrogate database.
Definition: interrogateDatabase.cxx:182
InterrogateDatabase::update_element
InterrogateElement & update_element(ElementIndex element)
Returns a non-const reference to the indicated data element, allowing the user to update it.
Definition: interrogateDatabase.cxx:592
InterrogateDatabase::get_num_all_types
int get_num_all_types()
Returns the total number of types known to the interrogate database.
Definition: interrogateDatabase.cxx:135
InterrogateDatabase::add_manifest
void add_manifest(ManifestIndex index, const InterrogateManifest &manifest)
Adds the indicated manifest constant to the database at the given index number.
Definition: interrogateDatabase.cxx:514
InterrogateDatabase::get_make_seq
const InterrogateMakeSeq & get_make_seq(MakeSeqIndex element)
Returns the make_seq associated with the given MakeSeqIndex, if there is one.
Definition: interrogateDatabase.cxx:334
InterrogateDatabase::get_error_flag
bool get_error_flag()
Returns the global error flag.
Definition: interrogateDatabase.cxx:101
InterrogateDatabase::add_wrapper
void add_wrapper(FunctionWrapperIndex index, const InterrogateFunctionWrapper &wrapper)
Adds the indicated function wrapper to the database at the given index number.
Definition: interrogateDatabase.cxx:502
InterrogateDatabase::get_num_global_elements
int get_num_global_elements()
Returns the total number of global data elements known to the interrogate database.
Definition: interrogateDatabase.cxx:227
InterrogateDatabase::add_type
void add_type(TypeIndex index, const InterrogateType &type)
Adds the indicated type to the database at the given index number.
Definition: interrogateDatabase.cxx:461
InterrogateDatabase::get_manifest
const InterrogateManifest & get_manifest(ManifestIndex manifest)
Returns the manifest constant associated with the given ManifestIndex, if there is one.
Definition: interrogateDatabase.cxx:300
InterrogateDatabase::get_type
const InterrogateType & get_type(TypeIndex type)
Returns the type associated with the given TypeIndex, if there is one.
Definition: interrogateDatabase.cxx:249
InterrogateDatabase::get_element
const InterrogateElement & get_element(ElementIndex element)
Returns the data element associated with the given ElementIndex, if there is one.
Definition: interrogateDatabase.cxx:317
InterrogateDatabase::get_num_global_manifests
int get_num_global_manifests()
Returns the total number of global manifest constants known to the interrogate database.
Definition: interrogateDatabase.cxx:204
InterrogateDatabase::update_manifest
InterrogateManifest & update_manifest(ManifestIndex manifest)
Returns a non-const reference to the indicated manifest constant, allowing the user to update it.
Definition: interrogateDatabase.cxx:582
InterrogateDatabase::get_num_global_functions
int get_num_global_functions()
Returns the total number of global functions known to the interrogate database.
Definition: interrogateDatabase.cxx:158
InterrogateDatabase::update_wrapper
InterrogateFunctionWrapper & update_wrapper(FunctionWrapperIndex wrapper)
Returns a non-const reference to the indicated function wrapper, allowing the user to update it.
Definition: interrogateDatabase.cxx:572
InterrogateDatabase::add_element
void add_element(ElementIndex index, const InterrogateElement &element)
Adds the indicated data element to the database at the given index number.
Definition: interrogateDatabase.cxx:526
InterrogateDatabase::get_file_minor_version
static int get_file_minor_version()
Returns the minor version number of the interrogate database file currently being read.
Definition: interrogateDatabase.cxx:417
InterrogateDatabase::read
bool read(std::istream &in, InterrogateModuleDef *def)
Reads a database from the indicated stream, associated with the indicated module definition and merge...
Definition: interrogateDatabase.cxx:799
InterrogateDatabase::set_error_flag
void set_error_flag(bool error_flag)
Sets the global error flag.
Definition: interrogateDatabase.cxx:444
InterrogateDatabase::get_wrapper
const InterrogateFunctionWrapper & get_wrapper(FunctionWrapperIndex wrapper)
Returns the function wrapper associated with the given FunctionWrapperIndex, if there is one.
Definition: interrogateDatabase.cxx:283
InterrogateDatabase::get_current_major_version
static int get_current_major_version()
Returns the major version number currently expected in interrogate database files generated by this c...
Definition: interrogateDatabase.cxx:426
InterrogateDatabase::get_next_index
int get_next_index()
Returns a new index number suitable for the next thing, that will not be shared with any other index ...
Definition: interrogateDatabase.cxx:453
InterrogateDatabase::get_ptr
static InterrogateDatabase * get_ptr()
Returns the global pointer to the one InterrogateDatabase.
Definition: interrogateDatabase.cxx:42
InterrogateDatabase::get_fptr
void * get_fptr(FunctionWrapperIndex wrapper)
Returns the function pointer associated with the given function wrapper, if it has a pointer availabl...
Definition: interrogateDatabase.cxx:359
InterrogateDatabase::get_all_function
FunctionIndex get_all_function(int n)
Returns the index of the nth function known to the interrogate database.
Definition: interrogateDatabase.cxx:191
InterrogateDatabase::get_all_type
TypeIndex get_all_type(int n)
Returns the index of the nth type known to the interrogate database.
Definition: interrogateDatabase.cxx:144
InterrogateDatabase::get_wrapper_by_unique_name
FunctionWrapperIndex get_wrapper_by_unique_name(const std::string &unique_name)
Looks up the function wrapper corresponding to the given unique name, if available.
Definition: interrogateDatabase.cxx:376
InterrogateDatabase::add_make_seq
void add_make_seq(MakeSeqIndex index, const InterrogateMakeSeq &make_seq)
Adds the indicated make_seq to the database at the given index number.
Definition: interrogateDatabase.cxx:540
InterrogateDatabase::update_make_seq
InterrogateMakeSeq & update_make_seq(MakeSeqIndex make_seq)
Returns a non-const reference to the indicated make_seq, allowing the user to update it.
Definition: interrogateDatabase.cxx:602
InterrogateDatabase::add_function
void add_function(FunctionIndex index, InterrogateFunction *function)
Adds the indicated function to the database at the given index number.
Definition: interrogateDatabase.cxx:486
InterrogateDatabase::remap_indices
int remap_indices(int first_index)
Resequences all of the various index numbers so that all of the functions start at first_index and in...
Definition: interrogateDatabase.cxx:613
InterrogateDatabase::write
void write(std::ostream &out, InterrogateModuleDef *def) const
Writes the database to the indicated stream for later reading.
Definition: interrogateDatabase.cxx:740
InterrogateDatabase::get_file_major_version
static int get_file_major_version()
Returns the major version number of the interrogate database file currently being read.
Definition: interrogateDatabase.cxx:408
InterrogateDatabase::get_global_element
ElementIndex get_global_element(int n)
Returns the index of the nth global data element known to the interrogate database.
Definition: interrogateDatabase.cxx:237
InterrogateDatabase::get_global_type
TypeIndex get_global_type(int n)
Returns the index of the nth global type known to the interrogate database.
Definition: interrogateDatabase.cxx:121
InterrogateDatabase::get_global_function
FunctionIndex get_global_function(int n)
Returns the index of the nth global function known to the interrogate database.
Definition: interrogateDatabase.cxx:168
InterrogateElement
An internal representation of a data element, like a data member or a global variable.
Definition: interrogateElement.h:28
InterrogateElement::is_global
bool is_global() const
Returns true if the element is marked as 'global'.
Definition: interrogateElement.I:68
InterrogateElement::remap_indices
void remap_indices(const IndexRemapper &remap)
Remaps all internal index numbers according to the indicated map.
Definition: interrogateElement.cxx:64
InterrogateFunctionWrapper
An internal representation of a callable function.
Definition: interrogateFunctionWrapper.h:28
InterrogateFunctionWrapper::remap_indices
void remap_indices(const IndexRemapper &remap)
Remaps all internal index numbers according to the indicated map.
Definition: interrogateFunctionWrapper.cxx:76
InterrogateFunction
An internal representation of a function.
Definition: interrogateFunction.h:30
InterrogateFunction::remap_indices
void remap_indices(const IndexRemapper &remap)
Remaps all internal index numbers according to the indicated map.
Definition: interrogateFunction.cxx:91
InterrogateMakeSeq
Represents a synthetic method created via the MAKE_SEQ() macro.
Definition: interrogateMakeSeq.h:26
InterrogateMakeSeq::remap_indices
void remap_indices(const IndexRemapper &remap)
Remaps all internal index numbers according to the indicated map.
Definition: interrogateMakeSeq.cxx:47
InterrogateManifest
An internal representation of a manifest constant.
Definition: interrogateManifest.h:26
InterrogateManifest::remap_indices
void remap_indices(const IndexRemapper &remap)
Remaps all internal index numbers according to the indicated map.
Definition: interrogateManifest.cxx:46
InterrogateType
An internal representation of a type.
Definition: interrogateType.h:30
InterrogateType::is_global
bool is_global() const
Returns true if the type is marked as 'global'.
Definition: interrogateType.I:19
InterrogateType::merge_with
void merge_with(const InterrogateType &other)
Combines type with the other similar definition.
Definition: interrogateType.cxx:122
InterrogateType::remap_indices
void remap_indices(const IndexRemapper &remap)
Remaps all internal index numbers according to the indicated map.
Definition: interrogateType.cxx:208
config_interrogatedb.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
indexRemapper.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
interrogateDatabase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
idf_input_string
void idf_input_string(istream &in, string &str)
Reads the given string from the input file, as previously written by output_string().
Definition: interrogate_datafile.cxx:38
idf_output_string
void idf_output_string(ostream &out, const string &str, char whitespace)
Writes the indicated string to the output file.
Definition: interrogate_datafile.cxx:26
interrogate_datafile.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
InterrogateModuleDef
Definition: interrogate_request.h:52
InterrogateUniqueNameDef
Definition: interrogate_request.h:47