Panda3D

Loading...
Searching...
No Matches
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 */
31InterrogateDatabase::
32InterrogateDatabase() {
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 */
41InterrogateDatabase *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 */
120TypeIndex 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 */
143TypeIndex 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 */
167FunctionIndex 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 */
190FunctionIndex 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 */
213ManifestIndex 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 */
236ElementIndex 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 */
375FunctionWrapperIndex 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::
826load_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::
905read_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 // Older versions of interrogate were not setting these flags.
973 const InterrogateType &itype = get_type(index);
974 FunctionIndex dtor = itype.get_destructor();
975 if (dtor != 0) {
976 update_function(dtor)._flags |= InterrogateFunction::F_destructor;
977 }
978 for (int i = 0; i < itype.number_of_constructors(); ++i) {
979 FunctionIndex ctor = itype.get_constructor(i);
980 update_function(ctor)._flags |= InterrogateFunction::F_constructor;
981 }
982 }
983 }
984
985 { // Manifests.
986 int num_manifests;
987 in >> num_manifests;
988 if (in.fail()) {
989 return false;
990 }
991
992 while (num_manifests > 0) {
993 ManifestIndex index;
994 InterrogateManifest manifest(def);
995 in >> index >> manifest;
996 if (in.fail()) {
997 return false;
998 }
999
1000 add_manifest(index, manifest);
1001 num_manifests--;
1002 }
1003 }
1004
1005 { // Elements.
1006 int num_elements;
1007 in >> num_elements;
1008 if (in.fail()) {
1009 return false;
1010 }
1011
1012 while (num_elements > 0) {
1013 ElementIndex index;
1014 InterrogateElement element(def);
1015 in >> index >> element;
1016 if (in.fail()) {
1017 return false;
1018 }
1019
1020 add_element(index, element);
1021 num_elements--;
1022 }
1023 }
1024
1025 { // MakeSeqs.
1026 int num_make_seqs;
1027 in >> num_make_seqs;
1028 if (in.fail()) {
1029 return false;
1030 }
1031
1032 while (num_make_seqs > 0) {
1033 MakeSeqIndex index;
1034 InterrogateMakeSeq make_seq(def);
1035 in >> index >> make_seq;
1036 if (in.fail()) {
1037 return false;
1038 }
1039
1040 add_make_seq(index, make_seq);
1041 num_make_seqs--;
1042 }
1043 }
1044
1045 return true;
1046}
1047
1048/**
1049 * Copies all the data from the indicated database into this one. It is an
1050 * error if any index numbers are shared between the two databases.
1051 */
1052 void InterrogateDatabase::
1053merge_from(const InterrogateDatabase &other) {
1054 // We want to collapse shared types together.
1055 IndexRemapper remap;
1056
1057 // First, we need to build a set of types by name, so we know what types we
1058 // already have.
1059 map<string, TypeIndex> types_by_name;
1060
1061 TypeMap::const_iterator ti;
1062 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
1063 const InterrogateType &type = (*ti).second;
1064 if (type.has_true_name()) {
1065 types_by_name[type.get_true_name()] = (*ti).first;
1066 }
1067 }
1068
1069 // Now go through the other set of types and determine the mapping into this
1070 // set.
1071 for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
1072 TypeIndex other_type_index = (*ti).first;
1073 const InterrogateType &other_type = (*ti).second;
1074
1075 if (other_type.has_name()) {
1076 map<string, TypeIndex>::iterator ni;
1077 ni = types_by_name.find(other_type.get_true_name());
1078 if (ni != types_by_name.end()) {
1079 // Here's a type that we seem to have in common! We'll have to merge
1080 // them.
1081 TypeIndex this_type_index = (*ni).second;
1082 remap.add_mapping(other_type_index, this_type_index);
1083 }
1084 }
1085 }
1086
1087 // Now that we know the full type-to-type mapping, we can copy the new
1088 // types, one at a time.
1089 for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
1090 TypeIndex other_type_index = (*ti).first;
1091 const InterrogateType &other_type = (*ti).second;
1092
1093 if (!remap.in_map(other_type_index)) {
1094 // Here's a new type.
1095 add_type(other_type_index, other_type);
1096 update_type(other_type_index).remap_indices(remap);
1097
1098 } else {
1099 // Here's a type to merge.
1100 TypeIndex this_type_index = remap.map_from(other_type_index);
1101
1102 InterrogateType &this_type = update_type(this_type_index);
1103 if (!this_type.is_global() && other_type.is_global()) {
1104 // If the type is about to become global, we need to add it to our
1105 // global_types list.
1106 _global_types.push_back(this_type_index);
1107 }
1108
1109 InterrogateType merge_type = other_type;
1110 merge_type.remap_indices(remap);
1111 this_type.merge_with(merge_type);
1112 }
1113 }
1114
1115 // And copy all of the functions, wrappers, manifests, and elements.
1116 FunctionMap::const_iterator fi;
1117 for (fi = other._function_map.begin();
1118 fi != other._function_map.end();
1119 ++fi) {
1120 FunctionIndex other_function_index = (*fi).first;
1121 InterrogateFunction *other_function = (*fi).second;
1122 add_function(other_function_index, other_function);
1123 update_function(other_function_index).remap_indices(remap);
1124 }
1125
1126 FunctionWrapperMap::const_iterator wi;
1127 for (wi = other._wrapper_map.begin();
1128 wi != other._wrapper_map.end();
1129 ++wi) {
1130 FunctionWrapperIndex other_wrapper_index = (*wi).first;
1131 const InterrogateFunctionWrapper &other_wrapper = (*wi).second;
1132 add_wrapper(other_wrapper_index, other_wrapper);
1133 update_wrapper(other_wrapper_index).remap_indices(remap);
1134 }
1135
1136 ManifestMap::const_iterator mi;
1137 for (mi = other._manifest_map.begin();
1138 mi != other._manifest_map.end();
1139 ++mi) {
1140 ManifestIndex other_manifest_index = (*mi).first;
1141 const InterrogateManifest &other_manifest = (*mi).second;
1142 add_manifest(other_manifest_index, other_manifest);
1143 update_manifest(other_manifest_index).remap_indices(remap);
1144 }
1145
1146 ElementMap::const_iterator ei;
1147 for (ei = other._element_map.begin();
1148 ei != other._element_map.end();
1149 ++ei) {
1150 ElementIndex other_element_index = (*ei).first;
1151 const InterrogateElement &other_element = (*ei).second;
1152 add_element(other_element_index, other_element);
1153 update_element(other_element_index).remap_indices(remap);
1154 }
1155
1156 MakeSeqMap::const_iterator si;
1157 for (si = other._make_seq_map.begin();
1158 si != other._make_seq_map.end();
1159 ++si) {
1160 MakeSeqIndex other_make_seq_index = (*si).first;
1161 const InterrogateMakeSeq &other_make_seq = (*si).second;
1162 add_make_seq(other_make_seq_index, other_make_seq);
1163 update_make_seq(other_make_seq_index).remap_indices(remap);
1164 }
1165
1166 _lookups_fresh = 0;
1167}
1168
1169/**
1170 * Looks up the wrapper definition in the set of module defs that are loaded
1171 * in at runtime and represent the part of the interrogate database that's
1172 * compiled in.
1173 *
1174 * If the wrapper definition is not found, returns false. If it is found,
1175 * returns true and sets def and module_index to the particular module and the
1176 * index within the module where the wrapper is defined.
1177 */
1178 bool InterrogateDatabase::
1179find_module(FunctionWrapperIndex wrapper, InterrogateModuleDef *&def,
1180 int &module_index) {
1181 if (_modules.empty()) {
1182 return false;
1183 }
1184
1185 int mi = binary_search_module(0, _modules.size(), wrapper);
1186 assert(mi >= 0 && mi < (int)_modules.size());
1187 def = _modules[mi];
1188 module_index = wrapper - def->first_index;
1189
1190 return (wrapper < def->next_index);
1191}
1192
1193/**
1194 * Searches for the function module that includes the given function index by
1195 * binary search.
1196 */
1197 int InterrogateDatabase::
1198binary_search_module(int begin, int end, FunctionIndex function) {
1199 int mid = begin + (end - begin) / 2;
1200 if (mid == begin) {
1201 return mid;
1202 }
1203
1204 int index = _modules[mid]->first_index;
1205 if (index <= function) {
1206 return binary_search_module(mid, end, function);
1207
1208 } else {
1209 return binary_search_module(begin, mid, function);
1210 }
1211}
1212
1213/**
1214 * Searches for the particular function wrapper's hash name within a given
1215 * module. Returns the index number local to the module, or -1 if it is not
1216 * found.
1217 */
1218 int InterrogateDatabase::
1219binary_search_wrapper_hash(InterrogateUniqueNameDef *begin,
1220 InterrogateUniqueNameDef *end,
1221 const string &wrapper_hash_name) {
1222 if (end <= begin) {
1223 return -1;
1224 }
1225
1226 InterrogateUniqueNameDef *mid = begin + (end - begin) / 2;
1227 string name = mid->name;
1228 if (name < wrapper_hash_name) {
1229 return binary_search_wrapper_hash(mid, end, wrapper_hash_name);
1230
1231 } else if (wrapper_hash_name < name) {
1232 return binary_search_wrapper_hash(begin, mid, wrapper_hash_name);
1233
1234 } else {
1235 return mid->index_offset;
1236 }
1237}
1238
1239/**
1240 * Builds up the lookup of types by name.
1241 */
1242 void InterrogateDatabase::
1243freshen_types_by_name() {
1244 _types_by_name.clear();
1245 TypeMap::const_iterator ti;
1246 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
1247 _types_by_name[(*ti).second.get_name()] = (*ti).first;
1248 }
1249}
1250
1251/**
1252 * Builds up the lookup of types by scoped name.
1253 */
1254 void InterrogateDatabase::
1255freshen_types_by_scoped_name() {
1256 _types_by_scoped_name.clear();
1257 TypeMap::const_iterator ti;
1258 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
1259 _types_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
1260 }
1261}
1262
1263/**
1264 * Builds up the lookup of types by true name.
1265 */
1266 void InterrogateDatabase::
1267freshen_types_by_true_name() {
1268 _types_by_true_name.clear();
1269 TypeMap::const_iterator ti;
1270 for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
1271 _types_by_true_name[(*ti).second.get_true_name()] = (*ti).first;
1272 }
1273}
1274
1275/**
1276 * Builds up the lookup of manifests by name.
1277 */
1278 void InterrogateDatabase::
1279freshen_manifests_by_name() {
1280 _manifests_by_name.clear();
1281 ManifestMap::const_iterator ti;
1282 for (ti = _manifest_map.begin(); ti != _manifest_map.end(); ++ti) {
1283 _manifests_by_name[(*ti).second.get_name()] = (*ti).first;
1284 }
1285}
1286
1287/**
1288 * Builds up the lookup of elements by name.
1289 */
1290 void InterrogateDatabase::
1291freshen_elements_by_name() {
1292 _elements_by_name.clear();
1293 ElementMap::const_iterator ti;
1294 for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
1295 _elements_by_name[(*ti).second.get_name()] = (*ti).first;
1296 }
1297}
1298
1299/**
1300 * Builds up the lookup of elements by scoped name.
1301 */
1302 void InterrogateDatabase::
1303freshen_elements_by_scoped_name() {
1304 _elements_by_scoped_name.clear();
1305 ElementMap::const_iterator ti;
1306 for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
1307 _elements_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
1308 }
1309}
1310
1311/**
1312 * Looks up a type, manifest, or element in the indicated lookup table by
1313 * name. This is an internal support function.
1314 */
1315 int InterrogateDatabase::
1316lookup(const string &name, Lookup &lookup, LookupType type,
1317 void (InterrogateDatabase::*freshen)()) {
1318 if ((_lookups_fresh & (int)type) == 0) {
1319 // The lookup table isn't fresh; we need to freshen it.
1320 (this->*freshen)();
1321 _lookups_fresh |= (int)type;
1322 }
1323
1324 Lookup::const_iterator li;
1325 li = lookup.find(name);
1326 if (li != lookup.end()) {
1327 return (*li).second;
1328 }
1329 return 0;
1330}
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:44
Filename::open_read
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
Definition filename.cxx:1872
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
InterrogateFunction::is_global
bool is_global() const
Returns true if the function is marked as 'global'.
Definition interrogateFunction.I:19
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