format-patch: avoid freopen()

We just taught the relevant functions to respect the diffopt.file field, to allow writing somewhere else than stdout. Let's make use of it. Technically, we do not need to avoid that call in a builtin: we assume that builtins (as opposed to library functions) are stand-alone programs that may do with their (global) state. Yet, we want to be able to reuse that code in properly lib-ified code, e.g. when converting scripts into builtins. Further, while we did not *have* to touch the cmd_show() and cmd_cherry() code paths (because they do not want to write anywhere but stdout as of yet), it just makes sense to be consistent, making it easier and safer to move the code later. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Jun 22, 2016 at 17:01 UTC 95235f5ba1a9398c8503b809370ece18bba72ba2
1 file changed +33 -31
builtin/log.c
+33 -31
@@ -236,7 +236,7 @@ static void show_early_header(struct rev_info *rev, const char *stage, int nr)
236 if (rev->commit_format != CMIT_FMT_ONELINE)
237 putchar(rev->diffopt.line_termination);
238 }
239 - printf(_("Final output: %d %s\n"), nr, stage);
239 + fprintf(rev->diffopt.file, _("Final output: %d %s\n"), nr, stage);
240 }
241
242 static struct itimerval early_output_timer;
@@ -454,7 +454,7 @@ static void show_tagger(char *buf, int len, struct rev_info *rev)
454 pp.fmt = rev->commit_format;
455 pp.date_mode = rev->date_mode;
456 pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding());
457 - printf("%s", out.buf);
457 + fprintf(rev->diffopt.file, "%s", out.buf);
458 strbuf_release(&out);
459 }
460
@@ -465,7 +465,7 @@ static int show_blob_object(const unsigned char *sha1, struct rev_info *rev, con
465 char *buf;
466 unsigned long size;
467
468 - fflush(stdout);
468 + fflush(rev->diffopt.file);
469 if (!DIFF_OPT_TOUCHED(&rev->diffopt, ALLOW_TEXTCONV) ||
470 !DIFF_OPT_TST(&rev->diffopt, ALLOW_TEXTCONV))
471 return stream_blob_to_fd(1, sha1, NULL, 0);
@@ -505,7 +505,7 @@ static int show_tag_object(const unsigned char *sha1, struct rev_info *rev)
505 }
506
507 if (offset < size)
508 - fwrite(buf + offset, size - offset, 1, stdout);
508 + fwrite(buf + offset, size - offset, 1, rev->diffopt.file);
509 free(buf);
510 return 0;
511 }
@@ -514,7 +514,8 @@ static int show_tree_object(const unsigned char *sha1,
514 struct strbuf *base,
515 const char *pathname, unsigned mode, int stage, void *context)
516 {
517 - printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
517 + FILE *file = context;
518 + fprintf(file, "%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
519 return 0;
520 }
521
@@ -574,7 +575,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
575
576 if (rev.shown_one)
577 putchar('\n');
577 - printf("%stag %s%s\n",
578 + fprintf(rev.diffopt.file, "%stag %s%s\n",
579 diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
580 t->tag,
581 diff_get_color_opt(&rev.diffopt, DIFF_RESET));
@@ -593,12 +594,12 @@ int cmd_show(int argc, const char **argv, const char *prefix)
594 case OBJ_TREE:
595 if (rev.shown_one)
596 putchar('\n');
596 - printf("%stree %s%s\n\n",
597 + fprintf(rev.diffopt.file, "%stree %s%s\n\n",
598 diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
599 name,
600 diff_get_color_opt(&rev.diffopt, DIFF_RESET));
601 read_tree_recursive((struct tree *)o, "", 0, 0, &match_all,
601 - show_tree_object, NULL);
602 + show_tree_object, rev.diffopt.file);
603 rev.shown_one = 1;
604 break;
605 case OBJ_COMMIT:
@@ -808,7 +809,7 @@ static FILE *realstdout = NULL;
809 static const char *output_directory = NULL;
810 static int outdir_offset;
811
811 -static int reopen_stdout(struct commit *commit, const char *subject,
812 +static int open_next_file(struct commit *commit, const char *subject,
813 struct rev_info *rev, int quiet)
814 {
815 struct strbuf filename = STRBUF_INIT;
@@ -832,7 +833,7 @@ static int reopen_stdout(struct commit *commit, const char *subject,
833 if (!quiet)
834 fprintf(realstdout, "%s\n", filename.buf + outdir_offset);
835
835 - if (freopen(filename.buf, "w", stdout) == NULL)
836 + if ((rev->diffopt.file = fopen(filename.buf, "w")) == NULL)
837 return error(_("Cannot open patch file %s"), filename.buf);
838
839 strbuf_release(&filename);
@@ -891,15 +892,15 @@ static void gen_message_id(struct rev_info *info, char *base)
892 info->message_id = strbuf_detach(&buf, NULL);
893 }
894
894 -static void print_signature(void)
895 +static void print_signature(FILE *file)
896 {
897 if (!signature || !*signature)
898 return;
899
899 - printf("-- \n%s", signature);
900 + fprintf(file, "-- \n%s", signature);
901 if (signature[strlen(signature)-1] != '\n')
901 - putchar('\n');
902 - putchar('\n');
902 + putc('\n', file);
903 + putc('\n', file);
904 }
905
906 static void add_branch_description(struct strbuf *buf, const char *branch_name)
@@ -968,7 +969,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
969 committer = git_committer_info(0);
970
971 if (!use_stdout &&
971 - reopen_stdout(NULL, rev->numbered_files ? NULL : "cover-letter", rev, quiet))
972 + open_next_file(NULL, rev->numbered_files ? NULL : "cover-letter", rev, quiet))
973 return;
974
975 log_write_email_headers(rev, head, &pp.subject, &pp.after_subject,
@@ -991,7 +992,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
992 pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);
993 pp_remainder(&pp, &msg, &sb, 0);
994 add_branch_description(&sb, branch_name);
994 - printf("%s\n", sb.buf);
995 + fprintf(rev->diffopt.file, "%s\n", sb.buf);
996
997 strbuf_release(&sb);
998
@@ -1000,6 +1001,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
1001 log.wrap = 72;
1002 log.in1 = 2;
1003 log.in2 = 4;
1004 + log.file = rev->diffopt.file;
1005 for (i = 0; i < nr; i++)
1006 shortlog_add_commit(&log, list[i]);
1007
@@ -1022,8 +1024,8 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
1024 diffcore_std(&opts);
1025 diff_flush(&opts);
1026
1025 - printf("\n");
1026 - print_signature();
1027 + fprintf(rev->diffopt.file, "\n");
1028 + print_signature(rev->diffopt.file);
1029 }
1030
1031 static const char *clean_message_id(const char *msg_id)
@@ -1333,7 +1335,7 @@ static void prepare_bases(struct base_tree_info *bases,
1335 }
1336 }
1337
1336 -static void print_bases(struct base_tree_info *bases)
1338 +static void print_bases(struct base_tree_info *bases, FILE *file)
1339 {
1340 int i;
1341
@@ -1342,11 +1344,11 @@ static void print_bases(struct base_tree_info *bases)
1344 return;
1345
1346 /* Show the base commit */
1345 - printf("base-commit: %s\n", oid_to_hex(&bases->base_commit));
1347 + fprintf(file, "base-commit: %s\n", oid_to_hex(&bases->base_commit));
1348
1349 /* Show the prerequisite patches */
1350 for (i = bases->nr_patch_id - 1; i >= 0; i--)
1349 - printf("prerequisite-patch-id: %s\n", oid_to_hex(&bases->patch_id[i]));
1351 + fprintf(file, "prerequisite-patch-id: %s\n", oid_to_hex(&bases->patch_id[i]));
1352
1353 free(bases->patch_id);
1354 bases->nr_patch_id = 0;
@@ -1704,7 +1706,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1706 gen_message_id(&rev, "cover");
1707 make_cover_letter(&rev, use_stdout,
1708 origin, nr, list, branch_name, quiet);
1707 - print_bases(&bases);
1709 + print_bases(&bases, rev.diffopt.file);
1710 total++;
1711 start_number--;
1712 }
@@ -1750,7 +1752,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1752 }
1753
1754 if (!use_stdout &&
1753 - reopen_stdout(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
1755 + open_next_file(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
1756 die(_("Failed to create output files"));
1757 shown = log_tree_commit(&rev, commit);
1758 free_commit_buffer(commit);
@@ -1765,15 +1767,15 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1767 rev.shown_one = 0;
1768 if (shown) {
1769 if (rev.mime_boundary)
1768 - printf("\n--%s%s--\n\n\n",
1770 + fprintf(rev.diffopt.file, "\n--%s%s--\n\n\n",
1771 mime_boundary_leader,
1772 rev.mime_boundary);
1773 else
1772 - print_signature();
1773 - print_bases(&bases);
1774 + print_signature(rev.diffopt.file);
1775 + print_bases(&bases, rev.diffopt.file);
1776 }
1777 if (!use_stdout)
1776 - fclose(stdout);
1778 + fclose(rev.diffopt.file);
1779 }
1780 free(list);
1781 free(branch_name);
@@ -1805,15 +1807,15 @@ static const char * const cherry_usage[] = {
1807 };
1808
1809 static void print_commit(char sign, struct commit *commit, int verbose,
1808 - int abbrev)
1810 + int abbrev, FILE *file)
1811 {
1812 if (!verbose) {
1811 - printf("%c %s\n", sign,
1813 + fprintf(file, "%c %s\n", sign,
1814 find_unique_abbrev(commit->object.oid.hash, abbrev));
1815 } else {
1816 struct strbuf buf = STRBUF_INIT;
1817 pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf);
1816 - printf("%c %s %s\n", sign,
1818 + fprintf(file, "%c %s %s\n", sign,
1819 find_unique_abbrev(commit->object.oid.hash, abbrev),
1820 buf.buf);
1821 strbuf_release(&buf);
@@ -1894,7 +1896,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
1896 commit = list->item;
1897 if (has_commit_patch_id(commit, &ids))
1898 sign = '-';
1897 - print_commit(sign, commit, verbose, abbrev);
1899 + print_commit(sign, commit, verbose, abbrev, revs.diffopt.file);
1900 list = list->next;
1901 }
1902