C/C++ User's Journal Synesis Software STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Test Programs

Introduction

Version 1.2.1 contains nine test programs.

C_Win32.c

This function uses the raw recls C API functions, implementing a recursive search for a given pattern, from a given directory

/* 
 * File:        C_Win32.c
 *
 * Purpose:     Implementation file for the C_Win32 project.
 *
 * Created:     15th August 2003
 * Updated:     24th November 2003
 *
 * 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. 
 *
 */

/* Remove this definition to use platform-specific aspects of the API */
#define RECLS_PURE_API

#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 */

#include <recls_assert.h>

#ifdef _MSC_VER
# include <crtdbg.h>
#endif /* _MSC_VER */

/* 
 * Macros
 */

#ifndef NUM_ELEMENTS
# define NUM_ELEMENTS(x)        (sizeof(x) / sizeof(0[(x)]))
#endif /* !NUM_ELEMENTS */

/* 
 * Forward declarations
 */

void usage(int bExit);

/* 
 * Main
 */

int main(int argc, char *argv[])
{
    int                 iRet        =   0;
    int                 i;
    char const          *pattern    =   NULL;
    char const          *rootDir    =   NULL;
    hrecls_t            hSrch;
    recls_rc_t          rc;
    recls_uint32_t      flags       =   RECLS_F_RECURSIVE;

    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;
                    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 == pattern)
    {
#if defined(RECLS_PLATFORM_IS_WIN32)
        pattern = "*.*";
#else
        pattern = "*";
#endif /* RECLS_PLATFORM_IS_WIN32 */
    }

    if(NULL == rootDir)
    {
        rootDir = ".";
    }

    /* Initiate the search. */
    rc = Recls_Search(rootDir, pattern, flags, &hSrch);

    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];

            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);
            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);
    }

#ifdef _MSC_VER
    /* Check that there are no leaks */
    _CrtDumpMemoryLeaks();
#endif /* _MSC_VER */

    return iRet;
}

/* 
 * Function implementations
 */

void usage(int bExit)
{
    fprintf(stderr, "recls C Test Program: C_Win32\n\n");
    fprintf(stderr, "Usage: Cpp_Win32 [-R] [<pattern>] [<root-dir>]\n");
    fprintf(stderr, "\t-R               -   does not recurse. (recursive search is the default)\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
 */

Cpp_UNIX.cpp

This function uses the recls C++ mapping classes, implementing a recursive search for a given pattern, from a given directory (UNIX platform)

/* 
 * File:        Cpp_UNIX.cpp
 *
 * Purpose:     Implementation file for the Cpp_UNIX project.
 *
 * Created:     16th August 2003
 * Updated:     24th November 2003
 *
 * 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. 
 *
 */

/* 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 */

#include <recls_assert.h>
#include <reclspp.h>
#include <reclspp_filesearch.h>

#ifdef _MSC_VER
# include <crtdbg.h>
#endif /* _MSC_VER */

#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_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
 */

//extern "C" void __stdcall Sleep(unsigned long);

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;

//      Sleep(100000);

    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;
                    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 == pattern)
    {
#if defined(RECLS_PLATFORM_IS_WIN32)
        pattern = "*.*";
#else
        pattern = "*";
#endif /* RECLS_PLATFORM_IS_WIN32 */
    }

    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();
            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
            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());
            printf("  %s\n", dirPath.c_str());
            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
            recls_assert(0 == strcmp(path.c_str(), pathCheck.c_str()));
            if(0 != strcmp(path.c_str(), pathCheck.c_str()))
            {
                fprintf(stderr, "Path is different from path components\n\tpath:  %s\n\tparts: %s\n\n", path.c_str(), pathCheck.c_str());

                abort();
            }
            recls_assert(dirPath == dir);
            if(dirPath != dir)
            {
                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);
    }

#ifdef _MSC_VER
    /* Check that there are no leaks */
    _CrtDumpMemoryLeaks();
#endif /* _MSC_VER */

    return iRet;
}

/* 
 * Function implementations
 */

void usage(int bExit)
{
    fprintf(stderr, "recls C++ Test Program: Cpp_UNIX\n\n");
    fprintf(stderr, "Usage: Cpp_UNIX [-R] [-p] [-d] [-f] [<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<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
 */

Cpp_Win32.cpp

This function uses the recls C++ mapping classes, implementing a recursive search for a given pattern, from a given directory (Win32 platform)

/* 
 * File:        Cpp_Win32.cpp
 *
 * Purpose:     Implementation file for the Cpp_Win32 project.
 *
 * Created:     16th August 2003
 * Updated:     24th November 2003
 *
 * 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. 
 *
 */

/* 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 */

#include <recls_assert.h>
#include <reclspp.h>
#include <reclspp_filesearch.h>

#ifdef _MSC_VER
# include <crtdbg.h>
#endif /* _MSC_VER */

#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;
    char const          *pattern    =   NULL;
    char const          *rootDir    =   NULL;
    recls_uint32_t      flags       =   RECLS_F_RECURSIVE;

    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;
                    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 == pattern)
    {
#if defined(RECLS_PLATFORM_IS_WIN32)
        pattern = "*.*";
#else
        pattern = "*";
#endif /* RECLS_PLATFORM_IS_WIN32 */
    }

    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;

            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());
            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");
            }
        }
    }

#ifdef _MSC_VER
    /* Check that there are no leaks */
    _CrtDumpMemoryLeaks();
#endif /* _MSC_VER */

    return iRet;
}

/* 
 * Function implementations
 */

void usage(int bExit)
{
    fprintf(stderr, "recls C++ Test Program: Cpp_Win32\n\n");
    fprintf(stderr, "Usage: Cpp_Win32 [-R] [-p] [-d] [-f] [<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<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
 */

STL_Win32.cpp

This function uses the recls STL mapping classes, implementing a recursive search for a given pattern, from a given directory

/* 
 * File:        STL_Win32.cpp
 *
 * Purpose:     Implementation file for the STL_Win32 project.
 *
 * Created:     16th August 2003
 * Updated:     24th November 2003
 *
 * 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. 
 *
 * 

// 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

#include <reclstl.h>
#include <reclstl_search_sequence.h>
#include <recls_assert.h>

#ifdef _MSC_VER
# include <crtdbg.h>
#endif /* _MSC_VER */

#include <iostream>
#include <iomanip>

#ifdef TAKE_COPIES_IN_VECTOR
# include <vector>

typedef std::vector<reclstl::search_sequence_a::value_type>     fileentry_t;
#endif /* TAKE_COPIES_IN_VECTOR */

/* 
 * Namespace
 */

using std::cout;
using std::cerr;
using std::endl;
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);

/* 
 * Main
 */

int main(int argc, char *argv[])
{
    int             iRet        =   0;
    int             i;
    char const      *pattern    =   NULL;
    char const      *rootDir    =   NULL;
    uint32_t        flags       =   RECLS_F_RECURSIVE;

    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;
                    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 == pattern)
    {
#if defined(RECLS_PLATFORM_IS_WIN32)
        pattern = "*.*";
#else
        pattern = "*";
#endif /* RECLS_PLATFORM_IS_WIN32 */
    }

    if(NULL == rootDir)
    {
        rootDir = ".";
    }

    {
        reclstl::basic_search_sequence<recls_char_t>    search(rootDir, pattern, flags);
#ifdef TAKE_COPIES_IN_VECTOR
        fileentry_t         entries;
#endif /* TAKE_COPIES_IN_VECTOR */

        reclstl::basic_search_sequence<recls_char_t>::const_iterator    begin   =   search.begin();
        reclstl::basic_search_sequence<recls_char_t>::const_iterator    end     =   search.end();

        for(; begin != end; ++begin)
        {
            using reclstl::string_t;

            reclstl::basic_search_sequence<recls_char_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;
            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 reclstl::basic_search_sequence<recls_char_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 << "    " << std::setw(off) << dirPart << std::setw(1) << endl;

                    pathCheck += dirPart;
                    dirCheck += dirPart;
                }
            }
            else
            {
                off += dir.length();
                pathCheck += dir;
            }

            off += file.length();
            cout << "    " << std::setw(off) << file << std::setw(1) << endl;
            if(fileExt.length() > 0)
            {
                cout << "    " << std::setw(off - (1 + fileExt.length())) << fileName << std::setw(1) << endl;
                cout << "    " << std::setw(off) << fileExt << std::setw(1) << endl;
            }
            else
            {
                cout << "    " << std::setw(off) << fileName << std::setw(1) << endl;
            }

            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 */
            {
                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 */
    }

#ifdef _MSC_VER
    _CrtDumpMemoryLeaks();
#endif /* _MSC_VER */

    return iRet;
}

/* 
 * Function implementations
 */

void usage(int bExit)
{
    cout << "recls C++ Test Program: STL_Win32" << endl << endl;
    cout << "Usage: STL_Win32 [-R] [<pattern>] [<root-dir>]" << endl;
    cout << "\t-R               -   does not recurse; recursive search is the default" << 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);
    }
}

/* 
 * End of file
 */

WinForm.cs

This function 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);
            }
        }
    }
}

recls_test_1.d

This function 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:     24th November 2003
 *
 * 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;

    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;
                    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);
            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_IsEntryReadOnly(entry))
            {
                printf("    - Read-only\n");
            }
            if(Search_IsEntryDirectory(entry))
            {
                printf("    - Directory\n");
            }
            else
            {
                printf("    - File\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] [-d] [-R] [<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<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
 */

recls_test_2.d

This function 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:     24th November 2003
 *
 * 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;

    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;
                    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);
            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_IsEntryReadOnly(entry))
            {
                printf("    - Read-only\n");
            }
            if(Search_IsEntryDirectory(entry))
            {
                printf("    - Directory\n");
            }
            else
            {
                printf("    - File\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] [-d] [-R] [<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<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
 */

recls_test.java

This function 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:     24th November 2003
 *
 * 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':    /* Find directories */
                            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<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-2003