From mboxrd@z Thu Jan 1 00:00:00 1970 From: e at 80x24.org (Eric Wong) Date: Mon, 22 Apr 2019 02:39:12 +0000 Subject: [PATCH v2] ui-ssdiff: get rid of strncat In-Reply-To: <20190102073710.580-1-e@80x24.org> Message-ID: <20190422023912.GA25959@dcvr> strncat is slow and error-prone, use the git strbuf API instead. We can steal much of our logic from git/pretty.c::strbuf_add_tabexpand, but maybe keep the invalid characters for now *shrug*. --- v2: call "strbuf_add(&sb, line, linelen);" at the end to ensure tab-less lines are shown. ui-ssdiff.c | 59 +++++++++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/ui-ssdiff.c b/ui-ssdiff.c index b6dc5b0..b27ba8b 100644 --- a/ui-ssdiff.c +++ b/ui-ssdiff.c @@ -109,44 +109,37 @@ static int line_from_hunk(char *line, char type) return res; } -static char *replace_tabs(char *line) +static char *replace_tabs(const char *line) { - char *prev_buf = line; - char *cur_buf; + const size_t tabwidth = 8; size_t linelen = strlen(line); - int n_tabs = 0; - int i; - char *result; - int result_len; - - if (linelen == 0) { - result = xmalloc(1); - result[0] = '\0'; - return result; + struct strbuf sb; + const char *tab; + size_t tab_extra = 0; + + while ((tab = memchr(line, '\t', linelen)) != NULL) { + tab_extra += tabwidth - 1; + linelen -= tab + 1 - line; + line = tab + 1; } - for (i = 0; i < linelen; i++) { - if (line[i] == '\t') - n_tabs += 1; - } - result_len = linelen + n_tabs * 8; - result = xmalloc(result_len + 1); - result[0] = '\0'; - - for (;;) { - cur_buf = strchr(prev_buf, '\t'); - if (!cur_buf) { - strncat(result, prev_buf, result_len); - break; - } else { - strncat(result, prev_buf, cur_buf - prev_buf); - linelen = strlen(result); - memset(&result[linelen], ' ', 8 - (linelen % 8)); - result[linelen + 8 - (linelen % 8)] = '\0'; - } - prev_buf = cur_buf + 1; + strbuf_init(&sb, linelen + tab_extra + 1); + + /* based on git/pretty.c::strbuf_add_tabexpand: */ + while ((tab = memchr(line, '\t', linelen)) != NULL) { + /* Output the data .. */ + strbuf_add(&sb, line, tab - line); + + /* .. and the de-tabified tab */ + strbuf_addchars(&sb, ' ', tabwidth); + + /* Skip over the printed part .. */ + linelen -= tab + 1 - line; + line = tab + 1; } - return result; + strbuf_add(&sb, line, linelen); + + return strbuf_detach(&sb, NULL); } static int calc_deferred_lines(struct deferred_lines *start) -- EW