%% options copyright owner = Dirk Krause copyright year = 2015-xxxx license = bsd %% header /** @file File name expander. CRT on Windows: Optional. */ #ifndef DK4DIR08_H_INCLUDED #include "dk4dir08.h" #endif #ifdef __cplusplus extern "C" { #endif /** Expand a file name. @param pattern File name pattern, may optionally include a directory part. @param erp Error report, may be NULL. @return Directory structure on success, NULL on error. On success the path component in the returned directory structure is NULL if the pattern did not contain a directory part. Error codes: - DK4_E_INVALID_ARGUMENTS
if path is NULL, - DK4_E_NOT_SUPPORTED
if no function to traverse directories was found during build process or the function is called on a non-Windows system, - DK4_E_MEMORY_ALLOCATION_FAILED
if a memory allocation failed, - DK4_E_MATH_OVERFLOW
if a mathematical overflow occured in a size calculation, - DK4_E_BUFFER_TOO_SMALL
if one of the involved directory or file names is too long for an internal buffer, - DK4_E_OPENDIR_FAILED
with errno value in iDetails1 if the attempt to open the directory failed, - DK4_E_FINDFIRSTFILE_FAILED
with GetLastError() value in lDetails1 if the FindFirstFile() function failed on Windows, - DK4_E_SYSTEM
if the stat() or lstat() function failed for one of the directory items. */ dk4_dir_c8_t * dk4fne_open_c8(const char *pattern, dk4_er_t *erp); #ifdef __cplusplus } #endif %% module #include "dk4conf.h" #if DK4_ON_WINDOWS #ifndef WINDOWS_H_INCLUDED #include #define WINDOWS_H_INCLUDED 1 #endif #endif #include "dk4fne08.h" #include "dk4str8.h" #include "dk4mem.h" $!trace-include /** Constant texts used by the module. */ static const char * const dk4fne_c8_kw[] = { $!string-table . .. $!end }; #if DK4_ON_WINDOWS static int dk4fne_c8_fill_directory(dk4_dir_c8_t *ptr, const char *fn, dk4_er_t *erp) { WIN32_FIND_DATAA ffdata; char *nn; HANDLE ffres; int back = 0; ffres = FindFirstFileA(fn, &ffdata); if (INVALID_HANDLE_VALUE != ffres) { back = 1; do { if (0 != dk4str8_cmp(dk4fne_c8_kw[0], ffdata.cFileName)) { if (0 != dk4str8_cmp(dk4fne_c8_kw[1], ffdata.cFileName)) { nn = dk4str8_dup(ffdata.cFileName, erp); if (NULL != nn) { if (0 != (FILE_ATTRIBUTE_DIRECTORY & (ffdata.dwFileAttributes))) { if (0 == dk4sto_add(ptr->s_dir, (void *)nn, erp)) { back = 0; dk4mem_free(nn); } } else { if (0 == dk4sto_add(ptr->s_file, (void *)nn, erp)) { back = 0; dk4mem_free(nn); } } } else { back = 0; } } } } while (FindNextFileA(ffres, &ffdata)); FindClose(ffres); } else { /* ERROR: FindFirstFile failed */ dk4error_set_ldetails( erp, DK4_E_FINDFIRSTFILE_FAILED, (long)((unsigned long)GetLastError()) ); } return back; } #endif dk4_dir_c8_t * dk4fne_open_c8(const char *fn, dk4_er_t *erp) { #if DK4_ON_WINDOWS dk4_dir_c8_t *back = NULL; char *p1 = NULL; int ok = 0; if (NULL != fn) { back = dk4mem_new(dk4_dir_c8_t, 1, erp); if (NULL != back) { back->path = NULL; back->s_dir = NULL; back->i_dir = NULL; back->s_file = NULL; back->i_file = NULL; back->path = dk4str8_dup(fn, erp); if (NULL != back->path) { p1 = dk4str8_rchr(back->path, '\\'); if (NULL != p1) { *p1 = '\0'; } else { dk4mem_free(back->path); back->path = NULL; } back->s_dir = dk4sto_open(erp); if (NULL != back->s_dir) { dk4sto_set_comp(back->s_dir, dk4dir_c8_compare, 0); back->i_dir = dk4sto_it_open(back->s_dir, erp); if (NULL != back->i_dir) { back->s_file = dk4sto_open(erp); if (NULL != back->s_file) { dk4sto_set_comp(back->s_file, dk4dir_c8_compare, 0); back->i_file = dk4sto_it_open(back->s_file, erp); if (NULL != back->i_file) { ok = dk4fne_c8_fill_directory(back, fn, erp); } } } } } if (0 == ok) { dk4dir_c8_close(back); back = NULL; } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return 0; #endif }