hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

env.ha (2344B)


      1 // License: GPL-3.0
      2 // (c) 2021 Drew DeVault <sir@cmpwn.com>
      3 // (c) 2022 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
      4 use bufio;
      5 use fmt;
      6 use hare::module;
      7 use io;
      8 use os::exec;
      9 use os;
     10 use strings;
     11 
     12 def PLATFORM: str = "unknown";
     13 
     14 fn default_tags() ([]module::tag | error) = {
     15 	let cmd = match (exec::cmd("hare", "version", "-v")) {
     16 	case let cmd: exec::command =>
     17 		yield cmd;
     18 	case exec::nocmd =>
     19 		let platform = strings::dup(PLATFORM);
     20 		let machine = strings::dup(os::machine());
     21 		fmt::errorln("Couldn't find hare binary in PATH")?;
     22 		fmt::errorfln("Build tags defaulting to +{}+{}",
     23 			platform, machine)?;
     24 
     25 		return alloc([module::tag {
     26 			name = platform,
     27 			mode = module::tag_mode::INCLUSIVE,
     28 		}, module::tag {
     29 			name = machine,
     30 			mode = module::tag_mode::INCLUSIVE,
     31 		}]);
     32 	case let err: exec::error =>
     33 		return err;
     34 	};
     35 
     36 	let pipe = exec::pipe();
     37 	defer io::close(pipe.0)!;
     38 	exec::addfile(&cmd, os::stdout_file, pipe.1);
     39 	let proc = exec::start(&cmd)?;
     40 	io::close(pipe.1)?;
     41 
     42 	let tags: []module::tag = [];
     43 	for (true) match (bufio::scanline(pipe.0)?) {
     44 	case let b: []u8 =>
     45 		defer free(b);
     46 		const (k, v) = strings::cut(strings::fromutf8(b)!, "\t");
     47 		if (k == "Build tags") {
     48 			tags = module::parsetags(v) as []module::tag;
     49 			break;
     50 		};
     51 	case io::EOF =>
     52 		// process exited with failure; handled below
     53 		break;
     54 	};
     55 
     56 	let status = exec::wait(&proc)?;
     57 	match (exec::check(&status)) {
     58 	case void =>
     59 		assert(len(tags) > 0);
     60 	case let status: !exec::exit_status =>
     61 		fmt::fatal("Error: hare:", exec::exitstr(status));
     62 	};
     63 	return tags;
     64 };
     65 
     66 fn addtags(tags: []module::tag, in: str) ([]module::tag | void) = {
     67 	let in = match (module::parsetags(in)) {
     68 	case void =>
     69 		return void;
     70 	case let t: []module::tag =>
     71 		yield t;
     72 	};
     73 	defer free(in);
     74 	append(tags, in...);
     75 	return tags;
     76 };
     77 
     78 fn deltags(tags: []module::tag, in: str) ([]module::tag | void) = {
     79 	if (in == "^") {
     80 		module::tags_free(tags);
     81 		return [];
     82 	};
     83 	let in = match (module::parsetags(in)) {
     84 	case void =>
     85 		return void;
     86 	case let t: []module::tag =>
     87 		yield t;
     88 	};
     89 	defer free(in);
     90 	for (let i = 0z; i < len(tags); i += 1) {
     91 		for (let j = 0z; j < len(in); j += 1) {
     92 			if (tags[i].name == in[j].name
     93 					&& tags[i].mode == in[j].mode) {
     94 				free(tags[i].name);
     95 				i -= 1;
     96 			};
     97 		};
     98 	};
     99 	return tags;
    100 };
    101 
    102 fn default_harepath() str = {
    103 	return HAREPATH;
    104 };