A line reader for simple text and configuration files.
It skips blank lines and # comments, can read a [version] header, and reports problems with
the file and line number through the context logger. Use file_to_array or file_to_table to
load a whole file, or a Text_File_Handler to go line by line.
Starts reading _file_data. _short_name and _full_path only label the messages the handler reports.
The text is not copied, so it must outlive the reading; deinit does not free it.
Frees the file the handler read, if any, and empties it. Safe to call twice. Starting the handler
again does it too. Lines returned earlier are no longer valid.
Removes the first line from sp and returns it, and whether there was one. A line ends at \n, \r or
\r\n. Nothing is trimmed or skipped: empty lines and comments come out as they are. At the end of
the text the result is an empty string and false.
text := "one\r\ntwo\n\nthree";
line, found := consume_next_line(*text);
assert(found && line == "one");
line, found = consume_next_line(*text);
assert(found && line == "two");
line, found = consume_next_line(*text);
assert(found && line == "");
Splits line after its first word: the word, and the rest with the spaces before it removed. Both
point into line. A line of one word gives an empty rest.
word, rest := break_by_spaces(" set volume 11 ");
assert(word == "set" && rest == "volume 11");
Logs an error for the handler, as file:line: message, through the context logger. format and args work
as in print. The logger receives the ERROR flag together with any flags given. Nothing is
written to standard output.
Like file_to_array, but returns the lines as the keys of a table, so repeated lines are kept once. The
second result is the table. The caller frees each key and the table (deinit from Hash_Table). On a
failure it is false and an empty table.