82 #ifndef INCLUDED_SimpleGlob 83 #define INCLUDED_SimpleGlob 154 # include <mbstring.h> 155 # define sg_strchr ::_mbschr 156 # define sg_strrchr ::_mbsrchr 157 # define sg_strlen ::_mbslen 158 # if __STDC_WANT_SECURE_LIB__ 159 # define sg_strcpy_s(a,n,b) ::_mbscpy_s(a,n,b) 161 # define sg_strcpy_s(a,n,b) ::_mbscpy(a,b) 163 # define sg_strcmp ::_mbscmp 164 # define sg_strcasecmp ::_mbsicmp 165 # define SOCHAR_T unsigned char 167 # include <sys/types.h> 168 # include <sys/stat.h> 171 # define MAX_PATH PATH_MAX 172 # define sg_strchr ::strchr 173 # define sg_strrchr ::strrchr 174 # define sg_strlen ::strlen 175 # define sg_strcpy_s(a,n,b) ::strcpy(a,b) 176 # define sg_strcmp ::strcmp 177 # define sg_strcasecmp ::strcasecmp 178 # define SOCHAR_T char 189 # define SG_ASSERT(b) _ASSERTE(b) 192 # define SG_ASSERT(b) assert(b) 195 # define SG_ASSERT(b) 201 static const char *
strchr(
const char *s,
char c) {
203 }
static const wchar_t *
strchr(
const wchar_t *s,
wchar_t c) {
204 return::wcschr(s, c);
207 static const char *
strrchr(
const char *s,
char c) {
210 static const wchar_t *
strrchr(
const wchar_t *s,
wchar_t c) {
211 return::wcsrchr(s, c);
222 static void strcpy_s(
char *dst,
size_t n,
const char *src) {
226 static void strcpy_s(
wchar_t *dst,
size_t n,
const wchar_t *src) {
227 # if __STDC_WANT_SECURE_LIB__ 228 ::wcscpy_s(dst, n, src);
235 static int strcmp(
const char *s1,
const char *s2) {
238 static int strcmp(
const wchar_t *s1,
const wchar_t *s2) {
239 return::wcscmp(s1, s2);
246 static int strcasecmp(
const wchar_t *s1,
const wchar_t *s2) {
247 return::_wcsicmp(s1, s2);
260 #ifndef INVALID_FILE_ATTRIBUTES 261 # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) 264 #define SG_PATH_CHAR '\\' 269 }
int FindFirstFileS(
const char *a_pszFileSpec,
unsigned int) {
270 m_hFind = FindFirstFileA(a_pszFileSpec, &m_oFindDataA);
271 if (m_hFind != INVALID_HANDLE_VALUE) {
274 DWORD dwErr = GetLastError();
275 if (dwErr == ERROR_FILE_NOT_FOUND) {
280 int FindFirstFileS(
const wchar_t *a_pszFileSpec,
unsigned int) {
281 m_hFind = FindFirstFileW(a_pszFileSpec, &m_oFindDataW);
282 if (m_hFind != INVALID_HANDLE_VALUE) {
285 DWORD dwErr = GetLastError();
286 if (dwErr == ERROR_FILE_NOT_FOUND) {
292 bool FindNextFileS(
char) {
293 return FindNextFileA(m_hFind, &m_oFindDataA) !=
FALSE;
295 bool FindNextFileS(
wchar_t) {
296 return FindNextFileW(m_hFind, &m_oFindDataW) !=
FALSE;
303 const char *GetFileNameS(
char)
const {
304 return m_oFindDataA.cFileName;
306 const wchar_t *GetFileNameS(
wchar_t)
const {
307 return m_oFindDataW.cFileName;
309 bool IsDirS(
char)
const {
312 bool IsDirS(
wchar_t)
const {
316 return GetFileTypeS(GetFileAttributesA(a_pszPath));
318 SG_FileType GetFileTypeS(
const wchar_t *a_pszPath) {
319 return GetFileTypeS(GetFileAttributesW(a_pszPath));
321 SG_FileType GetFileTypeS(DWORD a_dwAttribs)
const {
322 if (a_dwAttribs == INVALID_FILE_ATTRIBUTES) {
325 if (a_dwAttribs & FILE_ATTRIBUTE_DIRECTORY) {
333 WIN32_FIND_DATAA m_oFindDataA;
334 WIN32_FIND_DATAW m_oFindDataW;
339 #define SG_PATH_CHAR '/' 344 memset(&m_glob, 0,
sizeof(m_glob));
345 m_uiCurr = (size_t) -1;
352 size_t len =
strlen(m_glob.gl_pathv[m_uiCurr]);
353 if (m_glob.gl_pathv[m_uiCurr][len - 1] ==
'/') {
355 m_glob.gl_pathv[m_uiCurr][len - 1] = 0;
360 int nFlags = GLOB_MARK | GLOB_NOSORT;
365 nFlags |= GLOB_TILDE;
367 int rc = glob(a_pszFileSpec, nFlags, NULL, &m_glob);
368 if (rc == GLOB_NOSPACE)
370 if (rc == GLOB_ABORTED)
372 if (rc == GLOB_NOMATCH)
381 if (++m_uiCurr >= m_glob.gl_pathc) {
390 memset(&m_glob, 0,
sizeof(m_glob));
391 m_uiCurr = (size_t) -1;
396 return m_glob.gl_pathv[m_uiCurr];
404 if (0 != stat(a_pszPath, &sb)) {
407 if (S_ISDIR(sb.st_mode)) {
410 if (S_ISREG(sb.st_mode)) {
458 int Init(
unsigned int a_uiFlags = 0,
int a_nReservedSlots = 0);
473 int Add(
const SOCHAR * a_pszFileSpec);
489 int Add(
int a_nCount,
const SOCHAR *
const *a_rgpszFileSpec);
497 SetArgvArrayType(POINTERS);
519 int AppendName(
const SOCHAR * a_pszFileName,
bool a_bIsDir);
522 bool GrowArgvArray(
int a_nNewLen);
525 bool GrowStringBuffer(
size_t a_uiMinSize);
528 static int fileSortCompare(
const void *a1,
const void *a2);
554 Init(a_uiFlags, a_nReservedSlots);
567 m_nArgArrayType = POINTERS;
568 m_uiFlags = a_uiFlags;
569 m_nArgsLen = a_nReservedSlots;
570 m_nReservedSlots = a_nReservedSlots;
573 if (m_nReservedSlots > 0) {
574 if (!GrowArgvArray(m_nReservedSlots)) {
577 for (
int n = 0; n < m_nReservedSlots; ++n) {
598 a_pszFileSpec = szFileSpec;
602 m_szPathPrefix[0] = 0;
607 return AppendName(a_pszFileSpec,
false);
619 m_szPathPrefix[pszFilename - a_pszFileSpec + 1] = 0;
624 int rc = FindFirstFileS(a_pszFileSpec, m_uiFlags);
627 int ok = AppendName(a_pszFileSpec,
false);
634 int nError, nStartLen = m_nArgsLen;
637 nError = AppendName(GetFileNameS((SOCHAR) 0), IsDirS((SOCHAR) 0));
638 bSuccess = FindNextFileS((SOCHAR) 0);
646 nStartLen = m_nReservedSlots;
648 SetArgvArrayType(POINTERS);
649 qsort(m_rgpArgs + nStartLen, m_nArgsLen - nStartLen,
sizeof(m_rgpArgs[0]), fileSortCompare);
658 for (
int n = 0; n < a_nCount; ++n) {
659 nResult = Add(a_rgpszFileSpec[n]);
670 SetArgvArrayType(OFFSETS);
680 if (a_pszFileName[0] ==
'.') {
681 if (a_pszFileName[1] ==
'\0') {
684 if (a_pszFileName[1] ==
'.' && a_pszFileName[2] ==
'\0') {
690 if (!GrowArgvArray(m_nArgsLen + 1)) {
696 if (a_bIsDir && (m_uiFlags &
SG_GLOB_MARK) == SG_GLOB_MARK) {
699 if (!GrowStringBuffer(m_uiBufferLen + uiLen)) {
703 m_rgpArgs[m_nArgsLen++] = (SOCHAR *) m_uiBufferLen;
705 SimpleGlobUtil::strcpy_s(m_pBuffer + m_uiBufferLen + uiPrefixLen, m_uiBufferSize - m_uiBufferLen - uiPrefixLen, a_pszFileName);
706 m_uiBufferLen += uiLen;
709 if (a_bIsDir && (m_uiFlags & SG_GLOB_MARK) == SG_GLOB_MARK) {
719 if (m_nArgArrayType == a_nNewType)
721 if (a_nNewType == POINTERS) {
723 for (
int n = 0; n < m_nArgsLen; ++n) {
724 m_rgpArgs[n] = (m_rgpArgs[n] == (SOCHAR *) - 1) ? NULL : m_pBuffer + (size_t) m_rgpArgs[n];
729 for (
int n = 0; n < m_nArgsLen; ++n) {
730 m_rgpArgs[n] = (m_rgpArgs[n] == NULL) ? (SOCHAR *) - 1 : (SOCHAR *) (m_rgpArgs[n] - m_pBuffer);
733 m_nArgArrayType = a_nNewType;
738 if (a_nNewLen >= m_nArgsSize) {
739 static const int SG_ARGV_INITIAL_SIZE = 32;
740 int nNewSize = (m_nArgsSize > 0) ? m_nArgsSize * 2 : SG_ARGV_INITIAL_SIZE;
741 while (a_nNewLen >= nNewSize) {
744 void *pNewBuffer = realloc(m_rgpArgs, nNewSize *
sizeof(SOCHAR *));
747 m_nArgsSize = nNewSize;
748 m_rgpArgs = (SOCHAR **) pNewBuffer;
755 if (a_uiMinSize >= m_uiBufferSize) {
756 static const int SG_BUFFER_INITIAL_SIZE = 1024;
757 size_t uiNewSize = (m_uiBufferSize > 0) ? m_uiBufferSize * 2 : SG_BUFFER_INITIAL_SIZE;
758 while (a_uiMinSize >= uiNewSize) {
761 void *pNewBuffer = realloc(m_pBuffer, uiNewSize *
sizeof(SOCHAR));
764 m_uiBufferSize = uiNewSize;
765 m_pBuffer = (SOCHAR *) pNewBuffer;
772 const SOCHAR *s1 = *(
const SOCHAR **) a1;
773 const SOCHAR *s2 = *(
const SOCHAR **) a2;
778 return s1 == s2 ? 0 : (s1 ? 1 : -1);
787 #if defined(_UNICODE) 788 # define CSimpleGlob CSimpleGlobW 790 # define CSimpleGlob CSimpleGlobA 793 #endif // INCLUDED_SimpleGlob size_t m_uiBufferSize
allocated size of buffer
SG_FileType GetFileTypeS(const char *a_pszPath) const
Implementation of the SimpleGlob class.
static size_t strlen(const char *s)
SG_Flags
The operation of SimpleGlob is fine-tuned via the use of a combination of the following flags...
static const wchar_t * strchr(const wchar_t *s, wchar_t c)
SOCHAR ** Files()
Return the full argv array.
static const char * strrchr(const char *s, char c)
SOCHAR * m_pBuffer
argv string buffer
static int strcasecmp(const char *s1, const char *s2)
#define sg_strcpy_s(a, n, b)
int m_nArgsSize
allocated size of array
static int strcmp(const char *s1, const char *s2)
static void strcpy_s(char *dst, size_t n, const char *src)
CSimpleGlobTempl< wchar_t > CSimpleGlobW
wchar_t version of CSimpleGlob
ARG_ARRAY_TYPE
The argv array has it's members stored as either an offset into the string buffer, or as pointers to their string in the buffer. The offsets are used because if the string buffer is dynamically resized, all pointers into that buffer would become invalid.
String manipulation functions.
static void strcpy_s(wchar_t *dst, size_t n, const wchar_t *src)
static size_t strlen(const wchar_t *s)
CSimpleGlobTempl< char > CSimpleGlobA
ASCII/MBCS version of CSimpleGlob.
int FileCount() const
Return the number of files in the argv array.
static const char * strchr(const char *s, char c)
int m_nReservedSlots
number of client reserved slots in the argv array
int m_nArgsLen
used length
int FindFirstFileS(const char *a_pszFileSpec, unsigned int a_uiFlags)
SG_Error
Error return codes.
static int strcmp(const wchar_t *s1, const wchar_t *s2)
size_t m_uiBufferLen
used length of buffer
SOCHAR ** m_rgpArgs
argv array
static const wchar_t * strrchr(const wchar_t *s, wchar_t c)
const char * GetFileNameS(char) const
Unix glob implementation.
ARG_ARRAY_TYPE m_nArgArrayType
is the argv array storing indexes or pointers
SOCHAR * File(int n)
Return the a single file.