support dir exclusion part 1/2 default tip

Sun, 28 Jun 2026 15:57:44 +0200

author
Mike Becker <universe@uap-core.de>
date
Sun, 28 Jun 2026 15:57:44 +0200
changeset 90
9b541d22d649
parent 89
c80878da618c

support dir exclusion part 1/2

part 1: option parser + preps
part 2: feature implementation

relates to #838

src/cline.c file | annotate | diff | comparison | revisions
src/scanner.c file | annotate | diff | comparison | revisions
src/settings.c file | annotate | diff | comparison | revisions
src/settings.h file | annotate | diff | comparison | revisions
--- a/src/cline.c	Sun Jun 28 14:29:39 2026 +0200
+++ b/src/cline.c	Sun Jun 28 15:57:44 2026 +0200
@@ -45,6 +45,8 @@
     "\n                        One of: ignore low medium high"
     "\n  -c                  - Count non-whitespace characters instead of lines"
     "\n  -d                  - Report only directory sums"
+    "\n  -D <path>           - Excludes the directory at the specified <path>"
+    "\n  -D <name>           - Excludes all directories with the given <name>"
     "\n  -E <pattern>        - Excludes any line matching the <pattern>"
     "\n  -e <start> <end>    - Excludes lines between <start> and <end>"
     "\n                        You may use these options multiple times"
@@ -116,7 +118,7 @@
 
   for (int t = 1 ; t < argc ; t++) {
 
-    int argflags = checkArgument(argv[t], "hsSrRmvVbeEicd");
+    int argflags = checkArgument(argv[t], "hsSrRmvVbeEicdD");
     int paropt = 0;
 
     /* h */
@@ -234,6 +236,16 @@
         settings->dirsOnly = true;
       }
     }
+    /* D */
+    if ((argflags & 16384) > 0) {
+      t++;
+      if (!checkParamOpt(&paropt) || t >= argc) {
+        return exit_with_help(settings, 1);
+      }
+      // TODO: normalize argument before adding to dir list
+      //       this makes it more efficient to compare dir names later
+      add_string(settings->excludeDirs, argv[t]);
+    }
     if (argflags == 0) {
       /* SHORTCUTS */
       if (strcmp(argv[t], "--exclude-cstyle-comments") == 0) {
--- a/src/scanner.c	Sun Jun 28 14:29:39 2026 +0200
+++ b/src/scanner.c	Sun Jun 28 15:57:44 2026 +0200
@@ -185,6 +185,13 @@
   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
+  return false;
+}
+
 void scanDirectory(scanner_t scanner, settings_t* settings,
     string_list_t* output, scanresult_t* result) {
 
@@ -201,25 +208,31 @@
     if (!S_ISREG(filelist->st_mode)) {
       if (S_ISDIR(filelist->st_mode)) {
         if (settings->recursive) {
-          string_list_t *recoutput = settings->verbose ? new_string_list_t() : NULL;
-          scanresult_t recresult;
-          recresult.ext = result->ext;
-          scanDirectory(
-              (scanner_t) {filelist->filename, scanner.spaces+1},
-              settings, recoutput, &recresult);
-          result->result += recresult.result;
-          if (settings->verbose && (!settings->matchesOnly || recresult.result > 0)) {
-            outbuf = (char*) malloc(81);
-            snprintf(outbuf, 81, "%*s/%*s%13u %s\n",
-                filelist->displayname_len+scanner.spaces, filelist->displayname,
-                60-filelist->displayname_len-scanner.spaces-1, "",
-                recresult.result, result_type);
-            add_string(output, outbuf);
-            for (unsigned i = 0 ; i < recoutput->count ; i++) {
-              add_string(output, recoutput->items[i]);
+          if (is_dir_excluded(settings->excludeDirs, filelist->filename)) {
+            if (!settings->matchesOnly && settings->verbose) {
+              // TODO: print "no match"
             }
+          } else {
+            string_list_t *recoutput = settings->verbose ? new_string_list_t() : NULL;
+            scanresult_t recresult;
+            recresult.ext = result->ext;
+            scanDirectory(
+                (scanner_t) {filelist->filename, scanner.spaces+1},
+                settings, recoutput, &recresult);
+            result->result += recresult.result;
+            if (settings->verbose && (!settings->matchesOnly || recresult.result > 0)) {
+              outbuf = (char*) malloc(81);
+              snprintf(outbuf, 81, "%*s/%*s%13u %s\n",
+                  filelist->displayname_len+scanner.spaces, filelist->displayname,
+                  60-filelist->displayname_len-scanner.spaces-1, "",
+                  recresult.result, result_type);
+              add_string(output, outbuf);
+              for (unsigned i = 0 ; i < recoutput->count ; i++) {
+                add_string(output, recoutput->items[i]);
+              }
+            }
+            destroy_string_list_t(recoutput);
           }
-          destroy_string_list_t(recoutput);
         }
       } else if (!settings->matchesOnly && settings->verbose) {
         outbuf = (char*) malloc(81);
--- a/src/settings.c	Sun Jun 28 14:29:39 2026 +0200
+++ b/src/settings.c	Sun Jun 28 15:57:44 2026 +0200
@@ -38,6 +38,7 @@
     settings->matchesOnly        = false;
     settings->includeSuffixes    = new_string_list_t();
     settings->excludeSuffixes    = new_string_list_t();
+    settings->excludeDirs        = new_string_list_t();
     settings->verbose            = true;
     settings->bfileHeuristics    = new_bfile_heuristics_t();
     settings->confusing_lnlen    = false;
@@ -54,6 +55,7 @@
   destroy_regex_parser_t(settings->regex);
   destroy_string_list_t(settings->includeSuffixes);
   destroy_string_list_t(settings->excludeSuffixes);
+  destroy_string_list_t(settings->excludeDirs);
   destroy_bfile_heuristics_t(settings->bfileHeuristics);
   free(settings);
 }
--- a/src/settings.h	Sun Jun 28 14:29:39 2026 +0200
+++ b/src/settings.h	Sun Jun 28 15:57:44 2026 +0200
@@ -35,6 +35,7 @@
 typedef struct settings_s {
   string_list_t* includeSuffixes;
   string_list_t* excludeSuffixes;
+  string_list_t* excludeDirs;
   regex_parser_t* regex;
   bfile_heuristics_t* bfileHeuristics;
   char fileSeparator;

mercurial