aboutsummaryrefslogtreecommitdiff
path: root/builtins
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-09-09 02:02:08 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-09-09 02:02:08 -0400
commit1fbe2cb5dd1aa4b20411ee0c3b00310677373a55 (patch)
tree5362da93fdf255fd08b748e9a72b7179a719f4e0 /builtins
parent6752c60f32d0e154e54f30fd2b3e22904e56ea64 (diff)
For parsing paths, use nested parens: (./foo), also add some methods
Diffstat (limited to 'builtins')
-rw-r--r--builtins/path.c27
-rw-r--r--builtins/path.h2
2 files changed, 27 insertions, 2 deletions
diff --git a/builtins/path.c b/builtins/path.c
index ba14c3d8..d5305e30 100644
--- a/builtins/path.c
+++ b/builtins/path.c
@@ -220,7 +220,7 @@ public void Path$create_directory(Path_t path, int permissions)
fail("Could not create directory: %k (%s)", &path, strerror(errno));
}
-public Array_t Path$children(Path_t path, bool include_hidden)
+static Array_t _filtered_children(Path_t path, bool include_hidden, mode_t filter)
{
if (Text$matches(path, Pattern("~/{..}")))
path = Paths(Text$format("%s", getenv("HOME")), Text$slice(path, I(2), I(-1)));
@@ -240,13 +240,36 @@ public Array_t Path$children(Path_t path, bool include_hidden)
continue;
if (streq(dir->d_name, ".") || streq(dir->d_name, ".."))
continue;
- Path_t child = Text$format("%.*s/%s", path_len, path_str, dir->d_name);
+
+ const char *child_str = heap_strf("%.*s/%s", path_len, path_str, dir->d_name);
+ struct stat sb;
+ if (stat(child_str, &sb) != 0)
+ continue;
+ if (!((sb.st_mode & S_IFMT) & filter))
+ continue;
+
+ Path_t child = Text$format("%s%s", child_str, ((sb.st_mode & S_IFMT) == S_IFDIR) ? "/" : ""); // Trailing slash for dirs
Array$insert(&children, &child, I(0), sizeof(Path_t));
}
closedir(d);
return children;
}
+public Array_t Path$children(Path_t path, bool include_hidden)
+{
+ return _filtered_children(path, include_hidden, (mode_t)-1);
+}
+
+public Array_t Path$files(Path_t path, bool include_hidden)
+{
+ return _filtered_children(path, include_hidden, S_IFREG);
+}
+
+public Array_t Path$subdirectories(Path_t path, bool include_hidden)
+{
+ return _filtered_children(path, include_hidden, S_IFDIR);
+}
+
public const TypeInfo Path$info = {
.size=sizeof(Path_t),
.align=__alignof__(Path_t),
diff --git a/builtins/path.h b/builtins/path.h
index 9a37d92d..ea1e99ae 100644
--- a/builtins/path.h
+++ b/builtins/path.h
@@ -28,6 +28,8 @@ Text_t Path$read(Path_t path);
void Path$remove(Path_t path, bool ignore_missing);
void Path$create_directory(Path_t path, int permissions);
Array_t Path$children(Path_t path, bool include_hidden);
+Array_t Path$files(Path_t path, bool include_hidden);
+Array_t Path$subdirectories(Path_t path, bool include_hidden);
extern const TypeInfo Path$info;