Don't use a dereferencing operator when incrementing the pointer here.
[reactos.git] / reactos / tools / rbuild / directory.cpp
index 2b6d5ec..d0346d9 100644 (file)
@@ -20,8 +20,7 @@
 
 #include "rbuild.h"
 #ifdef _MSC_VER
-#define popen _popen
-#define pclose _pclose
+#include <errno.h>
 #else
 #include <dirent.h>
 #endif//_MSC_VER
@@ -38,6 +37,29 @@ using std::vector;
 Directory::Directory ( const string& name_ )
        : name(name_)
 {
+       size_t pos = name.find_first_of ( "$:" );
+       if ( pos != string::npos )
+       {
+               throw InvalidOperationException ( __FILE__,
+                                                 __LINE__,
+                                                 "Invalid directory name '%s'",
+                                                 name.c_str() );
+       }
+
+       const char* p = strpbrk ( name_.c_str (), "/\\" );
+       if ( name_.c_str () == p )
+       {
+               throw InvalidOperationException ( __FILE__,
+                                                 __LINE__,
+                                                 "Invalid relative path '%s'",
+                                                 name_.c_str () );
+       }
+
+       if ( p )
+       {
+               name.erase ( p - name_.c_str ());
+               Add ( p + 1 );
+       }
 }
 
 void
@@ -54,6 +76,14 @@ Directory::Add ( const char* subdir )
        }
 
        const char* p = strpbrk ( subdir, "/\\" );
+       if ( subdir == p || ( *subdir && subdir[1] == ':' ) )
+       {
+               throw InvalidOperationException ( __FILE__,
+                                                 __LINE__,
+                                                 "Invalid relative path '%s'",
+                                                 subdir );
+       }
+
        if ( !p )
                p = subdir + strlen(subdir);
        string s ( subdir, p-subdir );
@@ -88,13 +118,14 @@ Directory::mkdir_p ( const char* path )
 }
 
 bool
-Directory::CreateDirectory ( string path )
+Directory::CreateDirectory ( const string& path )
 {
        size_t index = 0;
        size_t nextIndex;
        if ( isalpha ( path[0] ) && path[1] == ':' && path[2] == cSep )
        {
                nextIndex = path.find ( cSep, 3);
+               index = path.find ( cSep );
        }
        else
                nextIndex = path.find ( cSep );
@@ -109,26 +140,24 @@ Directory::CreateDirectory ( string path )
        return directoryWasCreated;
 }
 
-string
-Directory::ReplaceVariable ( string name,
-                             string value,
-                             string path )
-{
-       size_t i = path.find ( name );
-       if ( i != string::npos )
-               return path.replace ( i, name.length (), value );
-       else
-               return path;
-}
-
 void
-Directory::ResolveVariablesInPath ( char* buf,
-                                    string path )
+Directory::GenerateTree ( DirectoryLocation root,
+                          bool verbose )
 {
-       string s = ReplaceVariable ( "$(INTERMEDIATE)", Environment::GetIntermediatePath (), path );
-       s = ReplaceVariable ( "$(OUTPUT)", Environment::GetOutputPath (), s );
-       s = ReplaceVariable ( "$(INSTALL)", Environment::GetInstallPath (), s );
-       strcpy ( buf, s.c_str () );
+       switch ( root )
+       {
+               case IntermediateDirectory:
+                       return GenerateTree ( Environment::GetIntermediatePath (), verbose );
+               case OutputDirectory:
+                       return GenerateTree ( Environment::GetOutputPath (), verbose );
+               case InstallDirectory:
+                       return GenerateTree ( Environment::GetInstallPath (), verbose );
+               default:
+                       throw InvalidOperationException ( __FILE__,
+                                                         __LINE__,
+                                                         "Invalid directory %d.",
+                                                         root );
+       }
 }
 
 void
@@ -139,12 +168,12 @@ Directory::GenerateTree ( const string& parent,
 
        if ( parent.size () > 0 )
        {
-               char buf[256];
-               
-               path = parent + sSep + name;
-               ResolveVariablesInPath ( buf, path );
-               if ( CreateDirectory ( buf ) && verbose )
-                       printf ( "Created %s\n", buf );
+               if ( name.size () > 0 )
+                       path = parent + sSep + name;
+               else
+                       path = parent;
+               if ( CreateDirectory ( path ) && verbose )
+                       printf ( "Created %s\n", path.c_str () );
        }
        else
                path = name;
@@ -158,17 +187,17 @@ Directory::GenerateTree ( const string& parent,
 }
 
 string
-Directory::EscapeSpaces ( string path )
+Directory::EscapeSpaces ( const string& path )
 {
        string newpath;
-       char* p = &path[0];
+       const char* p = &path[0];
        while ( *p != 0 )
        {
                if ( *p == ' ' )
                        newpath = newpath + "\\ ";
                else
                        newpath = newpath + *p;
-               *p++;
+               p++;
        }
        return newpath;
 }
@@ -178,27 +207,31 @@ Directory::CreateRule ( FILE* f,
                         const string& parent )
 {
        string path;
+       string escapedName = EscapeSpaces ( name );
 
-       if ( parent.size() > 0 )
+       if ( escapedName.size() > 0 )
        {
-               string escapedParent = EscapeSpaces ( parent );
-               fprintf ( f,
-                       "%s%c%s: | %s\n",
-                       escapedParent.c_str (),
-                       cSep,
-                       EscapeSpaces ( name ).c_str (),
-                       escapedParent.c_str () );
-
-               fprintf ( f,
-                       "\t$(ECHO_MKDIR)\n" );
-
-               fprintf ( f,
-                       "\t${mkdir} $@\n" );
-
-               path = parent + sSep + name;
+               if ( ! (escapedName == "tools" &&
+                    ( parent == "$(OUTPUT)" || parent == "$(INTERMEDIATE)" ) ) )
+               {
+                       fprintf ( f,
+                               "%s%c%s: | %s\n",
+                               parent.c_str (),
+                               cSep,
+                               escapedName.c_str (),
+                               parent.c_str () );
+
+                       fprintf ( f,
+                               "\t$(ECHO_MKDIR)\n" );
+
+                       fprintf ( f,
+                               "\t${mkdir} $@\n" );
+               }
+
+               path = parent + sSep + escapedName;
        }
        else
-               path = name;
+               path = parent;
 
        for ( directory_map::iterator i = subdirs.begin();
                i != subdirs.end();
@@ -207,3 +240,10 @@ Directory::CreateRule ( FILE* f,
                i->second->CreateRule ( f, path );
        }
 }
+
+Directory::~Directory()
+{
+       std::map<std::string, Directory*>::iterator theIterator;
+       for ( theIterator = subdirs.begin (); theIterator != subdirs.end (); theIterator++ )
+               delete theIterator->second;
+}