2 * Copyright (C) 2005 Casper S. Hornstrup
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #define MKDIR(s) mkdir(s)
31 #define MKDIR(s) mkdir(s, 0755)
37 Directory::Directory ( const string
& name_
)
40 size_t pos
= name
.find_first_of ( "$:" );
41 if ( pos
!= string::npos
)
43 throw InvalidOperationException ( __FILE__
,
45 "Invalid directory name '%s'",
49 const char* p
= strpbrk ( name_
.c_str (), "/\\" );
50 if ( name_
.c_str () == p
)
52 throw InvalidOperationException ( __FILE__
,
54 "Invalid relative path '%s'",
60 name
.erase ( p
- name_
.c_str ());
66 Directory::Add ( const char* subdir
)
69 string s1
= string ( subdir
);
70 if ( ( i
= s1
.find ( '$' ) ) != string::npos
)
72 throw InvalidOperationException ( __FILE__
,
74 "No environment variables can be used here. Path was %s",
78 const char* p
= strpbrk ( subdir
, "/\\" );
79 if ( subdir
== p
|| ( *subdir
&& subdir
[1] == ':' ) )
81 throw InvalidOperationException ( __FILE__
,
83 "Invalid relative path '%s'",
88 p
= subdir
+ strlen(subdir
);
89 string
s ( subdir
, p
-subdir
);
90 if ( subdirs
.find(s
) == subdirs
.end() )
91 subdirs
[s
] = new Directory(s
);
93 subdirs
[s
]->Add ( p
);
97 Directory::mkdir_p ( const char* path
)
101 directory
= opendir ( path
);
102 if ( directory
!= NULL
)
104 closedir ( directory
);
109 if ( MKDIR ( path
) != 0 )
112 if ( errno
== EEXIST
)
115 throw AccessDeniedException ( string ( path
) );
121 Directory::CreateDirectory ( const string
& path
)
125 if ( isalpha ( path
[0] ) && path
[1] == ':' && path
[2] == cSep
)
127 nextIndex
= path
.find ( cSep
, 3);
128 index
= path
.find ( cSep
);
131 nextIndex
= path
.find ( cSep
);
133 bool directoryWasCreated
= false;
134 while ( nextIndex
!= string::npos
)
136 nextIndex
= path
.find ( cSep
, index
+ 1 );
137 directoryWasCreated
= mkdir_p ( path
.substr ( 0, nextIndex
).c_str () );
140 return directoryWasCreated
;
144 Directory::GenerateTree ( DirectoryLocation root
,
149 case IntermediateDirectory
:
150 return GenerateTree ( Environment::GetIntermediatePath (), verbose
);
151 case OutputDirectory
:
152 return GenerateTree ( Environment::GetOutputPath (), verbose
);
153 case InstallDirectory
:
154 return GenerateTree ( Environment::GetInstallPath (), verbose
);
156 throw InvalidOperationException ( __FILE__
,
158 "Invalid directory %d.",
164 Directory::GenerateTree ( const string
& parent
,
169 if ( parent
.size () > 0 )
171 if ( name
.size () > 0 )
172 path
= parent
+ sSep
+ name
;
175 if ( CreateDirectory ( path
) && verbose
)
176 printf ( "Created %s\n", path
.c_str () );
181 for ( directory_map::iterator i
= subdirs
.begin ();
185 i
->second
->GenerateTree ( path
, verbose
);
190 Directory::EscapeSpaces ( const string
& path
)
193 const char* p
= &path
[0];
197 newpath
= newpath
+ "\\ ";
199 newpath
= newpath
+ *p
;
206 Directory::CreateRule ( FILE* f
,
207 const string
& parent
)
210 string escapedName
= EscapeSpaces ( name
);
212 if ( escapedName
.size() > 0 )
214 if ( ! (escapedName
== "tools" &&
215 ( parent
== "$(OUTPUT)" || parent
== "$(INTERMEDIATE)" ) ) )
221 escapedName
.c_str (),
225 "\t$(ECHO_MKDIR)\n" );
231 path
= parent
+ sSep
+ escapedName
;
236 for ( directory_map::iterator i
= subdirs
.begin();
240 i
->second
->CreateRule ( f
, path
);
244 Directory::~Directory()
246 std::map
<std::string
, Directory
*>::iterator theIterator
;
247 for ( theIterator
= subdirs
.begin (); theIterator
!= subdirs
.end (); theIterator
++ )
248 delete theIterator
->second
;