more parsing games

This commit is contained in:
David Rose 2004-10-05 06:12:50 +00:00
parent e397109f73
commit b020b2047a
17 changed files with 569 additions and 67 deletions

View File

@ -20,6 +20,7 @@
#include "xParserDefs.h" #include "xParserDefs.h"
#include "xLexerDefs.h" #include "xLexerDefs.h"
#include "xFileTemplate.h" #include "xFileTemplate.h"
#include "xFileDataObject.h"
#include "config_xfile.h" #include "config_xfile.h"
#include "standard_templates.h" #include "standard_templates.h"
#include "zStream.h" #include "zStream.h"
@ -36,7 +37,7 @@ PT(XFile) XFile::_standard_templates;
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
XFile:: XFile::
XFile() : XFileNode("") { XFile() : XFileNode(this, "") {
_major_version = 3; _major_version = 3;
_minor_version = 2; _minor_version = 2;
_format_type = FT_text; _format_type = FT_text;
@ -53,21 +54,6 @@ XFile::
clear(); clear();
} }
////////////////////////////////////////////////////////////////////
// Function: XFile::add_child
// Access: Public, Virtual
// Description: Adds the indicated node as a child of this node.
////////////////////////////////////////////////////////////////////
void XFile::
add_child(XFileNode *node) {
XFileNode::add_child(node);
if (node->is_of_type(XFileTemplate::get_class_type())) {
XFileTemplate *xtemplate = DCAST(XFileTemplate, node);
_templates_by_guid[xtemplate->get_guid()] = xtemplate;
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: XFile::clear // Function: XFile::clear
// Access: Public, Virtual // Access: Public, Virtual
@ -77,6 +63,8 @@ add_child(XFileNode *node) {
void XFile:: void XFile::
clear() { clear() {
XFileNode::clear(); XFileNode::clear();
_nodes_by_guid.clear();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -192,7 +180,7 @@ write(Filename filename) const {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// function: XFile::write // Function: XFile::write
// Access: Public // Access: Public
// Description: Writes a parseable description of all the known // Description: Writes a parseable description of all the known
// nodes and templates to the stream. // nodes and templates to the stream.
@ -241,10 +229,11 @@ find_template(const string &name) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
XFileTemplate *XFile:: XFileTemplate *XFile::
find_template(const WindowsGuid &guid) const { find_template(const WindowsGuid &guid) const {
TemplatesByGuid::const_iterator gi; NodesByGuid::const_iterator gi;
gi = _templates_by_guid.find(guid); gi = _nodes_by_guid.find(guid);
if (gi != _templates_by_guid.end()) { if (gi != _nodes_by_guid.end() &&
return (*gi).second; (*gi).second->is_of_type(XFileTemplate::get_class_type())) {
return DCAST(XFileTemplate, (*gi).second);
} }
const XFile *standard_templates = get_standard_templates(); const XFile *standard_templates = get_standard_templates();
@ -255,6 +244,41 @@ find_template(const WindowsGuid &guid) const {
return NULL; return NULL;
} }
////////////////////////////////////////////////////////////////////
// Function: XFile::find_data_object
// Access: Public
// Description: Returns the data object associated with the indicated
// name, if any, or NULL if none.
////////////////////////////////////////////////////////////////////
XFileDataObject *XFile::
find_data_object(const string &name) const {
XFileNode *child = find_descendent(name);
if (child != (XFileNode *)NULL &&
child->is_of_type(XFileDataObject::get_class_type())) {
return DCAST(XFileDataObject, child);
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: XFile::find_data_object
// Access: Public
// Description: Returns the data object associated with the indicated
// GUID, if any, or NULL if none.
////////////////////////////////////////////////////////////////////
XFileDataObject *XFile::
find_data_object(const WindowsGuid &guid) const {
NodesByGuid::const_iterator gi;
gi = _nodes_by_guid.find(guid);
if (gi != _nodes_by_guid.end() &&
(*gi).second->is_of_type(XFileDataObject::get_class_type())) {
return DCAST(XFileDataObject, (*gi).second);
}
return NULL;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: XFile::write_text // Function: XFile::write_text
// Access: Public, Virtual // Access: Public, Virtual

View File

@ -27,6 +27,7 @@
#include "pointerTo.h" #include "pointerTo.h"
class XFileTemplate; class XFileTemplate;
class XFileDataObject;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : XFile // Class : XFile
@ -39,7 +40,6 @@ public:
XFile(); XFile();
~XFile(); ~XFile();
virtual void add_child(XFileNode *node);
virtual void clear(); virtual void clear();
bool read(Filename filename); bool read(Filename filename);
@ -51,6 +51,9 @@ public:
XFileTemplate *find_template(const string &name) const; XFileTemplate *find_template(const string &name) const;
XFileTemplate *find_template(const WindowsGuid &guid) const; XFileTemplate *find_template(const WindowsGuid &guid) const;
XFileDataObject *find_data_object(const string &name) const;
XFileDataObject *find_data_object(const WindowsGuid &guid) const;
virtual void write_text(ostream &out, int indent_level) const; virtual void write_text(ostream &out, int indent_level) const;
enum FormatType { enum FormatType {
@ -73,8 +76,8 @@ private:
FormatType _format_type; FormatType _format_type;
FloatSize _float_size; FloatSize _float_size;
typedef pmap<WindowsGuid, XFileTemplate *> TemplatesByGuid; typedef pmap<WindowsGuid, XFileNode *> NodesByGuid;
TemplatesByGuid _templates_by_guid; NodesByGuid _nodes_by_guid;
static PT(XFile) _standard_templates; static PT(XFile) _standard_templates;
@ -94,6 +97,8 @@ public:
private: private:
static TypeHandle _type_handle; static TypeHandle _type_handle;
friend class XFileNode;
}; };
#include "xFile.I" #include "xFile.I"

View File

@ -23,10 +23,58 @@
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE XFileDataDef:: INLINE XFileDataDef::
XFileDataDef(XFileDataDef::Type type, const string &name, XFileDataDef(XFile *x_file, const string &name,
XFileTemplate *xtemplate) : XFileDataDef::Type type, XFileTemplate *xtemplate) :
XFileNode(name), XFileNode(x_file, name),
_type(type), _type(type),
_template(xtemplate) _template(xtemplate)
{ {
} }
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::get_data_type
// Access: Public
// Description: Returns the primitive type of this element, or
// T_template if this represents a nested template
// object.
////////////////////////////////////////////////////////////////////
INLINE XFileDataDef::Type XFileDataDef::
get_data_type() const {
return _type;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::get_template
// Access: Public
// Description: If get_data_type() returned T_template, this returns
// the particular template pointer that this object
// represents.
////////////////////////////////////////////////////////////////////
INLINE XFileTemplate *XFileDataDef::
get_template() const {
return _template;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::get_num_array_defs
// Access: Public
// Description: Returns the number of dimensions of array elements on
// this data object, or 0 if the data object is not an
// array.
////////////////////////////////////////////////////////////////////
INLINE int XFileDataDef::
get_num_array_defs() const {
return _array_def.size();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataDef::get_array_def
// Access: Public
// Description: Returns the description of the nth dimension of array
// elements on this data object.
////////////////////////////////////////////////////////////////////
INLINE const XFileArrayDef &XFileDataDef::
get_array_def(int i) const {
nassertr(i >= 0 && i < (int)_array_def.size(), _array_def[0]);
return _array_def[i];
}

View File

@ -30,7 +30,10 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : XFileDataDef // Class : XFileDataDef
// Description : A definition of a single data element appearing // Description : A definition of a single data element appearing
// within a template record. // within a template record. This class represents the
// *definition* of the data element (e.g. DWORD
// nVertices); see XFileDataObject for its *value*
// (e.g. 12).
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class XFileDataDef : public XFileNode { class XFileDataDef : public XFileNode {
public: public:
@ -49,13 +52,19 @@ public:
T_template, T_template,
}; };
INLINE XFileDataDef(Type type, const string &name, INLINE XFileDataDef(XFile *x_file, const string &name,
XFileTemplate *xtemplate = NULL); Type type, XFileTemplate *xtemplate = NULL);
virtual ~XFileDataDef(); virtual ~XFileDataDef();
virtual void clear(); virtual void clear();
void add_array_def(const XFileArrayDef &array_def); void add_array_def(const XFileArrayDef &array_def);
INLINE Type get_data_type() const;
INLINE XFileTemplate *get_template() const;
INLINE int get_num_array_defs() const;
INLINE const XFileArrayDef &get_array_def(int i) const;
virtual void write_text(ostream &out, int indent_level) const; virtual void write_text(ostream &out, int indent_level) const;
private: private:

View File

@ -23,6 +23,121 @@
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE XFileDataObject:: INLINE XFileDataObject::
XFileDataObject(const string &name) : XFileNode(name) XFileDataObject(XFile *x_file, const string &name) :
XFileNode(x_file, name)
{ {
} }
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::get_data_def
// Access: Public
// Description: Returns the data object that this object is
// represented by, if any, or NULL if there is none.
////////////////////////////////////////////////////////////////////
INLINE XFileDataDef *XFileDataObject::
get_data_def() const {
return _data_def;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::i
// Access: Public
// Description: Unambiguously returns the object's representation as
// an integer, or 0 if the object has no integer
// representation. See also the typecast operators, and
// get_data_def() to determine what kind of
// representation this object has.
////////////////////////////////////////////////////////////////////
INLINE int XFileDataObject::
i() const {
return as_integer_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::d
// Access: Public
// Description: Unambiguously returns the object's representation as
// a double, or 0.0 if the object has no double
// representation. See also the typecast operators, and
// get_data_def() to determine what kind of
// representation this object has.
////////////////////////////////////////////////////////////////////
INLINE double XFileDataObject::
d() const {
return as_double_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::s
// Access: Public
// Description: Unambiguously returns the object's representation as
// a string, or empty string if the object has no string
// representation. See also the typecast operators, and
// get_data_def() to determine what kind of
// representation this object has.
////////////////////////////////////////////////////////////////////
INLINE string XFileDataObject::
s() const {
return as_string_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::int typecast operator
// Access: Public
// Description: Returns the object's representation as an integer, or
// 0 if the object has no integer representation.
////////////////////////////////////////////////////////////////////
INLINE XFileDataObject::
operator int () const {
return as_integer_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::double typecast operator
// Access: Public
// Description: Returns the object's representation as a double, or
// 0.0 if the object has no integer representation.
////////////////////////////////////////////////////////////////////
INLINE XFileDataObject::
operator double () const {
return as_double_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::string typecast operator
// Access: Public
// Description: Returns the object's representation as a string, or
// empty string if the object has no string
// representation.
////////////////////////////////////////////////////////////////////
INLINE XFileDataObject::
operator string () const {
return as_string_value();
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::operator [] (int)
// Access: Public
// Description: Returns the nth nested object within this object.
// Call get_num_children() to determine the number of
// nested objects.
////////////////////////////////////////////////////////////////////
INLINE const XFileDataObject &XFileDataObject::
operator [] (int n) const {
nassertr(n >= 0 && n < get_num_children(), *this);
return *DCAST(XFileDataObject, get_child(n));
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::operator [] (string)
// Access: Public
// Description: Returns the named nested object within this object.
// It is an error if the named object does not exist.
// Call find_child() instead if there is any doubt.
////////////////////////////////////////////////////////////////////
INLINE const XFileDataObject &XFileDataObject::
operator [] (const string &name) const {
XFileNode *child = find_child(name);
nassertr(child != (XFileNode *)NULL, *this);
return *DCAST(XFileDataObject, child);
}

View File

@ -19,3 +19,36 @@
#include "xFileDataObject.h" #include "xFileDataObject.h"
TypeHandle XFileDataObject::_type_handle; TypeHandle XFileDataObject::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::as_integer_value
// Access: Protected, Virtual
// Description: Returns the object's representation as an integer, if
// it has one.
////////////////////////////////////////////////////////////////////
int XFileDataObject::
as_integer_value() const {
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::as_double_value
// Access: Protected, Virtual
// Description: Returns the object's representation as a double, if
// it has one.
////////////////////////////////////////////////////////////////////
double XFileDataObject::
as_double_value() const {
return 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObject::as_string_value
// Access: Protected, Virtual
// Description: Returns the object's representation as a string, if
// it has one.
////////////////////////////////////////////////////////////////////
string XFileDataObject::
as_string_value() const {
return string();
}

View File

@ -21,6 +21,9 @@
#include "pandatoolbase.h" #include "pandatoolbase.h"
#include "xFileNode.h" #include "xFileNode.h"
#include "xFileDataDef.h"
#include "pointerTo.h"
#include "dcast.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : XFileDataObject // Class : XFileDataObject
@ -30,8 +33,27 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class XFileDataObject : public XFileNode { class XFileDataObject : public XFileNode {
public: public:
INLINE XFileDataObject(const string &name); INLINE XFileDataObject(XFile *x_file, const string &name);
INLINE XFileDataDef *get_data_def() const;
INLINE int i() const;
INLINE double d() const;
INLINE string s() const;
INLINE operator int () const;
INLINE operator double () const;
INLINE operator string () const;
INLINE const XFileDataObject &operator [] (int n) const;
INLINE const XFileDataObject &operator [] (const string &name) const;
protected:
virtual int as_integer_value() const;
virtual double as_double_value() const;
virtual string as_string_value() const;
PT(XFileDataDef) _data_def;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;

View File

@ -27,8 +27,9 @@ TypeHandle XFileDataObjectTemplate::_type_handle;
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
XFileDataObjectTemplate:: XFileDataObjectTemplate::
XFileDataObjectTemplate(XFileTemplate *xtemplate, const string &name) : XFileDataObjectTemplate(XFile *x_file, const string &name,
XFileDataObject(name), XFileTemplate *xtemplate) :
XFileDataObject(x_file, name),
_template(xtemplate) _template(xtemplate)
{ {
} }
@ -51,3 +52,72 @@ write_text(ostream &out, int indent_level) const {
indent(out, indent_level) indent(out, indent_level)
<< "}\n"; << "}\n";
} }
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectTemplate::add_parse_object
// Access: Public
// Description: Adds the indicated object as a nested object
// encountered in the parser. It will later be
// processed by finalize_parse_data().
////////////////////////////////////////////////////////////////////
void XFileDataObjectTemplate::
add_parse_object(XFileDataObjectTemplate *object, bool reference) {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectTemplate::add_parse_double
// Access: Public
// Description: Adds the indicated list of doubles as a data element
// encountered in the parser. It will later be
// processed by finalize_parse_data().
////////////////////////////////////////////////////////////////////
void XFileDataObjectTemplate::
add_parse_double(PTA_double double_list, char separator) {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectTemplate::add_parse_int
// Access: Public
// Description: Adds the indicated list of ints as a data element
// encountered in the parser. It will later be
// processed by finalize_parse_data().
////////////////////////////////////////////////////////////////////
void XFileDataObjectTemplate::
add_parse_int(PTA_int int_list, char separator) {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectTemplate::add_parse_string
// Access: Public
// Description: Adds the indicated string as a data element
// encountered in the parser. It will later be
// processed by finalize_parse_data().
////////////////////////////////////////////////////////////////////
void XFileDataObjectTemplate::
add_parse_string(const string &str, char separator) {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectTemplate::add_parse_separator
// Access: Public
// Description: Adds the indicated separator character as an isolated
// separator encountered in the parser. It will later
// be processed by finalize_parse_data().
////////////////////////////////////////////////////////////////////
void XFileDataObjectTemplate::
add_parse_separator(char separator) {
}
////////////////////////////////////////////////////////////////////
// Function: XFileDataObjectTemplate::finalize_parse_data
// Access: Public
// Description: Processes all of the data elements added by
// add_parse_*(), checks them for syntactic and semantic
// correctness against the Template definition, and
// stores the appropriate child data elements. Returns
// true on success, false if there is a mismatch.
////////////////////////////////////////////////////////////////////
bool XFileDataObjectTemplate::
finalize_parse_data() {
return true;
}

View File

@ -23,6 +23,8 @@
#include "xFileDataObject.h" #include "xFileDataObject.h"
#include "xFileTemplate.h" #include "xFileTemplate.h"
#include "pointerTo.h" #include "pointerTo.h"
#include "pta_int.h"
#include "pta_double.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : XFileDataObjectTemplate // Class : XFileDataObjectTemplate
@ -34,14 +36,48 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class XFileDataObjectTemplate : public XFileDataObject { class XFileDataObjectTemplate : public XFileDataObject {
public: public:
XFileDataObjectTemplate(XFileTemplate *xtemplate, const string &name); XFileDataObjectTemplate(XFile *x_file, const string &name,
XFileTemplate *xtemplate);
INLINE XFileTemplate *get_template() const; INLINE XFileTemplate *get_template() const;
virtual void write_text(ostream &out, int indent_level) const; virtual void write_text(ostream &out, int indent_level) const;
public:
void add_parse_object(XFileDataObjectTemplate *object, bool reference);
void add_parse_double(PTA_double double_list, char separator);
void add_parse_int(PTA_int int_list, char separator);
void add_parse_string(const string &str, char separator);
void add_parse_separator(char separator);
bool finalize_parse_data();
private: private:
PT(XFileTemplate) _template; PT(XFileTemplate) _template;
// This class is used to fill up the data as the values are parsed.
// It only has a temporary lifespan; it will be converted into
// actual data by finalize_parse_data().
enum ParseFlags {
PF_object = 0x001,
PF_reference = 0x002,
PF_double = 0x004,
PF_int = 0x008,
PF_string = 0x010,
PF_comma = 0x020,
PF_semicolon = 0x040,
};
class ParseData {
public:
PT(XFileDataObjectTemplate) _object;
PTA_double _double_list;
PTA_int _int_list;
string _string;
int _parse_flags;
};
typedef pvector<ParseData> ParseDataList;
ParseDataList _parse_data_list;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {

View File

@ -17,6 +17,8 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#include "xFileNode.h" #include "xFileNode.h"
#include "windowsGuid.h"
#include "xFile.h"
TypeHandle XFileNode::_type_handle; TypeHandle XFileNode::_type_handle;
@ -26,7 +28,9 @@ TypeHandle XFileNode::_type_handle;
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
XFileNode:: XFileNode::
XFileNode(const string &name) : Namable(name) XFileNode(XFile *x_file, const string &name) :
Namable(name),
_x_file(x_file)
{ {
} }
@ -57,6 +61,53 @@ find_child(const string &name) const {
return NULL; return NULL;
} }
////////////////////////////////////////////////////////////////////
// Function: XFileNode::find_descendent
// Access: Public
// Description: Returns the first child or descendent found with the
// indicated name after a depth-first search, if any, or
// NULL if none.
////////////////////////////////////////////////////////////////////
XFileNode *XFileNode::
find_descendent(const string &name) const {
XFileNode *child = find_child(name);
if (child != (XFileNode *)NULL) {
return child;
}
Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) {
XFileNode *child = (*ci)->find_descendent(name);
if (child != (XFileNode *)NULL){
return child;
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::has_guid
// Access: Public, Virtual
// Description: Returns true if this node has a GUID associated.
////////////////////////////////////////////////////////////////////
bool XFileNode::
has_guid() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: XFileNode::get_guid
// Access: Public, Virtual
// Description: If has_guid() returned true, returns the particular
// GUID associated with this node.
////////////////////////////////////////////////////////////////////
const WindowsGuid &XFileNode::
get_guid() const {
static WindowsGuid empty;
return empty;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: XFileNode::add_child // Function: XFileNode::add_child
// Access: Public, Virtual // Access: Public, Virtual
@ -68,6 +119,9 @@ add_child(XFileNode *node) {
if (node->has_name()) { if (node->has_name()) {
_children_by_name[node->get_name()] = node; _children_by_name[node->get_name()] = node;
} }
if (node->has_guid()) {
_x_file->_nodes_by_guid[node->get_guid()] = node;
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -27,6 +27,9 @@
#include "pvector.h" #include "pvector.h"
#include "pmap.h" #include "pmap.h"
class XFile;
class WindowsGuid;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : XFileNode // Class : XFileNode
// Description : A single node of an X file. This may be either a // Description : A single node of an X file. This may be either a
@ -34,12 +37,16 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class XFileNode : public TypedReferenceCount, public Namable { class XFileNode : public TypedReferenceCount, public Namable {
public: public:
XFileNode(const string &name); XFileNode(XFile *x_file, const string &name);
virtual ~XFileNode(); virtual ~XFileNode();
INLINE int get_num_children() const; INLINE int get_num_children() const;
INLINE XFileNode *get_child(int n) const; INLINE XFileNode *get_child(int n) const;
XFileNode *find_child(const string &name) const; XFileNode *find_child(const string &name) const;
XFileNode *find_descendent(const string &name) const;
virtual bool has_guid() const;
virtual const WindowsGuid &get_guid() const;
virtual void add_child(XFileNode *node); virtual void add_child(XFileNode *node);
virtual void clear(); virtual void clear();
@ -47,12 +54,14 @@ public:
virtual void write_text(ostream &out, int indent_level) const; virtual void write_text(ostream &out, int indent_level) const;
protected: protected:
XFile *_x_file;
typedef pvector< PT(XFileNode) > Children; typedef pvector< PT(XFileNode) > Children;
Children _children; Children _children;
typedef pmap<string, XFileNode *> ChildrenByName; typedef pmap<string, XFileNode *> ChildrenByName;
ChildrenByName _children_by_name; ChildrenByName _children_by_name;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;

View File

@ -17,16 +17,6 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::get_guid
// Access: Public
// Description: Returns the GUID associated with this template.
////////////////////////////////////////////////////////////////////
INLINE const WindowsGuid &XFileTemplate::
get_guid() const {
return _guid;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::set_open // Function: XFileTemplate::set_open
// Access: Public // Access: Public

View File

@ -27,8 +27,8 @@ TypeHandle XFileTemplate::_type_handle;
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
XFileTemplate:: XFileTemplate::
XFileTemplate(const string &name, const WindowsGuid &guid) : XFileTemplate(XFile *x_file, const string &name, const WindowsGuid &guid) :
XFileNode(name), XFileNode(x_file, name),
_guid(guid), _guid(guid),
_open(false) _open(false)
{ {
@ -44,6 +44,26 @@ XFileTemplate::
clear(); clear();
} }
////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::has_guid
// Access: Public, Virtual
// Description: Returns true if this node has a GUID associated.
////////////////////////////////////////////////////////////////////
bool XFileTemplate::
has_guid() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::get_guid
// Access: Public, Virtual
// Description: Returns the GUID associated with this template.
////////////////////////////////////////////////////////////////////
const WindowsGuid &XFileTemplate::
get_guid() const {
return _guid;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: XFileTemplate::clear // Function: XFileTemplate::clear
// Access: Public, Virtual // Access: Public, Virtual

View File

@ -32,10 +32,11 @@ class XFileDataDef;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class XFileTemplate : public XFileNode { class XFileTemplate : public XFileNode {
public: public:
XFileTemplate(const string &name, const WindowsGuid &guid); XFileTemplate(XFile *x_file, const string &name, const WindowsGuid &guid);
virtual ~XFileTemplate(); virtual ~XFileTemplate();
INLINE const WindowsGuid &get_guid() const; virtual bool has_guid() const;
virtual const WindowsGuid &get_guid() const;
virtual void clear(); virtual void clear();
virtual void write_text(ostream &out, int indent_level) const; virtual void write_text(ostream &out, int indent_level) const;

View File

@ -542,7 +542,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
// An integer as part of a semicolon-delimited list. // An integer as part of a semicolon-delimited list.
accept(); accept();
xyylval.int_list = parse_int_list(xyytext, ";"); xyylval.int_list = parse_int_list(xyytext, ";");
xyylval.u.separator_token = TOKEN_SEMICOLON; xyylval.u.separator = ';';
return TOKEN_INTEGER_LIST; return TOKEN_INTEGER_LIST;
} }
@ -551,7 +551,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
// A floating-point number as part of a semicolon-delimited list. // A floating-point number as part of a semicolon-delimited list.
accept(); accept();
xyylval.double_list = parse_double_list(xyytext, ";"); xyylval.double_list = parse_double_list(xyytext, ";");
xyylval.u.separator_token = TOKEN_SEMICOLON; xyylval.u.separator = ';';
return TOKEN_REALNUM_LIST; return TOKEN_REALNUM_LIST;
} }
@ -560,7 +560,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
// An integer as part of a semicolon-delimited list. // An integer as part of a semicolon-delimited list.
accept(); accept();
xyylval.int_list = parse_int_list(xyytext, ","); xyylval.int_list = parse_int_list(xyytext, ",");
xyylval.u.separator_token = TOKEN_COMMA; xyylval.u.separator = ',';
return TOKEN_INTEGER_LIST; return TOKEN_INTEGER_LIST;
} }
@ -569,7 +569,7 @@ REALNUM ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
// A floating-point number as part of a semicolon-delimited list. // A floating-point number as part of a semicolon-delimited list.
accept(); accept();
xyylval.double_list = parse_double_list(xyytext, ","); xyylval.double_list = parse_double_list(xyytext, ",");
xyylval.u.separator_token = TOKEN_COMMA; xyylval.u.separator = ',';
return TOKEN_REALNUM_LIST; return TOKEN_REALNUM_LIST;
} }

View File

@ -98,6 +98,8 @@ x_cleanup_parser() {
%type <str> string %type <str> string
%type <guid> class_id %type <guid> class_id
%type <guid> optional_class_id %type <guid> optional_class_id
%type <u.separator> list_separator
%type <u.node> data_reference
%% %%
@ -111,7 +113,7 @@ template:
TOKEN_TEMPLATE name TOKEN_OBRACE class_id TOKEN_TEMPLATE name TOKEN_OBRACE class_id
{ {
$$ = current_node; $$ = current_node;
XFileTemplate *templ = new XFileTemplate($2, $4); XFileTemplate *templ = new XFileTemplate(x_file, $2, $4);
current_node->add_child(templ); current_node->add_child(templ);
current_node = templ; current_node = templ;
} }
@ -154,7 +156,7 @@ template_members:
primitive: primitive:
primitive_type optional_name TOKEN_SEMICOLON primitive_type optional_name TOKEN_SEMICOLON
{ {
current_data_def = new XFileDataDef($1, $2); current_data_def = new XFileDataDef(x_file, $2, $1);
current_node->add_child(current_data_def); current_node->add_child(current_data_def);
} }
; ;
@ -170,7 +172,7 @@ template_reference:
if (xtemplate == (XFileTemplate *)NULL) { if (xtemplate == (XFileTemplate *)NULL) {
yyerror("Unknown template: " + $1); yyerror("Unknown template: " + $1);
} else { } else {
current_data_def = new XFileDataDef(XFileDataDef::T_template, $2, xtemplate); current_data_def = new XFileDataDef(x_file, $2, XFileDataDef::T_template, xtemplate);
current_node->add_child(current_data_def); current_node->add_child(current_data_def);
} }
} }
@ -226,7 +228,7 @@ primitive_type:
array_data_type: array_data_type:
primitive_type name primitive_type name
{ {
current_data_def = new XFileDataDef($1, $2); current_data_def = new XFileDataDef(x_file, $2, $1);
current_node->add_child(current_data_def); current_node->add_child(current_data_def);
} }
| name name | name name
@ -235,7 +237,7 @@ array_data_type:
if (xtemplate == (XFileTemplate *)NULL) { if (xtemplate == (XFileTemplate *)NULL) {
yyerror("Unknown template: " + $1); yyerror("Unknown template: " + $1);
} else { } else {
current_data_def = new XFileDataDef(XFileDataDef::T_template, $2, xtemplate); current_data_def = new XFileDataDef(x_file, $2, XFileDataDef::T_template, xtemplate);
current_node->add_child(current_data_def); current_node->add_child(current_data_def);
} }
} }
@ -285,7 +287,7 @@ template_option_part:
DCAST(XFileTemplate, current_node)->add_option(xtemplate); DCAST(XFileTemplate, current_node)->add_option(xtemplate);
} }
} }
| name TOKEN_GUID | name class_id
{ {
XFileTemplate *xtemplate = x_file->find_template($2); XFileTemplate *xtemplate = x_file->find_template($2);
if (xtemplate == (XFileTemplate *)NULL) { if (xtemplate == (XFileTemplate *)NULL) {
@ -338,13 +340,19 @@ object:
yyerror("Unknown template: " + $1); yyerror("Unknown template: " + $1);
} else { } else {
XFileDataObjectTemplate *templ = XFileDataObjectTemplate *templ =
new XFileDataObjectTemplate(xtemplate, $2); new XFileDataObjectTemplate(x_file, $2, xtemplate);
current_node->add_child(templ); current_node->add_child(templ);
current_node = templ; current_node = templ;
} }
} }
optional_class_id data_parts_list TOKEN_CBRACE optional_class_id data_parts_list TOKEN_CBRACE
{ {
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
if (!current_template->finalize_parse_data()) {
yyerror("Invalid data for object.");
}
$$ = current_node; $$ = current_node;
current_node = $<u.node>4; current_node = $<u.node>4;
} }
@ -356,23 +364,53 @@ data_parts_list:
; ;
data_part: data_part:
data_reference TOKEN_OBRACE data_reference TOKEN_CBRACE
{ {
if ($2 != (XFileNode *)NULL) {
if (!$2->is_of_type(XFileDataObjectTemplate::get_class_type())) {
// Actually, maybe you can--the docs aren't clear about this.
// But I don't think there's any real reason to.
yyerror("Can't reference primitive data type.");
} else {
XFileDataObjectTemplate *object =
DCAST(XFileDataObjectTemplate, $2);
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
current_template->add_parse_object(object, true);
}
}
} }
| object | object
{ {
XFileDataObjectTemplate *object =
DCAST(XFileDataObjectTemplate, $1);
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
current_template->add_parse_object(object, false);
} }
| integer_list | integer_list
{ {
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
current_template->add_parse_int($1, $<u.separator>1);
} }
| realnum_list | realnum_list
{ {
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
current_template->add_parse_double($1, $<u.separator>1);
} }
| string list_separator | string list_separator
{ {
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
current_template->add_parse_string($1, $2);
} }
| list_separator | list_separator
{ {
XFileDataObjectTemplate *current_template =
DCAST(XFileDataObjectTemplate, current_node);
current_template->add_parse_separator($1);
} }
; ;
@ -390,11 +428,39 @@ string:
list_separator: list_separator:
TOKEN_SEMICOLON TOKEN_SEMICOLON
{
$$ = ';';
}
| TOKEN_COMMA | TOKEN_COMMA
{
$$ = ',';
}
; ;
data_reference: data_reference:
TOKEN_OBRACE name optional_class_id TOKEN_CBRACE name
{
XFileDataObject *data_object = x_file->find_data_object($1);
if (data_object == (XFileDataObject *)NULL) {
yyerror("Unknown data_object: " + $1);
}
$$ = data_object;
}
| name class_id
{
XFileDataObject *data_object = x_file->find_data_object($2);
if (data_object == (XFileDataObject *)NULL) {
yyerror("Unknown data_object: " + $1);
} else {
if (data_object->get_name() != $1) {
xyywarning("GUID identifies data_object " + data_object->get_name() +
", not " + $1);
}
}
$$ = data_object;
}
; ;
empty: empty:

View File

@ -45,7 +45,7 @@ public:
int number; int number;
XFileNode *node; XFileNode *node;
XFileDataDef::Type primitive_type; XFileDataDef::Type primitive_type;
int separator_token; // This is filled in for double_list and int_list. char separator; // This is filled in for double_list and int_list.
} u; } u;
string str; string str;
WindowsGuid guid; WindowsGuid guid;