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.0.1 contains two 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:     23rd September 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"
#include "recls_assert.h"

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

/* 
 * Macros
 */

#ifndef NUM_ELEMENTS
# define NUM_ELEMENTS(x)        (sizeof(x) / sizeof((x)[0]))
#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;
                    default:
                        usage(1);
                        break;
                }
            }
        }
        else
        {
            /* other arguments */
            if(NULL == pattern)
            {
                pattern = arg;
            }
            else if(NULL == rootDir)
            {
                rootDir = arg;
            }
            else
            {
                usage(1);
            }
        }
    }

    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))
    {
        char    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 */
        do
        {
            recls_info_t    info;

            rc = Recls_GetDetails(hSrch, &info);

            if(RECLS_FAILED(rc))
            {
                if(rc != RECLS_RC_NO_MORE_DATA)
                {
                    char    err[100];

                    Recls_GetErrorString(rc, err, 100);

                    fprintf(stderr, "Search terminated prematurely; recls error: %s\n", err);
                }

                break;
            }
            else
            {
                int     i;
                int     off;
                int     extLen;
                int     cDirParts;
                char    path[RECLS_PATH_MAX];
#ifdef RECLS_PLATFORM_API_WIN32
                char    drive;
#endif /* RECLS_PLATFORM_API_WIN32 */
                char    dir[RECLS_PATH_MAX];
                char    file[RECLS_PATH_MAX];
                char    fileName[RECLS_PATH_MAX];
                char    fileExt[RECLS_PATH_MAX];

                char    pathCheck[RECLS_PATH_MAX];
                char    dirCheck[RECLS_PATH_MAX];
                char    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);
#ifdef RECLS_PLATFORM_API_WIN32
                Recls_GetDriveProperty(info, &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);

                for(i = 0, off = 0, cDirParts = Recls_GetDirectoryPartProperty(info, -1, NULL, 0); i < cDirParts; ++i)
                {
                    char    dirPart[RECLS_PATH_MAX];

                    off += Recls_GetDirectoryPartProperty(info, i, dirPart, NUM_ELEMENTS(dirPart));
                    printf("    %*s\n", off, dirPart);

                    strcat(pathCheck, dirPart);
                    strcat(dirCheck, dirPart);
                }

                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 */
#ifdef RECLS_PLATFORM_API_WIN32
                recls_assert(0 == strcmp(path, pathCheck));
                if(0 != strcmp(path, pathCheck))
#else /* ? RECLS_PLATFORM_API_WIN32 */
                recls_assert(0 == strcmp(path + 2, pathCheck));
                if(0 != strcmp(path + 2, pathCheck))
#endif /* RECLS_PLATFORM_API_WIN32 */
                {
                    fprintf(stderr, "Path is different from path components\n\tpath:  %s\n\tparts: %s\n\n", path, pathCheck);

                    abort();
                }
                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");
                }
                if(Recls_IsFileLink(info))
                {
                    printf("    - Link\n");
                }

                Recls_CloseDetails(info);
            }

        } while(RECLS_SUCCEEDED(rc = Recls_GetNext(hSrch)));

        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.exe\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_Win32.cpp

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

/* 
 * File:        Cpp_Win32.cpp
 *
 * Purpose:     Implementation file for the Cpp_Win32 project.
 *
 * Created:     16th August 2003
 * Updated:     23rd September 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 defined(RECLS_STRICT) && \
    !defined(RECLS_COMPILER_IS_DMC)
# include <stlsoft_nulldef.h>
#endif /* RECLS_STRICT && !RECLS_COMPILER_IS_DMC */

#include <reclspp.h>
#include <reclspp_filesearch.h>
#include <recls_assert.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 */

/* 
 * Macros
 */

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

/* 
 * Namespace
 */

using recls::recls_uint32_t;
using recls::RECLS_F_RECURSIVE;

/* 
 * 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;
                    default:
                        usage(1);
                        break;
                }
            }
        }
        else
        {
            /* other arguments */
            if(NULL == pattern)
            {
                pattern = arg;
            }
            else if(NULL == rootDir)
            {
                rootDir = arg;
            }
            else
            {
                usage(1);
            }
        }
    }

    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, RECLS_F_RECURSIVE);
#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
            char                    drive       =   fileEntry.GetDrive();
#endif /* RECLS_PLATFORM_API_WIN32 */
            string_t                path        =   fileEntry.GetPath();
            string_t                dir         =   fileEntry.GetDirectory();
            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                dirCheck;
            string_t                fileCheck;

#ifdef TAKE_COPIES_IN_VECTOR
            entries.push_back(fileEntry);
#endif /* TAKE_COPIES_IN_VECTOR */

#ifdef _DEBUG
            {
                recls_uint32_t  cBlocks = search.GetNumOutstandingDetails();

                printf("\n%d outstanding block(s)\n", cBlocks);
            }
#endif /* _DEBUG */

            printf("  %s\n", path.c_str());
#ifdef RECLS_PLATFORM_API_WIN32
            printf("  %c\n", drive);
            pathCheck += drive;
            pathCheck += ':';
#endif /* RECLS_PLATFORM_API_WIN32 */
            printf("    %s\n", dir.c_str());

            int     i;
            int     off;
            int     cDirParts;

            for(i = 0, off = 0, cDirParts = dirParts.size(); i < cDirParts; ++i)
            {
                string_t    dirPart =   dirParts[i];

                off += dirPart.length();
                printf("    %*s\n", off, dirPart.c_str());

                pathCheck += dirPart;
                dirCheck += dirPart;
            }

            off += file.length();
            printf("    %*s\n", off, file.c_str());
            printf("    %*s\n", off - (1 + fileExt.length()), fileName.c_str());
            printf("    %*s\n", off, fileExt.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();
            }
            recls_assert(dir == dirCheck);
            if(dir != dirCheck)
            {
                fprintf(stderr, "Directory is different from directory components\n\tpath:  %s\n\tparts: %s\n\n", dir.c_str(), dirCheck.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");
            }
            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.exe\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
 */


recls Library documentation Synesis Software Pty Ltd, 2001-2003