aboutsummaryrefslogtreecommitdiff
path: root/toys
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2017-10-31 15:30:04 -0500
committerRob Landley <rob@landley.net>2017-10-31 15:33:27 -0500
commit2d893a4077c12732238f5a9fc9c31fda8bcc3ed9 (patch)
tree7bb8e9bd127179914ba46aec0f7699a7cc71a487 /toys
parent0c284d35e533c9d49dbfe2cfe3d68e680e79a66d (diff)
downloadtoybox-2d893a4077c12732238f5a9fc9c31fda8bcc3ed9.tar.gz
Fix cut -s and -f when delimiter not found (posix says print whole line).
Diffstat (limited to 'toys')
-rw-r--r--toys/posix/cut.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/toys/posix/cut.c b/toys/posix/cut.c
index 8410e695..2676d932 100644
--- a/toys/posix/cut.c
+++ b/toys/posix/cut.c
@@ -85,6 +85,9 @@ static void cut_line(char **pline, long len)
unsigned start = pairs[2*i], end = pairs[(2*i)+1], count;
char *s = line, *ss;
+ // input: start/end position, count=difference between them
+ // output: s = start of string, len = bytes to output
+
if (start) start--;
if (start>=len) continue;
if (!end || end>len) end = len;
@@ -132,22 +135,29 @@ static void cut_line(char **pline, long len)
for (j = 0; j<2; j++) {
ss = s;
if (j) start = count;
+ else end = start;
while (*ss && start) {
if (toys.optflags&FLAG_f) {
- if (strchr(TT.d, *ss++)) start--;
+ if (!strchr(TT.d, *ss++)) continue;
+ if (!--start && j) ss--;
} else {
if (regexec(&TT.reg, ss, 1, &match, REG_NOTBOL|REG_NOTEOL)) {
ss = line+len;
continue;
}
- if (!match.rm_eo) return;
+ if (!match.rm_eo) break; // zero length match == no delimiter
ss += (!--start && j) ? match.rm_so : match.rm_eo;
}
}
- // did start run us off the end, so nothing to print?
- if (!j) if (!*(s = ss)) break;
+ if (!j && !*(s = ss)) break;
}
- if (!*s) continue;
+
+ // If we never encountered even one separator, print whole line (posix!)
+ if (!j && end == start) {
+ if (toys.optflags&FLAG_s) return;
+ fwrite(line, len, 1, stdout);
+ break;
+ } else if (!*s) continue;
count = ss-s;
}
if (i && TT.O) fputs(TT.O, stdout);