Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

You seem to be missing a scandir implementation on Windows - one below - all yours :) #15

Closed
adv-sw opened this issue Jun 14, 2020 · 4 comments

Comments

@adv-sw
Copy link

adv-sw commented Jun 14, 2020

#if defined WIN32 || defined WIN64

#include <windows.h>
#include <wchar.h>
#include <shlwapi.h>

int _alphasort(const void *d1, const void d2)
{
return stricmp((
(struct dirent * const )d1)->d_name, ((struct dirent * const *)d2)->d_name);
}

// Scan a directory for all its entries
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>

int scandir(const char *dirname, struct dirent ***dest, int (*sdfilter)(struct dirent *), int (*dcomp)(const void *, const void *))
{
WIN32_FIND_DATAA ffd;
char szDir[MAX_PATH];
size_t length_of_path;
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError=0;

// Check that the input path plus 3 is not longer than MAX_PATH.
// Three characters are for the "*" plus NULL appended below.

StringCchLengthA(dirname, MAX_PATH, &length_of_path);

if (length_of_path > (MAX_PATH - 3))
{
printf("\nDirectory path is too long.\n");
return (-1);
}

// Prepare string for use with FindFile functions. First, copy the
// string to a buffer, then append '*' to the directory name.

StringCchCopyA(szDir, MAX_PATH, dirname);
StringCchCatA(szDir, MAX_PATH, "\*");

// 1st pass count how many entries we'll need.

size_t entry_count = 0;

{
hFind = FindFirstFileA(szDir, &ffd);

  if (INVALID_HANDLE_VALUE == hFind) 
     return -1;

  // Count all the files in the directory 

  do
  {
     entry_count++;
  }
  while (::FindNextFileA(hFind, &ffd) != 0);

  ::FindClose(hFind);

}

// Second pass allocate & store.

struct dirent **entries = (struct dirent **) malloc(sizeof(struct dirent *) * entry_count);

{
size_t index = 0;

  hFind = FindFirstFileA(szDir, &ffd);

  if (INVALID_HANDLE_VALUE == hFind) 
     return -1;

  // List all the files in the directory with some info about them.

  do
  {
     struct dirent *entry = (struct dirent*) calloc(sizeof(struct dirent), 1);
     entries[index] = entry;
     index++;
     
     char *fn = strrchr(ffd.cFileName, PATH_SEP);
     if (fn)
        fn++; // skip over seperator.
     else
        fn = ffd.cFileName;
              
     strncpy(entry->d_name, fn, PATH_MAX); 

     entry->d_type =(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG;
  }
  while (::FindNextFileA(hFind, &ffd) != 0);

  ::FindClose(hFind);

}

// Optional sort ...

if (dcomp)
qsort (entries, entry_count, sizeof(struct dirent *), dcomp);

*dest = entries;

return entry_count;
}

#endif // WIN32/64

@aiekick
Copy link
Owner

aiekick commented Jun 14, 2020

not missed.
i could extract also the scandir function from the dirent windows implementation.
if you think is better to integrate this func inside ImGuiFileDialog you can propose a PR if you want

@adv-sw
Copy link
Author

adv-sw commented Jun 15, 2020

Probably I found a different dirent implementation that didn't have that or I'm blind.. I guess you could be clearer about where to obtain the external dependencies. We both have it working, so doesn't matter which way you take it.

Thanks for the code. You're welcome to close this if you have everything resolved & I missed it.

@aiekick
Copy link
Owner

aiekick commented Jun 15, 2020

yes i will precise that in the readme.
i though it was clear with how the sample app of this repo was made with dependancy in 3rdparty but maybe not haha :)
thanks for your advice.

@aiekick aiekick closed this as completed Jun 15, 2020
@aiekick
Copy link
Owner

aiekick commented Jun 15, 2020

i added infos in readme file.

the dirent version you must use is the v1.23. i had some issues before.
i pointed this version in readme.

let me know if its more clear for you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants