create virtual attribute "top_href" for xi:include that is a path relative to top level of project to make it easier to generate non-recursive makefiles Modified: branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h _____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp --- branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp 2005-01-04 09:35:28 UTC (rev 12785) +++ branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp 2005-01-04 13:40:05 UTC (rev 12786) @@ -1,3 +1,9 @@
+// module.cpp + +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) // identifier was truncated to '255' characters in the debug information +#endif//_MSC_VER + #include "rbuild.h"
using std::string; _____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp --- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp 2005-01-04 09:35:28 UTC (rev 12785) +++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp 2005-01-04 13:40:05 UTC (rev 12786) @@ -1,7 +1,7 @@
// rbuild.cpp
#ifdef _MSC_VER -#pragma warning ( disable : 4786 ) +#pragma warning ( disable : 4786 ) // identifier was truncated to '255' characters in the debug information #endif//_MSC_VER
#include <stdio.h> @@ -16,6 +16,7 @@ #ifdef WIN32 #define getcwd _getcwd #endif//WIN32 +string working_directory;
#ifdef _MSC_VER unsigned __int64 @@ -39,11 +40,7 @@
Path::Path() { - string s; - s.resize ( _MAX_PATH ); - s[0] = 0; - getcwd ( &s[0], s.size() ); - s.resize ( strlen ( s.c_str() ) ); + string s ( working_directory ); const char* p = strtok ( &s[0], "/\" ); while ( p ) { @@ -65,7 +62,8 @@ } }
-string Path::Fixup ( const string& file, bool include_filename ) const +string +Path::Fixup ( const string& file, bool include_filename ) const { if ( strchr ( "/\", file[0] ) #ifdef WIN32 @@ -117,6 +115,64 @@ 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 ( int 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++ ) + { + // this squirreliness is b/c win32 has drive letters and *nix doesn't... +#ifdef WIN32 + if ( i ) out += "/"; +#else + out += "/"; +#endif + 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() { } @@ -290,8 +346,9 @@ return !( *p == '/' ) && !end_tag; }
-const XMLAttribute* XMLElement::GetAttribute ( const string& attribute, - bool required ) const +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. @@ -308,6 +365,25 @@ 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 ( int i = 0; i < attributes.size(); i++ ) + { + if ( attribute == attributes[i]->name ) + return attributes[i]; + } + if ( required ) + { + printf ( "syntax error: attribute '%s' required for <%s>\n", + attribute.c_str(), name.c_str() ); + } + return NULL; +} + // XMLParse() // This function reads a "token" from the file loaded in XMLFile // REM TODO FIXME: At the moment it can't handle comments or non-xml tags. @@ -330,11 +406,13 @@
if ( e->name == "xi:include" ) { - const XMLAttribute* att; + XMLAttribute* att; att = e->GetAttribute("href",true); if ( 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 ) ) printf ( "xi:include error, couldn't find file '%s'\n", file.c_str() ); @@ -439,6 +517,12 @@
int main ( int argc, char** argv ) { + // 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() ) ); + XMLFile f; Path path; if ( !f.open ( "ReactOS.xml" ) ) _____
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h --- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h 2005-01-04 09:35:28 UTC (rev 12785) +++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h 2005-01-04 13:40:05 UTC (rev 12786) @@ -11,6 +11,12 @@
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::vectorstd::string& out, + const std::string& path, + bool include_last ); };
class XMLFile @@ -56,8 +62,10 @@ ~XMLElement(); bool Parse(const std::string& token, bool& end_tag); + XMLAttribute* GetAttribute ( const std::string& attribute, + bool required); const XMLAttribute* GetAttribute ( const std::string& attribute, - bool required) const; + bool required) const; };
class Project;