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 };