From 8199b3ae54cd41ff1012a4cae3640028043b0bb4 Mon Sep 17 00:00:00 2001 From: "yuzo@chromium.org" Date: Tue, 9 Jun 2009 05:57:38 +0000 Subject: Include a parent directory link in the file list for file:///somepath Also, order files/directories lexicographically. TEST=on linux, type file:///usr/ in the address bar and make sure the contents are sorted and include an entry for '..', which is [parent directory]. On windows, type file:///C:/Users/ . BUG=12621, 12812 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17933 0039d316-1c4b-4281-b951-d872f2087c98 --- base/file_util_posix.cc | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'base/file_util_posix.cc') diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc index 7f40c17..92b9d00 100644 --- a/base/file_util_posix.cc +++ b/base/file_util_posix.cc @@ -522,6 +522,8 @@ FileEnumerator::FileEnumerator(const FilePath& root_path, file_type_(file_type), is_in_find_op_(false), fts_(NULL) { + // INCLUDE_DOT_DOT must not be specified if recursive. + DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_))); pending_paths_.push(root_path); } @@ -534,6 +536,8 @@ FileEnumerator::FileEnumerator(const FilePath& root_path, pattern_(root_path.value()), is_in_find_op_(false), fts_(NULL) { + // INCLUDE_DOT_DOT must not be specified if recursive. + DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_))); // The Windows version of this code only matches against items in the top-most // directory, and we're comparing fnmatch against full paths, so this is the // easiest way to get the right pattern. @@ -556,6 +560,14 @@ void FileEnumerator::GetFindInfo(FindInfo* info) { info->filename.assign(fts_ent_->fts_name); } +int CompareFiles(const FTSENT** a, const FTSENT** b) { + // Order lexicographically, ignoring case and whether they are files or + // directories. + // TODO(yuzo): make this case-sensitive, directories-then-files, and + // internationalized. + return base::strcasecmp((*a)->fts_name, (*b)->fts_name); +} + // As it stands, this method calls itself recursively when the next item of // the fts enumeration doesn't match (type, pattern, etc.). In the case of // large directories with many files this can be quite deep. @@ -571,11 +583,11 @@ FilePath FileEnumerator::Next() { pending_paths_.pop(); // Start a new find operation. - int ftsflags = FTS_LOGICAL; + int ftsflags = FTS_LOGICAL | FTS_SEEDOT; char top_dir[PATH_MAX]; base::strlcpy(top_dir, root_path_.value().c_str(), arraysize(top_dir)); char* dir_list[2] = { top_dir, NULL }; - fts_ = fts_open(dir_list, ftsflags, NULL); + fts_ = fts_open(dir_list, ftsflags, CompareFiles); if (!fts_) return Next(); is_in_find_op_ = true; @@ -604,6 +616,9 @@ FilePath FileEnumerator::Next() { } FilePath cur_file(fts_ent_->fts_path); + if (ShouldSkip(cur_file)) + return Next(); + if (fts_ent_->fts_info == FTS_D) { // If not recursive, then prune children. if (!recursive_) @@ -611,6 +626,11 @@ FilePath FileEnumerator::Next() { return (file_type_ & FileEnumerator::DIRECTORIES) ? cur_file : Next(); } else if (fts_ent_->fts_info == FTS_F) { return (file_type_ & FileEnumerator::FILES) ? cur_file : Next(); + } else if (fts_ent_->fts_info == FTS_DOT) { + if ((file_type_ & FileEnumerator::DIRECTORIES) && IsDotDot(cur_file)) { + return cur_file; + } + return Next(); } // TODO(erikkay) - verify that the other fts_info types aren't interesting return Next(); -- cgit v1.1