|
Version 1.4.1 contains nine test programs.
test/C
directory is a test program C.c that exercises the recls C API (for Win32)test/Cpp
directory is a test program Cpp.cpp that exercises the recls C++ mapping (for Win32)test/STL
directory is a test program STL.cpp that exercises the recls STL mapping (for Win32)test/CS
directory is a test program WinForm.cs that exercises the recls C# mappingtest/COM
directory is a test program COM.cpp that exercises the recls COM mapping (for C++)test/COM/VBClient
directory is a test program VBClient.frm that exercises the recls COM mapping (for Visual Basic)test/D
directory are two test programs recls_test_1.d and recls_test_2.d that exercise the recls D mappingtest/Java
directory is a test program recls_test.java that exercises the recls Java mappingThis program uses the raw recls C API functions, implementing a recursive search for a given pattern, from a given directory
/* * File: C.c * * Purpose: Implementation file for the C project. * * Created: 15th August 2003 * Updated: 12th April 2004 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright (C) 1999-2004, Synesis Software Pty Ltd. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2003 * by Synesis Software Pty Ltd. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Synesis Software Pty Ltd "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Synesis Software Pty Ltd be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Synesis Software Pty Ltd nor the names of * any subdivisions, employees or agents of Synesis Software Pty * Ltd, nor the names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * */ /* Remove this definition to use platform-specific aspects of the API */ #define RECLS_PURE_API #include <stdio.h> #include <stdlib.h> #include <string.h> #include <recls.h> #if RECLS_VER < RECLS_VER_1_1_1 # error This file now requires version 1.1.1 or later of the recls C API #endif /* RECLS_VER < 1.1.1 */ #include <recls_assert.h> #ifdef _MSC_VER # include <crtdbg.h> #endif /* _MSC_VER */ /* * Macros */ #ifndef NUM_ELEMENTS # ifdef __DMC__ # define NUM_ELEMENTS(x) (sizeof(x) / sizeof((x)[0])) # else /* ? compiler */ # define NUM_ELEMENTS(x) (sizeof(x) / sizeof(0[(x)])) # endif /* compiler */ #endif /* !NUM_ELEMENTS */ /* * Forward declarations */ void usage(int bExit); int processDirectory(char const *rootDir, char const *pattern, long flags, int bSuccinct); /* * Main */ int main(int argc, char *argv[]) { #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemState memState; #endif /* _MSC_VER && _MSC_VER */ int iRet = 0; int i; int totalFound = 0; int bAllHardDrives = 0; char const *pattern = NULL; char const *rootDir = NULL; recls_uint32_t flags = RECLS_F_RECURSIVE; int bSuccinct = 0; for(i = 1; i < argc; ++i) { const char *arg = argv[i]; if(arg[0] == '-') { if(arg[1] == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg[1]) { case 'R': /* Do not recurse */ flags &= ~(RECLS_F_RECURSIVE); break; case 'p': /* Show directory parts */ flags |= RECLS_F_DIRECTORY_PARTS; break; case 'f': /* Find files */ flags |= RECLS_F_FILES; break; case 'd': /* Find directories */ flags |= RECLS_F_DIRECTORIES; break; case 'h': /* Searches from hard drives */ bAllHardDrives = 1; break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = 1; break; default: usage(1); break; } } } else { /* other arguments */ if(NULL == pattern) { pattern = arg; } else if(NULL == rootDir) { rootDir = arg; } else { usage(1); } } } #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemCheckpoint(&memState); #endif /* _MSC_VER && _MSC_VER */ /* Search for files if neither files or directories specified/ * * Even though this is not necessary, because the recls API provides the * same interpretation, it's best to be explicit. */ if(0 == (flags & (RECLS_F_FILES | RECLS_F_DIRECTORIES))) { flags |= RECLS_F_FILES; } if(NULL == pattern) { pattern = Recls_GetWildcardsAll(); } if(NULL == rootDir) { rootDir = "."; } /* Initiate the search. */ if(bAllHardDrives) { recls_root_t roots[26]; size_t cRoots = Recls_GetRoots(roots, NUM_ELEMENTS(roots)); size_t i; for(i = 0; i < cRoots; ++i) { totalFound += processDirectory(roots[i].name, pattern, flags, bSuccinct); } } else { totalFound = processDirectory(rootDir, pattern, flags, bSuccinct); } fprintf(stdout, "Total found: %d\n", totalFound); #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemDumpAllObjectsSince(&memState); #endif /* _MSC_VER && _MSC_VER */ return iRet; } /* * Function implementations */ void usage(int bExit) { fprintf(stderr, "recls C Test Program\n\n"); fprintf(stderr, "Usage: C++ [-d] [-f] [-h] [-p] [-R] [-s] [<pattern>] [<root-dir>]\n"); fprintf(stderr, "\t-R - does not recurse; recursive search is the default\n"); fprintf(stderr, "\t-p - evaluate and display directory parts\n"); fprintf(stderr, "\t-d - search for directories\n"); fprintf(stderr, "\t-f - search for files (this is the default, if -d is not specified)\n"); fprintf(stderr, "\t-h - searches from hard drive roots. (Ignore <root-dir>.)\n"); fprintf(stderr, "\t-s - succinct; shows only the path\n"); fprintf(stderr, "\t<pattern> - search pattern, e.g. \"*.cpp\" (default is to search for all files)\n"); fprintf(stderr, "\t<root-dir> - root directory of search; default is current working directory\n"); if(bExit) { exit(1); } } int processDirectory(char const *rootDir, char const *pattern, long flags, int bSuccinct) { hrecls_t hSrch; recls_rc_t rc = Recls_Search(rootDir, pattern, flags, &hSrch); int totalFound = 0; if(RECLS_FAILED(rc)) { recls_char_t err[100]; Recls_GetErrorString(rc, err, 100); fprintf(stderr, "Failed to start search, with pattern \"%s\"; recls error: %s\n", pattern, err); } else { /* Iterate through the items, until done */ recls_info_t info; rc = Recls_GetDetails(hSrch, &info); for(; RECLS_SUCCEEDED(rc); rc = Recls_GetNextDetails(hSrch, &info)) { int i; int off; int extLen; int cDirParts; recls_char_t path[RECLS_PATH_MAX]; #ifdef RECLS_PLATFORM_API_WIN32 recls_char_t drive; #endif /* RECLS_PLATFORM_API_WIN32 */ recls_char_t dir[RECLS_PATH_MAX]; recls_char_t dirPath[RECLS_PATH_MAX]; recls_char_t file[RECLS_PATH_MAX]; recls_char_t fileName[RECLS_PATH_MAX]; recls_char_t fileExt[RECLS_PATH_MAX]; recls_char_t pathCheck[RECLS_PATH_MAX]; recls_char_t dirCheck[RECLS_PATH_MAX]; recls_char_t fileCheck[RECLS_PATH_MAX]; ++totalFound; pathCheck[0] = '\0'; dirCheck[0] = '\0'; fileCheck[0] = '\0'; #ifdef _DEBUG { recls_uint32_t cBlocks; Recls_OutstandingDetails(hSrch, &cBlocks); printf("\n%d outstanding blocks\n", cBlocks); } #endif /* _DEBUG */ Recls_GetPathProperty(info, path, NUM_ELEMENTS(path)); printf(" %s\n", path); if(!bSuccinct) { Recls_GetDirectoryPathProperty(info, dirPath, NUM_ELEMENTS(dirPath)); printf(" %s\n", dirPath); #ifdef RECLS_PLATFORM_API_WIN32 Recls_GetDriveProperty(info, &drive); if(isupper(path[0])) { drive = (recls_char_t)toupper(drive); } else { drive = (recls_char_t)tolower(drive); } printf(" %c\n", drive); sprintf(pathCheck, "%c:", drive); #endif /* RECLS_PLATFORM_API_WIN32 */ Recls_GetDirectoryProperty(info, dir, NUM_ELEMENTS(dir)); printf(" %s\n", dir); off = 0; if((flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS) { for(i = 0, cDirParts = Recls_GetDirectoryPartProperty(info, -1, NULL, 0); i < cDirParts; ++i) { recls_char_t dirPart[RECLS_PATH_MAX]; off += Recls_GetDirectoryPartProperty(info, i, dirPart, NUM_ELEMENTS(dirPart)); printf(" %*s\n", off, dirPart); strcat(pathCheck, dirPart); strcat(dirCheck, dirPart); } } else { off += strlen(dir); strcat(pathCheck, dir); } off += Recls_GetFileProperty(info, file, NUM_ELEMENTS(file)); Recls_GetFileNameProperty(info, fileName, NUM_ELEMENTS(fileName)); extLen = Recls_GetFileExtProperty(info, fileExt, NUM_ELEMENTS(fileExt)); printf(" %*s\n", off, file); printf(" %*s\n", off - (1 + extLen), fileName); printf(" %*s\n", off, fileExt); strcpy(fileCheck, fileName); if(0 < extLen) { strcat(fileCheck, "."); strcat(fileCheck, fileExt); } strcat(pathCheck, file); /* Now validate the components */ #if defined(RECLS_PLATFORM_IS_WIN32) && \ !defined(RECLS_PLATFORM_API_WIN32) recls_assert(0 == strcmp(path + 2, pathCheck)); if(0 != strcmp(path + 2, pathCheck)) #else /* ? RECLS_PLATFORM_API_WIN32 */ recls_assert(0 == strcmp(path, pathCheck)); if(0 != strcmp(path, pathCheck)) #endif /* RECLS_PLATFORM_API_WIN32 || !RECLS_PLATFORM_IS_WIN32 */ { fprintf(stderr, "Path is different from path components\n\tpath: %s\n\tparts: %s\n\n", path, pathCheck); abort(); } #if defined(RECLS_PLATFORM_API_WIN32) recls_assert(dirPath[0] == drive && 0 == strcmp(dir, dirPath + 2)); if( dirPath[0] != drive || 0 != strcmp(dir, dirPath + 2)) #elif defined(RECLS_PLATFORM_IS_WIN32) recls_assert(0 == strcmp(dir, dirPath + 2)); if(0 != strcmp(dir, dirPath + 2)) #else recls_assert(dirPath == dir); if(dirPath != dir) #endif /* RECLS_PLATFORM_API_WIN32 || !RECLS_PLATFORM_IS_WIN32 */ { fprintf(stderr, "DirectoryPath is different from Directory\n\tdirPath: %s\n\tdir: %s\n\n", dirPath, dir); abort(); } if((flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS) { recls_assert(0 == strcmp(dir, dirCheck)); if(0 != strcmp(dir, dirCheck)) { fprintf(stderr, "Directory is different from directory components\n\tpath: %s\n\tparts: %s\n\n", dir, dirCheck); abort(); } } recls_assert(0 == strcmp(file, fileCheck)); if(0 != strcmp(file, fileCheck)) { fprintf(stderr, "File is different from file components\n\tpath: %s\n\tparts: %s\n\n", file, fileCheck); abort(); } if(Recls_IsFileReadOnly(info)) { printf(" - Read-only\n"); } if(Recls_IsFileDirectory(info)) { printf(" - Directory\n"); } else { printf(" - File\n"); } if(Recls_IsFileLink(info)) { printf(" - Link\n"); } } Recls_CloseDetails(info); } if(rc != RECLS_RC_NO_MORE_DATA) { recls_char_t err[100]; Recls_GetErrorString(rc, err, 100); fprintf(stderr, "Search terminated prematurely; recls error: %s\n", err); } Recls_SearchClose(hSrch); } return totalFound; } /* * End of file */
This program uses the recls C++ mapping classes, implementing a recursive search for a given pattern, from a given directory (Win32 platform)
/* * File: Cpp.cpp * * Purpose: Implementation file for the Cpp project. * * Created: 16th August 2003 * Updated: 12th April 2004 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright (C) 1999-2004, Synesis Software Pty Ltd. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2003 * by Synesis Software Pty Ltd. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Synesis Software Pty Ltd "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Synesis Software Pty Ltd be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Synesis Software Pty Ltd nor the names of * any subdivisions, employees or agents of Synesis Software Pty * Ltd, nor the names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * */ /* Define this definition to retrict use to platform-independent aspects of the API */ //#define RECLS_PURE_API // Define this to copy file entries into a vector, to exercise the copy semantics //#define TAKE_COPIES_IN_VECTOR #include <stdio.h> #include <recls.h> #if RECLS_VER < RECLS_VER_1_1_1 # error This file now requires version 1.1.1 or later of the recls C API #endif /* RECLS_VER < 1.1.1 */ #if defined(RECLS_STRICT) && \ !defined(RECLS_COMPILER_IS_DMC) # include <stlsoft_nulldef.h> #endif /* RECLS_STRICT && !RECLS_COMPILER_IS_DMC */ #ifdef _MSC_VER # include <crtdbg.h> # pragma warning(disable : 4530) #endif /* _MSC_VER */ #include <recls_assert.h> #include <reclspp.h> #include <reclspp_filesearch.h> #ifdef TAKE_COPIES_IN_VECTOR # include <vector> # if defined(RECLS_COMPILER_IS_DMC) typedef vector<reclspp::FileEntry> fileentries_t; # else typedef std::vector<reclspp::FileEntry> fileentries_t; # endif /* RECLS_COMPILER_IS_DMC */ #endif /* TAKE_COPIES_IN_VECTOR */ /* * Namespace */ using recls::recls_uint32_t; using recls::recls_char_t; using recls::RECLS_F_FILES; using recls::RECLS_F_DIRECTORIES; using recls::RECLS_F_RECURSIVE; using recls::RECLS_F_DIRECTORY_PARTS; /* * Forward declarations */ void usage(int bExit); /* * Main */ int main(int argc, char *argv[]) { int iRet = 0; int i; int totalFound = 0; char const *pattern = NULL; char const *rootDir = NULL; recls_uint32_t flags = RECLS_F_RECURSIVE; int bSuccinct = false; for(i = 1; i < argc; ++i) { const char *arg = argv[i]; if(arg[0] == '-') { if(arg[1] == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg[1]) { case 'R': /* Do not recurse */ flags &= ~(RECLS_F_RECURSIVE); break; case 'p': /* Show directory parts */ flags |= RECLS_F_DIRECTORY_PARTS; break; case 'f': /* Find files */ flags |= RECLS_F_FILES; break; case 'd': /* Find directories */ flags |= RECLS_F_DIRECTORIES; break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = true; break; default: usage(1); break; } } } else { /* other arguments */ if(NULL == pattern) { pattern = arg; } else if(NULL == rootDir) { rootDir = arg; } else { usage(1); } } } #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemState memState; _CrtMemCheckpoint(&memState); #endif /* _MSC_VER && _MSC_VER */ // Search for files if neither files or directories specified // // Even though this is not necessary, because the recls API provides the // same interpretation, it's best to be explicit. if(0 == (flags & (RECLS_F_FILES | RECLS_F_DIRECTORIES))) { flags |= RECLS_F_FILES; } if(NULL == pattern) { pattern = recls::Recls_GetWildcardsAll(); } if(NULL == rootDir) { rootDir = "."; } { // Enter scope here, so vector (if used) will be cleared before mem-leak test reclspp::FileSearch search(rootDir, pattern, flags); #ifdef TAKE_COPIES_IN_VECTOR fileentries_t entries; #endif /* TAKE_COPIES_IN_VECTOR */ for(; search.HasMoreElements(); search.GetNext()) { using reclspp::string_t; ++totalFound; reclspp::FileEntry fileEntry = search.GetCurrentEntry(); #ifdef RECLS_PLATFORM_API_WIN32 recls_char_t drive = fileEntry.GetDrive(); #endif /* RECLS_PLATFORM_API_WIN32 */ string_t path = fileEntry.GetPath(); string_t dir = fileEntry.GetDirectory(); string_t dirPath = fileEntry.GetDirectoryPath(); reclspp::DirectoryParts dirParts = fileEntry.GetDirectoryParts(); string_t file = fileEntry.GetFile(); string_t fileName = fileEntry.GetFileName(); string_t fileExt = fileEntry.GetFileExt(); string_t pathCheck; string_t dirPartsCheck; string_t fileCheck; #ifdef TAKE_COPIES_IN_VECTOR entries.push_back(fileEntry); #endif /* TAKE_COPIES_IN_VECTOR */ #ifdef _DEBUG reclspp::FileEntry entry2; if( fileEntry && !entry2) { fprintf(stderr, "Good entry\n"); } if(!fileEntry) { fprintf(stderr, "Bad entry\n"); } #endif /* _DEBUG */ #ifdef _DEBUG { recls_uint32_t cBlocks = search.GetNumOutstandingDetails(); printf("\n%d outstanding block(s)\n", cBlocks); } #endif /* _DEBUG */ printf(" %s\n", path.c_str()); if(!bSuccinct) { printf(" %s\n", dirPath.c_str()); #ifdef RECLS_PLATFORM_API_WIN32 if(isupper(path[0])) { drive = (recls_char_t)toupper(drive); } else { drive = (recls_char_t)tolower(drive); } printf(" %c\n", drive); pathCheck += drive; pathCheck += ':'; #endif /* RECLS_PLATFORM_API_WIN32 */ printf(" %s\n", dir.c_str()); int off = 0; if((flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS) { int i; int cDirParts; for(i = 0, cDirParts = dirParts.size(); i < cDirParts; ++i) { string_t dirPart = dirParts[i]; off += dirPart.length(); printf(" %*s\n", off, dirPart.c_str()); pathCheck += dirPart; dirPartsCheck += dirPart; } } else { off += dir.length(); pathCheck += dir; } off += file.length(); printf(" %*s\n", off, file.c_str()); if(fileExt.length() > 0) { printf(" %*s\n", off - (1 + fileExt.length()), fileName.c_str()); printf(" %*s\n", off, fileExt.c_str()); } else { printf(" %*s\n", off, fileName.c_str()); } fileCheck = fileName; if(0 < fileExt.length()) { fileCheck += '.'; fileCheck += fileExt; } pathCheck += file; // Now validate the components #ifdef RECLS_PLATFORM_API_WIN32 recls_assert(path == pathCheck); if(path != pathCheck) #else /* ? RECLS_PLATFORM_API_WIN32 */ recls_assert(0 == strcmp(path.c_str() + 2, pathCheck.c_str())); if(0 != strcmp(path.c_str() + 2, pathCheck.c_str())) #endif /* RECLS_PLATFORM_API_WIN32 */ { fprintf(stderr, "Path is different from path components\n\tpath: %s\n\tparts: %s\n\n", path.c_str(), pathCheck.c_str()); abort(); } #ifdef RECLS_PLATFORM_API_WIN32 recls_assert(dirPath[0] == drive && dir == dirPath.c_str() + 2); if( dirPath[0] != drive || dir != dirPath.c_str() + 2) #else recls_assert(dirPath == dir); if(dirPath != dir) #endif /* RECLS_PLATFORM_API_WIN32 */ { fprintf(stderr, "DirectoryPath is different from Directory\n\tdirPath: %s\n\tdir: %s\n\n", dirPath.c_str(), dir.c_str()); abort(); } if((flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS) { recls_assert(dir == dirPartsCheck); if(dir != dirPartsCheck) { fprintf(stderr, "Directory is different from directory components\n\tpath: %s\n\tparts: %s\n\n", dir.c_str(), dirPartsCheck.c_str()); abort(); } } recls_assert(file == fileCheck); if(file != fileCheck) { fprintf(stderr, "File is different from file components\n\tpath: %s\n\tparts: %s\n\n", file.c_str(), fileCheck.c_str()); abort(); } if(fileEntry.IsReadOnly()) { printf(" - Read-only\n"); } if(fileEntry.IsDirectory()) { printf(" - Directory\n"); } else { printf(" - File\n"); } if(fileEntry.IsLink()) { printf(" - Link\n"); } } } fprintf(stdout, "Total found: %d\n", totalFound); } #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemDumpAllObjectsSince(&memState); #endif /* _MSC_VER && _MSC_VER */ return iRet; } /* * Function implementations */ void usage(int bExit) { fprintf(stderr, "recls C++ Test Program\n\n"); fprintf(stderr, "Usage: Cpp [-d] [-f] [-h] [-p] [-R] [-s] [<pattern>] [<root-dir>]\n"); fprintf(stderr, "\t-R - does not recurse; recursive search is the default\n"); fprintf(stderr, "\t-p - evaluate and display directory parts\n"); fprintf(stderr, "\t-d - search for directories\n"); fprintf(stderr, "\t-f - search for files (this is the default, if -d is not specified)\n"); fprintf(stderr, "\t-h - searches from hard drive roots. (Ignore <root-dir>.)\n"); fprintf(stderr, "\t-s - succinct; shows only the path\n"); fprintf(stderr, "\t<pattern> - search pattern, e.g. \"*.cpp\"; default is to search for all files\n"); fprintf(stderr, "\t<root-dir> - root directory of search; default is current working directory\n"); if(bExit) { exit(1); } } /* * End of file */
This program uses the recls STL mapping classes, implementing a recursive search for a given pattern, from a given directory
/* * File: STL.cpp * * Purpose: Implementation file for the STL project. * * Created: 16th August 2003 * Updated: 25th March 2004 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright (C) 1999-2004, Synesis Software Pty Ltd. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2003 * by Synesis Software Pty Ltd. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Synesis Software Pty Ltd "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Synesis Software Pty Ltd be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Synesis Software Pty Ltd nor the names of * any subdivisions, employees or agents of Synesis Software Pty * Ltd, nor the names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * * // Define this definition to retrict use to platform-independent aspects of the API //#define RECLS_PURE_API // Define this to copy file entries into a vector, to exercise the copy semantics //#define TAKE_COPIES_IN_VECTOR #include <recls.h> #if RECLS_VER < RECLS_VER_1_1_1 # error This file now requires version 1.1.1 or later of the recls C API #endif /* RECLS_VER < 1.1.1 */ #ifdef RECLS_STRICT # include <stlsoft_nulldef.h> #endif // RECLS_STRICT #ifdef _MSC_VER # include <crtdbg.h> # pragma warning(disable : 4530) #endif /* _MSC_VER */ #include <reclstl.h> #include <reclstl_root_sequence.h> #include <reclstl_search_sequence.h> #if !defined(RECLS_COMPILER_IS_DMC) # include <iostream> # include <iomanip> #else /* ? compiler */ # include <iostream.h> # include <iomanip.h> #endif /* compiler */ #ifdef TAKE_COPIES_IN_VECTOR # include <vector> typedef std::vector<reclstl::search_sequence_a::value_type> fileentry_t; #endif /* TAKE_COPIES_IN_VECTOR */ /* * Namespace */ #if !defined(RECLS_COMPILER_IS_DMC) using std::cout; using std::cerr; using std::endl; using std::setw; #endif /* compiler */ using recls::uint32_t; using recls::recls_info_t; using recls::recls_char_t; using recls::RECLS_F_FILES; using recls::RECLS_F_DIRECTORIES; using recls::RECLS_F_RECURSIVE; using recls::RECLS_F_DIRECTORY_PARTS; /* * Forward declarations */ void usage(int bExit); int processDirectory(char const *rootDir, char const *pattern, long flags, int bSuccinct); /* * Main */ int main(int argc, char *argv[]) { int iRet = 0; int i; int totalFound = 0; char const *pattern = NULL; char const *rootDir = NULL; uint32_t flags = RECLS_F_RECURSIVE; int bSuccinct = false; int bAllHardDrives = false; for(i = 1; i < argc; ++i) { const char *arg = argv[i]; if(arg[0] == '-') { if(arg[1] == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg[1]) { case 'R': /* Do not recurse */ flags &= ~(RECLS_F_RECURSIVE); break; case 'p': /* Show directory parts */ flags |= RECLS_F_DIRECTORY_PARTS; break; case 'f': /* Find files */ flags |= RECLS_F_FILES; break; case 'd': /* Find directories */ flags |= RECLS_F_DIRECTORIES; break; case 'h': /* Searches from hard drives */ bAllHardDrives = 1; break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = true; break; default: usage(1); break; } } } else { /* other arguments */ if(NULL == pattern) { pattern = arg; } else if(NULL == rootDir) { rootDir = arg; } else { usage(1); } } } #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemState memState; _CrtMemCheckpoint(&memState); #endif /* _MSC_VER && _MSC_VER */ // Search for files if neither files or directories specified // // Even though this is not necessary, because the recls API provides the // same interpretation, it's best to be explicit. if(0 == (flags & (RECLS_F_FILES | RECLS_F_DIRECTORIES))) { flags |= RECLS_F_FILES; } if(NULL == pattern) { pattern = recls::Recls_GetWildcardsAll(); } if(NULL == rootDir) { rootDir = "."; } if(bAllHardDrives) { reclstl::basic_root_sequence<recls_char_t> roots; reclstl::basic_root_sequence<recls_char_t>::const_iterator begin = roots.begin(); reclstl::basic_root_sequence<recls_char_t>::const_iterator end = roots.end(); for(; begin != end; ++begin) { totalFound += processDirectory(*begin, pattern, flags, bSuccinct); } } else { totalFound = processDirectory(rootDir, pattern, flags, bSuccinct); } fprintf(stdout, "Total found: %d\n", totalFound); #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemDumpAllObjectsSince(&memState); #endif /* _MSC_VER && _MSC_VER */ return iRet; } /* * Function implementations */ void usage(int bExit) { cout << "recls STL Test Program:" << endl << endl; cout << "Usage: STL [-d] [-f] [-h] [-p] [-R] [-s] [<pattern>] [<root-dir>]" << endl; cout << "\t-R - does not recurse; recursive search is the default" << endl; cout << "\t-p - evaluate and display directory parts" << endl; cout << "\t-d - search for directories" << endl; cout << "\t-f - search for files (this is the default, if -d is not specified" << endl; cout << "\t-h - searches from hard drive roots. (Ignore <root-dir>.)" << endl; cout << "\t-s - succinct; shows only the path" << endl; cout << "\t<pattern> - search pattern, e.g. \"*.cpp\"; default is to search for all files" << endl; cout << "\t<root-dir> - root directory of search; default is current working directory" << endl; if(bExit) { exit(1); } } int processDirectory(char const *rootDir, char const *pattern, long flags, int bSuccinct) { typedef reclstl::basic_search_sequence<recls_char_t> sequence_t; int totalFound = 0; sequence_t search(rootDir, pattern, flags); #ifdef TAKE_COPIES_IN_VECTOR fileentry_t entries; #endif /* TAKE_COPIES_IN_VECTOR */ sequence_t::const_iterator begin = search.begin(); sequence_t::const_iterator end = search.end(); for(; begin != end; ++begin) { using reclstl::string_t; ++totalFound; sequence_t::value_type fileEntry = *begin; #ifdef RECLS_PLATFORM_API_WIN32 recls_char_t drive = fileEntry.get_drive(); #endif /* RECLS_PLATFORM_API_WIN32 */ string_t path = fileEntry.get_path(); string_t dir = fileEntry.get_directory(); string_t dirPath = fileEntry.get_directory_path(); string_t file = fileEntry.get_file(); string_t fileName = fileEntry.get_filename(); string_t fileExt = fileEntry.get_fileext(); string_t pathCheck; string_t dirCheck; string_t fileCheck; #ifdef TAKE_COPIES_IN_VECTOR entries.push_back(fileEntry); #endif /* TAKE_COPIES_IN_VECTOR */ cout << " " << path << endl; if(!bSuccinct) { cout << " " << dirPath << endl; #ifdef RECLS_PLATFORM_API_WIN32 if(isupper(path[0])) { drive = (recls_char_t)toupper(drive); } else { drive = (recls_char_t)tolower(drive); } cout << " " << drive << endl; pathCheck += drive; pathCheck += ':'; #endif /* RECLS_PLATFORM_API_WIN32 */ cout << " " << dir << endl; typedef sequence_t::value_type::directory_parts_type directory_parts_type; int off = 0; if((flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS) { directory_parts_type dirParts = fileEntry.get_directory_parts(); int i; directory_parts_type::iterator begin = dirParts.begin(); directory_parts_type::iterator end = dirParts.end(); for(i = 0; begin != end; ++begin, ++i) { string_t dirPart = *begin; off += dirPart.length(); cout << " " << setw(off) << dirPart << setw(1) << endl; pathCheck += dirPart; dirCheck += dirPart; } } else { off += dir.length(); pathCheck += dir; } off += file.length(); cout << " " << setw(off) << file << setw(1) << endl; if(fileExt.length() > 0) { cout << " " << setw(off - (1 + fileExt.length())) << fileName << setw(1) << endl; cout << " " << setw(off) << fileExt << setw(1) << endl; } else { cout << " " << setw(off) << fileName << setw(1) << endl; } fileCheck = fileName; if(0 < fileExt.length()) { fileCheck += '.'; fileCheck += fileExt; } pathCheck += file; // Now validate the components recls_assert(path == pathCheck); if(path != pathCheck) { cerr << "Path is different from path components" << endl << "\tpath: " << path << "" << endl << "\tparts: " << pathCheck << endl << endl; abort(); } #ifdef RECLS_PLATFORM_API_WIN32 recls_assert(dirPath[0] == drive && dir == dirPath.c_str() + 2); if( dirPath[0] != drive || dir != dirPath.c_str() + 2) #else recls_assert(dirPath == dir); if(dirPath != dir) #endif /* RECLS_PLATFORM_API_WIN32 */ { cerr << "DirectoryPath is different from Directory" << endl << "\tdirPath: " << "%s" << "" << endl << "\tdir: " << "%s" << endl << endl; abort(); } if((flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS) { recls_assert(dir == dirCheck); if(dir != dirCheck) { cerr << "Directory is different from directory components" << endl << "\tpath: " << dir << "" << endl << "\tparts: " << dirCheck << endl << endl; abort(); } } recls_assert(file == fileCheck); if(file != fileCheck) { cerr << "File is different from file components" << endl << "\tpath: " << "%s" << "" << endl << "\tparts: " << "%s" << endl << endl; abort(); } if(fileEntry.is_readonly()) { cout << " - Read-only" << endl; } if(fileEntry.is_directory()) { cout << " - Directory" << endl; } else { cout << " - File" << endl; } if(fileEntry.is_link()) { cout << " - Link" << endl; } } } #ifdef TAKE_COPIES_IN_VECTOR entries.clear(); #endif /* TAKE_COPIES_IN_VECTOR */ return totalFound; } /* * End of file */
This program uses the recls C# mapping classes, implementing a recursive search for a given pattern, and other flags, from a given directory
namespace CS { using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using recls; public class WinForm : System.Windows.Forms.Form { private System.ComponentModel.Container components = null; private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox searchRoot; private System.Windows.Forms.Label label2; private System.Windows.Forms.TextBox pattern; private System.Windows.Forms.Button btnSearch; private System.Windows.Forms.ListView listFiles; private System.Windows.Forms.ListView listProperties; private System.Windows.Forms.Label label4; private System.Windows.Forms.ListBox listDirectoryParts; private System.Windows.Forms.CheckBox chkRecursive; private System.Windows.Forms.CheckBox chkDirectoryParts; private System.Windows.Forms.Label lblDirectoryParts; private System.Windows.Forms.ProgressBar progbar; private System.Windows.Forms.RadioButton rbtnFiles; private System.Windows.Forms.RadioButton rbtnDirectories; private System.Windows.Forms.RadioButton rbtnBoth; private System.Windows.Forms.Label label3; public WinForm() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // } protected override void Dispose (bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } #region Windows Form Designer generated code private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.searchRoot = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.pattern = new System.Windows.Forms.TextBox(); this.btnSearch = new System.Windows.Forms.Button(); this.label3 = new System.Windows.Forms.Label(); this.listFiles = new System.Windows.Forms.ListView(); this.listProperties = new System.Windows.Forms.ListView(); this.label4 = new System.Windows.Forms.Label(); this.lblDirectoryParts = new System.Windows.Forms.Label(); this.listDirectoryParts = new System.Windows.Forms.ListBox(); this.chkRecursive = new System.Windows.Forms.CheckBox(); this.chkDirectoryParts = new System.Windows.Forms.CheckBox(); this.progbar = new System.Windows.Forms.ProgressBar(); this.rbtnFiles = new System.Windows.Forms.RadioButton(); this.rbtnDirectories = new System.Windows.Forms.RadioButton(); this.rbtnBoth = new System.Windows.Forms.RadioButton(); this.SuspendLayout(); // // label1 // this.label1.Location = new System.Drawing.Point(8, 16); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(100, 16); this.label1.TabIndex = 0; this.label1.Text = "Search &root:"; // // searchRoot // this.searchRoot.Location = new System.Drawing.Point(112, 16); this.searchRoot.Name = "searchRoot"; this.searchRoot.Size = new System.Drawing.Size(632, 20); this.searchRoot.TabIndex = 1; this.searchRoot.Text = ""; // // label2 // this.label2.Location = new System.Drawing.Point(8, 56); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(100, 16); this.label2.TabIndex = 2; this.label2.Text = "&Pattern:"; // // pattern // this.pattern.Location = new System.Drawing.Point(112, 48); this.pattern.Name = "pattern"; this.pattern.TabIndex = 3; this.pattern.Text = "*.*"; // // btnSearch // this.btnSearch.Location = new System.Drawing.Point(664, 48); this.btnSearch.Name = "btnSearch"; this.btnSearch.Size = new System.Drawing.Size(80, 23); this.btnSearch.TabIndex = 9; this.btnSearch.Text = "&Search"; this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click); // // label3 // this.label3.Location = new System.Drawing.Point(8, 88); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(100, 16); this.label3.TabIndex = 10; this.label3.Text = "F&iles:"; // // listFiles // this.listFiles.Location = new System.Drawing.Point(8, 104); this.listFiles.MultiSelect = false; this.listFiles.Name = "listFiles"; this.listFiles.Size = new System.Drawing.Size(384, 368); this.listFiles.TabIndex = 11; this.listFiles.View = System.Windows.Forms.View.Details; this.listFiles.SelectedIndexChanged += new System.EventHandler(this.listFiles_SelectedIndexChanged); // // listProperties // this.listProperties.Location = new System.Drawing.Point(400, 104); this.listProperties.Name = "listProperties"; this.listProperties.Size = new System.Drawing.Size(344, 224); this.listProperties.TabIndex = 13; this.listProperties.View = System.Windows.Forms.View.Details; // // label4 // this.label4.Location = new System.Drawing.Point(408, 88); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(100, 16); this.label4.TabIndex = 12; this.label4.Text = "Pr&operties"; // // lblDirectoryParts // this.lblDirectoryParts.Location = new System.Drawing.Point(400, 336); this.lblDirectoryParts.Name = "lblDirectoryParts"; this.lblDirectoryParts.Size = new System.Drawing.Size(120, 16); this.lblDirectoryParts.TabIndex = 14; this.lblDirectoryParts.Text = "Directory par&ts:"; // // listDirectoryParts // this.listDirectoryParts.Location = new System.Drawing.Point(400, 352); this.listDirectoryParts.Name = "listDirectoryParts"; this.listDirectoryParts.Size = new System.Drawing.Size(344, 121); this.listDirectoryParts.TabIndex = 15; // // chkRecursive // this.chkRecursive.Checked = true; this.chkRecursive.CheckState = System.Windows.Forms.CheckState.Checked; this.chkRecursive.Location = new System.Drawing.Point(224, 56); this.chkRecursive.Name = "chkRecursive"; this.chkRecursive.Size = new System.Drawing.Size(96, 16); this.chkRecursive.TabIndex = 4; this.chkRecursive.Text = "Recursi&ve"; // // chkDirectoryParts // this.chkDirectoryParts.Checked = true; this.chkDirectoryParts.CheckState = System.Windows.Forms.CheckState.Checked; this.chkDirectoryParts.Location = new System.Drawing.Point(328, 56); this.chkDirectoryParts.Name = "chkDirectoryParts"; this.chkDirectoryParts.Size = new System.Drawing.Size(104, 16); this.chkDirectoryParts.TabIndex = 5; this.chkDirectoryParts.Text = "Directory P&arts"; // // progbar // this.progbar.Location = new System.Drawing.Point(8, 480); this.progbar.Name = "progbar"; this.progbar.Size = new System.Drawing.Size(736, 16); this.progbar.TabIndex = 11; // // rbtnFiles // this.rbtnFiles.Appearance = System.Windows.Forms.Appearance.Button; this.rbtnFiles.Checked = true; this.rbtnFiles.Location = new System.Drawing.Point(440, 48); this.rbtnFiles.Name = "rbtnFiles"; this.rbtnFiles.Size = new System.Drawing.Size(48, 24); this.rbtnFiles.TabIndex = 6; this.rbtnFiles.TabStop = true; this.rbtnFiles.Text = "&Files"; // // rbtnDirectories // this.rbtnDirectories.Appearance = System.Windows.Forms.Appearance.Button; this.rbtnDirectories.Location = new System.Drawing.Point(496, 48); this.rbtnDirectories.Name = "rbtnDirectories"; this.rbtnDirectories.Size = new System.Drawing.Size(72, 24); this.rbtnDirectories.TabIndex = 7; this.rbtnDirectories.Text = "&Directories"; // // rbtnBoth // this.rbtnBoth.Appearance = System.Windows.Forms.Appearance.Button; this.rbtnBoth.Location = new System.Drawing.Point(576, 48); this.rbtnBoth.Name = "rbtnBoth"; this.rbtnBoth.Size = new System.Drawing.Size(48, 24); this.rbtnBoth.TabIndex = 8; this.rbtnBoth.Text = "&Both"; // // WinForm // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(752, 499); this.Controls.AddRange(new System.Windows.Forms.Control[] { this.rbtnFiles, this.progbar, this.chkDirectoryParts, this.chkRecursive, this.listDirectoryParts, this.lblDirectoryParts, this.label4, this.listProperties, this.listFiles, this.label3, this.btnSearch, this.pattern, this.label2, this.searchRoot, this.label1, this.rbtnDirectories, this.rbtnBoth}); this.Name = "WinForm"; this.Text = "recls C# mapping test"; this.Load += new System.EventHandler(this.WinForm_Load); this.ResumeLayout(false); } #endregion [STAThread] static void Main() { Application.Run(new WinForm()); } private void btnSearch_Click(object sender, System.EventArgs e) { progbar.Maximum = 1000; RECLS_FLAG flags = 0; if(rbtnBoth.Checked) { flags |= RECLS_FLAG.RECLS_F_DIRECTORIES | RECLS_FLAG.RECLS_F_FILES; } else if(rbtnFiles.Checked) { flags |= RECLS_FLAG.RECLS_F_FILES; } else if(rbtnDirectories.Checked) { flags |= RECLS_FLAG.RECLS_F_DIRECTORIES; } if(chkRecursive.Checked) { flags |= RECLS_FLAG.RECLS_F_RECURSIVE; } if(chkDirectoryParts.Checked) { flags |= RECLS_FLAG.RECLS_F_DIRECTORY_PARTS; } listDirectoryParts.Enabled = chkDirectoryParts.Checked; lblDirectoryParts.Enabled = chkDirectoryParts.Checked; FileSearch fs = new FileSearch(searchRoot.Text, pattern.Text, flags); listFiles.Items.Clear(); listProperties.Items.Clear(); listDirectoryParts.Items.Clear(); foreach(FileEntry fe in fs) { ListViewItem lvi = new ListViewItem(fe.Path); lvi.Tag = fe; listFiles.Items.Add(lvi); if(1 + progbar.Value == progbar.Maximum) { progbar.Value = 0; } else { progbar.Value = 1 + progbar.Value; } progbar.Update(); listFiles.Update(); } progbar.Value = 0; } private void WinForm_Load(object sender, System.EventArgs e) { int cx; cx = listFiles.Width - 4; listFiles.Columns.Add("Filename", cx, HorizontalAlignment.Left); cx = listProperties.Width - 4; listProperties.Columns.Add("Property", cx * 2 / 5, HorizontalAlignment.Left); listProperties.Columns.Add("Value", cx * 3 / 5, HorizontalAlignment.Left); } private void listFiles_SelectedIndexChanged(object sender, System.EventArgs e) { ListView.SelectedListViewItemCollection items = listFiles.SelectedItems; if(items.Count == 1) { PopulateProperties((FileEntry)items[0].Tag); } } private string TranslateEntryAttributes(FileEntry fe) { string s = ""; if(fe.IsDirectory) { if(s.Length > 0) { s += " "; } s += "[Directory]"; } if(fe.IsLink) { if(s.Length > 0) { s += " "; } s += "[Link]"; } if(fe.IsReadOnly) { if(s.Length > 0) { s += " "; } s += "[Read only]"; } return s; } private void PopulateProperties(FileEntry entry) { listProperties.Items.Clear(); listDirectoryParts.Items.Clear(); listProperties.Items.Add("Path").SubItems.Add(entry.Path); listProperties.Items.Add("Drive").SubItems.Add(entry.Drive.ToString()); listProperties.Items.Add("Directory").SubItems.Add(entry.Directory); listProperties.Items.Add("DirectoryPath").SubItems.Add(entry.DirectoryPath); listProperties.Items.Add("File").SubItems.Add(entry.File); listProperties.Items.Add("ShortFile").SubItems.Add(entry.ShortFile); listProperties.Items.Add("FileName").SubItems.Add(entry.FileName); listProperties.Items.Add("FileExt").SubItems.Add(entry.FileExt); listProperties.Items.Add("CreationTime").SubItems.Add(entry.CreationTime.ToString()); listProperties.Items.Add("ModificationTime").SubItems.Add(entry.ModificationTime.ToString()); listProperties.Items.Add("LastAccessTime").SubItems.Add(entry.LastAccessTime.ToString()); listProperties.Items.Add("LastStatusChangeTime").SubItems.Add(entry.LastStatusChangeTime.ToString()); listProperties.Items.Add("Attributes").SubItems.Add(TranslateEntryAttributes(entry)); foreach(string part in entry.DirectoryParts) { listDirectoryParts.Items.Add(part); } } } }
This program uses the recls COM mapping coclasses, implementing a recursive search for a given pattern, and other flags, from a given directory
/* * File: COM.cpp * * Purpose: Implementation file for the COM project. * * Created: 19th December 2003 * Updated: 25th March 2004 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright (C) 1999-2004, Synesis Software Pty Ltd. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2003 * by Synesis Software Pty Ltd. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Synesis Software Pty Ltd "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Synesis Software Pty Ltd be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Synesis Software Pty Ltd nor the names of * any subdivisions, employees or agents of Synesis Software Pty * Ltd, nor the names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * * #include <windows.h> #include <stdio.h> #if defined(__DMC__) # include <iostream.h> #else /* ? __DMC__ */ # include <iostream> # include <iomanip> using std::cout; using std::wcout; using std::cerr; using std::endl; #endif /* __DMC__ */ #include <stdlib.h> #include <stlsoft.h> #include <atlstl.h> #include <comstl.h> #include <comstl_enumerator_policies.h> #include <comstl_initialisers.h> #include <comstl_interface_cast.h> #include <comstl_value_policies.h> #include <comstl_enum_sequence.h> #include <comstl_coll_sequence.h> // This version of recls has been released at the same time as STLSoft 1.7.1 beta 3, in which // comstl_method_cast.h resides in the "inprogress" sub-directory. #include <inprogress/comstl_method_cast.h> // // Once STLSoft 1.7.1 is released, this file will reside in the main directory, so you should // comment out the include above, and uncomment the one below //#include <comstl_method_cast.h> #include <winstl.h> #include <winstl_char_conversions.h> #include <recls_com.h> #include <recls_com_i.c> #ifdef _MSC_VER # include <CrtDbg.h> #endif /* _MSC_VER */ //#define USE_ENUMVARIANT #define USE_ENUMENTRY /* * Helper functions */ template<typename S> S &operator <<(S &s, CComBSTR const &bstr) { wchar_t const *str = bstr; return s << str; } namespace comstl { inline CComBSTR &transfer_resource(CComBSTR &r, BSTR v) { comstl_message_assert("Resource destination not empty!", NULL == r.m_str); r.m_str = v; return r; } } /* * Forward declarations */ void usage(int bExit); int processDirectory(IFileSearch *search, LPCOLESTR rootDir, LPCOLESTR pattern, long flags, int bSuccinct); /* * Main */ int main(int argc, char *argv[]) { #if 0 ::Sleep(100000); #endif /* 0 */ int iRet = 0; int i; int totalFound = 0; int bAllHardDrives = false; char const *pattern = NULL; char const *rootDir = NULL; long flags = RECLS_F_RECURSIVE; int bSuccinct = false; for(i = 1; i < argc; ++i) { const char *arg = argv[i]; if(arg[0] == '-') { if(arg[1] == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg[1]) { case 'R': /* Do not recurse */ flags &= ~(RECLS_F_RECURSIVE); break; case 'p': /* Show directory parts */ flags |= RECLS_F_DIRECTORY_PARTS; break; case 'f': /* Find files */ flags |= RECLS_F_FILES; break; case 'h': /* Searches from hard drives */ bAllHardDrives = true; break; case 'd': /* Find directories */ flags |= RECLS_F_DIRECTORIES; break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = true; break; default: usage(1); break; } } } else { /* other arguments */ if(NULL == pattern) { pattern = arg; } else if(NULL == rootDir) { rootDir = arg; } else { usage(1); } } } // Search for files if neither files or directories specified // // Even though this is not necessary, because the recls API provides the // same interpretation, it's best to be explicit. if(0 == (flags & (RECLS_F_FILES | RECLS_F_DIRECTORIES))) { flags |= RECLS_F_FILES; } if(NULL == rootDir) { rootDir = "."; } #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemState memState; _CrtMemCheckpoint(&memState); #endif /* _MSC_VER && _MSC_VER */ { IFileSearch *search; comstl::com_initialiser init; HRESULT hr = ::CoCreateInstance(CLSID_FileSearch, NULL, CLSCTX_ALL, IID_IFileSearch, (void**)&search); if(FAILED(hr)) { cerr << "Failed to load the recls COM server! Please check your installation" << endl; } else { USES_CONVERSION; CComBSTR bstrPattern = comstl::method_cast<CComBSTR>(search, &IFileSearch::get_WildcardsAll); if(NULL == pattern) pattern = OLE2CT(bstrPattern); if(bAllHardDrives) { LPUNKNOWN punkRoots; hr = search->get_Roots(&punkRoots); if(SUCCEEDED(hr)) { typedef comstl::enumerator_sequence<IEnumString, LPOLESTR, comstl::LPOLESTR_policy> enum_sequence_t; enum_sequence_t roots(comstl::interface_cast_addref<LPENUMSTRING>(punkRoots), false); enum_sequence_t::/* const_ */iterator begin = roots.begin(); enum_sequence_t::/* const_ */iterator end = roots.end(); for(; begin != end; ++begin) { totalFound += processDirectory(search, *begin, winstl::a2w(pattern), flags, bSuccinct); } punkRoots->Release(); } } else { totalFound = processDirectory(search, winstl::a2w(rootDir), winstl::a2w(pattern), flags, bSuccinct); } search->Release(); } } fprintf(stdout, "Total found: %d\n", totalFound); #if defined(_MSC_VER) && \ defined(_DEBUG) _CrtMemDumpAllObjectsSince(&memState); #endif /* _MSC_VER && _MSC_VER */ return iRet; } /* * Function implementations */ void usage(int bExit) { cout << "recls COM (C++) Test Program: COM" << endl << endl; cout << "Usage: COM [-d] [-f] [-h] [-p] [-R] [-s] [<pattern>] [<root-dir>]" << endl; cout << "\t-R - does not recurse; recursive search is the default" << endl; cout << "\t-p - evaluate and display directory parts" << endl; cout << "\t-d - search for directories" << endl; cout << "\t-f - search for files (this is the default, if -d is not specified" << endl; cout << "\t-h - searches from hard drive roots. (Ignore <root-dir>.)" << endl; cout << "\t-s - succinct; shows only the path" << endl; cout << "\t<pattern> - search pattern, e.g. \"*.cpp\"; default is to search for all files" << endl; cout << "\t<root-dir> - root directory of search; default is current working directory" << endl; if(bExit) { exit(1); } } int processDirectory(IFileSearch *search, LPCOLESTR rootDir, LPCOLESTR pattern, long flags, int bSuccinct) { int totalFound = 0; IUnknown *punkResults; HRESULT hr = search->Search(const_cast<LPOLESTR>(rootDir), const_cast<LPOLESTR>(pattern), flags, &punkResults); if(SUCCEEDED(hr)) { ISearchCollection *psc = comstl::interface_cast_addref<ISearchCollection*>(punkResults); if(NULL != psc) { #if defined(USE_ENUMVARIANT) typedef comstl::collection_sequence< ISearchCollection , IEnumVARIANT , VARIANT , comstl::VARIANT_policy > coll_seq_t; #elif defined(USE_ENUMENTRY) typedef comstl::collection_sequence< ISearchCollection , IEnumFileEntry , IFileEntry* , comstl::interface_policy<IFileEntry> > coll_seq_t; #else # error Must specify USE_ENUMVARIANT or USE_ENUMENTRY #endif /* 0 */ coll_seq_t collection(psc, true); coll_seq_t::iterator b = collection.begin(); coll_seq_t::iterator e = collection.end(); for(; b != e; ++b) { ++totalFound; #if defined(USE_ENUMVARIANT) IFileEntry *pfe = comstl::interface_cast_addref<IFileEntry*>((*b).punkVal); #elif defined(USE_ENUMENTRY) IFileEntry *pfe = *b; #else # error Must specify USE_ENUMVARIANT or USE_ENUMENTRY #endif /* 0 */ CComBSTR path = comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_Path); OLECHAR drive = comstl::method_cast<OLECHAR>(pfe, &IFileEntry::get_Drive); CComBSTR directory = comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_Directory); CComBSTR directoryPath = comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_DirectoryPath); LPUNKNOWN directoryParts = comstl::method_cast<LPUNKNOWN>(pfe, &IFileEntry::get_DirectoryParts); CComBSTR file = comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_File); CComBSTR shortFile = comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_ShortFile); CComBSTR fileName = comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_FileName); CComBSTR fileExt = comstl::method_cast<CComBSTR>(pfe, &IFileEntry::get_FileExt); DATE creationTime = comstl::method_cast<DATE>(pfe, &IFileEntry::get_CreationTime); DATE modificationTime = comstl::method_cast<DATE>(pfe, &IFileEntry::get_ModificationTime); DATE lastAccessTime = comstl::method_cast<DATE>(pfe, &IFileEntry::get_LastAccessTime); DATE lastStatusChangeTime = comstl::method_cast<DATE>(pfe, &IFileEntry::get_LastStatusChangeTime); long size = comstl::method_cast<long>(pfe, &IFileEntry::get_Size); BOOL isReadOnly = comstl::method_cast<BOOL>(pfe, &IFileEntry::get_IsReadOnly); BOOL isDirectory = comstl::method_cast<BOOL>(pfe, &IFileEntry::get_IsDirectory); wcout << L" " << path << endl; if(!bSuccinct) { wcout << L" " << directoryPath << endl; wcout << L" " << (wchar_t const *)winstl::a2w((char const*)&drive, 1) << endl; wcout << L" " << directory << endl; int off = 0; if( (flags & RECLS_F_DIRECTORY_PARTS) == RECLS_F_DIRECTORY_PARTS && NULL != directoryParts) { typedef comstl::collection_sequence< IDirectoryPartsCollection , IEnumVARIANT , VARIANT , comstl::VARIANT_policy , VARIANT const & , comstl::forward_cloning_policy<IEnumVARIANT> , 2 > parts_seq_t; parts_seq_t dirParts(comstl::interface_cast_addref<IDirectoryPartsCollection*>(directoryParts), false); parts_seq_t::iterator b = dirParts.begin(); parts_seq_t::iterator e = dirParts.end(); for(; b != e; ++b) { CComVariant vPart(*b); vPart.ChangeType(VT_BSTR); CComBSTR dirPart(vPart.bstrVal); off += dirPart.Length(); wcout << L" " << std::setw(off) << dirPart << std::setw(1) << endl; } directoryParts->Release(); } else { off += directory.Length(); // pathCheck += directory; } off += file.Length(); wcout << L" " << std::setw(off) << file << std::setw(1) << endl; if(fileExt.Length() > 0) { wcout << L" " << std::setw(off - (1 + fileExt.Length())) << fileName << std::setw(1) << endl; wcout << L" " << std::setw(off) << fileExt << std::setw(1) << endl; } else { wcout << L" " << std::setw(off) << fileName << std::setw(1) << endl; } if(isReadOnly) { wcout << L" - Read-only" << endl; } if(isDirectory) { wcout << L" - Directory" << endl; } else { wcout << L" - File" << endl; } } #if defined(USE_ENUMVARIANT) pfe->Release(); #endif /* USE_ENUMVARIANT */ } psc->Release(); } punkResults->Release(); } return totalFound; } /* * End of file */
This program uses the recls COM mapping coclasses, implementing a recursive search for a given pattern, and other flags, from a given directory
VERSION 5.00 Begin VB.Form Form1 BorderStyle = 3 'Fixed Dialog Caption = "Form1" ClientHeight = 7320 ClientLeft = 45 ClientTop = 360 ClientWidth = 11550 LinkTopic = "Form1" MaxButton = 0 'False MinButton = 0 'False ScaleHeight = 7320 ScaleWidth = 11550 ShowInTaskbar = 0 'False StartUpPosition = 3 'Windows Default Begin VB.ListBox lstDirectoryParts Height = 2010 Left = 6360 TabIndex = 15 Top = 5040 Width = 5055 End Begin VB.ListBox lstProperties Height = 2790 Left = 6360 TabIndex = 13 Top = 1800 Width = 5055 End Begin VB.OptionButton rdoBoth Caption = "&Both" Height = 375 Left = 8160 Style = 1 'Graphical TabIndex = 11 Top = 720 Width = 975 End Begin VB.OptionButton rdoDirectories Caption = "&Directories" Height = 375 Left = 7080 Style = 1 'Graphical TabIndex = 10 Top = 720 Width = 975 End Begin VB.OptionButton rdoFiles Caption = "&Files" Height = 375 Left = 6120 Style = 1 'Graphical TabIndex = 9 Top = 720 Width = 855 End Begin VB.CheckBox chkRecursive Caption = "Recursi&ve" Height = 375 Left = 3360 TabIndex = 8 Top = 720 Width = 1215 End Begin VB.CheckBox chkDirParts Caption = "Directory P&arts" Height = 375 Left = 4680 TabIndex = 7 Top = 720 Width = 1335 End Begin VB.TextBox txtPattern Height = 375 Left = 1320 TabIndex = 5 Text = "*.*" Top = 720 Width = 1935 End Begin VB.ListBox lstFiles Height = 5325 Left = 120 TabIndex = 3 Top = 1800 Width = 6135 End Begin VB.CommandButton btnSearch Caption = "&Search" Height = 375 Left = 10080 TabIndex = 2 Top = 600 Width = 1335 End Begin VB.TextBox txtSearchRoot Height = 375 Left = 1320 TabIndex = 1 Text = "." Top = 240 Width = 10095 End Begin VB.Label Label5 Caption = "Directory pa&rts:" Height = 255 Left = 6360 TabIndex = 14 Top = 4680 Width = 1815 End Begin VB.Label Label4 Caption = "P&roperties:" Height = 255 Left = 6360 TabIndex = 12 Top = 1440 Width = 1575 End Begin VB.Label Label3 Caption = "F&iles:" Height = 255 Left = 120 TabIndex = 6 Top = 1440 Width = 1335 End Begin VB.Label Label2 Caption = "&Pattern:" Height = 255 Left = 120 TabIndex = 4 Top = 840 Width = 975 End Begin VB.Label Label1 Caption = "Search &root:" Height = 255 Left = 120 TabIndex = 0 Top = 240 Width = 1095 End End Attribute VB_Name = "Form1" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False Private g_index As Integer Private g_entries As Collection Private Sub btnSearch_Click() Dim fs As New RECLS_COMLib.FileSearch Dim searchRoot As String Dim pattern As String Dim flags As Long Dim srch As Object ' Reset the collection Set g_entries = New Collection g_index = 0 searchRoot = txtSearchRoot.Text pattern = txtPattern.Text flags = 0 If chkRecursive.Value Then flags = flags Or RECLS_FLAG.RECLS_F_RECURSIVE End If If chkDirParts.Value Then flags = flags Or RECLS_FLAG.RECLS_F_DIRECTORY_PARTS End If If rdoBoth.Value = True Then flags = flags Or RECLS_FLAG.RECLS_F_FILES flags = flags Or RECLS_FLAG.RECLS_F_DIRECTORIES ElseIf rdoDirectories = True Then flags = flags Or RECLS_FLAG.RECLS_F_DIRECTORIES ElseIf rdoFiles = True Then flags = flags Or RECLS_FLAG.RECLS_F_FILES Else flags = flags Or RECLS_FLAG.RECLS_F_FILES End If Set srch = fs.Search(searchRoot, pattern, flags) lstFiles.Clear lstProperties.Clear lstDirectoryParts.Clear For Each entry In srch lstFiles.AddItem (entry) lstFiles.ItemData(lstFiles.NewIndex) = g_index g_entries.Add entry, CStr(g_index) g_index = g_index + 1 Next End Sub Private Sub Form_Load() chkRecursive.Value = 1 rdoFiles.Value = True End Sub Private Sub lstFiles_Click() Dim entry As RECLS_COMLib.FileEntry Dim index As Integer Dim dirParts As Object index = lstFiles.ItemData(lstFiles.ListIndex) Set entry = g_entries.Item(CStr(index)) ' Do the properties lstProperties.Clear lstProperties.AddItem ("Drive: " & entry.Drive) lstProperties.AddItem ("Directory: " & entry.Directory) lstProperties.AddItem ("DirectoryPath: " & entry.DirectoryPath) lstProperties.AddItem ("File: " & entry.File) lstProperties.AddItem ("ShortFile: " & entry.ShortFile) lstProperties.AddItem ("FileName: " & entry.FileName) lstProperties.AddItem ("FileExt: " & entry.FileExt) lstProperties.AddItem ("CreationTime: " & entry.CreationTime) lstProperties.AddItem ("ModificationTime: " & entry.ModificationTime) lstProperties.AddItem ("LastAccessTime: " & entry.LastAccessTime) lstProperties.AddItem ("LastStatusChangeTime: " & entry.LastStatusChangeTime) lstProperties.AddItem ("Size: " & entry.Size) ' Do the directory parts Set dirParts = entry.DirectoryParts lstDirectoryParts.Clear For Each dirPart In dirParts lstDirectoryParts.AddItem (dirPart) Next End Sub
This program uses the free API functions in the recls D mapping, implementing a recursive search for a given pattern, and other flags, from a given directory
/* * File: recls_test_1.d * * Purpose: Test program for the D mapping of recls. (Now the std.recls * module in the D standard library). Test free-functions. * * Created * Updated: 12th April 2004 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright (C) 1999-2003, Synesis Software Pty Ltd. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2003 * by Synesis Software Pty Ltd. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Synesis Software Pty Ltd "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Synesis Software Pty Ltd be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Synesis Software Pty Ltd nor the names of * any subdivisions, employees or agents of Synesis Software Pty * Ltd, nor the names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * */ import std.recls; import std.string; import std.c.stdio; import std.c.stdlib; int main(char[][] args) { int iRet = 0; int i; char[] pattern = null; char[] rootDir = null; hrecls_t hSrch; recls_rc_t rc; recls_uint32_t flags = RECLS_FLAG.RECLS_F_RECURSIVE; int bSuccinct = false; for(i = 1; i < args.length; ++i) { char[] arg = args[i]; if(arg[0] == '-') { if(arg[1] == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg[1]) { case 'R': /* Do not recurse */ flags &= ~(RECLS_FLAG.RECLS_F_RECURSIVE); break; case 'p': /* Show directory parts */ flags |= RECLS_FLAG.RECLS_F_DIRECTORY_PARTS; break; case 'f': /* Find files */ flags |= RECLS_FLAG.RECLS_F_FILES; break; case 'd': /* Find directories */ flags |= RECLS_FLAG.RECLS_F_DIRECTORIES; break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = true; break; default: usage(1); break; } } } else { /* other arguments */ if(null == pattern) { pattern = arg; } else if(null == rootDir) { rootDir = arg; } else { usage(1); } } } /* Search for files if neither files or directories specified/ * * Even though this is not necessary, because the recls API provides the * same interpretation, it's best to be explicit. */ if(0 == (flags & (RECLS_FLAG.RECLS_F_FILES | RECLS_FLAG.RECLS_F_DIRECTORIES))) { flags |= RECLS_FLAG.RECLS_F_FILES; } if(null == pattern) { version(Windows) { pattern = "*.*"; } else { pattern = "*"; } } if(null == rootDir) { rootDir = "."; } /* Initiate the search. */ rc = Search_Create(rootDir, pattern, flags, hSrch); if(RECLS_FAILED(rc)) { char[] err = Search_GetErrorString(rc); fprintf(stderr, "Failed to start search, with pattern \"%.*s\"; recls error: %.*s\n", pattern, err); } else { /* Iterate through the items, until done */ recls_info_t entry; rc = Search_GetEntry(hSrch, entry); for(; RECLS_SUCCEEDED(rc); rc = Search_GetNextEntry(hSrch, entry)) { int i; int off; int extLen; int cDirParts; char[] path = Search_GetEntryPath(entry); version(Windows) { char drive = Search_GetEntryDrive(entry); // This complex dance is necessitated because string and ctype seem // unable to coexist (with v0.74, anyway) if(drive != path[0]) { char p0upper = toupper(path[0 .. 1])[0]; char p0lower = tolower(path[0 .. 1])[0]; if(drive == p0upper) { drive = p0lower; } else { drive = p0upper; } } } char[] dir = Search_GetEntryDirectory(entry); char[] dirPath = Search_GetEntryDirectoryPath(entry); char[] file = Search_GetEntryFile(entry); char[] fileName = Search_GetEntryFileName(entry); char[] fileExt = Search_GetEntryFileExt(entry); char[] pathCheck = new char[0]; char[] dirCheck = new char[0]; char[] fileCheck; recls_filesize_t size = Search_GetEntrySize(entry); version(Debug) { recls_uint32_t cBlocks; Search_OutstandingEntry(hSrch, &cBlocks); printf("\n%d outstanding blocks\n", cBlocks); } printf(" %.*s\n", path); if(!bSuccinct) { printf(" %.*s\n", dirPath); version(Windows) { printf(" %c\n", drive); pathCheck ~= drive; pathCheck ~= ':'; } printf(" %.*s\n", dir); off = 0; if((flags & RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) == RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) { char[][] parts = Search_GetEntryDirectoryParts(entry); foreach(char[] part; parts) { printf(" %*s", off, (char*)""); printf("%.*s\n", part); off += part.length; pathCheck ~= part; dirCheck ~= part; } } else { off += dir.length; pathCheck ~= dir; } printf(" %*s%.*s\n", off, (char*)"", file); printf(" %*s%.*s\n", off, (char*)"", fileName); off += file.length; extLen = fileExt.length; printf(" %*s%.*s\n", off - extLen, (char*)"", fileExt); fileCheck = fileName; if(0 < extLen) { fileCheck ~= '.'; fileCheck ~= fileExt; } pathCheck ~= file; /* Now validate the components */ version(Windows) { if(path != pathCheck) { fprintf(stderr, "Path is different from path components\n\tpath: %.*s\n\tpathCheck: %.*s\n\n", path, pathCheck); } assert(path == pathCheck); } else { if(path != pathCheck) { fprintf(stderr, "Path is different from path components\n\tpath: %.*s\n\tpathCheck: %.*s\n\n", path, pathCheck); } assert(path == pathCheck); } version(Windows) { if( dirPath[0] != drive || dir != dirPath[2 .. dirPath.length]) { fprintf(stderr, "DirectoryPath is different from Directory\n\tdirPath: %.*s (%d)\n\tdir: %c:%.*s (%d)\n\n", dirPath, dirPath.length - 2, drive, dir, dir.length); } assert(dirPath[0] == drive && dir == dirPath[2 .. dirPath.length]); } else { if(dirPath != dir) { fprintf(stderr, "DirectoryPath is different from Directory\n\tdirPath: %.*s\n\tdir: %.*s\n\n", dirPath, dir); } assert(dirPath == dir); } if((flags & RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) == RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) { if(dir != dirCheck) { fprintf(stderr, "Directory is different from directory components\n\tdir: %.*s\n\tdirCheck: %.*s\n\n", dir, dirCheck); } assert(dir == dirCheck); } if(file != fileCheck) { fprintf(stderr, "File is different from file components\n\tfile: %d:%.*s\n\tfileCheck: %d:%.*s\n\n", file.length, file, fileCheck.length, fileCheck); } assert(file == fileCheck); if(Search_IsEntryDirectory(entry)) { printf(" - Directory\n"); } else { printf(" - File\n"); } if(Search_IsEntryReadOnly(entry)) { printf(" - Read-only\n"); } if(Search_IsEntryLink(entry)) { printf(" - Link\n"); } printf(" %lu\n", size); } Search_CloseEntry(entry); } if(rc != RECLS_RC_NO_MORE_DATA) { char[] err = Search_GetErrorString(rc); fprintf(stderr, "Search terminated prematurely; recls error: %.*s\n", err); } Search_Close(hSrch); } return iRet; } /* * Function implementations */ void usage(int bExit) { fprintf(stderr, "recls D Test Program: recls_test_1\n\n"); fprintf(stderr, "Usage: recls_test_1 [-d] [-f] [-h] [-p] [-R] [-s] [<pattern>] [<root-dir>]\n"); fprintf(stderr, "\t-d - search for directories\n"); fprintf(stderr, "\t-f - search for files. (default if neither f or d specified)\n"); fprintf(stderr, "\t-p - include directory parts in search, and display\n"); fprintf(stderr, "\t-R - does not recurse. (recursive search is the default)\n"); fprintf(stderr, "\t-h - searches from hard drive roots. (Ignore <root-dir>.)\n"); fprintf(stderr, "\t-s - succinct; shows only the path\n"); fprintf(stderr, "\t<pattern> - search pattern, e.g. \"*.cpp\" (default is to search for all files)\n"); fprintf(stderr, "\t<root-dir> - root directory of search; default is current working directory\n"); if(bExit) { exit(1); } } /* * End of file */
This program uses the classes in the recls D mapping, implementing a recursive search for a given pattern, and other flags, from a given directory
/* * File: recls_test_1.d * * Purpose: Test program for the D mapping of recls. (Now the std.recls * module in the D standard library). Test free-functions. * * Created * Updated: 12th April 2004 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright (C) 1999-2003, Synesis Software Pty Ltd. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2003 * by Synesis Software Pty Ltd. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Synesis Software Pty Ltd "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Synesis Software Pty Ltd be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Synesis Software Pty Ltd nor the names of * any subdivisions, employees or agents of Synesis Software Pty * Ltd, nor the names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * */ import std.recls; import std.string; import std.c.stdio; import std.c.stdlib; int main(char[][] args) { int iRet = 0; int i; char[] pattern = null; char[] rootDir = null; hrecls_t hSrch; recls_rc_t rc; recls_uint32_t flags = RECLS_FLAG.RECLS_F_RECURSIVE; int bSuccinct = false; for(i = 1; i < args.length; ++i) { char[] arg = args[i]; if(arg[0] == '-') { if(arg[1] == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg[1]) { case 'R': /* Do not recurse */ flags &= ~(RECLS_FLAG.RECLS_F_RECURSIVE); break; case 'p': /* Show directory parts */ flags |= RECLS_FLAG.RECLS_F_DIRECTORY_PARTS; break; case 'f': /* Find files */ flags |= RECLS_FLAG.RECLS_F_FILES; break; case 'd': /* Find directories */ flags |= RECLS_FLAG.RECLS_F_DIRECTORIES; break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = true; break; default: usage(1); break; } } } else { /* other arguments */ if(null == pattern) { pattern = arg; } else if(null == rootDir) { rootDir = arg; } else { usage(1); } } } /* Search for files if neither files or directories specified/ * * Even though this is not necessary, because the recls API provides the * same interpretation, it's best to be explicit. */ if(0 == (flags & (RECLS_FLAG.RECLS_F_FILES | RECLS_FLAG.RECLS_F_DIRECTORIES))) { flags |= RECLS_FLAG.RECLS_F_FILES; } if(null == pattern) { version(Windows) { pattern = "*.*"; } else { pattern = "*"; } } if(null == rootDir) { rootDir = "."; } /* Initiate the search. */ rc = Search_Create(rootDir, pattern, flags, hSrch); if(RECLS_FAILED(rc)) { char[] err = Search_GetErrorString(rc); fprintf(stderr, "Failed to start search, with pattern \"%.*s\"; recls error: %.*s\n", pattern, err); } else { /* Iterate through the items, until done */ recls_info_t entry; rc = Search_GetEntry(hSrch, entry); for(; RECLS_SUCCEEDED(rc); rc = Search_GetNextEntry(hSrch, entry)) { int i; int off; int extLen; int cDirParts; char[] path = Search_GetEntryPath(entry); version(Windows) { char drive = Search_GetEntryDrive(entry); // This complex dance is necessitated because string and ctype seem // unable to coexist (with v0.74, anyway) if(drive != path[0]) { char p0upper = toupper(path[0 .. 1])[0]; char p0lower = tolower(path[0 .. 1])[0]; if(drive == p0upper) { drive = p0lower; } else { drive = p0upper; } } } char[] dir = Search_GetEntryDirectory(entry); char[] dirPath = Search_GetEntryDirectoryPath(entry); char[] file = Search_GetEntryFile(entry); char[] fileName = Search_GetEntryFileName(entry); char[] fileExt = Search_GetEntryFileExt(entry); char[] pathCheck = new char[0]; char[] dirCheck = new char[0]; char[] fileCheck; recls_filesize_t size = Search_GetEntrySize(entry); version(Debug) { recls_uint32_t cBlocks; Search_OutstandingEntry(hSrch, &cBlocks); printf("\n%d outstanding blocks\n", cBlocks); } printf(" %.*s\n", path); if(!bSuccinct) { printf(" %.*s\n", dirPath); version(Windows) { printf(" %c\n", drive); pathCheck ~= drive; pathCheck ~= ':'; } printf(" %.*s\n", dir); off = 0; if((flags & RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) == RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) { char[][] parts = Search_GetEntryDirectoryParts(entry); foreach(char[] part; parts) { printf(" %*s", off, (char*)""); printf("%.*s\n", part); off += part.length; pathCheck ~= part; dirCheck ~= part; } } else { off += dir.length; pathCheck ~= dir; } printf(" %*s%.*s\n", off, (char*)"", file); printf(" %*s%.*s\n", off, (char*)"", fileName); off += file.length; extLen = fileExt.length; printf(" %*s%.*s\n", off - extLen, (char*)"", fileExt); fileCheck = fileName; if(0 < extLen) { fileCheck ~= '.'; fileCheck ~= fileExt; } pathCheck ~= file; /* Now validate the components */ version(Windows) { if(path != pathCheck) { fprintf(stderr, "Path is different from path components\n\tpath: %.*s\n\tpathCheck: %.*s\n\n", path, pathCheck); } assert(path == pathCheck); } else { if(path != pathCheck) { fprintf(stderr, "Path is different from path components\n\tpath: %.*s\n\tpathCheck: %.*s\n\n", path, pathCheck); } assert(path == pathCheck); } version(Windows) { if( dirPath[0] != drive || dir != dirPath[2 .. dirPath.length]) { fprintf(stderr, "DirectoryPath is different from Directory\n\tdirPath: %.*s (%d)\n\tdir: %c:%.*s (%d)\n\n", dirPath, dirPath.length - 2, drive, dir, dir.length); } assert(dirPath[0] == drive && dir == dirPath[2 .. dirPath.length]); } else { if(dirPath != dir) { fprintf(stderr, "DirectoryPath is different from Directory\n\tdirPath: %.*s\n\tdir: %.*s\n\n", dirPath, dir); } assert(dirPath == dir); } if((flags & RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) == RECLS_FLAG.RECLS_F_DIRECTORY_PARTS) { if(dir != dirCheck) { fprintf(stderr, "Directory is different from directory components\n\tdir: %.*s\n\tdirCheck: %.*s\n\n", dir, dirCheck); } assert(dir == dirCheck); } if(file != fileCheck) { fprintf(stderr, "File is different from file components\n\tfile: %d:%.*s\n\tfileCheck: %d:%.*s\n\n", file.length, file, fileCheck.length, fileCheck); } assert(file == fileCheck); if(Search_IsEntryDirectory(entry)) { printf(" - Directory\n"); } else { printf(" - File\n"); } if(Search_IsEntryReadOnly(entry)) { printf(" - Read-only\n"); } if(Search_IsEntryLink(entry)) { printf(" - Link\n"); } printf(" %lu\n", size); } Search_CloseEntry(entry); } if(rc != RECLS_RC_NO_MORE_DATA) { char[] err = Search_GetErrorString(rc); fprintf(stderr, "Search terminated prematurely; recls error: %.*s\n", err); } Search_Close(hSrch); } return iRet; } /* * Function implementations */ void usage(int bExit) { fprintf(stderr, "recls D Test Program: recls_test_1\n\n"); fprintf(stderr, "Usage: recls_test_1 [-d] [-f] [-h] [-p] [-R] [-s] [<pattern>] [<root-dir>]\n"); fprintf(stderr, "\t-d - search for directories\n"); fprintf(stderr, "\t-f - search for files. (default if neither f or d specified)\n"); fprintf(stderr, "\t-p - include directory parts in search, and display\n"); fprintf(stderr, "\t-R - does not recurse. (recursive search is the default)\n"); fprintf(stderr, "\t-h - searches from hard drive roots. (Ignore <root-dir>.)\n"); fprintf(stderr, "\t-s - succinct; shows only the path\n"); fprintf(stderr, "\t<pattern> - search pattern, e.g. \"*.cpp\" (default is to search for all files)\n"); fprintf(stderr, "\t<root-dir> - root directory of search; default is current working directory\n"); if(bExit) { exit(1); } } /* * End of file */
This program uses the classes in the recls Java mapping, implementing a recursive search for a given pattern, and other flags, from a given directory
/* * File: recls_test.java * * Purpose: Test file for the recls Java mapping. * * Created: 22nd November 2003 * Updated: 11th February 2004 * * Status: Wizard-generated * * License: (Licensed under the Synesis Software Open License) * * Copyright (C) 1999-2003, Synesis Software Pty Ltd. * All rights reserved. * * www: http://www.synesis.com.au/software * * email: software@synesis.com.au * * This source code is placed into the public domain 2003 * by Synesis Software Pty Ltd. There are no restrictions * whatsoever to your use of the software. * * This source code is provided by Synesis Software Pty Ltd "as is" * and any warranties, whether expressed or implied, including, but * not limited to, the implied warranties of merchantability and * fitness for a particular purpose are disclaimed. In no event * shall the Synesis Software Pty Ltd be liable for any direct, * indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of * substitute goods or services; loss of use, data, or profits; or * business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort * (including negligence or otherwise) arising in any way out of * the use of this software, even if advised of the possibility of * such damage. * * Neither the name of Synesis Software Pty Ltd nor the names of * any subdivisions, employees or agents of Synesis Software Pty * Ltd, nor the names of any other contributors to this software * may be used to endorse or promote products derived from this * software without specific prior written permission. * */ import org.recls.Entry; import org.recls.ReclsException; import org.recls.Search; import java.util.Enumeration; public class recls_test { public static void main(String[] args) { int i; String pattern = null; String rootDir = null; int flags = Search.RECLS_F_RECURSIVE; boolean bSuccinct = false; for(i = 0; i < args.length; ++i) { String arg = args[i]; if(arg.charAt(0) == '-') { if(arg.charAt(1) == '-') { /* -- arguments */ } else { /* - arguments */ switch(arg.charAt(1)) { case 'R': /* Do not recurse */ flags &= ~(Search.RECLS_F_RECURSIVE); break; case 'p': /* Show directory parts */ flags |= Search.RECLS_F_DIRECTORY_PARTS; break; case 'f': /* Find files */ flags |= Search.RECLS_F_FILES; break; case 'd': /* Find directories */ flags |= Search.RECLS_F_DIRECTORIES; break; case 's': /* Show only the full path; WHEREIS functionality */ bSuccinct = true; break; default: usage(true); break; } } } else { /* other arguments */ if(null == pattern) { pattern = arg; } else if(null == rootDir) { rootDir = arg; } else { usage(true); } } } /* Search for files if neither files or directories specified/ * * Even though this is not necessary, because the recls API provides the * same interpretation, it's best to be explicit. */ if(0 == (flags & (Search.RECLS_F_FILES | Search.RECLS_F_DIRECTORIES))) { flags |= Search.RECLS_F_FILES; } try { int total = 0; Search search = Search.MakeSearch(rootDir, pattern, flags); for(Enumeration en = search; en.hasMoreElements(); ++total) { Object el = en.nextElement(); System.out.println(el); if(!bSuccinct) { Entry entry = (Entry)el; System.out.println(" Path: " + entry.getPath()); System.out.println(" Drive: " + entry.getDrive()); System.out.println(" Directory: " + entry.getDirectory()); System.out.println(" DirectoryPath: " + entry.getDirectoryPath()); if((flags & Search.RECLS_F_DIRECTORY_PARTS) == Search.RECLS_F_DIRECTORY_PARTS) { String[] dirParts = entry.getDirectoryParts(); for(int j = 0; j < dirParts.length; ++j) { System.out.println(" " + dirParts[j]); } } System.out.println(" File: " + entry.getFile()); System.out.println(" ShortFile: " + entry.getShortFile()); System.out.println(" FileName: " + entry.getFileName()); System.out.println(" FileExtL " + entry.getFileExt()); System.out.println(" Size: " + entry.getSize()); System.out.println(" CreationTime: " + entry.getCreationTime()); System.out.println(" ModificationTime: " + entry.getModificationTime()); System.out.println(" LastAccessTime: " + entry.getLastAccessTime()); System.out.println(" LastStatusChangeTime: " + entry.getLastStatusChangeTime()); System.out.println(" isReadOnly: " + entry.isReadOnly()); System.out.println(" isDirectory: " + entry.isDirectory()); System.out.println(" isLink: " + entry.isLink()); } } search.Close(); System.out.println(" Total matched: " + total); } catch(ReclsException x) { System.out.println(x); } } private static void usage(boolean bExit) { System.err.println("recls Java Test Program: java_test\n"); System.err.println("Usage: java java_test [-d] [-f] [-d] [-R] [<pattern>] [<root-dir>]"); System.err.println("\t-d - search for directories"); System.err.println("\t-f - search for files. (default if neither f or d specified)"); System.err.println("\t-p - include directory parts in search, and display"); System.err.println("\t-R - does not recurse. (recursive search is the default)"); System.err.println("\t-s - succinct; shows only the path"); System.err.println("\t<pattern> - search pattern, e.g. \"*.cpp\" (default is to search for all files)"); System.err.println("\t<root-dir> - root directory of search; default is current working directory"); if(bExit) { System.exit(1); } } }
|
recls Library documentation © Synesis Software Pty Ltd, 2001-2004 |