{"thread":{"id":"15362","subject":"[PATCH] improve handling of sideband message display","startedAt":"2008-09-03T19:13:42Z","lastAt":"2008-09-03T19:13:42Z","messageCount":1,"participants":["Nicolas Pitre"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"89671","messageId":"alpine.LFD.1.10.0809031458150.23787@xanadu.home","threadId":"15362","inReplyTo":null,"subject":"[PATCH] improve handling of sideband message display","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2008-09-03T19:13:42Z","receivedAt":"2008-09-03T19:13:42Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"\nCurrently the code looks for line break characters in order to prepend\n\"remote: \" to every line received as many lines can be sent in a single\nchunk.  However the opposite might happen too, i.e. a single message\nline split amongst multiple chunks.  This patch adds support for the\nlater case to avoid displays like:\n\n\tremote: Compressing objeremote: cts: 100% (313/313), done.\n\nSigned-off-by: Nicolas Pitre <nico@cam.org>\n---\n sideband.c |   66 +++++++++++++++++++++++++++++++++++++++--------------------\n 1 files changed, 43 insertions(+), 23 deletions(-)\n\ndiff --git a/sideband.c b/sideband.c\nindex b677781..cca3360 100644\n--- a/sideband.c\n+++ b/sideband.c\n@@ -25,6 +25,7 @@ int recv_sideband(const char *me, int in_stream, int out, int err)\n \tunsigned sf;\n \tchar buf[LARGE_PACKET_MAX + 2*FIX_SIZE];\n \tchar *suffix, *term;\n+\tint skip_pf = 0;\n \n \tmemcpy(buf, PREFIX, pf);\n \tterm = getenv(\"TERM\");\n@@ -54,39 +55,58 @@ int recv_sideband(const char *me, int in_stream, int out, int err)\n \t\t\treturn SIDEBAND_REMOTE_ERROR;\n \t\tcase 2:\n \t\t\tbuf[pf] = ' ';\n-\t\t\tlen += pf+1;\n-\t\t\twhile (1) {\n-\t\t\t\tint brk = pf+1;\n+\t\t\tdo {\n+\t\t\t\tchar *b = buf;\n+\t\t\t\tint brk = 0;\n \n-\t\t\t\t/* Break the buffer into separate lines. */\n-\t\t\t\twhile (brk < len) {\n+\t\t\t\t/*\n+\t\t\t\t * If the last buffer didn't end with a line\n+\t\t\t\t * break then we should not print a prefix\n+\t\t\t\t * this time around.\n+\t\t\t\t */\n+\t\t\t\tif (skip_pf) {\n+\t\t\t\t\tb += pf+1;\n+\t\t\t\t} else {\n+\t\t\t\t\tlen += pf+1;\n+\t\t\t\t\tbrk += pf+1;\n+\t\t\t\t}\n+\n+\t\t\t\t/* Look for a line break. */\n+\t\t\t\tfor (;;) {\n \t\t\t\t\tbrk++;\n-\t\t\t\t\tif (buf[brk-1] == '\\n' ||\n-\t\t\t\t\t    buf[brk-1] == '\\r')\n+\t\t\t\t\tif (brk > len) {\n+\t\t\t\t\t\tbrk = 0;\n+\t\t\t\t\t\tbreak;\n+\t\t\t\t\t}\n+\t\t\t\t\tif (b[brk-1] == '\\n' ||\n+\t\t\t\t\t    b[brk-1] == '\\r')\n \t\t\t\t\t\tbreak;\n \t\t\t\t}\n \n \t\t\t\t/*\n \t\t\t\t * Let's insert a suffix to clear the end\n-\t\t\t\t * of the screen line, but only if current\n-\t\t\t\t * line data actually contains something.\n+\t\t\t\t * of the screen line if a line break was\n+\t\t\t\t * found.  Also, if we don't skip the\n+\t\t\t\t * prefix, then a non-empty string must be\n+\t\t\t\t * present too.\n \t\t\t\t */\n-\t\t\t\tif (brk > pf+1 + 1) {\n+\t\t\t\tif (brk > (skip_pf ? 0 : (pf+1 + 1))) {\n \t\t\t\t\tchar save[FIX_SIZE];\n-\t\t\t\t\tmemcpy(save, buf + brk, sf);\n-\t\t\t\t\tbuf[brk + sf - 1] = buf[brk - 1];\n-\t\t\t\t\tmemcpy(buf + brk - 1, suffix, sf);\n-\t\t\t\t\tsafe_write(err, buf, brk + sf);\n-\t\t\t\t\tmemcpy(buf + brk, save, sf);\n-\t\t\t\t} else\n-\t\t\t\t\tsafe_write(err, buf, brk);\n+\t\t\t\t\tmemcpy(save, b + brk, sf);\n+\t\t\t\t\tb[brk + sf - 1] = b[brk - 1];\n+\t\t\t\t\tmemcpy(b + brk - 1, suffix, sf);\n+\t\t\t\t\tsafe_write(err, b, brk + sf);\n+\t\t\t\t\tmemcpy(b + brk, save, sf);\n+\t\t\t\t\tlen -= brk;\n+\t\t\t\t} else {\n+\t\t\t\t\tint l = brk ? brk : len;\n+\t\t\t\t\tsafe_write(err, b, l);\n+\t\t\t\t\tlen -= l;\n+\t\t\t\t}\n \n-\t\t\t\tif (brk < len) {\n-\t\t\t\t\tmemmove(buf + pf+1, buf + brk, len - brk);\n-\t\t\t\t\tlen = len - brk + pf+1;\n-\t\t\t\t} else\n-\t\t\t\t\tbreak;\n-\t\t\t}\n+\t\t\t\tskip_pf = !brk;\n+\t\t\t\tmemmove(buf + pf+1, b + brk, len);\n+\t\t\t} while (len);\n \t\t\tcontinue;\n \t\tcase 1:\n \t\t\tsafe_write(out, buf + pf+1, len);\n-- \n1.6.0.1.305.g552e0.dirty\n"}]}