Vinicius Teshima před 3 měsíci
rodič
revize
e413c8a4d0
2 změnil soubory, kde provedl 58 přidání a 15 odebrání
  1. 1 1
      first.c
  2. 57 14
      src/lib.h

+ 1 - 1
first.c

@@ -57,7 +57,7 @@ main(int argc, char *argv[])
 
     struct dir dir = {0};
     struct dirs dirs = {0};
-    dirs = dir_list_cstr("./src", &err, .stat=true, .recurse=true);
+    dirs = dir_list_cstr(".", &err, .stat=true, .recurse=true);
 
     if ( err == ERR_OK ) DA_FOREACH(dirs, it) {
         if ( ! cstr_endswith(CSTR_WITH_SIZE(it->path, &err), ".c", 2, &err) )

+ 57 - 14
src/lib.h

@@ -1455,7 +1455,18 @@ _dir_list_cstr(const char *path, struct __dir_list_args args,
     struct dirs empty = {0};
     struct dirs dirs = {0};
 
-    DIR *d = NULL;
+    struct ddata {
+        DIR *d;
+        const char *path;
+    };
+
+    struct {
+        struct ddata *data;
+        u64 size;
+        u64 cap;
+    } ds = {0};
+    u64 ds_i = 0;
+
     struct dirent *de = NULL;
 
     LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, empty);
@@ -1463,14 +1474,24 @@ _dir_list_cstr(const char *path, struct __dir_list_args args,
 
     if ( out_err != NULL ) perr = out_err;
 
-    d = opendir(path);
-    if ( d == NULL ) {
-        *perr = ERR_FAILED_OPENDIR;
-        goto exit_err;
+    {
+        DIR *d = NULL;
+        d = opendir(path);
+        if ( d == NULL ) {
+            *perr = ERR_FAILED_OPENDIR;
+            goto exit_err;
+        }
+        DA_APPEND(ds, ((struct ddata) {.d=d, .path=path}), perr);
+        if ( *perr != ERR_OK ) goto exit_err;
     }
 
     errno = 0;
-    de = readdir(d);
+
+_loop_ds:
+    if ( ds_i >= ds.size ) goto _end_loop_ds;
+    struct ddata dd = ds.data[ds_i++];
+
+    de = readdir(dd.d);
     while ( de != NULL ) {
         struct dir dir = {0};
 
@@ -1486,11 +1507,8 @@ _dir_list_cstr(const char *path, struct __dir_list_args args,
             }
         }
 
-        if ( args.recurse == true ) {
-        }
-
         dir.path = cstr_dup(
-            temp_sprintf("%s/%s", path, de->d_name),
+            temp_sprintf("%s/%s", dd.path, de->d_name),
             perr
         );
         if ( *perr != ERR_OK ) goto exit_err;
@@ -1503,24 +1521,49 @@ _dir_list_cstr(const char *path, struct __dir_list_args args,
             }
         }
 
+        if ( args.recurse == true ) {
+            if ( S_ISDIR(dir.stat.st_mode) ) {
+                DIR *d = opendir(dir.path);
+                if ( d == NULL ) {
+                    *perr = ERR_FAILED_OPENDIR;
+                    goto exit_err;
+                }
+
+                DA_APPEND(ds, ((struct ddata) {.d=d, .path=dir.path}), perr);
+                if ( *perr != ERR_OK ) goto exit_err;
+            }
+        }
+
         DA_APPEND(dirs, dir, perr);
         if ( *perr != ERR_OK ) goto exit_err;
 
     _continue:
-        de = readdir(d);
+        de = readdir(dd.d);
     }
-
     if ( errno != 0 ) {
         *perr = ERR_FAILED_READDIR;
         goto exit_err;
     }
 
-    closedir(d);
+    if ( ds_i < ds.size ) goto _loop_ds;
+
+_end_loop_ds:
+
+    DA_FOREACH(ds, it) {
+        closedir(it->d);
+    }
+    LIB_FREE(ds.data);
 
     *perr = ERR_OK;
     return dirs;
 exit_err:
-    if ( d != NULL ) closedir(d);
+    if ( ds.data != NULL ) {
+        DA_FOREACH(ds, it) {
+            closedir(it->d);
+        }
+    }
+    LIB_FREE(ds.data);
+
     dir_list_destroy(&dirs, NULL);
     return empty;
 }