bring in latest filename code from panda
This commit is contained in:
parent
9492316ed7
commit
fa5f359fa3
|
|
@ -42,7 +42,7 @@ AC_SUBST(libm)
|
|||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(malloc.h alloca.h unistd.h utime.h io.h minmax.h dirent.h sys/types.h sys/time.h sys/utime.h sys/wait.h string.h regex.h getopt.h)
|
||||
AC_CHECK_HEADERS(malloc.h alloca.h unistd.h utime.h io.h minmax.h dirent.h glob.h sys/types.h sys/time.h sys/utime.h sys/wait.h string.h regex.h getopt.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
|
||||
|
|
|
|||
|
|
@ -85,12 +85,22 @@ get_num_files() const {
|
|||
// Access: Public
|
||||
// Description: Returns the nth file on the result list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Filename DSearchPath::Results::
|
||||
const Filename &DSearchPath::Results::
|
||||
get_file(int n) const {
|
||||
assert(n >= 0 && n < (int)_files.size());
|
||||
return _files[n];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DSearchPath::Results::add_file
|
||||
// Access: Public
|
||||
// Description: Adds a new file to the result list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DSearchPath::Results::
|
||||
add_file(const Filename &file) {
|
||||
_files.push_back(file);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DSearchPath::Default Constructor
|
||||
// Access: Public
|
||||
|
|
@ -246,7 +256,7 @@ get_num_directories() const {
|
|||
// Access: Public
|
||||
// Description: Returns the nth directory on the search list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Filename DSearchPath::
|
||||
const Filename &DSearchPath::
|
||||
get_directory(int n) const {
|
||||
assert(n >= 0 && n < (int)_directories.size());
|
||||
return _directories[n];
|
||||
|
|
@ -262,11 +272,22 @@ get_directory(int n) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
Filename DSearchPath::
|
||||
find_file(const Filename &filename) const {
|
||||
Directories::const_iterator di;
|
||||
for (di = _directories.begin(); di != _directories.end(); ++di) {
|
||||
Filename match((*di), filename);
|
||||
if (match.exists()) {
|
||||
return match;
|
||||
if (filename.is_local()) {
|
||||
Directories::const_iterator di;
|
||||
for (di = _directories.begin(); di != _directories.end(); ++di) {
|
||||
Filename match((*di), filename);
|
||||
if (match.exists()) {
|
||||
if ((*di) == "." && filename.is_fully_qualified()) {
|
||||
// A special case for the "." directory: to avoid prefixing
|
||||
// an endless stream of ./ in front of files, if the
|
||||
// filename already has a ./ prefixed
|
||||
// (i.e. is_fully_qualified() is true), we don't
|
||||
// prefix another one.
|
||||
return filename;
|
||||
} else {
|
||||
return match;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -280,21 +301,37 @@ find_file(const Filename &filename) const {
|
|||
// the indicated file, in order. Fills up the results
|
||||
// list with *all* of the matching filenames found, if
|
||||
// any. Returns the number of matches found.
|
||||
//
|
||||
// It is the responsibility of the the caller to clear
|
||||
// the results list first; otherwise, the newly-found
|
||||
// files will be appended to the list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int DSearchPath::
|
||||
find_all_files(const Filename &filename,
|
||||
DSearchPath::Results &results) const {
|
||||
results._files.clear();
|
||||
int num_added = 0;
|
||||
|
||||
Directories::const_iterator di;
|
||||
for (di = _directories.begin(); di != _directories.end(); ++di) {
|
||||
Filename match((*di), filename);
|
||||
if (match.exists()) {
|
||||
results._files.push_back(match);
|
||||
if (filename.is_local()) {
|
||||
Directories::const_iterator di;
|
||||
for (di = _directories.begin(); di != _directories.end(); ++di) {
|
||||
Filename match((*di), filename);
|
||||
if (match.exists()) {
|
||||
if ((*di) == "." && filename.is_fully_qualified()) {
|
||||
// A special case for the "." directory: to avoid prefixing
|
||||
// an endless stream of ./ in front of files, if the
|
||||
// filename already has a ./ prefixed
|
||||
// (i.e. is_fully_qualified() is true), we don't
|
||||
// prefix another one.
|
||||
results.add_file(filename);
|
||||
} else {
|
||||
results.add_file(match);
|
||||
}
|
||||
num_added++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results._files.size();
|
||||
return num_added;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@
|
|||
#include "ppremake.h"
|
||||
|
||||
#include "filename.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define pvector std::vector
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : DSearchPath
|
||||
// Description : This class stores a list of directories that can be
|
||||
|
|
@ -45,12 +46,14 @@ public:
|
|||
|
||||
void clear();
|
||||
int get_num_files() const;
|
||||
Filename get_file(int n) const;
|
||||
const Filename &get_file(int n) const;
|
||||
|
||||
public:
|
||||
void add_file(const Filename &file);
|
||||
|
||||
private:
|
||||
typedef vector<Filename> Files;
|
||||
typedef pvector<Filename> Files;
|
||||
Files _files;
|
||||
friend class DSearchPath;
|
||||
};
|
||||
|
||||
PUBLISHED:
|
||||
|
|
@ -70,7 +73,7 @@ PUBLISHED:
|
|||
|
||||
bool is_empty() const;
|
||||
int get_num_directories() const;
|
||||
Filename get_directory(int n) const;
|
||||
const Filename &get_directory(int n) const;
|
||||
|
||||
Filename find_file(const Filename &filename) const;
|
||||
int find_all_files(const Filename &filename, Results &results) const;
|
||||
|
|
@ -83,7 +86,7 @@ PUBLISHED:
|
|||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
private:
|
||||
typedef vector<Filename> Directories;
|
||||
typedef pvector<Filename> Directories;
|
||||
Directories _directories;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@
|
|||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GLOB_H
|
||||
#include <glob.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
|
@ -705,44 +709,14 @@ make_canonical() {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (get_fullpath() == "/") {
|
||||
// The root directory is a special case.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Temporarily save the current working directory.
|
||||
Filename cwd = ExecutionEnvironment::get_cwd();
|
||||
|
||||
if (is_directory()) {
|
||||
// If the filename itself represents a directory and not a
|
||||
// filename, cd to the named directory, not the one above it.
|
||||
string dirname = to_os_specific();
|
||||
|
||||
if (chdir(dirname.c_str()) < 0) {
|
||||
return false;
|
||||
}
|
||||
(*this) = ExecutionEnvironment::get_cwd();
|
||||
|
||||
} else {
|
||||
// Otherwise, if the filename represents a regular file (or
|
||||
// doesn't even exist), cd to the directory above.
|
||||
Filename dir(get_dirname());
|
||||
|
||||
if (dir.empty()) {
|
||||
// No dirname means the file is in this directory.
|
||||
set_dirname(cwd);
|
||||
return true;
|
||||
}
|
||||
|
||||
string dirname = dir.to_os_specific();
|
||||
if (chdir(dirname.c_str()) < 0) {
|
||||
return false;
|
||||
}
|
||||
set_dirname(ExecutionEnvironment::get_cwd().get_fullpath());
|
||||
}
|
||||
|
||||
// Now restore the current working directory.
|
||||
string osdir = cwd.to_os_specific();
|
||||
if (chdir(osdir.c_str()) < 0) {
|
||||
cerr << "Error! Cannot change back to " << cwd << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
return r_make_canonical(cwd);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1182,7 +1156,32 @@ find_on_searchpath(const DSearchPath &searchpath) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool Filename::
|
||||
scan_directory(vector_string &contents) const {
|
||||
#if defined(HAVE_DIRENT_H)
|
||||
#if defined(HAVE_GLOB_H)
|
||||
// In some cases, particularly with NFS, it seems that opendir()
|
||||
// .. readdir() fails to properly read the entire directory ("Value
|
||||
// too large for defined data type"), but glob() succeeds.
|
||||
string dirname;
|
||||
if (empty()) {
|
||||
dirname = "*";
|
||||
} else if (_filename[_filename.length() - 1] == '/') {
|
||||
dirname = _filename + "*";
|
||||
} else {
|
||||
dirname = _filename + "/*";
|
||||
}
|
||||
|
||||
glob_t globbuf;
|
||||
|
||||
int r = glob(dirname.c_str(), GLOB_ERR, NULL, &globbuf);
|
||||
size_t offset = dirname.size() - 1;
|
||||
|
||||
for (int i = 0; globbuf.gl_pathv[i] != NULL; i++) {
|
||||
contents.push_back(globbuf.gl_pathv[i] + offset);
|
||||
}
|
||||
globfree(&globbuf);
|
||||
|
||||
return true;
|
||||
|
||||
#elif defined(HAVE_DIRENT_H)
|
||||
size_t orig_size = contents.size();
|
||||
|
||||
string dirname;
|
||||
|
|
@ -1193,6 +1192,7 @@ scan_directory(vector_string &contents) const {
|
|||
}
|
||||
DIR *root = opendir(dirname.c_str());
|
||||
if (root == (DIR *)NULL) {
|
||||
perror(dirname.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1204,6 +1204,12 @@ scan_directory(vector_string &contents) const {
|
|||
}
|
||||
d = readdir(root);
|
||||
}
|
||||
if (errno != 0 && errno != ENOENT && errno != ENOTDIR) {
|
||||
cerr << "Error occurred while scanning directory " << dirname << "\n";
|
||||
perror(dirname.c_str());
|
||||
closedir(root);
|
||||
return false;
|
||||
}
|
||||
closedir(root);
|
||||
|
||||
sort(contents.begin() + orig_size, contents.end());
|
||||
|
|
@ -1379,14 +1385,20 @@ open_append(ofstream &stream) const {
|
|||
// false otherwise. This requires the setting of the
|
||||
// set_text()/set_binary() flags to open the file
|
||||
// appropriately as indicated; it is an error to call
|
||||
// open_read() without first calling one of set_text()
|
||||
// or set_binary().
|
||||
// open_read_write() without first calling one of
|
||||
// set_text() or set_binary().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Filename::
|
||||
open_read_write(fstream &stream) const {
|
||||
assert(is_text() || is_binary());
|
||||
|
||||
ios_openmode open_mode = ios::in | ios::out;
|
||||
ios_openmode open_mode = ios::out | ios::in;
|
||||
|
||||
// Since ios::in also seems to imply ios::nocreate (!), we must
|
||||
// guarantee the file already exists before we try to open it.
|
||||
if (!exists()) {
|
||||
touch();
|
||||
}
|
||||
|
||||
#ifdef HAVE_IOS_BINARY
|
||||
// For some reason, some systems (like Irix) don't define
|
||||
|
|
@ -1731,3 +1743,50 @@ count_slashes(const string &str) {
|
|||
return count;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::r_make_canonical
|
||||
// Access: Private
|
||||
// Description: The recursive implementation of make_canonical().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Filename::
|
||||
r_make_canonical(const Filename &cwd) {
|
||||
if (get_fullpath() == "/") {
|
||||
// If we reached the root, the whole path doesn't exist. Report
|
||||
// failure.
|
||||
return false;
|
||||
}
|
||||
|
||||
// First, try to cd to the filename directly.
|
||||
string os_specific = to_os_specific();
|
||||
|
||||
if (chdir(os_specific.c_str()) >= 0) {
|
||||
// That worked, save the full path string.
|
||||
(*this) = ExecutionEnvironment::get_cwd();
|
||||
|
||||
// And restore the current working directory.
|
||||
string osdir = cwd.to_os_specific();
|
||||
if (chdir(osdir.c_str()) < 0) {
|
||||
cerr << "Error! Cannot change back to " << cwd << "\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// That didn't work; maybe it's not a directory. Recursively go to
|
||||
// the directory above.
|
||||
|
||||
Filename dir(get_dirname());
|
||||
|
||||
if (dir.empty()) {
|
||||
// No dirname means the file is in this directory.
|
||||
set_dirname(cwd);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!dir.r_make_canonical(cwd)) {
|
||||
return false;
|
||||
}
|
||||
set_dirname(dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ private:
|
|||
void locate_extension();
|
||||
size_t get_common_prefix(const string &other) const;
|
||||
static int count_slashes(const string &str);
|
||||
bool r_make_canonical(const Filename &cwd);
|
||||
|
||||
string _filename;
|
||||
// We'll make these size_t instead of string::size_type to help out
|
||||
|
|
|
|||
Loading…
Reference in New Issue