{"thread":{"id":"4222","subject":"[PATCH] fmt-patch: add --check option","startedAt":"2006-05-20T21:43:13Z","lastAt":"2006-05-20T21:43:13Z","messageCount":1,"participants":["Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"20340","messageId":"Pine.LNX.4.63.0605202342160.1057@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"4222","inReplyTo":null,"subject":"[PATCH] fmt-patch: add --check option","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-05-20T21:43:13Z","receivedAt":"2006-05-20T21:43:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nActually, it is a diff option now, so you can say\n\n\tgit diff --check\n\nto ask if what you are about to commit is a good patch.\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\n---\n\n\tThe temptation to bastardize diff_flush_patch was not high\n\tenough. It would be ugly.\n\n\tInternally, I called it checkdiff, not just check, to make it\n\tmore obvious what it does.\n\n diff.c |  115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n diff.h |    1 +\n 2 files changed, 115 insertions(+), 1 deletions(-)\n\ndiff --git a/diff.c b/diff.c\nindex 3e2828b..af26dda 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -397,6 +397,46 @@ static void show_stats(struct diffstat_t\n \t\t\ttotal_files, adds, dels);\n }\n \n+struct checkdiff_t {\n+\tstruct xdiff_emit_state xm;\n+\tconst char *filename;\n+\tint lineno;\n+};\n+\n+static void checkdiff_consume(void *priv, char *line, unsigned long len)\n+{\n+\tstruct checkdiff_t *data = priv;\n+\n+\tif (line[0] == '+') {\n+\t\tint i, spaces = 0;\n+\n+\t\tdata->lineno++;\n+\n+\t\t/* check space before tab */\n+\t\tfor (i = 1; i < len && (line[i] == ' ' || line[i] == '\\t'); i++)\n+\t\t\tif (line[i] == ' ')\n+\t\t\t\tspaces++;\n+\t\tif (line[i - 1] == '\\t' && spaces)\n+\t\t\tprintf(\"%s:%d: space before tab:%.*s\\n\",\n+\t\t\t\tdata->filename, data->lineno, (int)len, line);\n+\n+\t\t/* check white space at line end */\n+\t\tif (line[len - 1] == '\\n')\n+\t\t\tlen--;\n+\t\tif (isspace(line[len - 1]))\n+\t\t\tprintf(\"%s:%d: white space at end: %.*s\\n\",\n+\t\t\t\tdata->filename, data->lineno, (int)len, line);\n+\t} else if (line[0] == ' ')\n+\t\tdata->lineno++;\n+\telse if (line[0] == '@') {\n+\t\tchar *plus = strchr(line, '+');\n+\t\tif (plus)\n+\t\t\tdata->lineno = strtol(plus, line + len, 10);\n+\t\telse\n+\t\t\tdie(\"invalid diff\");\n+\t}\n+}\n+\n static unsigned char *deflate_it(char *data,\n \t\t\t\t unsigned long size,\n \t\t\t\t unsigned long *result_size)\n@@ -624,6 +664,41 @@ static void builtin_diffstat(const char \n \t}\n }\n \n+static void builtin_checkdiff(const char *name_a, const char *name_b,\n+\t\t\t     struct diff_filespec *one,\n+\t\t\t     struct diff_filespec *two)\n+{\n+\tmmfile_t mf1, mf2;\n+\tstruct checkdiff_t data;\n+\n+\tif (!two)\n+\t\treturn;\n+\n+\tmemset(&data, 0, sizeof(data));\n+\tdata.xm.consume = checkdiff_consume;\n+\tdata.filename = name_b ? name_b : name_a;\n+\tdata.lineno = 0;\n+\n+\tif (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)\n+\t\tdie(\"unable to read files to diff\");\n+\n+\tif (mmfile_is_binary(&mf2))\n+\t\treturn;\n+\telse {\n+\t\t/* Crazy xdl interfaces.. */\n+\t\txpparam_t xpp;\n+\t\txdemitconf_t xecfg;\n+\t\txdemitcb_t ecb;\n+\n+\t\txpp.flags = XDF_NEED_MINIMAL;\n+\t\txecfg.ctxlen = 0;\n+\t\txecfg.flags = 0;\n+\t\tecb.outf = xdiff_outf;\n+\t\tecb.priv = &data;\n+\t\txdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);\n+\t}\n+}\n+\n struct diff_filespec *alloc_filespec(const char *path)\n {\n \tint namelen = strlen(path);\n@@ -1180,6 +1255,25 @@ static void run_diffstat(struct diff_fil\n \tbuiltin_diffstat(name, other, p->one, p->two, diffstat, complete_rewrite);\n }\n \n+static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)\n+{\n+\tconst char *name;\n+\tconst char *other;\n+\n+\tif (DIFF_PAIR_UNMERGED(p)) {\n+\t\t/* unmerged */\n+\t\treturn;\n+\t}\n+\n+\tname = p->one->path;\n+\tother = (strcmp(name, p->two->path) ? p->two->path : NULL);\n+\n+\tdiff_fill_sha1_info(p->one);\n+\tdiff_fill_sha1_info(p->two);\n+\n+\tbuiltin_checkdiff(name, other, p->one, p->two);\n+}\n+\n void diff_setup(struct diff_options *options)\n {\n \tmemset(options, 0, sizeof(*options));\n@@ -1205,7 +1299,8 @@ int diff_setup_done(struct diff_options \n \t * recursive bits for other formats here.\n \t */\n \tif ((options->output_format == DIFF_FORMAT_PATCH) ||\n-\t    (options->output_format == DIFF_FORMAT_DIFFSTAT))\n+\t    (options->output_format == DIFF_FORMAT_DIFFSTAT) ||\n+\t    (options->output_format == DIFF_FORMAT_CHECKDIFF))\n \t\toptions->recursive = 1;\n \n \tif (options->detect_rename && options->rename_limit < 0)\n@@ -1288,6 +1383,8 @@ int diff_opt_parse(struct diff_options *\n \t}\n \telse if (!strcmp(arg, \"--stat\"))\n \t\toptions->output_format = DIFF_FORMAT_DIFFSTAT;\n+\telse if (!strcmp(arg, \"--check\"))\n+\t\toptions->output_format = DIFF_FORMAT_CHECKDIFF;\n \telse if (!strcmp(arg, \"--summary\"))\n \t\toptions->summary = 1;\n \telse if (!strcmp(arg, \"--patch-with-stat\")) {\n@@ -1610,6 +1707,19 @@ static void diff_flush_stat(struct diff_\n \trun_diffstat(p, o, diffstat);\n }\n \n+static void diff_flush_checkdiff(struct diff_filepair *p,\n+\t\tstruct diff_options *o)\n+{\n+\tif (diff_unmodified_pair(p))\n+\t\treturn;\n+\n+\tif ((DIFF_FILE_VALID(p->one) && S_ISDIR(p->one->mode)) ||\n+\t    (DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode)))\n+\t\treturn; /* no tree diffs in patch format */\n+\n+\trun_checkdiff(p, o);\n+}\n+\n int diff_queue_is_empty(void)\n {\n \tstruct diff_queue_struct *q = &diff_queued_diff;\n@@ -1740,6 +1850,9 @@ static void flush_one_pair(struct diff_f\n \t\tcase DIFF_FORMAT_DIFFSTAT:\n \t\t\tdiff_flush_stat(p, options, diffstat);\n \t\t\tbreak;\n+\t\tcase DIFF_FORMAT_CHECKDIFF:\n+\t\t\tdiff_flush_checkdiff(p, options);\n+\t\t\tbreak;\n \t\tcase DIFF_FORMAT_PATCH:\n \t\t\tdiff_flush_patch(p, options);\n \t\t\tbreak;\ndiff --git a/diff.h b/diff.h\nindex 83619eb..08b3fed 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -155,6 +155,7 @@ #define DIFF_FORMAT_NO_OUTPUT\t3\n #define DIFF_FORMAT_NAME\t4\n #define DIFF_FORMAT_NAME_STATUS\t5\n #define DIFF_FORMAT_DIFFSTAT\t6\n+#define DIFF_FORMAT_CHECKDIFF\t7\n \n extern void diff_flush(struct diff_options*);\n \n-- \n1.3.3.g734b-dirty\n"}]}