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:
M | nl.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);
};