1670
}
1671
1672
1673
+/*
1674
+ * Just saw a single line in a fragment. If it is a part of this hunk
1675
+ * that is a context " ", an added "+", or a removed "-" line, it may
1676
+ * be followed by "\\ No newline..." to signal that the last "\n" on
1677
+ * this line needs to be dropped. Depending on locale settings when
1678
+ * the patch was produced we don't know what this line would exactly
1679
+ * say. The only thing we do know is that it begins with "\ ".
1680
+ * Checking for 12 is just for sanity check; "\ No newline..." would
1681
+ * be at least that long in any l10n.
1682
+ *
1683
+ * Return 0 if the line we saw is not followed by "\ No newline...",
1684
+ * or length of that line. The caller will use it to skip over the
1685
+ * "\ No newline..." line.
1686
+ */
1687
+static int adjust_incomplete(const char *line, int len,
1688
+ unsigned long size)
1689
+{
1690
+ int nextlen;
1691
+
1692
+ if (*line != '\n' && *line != ' ' && *line != '+' && *line != '-')
1693
+ return 0;
1694
+ if (size - len < 12 || memcmp(line + len, "\\ ", 2))
1695
+ return 0;
1696
+ nextlen = linelen(line + len, size - len);
1697
+ if (nextlen < 12)
1698
+ return 0;
1699
+ return nextlen;
1700
+}
1701
+
1702
/*
1703
* Parse a unified diff. Note that this really needs to parse each
1704
* fragment separately, since the only way to know the difference
1713
{
1714
int added, deleted;
1715
int len = linelen(line, size), offset;
1716
+ int skip_len = 0;
1717
unsigned long oldlines, newlines;
1718
unsigned long leading, trailing;
1719
1740
len = linelen(line, size);
1741
if (!len || line[len-1] != '\n')
1742
return -1;
1743
+
1744
+ /*
1745
+ * For an incomplete line, skip_len counts the bytes
1746
+ * on "\\ No newline..." marker line that comes next
1747
+ * to the current line.
1748
+ *
1749
+ * Reduce "len" to drop the newline at the end of
1750
+ * line[], but add one to "skip_len", which will be
1751
+ * added back to "len" for the next iteration, to
1752
+ * compensate.
1753
+ */
1754
+ skip_len = adjust_incomplete(line, len, size);
1755
+ if (skip_len) {
1756
+ len--;
1757
+ skip_len++;
1758
+ }
1759
switch (*line) {
1760
default:
1761
return -1;
1791
newlines--;
1792
trailing = 0;
1793
break;
1748
-
1749
- /*
1750
- * We allow "\ No newline at end of file". Depending
1751
- * on locale settings when the patch was produced we
1752
- * don't know what this line looks like. The only
1753
- * thing we do know is that it begins with "\ ".
1754
- * Checking for 12 is just for sanity check -- any
1755
- * l10n of "\ No newline..." is at least that long.
1756
- */
1757
- case '\\':
1758
- if (len < 12 || memcmp(line, "\\ ", 2))
1759
- return -1;
1760
- break;
1794
}
1795
+
1796
+ /* eat the "\\ No newline..." as well, if exists */
1797
+ len += skip_len;
1798
}
1799
if (oldlines || newlines)
1800
return -1;
1804
fragment->leading = leading;
1805
fragment->trailing = trailing;
1806
1771
- /*
1772
- * If a fragment ends with an incomplete line, we failed to include
1773
- * it in the above loop because we hit oldlines == newlines == 0
1774
- * before seeing it.
1775
- */
1776
- if (12 < size && !memcmp(line, "\\ ", 2))
1777
- offset += linelen(line, size);
1778
-
1807
patch->lines_added += added;
1808
patch->lines_deleted += deleted;
1809