mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-03 11:08:32 +00:00
For PR797:
Remove exception throwing from Path::getDirectoryContents and its users. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29841 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e5c9cb5eb6
commit
142ca8e818
@ -343,10 +343,12 @@ namespace sys {
|
|||||||
|
|
||||||
/// This function builds a list of paths that are the names of the
|
/// This function builds a list of paths that are the names of the
|
||||||
/// files and directories in a directory.
|
/// files and directories in a directory.
|
||||||
/// @returns false if \p this is not a directory, true otherwise
|
/// @returns true if an error occurs, true otherwise
|
||||||
/// @throws std::string if the directory cannot be searched
|
|
||||||
/// @brief Build a list of directory's contents.
|
/// @brief Build a list of directory's contents.
|
||||||
bool getDirectoryContents(std::set<Path> &paths) const;
|
bool getDirectoryContents(
|
||||||
|
std::set<Path> &paths, ///< The resulting list of file & directory names
|
||||||
|
std::string* ErrMsg ///< Optional place to return an error message.
|
||||||
|
) const;
|
||||||
|
|
||||||
/// This function returns status information about the file. The type of
|
/// This function returns status information about the file. The type of
|
||||||
/// path (file or directory) is updated to reflect the actual contents
|
/// path (file or directory) is updated to reflect the actual contents
|
||||||
|
@ -415,10 +415,12 @@ bool Path::makeExecutableOnDisk(std::string* ErrMsg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Path::getDirectoryContents(std::set<Path>& result) const {
|
Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const {
|
||||||
DIR* direntries = ::opendir(path.c_str());
|
DIR* direntries = ::opendir(path.c_str());
|
||||||
if (direntries == 0)
|
if (direntries == 0) {
|
||||||
ThrowErrno(path + ": can't open directory");
|
MakeErrMsg(ErrMsg, path + ": can't open directory");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::string dirPath = path;
|
std::string dirPath = path;
|
||||||
if (!lastIsSlash(dirPath))
|
if (!lastIsSlash(dirPath))
|
||||||
@ -433,14 +435,15 @@ Path::getDirectoryContents(std::set<Path>& result) const {
|
|||||||
if (0 != lstat(aPath.path.c_str(), &st)) {
|
if (0 != lstat(aPath.path.c_str(), &st)) {
|
||||||
if (S_ISLNK(st.st_mode))
|
if (S_ISLNK(st.st_mode))
|
||||||
continue; // dangling symlink -- ignore
|
continue; // dangling symlink -- ignore
|
||||||
ThrowErrno(aPath.path + ": can't determine file object type");
|
MakeErrMsg(ErrMsg, aPath.path + ": can't determine file object type");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
result.insert(aPath);
|
result.insert(aPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(direntries);
|
closedir(direntries);
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -353,9 +353,11 @@ bool Path::makeExecutableOnDisk(std::string* ErrMsg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Path::getDirectoryContents(std::set<Path>& result) const {
|
Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const {
|
||||||
if (!isDirectory())
|
if (!isDirectory()) {
|
||||||
return false;
|
MakeErrMsg(ErrMsg, path + ": not a directory");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
result.clear();
|
result.clear();
|
||||||
WIN32_FIND_DATA fd;
|
WIN32_FIND_DATA fd;
|
||||||
@ -369,7 +371,8 @@ Path::getDirectoryContents(std::set<Path>& result) const {
|
|||||||
if (h == INVALID_HANDLE_VALUE) {
|
if (h == INVALID_HANDLE_VALUE) {
|
||||||
if (GetLastError() == ERROR_FILE_NOT_FOUND)
|
if (GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||||
return true; // not really an error, now is it?
|
return true; // not really an error, now is it?
|
||||||
ThrowError(path + ": Can't read directory: ");
|
MakeErrMsg(ErrMsg, path + ": Can't read directory: ");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -384,9 +387,10 @@ Path::getDirectoryContents(std::set<Path>& result) const {
|
|||||||
FindClose(h);
|
FindClose(h);
|
||||||
if (err != ERROR_NO_MORE_FILES) {
|
if (err != ERROR_NO_MORE_FILES) {
|
||||||
SetLastError(err);
|
SetLastError(err);
|
||||||
ThrowError(path + ": Can't read directory: ");
|
MakeErrMsg(ErrMsg, path + ": Can't read directory: ");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -157,7 +157,8 @@ static bool isBytecodeLPath(const std::string &LibPath) {
|
|||||||
|
|
||||||
// Grab the contents of the -L path
|
// Grab the contents of the -L path
|
||||||
std::set<sys::Path> Files;
|
std::set<sys::Path> Files;
|
||||||
LPath.getDirectoryContents(Files);
|
if (LPath.getDirectoryContents(Files, 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Iterate over the contents one by one to determine
|
// Iterate over the contents one by one to determine
|
||||||
// if this -L path has any bytecode shared libraries
|
// if this -L path has any bytecode shared libraries
|
||||||
|
@ -269,32 +269,38 @@ ArchiveOperation parseCommandLine() {
|
|||||||
// the Paths vector (built by buildPaths, below) and replaces any directories it
|
// the Paths vector (built by buildPaths, below) and replaces any directories it
|
||||||
// finds with all the files in that directory (recursively). It uses the
|
// finds with all the files in that directory (recursively). It uses the
|
||||||
// sys::Path::getDirectoryContent method to perform the actual directory scans.
|
// sys::Path::getDirectoryContent method to perform the actual directory scans.
|
||||||
std::set<sys::Path> recurseDirectories(const sys::Path& path) {
|
bool
|
||||||
std::set<sys::Path> result;
|
recurseDirectories(const sys::Path& path,
|
||||||
|
std::set<sys::Path>& result, std::string* ErrMsg) {
|
||||||
|
result.clear();
|
||||||
if (RecurseDirectories) {
|
if (RecurseDirectories) {
|
||||||
std::set<sys::Path> content;
|
std::set<sys::Path> content;
|
||||||
path.getDirectoryContents(content);
|
if (path.getDirectoryContents(content, ErrMsg))
|
||||||
|
return true;
|
||||||
|
|
||||||
for (std::set<sys::Path>::iterator I = content.begin(), E = content.end();
|
for (std::set<sys::Path>::iterator I = content.begin(), E = content.end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
// Make sure it exists and is a directory
|
// Make sure it exists and is a directory
|
||||||
sys::FileStatus Status;
|
sys::FileStatus Status;
|
||||||
if (!I->getFileStatus(Status)) {
|
if (I->getFileStatus(Status)) {
|
||||||
if (Status.isDir) {
|
if (Status.isDir) {
|
||||||
std::set<sys::Path> moreResults = recurseDirectories(*I);
|
std::set<sys::Path> moreResults;
|
||||||
result.insert(moreResults.begin(), moreResults.end());
|
if (recurseDirectories(*I, moreResults, ErrMsg))
|
||||||
} else {
|
return true;
|
||||||
result.insert(*I);
|
result.insert(moreResults.begin(), moreResults.end());
|
||||||
}
|
} else {
|
||||||
}
|
result.insert(*I);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildPaths - Convert the strings in the Members vector to sys::Path objects
|
// buildPaths - Convert the strings in the Members vector to sys::Path objects
|
||||||
// and make sure they are valid and exist exist. This check is only needed for
|
// and make sure they are valid and exist exist. This check is only needed for
|
||||||
// the operations that add/replace files to the archive ('q' and 'r')
|
// the operations that add/replace files to the archive ('q' and 'r')
|
||||||
void buildPaths(bool checkExistence = true) {
|
bool buildPaths(bool checkExistence, std::string* ErrMsg) {
|
||||||
for (unsigned i = 0; i < Members.size(); i++) {
|
for (unsigned i = 0; i < Members.size(); i++) {
|
||||||
sys::Path aPath;
|
sys::Path aPath;
|
||||||
if (!aPath.set(Members[i]))
|
if (!aPath.set(Members[i]))
|
||||||
@ -307,7 +313,9 @@ void buildPaths(bool checkExistence = true) {
|
|||||||
if (aPath.getFileStatus(si, &Err))
|
if (aPath.getFileStatus(si, &Err))
|
||||||
throw Err;
|
throw Err;
|
||||||
if (si.isDir) {
|
if (si.isDir) {
|
||||||
std::set<sys::Path> dirpaths = recurseDirectories(aPath);
|
std::set<sys::Path> dirpaths;
|
||||||
|
if (recurseDirectories(aPath, dirpaths, ErrMsg))
|
||||||
|
return true;
|
||||||
Paths.insert(dirpaths.begin(),dirpaths.end());
|
Paths.insert(dirpaths.begin(),dirpaths.end());
|
||||||
} else {
|
} else {
|
||||||
Paths.insert(aPath);
|
Paths.insert(aPath);
|
||||||
@ -316,6 +324,7 @@ void buildPaths(bool checkExistence = true) {
|
|||||||
Paths.insert(aPath);
|
Paths.insert(aPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// printSymbolTable - print out the archive's symbol table.
|
// printSymbolTable - print out the archive's symbol table.
|
||||||
@ -333,8 +342,9 @@ void printSymbolTable() {
|
|||||||
// looking for members that match the path list. It is careful to uncompress
|
// looking for members that match the path list. It is careful to uncompress
|
||||||
// things that should be and to skip bytecode files unless the 'k' modifier was
|
// things that should be and to skip bytecode files unless the 'k' modifier was
|
||||||
// given.
|
// given.
|
||||||
void doPrint() {
|
bool doPrint(std::string* ErrMsg) {
|
||||||
buildPaths(false);
|
if (buildPaths(false, ErrMsg))
|
||||||
|
return true;
|
||||||
unsigned countDown = Count;
|
unsigned countDown = Count;
|
||||||
for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
|
for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
|
||||||
I != E; ++I ) {
|
I != E; ++I ) {
|
||||||
@ -365,11 +375,13 @@ void doPrint() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// putMode - utility function for printing out the file mode when the 't'
|
// putMode - utility function for printing out the file mode when the 't'
|
||||||
// operation is in verbose mode.
|
// operation is in verbose mode.
|
||||||
void printMode(unsigned mode) {
|
void
|
||||||
|
printMode(unsigned mode) {
|
||||||
if (mode & 004)
|
if (mode & 004)
|
||||||
std::cout << "r";
|
std::cout << "r";
|
||||||
else
|
else
|
||||||
@ -388,8 +400,10 @@ void printMode(unsigned mode) {
|
|||||||
// the file names of each of the members. However, if verbose mode is requested
|
// the file names of each of the members. However, if verbose mode is requested
|
||||||
// ('v' modifier) then the file type, permission mode, user, group, size, and
|
// ('v' modifier) then the file type, permission mode, user, group, size, and
|
||||||
// modification time are also printed.
|
// modification time are also printed.
|
||||||
void doDisplayTable() {
|
bool
|
||||||
buildPaths(false);
|
doDisplayTable(std::string* ErrMsg) {
|
||||||
|
if (buildPaths(false, ErrMsg))
|
||||||
|
return true;
|
||||||
for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
|
for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
|
||||||
I != E; ++I ) {
|
I != E; ++I ) {
|
||||||
if (Paths.empty() ||
|
if (Paths.empty() ||
|
||||||
@ -422,12 +436,15 @@ void doDisplayTable() {
|
|||||||
}
|
}
|
||||||
if (ReallyVerbose)
|
if (ReallyVerbose)
|
||||||
printSymbolTable();
|
printSymbolTable();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// doExtract - Implement the 'x' operation. This function extracts files back to
|
// doExtract - Implement the 'x' operation. This function extracts files back to
|
||||||
// the file system, making sure to uncompress any that were compressed
|
// the file system, making sure to uncompress any that were compressed
|
||||||
bool doExtract(std::string* ErrMsg) {
|
bool
|
||||||
buildPaths(false);
|
doExtract(std::string* ErrMsg) {
|
||||||
|
if (buildPaths(false, ErrMsg))
|
||||||
|
return true;
|
||||||
unsigned countDown = Count;
|
unsigned countDown = Count;
|
||||||
for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
|
for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
|
||||||
I != E; ++I ) {
|
I != E; ++I ) {
|
||||||
@ -472,9 +489,12 @@ bool doExtract(std::string* ErrMsg) {
|
|||||||
// members from the archive. Note that if the count is specified, there should
|
// members from the archive. Note that if the count is specified, there should
|
||||||
// be no more than one path in the Paths list or else this algorithm breaks.
|
// be no more than one path in the Paths list or else this algorithm breaks.
|
||||||
// That check is enforced in parseCommandLine (above).
|
// That check is enforced in parseCommandLine (above).
|
||||||
void doDelete() {
|
bool
|
||||||
buildPaths(false);
|
doDelete(std::string* ErrMsg) {
|
||||||
if (Paths.empty()) return;
|
if (buildPaths(false, ErrMsg))
|
||||||
|
return true;
|
||||||
|
if (Paths.empty())
|
||||||
|
return false;
|
||||||
unsigned countDown = Count;
|
unsigned countDown = Count;
|
||||||
for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
|
for (Archive::iterator I = TheArchive->begin(), E = TheArchive->end();
|
||||||
I != E; ) {
|
I != E; ) {
|
||||||
@ -491,20 +511,21 @@ void doDelete() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We're done editting, reconstruct the archive.
|
// We're done editting, reconstruct the archive.
|
||||||
std::string errmsg;
|
if (!TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg))
|
||||||
if (!TheArchive->writeToDisk(SymTable,TruncateNames,Compression,&errmsg))
|
return true;
|
||||||
throw errmsg;
|
|
||||||
if (ReallyVerbose)
|
if (ReallyVerbose)
|
||||||
printSymbolTable();
|
printSymbolTable();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// doMore - Implement the move operation. This function re-arranges just the
|
// doMore - Implement the move operation. This function re-arranges just the
|
||||||
// order of the archive members so that when the archive is written the move
|
// order of the archive members so that when the archive is written the move
|
||||||
// of the members is accomplished. Note the use of the RelPos variable to
|
// of the members is accomplished. Note the use of the RelPos variable to
|
||||||
// determine where the items should be moved to.
|
// determine where the items should be moved to.
|
||||||
void doMove() {
|
bool
|
||||||
|
doMove(std::string* ErrMsg) {
|
||||||
buildPaths(false);
|
if (buildPaths(false, ErrMsg))
|
||||||
|
return true;
|
||||||
|
|
||||||
// By default and convention the place to move members to is the end of the
|
// By default and convention the place to move members to is the end of the
|
||||||
// archive.
|
// archive.
|
||||||
@ -545,19 +566,22 @@ void doMove() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We're done editting, reconstruct the archive.
|
// We're done editting, reconstruct the archive.
|
||||||
std::string errmsg;
|
if (!TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg))
|
||||||
if (!TheArchive->writeToDisk(SymTable,TruncateNames,Compression,&errmsg))
|
return true;
|
||||||
throw errmsg;
|
|
||||||
if (ReallyVerbose)
|
if (ReallyVerbose)
|
||||||
printSymbolTable();
|
printSymbolTable();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// doQuickAppend - Implements the 'q' operation. This function just
|
// doQuickAppend - Implements the 'q' operation. This function just
|
||||||
// indiscriminantly adds the members to the archive and rebuilds it.
|
// indiscriminantly adds the members to the archive and rebuilds it.
|
||||||
void doQuickAppend() {
|
bool
|
||||||
|
doQuickAppend(std::string* ErrMsg) {
|
||||||
// Get the list of paths to append.
|
// Get the list of paths to append.
|
||||||
buildPaths(true);
|
if (buildPaths(true, ErrMsg))
|
||||||
if (Paths.empty()) return;
|
return true;
|
||||||
|
if (Paths.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
// Append them quickly.
|
// Append them quickly.
|
||||||
for (std::set<sys::Path>::iterator PI = Paths.begin(), PE = Paths.end();
|
for (std::set<sys::Path>::iterator PI = Paths.begin(), PE = Paths.end();
|
||||||
@ -566,20 +590,23 @@ void doQuickAppend() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We're done editting, reconstruct the archive.
|
// We're done editting, reconstruct the archive.
|
||||||
std::string errmsg;
|
if (!TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg))
|
||||||
if (!TheArchive->writeToDisk(SymTable,TruncateNames,Compression,&errmsg))
|
return true;
|
||||||
throw errmsg;
|
|
||||||
if (ReallyVerbose)
|
if (ReallyVerbose)
|
||||||
printSymbolTable();
|
printSymbolTable();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// doReplaceOrInsert - Implements the 'r' operation. This function will replace
|
// doReplaceOrInsert - Implements the 'r' operation. This function will replace
|
||||||
// any existing files or insert new ones into the archive.
|
// any existing files or insert new ones into the archive.
|
||||||
void doReplaceOrInsert() {
|
bool
|
||||||
|
doReplaceOrInsert(std::string* ErrMsg) {
|
||||||
|
|
||||||
// Build the list of files to be added/replaced.
|
// Build the list of files to be added/replaced.
|
||||||
buildPaths(true);
|
if (buildPaths(true, ErrMsg))
|
||||||
if (Paths.empty()) return;
|
return true;
|
||||||
|
if (Paths.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
// Keep track of the paths that remain to be inserted.
|
// Keep track of the paths that remain to be inserted.
|
||||||
std::set<sys::Path> remaining(Paths);
|
std::set<sys::Path> remaining(Paths);
|
||||||
@ -657,11 +684,11 @@ void doReplaceOrInsert() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We're done editting, reconstruct the archive.
|
// We're done editting, reconstruct the archive.
|
||||||
std::string errmsg;
|
if (!TheArchive->writeToDisk(SymTable,TruncateNames,Compression,ErrMsg))
|
||||||
if (!TheArchive->writeToDisk(SymTable,TruncateNames,Compression,&errmsg))
|
return true;
|
||||||
throw errmsg;
|
|
||||||
if (ReallyVerbose)
|
if (ReallyVerbose)
|
||||||
printSymbolTable();
|
printSymbolTable();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// main - main program for llvm-ar .. see comments in the code
|
// main - main program for llvm-ar .. see comments in the code
|
||||||
@ -714,23 +741,23 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
// Perform the operation
|
// Perform the operation
|
||||||
std::string ErrMsg;
|
std::string ErrMsg;
|
||||||
|
bool haveError = false;
|
||||||
switch (Operation) {
|
switch (Operation) {
|
||||||
case Print: doPrint(); break;
|
case Print: haveError = doPrint(&ErrMsg); break;
|
||||||
case Delete: doDelete(); break;
|
case Delete: haveError = doDelete(&ErrMsg); break;
|
||||||
case Move: doMove(); break;
|
case Move: haveError = doMove(&ErrMsg); break;
|
||||||
case QuickAppend: /* FALL THROUGH */
|
case QuickAppend: haveError = doQuickAppend(&ErrMsg); break;
|
||||||
case ReplaceOrInsert: doReplaceOrInsert(); break;
|
case ReplaceOrInsert: haveError = doReplaceOrInsert(&ErrMsg); break;
|
||||||
case DisplayTable: doDisplayTable(); break;
|
case DisplayTable: haveError = doDisplayTable(&ErrMsg); break;
|
||||||
case Extract:
|
case Extract: haveError = doExtract(&ErrMsg); break;
|
||||||
if (doExtract(&ErrMsg)) {
|
|
||||||
std::cerr << argv[0] << ": " << ErrMsg << "\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NoOperation:
|
case NoOperation:
|
||||||
std::cerr << argv[0] << ": No operation was selected.\n";
|
std::cerr << argv[0] << ": No operation was selected.\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (haveError) {
|
||||||
|
std::cerr << argv[0] << ": " << ErrMsg << "\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
} catch (const char*msg) {
|
} catch (const char*msg) {
|
||||||
// These errors are usage errors, thrown only by the various checks in the
|
// These errors are usage errors, thrown only by the various checks in the
|
||||||
// code above.
|
// code above.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user