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  */
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  */
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  */
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  */
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::
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  */
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  */
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::
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  */
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::
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  */
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::
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  */
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::
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
359 get_fptr(FunctionWrapperIndex wrapper) {
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  */
409  return _file_major_version;
410 }
411 
412 /**
413  * Returns the minor version number of the interrogate database file currently
414  * being read.
415  */
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  */
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  */
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  */
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  */
454  return _next_index++;
455 }
456 
457 /**
458  * Adds the indicated type to the database at the given index number.
459  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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,
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 }
InterrogateElement::remap_indices
void remap_indices(const IndexRemapper &remap)
Remaps all internal index numbers according to the indicated map.
Definition: interrogateElement.cxx:64
Filename::set_text
void set_text()
Indicates that the filename represents a text file.
Definition: filename.I:424
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_all_type
TypeIndex get_all_type(int n)
Returns the index of the nth type known to the interrogate database.
Definition: interrogateDatabase.cxx:144
Filename::open_read
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
Definition: filename.cxx:1863
InterrogateElement::is_global
bool is_global() const
Returns true if the element is marked as 'global'.
Definition: interrogateElement.I:68
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::remove_type
void remove_type(TypeIndex type)
Erases the type from the database.
Definition: interrogateDatabase.cxx:350
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_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::get_num_all_types
int get_num_all_types()
Returns the total number of types known to the interrogate database.
Definition: interrogateDatabase.cxx:135
InterrogateType::is_global
bool is_global() const
Returns true if the type is marked as 'global'.
Definition: interrogateType.I:19
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
InterrogateFunction
An internal representation of a function.
Definition: interrogateFunction.h:30
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::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::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
InterrogateManifest
An internal representation of a manifest constant.
Definition: interrogateManifest.h:26
config_interrogatedb.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
InterrogateMakeSeq
Represents a synthetic method created via the MAKE_SEQ() macro.
Definition: interrogateMakeSeq.h:26
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
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
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_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::get_error_flag
bool get_error_flag()
Returns the global error flag.
Definition: interrogateDatabase.cxx:101
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::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::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
This stores all of the interrogate data and handles reading the data from a disk file when necessary.
Definition: interrogateDatabase.h:36
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
IndexRemapper
This class manages a mapping of integers to integers.
Definition: indexRemapper.h:29
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
InterrogateType::remap_indices
void remap_indices(const IndexRemapper &remap)
Remaps all internal index numbers according to the indicated map.
Definition: interrogateType.cxx:208
DSearchPath
This class stores a list of directories that can be searched, in order, to locate a particular file.
Definition: dSearchPath.h:28
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_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_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
InterrogateFunctionWrapper::remap_indices
void remap_indices(const IndexRemapper &remap)
Remaps all internal index numbers according to the indicated map.
Definition: interrogateFunctionWrapper.cxx:76
InterrogateType
An internal representation of a type.
Definition: interrogateType.h:30
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
InterrogateManifest::remap_indices
void remap_indices(const IndexRemapper &remap)
Remaps all internal index numbers according to the indicated map.
Definition: interrogateManifest.cxx:46
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_ptr
static InterrogateDatabase * get_ptr()
Returns the global pointer to the one InterrogateDatabase.
Definition: interrogateDatabase.cxx:42
interrogateDatabase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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::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
InterrogateUniqueNameDef
Definition: interrogate_request.h:47
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::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
InterrogateFunction::remap_indices
void remap_indices(const IndexRemapper &remap)
Remaps all internal index numbers according to the indicated map.
Definition: interrogateFunction.cxx:91
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::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
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
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
InterrogateType::merge_with
void merge_with(const InterrogateType &other)
Combines type with the other similar definition.
Definition: interrogateType.cxx:122
InterrogateFunctionWrapper
An internal representation of a callable function.
Definition: interrogateFunctionWrapper.h:28
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::get_num_all_functions
int get_num_all_functions()
Returns the total number of functions known to the interrogate database.
Definition: interrogateDatabase.cxx:182
IndexRemapper::add_mapping
void add_mapping(int from, int to)
Adds a mapping from the integer 'from' to 'to'.
Definition: indexRemapper.cxx:43
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::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::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
InterrogateModuleDef
Definition: interrogate_request.h:52
InterrogateDatabase::set_error_flag
void set_error_flag(bool error_flag)
Sets the global error flag.
Definition: interrogateDatabase.cxx:444
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
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
indexRemapper.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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::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::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
InterrogateMakeSeq::remap_indices
void remap_indices(const IndexRemapper &remap)
Remaps all internal index numbers according to the indicated map.
Definition: interrogateMakeSeq.cxx:47
interrogate_datafile.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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
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
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
Filename
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
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
InterrogateElement
An internal representation of a data element, like a data member or a global variable.
Definition: interrogateElement.h:28
IndexRemapper::clear
void clear()
Removes all mappings from the object.
Definition: indexRemapper.cxx:35