--- trunk/reactos/tools/Makefile 2005-02-19 22:59:17 UTC (rev 13655)
+++ trunk/reactos/tools/Makefile 2005-02-19 23:05:09 UTC (rev 13656)
@@ -5,7 +5,6 @@
CFLAGS += -Wall -Werror
TOOLS = \
- buildno$(EXE_POSTFIX) \
regtests$(EXE_POSTFIX) \
rcopy$(EXE_POSTFIX) \
rdel$(EXE_POSTFIX) \
@@ -20,12 +19,8 @@
CLEAN_FILES = $(TOOLS)
all: $(TOOLS) zlib_target wmc_target cabman_target cdmake_target mkhive_target rgenstat_target \
- wine2ros_target pipetools_target winebuild_target bin2res_target wrc_target
+ wine2ros_target pipetools_target winebuild_target bin2res_target wrc_target buildno_target
-buildno$(EXE_POSTFIX): buildno.c ../include/reactos/version.h
- @$(HOST_CC) $(CFLAGS) -o buildno$(EXE_POSTFIX) buildno.c
- @$(EXE_PREFIX)buildno$(EXE_POSTFIX)
-
regtests$(EXE_POSTFIX): regtests.c
@$(HOST_CC) $(CFLAGS) -o regtests$(EXE_POSTFIX) regtests.c
@@ -133,11 +128,15 @@
wrc_target:
$(MAKE) --silent -C wrc wrc$(EXE_POSTFIX)
-.PHONY: wmc_target cdmake_target mkhive_target rgenstat_target pipetools_target wrc_target
+buildno_target:
+ $(MAKE) --silent -C buildno buildno$(EXE_POSTFIX)
+.PHONY: wmc_target cdmake_target mkhive_target rgenstat_target pipetools_target wrc_target buildno_target
+
ifeq ($(HOST),mingw32-linux)
clean:
+ $(MAKE) --silent -C buildno clean
$(MAKE) --silent -C wrc clean
$(MAKE) --silent -C cabman clean
$(MAKE) --silent -C cdmake clean
@@ -148,12 +147,12 @@
$(MAKE) --silent -C winebuild clean
$(MAKE) --silent -C bin2res clean
$(MAKE) --silent -C ../lib/zlib -f Makefile.host clean
- @rm ../include/reactos/buildno.h
@rm mkconfig
@rm $(TOOLS)
endif
ifeq ($(HOST),mingw32-windows)
clean:
+ $(MAKE) --silent -C buildno clean
$(MAKE) --silent -C wrc clean
$(MAKE) --silent -C cabman clean
$(MAKE) --silent -C cdmake clean
@@ -165,7 +164,6 @@
$(MAKE) --silent -C winebuild clean
$(MAKE) --silent -C bin2res clean
$(MAKE) --silent -C ../lib/zlib -f Makefile.host clean
- -@del ..\include\reactos\buildno.h
-@del *$(EXE_POSTFIX)
endif
Property changes on: trunk/reactos/tools/buildno
___________________________________________________________________
Name: svn:ignore
+ *.o
buildno
buildno.exe
--- trunk/reactos/tools/buildno/XML.cpp 2005-02-19 22:59:17 UTC (rev 13655)
+++ trunk/reactos/tools/buildno/XML.cpp 2005-02-19 23:05:09 UTC (rev 13656)
@@ -0,0 +1,727 @@
+// XML.cpp
+
+#include "pch.h"
+
+#ifdef _MSC_VER
+#define MAX_PATH _MAX_PATH
+#endif
+
+#ifdef WIN32
+# include <direct.h>
+# include <io.h>
+#else
+# include <sys/stat.h>
+# define MAX_PATH PATH_MAX
+#endif
+#include <assert.h>
+
+#include "XML.h"
+#include "exception.h"
+#include "ssprintf.h"
+
+using std::string;
+using std::vector;
+
+#ifdef WIN32
+#define getcwd _getcwd
+#endif//WIN32
+
+static const char* WS = " \t\r\n";
+static const char* WSEQ = " =\t\r\n";
+
+string working_directory;
+
+class XMLInclude
+{
+public:
+ XMLElement *e;
+ Path path;
+
+ XMLInclude ( XMLElement* e_, const Path& path_ )
+ : e(e_), path(path_)
+ {
+ }
+};
+
+class XMLIncludes : public vector<XMLInclude*>
+{
+public:
+ ~XMLIncludes()
+ {
+ for ( size_t i = 0; i < this->size(); i++ )
+ delete (*this)[i];
+ }
+};
+
+void
+InitWorkingDirectory()
+{
+ // store the current directory for path calculations
+ working_directory.resize ( _MAX_PATH );
+ working_directory[0] = 0;
+ getcwd ( &working_directory[0], working_directory.size() );
+ working_directory.resize ( strlen ( working_directory.c_str() ) );
+}
+
+#ifdef _MSC_VER
+unsigned __int64
+#else
+unsigned long long
+#endif
+filelen ( FILE* f )
+{
+#ifdef WIN32
+ return _filelengthi64 ( _fileno(f) );
+#else
+ struct stat64 file_stat;
+ if ( fstat64(fileno(f), &file_stat) != 0 )
+ return 0;
+ return file_stat.st_size;
+#endif
+}
+
+Path::Path()
+{
+ if ( !working_directory.size() )
+ InitWorkingDirectory();
+ string s ( working_directory );
+ const char* p = strtok ( &s[0], "/\\" );
+ while ( p )
+ {
+ if ( *p )
+ path.push_back ( p );
+ p = strtok ( NULL, "/\\" );
+ }
+}
+
+Path::Path ( const Path& cwd, const string& file )
+{
+ string s ( cwd.Fixup ( file, false ) );
+ const char* p = strtok ( &s[0], "/\\" );
+ while ( p )
+ {
+ if ( *p )
+ path.push_back ( p );
+ p = strtok ( NULL, "/\\" );
+ }
+}
+
+string
+Path::Fixup ( const string& file, bool include_filename ) const
+{
+ if ( strchr ( "/\\", file[0] )
+#ifdef WIN32
+ // this squirreliness is b/c win32 has drive letters and *nix doesn't...
+ || file[1] == ':'
+#endif//WIN32
+ )
+ {
+ return file;
+ }
+ vector<string> pathtmp ( path );
+ string tmp ( file );
+ const char* prev = strtok ( &tmp[0], "/\\" );
+ const char* p = strtok ( NULL, "/\\" );
+ while ( p )
+ {
+ if ( !strcmp ( prev, "." ) )
+ ; // do nothing
+ else if ( !strcmp ( prev, ".." ) )
+ {
+ // this squirreliness is b/c win32 has drive letters and *nix doesn't...
+#ifdef WIN32
+ if ( pathtmp.size() > 1 )
+#else
+ if ( pathtmp.size() )
+#endif
+ pathtmp.resize ( pathtmp.size() - 1 );
+ }
+ else
+ pathtmp.push_back ( prev );
+ prev = p;
+ p = strtok ( NULL, "/\\" );
+ }
+ if ( include_filename )
+ pathtmp.push_back ( prev );
+
+ // reuse tmp variable to return recombined path
+ tmp.resize(0);
+ for ( size_t i = 0; i < pathtmp.size(); i++ )
+ {
+ // this squirreliness is b/c win32 has drive letters and *nix doesn't...
+#ifdef WIN32
+ if ( i ) tmp += "/";
+#else
+ tmp += "/";
+#endif
+ tmp += pathtmp[i];
+ }
+ return tmp;
+}
+
+/*static*/ string
+Path::RelativeFromWorkingDirectory ( const string& path )
+{
+ vector<string> vwork, vpath, vout;
+ Path::Split ( vwork, working_directory, true );
+ Path::Split ( vpath, path, true );
+#ifdef WIN32
+ // this squirreliness is b/c win32 has drive letters and *nix doesn't...
+ // not possible to do relative across different drive letters
+ if ( vwork[0] != vpath[0] )
+ return path;
+#endif
+ size_t i = 0;
+ while ( i < vwork.size() && i < vpath.size() && vwork[i] == vpath[i] )
+ ++i;
+ if ( i < vwork.size() )
+ {
+ // path goes above our working directory, we will need some ..'s
+ for ( size_t j = 0; j < i; j++ )
+ vout.push_back ( ".." );
+ }
+ while ( i < vpath.size() )
+ vout.push_back ( vpath[i++] );
+
+ // now merge vout into a string again
+ string out = ".";
+ for ( i = 0; i < vout.size(); i++ )
+ {
+ out += "/" + vout[i];
+ }
+ return out;
+}
+
+/*static*/ void
+Path::Split ( vector<string>& out,
+ const string& path,
+ bool include_last )
+{
+ string s ( path );
+ const char* prev = strtok ( &s[0], "/\\" );
+ const char* p = strtok ( NULL, "/\\" );
+ out.resize ( 0 );
+ while ( p )
+ {
+ out.push_back ( prev );
+ prev = p;
+ p = strtok ( NULL, "/\\" );
+ }
+ if ( include_last )
+ out.push_back ( prev );
+}
+
+XMLFile::XMLFile()
+{
+}
+
+void
+XMLFile::close()
+{
+ _buf.resize(0);
+ _p = _end = NULL;
+}
+
+bool
+XMLFile::open(const string& filename_)
+{
+ close();
+ FILE* f = fopen ( filename_.c_str(), "rb" );
+ if ( !f )
+ return false;
+ unsigned long len = (unsigned long)filelen(f);
+ _buf.resize ( len );
+ fread ( &_buf[0], 1, len, f );
+ fclose ( f );
+ _p = _buf.c_str();
+ _end = _p + len;
+ _filename = filename_;
+ next_token();
+ return true;
+}
+
+// next_token() moves the pointer to next token, which may be
+// an xml element or a text element, basically it's a glorified
+// skipspace, normally the user of this class won't need to call
+// this function
+void
+XMLFile::next_token()
+{
+ _p += strspn ( _p, WS );
+}
+
+bool
+XMLFile::next_is_text()
+{
+ return *_p != '<';
+}
+
+bool
+XMLFile::more_tokens()
+{
+ return _p != _end;
+}
+
+// get_token() is used to return a token, and move the pointer
+// past the token
+bool
+XMLFile::get_token(string& token)
+{
+ const char* tokend;
+ if ( !strncmp ( _p, "<!--", 4 ) )
+ {
+ tokend = strstr ( _p, "-->" );
+ if ( !tokend )
+ tokend = _end;
+ else
+ tokend += 3;
+ }
+ else if ( !strncmp ( _p, "<?", 2 ) )
+ {
+ tokend = strstr ( _p, "?>" );
+ if ( !tokend )
+ tokend = _end;
+ else
+ tokend += 2;
+ }
+ else if ( *_p == '<' )
+ {
+ tokend = strchr ( _p, '>' );
+ if ( !tokend )
+ tokend = _end;
+ else
+ ++tokend;
+ }
+ else
+ {
+ tokend = strchr ( _p, '<' );
+ if ( !tokend )
+ tokend = _end;
+ while ( tokend > _p && isspace(tokend[-1]) )
+ --tokend;
+ }
+ if ( tokend == _p )
+ return false;
+ token = string ( _p, tokend-_p );
+ _p = tokend;
+ next_token();
+ return true;
+}
+
+string
+XMLFile::Location() const
+{
+ int line = 1;
+ const char* p = strchr ( _buf.c_str(), '\n' );
+ while ( p && p < _p )
+ {
+ ++line;
+ p = strchr ( p+1, '\n' );
+ }
+ return ssprintf ( "%s(%i)",_filename.c_str(), line );
+}
+
+XMLAttribute::XMLAttribute()
+{
+}
+
+XMLAttribute::XMLAttribute(const string& name_,
+ const string& value_)
+ : name(name_), value(value_)
+{
+}
+
+XMLAttribute::XMLAttribute ( const XMLAttribute& src )
+ : name(src.name), value(src.value)
+{
+
+}
+
+XMLAttribute& XMLAttribute::operator = ( const XMLAttribute& src )
+{
+ name = src.name;
+ value = src.value;
+ return *this;
+}
+
+XMLElement::XMLElement ( const string& location_ )
+ : location(location_),
+ parentElement(NULL)
+{
+}
+
+XMLElement::~XMLElement()
+{
+ size_t i;
+ for ( i = 0; i < attributes.size(); i++ )
+ delete attributes[i];
+ for ( i = 0; i < subElements.size(); i++ )
+ delete subElements[i];
+}
+
+void
+XMLElement::AddSubElement ( XMLElement* e )
+{
+ subElements.push_back ( e );
+ e->parentElement = this;
+}
+
+// Parse()
+// This function takes a single xml tag ( i.e. beginning with '<' and
+// ending with '>', and parses out it's tag name and constituent
+// attributes.
+// Return Value: returns true if you need to look for a </tag> for
+// the one it just parsed...
+bool
+XMLElement::Parse(const string& token,
+ bool& end_tag)
+{
+ const char* p = token.c_str();
+ assert ( *p == '<' );
+ ++p;
+ p += strspn ( p, WS );
+
+ // check if this is a comment
+ if ( !strncmp ( p, "!--", 3 ) )
+ {
+ name = "!--";
+ end_tag = false;
+ return false; // never look for end tag to a comment
+ }
+
+ end_tag = ( *p == '/' );
+ if ( end_tag )
+ {
+ ++p;
+ p += strspn ( p, WS );
+ }
+ const char* end = strpbrk ( p, WS );
+ if ( !end )
+ {
+ end = strpbrk ( p, "/>" );
+ assert ( end );
+ }
+ name = string ( p, end-p );
+ p = end;
+ p += strspn ( p, WS );
+ while ( *p != '>' && *p != '/' )
+ {
+ end = strpbrk ( p, WSEQ );
+ if ( !end )
+ {
+ end = strpbrk ( p, "/>" );
+ assert ( end );
+ }
+ string attribute ( p, end-p ), value;
+ p = end;
+ p += strspn ( p, WS );
+ if ( *p == '=' )
+ {
+ ++p;
+ p += strspn ( p, WS );
+ char quote = 0;
+ if ( strchr ( "\"'", *p ) )
+ {
+ quote = *p++;
+ end = strchr ( p, quote );
+ }
+ else
+ {
+ end = strpbrk ( p, WS );
+ }
+ if ( !end )
+ {
+ end = strchr ( p, '>' );
+ assert(end);
+ if ( end[-1] == '/' )
+ end--;
+ }
+ value = string ( p, end-p );
+ p = end;
+ if ( quote && *p == quote )
+ p++;
+ p += strspn ( p, WS );
+ }
+ else if ( name[0] != '!' )
+ {
+ throw XMLSyntaxErrorException ( location,
+ "attributes must have values" );
+ }
+ attributes.push_back ( new XMLAttribute ( attribute, value ) );
+ }
+ return !( *p == '/' ) && !end_tag;
+}
+
+XMLAttribute*
+XMLElement::GetAttribute ( const string& attribute,
+ bool required )
+{
+ // this would be faster with a tree-based container, but our attribute
+ // lists are likely to stay so short as to not be an issue.
+ for ( size_t i = 0; i < attributes.size(); i++ )
+ {
+ if ( attribute == attributes[i]->name )
+ return attributes[i];
+ }
+ if ( required )
+ {
+ throw RequiredAttributeNotFoundException ( location,
+ attribute,
+ name );
+ }
+ return NULL;
+}
+
+const XMLAttribute*
+XMLElement::GetAttribute ( const string& attribute,
+ bool required ) const
+{
+ // this would be faster with a tree-based container, but our attribute
+ // lists are likely to stay so short as to not be an issue.
+ for ( size_t i = 0; i < attributes.size(); i++ )
+ {
+ if ( attribute == attributes[i]->name )
+ return attributes[i];
+ }
+ if ( required )
+ {
+ throw RequiredAttributeNotFoundException ( location,
+ attribute,
+ name );
+ }
+ return NULL;
+}
+
+// XMLParse()
+// This function reads a "token" from the file loaded in XMLFile
+// if it finds a tag that is non-singular, it parses sub-elements and/or
+// inner text into the XMLElement that it is building to return.
+// Return Value: an XMLElement allocated via the new operator that contains
+// it's parsed data. Keep calling this function until it returns NULL
+// (no more data)
+XMLElement*
+XMLParse(XMLFile& f,
+ XMLIncludes* includes,
+ const Path& path,
+ bool* pend_tag = NULL )
+{
+ string token;
+ if ( !f.get_token(token) )
+ return NULL;
+ bool end_tag, is_include = false;
+
+ while ( token[0] != '<'
+ || !strncmp ( token.c_str(), "<!--", 4 )
+ || !strncmp ( token.c_str(), "<?", 2 ) )
+ {
+ if ( token[0] != '<' )
+ throw XMLSyntaxErrorException ( f.Location(),
+ "expecting xml tag, not '%s'",
+ token.c_str() );
+ if ( !f.get_token(token) )
+ return NULL;
+ }
+
+ XMLElement* e = new XMLElement ( f.Location() );
+ bool bNeedEnd = e->Parse ( token, end_tag );
+
+ if ( e->name == "xi:include" && includes )
+ {
+ includes->push_back ( new XMLInclude ( e, path ) );
+ is_include = true;
+ }
+
+ if ( !bNeedEnd )
+ {
+ if ( pend_tag )
+ *pend_tag = end_tag;
+ else if ( end_tag )
+ {
+ delete e;
+ throw XMLSyntaxErrorException ( f.Location(),
+ "end tag '%s' not expected",
+ token.c_str() );
+ return NULL;
+ }
+ return e;
+ }
+ bool bThisMixingErrorReported = false;
+ while ( f.more_tokens() )
+ {
+ if ( f.next_is_text() )
+ {
+ if ( !f.get_token ( token ) || !token.size() )
+ {
+ throw InvalidBuildFileException (
+ f.Location(),
+ "internal tool error - get_token() failed when more_tokens() returned true" );
+ break;
+ }
+ if ( e->subElements.size() && !bThisMixingErrorReported )
+ {
+ throw XMLSyntaxErrorException ( f.Location(),
+ "mixing of inner text with sub elements" );
+ bThisMixingErrorReported = true;
+ }
+ if ( strchr ( token.c_str(), '>' ) )
+ {
+ throw XMLSyntaxErrorException ( f.Location(),
+ "invalid symbol '>'" );
+ }
+ if ( e->value.size() )
+ {
+ throw XMLSyntaxErrorException ( f.Location(),
+ "multiple instances of inner text" );
+ e->value += " " + token;
+ }
+ else
+ e->value = token;
+ }
+ else
+ {
+ XMLElement* e2 = XMLParse ( f, is_include ? NULL : includes, path, &end_tag );
+ if ( !e2 )
+ {
+ throw InvalidBuildFileException (
+ e->location,
+ "end of file found looking for end tag" );
+ break;
+ }
+ if ( end_tag )
+ {
+ if ( e->name != e2->name )
+ {
+ delete e2;
+ throw XMLSyntaxErrorException ( f.Location(),
+ "end tag name mismatch" );
+ break;
+ }
+ delete e2;
+ break;
+ }
+ if ( e->value.size() && !bThisMixingErrorReported )
+ {
+ throw XMLSyntaxErrorException ( f.Location(),
+ "mixing of inner text with sub elements" );
+ bThisMixingErrorReported = true;
+ }
+ e->AddSubElement ( e2 );
+ }
+ }
+ return e;
+}
+
+void
+XMLReadFile ( XMLFile& f, XMLElement& head, XMLIncludes& includes, const Path& path )
+{
+ for ( ;; )
+ {
+ XMLElement* e = XMLParse ( f, &includes, path );
+ if ( !e )
+ return;
+ head.AddSubElement ( e );
+ }
+}
+
+XMLElement*
+XMLLoadInclude ( XMLElement* e, const Path& path, XMLIncludes& includes )
+{
+ XMLAttribute* att;
+ att = e->GetAttribute("href",true);
+ assert(att);
+
+ string file ( path.Fixup(att->value,true) );
+ string top_file ( Path::RelativeFromWorkingDirectory ( file ) );
+ e->attributes.push_back ( new XMLAttribute ( "top_href", top_file ) );
+ XMLFile fInc;
+ if ( !fInc.open ( file ) )
+ {
+ // look for xi:fallback element
+ for ( size_t i = 0; i < e->subElements.size(); i++ )
+ {
+ XMLElement* e2 = e->subElements[i];
+ if ( e2->name == "xi:fallback" )
+ {
+ // now look for xi:include below...
+ for ( i = 0; i < e2->subElements.size(); i++ )
+ {
+ XMLElement* e3 = e2->subElements[i];
+ if ( e3->name == "xi:include" )
+ {
+ return XMLLoadInclude ( e3, path, includes );
+ }
+ }
+ throw InvalidBuildFileException (
+ e2->location,
+ "<xi:fallback> must have a <xi:include> sub-element" );
+ return NULL;
+ }
+ }
+ return NULL;
+ }
+ else
+ {
+ XMLElement* new_e = new XMLElement ( e->location );
+ new_e->name = "xi:included";
+ Path path2 ( path, att->value );
+ XMLReadFile ( fInc, *new_e, includes, path2 );
+ return new_e;
+ }
+}
+
+XMLElement*
+XMLLoadFile ( const string& filename, const Path& path )
+{
+ XMLIncludes includes;
+ XMLFile f;
+
+ if ( !f.open ( filename ) )
+ throw FileNotFoundException ( filename );
+
+ XMLElement* head = new XMLElement("(virtual)");
+
+ XMLReadFile ( f, *head, includes, path );
+
+ for ( size_t i = 0; i < includes.size(); i++ )
+ {
+ XMLElement* e = includes[i]->e;
+ XMLElement* e2 = XMLLoadInclude ( includes[i]->e, includes[i]->path, includes );
+ if ( !e2 )
+ {
+ throw FileNotFoundException (
+ ssprintf("%s (referenced from %s)",
+ e->GetAttribute("top_href",true)->value.c_str(),
+ f.Location().c_str() ) );
+ }
+ XMLElement* parent = e->parentElement;
+ XMLElement** parent_container = NULL;
+ if ( !parent )
+ {
+ delete e;
+ throw Exception ( "internal tool error: xi:include doesn't have a parent" );
+ return NULL;
+ }
+ for ( size_t j = 0; j < parent->subElements.size(); j++ )
+ {
+ if ( parent->subElements[j] == e )
+ {
+ parent_container = &parent->subElements[j];
+ break;
+ }
+ }
+ if ( !parent_container )
+ {
+ delete e;
+ throw Exception ( "internal tool error: couldn't find xi:include in parent's sub-elements" );
+ return NULL;
+ }
+ // replace inclusion tree with the imported tree
+ e2->parentElement = e->parentElement;
+ e2->name = e->name;
+ e2->attributes = e->attributes;
+ *parent_container = e2;
+ e->attributes.resize(0);
+ delete e;
+ }
+ return head;
+}
Property changes on: trunk/reactos/tools/buildno/XML.cpp
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
--- trunk/reactos/tools/buildno/XML.h 2005-02-19 22:59:17 UTC (rev 13655)
+++ trunk/reactos/tools/buildno/XML.h 2005-02-19 23:05:09 UTC (rev 13656)
@@ -0,0 +1,96 @@
+// XML.h
+
+#ifndef XML_H
+#define XML_H
+
+#include "pch.h"
+
+void
+InitWorkingDirectory();
+
+#ifdef _MSC_VER
+unsigned __int64
+#else
+unsigned long long
+#endif
+filelen ( FILE* f );
+
+class Path
+{
+ std::vector<std::string> path;
+public:
+ Path(); // initializes path to getcwd();
+ Path ( const Path& cwd, const std::string& filename );
+ std::string Fixup ( const std::string& filename, bool include_filename ) const;
+
+ static std::string RelativeFromWorkingDirectory ( const std::string& path );
+
+ static void Split ( std::vector<std::string>& out,
+ const std::string& path,
+ bool include_last );
+};
+
+class XMLFile
+{
+ friend class XMLElement;
+public:
+ XMLFile();
+ void close();
+ bool open(const std::string& filename);
+ void next_token();
+ bool next_is_text();
+ bool more_tokens();
+ bool get_token(std::string& token);
+ const std::string& filename() { return _filename; }
+ std::string Location() const;
+
+private:
+ std::string _buf, _filename;
+
+ const char *_p, *_end;
+};
+
+
+class XMLAttribute
+{
+public:
+ std::string name;
+ std::string value;
+
+ XMLAttribute();
+ XMLAttribute ( const std::string& name_, const std::string& value_ );
+ XMLAttribute ( const XMLAttribute& );
+ XMLAttribute& operator = ( const XMLAttribute& );
+};
+
+
+class XMLElement
+{
+public:
+ std::string location;
+ std::string name;
+ std::vector<XMLAttribute*> attributes;
+ XMLElement* parentElement;
+ std::vector<XMLElement*> subElements;
+ std::string value;
+
+ XMLElement ( const std::string& location_ );
+ ~XMLElement();
+ bool Parse(const std::string& token,
+ bool& end_tag);
+ void AddSubElement ( XMLElement* e );
+ XMLAttribute* GetAttribute ( const std::string& attribute,
+ bool required);
+ const XMLAttribute* GetAttribute ( const std::string& attribute,
+ bool required) const;
+};
+
+XMLElement*
+XMLLoadFile ( const std::string& filename, const Path& path );
+
+/*XMLElement*
+XMLParse(XMLFile& f,
+ const Path& path,
+ bool* pend_tag = NULL);*/
+
+#endif//XML_H
Property changes on: trunk/reactos/tools/buildno/XML.h
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native