From 8e565685dcaccc94cc27850f56d8e3fbf5d5e8c0 Mon Sep 17 00:00:00 2001 From: Amine El Baghdadi <75886237+NoobJsPerson@users.noreply.github.com> Date: Tue, 25 Jun 2024 18:04:09 +0100 Subject: [PATCH 1/2] implement scandir and add polyfill for unsuppotred types on Windows --- .gitignore | 1 + include/files.h | 2 +- include/osddirent.h | 10 ++++++++++ include/windirent.h | 17 +++++++++++++++++ src/files.c | 4 ++-- src/main.c | 2 +- src/windirent.c | 36 ++++++++++++++++++++++++++++++++++++ 7 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 include/osddirent.h create mode 100644 include/windirent.h create mode 100644 src/windirent.c diff --git a/.gitignore b/.gitignore index 08b2688..e784b75 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ clings_debug compile_commands.json .cache tags +.vscode diff --git a/include/files.h b/include/files.h index 868f0c3..b216e78 100644 --- a/include/files.h +++ b/include/files.h @@ -1,7 +1,7 @@ #ifndef FILES_H #define FILES_H -#include +#include "osddirent.h" #include #include diff --git a/include/osddirent.h b/include/osddirent.h new file mode 100644 index 0000000..481b142 --- /dev/null +++ b/include/osddirent.h @@ -0,0 +1,10 @@ +#ifndef OSDDIRENT_H +#define OSDDIRENT_H + +#ifdef _WIN32 +#include +#else +#include +#endif + +#endif \ No newline at end of file diff --git a/include/windirent.h b/include/windirent.h new file mode 100644 index 0000000..4ff9de8 --- /dev/null +++ b/include/windirent.h @@ -0,0 +1,17 @@ +#ifndef WINDIRENT_H +#define WINDIRENT_H +#define DIR int + +#include +#include +#include +#include +struct dirent { + size_t d_ino; + int d_type; + char *d_name; + +}; +int alphasort(const struct dirent **a, const struct dirent **b); +int scandir(const char *path, struct dirent ***namelist, void *unused, int (*compar)(const struct dirent **, const struct dirent **)); +#endif \ No newline at end of file diff --git a/src/files.c b/src/files.c index fed561d..255aeb3 100644 --- a/src/files.c +++ b/src/files.c @@ -1,5 +1,5 @@ #include "files.h" -#include +// #include #include #include #include @@ -152,7 +152,7 @@ char *get_filename_no_ext(const char *filename) { /// pointer and returns total exercise files int load_files(FileCollection **dirs) { struct dirent **nmlist; - int ex_dirs_ct = scandir(DIR_PATH, &nmlist, NULL, alphasort); + int ex_dirs_ct = scandir(DIR_PATH, &nmlist, NULL, alphasort); // important line if (ex_dirs_ct < 0) { perror("could not open directory"); diff --git a/src/main.c b/src/main.c index 65d7fc8..9eab3ef 100644 --- a/src/main.c +++ b/src/main.c @@ -4,8 +4,8 @@ #include "files.h" #include "runna.h" #include "utils.h" +#include "osddirent.h" -#include #include #include #include diff --git a/src/windirent.c b/src/windirent.c new file mode 100644 index 0000000..375705f --- /dev/null +++ b/src/windirent.c @@ -0,0 +1,36 @@ +#include "windirent.h" + +const int DIR_TYPE_CODE = 4; + +int alphasort(const struct dirent **a, const struct dirent **b) { + return strcoll((*a)->d_name,(*b)->d_name); +} + +int scandir( + const char *path, + struct dirent ***namelist, + void *unused, + int (*compar)(const struct dirent **, const struct dirent **) +) { + size_t nmsize = sizeof(struct dirent); + int index = 0; + **namelist = malloc(nmsize); + WIN32_FIND_DATA FindFileData; + HANDLE hFind = FindFirstFile(path,&FindFileData); + if (hFind == INVALID_HANDLE_VALUE) return -1; + (*namelist)[0]->d_ino = FindFileData.dwFileAttributes; + (*namelist)[0]->d_name = FindFileData.cFileName; + if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) (*namelist)[0]->d_type = DIR_TYPE_CODE; + else (*namelist)[0]->d_type = 0; + while(FindNextFile(hFind, &FindFileData)) { + index++; + **namelist = realloc(namelist, nmsize + sizeof(struct dirent)); + (*namelist)[index]->d_ino = FindFileData.dwFileAttributes; + (*namelist)[index]->d_name = FindFileData.cFileName; + if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) (*namelist)[index]->d_type = DIR_TYPE_CODE; + else (*namelist)[index]->d_type = 0; + } + qsort(**namelist, index+1, sizeof(struct dirent), alphasort); + FindClose(hFind); + return 1; +} \ No newline at end of file From b548940e7499bf552e36bd78b0d10f3646b84249 Mon Sep 17 00:00:00 2001 From: Amine El Baghdadi <75886237+NoobJsPerson@users.noreply.github.com> Date: Tue, 25 Jun 2024 18:35:18 +0100 Subject: [PATCH 2/2] reimplement count_dir for Windows --- src/main.c | 5 ++++- src/runna.c | 4 ++++ src/windirent.c | 16 +++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 9eab3ef..bb52059 100644 --- a/src/main.c +++ b/src/main.c @@ -221,7 +221,9 @@ static void sig_handler(int _) { (void)_; keep_running = 0; } - +#ifdef _WIN32 +#define count_dir win_count_dir +#else int count_dir(char *dir) { struct dirent *dp; DIR *fd; @@ -241,6 +243,7 @@ int count_dir(char *dir) { return dir_count; } +#endif void print_usage() { printf("Usage:\n\n" diff --git a/src/runna.c b/src/runna.c index 4624e1f..d9a415e 100644 --- a/src/runna.c +++ b/src/runna.c @@ -74,7 +74,11 @@ int exec_compile_output(char *file_path, char *file_name_no_ext) { closedir(dir); } else if (ENOENT == errno) { // need to make BIN_PATH + #ifdef _WIN32 + mkdir(BIN_PATH); + #else mkdir(BIN_PATH, 0700); + #endif } else { perror("probing BIN_PATH failed"); } diff --git a/src/windirent.c b/src/windirent.c index 375705f..84ef019 100644 --- a/src/windirent.c +++ b/src/windirent.c @@ -33,4 +33,18 @@ int scandir( qsort(**namelist, index+1, sizeof(struct dirent), alphasort); FindClose(hFind); return 1; -} \ No newline at end of file +} +int win_count_dir(char *dir) +{ + int dir_count; + WIN32_FIND_DATA FindFileData; + HANDLE hFind = FindFirstFile(dir,&FindFileData); + if (hFind == INVALID_HANDLE_VALUE) return -1; + while(FindNextFile(hFind, &FindFileData)) { + if (!strcmp(FindFileData.cFileName, ".") || !strcmp(FindFileData.cFileName, "..")) + continue; /* skip self and parent */ + dir_count++; + } + FindClose(hFind); + return dir_count; +}