hautils

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit da3b9701cc3b0453372f6df31db7a713d57fc01c
parent d1405abc2229d904805366e36b7e1c7b3f53cad0
Author: Byron Torres <b@torresjrjr.com>
Date:   Thu, 28 Apr 2022 23:00:14 +0100

nl: improve output consistency and UTF8 handling

Diffstat:
Mnl.ha | 55++++++++++++++++++++++++++++++++++---------------------
1 file changed, 34 insertions(+), 21 deletions(-)

diff --git a/nl.ha b/nl.ha @@ -34,6 +34,7 @@ type context = struct { conblanks: uint, // counter of consecutive blank lines maxblanks: uint, // 1 + maximum run of unnumbered blank lines sep: str, + sepblank: str, incr: int, mod: *fmt::modifiers, }; @@ -61,7 +62,7 @@ export fn utilmain() (void | main::error) = { usage(help, void); }; - static const delim_buf: [2]u8 = [0, 0]; + static const delim_buf: [3 * 2 * 4]u8 = [0...]; // 3 pairs of runes let delim = "\\:"; let head_style: style = none; @@ -76,6 +77,7 @@ export fn utilmain() (void | main::error) = { conblanks = 0, maxblanks = 1, sep = "\t", + sepblank = "\t", incr = 1, mod = &fmt::modifiers { width = 6, @@ -111,9 +113,11 @@ export fn utilmain() (void | main::error) = { }; }; case 'd' => - delim = switch (len(opt.1)) { + const rs = strings::runes(opt.1); + defer free(rs); + delim = switch (len(rs)) { case 1 => - yield fmt::bsprintf(delim_buf, "{}:", opt.1); + yield fmt::bsprintf(delim_buf, "{}:", rs[0]); case 2 => yield opt.1; case => @@ -173,7 +177,10 @@ export fn utilmain() (void | main::error) = { case (strconv::invalid | strconv::overflow) => usage(help, 'l'); case let maxblanks: uint => - yield if (maxblanks > 0) maxblanks else usage(help, 'l'); + yield if (maxblanks > 0) + maxblanks + else + usage(help, 'l'); }; case 'n' => ctx.mod.padding = switch (opt.1) { @@ -193,7 +200,10 @@ export fn utilmain() (void | main::error) = { case (strconv::invalid | strconv::overflow) => usage(help, 'w'); case let width: uint => - yield if (width > 0) width else usage(help, 'w'); + yield if (width > 0) + width + else + usage(help, 'w'); }; case 'v' => startnum = match (strconv::stoi(opt.1)) { @@ -233,12 +243,17 @@ export fn utilmain() (void | main::error) = { defer io::close(input)!; - static const delim_head_buf: [2 * 3]u8 = [0...]; - static const delim_body_buf: [2 * 2]u8 = [0...]; - const delim_head = fmt::bsprintf(delim_head_buf, "{0}{0}{0}", delim); - const delim_body = fmt::bsprintf(delim_body_buf, "{0}{0}", delim); + const delim_head = fmt::bsprintf(delim_buf, "{0}{0}{0}", delim); + const delim_body = fmt::bsprintf(delim_buf, "{0}{0}", delim); const delim_foot = delim; + if (ctx.sep != "\t") { + ctx.sepblank = strings::padend("", ' ', len(ctx.sep)); + }; + defer if (ctx.sep != "\t") { + free(ctx.sepblank); + }; + let section = section::BODY; ctx.linenum = startnum; @@ -293,37 +308,35 @@ fn println(line: str, s: style, ctx: *context) (void | io::error) = { match (s) { case all => if (!isblank(line)) { - fmt::printf("{%}", ctx.linenum, ctx.mod)?; - fmt::print(ctx.sep)?; + fmt::printf("{%}{}", ctx.linenum, ctx.mod, ctx.sep)?; ctx.linenum += ctx.incr; ctx.conblanks = 0; } else { ctx.conblanks += 1; if (ctx.conblanks == ctx.maxblanks) { - fmt::printf("{%}", ctx.linenum, ctx.mod)?; - fmt::print(ctx.sep)?; + fmt::printf("{%}{}", ctx.linenum, ctx.mod, ctx.sep)?; ctx.linenum += ctx.incr; ctx.conblanks = 0; + } else { + fmt::printf("{%}{}", " ", ctx.mod, ctx.sepblank)?; }; }; case nonempty => if (!isblank(line)) { - fmt::printf("{%}", ctx.linenum, ctx.mod)?; - fmt::print(ctx.sep)?; + fmt::printf("{%}{}", ctx.linenum, ctx.mod, ctx.sep)?; ctx.linenum += ctx.incr; + } else { + fmt::printf("{%}{}", " ", ctx.mod, ctx.sepblank)?; }; case none => - fmt::printf("{%}", "", ctx.mod)?; - fmt::print(ctx.sep)?; + fmt::printf("{%}{}", " ", ctx.mod, ctx.sepblank)?; case let re: regex::regex => match (regex::find(re, line)) { case []regex::matchgroup => - fmt::printf("{%}", ctx.linenum, ctx.mod)?; - fmt::print(ctx.sep)?; + fmt::printf("{%}{}", ctx.linenum, ctx.mod, ctx.sep)?; ctx.linenum += ctx.incr; case void => - fmt::printf("{%}", "", ctx.mod)?; - fmt::print(ctx.sep)?; + fmt::printf("{%}{}", " ", ctx.mod, ctx.sepblank)?; case let err: regex::error => fmt::fatal("Error: regex: {}", err); };