## == Libraries to dynamically load ==
## ===================================
-SET(cpPlugins_DynLibs "${CMAKE_INSTALL_PREFIX}/bin|cpExtensions")
-LIST(APPEND cpPlugins_DynLibs "${CMAKE_INSTALL_PREFIX}/lib|cpExtensions")
-LIST(APPEND cpPlugins_DynLibs "${LIBRARY_OUTPUT_PATH}|cpExtensions")
+SET(_pre ${CMAKE_SHARED_LIBRARY_PREFIX})
+SET(_suf ${CMAKE_SHARED_LIBRARY_SUFFIX})
+
+SET(cpPlugins_DynLibs "${CMAKE_INSTALL_PREFIX}/bin/${_pre}cpExtensions${_suf}")
+LIST(APPEND cpPlugins_DynLibs "${CMAKE_INSTALL_PREFIX}/lib/${_pre}cpExtensions${_suf}")
+LIST(APPEND cpPlugins_DynLibs "${LIBRARY_OUTPUT_PATH}/${_pre}cpExtensions${_suf}")
FOREACH(_lib ${cpPlugins_Instances})
- LIST(APPEND cpPlugins_DynLibs "${CMAKE_INSTALL_PREFIX}/bin|${_lib}")
- LIST(APPEND cpPlugins_DynLibs "${CMAKE_INSTALL_PREFIX}/lib|${_lib}")
- LIST(APPEND cpPlugins_DynLibs "${LIBRARY_OUTPUT_PATH}|${_lib}")
+ LIST(APPEND cpPlugins_DynLibs "${CMAKE_INSTALL_PREFIX}/bin/${_pre}${_lib}${_suf}")
+ LIST(APPEND cpPlugins_DynLibs "${CMAKE_INSTALL_PREFIX}/lib/${_pre}${_lib}${_suf}")
+ LIST(APPEND cpPlugins_DynLibs "${LIBRARY_OUTPUT_PATH}/${_pre}${_lib}${_suf}")
ENDFOREACH(_lib)
-LIST(APPEND cpPlugins_DynLibs "${VTK_INSTALL_PREFIX}/bin|vtk*")
-LIST(APPEND cpPlugins_DynLibs "${VTK_INSTALL_PREFIX}/lib|vtk*")
-LIST(APPEND cpPlugins_DynLibs "${ITK_INSTALL_PREFIX}/bin|itk*")
-LIST(APPEND cpPlugins_DynLibs "${ITK_INSTALL_PREFIX}/lib|itk*")
-LIST(APPEND cpPlugins_DynLibs "${ITK_INSTALL_PREFIX}/bin|ITK*")
-LIST(APPEND cpPlugins_DynLibs "${ITK_INSTALL_PREFIX}/lib|ITK*")
+LIST(APPEND cpPlugins_DynLibs "${VTK_INSTALL_PREFIX}/bin/*vtk*${_suf}")
+LIST(APPEND cpPlugins_DynLibs "${VTK_INSTALL_PREFIX}/lib/*vtk*${_suf}")
+LIST(APPEND cpPlugins_DynLibs "${ITK_INSTALL_PREFIX}/bin/*itk*${_suf}")
+LIST(APPEND cpPlugins_DynLibs "${ITK_INSTALL_PREFIX}/lib/*itk*${_suf}")
+LIST(APPEND cpPlugins_DynLibs "${ITK_INSTALL_PREFIX}/bin/*ITK*${_suf}")
+LIST(APPEND cpPlugins_DynLibs "${ITK_INSTALL_PREFIX}/lib/*ITK*${_suf}")
FILE(WRITE ${PROJECT_BINARY_DIR}/cpPlugins_Libraries.config "")
FOREACH(_lib ${cpPlugins_DynLibs})
FILE(APPEND ${PROJECT_BINARY_DIR}/cpPlugins_Libraries.config "${_lib}\n")
+++ /dev/null
-/*
- * dirent.h - dirent API for Microsoft Visual Studio
- *
- * Copyright (C) 2006-2012 Toni Ronkko
- * Modified by Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * ``Software''), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * $Id: dirent.h,v 1.20 2014/03/19 17:52:23 tronkko Exp $
- */
-#ifndef __cpPlugins__dirent__h__
-#define __cpPlugins__dirent__h__
-
-// florez-l: use this file in windows environments
-#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
-
-/*
- * Define architecture flags so we don't need to include windows.h.
- * Avoiding windows.h makes it simpler to use windows sockets in conjunction
- * with dirent.h.
- */
-#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
-# define _X86_
-#endif
-#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
-#define _AMD64_
-#endif
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <windef.h>
-#include <winbase.h>
-#include <wchar.h>
-#include <string.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-/* Indicates that d_type field is available in dirent structure */
-#define ___cpPlugins__dirent__h__AVE_D_TYPE
-
-/* Indicates that d_namlen field is available in dirent structure */
-#define ___cpPlugins__dirent__h__AVE_D_NAMLEN
-
-/* Entries missing from MSVC 6.0 */
-#if !defined(FILE_ATTRIBUTE_DEVICE)
-# define FILE_ATTRIBUTE_DEVICE 0x40
-#endif
-
-/* File type and permission flags for stat() */
-#if !defined(S_IFMT)
-# define S_IFMT _S_IFMT /* File type mask */
-#endif
-#if !defined(S_IFDIR)
-# define S_IFDIR _S_IFDIR /* Directory */
-#endif
-#if !defined(S_IFCHR)
-# define S_IFCHR _S_IFCHR /* Character device */
-#endif
-#if !defined(S_IFFIFO)
-# define S_IFFIFO _S_IFFIFO /* Pipe */
-#endif
-#if !defined(S_IFREG)
-# define S_IFREG _S_IFREG /* Regular file */
-#endif
-#if !defined(S_IREAD)
-# define S_IREAD _S_IREAD /* Read permission */
-#endif
-#if !defined(S_IWRITE)
-# define S_IWRITE _S_IWRITE /* Write permission */
-#endif
-#if !defined(S_IEXEC)
-# define S_IEXEC _S_IEXEC /* Execute permission */
-#endif
-#if !defined(S_IFIFO)
-# define S_IFIFO _S_IFIFO /* Pipe */
-#endif
-#if !defined(S_IFBLK)
-# define S_IFBLK 0 /* Block device */
-#endif
-#if !defined(S_IFLNK)
-# define S_IFLNK 0 /* Link */
-#endif
-#if !defined(S_IFSOCK)
-# define S_IFSOCK 0 /* Socket */
-#endif
-
-#if defined(_MSC_VER)
-# define S_IRUSR S_IREAD /* Read user */
-# define S_IWUSR S_IWRITE /* Write user */
-# define S_IXUSR 0 /* Execute user */
-# define S_IRGRP 0 /* Read group */
-# define S_IWGRP 0 /* Write group */
-# define S_IXGRP 0 /* Execute group */
-# define S_IROTH 0 /* Read others */
-# define S_IWOTH 0 /* Write others */
-# define S_IXOTH 0 /* Execute others */
-#endif
-
-/* Maximum length of file name */
-#if !defined(PATH_MAX)
-# define PATH_MAX MAX_PATH
-#endif
-#if !defined(FILENAME_MAX)
-# define FILENAME_MAX MAX_PATH
-#endif
-#if !defined(NAME_MAX)
-# define NAME_MAX FILENAME_MAX
-#endif
-
-/* File type flags for d_type */
-#define DT_UNKNOWN 0
-#define DT_REG S_IFREG
-#define DT_DIR S_IFDIR
-#define DT_FIFO S_IFIFO
-#define DT_SOCK S_IFSOCK
-#define DT_CHR S_IFCHR
-#define DT_BLK S_IFBLK
-#define DT_LNK S_IFLNK
-
-/* Macros for converting between st_mode and d_type */
-#define IFTODT(mode) ((mode) & S_IFMT)
-#define DTTOIF(type) (type)
-
-/*
- * File type macros. Note that block devices, sockets and links cannot be
- * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
- * only defined for compatibility. These macros should always return false
- * on Windows.
- */
-#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
-#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
-#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
-#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
-#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
-#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
-#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
-
-/* Return the exact length of d_namlen without zero terminator */
-#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
-
-/* Return number of bytes needed to store d_namlen */
-#define _D_ALLOC_NAMLEN(p) (PATH_MAX)
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* Wide-character version */
-struct _wdirent {
- long d_ino; /* Always zero */
- unsigned short d_reclen; /* Structure size */
- size_t d_namlen; /* Length of name without \0 */
- int d_type; /* File type */
- wchar_t d_name[PATH_MAX]; /* File name */
-};
-typedef struct _wdirent _wdirent;
-
-struct _WDIR {
- struct _wdirent ent; /* Current directory entry */
- WIN32_FIND_DATAW data; /* Private file data */
- int cached; /* True if data is valid */
- HANDLE handle; /* Win32 search handle */
- wchar_t *patt; /* Initial directory name */
-};
-typedef struct _WDIR _WDIR;
-
-static _WDIR *_wopendir (const wchar_t *dirname);
-static struct _wdirent *_wreaddir (_WDIR *dirp);
-static int _wclosedir (_WDIR *dirp);
-static void _wrewinddir (_WDIR* dirp);
-
-
-/* For compatibility with Symbian */
-#define wdirent _wdirent
-#define WDIR _WDIR
-#define wopendir _wopendir
-#define wreaddir _wreaddir
-#define wclosedir _wclosedir
-#define wrewinddir _wrewinddir
-
-
-/* Multi-byte character versions */
-struct dirent {
- long d_ino; /* Always zero */
- unsigned short d_reclen; /* Structure size */
- size_t d_namlen; /* Length of name without \0 */
- int d_type; /* File type */
- char d_name[PATH_MAX]; /* File name */
-};
-typedef struct dirent dirent;
-
-struct DIR {
- struct dirent ent;
- struct _WDIR *wdirp;
-};
-typedef struct DIR DIR;
-
-static DIR *opendir (const char *dirname);
-static struct dirent *readdir (DIR *dirp);
-static int closedir (DIR *dirp);
-static void rewinddir (DIR* dirp);
-
-
-/* Internal utility functions */
-static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
-static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
-
-static int dirent_mbstowcs_s(
- size_t *pReturnValue,
- wchar_t *wcstr,
- size_t sizeInWords,
- const char *mbstr,
- size_t count);
-
-static int dirent_wcstombs_s(
- size_t *pReturnValue,
- char *mbstr,
- size_t sizeInBytes,
- const wchar_t *wcstr,
- size_t count);
-
-static void dirent_set_errno (int error);
-
-/*
- * Open directory stream DIRNAME for read and return a pointer to the
- * internal working area that is used to retrieve individual directory
- * entries.
- */
-static _WDIR*
-_wopendir(
- const wchar_t *dirname)
-{
- _WDIR *dirp = NULL;
- int error;
-
- /* Must have directory name */
- if (dirname == NULL || dirname[0] == '\0') {
- dirent_set_errno (ENOENT);
- return NULL;
- }
-
- /* Allocate new _WDIR structure */
- dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
- if (dirp != NULL) {
- DWORD n;
-
- /* Reset _WDIR structure */
- dirp->handle = INVALID_HANDLE_VALUE;
- dirp->patt = NULL;
- dirp->cached = 0;
-
- /* Compute the length of full path plus zero terminator */
- n = GetFullPathNameW (dirname, 0, NULL, NULL);
-
- /* Allocate room for absolute directory name and search pattern */
- dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
- if (dirp->patt) {
-
- /*
- * Convert relative directory name to an absolute one. This
- * allows rewinddir() to function correctly even when current
- * working directory is changed between opendir() and rewinddir().
- */
- n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
- if (n > 0) {
- wchar_t *p;
-
- /* Append search pattern \* to the directory name */
- p = dirp->patt + n;
- if (dirp->patt < p) {
- switch (p[-1]) {
- case '\\':
- case '/':
- case ':':
- /* Directory ends in path separator, e.g. c:\temp\ */
- /*NOP*/;
- break;
-
- default:
- /* Directory name doesn't end in path separator */
- *p++ = '\\';
- }
- }
- *p++ = '*';
- *p = '\0';
-
- /* Open directory stream and retrieve the first entry */
- if (dirent_first (dirp)) {
- /* Directory stream opened successfully */
- error = 0;
- } else {
- /* Cannot retrieve first entry */
- error = 1;
- dirent_set_errno (ENOENT);
- }
-
- } else {
- /* Cannot retrieve full path name */
- dirent_set_errno (ENOENT);
- error = 1;
- }
-
- } else {
- /* Cannot allocate memory for search pattern */
- error = 1;
- }
-
- } else {
- /* Cannot allocate _WDIR structure */
- error = 1;
- }
-
- /* Clean up in case of error */
- if (error && dirp) {
- _wclosedir (dirp);
- dirp = NULL;
- }
-
- return dirp;
-}
-
-/*
- * Read next directory entry. The directory entry is returned in dirent
- * structure in the d_name field. Individual directory entries returned by
- * this function include regular files, sub-directories, pseudo-directories
- * "." and ".." as well as volume labels, hidden files and system files.
- */
-static struct _wdirent*
-_wreaddir(
- _WDIR *dirp)
-{
- WIN32_FIND_DATAW *datap;
- struct _wdirent *entp;
-
- /* Read next directory entry */
- datap = dirent_next (dirp);
- if (datap) {
- size_t n;
- DWORD attr;
-
- /* Pointer to directory entry to return */
- entp = &dirp->ent;
-
- /*
- * Copy file name as wide-character string. If the file name is too
- * long to fit in to the destination buffer, then truncate file name
- * to PATH_MAX characters and zero-terminate the buffer.
- */
- n = 0;
- while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
- entp->d_name[n] = datap->cFileName[n];
- n++;
- }
- dirp->ent.d_name[n] = 0;
-
- /* Length of file name excluding zero terminator */
- entp->d_namlen = n;
-
- /* File type */
- attr = datap->dwFileAttributes;
- if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
- entp->d_type = DT_CHR;
- } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
- entp->d_type = DT_DIR;
- } else {
- entp->d_type = DT_REG;
- }
-
- /* Reset dummy fields */
- entp->d_ino = 0;
- entp->d_reclen = sizeof (struct _wdirent);
-
- } else {
-
- /* Last directory entry read */
- entp = NULL;
-
- }
-
- return entp;
-}
-
-/*
- * Close directory stream opened by opendir() function. This invalidates the
- * DIR structure as well as any directory entry read previously by
- * _wreaddir().
- */
-static int
-_wclosedir(
- _WDIR *dirp)
-{
- int ok;
- if (dirp) {
-
- /* Release search handle */
- if (dirp->handle != INVALID_HANDLE_VALUE) {
- FindClose (dirp->handle);
- dirp->handle = INVALID_HANDLE_VALUE;
- }
-
- /* Release search pattern */
- if (dirp->patt) {
- free (dirp->patt);
- dirp->patt = NULL;
- }
-
- /* Release directory structure */
- free (dirp);
- ok = /*success*/0;
-
- } else {
- /* Invalid directory stream */
- dirent_set_errno (EBADF);
- ok = /*failure*/-1;
- }
- return ok;
-}
-
-/*
- * Rewind directory stream such that _wreaddir() returns the very first
- * file name again.
- */
-static void
-_wrewinddir(
- _WDIR* dirp)
-{
- if (dirp) {
- /* Release existing search handle */
- if (dirp->handle != INVALID_HANDLE_VALUE) {
- FindClose (dirp->handle);
- }
-
- /* Open new search handle */
- dirent_first (dirp);
- }
-}
-
-/* Get first directory entry (internal) */
-static WIN32_FIND_DATAW*
-dirent_first(
- _WDIR *dirp)
-{
- WIN32_FIND_DATAW *datap;
-
- /* Open directory and retrieve the first entry */
- dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
- if (dirp->handle != INVALID_HANDLE_VALUE) {
-
- /* a directory entry is now waiting in memory */
- datap = &dirp->data;
- dirp->cached = 1;
-
- } else {
-
- /* Failed to re-open directory: no directory entry in memory */
- dirp->cached = 0;
- datap = NULL;
-
- }
- return datap;
-}
-
-/* Get next directory entry (internal) */
-static WIN32_FIND_DATAW*
-dirent_next(
- _WDIR *dirp)
-{
- WIN32_FIND_DATAW *p;
-
- /* Get next directory entry */
- if (dirp->cached != 0) {
-
- /* A valid directory entry already in memory */
- p = &dirp->data;
- dirp->cached = 0;
-
- } else if (dirp->handle != INVALID_HANDLE_VALUE) {
-
- /* Get the next directory entry from stream */
- if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
- /* Got a file */
- p = &dirp->data;
- } else {
- /* The very last entry has been processed or an error occured */
- FindClose (dirp->handle);
- dirp->handle = INVALID_HANDLE_VALUE;
- p = NULL;
- }
-
- } else {
-
- /* End of directory stream reached */
- p = NULL;
-
- }
-
- return p;
-}
-
-/*
- * Open directory stream using plain old C-string.
- */
-static DIR*
-opendir(
- const char *dirname)
-{
- struct DIR *dirp;
- int error;
-
- /* Must have directory name */
- if (dirname == NULL || dirname[0] == '\0') {
- dirent_set_errno (ENOENT);
- return NULL;
- }
-
- /* Allocate memory for DIR structure */
- dirp = (DIR*) malloc (sizeof (struct DIR));
- if (dirp) {
- wchar_t wname[PATH_MAX];
- size_t n;
-
- /* Convert directory name to wide-character string */
- error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX);
- if (!error) {
-
- /* Open directory stream using wide-character name */
- dirp->wdirp = _wopendir (wname);
- if (dirp->wdirp) {
- /* Directory stream opened */
- error = 0;
- } else {
- /* Failed to open directory stream */
- error = 1;
- }
-
- } else {
- /*
- * Cannot convert file name to wide-character string. This
- * occurs if the string contains invalid multi-byte sequences or
- * the output buffer is too small to contain the resulting
- * string.
- */
- error = 1;
- }
-
- } else {
- /* Cannot allocate DIR structure */
- error = 1;
- }
-
- /* Clean up in case of error */
- if (error && dirp) {
- free (dirp);
- dirp = NULL;
- }
-
- return dirp;
-}
-
-/*
- * Read next directory entry.
- *
- * When working with text consoles, please note that file names returned by
- * readdir() are represented in the default ANSI code page while any output to
- * console is typically formatted on another code page. Thus, non-ASCII
- * characters in file names will not usually display correctly on console. The
- * problem can be fixed in two ways: (1) change the character set of console
- * to 1252 using chcp utility and use Lucida Console font, or (2) use
- * _cprintf function when writing to console. The _cprinf() will re-encode
- * ANSI strings to the console code page so many non-ASCII characters will
- * display correcly.
- */
-static struct dirent*
-readdir(
- DIR *dirp)
-{
- WIN32_FIND_DATAW *datap;
- struct dirent *entp;
-
- /* Read next directory entry */
- datap = dirent_next (dirp->wdirp);
- if (datap) {
- size_t n;
- int error;
-
- /* Attempt to convert file name to multi-byte string */
- error = dirent_wcstombs_s(
- &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
-
- /*
- * If the file name cannot be represented by a multi-byte string,
- * then attempt to use old 8+3 file name. This allows traditional
- * Unix-code to access some file names despite of unicode
- * characters, although file names may seem unfamiliar to the user.
- *
- * Be ware that the code below cannot come up with a short file
- * name unless the file system provides one. At least
- * VirtualBox shared folders fail to do this.
- */
- if (error && datap->cAlternateFileName[0] != '\0') {
- error = dirent_wcstombs_s(
- &n, dirp->ent.d_name, PATH_MAX,
- datap->cAlternateFileName, PATH_MAX);
- }
-
- if (!error) {
- DWORD attr;
-
- /* Initialize directory entry for return */
- entp = &dirp->ent;
-
- /* Length of file name excluding zero terminator */
- entp->d_namlen = n - 1;
-
- /* File attributes */
- attr = datap->dwFileAttributes;
- if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
- entp->d_type = DT_CHR;
- } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
- entp->d_type = DT_DIR;
- } else {
- entp->d_type = DT_REG;
- }
-
- /* Reset dummy fields */
- entp->d_ino = 0;
- entp->d_reclen = sizeof (struct dirent);
-
- } else {
- /*
- * Cannot convert file name to multi-byte string so construct
- * an errornous directory entry and return that. Note that
- * we cannot return NULL as that would stop the processing
- * of directory entries completely.
- */
- entp = &dirp->ent;
- entp->d_name[0] = '?';
- entp->d_name[1] = '\0';
- entp->d_namlen = 1;
- entp->d_type = DT_UNKNOWN;
- entp->d_ino = 0;
- entp->d_reclen = 0;
- }
-
- } else {
- /* No more directory entries */
- entp = NULL;
- }
-
- return entp;
-}
-
-/*
- * Close directory stream.
- */
-static int
-closedir(
- DIR *dirp)
-{
- int ok;
- if (dirp) {
-
- /* Close wide-character directory stream */
- ok = _wclosedir (dirp->wdirp);
- dirp->wdirp = NULL;
-
- /* Release multi-byte character version */
- free (dirp);
-
- } else {
-
- /* Invalid directory stream */
- dirent_set_errno (EBADF);
- ok = /*failure*/-1;
-
- }
- return ok;
-}
-
-/*
- * Rewind directory stream to beginning.
- */
-static void
-rewinddir(
- DIR* dirp)
-{
- /* Rewind wide-character string directory stream */
- _wrewinddir (dirp->wdirp);
-}
-
-/* Convert multi-byte string to wide character string */
-static int
-dirent_mbstowcs_s(
- size_t *pReturnValue,
- wchar_t *wcstr,
- size_t sizeInWords,
- const char *mbstr,
- size_t count)
-{
- int error;
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-
- /* Microsoft Visual Studio 2005 or later */
- error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
-
-#else
-
- /* Older Visual Studio or non-Microsoft compiler */
- size_t n;
-
- /* Convert to wide-character string (or count characters) */
- n = mbstowcs (wcstr, mbstr, sizeInWords);
- if (!wcstr || n < count) {
-
- /* Zero-terminate output buffer */
- if (wcstr && sizeInWords) {
- if (n >= sizeInWords) {
- n = sizeInWords - 1;
- }
- wcstr[n] = 0;
- }
-
- /* Length of resuting multi-byte string WITH zero terminator */
- if (pReturnValue) {
- *pReturnValue = n + 1;
- }
-
- /* Success */
- error = 0;
-
- } else {
-
- /* Could not convert string */
- error = 1;
-
- }
-
-#endif
-
- return error;
-}
-
-/* Convert wide-character string to multi-byte string */
-static int
-dirent_wcstombs_s(
- size_t *pReturnValue,
- char *mbstr,
- size_t sizeInBytes, /* max size of mbstr */
- const wchar_t *wcstr,
- size_t count)
-{
- int error;
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-
- /* Microsoft Visual Studio 2005 or later */
- error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
-
-#else
-
- /* Older Visual Studio or non-Microsoft compiler */
- size_t n;
-
- /* Convert to multi-byte string (or count the number of bytes needed) */
- n = wcstombs (mbstr, wcstr, sizeInBytes);
- if (!mbstr || n < count) {
-
- /* Zero-terminate output buffer */
- if (mbstr && sizeInBytes) {
- if (n >= sizeInBytes) {
- n = sizeInBytes - 1;
- }
- mbstr[n] = '\0';
- }
-
- /* Lenght of resulting multi-bytes string WITH zero-terminator */
- if (pReturnValue) {
- *pReturnValue = n + 1;
- }
-
- /* Success */
- error = 0;
-
- } else {
-
- /* Cannot convert string */
- error = 1;
-
- }
-
-#endif
-
- return error;
-}
-
-/* Set errno variable */
-static void
-dirent_set_errno(
- int error)
-{
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-
- /* Microsoft Visual Studio 2005 and later */
- _set_errno (error);
-
-#else
-
- /* Non-Microsoft compiler or older Microsoft compiler */
- errno = error;
-
-#endif
-}
-
-
-#ifdef __cplusplus
-}
-#endif
-
-// florez-l: use the standard linux header
-#else // defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
-# include <sys/types.h>
-# include <dirent.h>
-#endif // defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
-
-#endif /*__cpPlugins__dirent__h__*/
-
#include <cpPlugins/Interface/Plugins.h>
#include <cpPlugins/OS/DLLManager.h>
-#include <cpPlugins/Interface/Dirent.h>
+#include <cpPlugins/OS/DirContents.h>
#include <cpExtensions/Utility.h>
-#include <regex>
// -------------------------------------------------------------------------
cpPlugins::Interface::Plugins::
std::istringstream input( buffer );
for( std::string line; std::getline( input, line ); )
{
- std::vector< std::string > tokens;
- cpExtensions::Tokenize( tokens, line, "|" );
- if( tokens.size( ) == 2 )
+ auto pos = line.find( "*" );
+ if( pos != std::string::npos )
{
- std::string pth = tokens[ 0 ];
- std::string lib = tokens[ 1 ];
- if( lib.find( "*" ) != std::string::npos )
- {
- std::string ext( cpPlugins_LIB_EXT );
- DIR* dir;
- struct dirent* ent;
- if( ( dir = opendir( pth.c_str( ) ) ) != NULL )
- {
- while( ( ent = readdir( dir ) ) != NULL )
- {
- std::string fname( ent->d_name );
- long pos = long( fname.size( ) ) - long( ext.size( ) );
- if( pos > 0 )
- {
- if( fname.substr( pos ) == ext )
- {
- std::regex re( lib );
- std::smatch match;
- if( std::regex_search( fname, match, re ) && match.size( ) >= 1 )
- {
- std::stringstream str;
- str
- << pth << cpPlugins_PATH_SEPARATOR << fname;
- libs.insert( str.str( ) );
- } // fi
-
- } // fi
-
- } // fi
-
- } // elihw
- closedir( dir );
-
- } // fi
- }
- else
- {
- std::stringstream str;
- str
- << pth << cpPlugins_PATH_SEPARATOR << cpPlugins_LIB_PREFIX
- << lib << cpPlugins_LIB_EXT;
- libs.insert( str.str( ) );
-
- } // fi
-
- } // fi
+ std::string dname, fname;
+ cpPlugins::OS::SplitPath( dname, fname, line );
+ auto files = cpPlugins::OS::LoadDirContents( dname, false, fname );
+ for( auto fIt = files.begin( ); fIt != files.end( ); ++fIt )
+ libs.insert( *fIt );
+ }
+ else
+ libs.insert( line );
} // rof
} // fi
} // rof
+
for( auto l = libs.begin( ); l != libs.end( ); ++l )
{
std::string lib = cpExtensions::CanonicalPath( *l );
// Get filter creator
TCreator creator = ( TCreator )(
- cpPlugins::OS::DLLManager::GetFunctionHandle( hnd, category + "_" + name )
+ cpPlugins::OS::DLLManager::GetFunctionHandle(
+ hnd, category + "_" + name
+ )
);
if( creator == NULL )
{
void cpPlugins::Interface::Plugins::
LoadDirectory( const std::string& dirname )
{
- DIR* dir;
- struct dirent* ent;
- if( ( dir = opendir( dirname.c_str( ) ) ) != NULL )
+ std::stringstream pat;
+ pat << "*" << cpPlugins_LIB_EXT;
+ auto libs = cpPlugins::OS::LoadDirContents( dirname, false, pat.str( ) );
+ for( auto lIt = libs.begin( ); lIt != libs.end( ); ++lIt )
{
- while( ( ent = readdir( dir ) ) != NULL )
+ try
{
- try
- {
- std::stringstream fname;
- fname << dirname << cpExtensions_PATH_SEPARATOR << ent->d_name;
- this->LoadFile( fname.str( ) );
- }
- catch( ... ) { }
-
- } // elihw
- closedir( dir );
- }
- else
- throw std::runtime_error(
- std::string( "Could not load directory " ) +
- std::string( "\"" ) + dirname + std::string( "\"" )
- );
+ this->LoadFile( *lIt );
+ }
+ catch( ... ) { }
+
+ } // rof
}
// -------------------------------------------------------------------------
--- /dev/null
+#include <cpPlugins/OS/DirContents.h>
+#include <cpPlugins/OS/tinydir.h>
+#include <sstream>
+
+// -------------------------------------------------------------------------
+std::set< std::string > cpPlugins::OS::
+LoadDirContents(
+ const std::string& path, bool recursive, const std::string& pattern
+ )
+{
+ // Prepare inputs and outputs
+ std::stringstream path_stream;
+ path_stream << path << cpPlugins_PATH_SEPARATOR;
+ std::string path_str = path_stream.str( );
+ std::set< std::string > output;
+
+ // Process data
+ tinydir_dir dir;
+ if( tinydir_open_sorted( &dir, path.c_str( ) ) != -1 )
+ {
+ for( auto i = 0; i < dir.n_files; i++ )
+ {
+ tinydir_file file;
+ if( tinydir_readfile_n( &dir, &file , i ) != -1 )
+ {
+ std::string fname = path_str + file.name;
+ if( file.is_dir )
+ {
+ if( recursive )
+ {
+ if( fname != "." && fname != ".." )
+ {
+ auto tmp = cpPlugins::OS::LoadDirContents( fname, true );
+ output.insert( tmp.begin( ), tmp.end( ) );
+
+ } // fi
+
+ } // fi
+ }
+ else
+ {
+ if( pattern != "" )
+ {
+ if( cpPlugins::OS::Glob( fname, pattern ) )
+ output.insert( fname );
+ }
+ else
+ output.insert( fname );
+
+ } // fi
+
+ } // fi
+
+ } // rof
+
+ } // fi
+ tinydir_close( &dir );
+ return( output );
+}
+
+// ------------------------------------------------------------------------
+void cpPlugins::OS::
+SplitPath( std::string& dname, std::string& fname, const std::string& path )
+{
+ auto found = path.find_last_of( "/\\" );
+ dname = path.substr( 0, found );
+ fname = path.substr( found + 1 );
+}
+
+// ------------------------------------------------------------------------
+int cpPlugins::OS::
+GlobMatch( const char* target, const char* pattern )
+{
+ char* pat = const_cast< char* >( pattern );
+ char* end = strchr( pat, ']' );
+ char* ptr;
+ if( *pat == '[' && end != NULL )
+ {
+ if( end == pat + 1 )
+ {
+ end = strchr( pat + 2, ']' );
+ if( end == NULL )
+ return( 0 );
+
+ } // fi
+
+ if( end - pat == 4 && pat[ 2 ] == '-' && pat[ 1 ] <= pattern[ 3 ] )
+ {
+ if( *target >= pat[ 1 ] && *target <= pat[ 3 ] )
+ return( 5 );
+ else
+ return( 0 );
+
+ } // fi
+
+ ptr = strchr( pat + 1, *target );
+ if( ptr != NULL && ptr < end )
+ return( end - pat + 1 );
+ else
+ return( 0 );
+
+ } // fi
+
+ if( *pat == '?' && *target != 0 )
+ return( 1 );
+ if( *pat == '*' )
+ return( 0 );
+ if( *target == 0 || *pat == 0 )
+ return( 0 );
+ if( *target == *pat )
+ return( 1 );
+ return( 0 );
+}
+
+// ------------------------------------------------------------------------
+bool cpPlugins::OS::
+Glob( const std::string& line, const std::string& pattern )
+{
+ const char* target = line.c_str( );
+ const char* pat = pattern.c_str( );
+ int gobble;
+
+ while( ( gobble = GlobMatch( target, pat ) ) )
+ {
+ target++;
+ pat += gobble;
+
+ } // elihw
+ if( *target == 0 && *pat == 0 )
+ return( true );
+ else if( *pat == '*' )
+ {
+ while( pat[ 1 ] == '*' )
+ pat++;
+ if( pat[ 1 ] == 0 )
+ return( true );
+ while( *target )
+ if( Glob( target++, pat + 1 ) )
+ return( 1 );
+
+ } // fi
+ return( false );
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __cpPlugins__OS__DirContents__h__
+#define __cpPlugins__OS__DirContents__h__
+
+#include <cpPlugins/Config.h>
+#include <set>
+#include <string>
+
+namespace cpPlugins
+{
+ namespace OS
+ {
+ /**
+ */
+ std::set< std::string > cpPlugins_EXPORT LoadDirContents(
+ const std::string& path, bool recursive,
+ const std::string& pattern = ""
+ );
+
+ /**
+ */
+ void cpPlugins_EXPORT SplitPath(
+ std::string& dname, std::string& fname,
+ const std::string& path
+ );
+
+ /**
+ */
+ int cpPlugins_EXPORT GlobMatch( const char* target, const char* pattern );
+
+ /**
+ */
+ bool cpPlugins_EXPORT Glob(
+ const std::string& line, const std::string& pattern
+ );
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __cpPlugins__OS__DirContents__h__
+
+// eof - $RCSfile$
--- /dev/null
+/*
+Copyright (c) 2013-2016, tinydir authors:
+- Cong Xu
+- Lautis Sun
+- Baudouin Feildel
+- Andargor <andargor@yahoo.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 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.
+*/
+#ifndef TINYDIR_H
+#define TINYDIR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if ((defined _UNICODE) && !(defined UNICODE))
+#define UNICODE
+#endif
+
+#if ((defined UNICODE) && !(defined _UNICODE))
+#define _UNICODE
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _MSC_VER
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <tchar.h>
+# pragma warning(push)
+# pragma warning (disable : 4996)
+#else
+# include <dirent.h>
+# include <libgen.h>
+# include <sys/stat.h>
+# include <stddef.h>
+#endif
+#ifdef __MINGW32__
+# include <tchar.h>
+#endif
+
+
+/* types */
+
+/* Windows UNICODE wide character support */
+#if defined _MSC_VER || defined __MINGW32__
+#define _tinydir_char_t TCHAR
+#define TINYDIR_STRING(s) _TEXT(s)
+#define _tinydir_strlen _tcslen
+#define _tinydir_strcpy _tcscpy
+#define _tinydir_strcat _tcscat
+#define _tinydir_strcmp _tcscmp
+#define _tinydir_strrchr _tcsrchr
+#define _tinydir_strncmp _tcsncmp
+#else
+#define _tinydir_char_t char
+#define TINYDIR_STRING(s) s
+#define _tinydir_strlen strlen
+#define _tinydir_strcpy strcpy
+#define _tinydir_strcat strcat
+#define _tinydir_strcmp strcmp
+#define _tinydir_strrchr strrchr
+#define _tinydir_strncmp strncmp
+#endif
+
+#if (defined _MSC_VER || defined __MINGW32__)
+#include <windows.h>
+#define _TINYDIR_PATH_MAX MAX_PATH
+#elif defined __linux__
+#include <linux/limits.h>
+#define _TINYDIR_PATH_MAX PATH_MAX
+#else
+#define _TINYDIR_PATH_MAX 4096
+#endif
+
+#ifdef _MSC_VER
+/* extra chars for the "\\*" mask */
+# define _TINYDIR_PATH_EXTRA 2
+#else
+# define _TINYDIR_PATH_EXTRA 0
+#endif
+
+#define _TINYDIR_FILENAME_MAX 256
+
+#if (defined _MSC_VER || defined __MINGW32__)
+#define _TINYDIR_DRIVE_MAX 3
+#endif
+
+#ifdef _MSC_VER
+# define _TINYDIR_FUNC static __inline
+#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
+# define _TINYDIR_FUNC static __inline__
+#else
+# define _TINYDIR_FUNC static inline
+#endif
+
+/* readdir_r usage; define TINYDIR_USE_READDIR_R to use it (if supported) */
+#ifdef TINYDIR_USE_READDIR_R
+
+/* readdir_r is a POSIX-only function, and may not be available under various
+ * environments/settings, e.g. MinGW. Use readdir fallback */
+#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE ||\
+ _POSIX_SOURCE
+# define _TINYDIR_HAS_READDIR_R
+#endif
+#if _POSIX_C_SOURCE >= 200112L
+# define _TINYDIR_HAS_FPATHCONF
+# include <unistd.h>
+#endif
+#if _BSD_SOURCE || _SVID_SOURCE || \
+ (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
+# define _TINYDIR_HAS_DIRFD
+# include <sys/types.h>
+#endif
+#if defined _TINYDIR_HAS_FPATHCONF && defined _TINYDIR_HAS_DIRFD &&\
+ defined _PC_NAME_MAX
+# define _TINYDIR_USE_FPATHCONF
+#endif
+#if defined __MINGW32__ || !defined _TINYDIR_HAS_READDIR_R ||\
+ !(defined _TINYDIR_USE_FPATHCONF || defined NAME_MAX)
+# define _TINYDIR_USE_READDIR
+#endif
+
+/* Use readdir by default */
+#else
+# define _TINYDIR_USE_READDIR
+#endif
+
+/* MINGW32 has two versions of dirent, ASCII and UNICODE*/
+#ifndef _MSC_VER
+#if (defined __MINGW32__) && (defined _UNICODE)
+#define _TINYDIR_DIR _WDIR
+#define _tinydir_dirent _wdirent
+#define _tinydir_opendir _wopendir
+#define _tinydir_readdir _wreaddir
+#define _tinydir_closedir _wclosedir
+#else
+#define _TINYDIR_DIR DIR
+#define _tinydir_dirent dirent
+#define _tinydir_opendir opendir
+#define _tinydir_readdir readdir
+#define _tinydir_closedir closedir
+#endif
+#endif
+
+/* Allow user to use a custom allocator by defining _TINYDIR_MALLOC and _TINYDIR_FREE. */
+#if defined(_TINYDIR_MALLOC) && defined(_TINYDIR_FREE)
+#elif !defined(_TINYDIR_MALLOC) && !defined(_TINYDIR_FREE)
+#else
+#error "Either define both alloc and free or none of them!"
+#endif
+
+#if !defined(_TINYDIR_MALLOC)
+ #define _TINYDIR_MALLOC(_size) malloc(_size)
+ #define _TINYDIR_FREE(_ptr) free(_ptr)
+#endif /* !defined(_TINYDIR_MALLOC) */
+
+typedef struct tinydir_file
+{
+ _tinydir_char_t path[_TINYDIR_PATH_MAX];
+ _tinydir_char_t name[_TINYDIR_FILENAME_MAX];
+ _tinydir_char_t *extension;
+ int is_dir;
+ int is_reg;
+
+#ifndef _MSC_VER
+#ifdef __MINGW32__
+ struct _stat _s;
+#else
+ struct stat _s;
+#endif
+#endif
+} tinydir_file;
+
+typedef struct tinydir_dir
+{
+ _tinydir_char_t path[_TINYDIR_PATH_MAX];
+ int has_next;
+ size_t n_files;
+
+ tinydir_file *_files;
+#ifdef _MSC_VER
+ HANDLE _h;
+ WIN32_FIND_DATA _f;
+#else
+ _TINYDIR_DIR *_d;
+ struct _tinydir_dirent *_e;
+#ifndef _TINYDIR_USE_READDIR
+ struct _tinydir_dirent *_ep;
+#endif
+#endif
+} tinydir_dir;
+
+
+/* declarations */
+
+_TINYDIR_FUNC
+int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path);
+_TINYDIR_FUNC
+int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path);
+_TINYDIR_FUNC
+void tinydir_close(tinydir_dir *dir);
+
+_TINYDIR_FUNC
+int tinydir_next(tinydir_dir *dir);
+_TINYDIR_FUNC
+int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file);
+_TINYDIR_FUNC
+int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i);
+_TINYDIR_FUNC
+int tinydir_open_subdir_n(tinydir_dir *dir, size_t i);
+
+_TINYDIR_FUNC
+int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path);
+_TINYDIR_FUNC
+void _tinydir_get_ext(tinydir_file *file);
+_TINYDIR_FUNC
+int _tinydir_file_cmp(const void *a, const void *b);
+#ifndef _MSC_VER
+#ifndef _TINYDIR_USE_READDIR
+_TINYDIR_FUNC
+size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp);
+#endif
+#endif
+
+
+/* definitions*/
+
+_TINYDIR_FUNC
+int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path)
+{
+#ifndef _MSC_VER
+#ifndef _TINYDIR_USE_READDIR
+ int error;
+ int size; /* using int size */
+#endif
+#else
+ _tinydir_char_t path_buf[_TINYDIR_PATH_MAX];
+#endif
+ _tinydir_char_t *pathp;
+
+ if (dir == NULL || path == NULL || _tinydir_strlen(path) == 0)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ /* initialise dir */
+ dir->_files = NULL;
+#ifdef _MSC_VER
+ dir->_h = INVALID_HANDLE_VALUE;
+#else
+ dir->_d = NULL;
+#ifndef _TINYDIR_USE_READDIR
+ dir->_ep = NULL;
+#endif
+#endif
+ tinydir_close(dir);
+
+ _tinydir_strcpy(dir->path, path);
+ /* Remove trailing slashes */
+ pathp = &dir->path[_tinydir_strlen(dir->path) - 1];
+ while (pathp != dir->path && (*pathp == TINYDIR_STRING('\\') || *pathp == TINYDIR_STRING('/')))
+ {
+ *pathp = TINYDIR_STRING('\0');
+ pathp++;
+ }
+#ifdef _MSC_VER
+ _tinydir_strcpy(path_buf, dir->path);
+ _tinydir_strcat(path_buf, TINYDIR_STRING("\\*"));
+ dir->_h = FindFirstFile(path_buf, &dir->_f);
+ if (dir->_h == INVALID_HANDLE_VALUE)
+ {
+ errno = ENOENT;
+#else
+ dir->_d = _tinydir_opendir(path);
+ if (dir->_d == NULL)
+ {
+#endif
+ goto bail;
+ }
+
+ /* read first file */
+ dir->has_next = 1;
+#ifndef _MSC_VER
+#ifdef _TINYDIR_USE_READDIR
+ dir->_e = _tinydir_readdir(dir->_d);
+#else
+ /* allocate dirent buffer for readdir_r */
+ size = _tinydir_dirent_buf_size(dir->_d); /* conversion to int */
+ if (size == -1) return -1;
+ dir->_ep = (struct _tinydir_dirent*)_TINYDIR_MALLOC(size);
+ if (dir->_ep == NULL) return -1;
+
+ error = readdir_r(dir->_d, dir->_ep, &dir->_e);
+ if (error != 0) return -1;
+#endif
+ if (dir->_e == NULL)
+ {
+ dir->has_next = 0;
+ }
+#endif
+
+ return 0;
+
+bail:
+ tinydir_close(dir);
+ return -1;
+}
+
+_TINYDIR_FUNC
+int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path)
+{
+ /* Count the number of files first, to pre-allocate the files array */
+ size_t n_files = 0;
+ if (tinydir_open(dir, path) == -1)
+ {
+ return -1;
+ }
+ while (dir->has_next)
+ {
+ n_files++;
+ if (tinydir_next(dir) == -1)
+ {
+ goto bail;
+ }
+ }
+ tinydir_close(dir);
+
+ if (tinydir_open(dir, path) == -1)
+ {
+ return -1;
+ }
+
+ dir->n_files = 0;
+ dir->_files = (tinydir_file *)_TINYDIR_MALLOC(sizeof *dir->_files * n_files);
+ if (dir->_files == NULL)
+ {
+ goto bail;
+ }
+ while (dir->has_next)
+ {
+ tinydir_file *p_file;
+ dir->n_files++;
+
+ p_file = &dir->_files[dir->n_files - 1];
+ if (tinydir_readfile(dir, p_file) == -1)
+ {
+ goto bail;
+ }
+
+ if (tinydir_next(dir) == -1)
+ {
+ goto bail;
+ }
+
+ /* Just in case the number of files has changed between the first and
+ second reads, terminate without writing into unallocated memory */
+ if (dir->n_files == n_files)
+ {
+ break;
+ }
+ }
+
+ qsort(dir->_files, dir->n_files, sizeof(tinydir_file), _tinydir_file_cmp);
+
+ return 0;
+
+bail:
+ tinydir_close(dir);
+ return -1;
+}
+
+_TINYDIR_FUNC
+void tinydir_close(tinydir_dir *dir)
+{
+ if (dir == NULL)
+ {
+ return;
+ }
+
+ memset(dir->path, 0, sizeof(dir->path));
+ dir->has_next = 0;
+ dir->n_files = 0;
+ _TINYDIR_FREE(dir->_files);
+ dir->_files = NULL;
+#ifdef _MSC_VER
+ if (dir->_h != INVALID_HANDLE_VALUE)
+ {
+ FindClose(dir->_h);
+ }
+ dir->_h = INVALID_HANDLE_VALUE;
+#else
+ if (dir->_d)
+ {
+ _tinydir_closedir(dir->_d);
+ }
+ dir->_d = NULL;
+ dir->_e = NULL;
+#ifndef _TINYDIR_USE_READDIR
+ _TINYDIR_FREE(dir->_ep);
+ dir->_ep = NULL;
+#endif
+#endif
+}
+
+_TINYDIR_FUNC
+int tinydir_next(tinydir_dir *dir)
+{
+ if (dir == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ if (!dir->has_next)
+ {
+ errno = ENOENT;
+ return -1;
+ }
+
+#ifdef _MSC_VER
+ if (FindNextFile(dir->_h, &dir->_f) == 0)
+#else
+#ifdef _TINYDIR_USE_READDIR
+ dir->_e = _tinydir_readdir(dir->_d);
+#else
+ if (dir->_ep == NULL)
+ {
+ return -1;
+ }
+ if (readdir_r(dir->_d, dir->_ep, &dir->_e) != 0)
+ {
+ return -1;
+ }
+#endif
+ if (dir->_e == NULL)
+#endif
+ {
+ dir->has_next = 0;
+#ifdef _MSC_VER
+ if (GetLastError() != ERROR_SUCCESS &&
+ GetLastError() != ERROR_NO_MORE_FILES)
+ {
+ tinydir_close(dir);
+ errno = EIO;
+ return -1;
+ }
+#endif
+ }
+
+ return 0;
+}
+
+_TINYDIR_FUNC
+int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file)
+{
+ if (dir == NULL || file == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+#ifdef _MSC_VER
+ if (dir->_h == INVALID_HANDLE_VALUE)
+#else
+ if (dir->_e == NULL)
+#endif
+ {
+ errno = ENOENT;
+ return -1;
+ }
+ if (_tinydir_strlen(dir->path) +
+ _tinydir_strlen(
+#ifdef _MSC_VER
+ dir->_f.cFileName
+#else
+ dir->_e->d_name
+#endif
+ ) + 1 + _TINYDIR_PATH_EXTRA >=
+ _TINYDIR_PATH_MAX)
+ {
+ /* the path for the file will be too long */
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+ if (_tinydir_strlen(
+#ifdef _MSC_VER
+ dir->_f.cFileName
+#else
+ dir->_e->d_name
+#endif
+ ) >= _TINYDIR_FILENAME_MAX)
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ _tinydir_strcpy(file->path, dir->path);
+ _tinydir_strcat(file->path, TINYDIR_STRING("/"));
+ _tinydir_strcpy(file->name,
+#ifdef _MSC_VER
+ dir->_f.cFileName
+#else
+ dir->_e->d_name
+#endif
+ );
+ _tinydir_strcat(file->path, file->name);
+#ifndef _MSC_VER
+#ifdef __MINGW32__
+ if (_tstat(
+#else
+ if (stat(
+#endif
+ file->path, &file->_s) == -1)
+ {
+ return -1;
+ }
+#endif
+ _tinydir_get_ext(file);
+
+ file->is_dir =
+#ifdef _MSC_VER
+ !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
+#else
+ S_ISDIR(file->_s.st_mode);
+#endif
+ file->is_reg =
+#ifdef _MSC_VER
+ !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) ||
+ (
+ !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) &&
+ !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
+ !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) &&
+#ifdef FILE_ATTRIBUTE_INTEGRITY_STREAM
+ !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM) &&
+#endif
+#ifdef FILE_ATTRIBUTE_NO_SCRUB_DATA
+ !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA) &&
+#endif
+ !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) &&
+ !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY));
+#else
+ S_ISREG(file->_s.st_mode);
+#endif
+
+ return 0;
+}
+
+_TINYDIR_FUNC
+int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i)
+{
+ if (dir == NULL || file == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ if (i >= dir->n_files)
+ {
+ errno = ENOENT;
+ return -1;
+ }
+
+ memcpy(file, &dir->_files[i], sizeof(tinydir_file));
+ _tinydir_get_ext(file);
+
+ return 0;
+}
+
+_TINYDIR_FUNC
+int tinydir_open_subdir_n(tinydir_dir *dir, size_t i)
+{
+ _tinydir_char_t path[_TINYDIR_PATH_MAX];
+ if (dir == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ if (i >= dir->n_files || !dir->_files[i].is_dir)
+ {
+ errno = ENOENT;
+ return -1;
+ }
+
+ _tinydir_strcpy(path, dir->_files[i].path);
+ tinydir_close(dir);
+ if (tinydir_open_sorted(dir, path) == -1)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Open a single file given its path */
+_TINYDIR_FUNC
+int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path)
+{
+ tinydir_dir dir;
+ int result = 0;
+ int found = 0;
+ _tinydir_char_t dir_name_buf[_TINYDIR_PATH_MAX];
+ _tinydir_char_t file_name_buf[_TINYDIR_FILENAME_MAX];
+ _tinydir_char_t *dir_name;
+ _tinydir_char_t *base_name;
+#if (defined _MSC_VER || defined __MINGW32__)
+ _tinydir_char_t drive_buf[_TINYDIR_DRIVE_MAX];
+ _tinydir_char_t ext_buf[_TINYDIR_FILENAME_MAX];
+#endif
+
+ if (file == NULL || path == NULL || _tinydir_strlen(path) == 0)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ /* Get the parent path */
+#if (defined _MSC_VER || defined __MINGW32__)
+#if ((defined _MSC_VER) && (_MSC_VER >= 1400))
+ _tsplitpath_s(
+ path,
+ drive_buf, _TINYDIR_DRIVE_MAX,
+ dir_name_buf, _TINYDIR_FILENAME_MAX,
+ file_name_buf, _TINYDIR_FILENAME_MAX,
+ ext_buf, _TINYDIR_FILENAME_MAX);
+#else
+ _tsplitpath(
+ path,
+ drive_buf,
+ dir_name_buf,
+ file_name_buf,
+ ext_buf);
+#endif
+
+/* _splitpath_s not work fine with only filename and widechar support */
+#ifdef _UNICODE
+ if (drive_buf[0] == L'\xFEFE')
+ drive_buf[0] = '\0';
+ if (dir_name_buf[0] == L'\xFEFE')
+ dir_name_buf[0] = '\0';
+#endif
+
+ if (errno)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ /* Emulate the behavior of dirname by returning "." for dir name if it's
+ empty */
+ if (drive_buf[0] == '\0' && dir_name_buf[0] == '\0')
+ {
+ _tinydir_strcpy(dir_name_buf, TINYDIR_STRING("."));
+ }
+ /* Concatenate the drive letter and dir name to form full dir name */
+ _tinydir_strcat(drive_buf, dir_name_buf);
+ dir_name = drive_buf;
+ /* Concatenate the file name and extension to form base name */
+ _tinydir_strcat(file_name_buf, ext_buf);
+ base_name = file_name_buf;
+#else
+ _tinydir_strcpy(dir_name_buf, path);
+ dir_name = dirname(dir_name_buf);
+ _tinydir_strcpy(file_name_buf, path);
+ base_name =basename(file_name_buf);
+#endif
+
+ /* Open the parent directory */
+ if (tinydir_open(&dir, dir_name) == -1)
+ {
+ return -1;
+ }
+
+ /* Read through the parent directory and look for the file */
+ while (dir.has_next)
+ {
+ if (tinydir_readfile(&dir, file) == -1)
+ {
+ result = -1;
+ goto bail;
+ }
+ if (_tinydir_strcmp(file->name, base_name) == 0)
+ {
+ /* File found */
+ found = 1;
+ break;
+ }
+ tinydir_next(&dir);
+ }
+ if (!found)
+ {
+ result = -1;
+ errno = ENOENT;
+ }
+
+bail:
+ tinydir_close(&dir);
+ return result;
+}
+
+_TINYDIR_FUNC
+void _tinydir_get_ext(tinydir_file *file)
+{
+ _tinydir_char_t *period = _tinydir_strrchr(file->name, TINYDIR_STRING('.'));
+ if (period == NULL)
+ {
+ file->extension = &(file->name[_tinydir_strlen(file->name)]);
+ }
+ else
+ {
+ file->extension = period + 1;
+ }
+}
+
+_TINYDIR_FUNC
+int _tinydir_file_cmp(const void *a, const void *b)
+{
+ const tinydir_file *fa = (const tinydir_file *)a;
+ const tinydir_file *fb = (const tinydir_file *)b;
+ if (fa->is_dir != fb->is_dir)
+ {
+ return -(fa->is_dir - fb->is_dir);
+ }
+ return _tinydir_strncmp(fa->name, fb->name, _TINYDIR_FILENAME_MAX);
+}
+
+#ifndef _MSC_VER
+#ifndef _TINYDIR_USE_READDIR
+/*
+The following authored by Ben Hutchings <ben@decadent.org.uk>
+from https://womble.decadent.org.uk/readdir_r-advisory.html
+*/
+/* Calculate the required buffer size (in bytes) for directory *
+* entries read from the given directory handle. Return -1 if this *
+* this cannot be done. *
+* *
+* This code does not trust values of NAME_MAX that are less than *
+* 255, since some systems (including at least HP-UX) incorrectly *
+* define it to be a smaller value. */
+_TINYDIR_FUNC
+size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp)
+{
+ long name_max;
+ size_t name_end;
+ /* parameter may be unused */
+ (void)dirp;
+
+#if defined _TINYDIR_USE_FPATHCONF
+ name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
+ if (name_max == -1)
+#if defined(NAME_MAX)
+ name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
+#else
+ return (size_t)(-1);
+#endif
+#elif defined(NAME_MAX)
+ name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
+#else
+#error "buffer size for readdir_r cannot be determined"
+#endif
+ name_end = (size_t)offsetof(struct _tinydir_dirent, d_name) + name_max + 1;
+ return (name_end > sizeof(struct _tinydir_dirent) ?
+ name_end : sizeof(struct _tinydir_dirent));
+}
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+# if defined (_MSC_VER)
+# pragma warning(pop)
+# endif
+
+#endif
--- /dev/null
+Copyright (c) 2013-2016, tinydir authors:
+- Cong Xu
+- Lautis Sun
+- Baudouin Feildel
+- Andargor <andargor@yahoo.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 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.
--- /dev/null
+TinyDir
+=======
+[![Build Status](https://travis-ci.org/cxong/tinydir.svg?branch=master)](https://travis-ci.org/cxong/tinydir)[![Project Stats](https://www.openhub.net/p/tinydir/widgets/project_thin_badge.gif)](https://www.openhub.net/p/tinydir)
+
+Lightweight, portable and easy to integrate C directory and file reader. TinyDir wraps dirent for POSIX and FindFirstFile for Windows.
+
+Windows unicode is supported by defining `UNICODE` and `_UNICODE` before including `tinydir.h`.
+
+Example
+=======
+
+There are two methods. Error checking omitted:
+
+```C
+tinydir_dir dir;
+tinydir_open(&dir, "/path/to/dir");
+
+while (dir.has_next)
+{
+ tinydir_file file;
+ tinydir_readfile(&dir, &file);
+
+ printf("%s", file.name);
+ if (file.is_dir)
+ {
+ printf("/");
+ }
+ printf("\n");
+
+ tinydir_next(&dir);
+}
+
+tinydir_close(&dir);
+```
+
+```C
+tinydir_dir dir;
+int i;
+tinydir_open_sorted(&dir, "/path/to/dir");
+
+for (i = 0; i < dir.n_files; i++)
+{
+ tinydir_file file;
+ tinydir_readfile_n(&dir, &file, i);
+
+ printf("%s", file.name);
+ if (file.is_dir)
+ {
+ printf("/");
+ }
+ printf("\n");
+}
+
+tinydir_close(&dir);
+```
+
+See the `/samples` folder for more examples, including an interactive command-line directory navigator.
+
+Language
+========
+
+ANSI C, or C90.
+
+Platforms
+=========
+
+POSIX and Windows supported. Open to the possibility of supporting other platforms.
+
+License
+=======
+
+Simplified BSD; if you use tinydir you can comply by including `tinydir.h` or `COPYING` somewhere in your package.
+
+Known Limitations
+=================
+
+- Limited path and filename sizes
+- [Possible race condition bug if folder being read has changing content](https://github.com/cxong/tinydir/issues/13)