commit 3fe0ba2ced1548dba035852b8b0e910ff550ebcc
parent ac91eab7e3fa2a0d8b1379b827b88d9138b74a90
Author: Lou Woell <lou.woell@posteo.de>
Date: Fri, 12 Sep 2025 17:44:29 +0200
unhardcode default HAREPATH & tagset
Diffstat:
6 files changed, 60 insertions(+), 17 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,7 +1,10 @@
.POSIX:
.SUFFIXES:
HARE=hare
-HAREFLAGS=
+
+export HAREPATH != $(HARE) version -vv | grep HAREPATH | sed s+HAREPATH=++
+
+HAREFLAGS= -D HAREPATH="\"$(HAREPATH)\""
DESTDIR=
PREFIX=$(HOME)/.local
diff --git a/README.md b/README.md
@@ -6,18 +6,14 @@ documentation from within an editor, and jump to definitions.
In principle, everything needed for basic completion should be in place, I
haven't attempted using harehelper for that yet though.
-**VERY Work-in-Progress**
-
-- There's a bunch of stuff hardcoded that probably shouldn't be. (e.g. the base
- value of HAREPATH and the linux tagset)
-- All command names may change.
-
## Functionality
-All subcommands can be used with the toplevel `-p` flag to append directories
-(such as the current project root) to the HAREPATH.
+All subcommands can be used with the toplevel
+ - `-p` flag to append directories (such as the current project root) to the
+ HAREPATH.
+ - `-t` flag to (un)set build tags.
-### resolve namespaces
+### resolve namespaces
given a file.ha:
```hare
diff --git a/cmd/harehelper/+test/list_test.ha b/cmd/harehelper/+test/list_test.ha
@@ -5,7 +5,7 @@ use os;
@test fn list_symbols () void = {
const ctx = module::context {
- harepath = os::tryenv("HAREPATH", HAREPATH),
+ harepath = harepath(),
harecache = match (os::getenv("HARECACHE")) {
case let s: str =>
yield s;
diff --git a/cmd/harehelper/+test/locate_test.ha b/cmd/harehelper/+test/locate_test.ha
@@ -11,7 +11,7 @@ const s = 1, d = 2;
fn loc_test_fn (in: str, out: lex::location) void = {
const ctx = module::context {
- harepath = os::tryenv("HAREPATH", HAREPATH),
+ harepath = harepath(),
harecache = match (os::getenv("HARECACHE")) {
case let s: str =>
yield s;
diff --git a/cmd/harehelper/helper.ha b/cmd/harehelper/helper.ha
@@ -19,13 +19,12 @@ use hare::module;
use os;
use strings;
-def HAREPATH = "/usr/src/hare/stdlib/:/usr/src/hare/third-party:.";
-
const help: []getopt::help = [
"help with hare",
('h', "show help"),
- ('p', "path", "append to harepath"),
+ ('p', "<path>", "append to harepath"),
('P', "return harepath"),
+ ('t', "<tagset>", "set/unset build tags"),
("list", [
"list symbols in module",
"module"
@@ -52,15 +51,16 @@ export fn main () void = {
defer getopt::finish(&cmd);
const ctx = module::context {
- harepath = os::tryenv("HAREPATH", HAREPATH),
+ harepath = harepath(),
harecache = match (os::getenv("HARECACHE")) {
case let s: str =>
yield s;
case void =>
yield dirs::cache("hare");
},
- tags = ["linux"],
+ tags = default_tags(),
};
+ defer free(ctx.tags);
for (let (k, v) .. cmd.opts) {
switch (k) {
@@ -71,6 +71,8 @@ export fn main () void = {
ctx.harepath = strings::join(":", ctx.harepath, v)!;
case 'P' =>
ppath = true;
+ case 't' =>
+ merge_tags(&ctx.tags, v)!;
case => void;
};
};
diff --git a/cmd/harehelper/util.ha b/cmd/harehelper/util.ha
@@ -12,15 +12,20 @@
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <https://www.gnu.org/licenses/>.
+use ascii;
use bufio;
use fmt;
use fs;
use hare::ast;
use hare::lex;
+use hare::module;
use hare::parse;
use hare::unparse;
use io;
use os;
+use strings;
+
+def HAREPATH = ".";
fn printident(i: ast::ident) void = {
unparse::ident(os::stdout, i)!;
@@ -68,3 +73,40 @@ fn decls_finish (decls: []ast::decl) void = {
};
free(decls);
};
+
+
+// The functions below are taken from haredoc (included with hare stdlib)
+// GPL-3-only (C) the hare authors
+
+fn harepath() str = os::tryenv("HAREPATH", HAREPATH);
+
+fn default_tags() []str = {
+ let arch = os::arch_name(os::architecture());
+ static let platform: [7]u8 = [0...];
+ let platform = ascii::strlower_buf(os::sysname(), platform[..0])!;
+ let tags: []str = alloc([arch, platform])!;
+ return tags;
+};
+
+fn merge_tags(current: *[]str, new: str) (void | module::error) = {
+ let trimmed = strings::ltrim(new, '^');
+ if (trimmed != new) {
+ free(*current);
+ *current = [];
+ };
+ let newtags = module::parse_tags(trimmed)?;
+ defer free(newtags);
+ for :new (let newtag .. newtags) {
+ for (let i = 0z; i < len(current); i += 1) {
+ if (newtag.name == current[i]) {
+ if (!newtag.include) {
+ static delete(current[i]);
+ };
+ continue :new;
+ };
+ };
+ if (newtag.include) {
+ append(current, newtag.name)!;
+ };
+ };
+};