src/scanner.c

changeset 95
8a20001544c1
parent 90
9b541d22d649
child 96
eca455ac32c2
--- 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 <sys/stat.h>
 #include <ctype.h>
 
+#ifdef _MSC_VER
+#include <windows.h>
+#include <shlwapi.h>
+
+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 <unistd.h>
+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);
+  }
+}

mercurial