logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git/
commit: 5efc5d6eb2d59e6f6e2f9076f33e6aa9e531fb8c
parent e904524ea5f50a8ea870fa62addb9a5d1f59c54e
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Thu, 24 Jul 2025 22:33:13 +0200

cmd/cut: add support for -z option

Diffstat:

Mcmd/cut.17+++++--
Mcmd/cut.c26++++++++++++++++----------
Mtest-cmd/cut.sh6+++---
3 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/cmd/cut.1 b/cmd/cut.1 @@ -10,15 +10,16 @@ .Sh SYNOPSIS .Nm .Fl b Ar list -.Op Fl n +.Op Fl nz .Op Ar file... .Nm .Fl c Ar list +.Op Fl z .Op Ar file... .Nm .Fl f Ar list .Op Fl d Ar delim -.Op Fl s +.Op Fl sz .Op Ar file... .Sh DESCRIPTION .Nm @@ -77,6 +78,8 @@ Do not split codepoints. (Currently unsupported in this implementation) .It Fl s Suppress lines with no delimiter characters, otherwise whole delimiter-less lines are printed as-is. +.It Fl z +Use NULL as line separator instead of newline. .El .Sh EXIT STATUS .Ex -std diff --git a/cmd/cut.c b/cmd/cut.c @@ -30,6 +30,8 @@ enum cut_mode }; char delim = '\t'; +char line_delim = '\n'; +wchar_t line_delim_w = L'\n'; bool opt_n = false, opt_s = false; enum cut_mode mode = CUT_MODE_NONE; bool *list = NULL; @@ -152,7 +154,7 @@ cut_b(FILE *in, const char *filename) while(err == 0) { errno = 0; - ssize_t nread = getline(&line, &line_len, in); + ssize_t nread = getdelim(&line, &line_len, line_delim, in); if(nread < 0) { @@ -167,7 +169,7 @@ cut_b(FILE *in, const char *filename) if(nread == 0) { - fputc('\n', stdout); + fputc(line_delim, stdout); continue; } @@ -178,7 +180,7 @@ cut_b(FILE *in, const char *filename) if(nostop && (size_t)nread > list_len) fwrite(line + list_len, nread - list_len, 1, stdout); - fputc('\n', stdout); + fputc(line_delim, stdout); } if(line_len != 0) free(line); @@ -198,7 +200,7 @@ cut_c(FILE *in, const char *filename) while(err == 0) { errno = 0; - ssize_t nread = getline(&line, &line_len, in); + ssize_t nread = getdelim(&line, &line_len, line_delim, in); if(nread < 0) { @@ -213,7 +215,7 @@ cut_c(FILE *in, const char *filename) if(nread == 0) { - fputwc(L'\n', stdout); + fputwc(line_delim_w, stdout); continue; } @@ -256,7 +258,7 @@ cut_c(FILE *in, const char *filename) fputwc(line_w[i], stdout); } - fputwc(L'\n', stdout); + fputwc(line_delim_w, stdout); } if(line_len != 0) free(line); @@ -274,7 +276,7 @@ cut_f(FILE *in, const char *filename) while(err == 0) { errno = 0; - ssize_t nread = getline(&line, &line_len, in); + ssize_t nread = getdelim(&line, &line_len, line_delim, in); if(nread < 0) { @@ -289,7 +291,7 @@ cut_f(FILE *in, const char *filename) if(nread == 0) { - fputc('\n', stdout); + fputc(line_delim, stdout); continue; } @@ -335,7 +337,7 @@ cut_f(FILE *in, const char *filename) c = line + pos + 1; } - fputc('\n', stdout); + fputc(line_delim, stdout); } if(line_len != 0) free(line); @@ -377,7 +379,7 @@ main(int argc, char *argv[]) } errno = 0; - for(int c = -1; (c = getopt_nolong(argc, argv, ":b:c:d:f:ns")) != -1;) + for(int c = -1; (c = getopt_nolong(argc, argv, ":b:c:d:f:nsz")) != -1;) { switch(c) { @@ -425,6 +427,10 @@ main(int argc, char *argv[]) case 's': opt_s = true; break; + case 'z': + line_delim = '\0'; + line_delim_w = L'\0'; + break; case ':': fprintf(stderr, "%s: error: Option '-%c' requires an operand\n", argv0, optopt); return 1; diff --git a/test-cmd/cut.sh b/test-cmd/cut.sh @@ -17,11 +17,11 @@ t_null_f2() out="$("$target" -d '' -f2 "${WD}/test-cmd/inputs/strings/length" 2>&1)" ret="$?" if [ "$?" != 0 ]; then - printf 'not ok %s - %s\n' "$count $name" "$out" + printf 'not ok %d - %s %s\n' "$count" "$name" "$out" elif [ "$out" != "$exp" ]; then - printf 'not ok %s - (%s != %s)\n' "$count $name" "$out" "$exp" + printf 'not ok %d - %s (%s != %s)\n' "$count" "$name" "$out" "$exp" else - printf 'ok %s\n' "$count $name" + printf 'ok %d - %s\n' "$count" "$name" fi }