commit: e347dbeed068198522c58c9ea5785477e17be282
parent 5e0d5c0545d8de4b3a177a09a7e0e4038f33910e
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Sat, 24 Aug 2024 06:45:58 +0200
cmd/cut: support -d ''
Diffstat:
3 files changed, 46 insertions(+), 16 deletions(-)
diff --git a/cmd/cut.1 b/cmd/cut.1
@@ -49,8 +49,9 @@ Cut codepoints based on
.Ar list .
.It Fl d Ar delim
Set the field delimiter to the character
-.Ar delim .
-(default: \t)
+.Ar delim ,
+if an empty string is passed, then NULL is used as separator.
+(default:\ \et)
.It Fl f Ar list
Cut fields based on
.Ar list .
diff --git a/cmd/cut.c b/cmd/cut.c
@@ -286,13 +286,23 @@ cut_f(FILE *in, const char *filename)
if(line[nread - 1] == '\n') line[--nread] = '\0';
- if(opt_s && strchr(line, delim) == NULL) continue;
+ if(opt_s)
+ {
+ size_t i = 0;
+ for(; i < (size_t)nread; i++)
+ if(line[i] == delim) break;
+
+ if(i == (size_t)nread) continue;
+ }
bool need_sep = false;
- size_t i = 0;
- char *toks = NULL;
- for(char *c = strtok_r(line, &delim, &toks); c != NULL; c = strtok_r(NULL, &delim, &toks), i++)
+ char *c = line;
+ for(size_t pos = 0, i = 0; pos <= (size_t)nread; pos++)
{
+ if(pos < (size_t)nread && line[pos] != delim) continue;
+
+ line[pos] = '\0';
+
if(i >= list_len)
{
if(!nostop) break;
@@ -301,16 +311,17 @@ cut_f(FILE *in, const char *filename)
fputs(c, stdout);
need_sep = true;
- continue;
}
-
- if(list[i])
+ else if(list[i])
{
if(need_sep) fputc(delim, stdout);
fputs(c, stdout);
need_sep = true;
}
+
+ i++;
+ c = line + pos + 1;
}
fputc('\n', stdout);
@@ -386,12 +397,7 @@ main(int argc, char *argv[])
opt_list = optarg;
break;
case 'd':
- if(optarg[0] == '\0')
- {
- fprintf(stderr, "cut: Option '-d' requires a character, got an empty string\n");
- return 1;
- }
- if(optarg[1] != '\0')
+ if(optarg[0] != '\0' && optarg[1] != '\0')
{
fprintf(stderr, "cut: Option '-d' only accepts single characters, got \"%s\"\n", optarg);
return 1;
diff --git a/test-cmd/cut.sh b/test-cmd/cut.sh
@@ -4,10 +4,27 @@
WD="$(dirname "$0")/../"
target="${WD}/cmd/cut"
-plans=12
+plans=15
. "${WD}/test-cmd/tap.sh"
. "${WD}/test-cmd/init_env.sh"
+t_null_f2()
+{
+ name="null_f2"
+ exp="_2"
+
+ count=$((count+1))
+ 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"
+ elif [ "$out" != "$exp" ]; then
+ printf 'not ok %s - (%s != %s)\n' "$count $name" "$out" "$exp"
+ else
+ printf 'ok %s\n' "$count $name"
+ fi
+}
+
t 'bytes:2-3,10-20,4,12' "-b 2-3,10-20,4,12 ${WD}/test-cmd/inputs/alnum" '1239ABCDEFGHIJ
'
t 'bytes:11-' "-b 11- ${WD}/test-cmd/inputs/alnum" 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
@@ -49,3 +66,9 @@ t --input="$fields" f-2 '-f-2' '1 2
a b
'
+
+t --input="hello" 'hello_f1' '-f1' 'hello
+'
+t --input="hello" 'hello_f1_s' '-f1 -s'
+
+t_null_f2