| 1800 | } |
| 1801 | |
| 1802 | static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */ |
| 1803 | const char *placeholder, |
| 1804 | struct format_commit_context *c) |
| 1805 | { |
| 1806 | struct strbuf local_sb = STRBUF_INIT; |
| 1807 | size_t total_consumed = 0; |
| 1808 | int len, padding = c->padding; |
| 1809 | |
| 1810 | if (padding < 0) { |
| 1811 | const char *start = strrchr(sb->buf, '\n'); |
| 1812 | int occupied; |
| 1813 | if (!start) |
| 1814 | start = sb->buf; |
| 1815 | occupied = utf8_strnwidth(start, strlen(start), 1); |
| 1816 | occupied += c->pretty_ctx->graph_width; |
| 1817 | padding = (-padding) - occupied; |
| 1818 | } |
| 1819 | while (1) { |
| 1820 | int modifier = *placeholder == 'C'; |
| 1821 | size_t consumed = format_commit_one(&local_sb, placeholder, c); |
| 1822 | total_consumed += consumed; |
| 1823 | |
| 1824 | if (!modifier) |
| 1825 | break; |
| 1826 | |
| 1827 | placeholder += consumed; |
| 1828 | if (*placeholder != '%') |
| 1829 | break; |
| 1830 | placeholder++; |
| 1831 | total_consumed++; |
| 1832 | } |
| 1833 | len = utf8_strnwidth(local_sb.buf, local_sb.len, 1); |
| 1834 | |
| 1835 | if (c->flush_type == flush_left_and_steal) { |
| 1836 | const char *ch = sb->buf + sb->len - 1; |
| 1837 | while (len > padding && ch > sb->buf) { |
| 1838 | const char *p; |
| 1839 | if (*ch == ' ') { |
| 1840 | ch--; |
| 1841 | padding++; |
| 1842 | continue; |
| 1843 | } |
| 1844 | /* check for trailing ansi sequences */ |
| 1845 | if (*ch != 'm') |
| 1846 | break; |
| 1847 | p = ch - 1; |
| 1848 | while (p > sb->buf && ch - p < 10 && *p != '\033') |
| 1849 | p--; |
| 1850 | if (*p != '\033' || |
| 1851 | ch + 1 - p != display_mode_esc_sequence_len(p)) |
| 1852 | break; |
| 1853 | /* |
| 1854 | * got a good ansi sequence, put it back to |
| 1855 | * local_sb as we're cutting sb |
| 1856 | */ |
| 1857 | strbuf_insert(&local_sb, 0, p, ch + 1 - p); |
| 1858 | ch = p - 1; |
| 1859 | } |
no test coverage detected