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