ACCU Home page ACCU Conference Page
Search Contact us ACCU at Flickr ACCU at GitHib ACCU at Facebook ACCU at Linked-in ACCU at Twitter Skip Navigation

pinQuality Matters: Diagnostic Measures (Listings)

Overload Journal #95 - February 2010 + Programming Topics + Design of applications and programs   Author: Matthew Wilson
Program listings for Quality Matters: Diagnostic Measures

    unsigned list_all_files_r(char const* path)  
    {  
      STLSOFT_ASSERT(NULL != path);  
      STLSOFT_ASSERT('\0' != 0[path]);  
      std::string directory(path);  
      if(directory[directory.size() - 1u] != '/')  
      {  
        directory += '/';  
      }  

      DIR* dir = ::opendir(path);

      if(NULL == dir)  
      {  
        ff::fmtln(std::cerr,  
           "failed to search '{0}': {1} ({2})", path,  
           stlsoft::error_desc(errno), errno);  
        return ~0u;  
      }  
      else  
      {  
        stlsoft::scoped_handle<DIR*>  scoper(dir,  
           ::closedir);  
        unsigned n = 0u;  
        { for(struct dirent* de; NULL != (  
           de = ::readdir(dir));)  
        {  
          if( de->d_name[0] == '.' &&  
              de->d_name[1] == '\0')  
          {  
            // '.'  
          }  
          else if(de->d_name[0] == '.' &&  
                  de->d_name[1] == '.' &&  
                  de->d_name[2] == '\0')  
          {  
            // '..'  
          }  
          else  
          {  
            std::string entryPath   
               = directory + de->d_name;  
            struct stat st;  
            int r = ::stat(entryPath.c_str(), &st);  
            if(0 != r)  
            {  
              ff::fmtln(std::cerr,  
                 "failed to stat '{0}': {1} ({2})",  
                 entryPath,  
                 stlsoft::error_desc(errno), errno);  
            }  
            else  
            {  
              if(st.st_mode & S_IFREG)  
              {  
                ff::fmtln(std::cout, "    {0}",  
                   entryPath);  
                ++n;  
              }  
              else  
              {  
                n += list_all_files_r(  
                   entryPath.c_str());  
              }  
            }  
          }  
        }}  
        return n;  
      }  
    }  
    void list_all_files(char const* path)  
    {  
      ff::fmtln(std::cout, "Searching '{0}'", path);  
      unsigned n = list_all_files_r(path);  
      if(~0u != n)  
      {  
        ff::fmtln(std::cout, "  {0} file(s) found",  
           n);  
      }  
    }
Listing 1

    unsigned list_all_files_r(char const* path)  
    {  
      STLSOFT_ASSERT(NULL != path);  
      STLSOFT_ASSERT('\0' != 0[path]);  
      std::string directory(path);  
      if(directory[directory.size() - 1u] != '\\')  
      {  
        directory += '\\';  
      }  
      std::string searchSpec = directory + "*.*";  
      WIN32_FIND_DATA data;  
      HANDLE  h = ::FindFirstFile(searchSpec.c_str(),  
         &data);  
      if(INVALID_HANDLE_VALUE == h)  
      {  
        DWORD err = ::GetLastError();  
        ff::fmtln(std::cerr, "failed to search '{0}'  
           : {1} ({2})", path,  
           winstl::error_desc(err), err);  
        return ~0u;  
      }  
      else  
      {  
        stlsoft::scoped_handle<HANDLE>  scoper(h,  
           ::FindClose, INVALID_HANDLE_VALUE);  
        unsigned n = 0u;  
        do  
        {  
          if(data.dwFileAttributes   
             & FILE_ATTRIBUTE_DIRECTORY)  
          {  
            if( data.cFileName[0] == '.' &&  
                data.cFileName[1] == '\0')  
            {  
              // '.'  
            }  
            else if(data.cFileName[0] == '.' &&  
                    data.cFileName[1] == '.' &&  
                    data.cFileName[2] == '\0')  
            {  
              // '..'  
            }  
            else  
            {  
              n += list_all_files_r((directory   
                 + data.cFileName).c_str());  
            }  
          }  
          else  
          {  
            ff::fmtln(std::cout, "    {0}{1}",  
               directory, data.cFileName);  
            ++n;  
          }  
        } while(::FindNextFile(h, &data));  
        return n;  
      }  
    }  
    void list_all_files(char const* path)  
    {  
      ff::fmtln(std::cout, "Searching '{0}'", path);  
      unsigned n = list_all_files_r(path);  
      if(~0u != n)  
      {  
        ff::fmtln(std::cout,  
           "  {0} file(s) found", n);  
      }  
    }  
Listing 2

    // Assumes introduction of recls namespace symbols  
    void list_all_files(char const* path)  
    {  
      ff::fmtln(std::cout, "Searching '{0}'", path);  
      hrecls_t    hSrch;  
      recls_rc_t  rc  = Recls_Search(path, NULL,  
         recls::FILES | recls::RECURSIVE, &hSrch);  
      if(RECLS_FAILED(rc))  
      {  
        ff::fmtln(std::cerr,  
           "failed to search '{0}': {1} ({2})",  
           path, rc, int(rc));  
      }  
      else  
      {  
        stlsoft::scoped_handle<hrecls_t> scoper(  
           hSrch, Recls_SearchClose);  
        unsigned  n = 0u;  
        entry_t   entry;  
        { for(RECLS_GetDetails(hSrch, &entry);  
           RECLS_SUCCEEDED(rc);  
           rc = Recls_GetNextDetails(hSrch, &entry),  
           ++n)  
        {  
          stlsoft::scoped_handle<entry_t> scoper2(  
             entry, Recls_CloseDetails);  
          ff::fmtln(std::cout, "    {0}",  
             entry->path);  
        }}  
        ff::fmtln(std::cout,  
           "  {0} file(s) found", n);  
      }  
    }  
Listing 3

    // Assumes introduction of recls namespace symbols  
    int RECLS_CALLCONV_DEFAULT onFile(  
        recls_entry_t               entry  
    ,   recls_process_fn_param_t    param  
    )  
    {  
      ff::fmtln(std::cout, "    {0}", entry->path);  
      ++*static_cast<unsigned*>(param);  
      return +1; // continue
    }  
    void list_all_files(char const* path)  
    {  
      ff::fmtln(std::cout, "Searching '{0}'", path);  
      unsigned    n   = 0u;  
      recls_rc_t  rc  = Recls_SearchProcess(path,  
         NULL, recls::FILES | recls::RECURSIVE,  
         onFile, &n);  
      if(RECLS_SUCCEEDED(rc))  
      {  
        ff::fmtln(std::cout,  
           "  {0} file(s) found", n);  
      }  
      else  
      {  
        ff::fmtln(std::cerr,  
           "failed to search '{0}': {1} ({2})", path,  
           rc, int(rc));  
      }  
    }
Listing 4

    void list_all_files(char const* path)  
    {  
      ff::fmtln(std::cout, "Searching '{0}'", path);  
      try  
      {  
        recls::search_sequence files(path,  
           recls::wildcardsAll(), recls::FILES |  
           recls::RECURSIVE);  
        unsigned n = 0;  
        { for(recls::search_sequence  
           ::const_iterator i = files.begin();   
           i != files.end(); ++i, ++n)  
        {  
          ff::fmtln(std::cout, "    {0}", *i);  
        }}  
        ff::fmtln(std::cout,  
           "  {0} file(s) found", n);  
      }  
      catch(recls::recls_exception& x)  
      {  
        ff::fmtln(std::cerr,  
           "failed to search '{0}': {1} ({2})",  
           path, x, int(x.get_rc()));  
      }  
    }
Listing 5

    typedef struct recls_entryinfo_t const* recls_entry_t;  
 
    struct recls_strptrs_t  
    {  
      recls_char_t const* begin;  
      recls_char_t const* end;  
    };  
    struct recls_strptrsptrs_t  
    {  
      struct recls_strptrs_t const* begin;  
      struct recls_strptrs_t const* end;  
    };  
 
    #if !defined(RECLS_PURE_API)  
    struct recls_entryinfo_t  
    {  
      recls_uint32_t              attributes;  
      struct recls_strptrs_t      path;  
    # if defined(RECLS_PLATFORM_IS_WINDOWS)  
      struct recls_strptrs_t      shortFile;  
      recls_char_t                drive;  
    # endif /* RECLS_PLATFORM_IS_WINDOWS */
      struct recls_strptrs_t      directory;  
      struct recls_strptrs_t      fileName;  
      struct recls_strptrs_t      fileExt;  
      struct recls_strptrsptrs_t  directoryParts;  
    # if defined(RECLS_PLATFORM_IS_WINDOWS)  
      recls_time_t                creationTime;  
    # endif /* RECLS_PLATFORM_IS_WINDOWS */
      recls_time_t                modificationTime;  
      recls_time_t                lastAccessTime;  
    # if defined(RECLS_PLATFORM_IS_UNIX)  
      recls_time_t               lastStatusChangeTime;  
    # endif /* RECLS_PLATFORM_IS_UNIX */
      recls_filesize_t            size;  
      struct recls_strptrs_t      searchDirectory;  
      struct recls_strptrs_t      searchRelativePath;  
      /* Remaining member are undocumented and subject  
         to change */    
      recls_uint64_t              checkSum;  
      recls_uint32_t              extendedFlags[2];  
      recls_byte_t                data[1];  
    };  
    #endif /* !RECLS_PURE_API */
Listing 6

    ReclsFileSearchDirectoryNode::  
       ReclsFileSearchDirectoryNode(  
      recls_uint32_t            flags  
    , recls_char_t const*       searchDir  
    , size_t                    rootDirLen  
    , recls_char_t const*       pattern  
    , size_t                    patternLen  
    , hrecls_progress_fn_t      pfn  
    , recls_process_fn_param_t  param  
    )  
      : m_current(NULL)  
      , m_dnode(NULL)  
      , m_flags(flags)  
      , m_rootDirLen(rootDirLen)  
      , m_searchDir()  
      , m_searchDirLen(prepare_searchDir_(  
        m_searchDir, searchDir))  
      , m_pattern(pattern)  
      , m_patternLen(patternLen)  
      , m_directories(  
          searchDir  
    #if defined(RECLS_PLATFORM_IS_WINDOWS)  
        , types::traits_type::pattern_all()  
    #endif /* platform */
        , dssFlags_from_reclsFlags_(flags))  
      , m_directoriesBegin(  
          select_iter_if_(  
            flags & RECLS_F_RECURSIVE  
          , m_directories.begin()  
          , m_directories.end()))  
      , m_entries(  
          searchDir  
        , pattern  
    #ifdef RECLS_SUPPORTS_MULTIPATTERN_  
        , types::traits_type::path_separator()  
    #endif /* RECLS_SUPPORTS_MULTIPATTERN_ */
        , essFlags_from_reclsFlags_(flags))  
      , m_entriesBegin(m_entries.begin())  
      , m_pfn(pfn)  
      , m_param(param)  
    {  
      . . .  
    }
Listing 7

    void list_all_files(char const* path)  
    {  
      ff::fmtln(std::cout, "Searching '{0}'", path);  
 
      try  
      {  
        recls::cpp::FileSearch search(path,  
           recls::Recls_GetWildcardsAll(),  
           recls::FILES | recls::RECURSIVE);  
 
        unsigned n = 0;  
        for(; search.HasMoreElements();  
           search.GetNext(), ++n)  
        {  
          recls::cpp::FileEntry entry   
             = search.GetCurrentEntry();  
          ff::fmtln(std::cout, "    {0}", entry);  
        }  
        ff::fmtln(std::cout,  
           "  {0} file(s) found", n);  
      }  
 
      catch(recls::cpp::ReclsException& x)  
      {  
        ff::fmtln(std::cerr,  
           "failed to search '{0}': {1} ({2})",  
           path, x, int(x.rc()));  
      }  
    }
Listing 8

    search_sequence::const_iterator  
    search_sequence::begin() const  
    {  
      hrecls_t    hSrch;  
      recls_rc_t  rc = Recls_Search(m_directory,  
         m_pattern, m_flags, &hSrch);  
 
      if( RECLS_FAILED(rc) &&  
          RECLS_RC_NO_MORE_DATA != rc)  
      {  
        throw recls_exception(rc);  
      }  
      return const_iterator(hSrch);  
    }  
 
    ftp_search_sequence::const_iterator  
    ftp_search_sequence::begin() const  
    {  
      hrecls_t    hSrch;  
      recls_rc_t    
         rc = Recls_SearchFtp(m_host.c_str(),  
         m_username.c_str(), m_password.c_str(),  
         m_directory, m_pattern, m_flags, &hSrch);  
      if( RECLS_FAILED(rc) &&  
          RECLS_RC_NO_MORE_DATA != rc)  
      {  
        throw recls_exception(rc);  
      }  
 
      return const_iterator(hSrch);  
    }

    template <typename C, typename T, typename V>  
    basic_search_sequence_const_iterator<C, T, V>&  
    basic_search_sequence_const_iterator<C, T, V>::operator ++()  
    {  
      RECLS_MESSAGE_ASSERT(  
         "Attempting to increment invalid iterator",  
         NULL != m_handle);  
      if(RECLS_FAILED(Recls_GetNext(  
         m_handle->hSrch)))  
      {  
        m_handle->Release();  
        m_handle = NULL;  
      }  
      return *this;  
    }  
    class entry  
    {  
      . . .  
    public: /// Attribute Methods
      char_type const* c_str() const  
      {  
        STLSOFT_ASSERT(NULL != m_entry);  
        return m_entry->path.begin;  
      }  
      . . .  
      recls_time_t get_creation_time() const  
      {  
        STLSOFT_ASSERT(NULL != m_entry);  
        return Recls_GetCreationTime(m_entry);  
      }  
      . . .  
      string_type get_path() const  
      {  
        STLSOFT_ASSERT(NULL != m_entry);  
        return string_type(m_entry->path.begin,  
           m_entry->path.end);  
      }  
      string_type get_drive() const  
      {  
        STLSOFT_ASSERT(NULL != m_entry);  
        return string_type(m_entry->path.begin,  
           m_entry->directory.begin);  
      }  
      string_type get_directory_path() const  
      {  
        STLSOFT_ASSERT(NULL != m_entry);  
        return string_type(m_entry->path.begin,  
           m_entry->directory.end);  
      }  
      string_type get_directory() const  
      {  
        STLSOFT_ASSERT(NULL != m_entry);  
        return string_type(m_entry->directory.begin,  
           m_entry->directory.end);  
      }  
      string_type get_file() const  
      {  
        STLSOFT_ASSERT(NULL != m_entry);  
        return string_type(m_entry->fileName.begin,  
           m_entry->fileExt.end);  
      }  
      string_type get_file_name() const  
      {  
        STLSOFT_ASSERT(NULL != m_entry);  
        return string_type(m_entry->fileName.begin,  
           m_entry->fileName.end);  
      }

      string_type get_file_extension() const  
      {  
        STLSOFT_ASSERT(NULL != m_entry);  
        if(m_entry->fileExt.begin   
           == m_entry->fileExt.end)  
        {  
          return string_type();  
        }  
        else  
        {  
          return string_type(  
             m_entry->fileExt.begin - 1,  
             m_entry->fileExt.end);  
        }  
      }  
      . . .  
    private: /// Member Variables
      recls_entry_t m_entry;  
    };
Listing 9

    /* test.unit.api.combine_paths.c */  
    static void test_1(void);  
    static void test_2(void);  
    static void test_3(void);  
    static void test_4(void);  
    int main(int argc, char **argv)  
    {  
      int retCode = EXIT_SUCCESS;  
      int verbosity = 2;  
      XTESTS_COMMANDLINE_PARSEVERBOSITY(argc,  
         argv, &verbosity);  
      if(XTESTS_START_RUNNER(  
         "test.unit.api.combine_paths", verbosity))  
      {  
        XTESTS_RUN_CASE(test_1);  
        XTESTS_RUN_CASE(test_2);  
        XTESTS_RUN_CASE(test_3);  
        XTESTS_RUN_CASE(test_4);  
    #ifdef XCOVER_VER  
        XCOVER_REPORT_GROUP_COVERAGE(  
           "recls.core.extended.combine_paths", NULL);  
    #endif /* XCOVER_VER */  
        XTESTS_PRINT_RESULTS();  
        XTESTS_END_RUNNER_UPDATE_EXITCODE(  
           &retCode);  
      }  
      return retCode;  
    }  
    . . .  
    static void test_4()  
    {  
      char    result[101];  
      size_t  cch = Recls_CombinePaths("abc", "def",  
         &result[0], STLSOFT_NUM_ELEMENTS(result));  
      result[cch] = '\0';  
      XTESTS_TEST_INTEGER_EQUAL(7u, cch);  
    #if defined(RECLS_PLATFORM_IS_UNIX)  
      XTESTS_TEST_MULTIBYTE_STRING_EQUAL("abc/def",  
         result);  
    #elif defined(RECLS_PLATFORM_IS_WINDOWS)  
      XTESTS_TEST_MULTIBYTE_STRING_EQUAL("abc\\def",  
         result);  
    #endif  
    }
Listing 10

Overload Journal #95 - February 2010 + Programming Topics + Design of applications and programs