commit 78bedb21079c4c51939de6ee60adb4983ffb8ff1
parent 17b238f7f77f52c34d093fff259293f81d3b59a8
Author: Drew DeVault <sir@cmpwn.com>
Date: Fri, 26 Feb 2021 14:52:59 -0500
hare::module: implement scan, somewhat
Diffstat:
2 files changed, 69 insertions(+), 10 deletions(-)
diff --git a/hare/module/scan.ha b/hare/module/scan.ha
@@ -1,13 +1,51 @@
use fs;
use hare::ast;
-use slice;
-use path;
use io;
+use path;
+use slice;
+use strings;
// Scans the files in a directory for eligible build inputs and returns a
// [version] which includes all applicable files.
export fn scan(ctx: *context, path: path::path) (version | error) = {
- abort();
+ let inputs: []input = [];
+ let iter = match (fs::iter(ctx.fs, path)) {
+ fs::wrongtype => {
+ let st = fs::stat(ctx.fs, path)?;
+ append(inputs, input {
+ path = path,
+ stat = st,
+ ...
+ });
+ return version {
+ hash = "", // TODO
+ inputs = inputs,
+ };
+ },
+ err: fs::error => return err,
+ iter: *fs::iterator => iter,
+ };
+ for (true) match (fs::next(iter)) {
+ void => break,
+ ent: fs::dirent => switch (ent.ftype) {
+ fs::mode::DIR => void, // TODO
+ fs::mode::LINK => abort(), // TODO
+ fs::mode::REG => if (eligible(ctx, ent.name)) {
+ let p = path::join(path, ent.name);
+ let st = fs::stat(ctx.fs, p)?;
+ append(inputs, input {
+ path = p,
+ stat = st,
+ ...
+ });
+ },
+ * => void,
+ },
+ };
+ return version {
+ hash = "", // TODO
+ inputs = inputs,
+ };
};
// Looks up a module by its identifier from HAREPATH, and returns a [version]
@@ -15,3 +53,18 @@ export fn scan(ctx: *context, path: path::path) (version | error) = {
export fn lookup(ctx: *context, name: ast::ident) (version | error) = {
abort();
};
+
+// TODO: Filter inputs by build tags
+fn eligible(ctx: *context, name: path::path) bool = {
+ if (!(name is str)) {
+ return false;
+ };
+ let name = name as str;
+ static const exts = [".ha", ".s"];
+ for (let i = 0z; i < len(exts); i += 1) {
+ if (strings::has_suffix(name, exts[i])) {
+ return true;
+ };
+ };
+ return false;
+};
diff --git a/hare/module/types.ha b/hare/module/types.ha
@@ -1,36 +1,36 @@
use fs;
use io;
+use path;
// The inclusive/exclusive state for a build tag.
-type tag_mode = enum {
+export type tag_mode = enum {
INCLUSIVE,
EXCLUSIVE,
};
// A build tag, e.g. +x86_64.
-type tag = struct {
+export type tag = struct {
name: str,
mode: tag_mode,
};
// The manifest for a particular module, with some number of inputs, and
// versions.
-type manifest = struct {
+export type manifest = struct {
inputs: []input,
versions: []version,
};
// A module version: a set of possible input files for that module.
-type version = struct {
+export type version = struct {
hash: str,
inputs: []input,
};
// An input to a module, generally a source file.
-type input = struct {
+export type input = struct {
hash: str,
- path: str,
- tags: []tag,
+ path: path::path,
stat: fs::filestat,
};
@@ -39,3 +39,9 @@ export type module_not_found = void!;
// All possible error types.
export type error = (fs::error | io::error | module_not_found);
+
+export fn errstr(err: error) const str = match (err) {
+ err: fs::error => fs::errstr(err),
+ err: io::error => io::errstr(err),
+ module_not_found => "Module not found",
+};