diff -r 9637e3efb8e7 -r 8a20001544c1 src/scanner.c --- a/src/scanner.c Tue Jun 30 12:00:16 2026 +0200 +++ b/src/scanner.c Tue Jun 30 14:19:08 2026 +0200 @@ -31,6 +31,54 @@ #include #include +#ifdef _MSC_VER +#include +#include + +void get_working_dir(const char** out_ptr, size_t *out_len) { + static char cwd[MAX_PATH]; + if (GetCurrentDirectory(MAX_PATH, cwd) == 0) { + fprintf(stderr, "Could not get current working directory.\n"); + exit(1); + } + size_t len = strlen(cwd); + if (cwd[len - 1] != '/') { + cwd[len++] = '/'; + cwd[len] = '\0'; + } + *out_ptr = cwd; + *out_len = len; +} +bool path_is_relative(const char *path) { + return PathIsRelative(path); +} +int pathcmp(const char *p1, const char *p2) { + return strcasecmp(p1, p2); +} +#else +#include +void get_working_dir(const char** out_ptr, size_t *out_len) { + static char cwd[PATH_MAX]; + if (getcwd(cwd, sizeof(cwd)) == NULL) { + fprintf(stderr, "Could not get current working directory.\n"); + exit(1); + } + size_t len = strlen(cwd); + if (cwd[len - 1] != '/') { + cwd[len++] = '/'; + cwd[len] = '\0'; + } + *out_ptr = cwd; + *out_len = len; +} +bool path_is_relative(const char *path) { + return path[0] != '/'; +} +int pathcmp(const char *p1, const char *p2) { + return strcmp(p1, p2); +} +#endif + typedef struct filelist filelist_t; struct filelist { @@ -185,10 +233,32 @@ return list; } -static bool is_dir_excluded(string_list_t* list, char* dir) { - // TODO: implement - // assume normalized dir names in list (cline.c will make sure of it) - // remember to do case-insensitive comparison for WIN32 +static bool is_dir_excluded(settings_t* settings, const char* dir) { + const string_list_t * const list = settings->excludeDirs; + + for (size_t i = 0 ; i < list->count ; i++) { + /* determine if the list item is a path or a name */ + if (strchr(list->items[i], settings->fileSeparator) == NULL) { + /* compare only the name */ + const char *dirpart = strrchr(dir, settings->fileSeparator); + if (dirpart == NULL) { + dirpart = dir; + } else { + dirpart++; + } + if (pathcmp(list->items[i], dirpart) == 0) { + return true; + } + } else { + /* compare the full paths */ + char* absdir = make_path_absolute(dir); + if (pathcmp(list->items[i], absdir) == 0) { + free(absdir); + return true; + } + free(absdir); + } + } return false; } @@ -208,9 +278,16 @@ if (!S_ISREG(filelist->st_mode)) { if (S_ISDIR(filelist->st_mode)) { if (settings->recursive) { - if (is_dir_excluded(settings->excludeDirs, filelist->filename)) { + if (is_dir_excluded(settings, filelist->filename)) { if (!settings->matchesOnly && settings->verbose) { - // TODO: print "no match" + /* Print hint */ + outbuf = malloc(81); + snprintf(outbuf, 81, "%*s%*s%19s\n", + filelist->displayname_len + scanner.spaces, + filelist->displayname, + 60 - filelist->displayname_len - scanner.spaces, + "", "no match"); + add_string(output, outbuf); } } else { string_list_t *recoutput = settings->verbose ? new_string_list_t() : NULL; @@ -343,3 +420,32 @@ free(freethis); } } + +char *make_path_absolute(const char *path) { + static const char *cwd = NULL; + static size_t cwdlen = 0; +#ifdef _WIN32 + static char fs = '\\'; +#else + static char fs = '/'; +#endif /* _WIN32 */ + if (path_is_relative(path)) { + if (cwdlen == 0) { + get_working_dir(&cwd, &cwdlen); + } + size_t pathlen = strlen(path); + char *result = malloc(pathlen+cwdlen+1); + const char *part = path; + size_t partlen = pathlen; + if (part[0] == '.' && part[1] == fs) { + part += 2; + partlen -= 2; + } + memcpy(result, cwd, cwdlen); + memcpy(result+cwdlen, part, partlen); + result[cwdlen+partlen] = '\0'; + return result; + } else { + return strdup(path); + } +}