diff options
author | Rob Landley <rob@landley.net> | 2017-10-31 15:30:04 -0500 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2017-10-31 15:33:27 -0500 |
commit | 2d893a4077c12732238f5a9fc9c31fda8bcc3ed9 (patch) | |
tree | 7bb8e9bd127179914ba46aec0f7699a7cc71a487 | |
parent | 0c284d35e533c9d49dbfe2cfe3d68e680e79a66d (diff) | |
download | toybox-2d893a4077c12732238f5a9fc9c31fda8bcc3ed9.tar.gz |
Fix cut -s and -f when delimiter not found (posix says print whole line).
-rw-r--r-- | toys/posix/cut.c | 20 |
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); |