From: Junio C Hamano Date: Sun, 24 Feb 2008 00:59:16 +0000 (-0800) Subject: ws_fix_copy(): move the whitespace fixing function to ws.c X-Git-Tag: v1.5.5-rc0~156^2 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=fe3403c3205de44faa926a086b4b99f157fc63fe;p=git.git ws_fix_copy(): move the whitespace fixing function to ws.c This is used by git-apply but we can use it elsewhere by slightly generalizing it. Signed-off-by: Junio C Hamano --- diff --git a/builtin-apply.c b/builtin-apply.c index 5ed4e918c..64471a27e 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -1515,110 +1515,6 @@ static int read_old_data(struct stat *st, const char *path, struct strbuf *buf) } } -static int copy_wsfix(char *output, const char *patch, int plen, - unsigned ws_rule, int count_error) -{ - /* - * plen is number of bytes to be copied from patch, starting - * at patch. Typically patch[plen-1] is '\n', unless this is - * the incomplete last line. - */ - int i; - int add_nl_to_tail = 0; - int add_cr_to_tail = 0; - int fixed = 0; - int last_tab_in_indent = -1; - int last_space_in_indent = -1; - int need_fix_leading_space = 0; - char *buf; - - /* - * Strip trailing whitespace - */ - if ((ws_rule & WS_TRAILING_SPACE) && - (2 < plen && isspace(patch[plen-2]))) { - if (patch[plen - 1] == '\n') { - add_nl_to_tail = 1; - plen--; - if (1 < plen && patch[plen - 1] == '\r') { - add_cr_to_tail = !!(ws_rule & WS_CR_AT_EOL); - plen--; - } - } - if (0 < plen && isspace(patch[plen - 1])) { - while (0 < plen && isspace(patch[plen-1])) - plen--; - fixed = 1; - } - } - - /* - * Check leading whitespaces (indent) - */ - for (i = 0; i < plen; i++) { - char ch = patch[i]; - if (ch == '\t') { - last_tab_in_indent = i; - if ((ws_rule & WS_SPACE_BEFORE_TAB) && - 0 <= last_space_in_indent) - need_fix_leading_space = 1; - } else if (ch == ' ') { - last_space_in_indent = i; - if ((ws_rule & WS_INDENT_WITH_NON_TAB) && - 8 <= i - last_tab_in_indent) - need_fix_leading_space = 1; - } else - break; - } - - buf = output; - if (need_fix_leading_space) { - /* Process indent ourselves */ - int consecutive_spaces = 0; - int last = last_tab_in_indent + 1; - - if (ws_rule & WS_INDENT_WITH_NON_TAB) { - /* have "last" point at one past the indent */ - if (last_tab_in_indent < last_space_in_indent) - last = last_space_in_indent + 1; - else - last = last_tab_in_indent + 1; - } - - /* - * between patch[0..last-1], strip the funny spaces, - * updating them to tab as needed. - */ - for (i = 0; i < last; i++) { - char ch = patch[i]; - if (ch != ' ') { - consecutive_spaces = 0; - *output++ = ch; - } else { - consecutive_spaces++; - if (consecutive_spaces == 8) { - *output++ = '\t'; - consecutive_spaces = 0; - } - } - } - while (0 < consecutive_spaces--) - *output++ = ' '; - plen -= last; - patch += last; - fixed = 1; - } - - memcpy(output, patch, plen); - if (add_cr_to_tail) - output[plen++] = '\r'; - if (add_nl_to_tail) - output[plen++] = '\n'; - if (fixed && count_error) - applied_after_fixing_ws++; - return output + plen - buf; -} - static void update_pre_post_images(struct image *preimage, struct image *postimage, char *buf, @@ -1740,14 +1636,14 @@ static int match_fragment(struct image *img, int match; /* Try fixing the line in the preimage */ - fixlen = copy_wsfix(buf, orig, oldlen, ws_rule, 0); + fixlen = ws_fix_copy(buf, orig, oldlen, ws_rule, NULL); /* Try fixing the line in the target */ if (sizeof(tgtfixbuf) < tgtlen) tgtfix = tgtfixbuf; else tgtfix = xmalloc(tgtlen); - tgtfixlen = copy_wsfix(tgtfix, target, tgtlen, ws_rule, 0); + tgtfixlen = ws_fix_copy(tgtfix, target, tgtlen, ws_rule, NULL); /* * If they match, either the preimage was based on @@ -2006,8 +1902,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag, added = plen; } else { - added = copy_wsfix(new, patch + 1, plen, - ws_rule, 1); + added = ws_fix_copy(new, patch + 1, plen, ws_rule, &applied_after_fixing_ws); } add_line_info(&postimage, new, added, (first == '+' ? 0 : LINE_COMMON)); diff --git a/cache.h b/cache.h index ad11c90ca..3d4c6b078 100644 --- a/cache.h +++ b/cache.h @@ -661,6 +661,7 @@ extern unsigned check_and_emit_line(const char *line, int len, unsigned ws_rule, FILE *stream, const char *set, const char *reset, const char *ws); extern char *whitespace_error_string(unsigned ws); +extern int ws_fix_copy(char *, const char *, int, unsigned, int *); /* ls-files */ int pathspec_match(const char **spec, char *matched, const char *filename, int skiplen); diff --git a/ws.c b/ws.c index 5a9ac457d..522f646ed 100644 --- a/ws.c +++ b/ws.c @@ -212,3 +212,107 @@ unsigned check_and_emit_line(const char *line, int len, unsigned ws_rule, } return result; } + +/* Copy the line to the buffer while fixing whitespaces */ +int ws_fix_copy(char *dst, const char *src, int len, unsigned ws_rule, int *error_count) +{ + /* + * len is number of bytes to be copied from src, starting + * at src. Typically src[len-1] is '\n', unless this is + * the incomplete last line. + */ + int i; + int add_nl_to_tail = 0; + int add_cr_to_tail = 0; + int fixed = 0; + int last_tab_in_indent = -1; + int last_space_in_indent = -1; + int need_fix_leading_space = 0; + char *buf; + + /* + * Strip trailing whitespace + */ + if ((ws_rule & WS_TRAILING_SPACE) && + (2 < len && isspace(src[len-2]))) { + if (src[len - 1] == '\n') { + add_nl_to_tail = 1; + len--; + if (1 < len && src[len - 1] == '\r') { + add_cr_to_tail = !!(ws_rule & WS_CR_AT_EOL); + len--; + } + } + if (0 < len && isspace(src[len - 1])) { + while (0 < len && isspace(src[len-1])) + len--; + fixed = 1; + } + } + + /* + * Check leading whitespaces (indent) + */ + for (i = 0; i < len; i++) { + char ch = src[i]; + if (ch == '\t') { + last_tab_in_indent = i; + if ((ws_rule & WS_SPACE_BEFORE_TAB) && + 0 <= last_space_in_indent) + need_fix_leading_space = 1; + } else if (ch == ' ') { + last_space_in_indent = i; + if ((ws_rule & WS_INDENT_WITH_NON_TAB) && + 8 <= i - last_tab_in_indent) + need_fix_leading_space = 1; + } else + break; + } + + buf = dst; + if (need_fix_leading_space) { + /* Process indent ourselves */ + int consecutive_spaces = 0; + int last = last_tab_in_indent + 1; + + if (ws_rule & WS_INDENT_WITH_NON_TAB) { + /* have "last" point at one past the indent */ + if (last_tab_in_indent < last_space_in_indent) + last = last_space_in_indent + 1; + else + last = last_tab_in_indent + 1; + } + + /* + * between src[0..last-1], strip the funny spaces, + * updating them to tab as needed. + */ + for (i = 0; i < last; i++) { + char ch = src[i]; + if (ch != ' ') { + consecutive_spaces = 0; + *dst++ = ch; + } else { + consecutive_spaces++; + if (consecutive_spaces == 8) { + *dst++ = '\t'; + consecutive_spaces = 0; + } + } + } + while (0 < consecutive_spaces--) + *dst++ = ' '; + len -= last; + src += last; + fixed = 1; + } + + memcpy(dst, src, len); + if (add_cr_to_tail) + dst[len++] = '\r'; + if (add_nl_to_tail) + dst[len++] = '\n'; + if (fixed && error_count) + (*error_count)++; + return dst + len - buf; +}