THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

860 lines
18 KiB

  1. #include "cache.h"
  2. #include "refs.h"
  3. #include "utf8.h"
  4. int starts_with(const char *str, const char *prefix)
  5. {
  6. for (; ; str++, prefix++)
  7. if (!*prefix)
  8. return 1;
  9. else if (*str != *prefix)
  10. return 0;
  11. }
  12. /*
  13. * Used as the default ->buf value, so that people can always assume
  14. * buf is non NULL and ->buf is NUL terminated even for a freshly
  15. * initialized strbuf.
  16. */
  17. char strbuf_slopbuf[1];
  18. void strbuf_init(struct strbuf *sb, size_t hint)
  19. {
  20. sb->alloc = sb->len = 0;
  21. sb->buf = strbuf_slopbuf;
  22. if (hint)
  23. strbuf_grow(sb, hint);
  24. }
  25. void strbuf_release(struct strbuf *sb)
  26. {
  27. if (sb->alloc) {
  28. free(sb->buf);
  29. strbuf_init(sb, 0);
  30. }
  31. }
  32. char *strbuf_detach(struct strbuf *sb, size_t *sz)
  33. {
  34. char *res;
  35. strbuf_grow(sb, 0);
  36. res = sb->buf;
  37. if (sz)
  38. *sz = sb->len;
  39. strbuf_init(sb, 0);
  40. return res;
  41. }
  42. void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc)
  43. {
  44. strbuf_release(sb);
  45. sb->buf = buf;
  46. sb->len = len;
  47. sb->alloc = alloc;
  48. strbuf_grow(sb, 0);
  49. sb->buf[sb->len] = '\0';
  50. }
  51. void strbuf_grow(struct strbuf *sb, size_t extra)
  52. {
  53. int new_buf = !sb->alloc;
  54. if (unsigned_add_overflows(extra, 1) ||
  55. unsigned_add_overflows(sb->len, extra + 1))
  56. die("you want to use way too much memory");
  57. if (new_buf)
  58. sb->buf = NULL;
  59. ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
  60. if (new_buf)
  61. sb->buf[0] = '\0';
  62. }
  63. void strbuf_trim(struct strbuf *sb)
  64. {
  65. strbuf_rtrim(sb);
  66. strbuf_ltrim(sb);
  67. }
  68. void strbuf_rtrim(struct strbuf *sb)
  69. {
  70. while (sb->len > 0 && isspace((unsigned char)sb->buf[sb->len - 1]))
  71. sb->len--;
  72. sb->buf[sb->len] = '\0';
  73. }
  74. void strbuf_ltrim(struct strbuf *sb)
  75. {
  76. char *b = sb->buf;
  77. while (sb->len > 0 && isspace(*b)) {
  78. b++;
  79. sb->len--;
  80. }
  81. memmove(sb->buf, b, sb->len);
  82. sb->buf[sb->len] = '\0';
  83. }
  84. int strbuf_reencode(struct strbuf *sb, const char *from, const char *to)
  85. {
  86. char *out;
  87. int len;
  88. if (same_encoding(from, to))
  89. return 0;
  90. out = reencode_string_len(sb->buf, sb->len, to, from, &len);
  91. if (!out)
  92. return -1;
  93. strbuf_attach(sb, out, len, len);
  94. return 0;
  95. }
  96. void strbuf_tolower(struct strbuf *sb)
  97. {
  98. char *p = sb->buf, *end = sb->buf + sb->len;
  99. for (; p < end; p++)
  100. *p = tolower(*p);
  101. }
  102. struct strbuf **strbuf_split_buf(const char *str, size_t slen,
  103. int terminator, int max)
  104. {
  105. struct strbuf **ret = NULL;
  106. size_t nr = 0, alloc = 0;
  107. struct strbuf *t;
  108. while (slen) {
  109. int len = slen;
  110. if (max <= 0 || nr + 1 < max) {
  111. const char *end = memchr(str, terminator, slen);
  112. if (end)
  113. len = end - str + 1;
  114. }
  115. t = xmalloc(sizeof(struct strbuf));
  116. strbuf_init(t, len);
  117. strbuf_add(t, str, len);
  118. ALLOC_GROW(ret, nr + 2, alloc);
  119. ret[nr++] = t;
  120. str += len;
  121. slen -= len;
  122. }
  123. ALLOC_GROW(ret, nr + 1, alloc); /* In case string was empty */
  124. ret[nr] = NULL;
  125. return ret;
  126. }
  127. void strbuf_list_free(struct strbuf **sbs)
  128. {
  129. struct strbuf **s = sbs;
  130. while (*s) {
  131. strbuf_release(*s);
  132. free(*s++);
  133. }
  134. free(sbs);
  135. }
  136. int strbuf_cmp(const struct strbuf *a, const struct strbuf *b)
  137. {
  138. int len = a->len < b->len ? a->len: b->len;
  139. int cmp = memcmp(a->buf, b->buf, len);
  140. if (cmp)
  141. return cmp;
  142. return a->len < b->len ? -1: a->len != b->len;
  143. }
  144. void strbuf_splice(struct strbuf *sb, size_t pos, size_t len,
  145. const void *data, size_t dlen)
  146. {
  147. if (unsigned_add_overflows(pos, len))
  148. die("you want to use way too much memory");
  149. if (pos > sb->len)
  150. die("`pos' is too far after the end of the buffer");
  151. if (pos + len > sb->len)
  152. die("`pos + len' is too far after the end of the buffer");
  153. if (dlen >= len)
  154. strbuf_grow(sb, dlen - len);
  155. memmove(sb->buf + pos + dlen,
  156. sb->buf + pos + len,
  157. sb->len - pos - len);
  158. memcpy(sb->buf + pos, data, dlen);
  159. strbuf_setlen(sb, sb->len + dlen - len);
  160. }
  161. void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len)
  162. {
  163. strbuf_splice(sb, pos, 0, data, len);
  164. }
  165. void strbuf_remove(struct strbuf *sb, size_t pos, size_t len)
  166. {
  167. strbuf_splice(sb, pos, len, NULL, 0);
  168. }
  169. void strbuf_add(struct strbuf *sb, const void *data, size_t len)
  170. {
  171. strbuf_grow(sb, len);
  172. memcpy(sb->buf + sb->len, data, len);
  173. strbuf_setlen(sb, sb->len + len);
  174. }
  175. void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len)
  176. {
  177. strbuf_grow(sb, len);
  178. memcpy(sb->buf + sb->len, sb->buf + pos, len);
  179. strbuf_setlen(sb, sb->len + len);
  180. }
  181. void strbuf_addchars(struct strbuf *sb, int c, size_t n)
  182. {
  183. strbuf_grow(sb, n);
  184. memset(sb->buf + sb->len, c, n);
  185. strbuf_setlen(sb, sb->len + n);
  186. }
  187. void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
  188. {
  189. va_list ap;
  190. va_start(ap, fmt);
  191. strbuf_vaddf(sb, fmt, ap);
  192. va_end(ap);
  193. }
  194. static void add_lines(struct strbuf *out,
  195. const char *prefix1,
  196. const char *prefix2,
  197. const char *buf, size_t size)
  198. {
  199. while (size) {
  200. const char *prefix;
  201. const char *next = memchr(buf, '\n', size);
  202. next = next ? (next + 1) : (buf + size);
  203. prefix = ((prefix2 && (buf[0] == '\n' || buf[0] == '\t'))
  204. ? prefix2 : prefix1);
  205. strbuf_addstr(out, prefix);
  206. strbuf_add(out, buf, next - buf);
  207. size -= next - buf;
  208. buf = next;
  209. }
  210. strbuf_complete_line(out);
  211. }
  212. void strbuf_add_commented_lines(struct strbuf *out, const char *buf, size_t size)
  213. {
  214. static char prefix1[3];
  215. static char prefix2[2];
  216. if (prefix1[0] != comment_line_char) {
  217. xsnprintf(prefix1, sizeof(prefix1), "%c ", comment_line_char);
  218. xsnprintf(prefix2, sizeof(prefix2), "%c", comment_line_char);
  219. }
  220. add_lines(out, prefix1, prefix2, buf, size);
  221. }
  222. void strbuf_commented_addf(struct strbuf *sb, const char *fmt, ...)
  223. {
  224. va_list params;
  225. struct strbuf buf = STRBUF_INIT;
  226. int incomplete_line = sb->len && sb->buf[sb->len - 1] != '\n';
  227. va_start(params, fmt);
  228. strbuf_vaddf(&buf, fmt, params);
  229. va_end(params);
  230. strbuf_add_commented_lines(sb, buf.buf, buf.len);
  231. if (incomplete_line)
  232. sb->buf[--sb->len] = '\0';
  233. strbuf_release(&buf);
  234. }
  235. void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap)
  236. {
  237. int len;
  238. va_list cp;
  239. if (!strbuf_avail(sb))
  240. strbuf_grow(sb, 64);
  241. va_copy(cp, ap);
  242. len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, cp);
  243. va_end(cp);
  244. if (len < 0)
  245. die("BUG: your vsnprintf is broken (returned %d)", len);
  246. if (len > strbuf_avail(sb)) {
  247. strbuf_grow(sb, len);
  248. len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
  249. if (len > strbuf_avail(sb))
  250. die("BUG: your vsnprintf is broken (insatiable)");
  251. }
  252. strbuf_setlen(sb, sb->len + len);
  253. }
  254. void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn,
  255. void *context)
  256. {
  257. for (;;) {
  258. const char *percent;
  259. size_t consumed;
  260. percent = strchrnul(format, '%');
  261. strbuf_add(sb, format, percent - format);
  262. if (!*percent)
  263. break;
  264. format = percent + 1;
  265. if (*format == '%') {
  266. strbuf_addch(sb, '%');
  267. format++;
  268. continue;
  269. }
  270. consumed = fn(sb, format, context);
  271. if (consumed)
  272. format += consumed;
  273. else
  274. strbuf_addch(sb, '%');
  275. }
  276. }
  277. size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder,
  278. void *context)
  279. {
  280. struct strbuf_expand_dict_entry *e = context;
  281. size_t len;
  282. for (; e->placeholder && (len = strlen(e->placeholder)); e++) {
  283. if (!strncmp(placeholder, e->placeholder, len)) {
  284. if (e->value)
  285. strbuf_addstr(sb, e->value);
  286. return len;
  287. }
  288. }
  289. return 0;
  290. }
  291. void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src)
  292. {
  293. int i, len = src->len;
  294. for (i = 0; i < len; i++) {
  295. if (src->buf[i] == '%')
  296. strbuf_addch(dst, '%');
  297. strbuf_addch(dst, src->buf[i]);
  298. }
  299. }
  300. size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f)
  301. {
  302. size_t res;
  303. size_t oldalloc = sb->alloc;
  304. strbuf_grow(sb, size);
  305. res = fread(sb->buf + sb->len, 1, size, f);
  306. if (res > 0)
  307. strbuf_setlen(sb, sb->len + res);
  308. else if (oldalloc == 0)
  309. strbuf_release(sb);
  310. return res;
  311. }
  312. ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint)
  313. {
  314. size_t oldlen = sb->len;
  315. size_t oldalloc = sb->alloc;
  316. strbuf_grow(sb, hint ? hint : 8192);
  317. for (;;) {
  318. ssize_t want = sb->alloc - sb->len - 1;
  319. ssize_t got = read_in_full(fd, sb->buf + sb->len, want);
  320. if (got < 0) {
  321. if (oldalloc == 0)
  322. strbuf_release(sb);
  323. else
  324. strbuf_setlen(sb, oldlen);
  325. return -1;
  326. }
  327. sb->len += got;
  328. if (got < want)
  329. break;
  330. strbuf_grow(sb, 8192);
  331. }
  332. sb->buf[sb->len] = '\0';
  333. return sb->len - oldlen;
  334. }
  335. ssize_t strbuf_read_once(struct strbuf *sb, int fd, size_t hint)
  336. {
  337. ssize_t cnt;
  338. strbuf_grow(sb, hint ? hint : 8192);
  339. cnt = xread(fd, sb->buf + sb->len, sb->alloc - sb->len - 1);
  340. if (cnt > 0)
  341. strbuf_setlen(sb, sb->len + cnt);
  342. return cnt;
  343. }
  344. #define STRBUF_MAXLINK (2*PATH_MAX)
  345. int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint)
  346. {
  347. size_t oldalloc = sb->alloc;
  348. if (hint < 32)
  349. hint = 32;
  350. while (hint < STRBUF_MAXLINK) {
  351. int len;
  352. strbuf_grow(sb, hint);
  353. len = readlink(path, sb->buf, hint);
  354. if (len < 0) {
  355. if (errno != ERANGE)
  356. break;
  357. } else if (len < hint) {
  358. strbuf_setlen(sb, len);
  359. return 0;
  360. }
  361. /* .. the buffer was too small - try again */
  362. hint *= 2;
  363. }
  364. if (oldalloc == 0)
  365. strbuf_release(sb);
  366. return -1;
  367. }
  368. int strbuf_getcwd(struct strbuf *sb)
  369. {
  370. size_t oldalloc = sb->alloc;
  371. size_t guessed_len = 128;
  372. for (;; guessed_len *= 2) {
  373. strbuf_grow(sb, guessed_len);
  374. if (getcwd(sb->buf, sb->alloc)) {
  375. strbuf_setlen(sb, strlen(sb->buf));
  376. return 0;
  377. }
  378. if (errno != ERANGE)
  379. break;
  380. }
  381. if (oldalloc == 0)
  382. strbuf_release(sb);
  383. else
  384. strbuf_reset(sb);
  385. return -1;
  386. }
  387. #ifdef HAVE_GETDELIM
  388. int strbuf_getwholeline(struct strbuf *sb, FILE *fp, int term)
  389. {
  390. ssize_t r;
  391. if (feof(fp))
  392. return EOF;
  393. strbuf_reset(sb);
  394. /* Translate slopbuf to NULL, as we cannot call realloc on it */
  395. if (!sb->alloc)
  396. sb->buf = NULL;
  397. r = getdelim(&sb->buf, &sb->alloc, term, fp);
  398. if (r > 0) {
  399. sb->len = r;
  400. return 0;
  401. }
  402. assert(r == -1);
  403. /*
  404. * Normally we would have called xrealloc, which will try to free
  405. * memory and recover. But we have no way to tell getdelim() to do so.
  406. * Worse, we cannot try to recover ENOMEM ourselves, because we have
  407. * no idea how many bytes were read by getdelim.
  408. *
  409. * Dying here is reasonable. It mirrors what xrealloc would do on
  410. * catastrophic memory failure. We skip the opportunity to free pack
  411. * memory and retry, but that's unlikely to help for a malloc small
  412. * enough to hold a single line of input, anyway.
  413. */
  414. if (errno == ENOMEM)
  415. die("Out of memory, getdelim failed");
  416. /*
  417. * Restore strbuf invariants; if getdelim left us with a NULL pointer,
  418. * we can just re-init, but otherwise we should make sure that our
  419. * length is empty, and that the result is NUL-terminated.
  420. */
  421. if (!sb->buf)
  422. strbuf_init(sb, 0);
  423. else
  424. strbuf_reset(sb);
  425. return EOF;
  426. }
  427. #else
  428. int strbuf_getwholeline(struct strbuf *sb, FILE *fp, int term)
  429. {
  430. int ch;
  431. if (feof(fp))
  432. return EOF;
  433. strbuf_reset(sb);
  434. flockfile(fp);
  435. while ((ch = getc_unlocked(fp)) != EOF) {
  436. if (!strbuf_avail(sb))
  437. strbuf_grow(sb, 1);
  438. sb->buf[sb->len++] = ch;
  439. if (ch == term)
  440. break;
  441. }
  442. funlockfile(fp);
  443. if (ch == EOF && sb->len == 0)
  444. return EOF;
  445. sb->buf[sb->len] = '\0';
  446. return 0;
  447. }
  448. #endif
  449. static int strbuf_getdelim(struct strbuf *sb, FILE *fp, int term)
  450. {
  451. if (strbuf_getwholeline(sb, fp, term))
  452. return EOF;
  453. if (sb->buf[sb->len - 1] == term)
  454. strbuf_setlen(sb, sb->len - 1);
  455. return 0;
  456. }
  457. int strbuf_getline(struct strbuf *sb, FILE *fp)
  458. {
  459. if (strbuf_getwholeline(sb, fp, '\n'))
  460. return EOF;
  461. if (sb->buf[sb->len - 1] == '\n') {
  462. strbuf_setlen(sb, sb->len - 1);
  463. if (sb->len && sb->buf[sb->len - 1] == '\r')
  464. strbuf_setlen(sb, sb->len - 1);
  465. }
  466. return 0;
  467. }
  468. int strbuf_getline_lf(struct strbuf *sb, FILE *fp)
  469. {
  470. return strbuf_getdelim(sb, fp, '\n');
  471. }
  472. int strbuf_getline_nul(struct strbuf *sb, FILE *fp)
  473. {
  474. return strbuf_getdelim(sb, fp, '\0');
  475. }
  476. int strbuf_getwholeline_fd(struct strbuf *sb, int fd, int term)
  477. {
  478. strbuf_reset(sb);
  479. while (1) {
  480. char ch;
  481. ssize_t len = xread(fd, &ch, 1);
  482. if (len <= 0)
  483. return EOF;
  484. strbuf_addch(sb, ch);
  485. if (ch == term)
  486. break;
  487. }
  488. return 0;
  489. }
  490. ssize_t strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
  491. {
  492. int fd;
  493. ssize_t len;
  494. fd = open(path, O_RDONLY);
  495. if (fd < 0)
  496. return -1;
  497. len = strbuf_read(sb, fd, hint);
  498. close(fd);
  499. if (len < 0)
  500. return -1;
  501. return len;
  502. }
  503. void strbuf_add_lines(struct strbuf *out, const char *prefix,
  504. const char *buf, size_t size)
  505. {
  506. add_lines(out, prefix, NULL, buf, size);
  507. }
  508. void strbuf_addstr_xml_quoted(struct strbuf *buf, const char *s)
  509. {
  510. while (*s) {
  511. size_t len = strcspn(s, "\"<>&");
  512. strbuf_add(buf, s, len);
  513. s += len;
  514. switch (*s) {
  515. case '"':
  516. strbuf_addstr(buf, "&quot;");
  517. break;
  518. case '<':
  519. strbuf_addstr(buf, "&lt;");
  520. break;
  521. case '>':
  522. strbuf_addstr(buf, "&gt;");
  523. break;
  524. case '&':
  525. strbuf_addstr(buf, "&amp;");
  526. break;
  527. case 0:
  528. return;
  529. }
  530. s++;
  531. }
  532. }
  533. static int is_rfc3986_reserved(char ch)
  534. {
  535. switch (ch) {
  536. case '!': case '*': case '\'': case '(': case ')': case ';':
  537. case ':': case '@': case '&': case '=': case '+': case '$':
  538. case ',': case '/': case '?': case '#': case '[': case ']':
  539. return 1;
  540. }
  541. return 0;
  542. }
  543. static int is_rfc3986_unreserved(char ch)
  544. {
  545. return isalnum(ch) ||
  546. ch == '-' || ch == '_' || ch == '.' || ch == '~';
  547. }
  548. static void strbuf_add_urlencode(struct strbuf *sb, const char *s, size_t len,
  549. int reserved)
  550. {
  551. strbuf_grow(sb, len);
  552. while (len--) {
  553. char ch = *s++;
  554. if (is_rfc3986_unreserved(ch) ||
  555. (!reserved && is_rfc3986_reserved(ch)))
  556. strbuf_addch(sb, ch);
  557. else
  558. strbuf_addf(sb, "%%%02x", ch);
  559. }
  560. }
  561. void strbuf_addstr_urlencode(struct strbuf *sb, const char *s,
  562. int reserved)
  563. {
  564. strbuf_add_urlencode(sb, s, strlen(s), reserved);
  565. }
  566. void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes)
  567. {
  568. if (bytes > 1 << 30) {
  569. strbuf_addf(buf, "%u.%2.2u GiB",
  570. (int)(bytes >> 30),
  571. (int)(bytes & ((1 << 30) - 1)) / 10737419);
  572. } else if (bytes > 1 << 20) {
  573. int x = bytes + 5243; /* for rounding */
  574. strbuf_addf(buf, "%u.%2.2u MiB",
  575. x >> 20, ((x & ((1 << 20) - 1)) * 100) >> 20);
  576. } else if (bytes > 1 << 10) {
  577. int x = bytes + 5; /* for rounding */
  578. strbuf_addf(buf, "%u.%2.2u KiB",
  579. x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10);
  580. } else {
  581. strbuf_addf(buf, "%u bytes", (int)bytes);
  582. }
  583. }
  584. void strbuf_add_absolute_path(struct strbuf *sb, const char *path)
  585. {
  586. if (!*path)
  587. die("The empty string is not a valid path");
  588. if (!is_absolute_path(path)) {
  589. struct stat cwd_stat, pwd_stat;
  590. size_t orig_len = sb->len;
  591. char *cwd = xgetcwd();
  592. char *pwd = getenv("PWD");
  593. if (pwd && strcmp(pwd, cwd) &&
  594. !stat(cwd, &cwd_stat) &&
  595. (cwd_stat.st_dev || cwd_stat.st_ino) &&
  596. !stat(pwd, &pwd_stat) &&
  597. pwd_stat.st_dev == cwd_stat.st_dev &&
  598. pwd_stat.st_ino == cwd_stat.st_ino)
  599. strbuf_addstr(sb, pwd);
  600. else
  601. strbuf_addstr(sb, cwd);
  602. if (sb->len > orig_len && !is_dir_sep(sb->buf[sb->len - 1]))
  603. strbuf_addch(sb, '/');
  604. free(cwd);
  605. }
  606. strbuf_addstr(sb, path);
  607. }
  608. int printf_ln(const char *fmt, ...)
  609. {
  610. int ret;
  611. va_list ap;
  612. va_start(ap, fmt);
  613. ret = vprintf(fmt, ap);
  614. va_end(ap);
  615. if (ret < 0 || putchar('\n') == EOF)
  616. return -1;
  617. return ret + 1;
  618. }
  619. int fprintf_ln(FILE *fp, const char *fmt, ...)
  620. {
  621. int ret;
  622. va_list ap;
  623. va_start(ap, fmt);
  624. ret = vfprintf(fp, fmt, ap);
  625. va_end(ap);
  626. if (ret < 0 || putc('\n', fp) == EOF)
  627. return -1;
  628. return ret + 1;
  629. }
  630. char *xstrdup_tolower(const char *string)
  631. {
  632. char *result;
  633. size_t len, i;
  634. len = strlen(string);
  635. result = xmallocz(len);
  636. for (i = 0; i < len; i++)
  637. result[i] = tolower(string[i]);
  638. result[i] = '\0';
  639. return result;
  640. }
  641. char *xstrvfmt(const char *fmt, va_list ap)
  642. {
  643. struct strbuf buf = STRBUF_INIT;
  644. strbuf_vaddf(&buf, fmt, ap);
  645. return strbuf_detach(&buf, NULL);
  646. }
  647. char *xstrfmt(const char *fmt, ...)
  648. {
  649. va_list ap;
  650. char *ret;
  651. va_start(ap, fmt);
  652. ret = xstrvfmt(fmt, ap);
  653. va_end(ap);
  654. return ret;
  655. }
  656. void strbuf_addftime(struct strbuf *sb, const char *fmt, const struct tm *tm)
  657. {
  658. size_t hint = 128;
  659. size_t len;
  660. if (!*fmt)
  661. return;
  662. strbuf_grow(sb, hint);
  663. len = strftime(sb->buf + sb->len, sb->alloc - sb->len, fmt, tm);
  664. if (!len) {
  665. /*
  666. * strftime reports "0" if it could not fit the result in the buffer.
  667. * Unfortunately, it also reports "0" if the requested time string
  668. * takes 0 bytes. So our strategy is to munge the format so that the
  669. * output contains at least one character, and then drop the extra
  670. * character before returning.
  671. */
  672. struct strbuf munged_fmt = STRBUF_INIT;
  673. strbuf_addf(&munged_fmt, "%s ", fmt);
  674. while (!len) {
  675. hint *= 2;
  676. strbuf_grow(sb, hint);
  677. len = strftime(sb->buf + sb->len, sb->alloc - sb->len,
  678. munged_fmt.buf, tm);
  679. }
  680. strbuf_release(&munged_fmt);
  681. len--; /* drop munged space */
  682. }
  683. strbuf_setlen(sb, sb->len + len);
  684. }
  685. void strbuf_add_unique_abbrev(struct strbuf *sb, const unsigned char *sha1,
  686. int abbrev_len)
  687. {
  688. int r;
  689. strbuf_grow(sb, GIT_SHA1_HEXSZ + 1);
  690. r = find_unique_abbrev_r(sb->buf + sb->len, sha1, abbrev_len);
  691. strbuf_setlen(sb, sb->len + r);
  692. }
  693. /*
  694. * Returns the length of a line, without trailing spaces.
  695. *
  696. * If the line ends with newline, it will be removed too.
  697. */
  698. static size_t cleanup(char *line, size_t len)
  699. {
  700. while (len) {
  701. unsigned char c = line[len - 1];
  702. if (!isspace(c))
  703. break;
  704. len--;
  705. }
  706. return len;
  707. }
  708. /*
  709. * Remove empty lines from the beginning and end
  710. * and also trailing spaces from every line.
  711. *
  712. * Turn multiple consecutive empty lines between paragraphs
  713. * into just one empty line.
  714. *
  715. * If the input has only empty lines and spaces,
  716. * no output will be produced.
  717. *
  718. * If last line does not have a newline at the end, one is added.
  719. *
  720. * Enable skip_comments to skip every line starting with comment
  721. * character.
  722. */
  723. void strbuf_stripspace(struct strbuf *sb, int skip_comments)
  724. {
  725. int empties = 0;
  726. size_t i, j, len, newlen;
  727. char *eol;
  728. /* We may have to add a newline. */
  729. strbuf_grow(sb, 1);
  730. for (i = j = 0; i < sb->len; i += len, j += newlen) {
  731. eol = memchr(sb->buf + i, '\n', sb->len - i);
  732. len = eol ? eol - (sb->buf + i) + 1 : sb->len - i;
  733. if (skip_comments && len && sb->buf[i] == comment_line_char) {
  734. newlen = 0;
  735. continue;
  736. }
  737. newlen = cleanup(sb->buf + i, len);
  738. /* Not just an empty line? */
  739. if (newlen) {
  740. if (empties > 0 && j > 0)
  741. sb->buf[j++] = '\n';
  742. empties = 0;
  743. memmove(sb->buf + j, sb->buf + i, newlen);
  744. sb->buf[newlen + j++] = '\n';
  745. } else {
  746. empties++;
  747. }
  748. }
  749. strbuf_setlen(sb, j);
  750. }