hautils

[hare] Set of POSIX utilities
Log | Files | Refs | README | LICENSE

head.ha (1480B)


      1 use bufio;
      2 use errors;
      3 use fmt;
      4 use fs;
      5 use getopt;
      6 use io;
      7 use main;
      8 use os;
      9 use strconv;
     10 
     11 export fn utilmain() (void | main::error) = {
     12 	const help: []getopt::help = [
     13 		"print the first lines of files",
     14 		('n', "lines", "print maximum number of lines"),
     15 	];
     16 	const cmd = getopt::parse(os::args, help...);
     17 	defer getopt::finish(&cmd);
     18 
     19 	let n = 10u;
     20 	for (let i = 0z; i < len(cmd.opts); i += 1) {
     21 		const opt = cmd.opts[i];
     22 		// Only opt is -n
     23 		n = match (strconv::stou(opt.1)) {
     24 		case (strconv::invalid | strconv::overflow) =>
     25 			main::usage(help, 'n');
     26 		case let n: uint =>
     27 			yield n;
     28 		};
     29 	};
     30 
     31 	if (len(cmd.args) == 0) {
     32 		head(os::stdin, n)?;
     33 	};
     34 
     35 	for (let i = 0z; i < len(cmd.args); i += 1) {
     36 		const file = match (os::open(cmd.args[i])) {
     37 		case let err: fs::error =>
     38 			fmt::fatalf("Error opening '{}': {}",
     39 				cmd.args[i], fs::strerror(err));
     40 		case let file: io::file =>
     41 			yield file;
     42 		};
     43 		static let buf: [os::BUFSZ]u8 = [0...];
     44 		const file = bufio::init(file, buf, []);
     45 		match (head(&file, n)) {
     46 		case void => void;
     47 		case let err: main::error =>
     48 			io::close(file.source): void;
     49 			return err;
     50 		};
     51 		io::close(file.source)?;
     52 	};
     53 };
     54 
     55 fn head(in: io::handle, n: uint) (void | main::error) = {
     56 	for (n > 0; n -= 1) {
     57 		let line = match (bufio::read_line(in)) {
     58 		case let err: io::error =>
     59 			return err;
     60 		case io::EOF =>
     61 			break;
     62 		case let line: []u8 =>
     63 			yield line;
     64 		};
     65 		defer free(line);
     66 		io::write(os::stdout, line)?;
     67 		fmt::println()?;
     68 	};
     69 };