hare

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

system.ha (1840B)


      1 // License: MPL-2.0
      2 // (c) 2022 Drew DeVault <sir@cmpwn.com>
      3 use bufio;
      4 use encoding::utf8;
      5 use errors;
      6 use fmt;
      7 use fs;
      8 use io;
      9 use os;
     10 use strings;
     11 
     12 // Path to the system MIME database.
     13 export def SYSTEM_DB: str = "/etc/mime.types";
     14 
     15 @init fn init() void = {
     16 	// Done in a separate function so we can discard errors here
     17 	load_systemdb(): void;
     18 };
     19 
     20 fn load_systemdb() (void | fs::error | io::error) = {
     21 	const file = os::open(SYSTEM_DB)?;
     22 
     23 	let buf: [os::BUFSIZ]u8 = [0...];
     24 	const strm = bufio::buffered(file, buf, []);
     25 
     26 	for (true) {
     27 		const line = match (bufio::scanline(&strm)) {
     28 		case let bytes: []u8 =>
     29 			yield match (strings::try_fromutf8(bytes)) {
     30 			case utf8::invalid =>
     31 				fmt::errorln("Warning: /etc/mime.types contains invalid UTF-8")!;
     32 				io::close(&strm)?;
     33 				io::close(file)?;
     34 				return;
     35 			case let s: str =>
     36 				yield s;
     37 			};
     38 		case let err: io::error =>
     39 			io::close(&strm): void;
     40 			io::close(file): void;
     41 			return err;
     42 		case io::EOF =>
     43 			break;
     44 		};
     45 		defer free(line);
     46 
     47 		const line = strings::trim(line);
     48 		if (strings::hasprefix(line, "#") || len(line) == 0) {
     49 			continue;
     50 		};
     51 
     52 		const items = strings::cut(line, "\t");
     53 		const mime = strings::trim(items.0),
     54 			exts = strings::trim(items.1);
     55 		if (len(exts) == 0) {
     56 			continue;
     57 		};
     58 
     59 		const tok = strings::tokenize(exts, " ");
     60 		let entry = alloc(mimetype {
     61 			mime = strings::dup(mime),
     62 			exts = [],
     63 		});
     64 		for (true) {
     65 			const ext = match (strings::next_token(&tok)) {
     66 			case let tok: str =>
     67 				yield strings::trim(tok);
     68 			case void =>
     69 				break;
     70 			};
     71 			append(entry.exts, strings::dup(ext));
     72 		};
     73 		register_heap(entry);
     74 	};
     75 
     76 	io::close(&strm)?;
     77 	io::close(file)?;
     78 };
     79 
     80 fn register_heap(mime: *mimetype...) void = {
     81 	let i = len(heap_db);
     82 	append(heap_db, mime...);
     83 	for (i < len(heap_db); i += 1) {
     84 		hashtable_insert(heap_db[i]);
     85 	};
     86 };