Welcome to little lamb

Code » limb » commit 37bc6b8

direntry.h: Tweak sascandirat() interface..

author Olivier Brunel
2023-06-02 06:27:43 UTC
committer Olivier Brunel
2023-07-05 07:39:26 UTC
parent 357eb0dc86b26c29efe5c8b663820e890e9fa974

direntry.h: Tweak sascandirat() interface..

..so it doesn't take a size_t and set it to the longest name, but simply
takes a pointer that is passed to the sascande function.

Adapt salsat() - caller of sascandirat().

src/doc/direntry.h/sascandirat.3.md +6 -9
src/liblimb/direntry.h/sascandirat.c +4 -8
src/liblimb/djbunix.h/salsat.c +5 -1
src/liblimb/include/limb/direntry.h +3 -3

diff --git a/src/doc/direntry.h/sascandirat.3.md b/src/doc/direntry.h/sascandirat.3.md
index 27851cf..da39747 100644
--- a/src/doc/direntry.h/sascandirat.3.md
+++ b/src/doc/direntry.h/sascandirat.3.md
@@ -11,10 +11,10 @@ sascandirat, sascandir - scan a directory to fill a stralloc
     #include <limb/direntry.h>
 
 ```pre hl
-typedef ssize_t (*sascande) (stralloc *<em>sa</em>, direntry *<em>de</em>, int <em>dirfd</em>)
+typedef ssize_t (*sascande) (stralloc *<em>sa</em>, direntry *<em>de</em>, int <em>dirfd</em>, void *<em>ctx</em>)
 
-int sascandirat(stralloc *<em>sa</em>, int <em>dirfd</em>, const char *<em>name</em>, sascande <em>fn</em>, size_t *<em>mlen</em>)
-int sascandir(stralloc *<em>sa</em>, const char *<em>name</em>, sascande <em>fn</em>, size_t *<em>mlen</em>)
+int sascandirat(stralloc *<em>sa</em>, int <em>dirfd</em>, const char *<em>name</em>, sascande <em>fn</em>, void *<em>ctx</em>)
+int sascandir(stralloc *<em>sa</em>, const char *<em>name</em>, sascande <em>fn</em>, void *<em>ctx</em>)
 ```
 
 # DESCRIPTION
@@ -22,17 +22,14 @@ int sascandir(stralloc *<em>sa</em>, const char *<em>name</em>, sascande <em>fn<
 The `sascandirat`() function scans the directory `name` calling the function
 `fn` on each of its directory entry, save for `.` and `..` which are ignored.
 Said function shall add relevant information regarding the directory entry
-pointed by `de` into the stralloc pointed by `sa` and return the size added. It
-may return zero to indicate the entry was ignored. On error, it should return -1
-and set `errno` to indicate the error.
+pointed by `de` into the stralloc pointed by `sa` and return 1 on success. It
+can also return 0 if nothing was added, e.g. the file/entry was simply ignored.
+In case of failure it must return -1 and set `errno` to indicate the error.
 
 If `name` describes a relative path, it is relative to the directory associated
 with the file descriptor `dirfd`, which may be *AT_FDCWD* to use the current
 working directory.
 
-Once the entire directory has been scanned, if `mlen` is not *NULL* the pointed
-value will be set to the maximum length returned by `fn`.
-
 The `sascandir`() macro is similar, except when `name` describes a relative
 path, in which case it is relative to the current working directory.
 
diff --git a/src/liblimb/direntry.h/sascandirat.c b/src/liblimb/direntry.h/sascandirat.c
index 082afab..1a90b33 100644
--- a/src/liblimb/direntry.h/sascandirat.c
+++ b/src/liblimb/direntry.h/sascandirat.c
@@ -5,10 +5,9 @@
 #include <limb/direntry.h>
 
 int
-sascandirat(stralloc *sa, int bfd, const char *name, sascande fn, size_t *mlen)
+sascandirat(stralloc *sa, int bfd, const char *name, sascande fn, void *ctx)
 {
     size_t salen = sa->len;
-    size_t maxlen = 0;
     int ret = 0;
     DIR *dir = opendirat(bfd, name);
     if (!dir) return -1;
@@ -17,16 +16,13 @@ sascandirat(stralloc *sa, int bfd, const char *name, sascande fn, size_t *mlen)
     while ((errno = 0, de = readdir(dir))) {
         if (ISDOTDOT(de)) continue;
 
-        ssize_t len = fn(sa, de, dirfd(dir));
-        if (len < 0) break;
-        if ((size_t) len > maxlen) maxlen = len;
-        if (len) ++ret;
+        int r = fn(sa, de, dirfd(dir), ctx);
+        if (r < 0) break;
+        if (r) ++ret;
     }
     if (errno) {
         ret = -1;
         sa->len = salen;
-    } else if (mlen) {
-        *mlen = maxlen;
     }
 
     dir_close(dir);
diff --git a/src/liblimb/djbunix.h/salsat.c b/src/liblimb/djbunix.h/salsat.c
index fb8bbe6..223073d 100644
--- a/src/liblimb/djbunix.h/salsat.c
+++ b/src/liblimb/djbunix.h/salsat.c
@@ -7,16 +7,20 @@
 #include <limb/gccattributes.h>
 
 static ssize_t
-sascandir_name(stralloc *sa, direntry *de, int bfd gccattr_unused)
+sascandir_name(stralloc *sa, direntry *de, int bfd gccattr_unused, void *mlen_)
 {
+    size_t *mlen = mlen_;
     size_t len = strlen(de->d_name);
     if (!stralloc_catb(sa, de->d_name, len + 1))
         return -1;
+    if (mlen && len > *mlen)
+        *mlen = len;
     return len;
 }
 
 int
 salsat(int fd, const char *name, stralloc *sa, size_t *mlen)
 {
+    if (mlen) *mlen = 0;
     return sascandirat(sa, fd, name, sascandir_name, mlen);
 }
diff --git a/src/liblimb/include/limb/direntry.h b/src/liblimb/include/limb/direntry.h
index 78a308b..cc4a8f5 100644
--- a/src/liblimb/include/limb/direntry.h
+++ b/src/liblimb/include/limb/direntry.h
@@ -7,13 +7,13 @@
 #include <skalibs/direntry.h>
 #include <limb/stralloc.h>
 
-typedef ssize_t (*sascande) (stralloc *sa, direntry *de, int bfd);
+typedef ssize_t (*sascande) (stralloc *sa, direntry *de, int bfd, void *ctx);
 
 #define ISDOTDOT(de)    ((de)->d_name[0] == '.' && (!(de)->d_name[1] || ((de)->d_name[1] == '.' && !(de)->d_name[2])))
 
 extern DIR *opendirat(int bfd, const char *name);
 
-extern int sascandirat(stralloc *sa, int bfd, const char *name, sascande fn, size_t *mlen);
-#define sascandir(sa,name,fn,mlen)      sascandirat(sa, AT_FDCWD, name, fn, mlen)
+extern int sascandirat(stralloc *sa, int bfd, const char *name, sascande fn, void *ctx);
+#define sascandir(sa,name,fn,ctx)   sascandirat(sa, AT_FDCWD, name, fn, ctx)
 
 #endif /* LIMB_DIRENTRY_H */