[Lldb-commits] [lldb] r240983 - Rewrite FileSpec::EnumerateDirectory to avoid code duplication.

Chaoren Lin chaorenl at google.com
Mon Jun 29 12:07:35 PDT 2015


Author: chaoren
Date: Mon Jun 29 14:07:35 2015
New Revision: 240983

URL: http://llvm.org/viewvc/llvm-project?rev=240983&view=rev
Log:
Rewrite FileSpec::EnumerateDirectory to avoid code duplication.

Reviewers: clayborg

Reviewed By: clayborg

Subscribers: lldb-commits

Differential Revision: http://reviews.llvm.org/D10811

Modified:
    lldb/trunk/include/lldb/Host/FileSpec.h
    lldb/trunk/source/Host/common/FileSpec.cpp

Modified: lldb/trunk/include/lldb/Host/FileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/FileSpec.h?rev=240983&r1=240982&r2=240983&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/FileSpec.h (original)
+++ lldb/trunk/include/lldb/Host/FileSpec.h Mon Jun 29 14:07:35 2015
@@ -803,8 +803,7 @@ public:
 
     typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton,
                                                                         FileType file_type,
-                                                                        const FileSpec &spec
-);
+                                                                        const FileSpec &spec);
 
     static EnumerateDirectoryResult
     EnumerateDirectory (const char *dir_path,

Modified: lldb/trunk/source/Host/common/FileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSpec.cpp?rev=240983&r1=240982&r2=240983&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/FileSpec.cpp (original)
+++ lldb/trunk/source/Host/common/FileSpec.cpp Mon Jun 29 14:07:35 2015
@@ -1272,207 +1272,26 @@ FileSpec::EnumerateDirectory
     void *callback_baton
 )
 {
-    if (dir_path && dir_path[0])
-    {
-#if _WIN32
-        std::string szDir(dir_path);
-        szDir += "\\*";
-
-        WIN32_FIND_DATA ffd;
-        HANDLE hFind = FindFirstFile(szDir.c_str(), &ffd);
-
-        if (hFind == INVALID_HANDLE_VALUE)
-        {
-            return eEnumerateDirectoryResultNext;
-        }
-
-        do
-        {
-            bool call_callback = false;
-            FileSpec::FileType file_type = eFileTypeUnknown;
-            if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-            {
-                size_t len = strlen(ffd.cFileName);
-
-                if (len == 1 && ffd.cFileName[0] == '.')
-                    continue;
-
-                if (len == 2 && ffd.cFileName[0] == '.' && ffd.cFileName[1] == '.')
-                    continue;
-
-                file_type = eFileTypeDirectory;
-                call_callback = find_directories;
-            }
-            else if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE)
-            {
-                file_type = eFileTypeOther;
-                call_callback = find_other;
-            }
-            else
-            {
-                file_type = eFileTypeRegular;
-                call_callback = find_files;
-            }
-            if (call_callback)
-            {
-                char child_path[MAX_PATH];
-                const int child_path_len = ::snprintf (child_path, sizeof(child_path), "%s\\%s", dir_path, ffd.cFileName);
-                if (child_path_len < (int)(sizeof(child_path) - 1))
+    return ForEachItemInDirectory(dir_path,
+            [&find_directories, &find_files, &find_other, &callback, &callback_baton]
+            (FileType file_type, const FileSpec &file_spec) {
+                switch (file_type)
                 {
-                    // Don't resolve the file type or path
-                    FileSpec child_path_spec (child_path, false);
-
-                    EnumerateDirectoryResult result = callback (callback_baton, file_type, child_path_spec);
-
-                    switch (result)
-                    {
-                    case eEnumerateDirectoryResultNext:
-                        // Enumerate next entry in the current directory. We just
-                        // exit this switch and will continue enumerating the
-                        // current directory as we currently are...
+                    case FileType::eFileTypeDirectory:
+                        if (find_directories)
+                            return callback(callback_baton, file_type, file_spec);
                         break;
-
-                    case eEnumerateDirectoryResultEnter: // Recurse into the current entry if it is a directory or symlink, or next if not
-                        if (FileSpec::EnumerateDirectory(child_path,
-                            find_directories,
-                            find_files,
-                            find_other,
-                            callback,
-                            callback_baton) == eEnumerateDirectoryResultQuit)
-                        {
-                            // The subdirectory returned Quit, which means to 
-                            // stop all directory enumerations at all levels.
-                            return eEnumerateDirectoryResultQuit;
-                        }
+                    case FileType::eFileTypeRegular:
+                        if (find_files)
+                            return callback(callback_baton, file_type, file_spec);
+                        break;
+                    default:
+                        if (find_other)
+                            return callback(callback_baton, file_type, file_spec);
                         break;
-
-                    case eEnumerateDirectoryResultExit:  // Exit from the current directory at the current level.
-                        // Exit from this directory level and tell parent to 
-                        // keep enumerating.
-                        return eEnumerateDirectoryResultNext;
-
-                    case eEnumerateDirectoryResultQuit:  // Stop directory enumerations at any level
-                        return eEnumerateDirectoryResultQuit;
-                    }
-                }
-            }
-        } while (FindNextFile(hFind, &ffd) != 0);
-
-        FindClose(hFind);
-#else
-        lldb_utility::CleanUp <DIR *, int> dir_path_dir(opendir(dir_path), NULL, closedir);
-        if (dir_path_dir.is_valid())
-        {
-            char dir_path_last_char = dir_path[strlen(dir_path) - 1];
-
-            long path_max = fpathconf (dirfd (dir_path_dir.get()), _PC_NAME_MAX);
-#if defined (__APPLE_) && defined (__DARWIN_MAXPATHLEN)
-            if (path_max < __DARWIN_MAXPATHLEN)
-                path_max = __DARWIN_MAXPATHLEN;
-#endif
-            struct dirent *buf, *dp;
-            buf = (struct dirent *) malloc (offsetof (struct dirent, d_name) + path_max + 1);
-
-            while (buf && readdir_r(dir_path_dir.get(), buf, &dp) == 0 && dp)
-            {
-                // Only search directories
-                if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN)
-                {
-                    size_t len = strlen(dp->d_name);
-
-                    if (len == 1 && dp->d_name[0] == '.')
-                        continue;
-
-                    if (len == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
-                        continue;
-                }
-            
-                bool call_callback = false;
-                FileSpec::FileType file_type = eFileTypeUnknown;
-
-                switch (dp->d_type)
-                {
-                default:
-                case DT_UNKNOWN:    file_type = eFileTypeUnknown;       call_callback = true;               break;
-                case DT_FIFO:       file_type = eFileTypePipe;          call_callback = find_other;         break;
-                case DT_CHR:        file_type = eFileTypeOther;         call_callback = find_other;         break;
-                case DT_DIR:        file_type = eFileTypeDirectory;     call_callback = find_directories;   break;
-                case DT_BLK:        file_type = eFileTypeOther;         call_callback = find_other;         break;
-                case DT_REG:        file_type = eFileTypeRegular;       call_callback = find_files;         break;
-                case DT_LNK:        file_type = eFileTypeSymbolicLink;  call_callback = find_other;         break;
-                case DT_SOCK:       file_type = eFileTypeSocket;        call_callback = find_other;         break;
-#if !defined(__OpenBSD__)
-                case DT_WHT:        file_type = eFileTypeOther;         call_callback = find_other;         break;
-#endif
-                }
-
-                if (call_callback)
-                {
-                    char child_path[PATH_MAX];
-
-                    // Don't make paths with "/foo//bar", that just confuses everybody.
-                    int child_path_len;
-                    if (dir_path_last_char == '/')
-                        child_path_len = ::snprintf (child_path, sizeof(child_path), "%s%s", dir_path, dp->d_name);
-                    else
-                        child_path_len = ::snprintf (child_path, sizeof(child_path), "%s/%s", dir_path, dp->d_name);
-
-                    if (child_path_len < (int)(sizeof(child_path) - 1))
-                    {
-                        // Don't resolve the file type or path
-                        FileSpec child_path_spec (child_path, false);
-
-                        EnumerateDirectoryResult result = callback (callback_baton, file_type, child_path_spec);
-                        
-                        switch (result)
-                        {
-                        case eEnumerateDirectoryResultNext:  
-                            // Enumerate next entry in the current directory. We just
-                            // exit this switch and will continue enumerating the
-                            // current directory as we currently are...
-                            break;
-
-                        case eEnumerateDirectoryResultEnter: // Recurse into the current entry if it is a directory or symlink, or next if not
-                            if (FileSpec::EnumerateDirectory (child_path, 
-                                                              find_directories, 
-                                                              find_files, 
-                                                              find_other, 
-                                                              callback, 
-                                                              callback_baton) == eEnumerateDirectoryResultQuit)
-                            {
-                                // The subdirectory returned Quit, which means to 
-                                // stop all directory enumerations at all levels.
-                                if (buf)
-                                    free (buf);
-                                return eEnumerateDirectoryResultQuit;
-                            }
-                            break;
-                        
-                        case eEnumerateDirectoryResultExit:  // Exit from the current directory at the current level.
-                            // Exit from this directory level and tell parent to 
-                            // keep enumerating.
-                            if (buf)
-                                free (buf);
-                            return eEnumerateDirectoryResultNext;
-
-                        case eEnumerateDirectoryResultQuit:  // Stop directory enumerations at any level
-                            if (buf)
-                                free (buf);
-                            return eEnumerateDirectoryResultQuit;
-                        }
-                    }
                 }
-            }
-            if (buf)
-            {
-                free (buf);
-            }
-        }
-#endif
-    }
-    // By default when exiting a directory, we tell the parent enumeration
-    // to continue enumerating.
-    return eEnumerateDirectoryResultNext;    
+                return eEnumerateDirectoryResultNext;
+            });
 }
 
 FileSpec





More information about the lldb-commits mailing list