@matheusbsbs / matheus-bagliano / commits / fe3403c320
Fork 0

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 <gitster@pobox.com>

Junio C Hamano committed Feb 23, 2008 at 16:59 UTC fe3403c3205de44faa926a086b4b99f157fc63fe
3 files changed +108 -108
builtin-apply.c
+3 -108
@@ -1515,110 +1515,6 @@ static int read_old_data(struct stat *st, const char *path, struct strbuf *buf)
1515 }
1516 }
1517
1518 -static int copy_wsfix(char *output, const char *patch, int plen,
1519 - unsigned ws_rule, int count_error)
1520 -{
1521 - /*
1522 - * plen is number of bytes to be copied from patch, starting
1523 - * at patch. Typically patch[plen-1] is '\n', unless this is
1524 - * the incomplete last line.
1525 - */
1526 - int i;
1527 - int add_nl_to_tail = 0;
1528 - int add_cr_to_tail = 0;
1529 - int fixed = 0;
1530 - int last_tab_in_indent = -1;
1531 - int last_space_in_indent = -1;
1532 - int need_fix_leading_space = 0;
1533 - char *buf;
1534 -
1535 - /*
1536 - * Strip trailing whitespace
1537 - */
1538 - if ((ws_rule & WS_TRAILING_SPACE) &&
1539 - (2 < plen && isspace(patch[plen-2]))) {
1540 - if (patch[plen - 1] == '\n') {
1541 - add_nl_to_tail = 1;
1542 - plen--;
1543 - if (1 < plen && patch[plen - 1] == '\r') {
1544 - add_cr_to_tail = !!(ws_rule & WS_CR_AT_EOL);
1545 - plen--;
1546 - }
1547 - }
1548 - if (0 < plen && isspace(patch[plen - 1])) {
1549 - while (0 < plen && isspace(patch[plen-1]))
1550 - plen--;
1551 - fixed = 1;
1552 - }
1553 - }
1554 -
1555 - /*
1556 - * Check leading whitespaces (indent)
1557 - */
1558 - for (i = 0; i < plen; i++) {
1559 - char ch = patch[i];
1560 - if (ch == '\t') {
1561 - last_tab_in_indent = i;
1562 - if ((ws_rule & WS_SPACE_BEFORE_TAB) &&
1563 - 0 <= last_space_in_indent)
1564 - need_fix_leading_space = 1;
1565 - } else if (ch == ' ') {
1566 - last_space_in_indent = i;
1567 - if ((ws_rule & WS_INDENT_WITH_NON_TAB) &&
1568 - 8 <= i - last_tab_in_indent)
1569 - need_fix_leading_space = 1;
1570 - } else
1571 - break;
1572 - }
1573 -
1574 - buf = output;
1575 - if (need_fix_leading_space) {
1576 - /* Process indent ourselves */
1577 - int consecutive_spaces = 0;
1578 - int last = last_tab_in_indent + 1;
1579 -
1580 - if (ws_rule & WS_INDENT_WITH_NON_TAB) {
1581 - /* have "last" point at one past the indent */
1582 - if (last_tab_in_indent < last_space_in_indent)
1583 - last = last_space_in_indent + 1;
1584 - else
1585 - last = last_tab_in_indent + 1;
1586 - }
1587 -
1588 - /*
1589 - * between patch[0..last-1], strip the funny spaces,
1590 - * updating them to tab as needed.
1591 - */
1592 - for (i = 0; i < last; i++) {
1593 - char ch = patch[i];
1594 - if (ch != ' ') {
1595 - consecutive_spaces = 0;
1596 - *output++ = ch;
1597 - } else {
1598 - consecutive_spaces++;
1599 - if (consecutive_spaces == 8) {
1600 - *output++ = '\t';
1601 - consecutive_spaces = 0;
1602 - }
1603 - }
1604 - }
1605 - while (0 < consecutive_spaces--)
1606 - *output++ = ' ';
1607 - plen -= last;
1608 - patch += last;
1609 - fixed = 1;
1610 - }
1611 -
1612 - memcpy(output, patch, plen);
1613 - if (add_cr_to_tail)
1614 - output[plen++] = '\r';
1615 - if (add_nl_to_tail)
1616 - output[plen++] = '\n';
1617 - if (fixed && count_error)
1618 - applied_after_fixing_ws++;
1619 - return output + plen - buf;
1620 -}
1621 -
1518 static void update_pre_post_images(struct image *preimage,
1519 struct image *postimage,
1520 char *buf,
@@ -1740,14 +1636,14 @@ static int match_fragment(struct image *img,
1636 int match;
1637
1638 /* Try fixing the line in the preimage */
1743 - fixlen = copy_wsfix(buf, orig, oldlen, ws_rule, 0);
1639 + fixlen = ws_fix_copy(buf, orig, oldlen, ws_rule, NULL);
1640
1641 /* Try fixing the line in the target */
1642 if (sizeof(tgtfixbuf) < tgtlen)
1643 tgtfix = tgtfixbuf;
1644 else
1645 tgtfix = xmalloc(tgtlen);
1750 - tgtfixlen = copy_wsfix(tgtfix, target, tgtlen, ws_rule, 0);
1646 + tgtfixlen = ws_fix_copy(tgtfix, target, tgtlen, ws_rule, NULL);
1647
1648 /*
1649 * If they match, either the preimage was based on
@@ -2006,8 +1902,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
1902 added = plen;
1903 }
1904 else {
2009 - added = copy_wsfix(new, patch + 1, plen,
2010 - ws_rule, 1);
1905 + added = ws_fix_copy(new, patch + 1, plen, ws_rule, &applied_after_fixing_ws);
1906 }
1907 add_line_info(&postimage, new, added,
1908 (first == '+' ? 0 : LINE_COMMON));
cache.h
+1
@@ -661,6 +661,7 @@ extern unsigned check_and_emit_line(const char *line, int len, unsigned ws_rule,
661 FILE *stream, const char *set,
662 const char *reset, const char *ws);
663 extern char *whitespace_error_string(unsigned ws);
664 +extern int ws_fix_copy(char *, const char *, int, unsigned, int *);
665
666 /* ls-files */
667 int pathspec_match(const char **spec, char *matched, const char *filename, int skiplen);
ws.c
+104
@@ -212,3 +212,107 @@ unsigned check_and_emit_line(const char *line, int len, unsigned ws_rule,
212 }
213 return result;
214 }
215 +
216 +/* Copy the line to the buffer while fixing whitespaces */
217 +int ws_fix_copy(char *dst, const char *src, int len, unsigned ws_rule, int *error_count)
218 +{
219 + /*
220 + * len is number of bytes to be copied from src, starting
221 + * at src. Typically src[len-1] is '\n', unless this is
222 + * the incomplete last line.
223 + */
224 + int i;
225 + int add_nl_to_tail = 0;
226 + int add_cr_to_tail = 0;
227 + int fixed = 0;
228 + int last_tab_in_indent = -1;
229 + int last_space_in_indent = -1;
230 + int need_fix_leading_space = 0;
231 + char *buf;
232 +
233 + /*
234 + * Strip trailing whitespace
235 + */
236 + if ((ws_rule & WS_TRAILING_SPACE) &&
237 + (2 < len && isspace(src[len-2]))) {
238 + if (src[len - 1] == '\n') {
239 + add_nl_to_tail = 1;
240 + len--;
241 + if (1 < len && src[len - 1] == '\r') {
242 + add_cr_to_tail = !!(ws_rule & WS_CR_AT_EOL);
243 + len--;
244 + }
245 + }
246 + if (0 < len && isspace(src[len - 1])) {
247 + while (0 < len && isspace(src[len-1]))
248 + len--;
249 + fixed = 1;
250 + }
251 + }
252 +
253 + /*
254 + * Check leading whitespaces (indent)
255 + */
256 + for (i = 0; i < len; i++) {
257 + char ch = src[i];
258 + if (ch == '\t') {
259 + last_tab_in_indent = i;
260 + if ((ws_rule & WS_SPACE_BEFORE_TAB) &&
261 + 0 <= last_space_in_indent)
262 + need_fix_leading_space = 1;
263 + } else if (ch == ' ') {
264 + last_space_in_indent = i;
265 + if ((ws_rule & WS_INDENT_WITH_NON_TAB) &&
266 + 8 <= i - last_tab_in_indent)
267 + need_fix_leading_space = 1;
268 + } else
269 + break;
270 + }
271 +
272 + buf = dst;
273 + if (need_fix_leading_space) {
274 + /* Process indent ourselves */
275 + int consecutive_spaces = 0;
276 + int last = last_tab_in_indent + 1;
277 +
278 + if (ws_rule & WS_INDENT_WITH_NON_TAB) {
279 + /* have "last" point at one past the indent */
280 + if (last_tab_in_indent < last_space_in_indent)
281 + last = last_space_in_indent + 1;
282 + else
283 + last = last_tab_in_indent + 1;
284 + }
285 +
286 + /*
287 + * between src[0..last-1], strip the funny spaces,
288 + * updating them to tab as needed.
289 + */
290 + for (i = 0; i < last; i++) {
291 + char ch = src[i];
292 + if (ch != ' ') {
293 + consecutive_spaces = 0;
294 + *dst++ = ch;
295 + } else {
296 + consecutive_spaces++;
297 + if (consecutive_spaces == 8) {
298 + *dst++ = '\t';
299 + consecutive_spaces = 0;
300 + }
301 + }
302 + }
303 + while (0 < consecutive_spaces--)
304 + *dst++ = ' ';
305 + len -= last;
306 + src += last;
307 + fixed = 1;
308 + }
309 +
310 + memcpy(dst, src, len);
311 + if (add_cr_to_tail)
312 + dst[len++] = '\r';
313 + if (add_nl_to_tail)
314 + dst[len++] = '\n';
315 + if (fixed && error_count)
316 + (*error_count)++;
317 + return dst + len - buf;
318 +}