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:
MMakefile | 5++++-
MREADME.md | 14+++++---------
Mcmd/harehelper/+test/list_test.ha | 2+-
Mcmd/harehelper/+test/locate_test.ha | 2+-
Mcmd/harehelper/helper.ha | 12+++++++-----
Mcmd/harehelper/util.ha | 42++++++++++++++++++++++++++++++++++++++++++
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)!; + }; + }; +};