18 #include "dcParserDefs.h"
19 #include "dcLexerDefs.h"
20 #include "dcTypedef.h"
21 #include "dcKeyword.h"
22 #include "hashGenerator.h"
26 #include "config_express.h"
27 #include "virtualFileSystem.h"
28 #include "executionEnvironment.h"
29 #include "configVariableList.h"
40 _all_objects_valid =
true;
41 _inherited_fields_stale =
false;
43 setup_default_keywords();
64 Declarations::iterator di;
65 for (di = _declarations.begin(); di != _declarations.end(); ++di) {
68 for (di = _things_to_delete.begin(); di != _things_to_delete.end(); ++di) {
74 _things_by_name.clear();
76 _typedefs_by_name.clear();
78 _declarations.clear();
79 _things_to_delete.clear();
80 setup_default_keywords();
82 _all_objects_valid =
true;
83 _inherited_fields_stale =
false;
98 (
"dc-file", PRC_DESC(
"The list of dc files to load."));
100 if (dc_files.size() == 0) {
101 cerr <<
"No files specified via dc-file Config.prc variable!\n";
105 int size = dc_files.size();
109 for (
int i = size - 1; i >= 0; --i) {
112 if (!
read(filename)) {
120 #endif // WITHIN_PANDA
140 if (in == (istream *)NULL) {
141 cerr <<
"Cannot open " << filename <<
" for reading.\n";
144 bool okflag =
read(*in, filename);
154 #else // WITHIN_PANDA
157 in.open(filename.c_str());
160 cerr <<
"Cannot open " << filename <<
" for reading.\n";
164 return read(in, filename);
166 #endif // WITHIN_PANDA
186 read(istream &in,
const string &filename) {
187 cerr <<
"DCFile::read of " << filename <<
"\n";
188 dc_init_parser(in, filename, *
this);
192 return (dc_error_count() == 0);
213 out.open(filename.c_str());
217 cerr <<
"Can't open " << filename <<
" for output.\n";
220 return write(out, brief);
233 write(ostream &out,
bool brief)
const {
234 if (!_imports.empty()) {
235 Imports::const_iterator ii;
236 for (ii = _imports.begin(); ii != _imports.end(); ++ii) {
237 const Import &
import = (*ii);
238 if (
import._symbols.empty()) {
239 out <<
"import " <<
import._module <<
"\n";
241 out <<
"from " <<
import._module <<
" import ";
242 ImportSymbols::const_iterator si =
import._symbols.begin();
245 while (si !=
import._symbols.end()) {
255 Declarations::const_iterator di;
256 for (di = _declarations.begin(); di != _declarations.end(); ++di) {
257 (*di)->write(out, brief, 0);
272 return _classes.size();
282 nassertr(n >= 0 && n < (
int)_classes.size(), NULL);
294 ThingsByName::const_iterator ni;
295 ni = _things_by_name.find(name);
296 if (ni != _things_by_name.end()) {
297 return (*ni).second->as_class();
311 ThingsByName::const_iterator ni;
312 ni = _things_by_name.find(name);
313 if (ni != _things_by_name.end()) {
314 return (*ni).second->as_switch();
334 nassertr(dc_multiple_inheritance, NULL);
336 if (index_number >= 0 && index_number < (
int)_fields_by_index.size()) {
337 return _fields_by_index[index_number];
351 return _imports.size();
362 nassertr(n >= 0 && n < (
int)_imports.size(), string());
363 return _imports[n]._module;
376 nassertr(n >= 0 && n < (
int)_imports.size(), 0);
377 return _imports[n]._symbols.size();
388 nassertr(n >= 0 && n < (
int)_imports.size(), string());
389 nassertr(i >= 0 && i < (
int)_imports[n]._symbols.size(), string());
390 return _imports[n]._symbols[i];
401 return _typedefs.size();
411 nassertr(n >= 0 && n < (
int)_typedefs.size(), NULL);
423 TypedefsByName::const_iterator ni;
424 ni = _typedefs_by_name.find(name);
425 if (ni != _typedefs_by_name.end()) {
462 if (keyword == (
const DCKeyword *)NULL) {
464 if (keyword != (
const DCKeyword *)NULL) {
467 ((
DCFile *)
this)->_keywords.add_keyword(keyword);
498 if (dc_virtual_inheritance) {
500 if (dc_sort_inheritance_by_file) {
507 hashgen.
add_int(_classes.size());
508 Classes::const_iterator ci;
509 for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
510 (*ci)->generate_hash(hashgen);
526 bool inserted = _things_by_name.insert
527 (ThingsByName::value_type(dclass->
get_name(), dclass)).second;
537 _classes.push_back(dclass);
540 _all_objects_valid =
false;
544 _declarations.push_back(dclass);
546 _things_to_delete.push_back(dclass);
564 bool inserted = _things_by_name.insert
565 (ThingsByName::value_type(dswitch->
get_name(), dswitch)).second;
572 _declarations.push_back(dswitch);
588 import._module = import_module;
589 _imports.push_back(
import);
603 nassertv(!_imports.empty());
604 _imports.back()._symbols.push_back(import_symbol);
618 bool inserted = _typedefs_by_name.insert
619 (TypedefsByName::value_type(dtypedef->
get_name(), dtypedef)).second;
626 _typedefs.push_back(dtypedef);
629 _all_objects_valid =
false;
633 _declarations.push_back(dtypedef);
635 _things_to_delete.push_back(dtypedef);
655 _declarations.push_back(keyword);
674 _things_to_delete.push_back(decl);
687 field->
set_number((
int)_fields_by_index.size());
688 _fields_by_index.push_back(field);
698 setup_default_keywords() {
703 static KeywordDef default_keywords[] = {
704 {
"required", 0x0001 },
705 {
"broadcast", 0x0002 },
706 {
"ownrecv", 0x0004 },
709 {
"clsend", 0x0020 },
710 {
"clrecv", 0x0040 },
711 {
"ownsend", 0x0080 },
712 {
"airecv", 0x0100 },
717 for (
int i = 0; default_keywords[i].name != NULL; ++i) {
720 default_keywords[i].flag);
723 _things_to_delete.push_back(keyword);
734 rebuild_inherited_fields() {
735 _inherited_fields_stale =
false;
737 Classes::iterator ci;
738 for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
739 (*ci)->clear_inherited_fields();
741 for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
742 (*ci)->rebuild_inherited_fields();
bool is_struct() const
Returns true if the class has been identified with the "struct" keyword in the dc file...
This represents a single keyword declaration in the dc file.
void add_import_symbol(const string &import_symbol)
Adds a new name to the list of symbols that are to be explicitly imported from the most-recently adde...
void set_number(int number)
Assigns the unique number to this typedef.
const DCKeyword * get_keyword_by_name(const string &name) const
Returns the keyword that has the indicated name, or NULL if there is no such keyword name...
const DCKeyword * get_keyword(int n) const
Returns the nth keyword in the list.
This represents a single typedef declaration in the dc file.
int get_num_import_symbols(int n) const
Returns the number of symbols explicitly imported by the nth import line.
DCField * get_field_by_index(int index_number) const
Returns a pointer to the one DCField that has the indicated index number, of all the DCFields across ...
int get_num_keywords() const
Returns the number of keywords read from the .dc file(s).
const string & get_name() const
Returns the name of this class.
int get_num_keywords() const
Returns the number of keywords in the list.
void add_int(int num)
Adds another integer to the hash so far.
DCTypedef * get_typedef(int n) const
Returns the nth typedef read from the .dc file(s).
A single field of a Distributed Class, either atomic or molecular.
A hierarchy of directories and files that appears to be one continuous file system, even though the files may originate from several different sources that may not be related to the actual OS's file system.
DCTypedef * get_typedef_by_name(const string &name) const
Returns the typedef that has the indicated name, or NULL if there is no such typedef name...
bool add_class(DCClass *dclass)
Adds the newly-allocated distributed class definition to the file.
void set_text()
Indicates that the filename represents a text file.
void set_number(int number)
Assigns the unique number to this field.
bool read(Filename filename)
Opens and reads the indicated .dc file by name.
This represents a switch statement, which can appear inside a class body and represents two or more a...
Defines a particular DistributedClass as read from an input .dc file.
unsigned long get_hash() const
Returns a 32-bit hash index associated with this file.
string get_import_module(int n) const
Returns the module named by the nth import line read from the .dc file(s).
DCSwitch * get_switch_by_name(const string &name) const
Returns the switch that has the indicated name, or NULL if there is no such switch.
bool add_typedef(DCTypedef *dtypedef)
Adds the newly-allocated distributed typedef definition to the file.
void set_new_index_number(DCField *field)
Sets the next sequential available index number on the indicated field.
string get_import_symbol(int n, int i) const
Returns the ith symbol named by the nth import line read from the .dc file(s).
bool is_implicit_typedef() const
Returns true if the typedef has been flagged as an implicit typedef, meaning it was created for a DCC...
This class is similar to ConfigVariable, but it reports its value as a list of strings.
static void close_read_file(istream *stream)
Closes a file opened by a previous call to open_read_file().
Represents the complete list of Distributed Class descriptions as read from a .dc file...
DCClass * get_class(int n) const
Returns the nth class read from the .dc file(s).
bool add_switch(DCSwitch *dswitch)
Adds the newly-allocated switch definition to the file.
int get_num_classes() const
Returns the number of classes read from the .dc file(s).
void generate_hash(HashGenerator &hashgen) const
Accumulates the properties of this file into the hash.
The name of a file, such as a texture file or an Egg file.
int get_num_import_modules() const
Returns the number of import lines read from the .dc file(s).
This is a common interface for a declaration in a DC file.
const string & get_name() const
Returns the name of this typedef.
void add_thing_to_delete(DCDeclaration *decl)
Adds the indicated declaration to the list of declarations that are not reported with the file...
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
void add_import_module(const string &import_module)
Adds a new name to the list of names of Python modules that are to be imported by the client or AI to...
This class generates an arbitrary hash number from a sequence of ints.
bool is_bogus_typedef() const
Returns true if the typedef has been flagged as a bogus typedef.
const string & get_name() const
Returns the name of this switch.
istream * open_read_file(const Filename &filename, bool auto_unwrap) const
Convenience function; returns a newly allocated istream if the file exists and can be read...
bool add_keyword(const DCKeyword *keyword)
Adds the indicated keyword to the list.
bool write(Filename filename, bool brief) const
Opens the indicated filename for output and writes a parseable description of all the known distribut...
void clear()
Removes all of the classes defined within the DCFile and prepares it for reading a new file...
void clear_keywords()
Removes all keywords from the field.
bool is_bogus_class() const
Returns true if the class has been flagged as a bogus class.
int get_num_typedefs() const
Returns the number of typedefs read from the .dc file(s).
DCClass * get_class_by_name(const string &name) const
Returns the class that has the indicated name, or NULL if there is no such class. ...
unsigned long get_hash() const
Returns the hash number generated.
bool open_write(ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
static string expand_string(const string &str)
Reads the string, looking for environment variable names marked by a $.
bool add_keyword(const string &name)
Adds the indicated keyword string to the list of keywords known to the DCFile.
const DCKeyword * get_keyword_by_name(const string &name) const
Returns the keyword in the list with the indicated name, or NULL if there is no keyword in the list w...
const DCKeyword * get_keyword(int n) const
Returns the nth keyword read from the .dc file(s).
void set_number(int number)
Assigns the unique number to this class.
static Filename from_os_specific(const string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes, and no drive letter) based on the supplied filename string that describes a filename in the local system conventions (for instance, on Windows, it may use backslashes or begin with a drive letter and a colon).