logo

deblob

remove binary executables from a directory git clone https://hacktivis.me/git/deblob.git
commit: 4a0166e23b319388c7356c88a3ca2851b7438395
parent 074b50fa51aebb4378bc1e50fac94a4332bd6643
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 18 Feb 2022 10:26:16 +0100

Use os::iter instead of os::readdir

This should be faster and more memory efficient, especially for large
directories, as it skips an allocation and allows the tool to work
incrementally. It also addresses a memory leak in the previous version;
the caller must free the return value of os::readdir.

Diffstat:

Mmain.ha28+++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/main.ha b/main.ha @@ -90,19 +90,25 @@ fn is_excluded(filename: str) bool = { }; fn check_dir(dirname: str, ignoring: bool) (ok | invalid) = { - const dir_ls = match (os::readdir(dirname)) { - case let d: []fs::dirent => - yield d; - case let e: fs::error => - fmt::errorf("os::readdir({}): {}\n", dirname, fs::strerror(e))!; + const iter = match (os::iter(dirname)) { + case let iter: *fs::iterator => + yield iter; + case let err: fs::error => + fmt::errorf("os::iter({}): {}\n", dirname, fs::strerror(err))!; return invalid; }; - for (let i = 0z; i < len(dir_ls); i += 1) { - const file = dir_ls[i]; - const filename = path::join(dirname, file.name); + for (true) { + const ent = match (fs::next(iter)) { + case let ent: fs::dirent => + yield ent; + case void => + break; + }; + + const filename = path::join(dirname, ent.name); - if (file.name == "." || file.name == "..") { + if (ent.name == "." || ent.name == "..") { continue; }; @@ -110,9 +116,9 @@ fn check_dir(dirname: str, ignoring: bool) (ok | invalid) = { ignoring = is_excluded(filename); }; - if(fs::isdir(file.ftype)) { + if (fs::isdir(ent.ftype)) { check_dir(filename, ignoring): void; - } else if(fs::isfile(file.ftype)) { + } else if(fs::isfile(ent.ftype)) { const is_blob = match (is_blob(filename)) { case let b: bool => yield b;