Read a file one line at a time,
as opposed to reading the entire file at once.



Related tasks

 Read a file character by character
 Input loop.


/**
 Read a file line by line, in Neko
 <doc><pre>Tectonics:
   nekoc readfile.neko
   neko readfile [filename]</pre></doc>
*/
 
 
var stdin = $loader.loadprim("std@file_stdin", 0)()
var file_open = $loader.loadprim("std@file_open", 2)
var file_read_char = $loader.loadprim("std@file_read_char", 1)
 
/* Read a line from file f into string s returning length without any newline */
var NEKO_MAX = 1 << 29 
var strsize = 256
var NEWLINE = 10
var readline = function(f) {
    var s = $smake(strsize)
    var len = 0
    var ch
    var file_exception = false
    while true {
        try ch = file_read_char(f) catch problem { file_exception = problem; break; }
        if ch == NEWLINE break;
        if $sset(s, len, ch) == null break; else len += 1
 
        if len == strsize - 1 {
            strsize *= 2
            if strsize > NEKO_MAX $throw("Out of string space for readline")
            var t = s
            s = $smake(strsize)
            $sblit(s, 0, t, 0, $ssize(t))
        }
    }
    if $istrue(file_exception) $rethrow(file_exception)
    return $ssub(s, 0, len)
}
 
var infile
var cli = $loader.args[0]
if cli == null infile = stdin
else {
    cli = $string(cli)
    try infile = file_open(cli, "r")
    catch problem $print(problem, " Can't open ", cli, "\n")
}
if infile == null $throw("Can't open " + cli)
 
var str
while true {
    try {
        str = readline(infile)
        $print(":", str, ":\n")
    } catch a break;
}
 