diff options
author | dgp <dgp@users.sourceforge.net> | 2014-03-10 19:00:19 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2014-03-10 19:00:19 (GMT) |
commit | dd5ac1c6419faed6fedef71a19409cb52335353c (patch) | |
tree | a086b48ece22286ad20d0a2c2a7664f089f47d32 /generic | |
parent | 091096d315755aa89f28bd063b426e16a4c16e51 (diff) | |
download | tcl-dd5ac1c6419faed6fedef71a19409cb52335353c.zip tcl-dd5ac1c6419faed6fedef71a19409cb52335353c.tar.gz tcl-dd5ac1c6419faed6fedef71a19409cb52335353c.tar.bz2 |
Rewrite CRLF translation to use more system calls.
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclIO.c | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index 2971838..1070f0a 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5645,28 +5645,38 @@ TranslateInputEOL( dstLen = srcLen; break; case TCL_TRANSLATE_CRLF: { - const char *srcEnd = srcStart + srcLen; - const char *dstEnd = dstStart + dstLen; - const char *src = srcStart; + const char *crFound, *src = srcStart; char *dst = dstStart; - - for ( ; dst < dstEnd && src < srcEnd; ) { - if (*src == '\r') { - src++; - if (src == srcEnd) { - src--; - break; - } else if (*src == '\n') { - *dst++ = *src++; - } else { - *dst++ = '\r'; - } + int lesser = (dstLen < srcLen) ? dstLen : srcLen; + + while ((crFound = memchr(src, '\r', lesser))) { + int numBytes = crFound - src; + memmove(dst, src, numBytes); + + dst += numBytes; + src += numBytes; + dstLen -= numBytes; + srcLen -= numBytes; + if (srcLen == 1) { + /* valid src bytes end in \r */ + lesser = 0; + break; + } + if (src[1] == '\n') { + *dst++ = '\n'; + srcLen -= 2; + src += 2; } else { - *dst++ = *src++; + *dst++ = '\r'; + srcLen--; + src++; } + dstLen++; + lesser = (dstLen < srcLen) ? dstLen : srcLen; } - srcLen = src - srcStart; - dstLen = dst - dstStart; + memmove(dst, src, lesser); + srcLen = src + lesser - srcStart; + dstLen = dst + lesser - dstStart; break; } case TCL_TRANSLATE_AUTO: { |