{"thread":{"id":"6979","subject":"[PATCH] diff: add some heuristics to detect java method names","startedAt":"2007-02-26T20:32:54Z","lastAt":"2007-02-26T20:32:54Z","messageCount":1,"participants":["Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"35544","messageId":"Pine.LNX.4.63.0702262127470.22628@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"6979","inReplyTo":null,"subject":"[PATCH] diff: add some heuristics to detect java method names","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-02-26T20:32:54Z","receivedAt":"2007-02-26T20:32:54Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nThe heuristics to identify function names for use in hunk headers used to \nmatch the lines defining classes in java source code. This issue was \nbrought up by Shawn Pearce.\n\nThis patch adds the following heuristics:\n\nIf the candidate contains the word \"class\", we search between the current \nline and the \"class\" line for a line defining a method.\n\nA line is taken to define a method when it starts with at least two \nidentifiers (a word starting with a letter or underscore, continuing with \nletters, underscores, digits, brackets or stars) followed by a left \nbracket.\n\nThis heuristics should also work in C++ header files with inlined methods.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n xdiff/xemit.c |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n 1 files changed, 69 insertions(+), 1 deletions(-)\n\ndiff --git a/xdiff/xemit.c b/xdiff/xemit.c\nindex e291dc7..0267476 100644\n--- a/xdiff/xemit.c\n+++ b/xdiff/xemit.c\n@@ -69,6 +69,68 @@ static xdchange_t *xdl_get_hunk(xdchange_t *xscr, xdemitconf_t const *xecfg) {\n }\n \n \n+static int is_identifier(const char *rec, long len) {\n+\tlong i;\n+\tif (!len)\n+\t\treturn -1;\n+\tfor (i = 0; i < len; i++) {\n+\t\tchar c = rec[i];\n+\t\tif (!isalnum(c) && c != '_' && (i == 0 ||\n+\t\t\t\t\t(!isdigit(c)  && !strchr(\"_[]*\", c))))\n+\t\t\treturn i;\n+\t}\n+\treturn i;\n+}\n+\n+static void xdl_find_method(xdfile_t *xf, long i, long i_class,\n+\t\tchar *buf, long sz, long *ll) {\n+\t/*\n+\t * A \"class\" line has been found in line i_class. Find a method\n+\t * name between that line and line i.\n+\t *\n+\t * The heuristics is this: the line begins with at least two\n+\t * identifiers, followed by an opening parenthesis.\n+\t */\n+\tconst char *rec;\n+\tlong len;\n+\n+\twhile (i-- > i_class) {\n+\t\tlong off, count, identifier_count = 0;\n+\t\tlen = xdl_get_rec(xf, i, &rec);\n+\t\tfor (off = 0; off < len && isspace(rec[off]); off++)\n+\t\t\t; /* do nothing */\n+\t\tfor(;;) {\n+\t\t\tif ((count = is_identifier(rec + off, len - off)) <= 0)\n+\t\t\t\tbreak;\n+\t\t\tfor (off += count;\n+\t\t\t\t\toff < len && isspace(rec[off]);\n+\t\t\t\t\toff++)\n+\t\t\t\t; /* do nothing */\n+\t\t\tif (++identifier_count > 1 && rec[off] == '(') {\n+\t\t\t\tfor (off = 0; isspace(rec[off]); off++)\n+\t\t\t\t\t; /* do nothing */\n+\t\t\t\tfor (; isspace(rec[len - 1]); len--)\n+\t\t\t\t\t; /* do nothing */\n+\t\t\t\tlen -= off;\n+\t\t\t\tif (len > sz)\n+\t\t\t\t\tlen = sz;\n+\t\t\t\tmemcpy(buf, rec + off, len);\n+\t\t\t\t*ll = len;\n+\t\t\t\treturn;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\t/* fall back to class line */\n+\tlen = xdl_get_rec(xf, i_class, &rec);\n+\twhile (len > 0 && isspace(rec[len - 1]))\n+\t\tlen--;\n+\tif (len > sz)\n+\t\tlen = sz;\n+\tmemcpy(buf, rec, len);\n+\t*ll = len;\n+}\n+\n static void xdl_find_func(xdfile_t *xf, long i, char *buf, long sz, long *ll) {\n \n \t/*\n@@ -78,7 +140,7 @@ static void xdl_find_func(xdfile_t *xf, long i, char *buf, long sz, long *ll) {\n \t */\n \n \tconst char *rec;\n-\tlong len;\n+\tlong len, i_start = i;\n \n \t*ll = 0;\n \twhile (i-- > 0) {\n@@ -87,6 +149,12 @@ static void xdl_find_func(xdfile_t *xf, long i, char *buf, long sz, long *ll) {\n \t\t    (isalpha((unsigned char)*rec) || /* identifier? */\n \t\t     *rec == '_' ||\t/* also identifier? */\n \t\t     *rec == '$')) {\t/* mysterious GNU diff's invention */\n+\t\t\tconst char *is_class = strstr(rec, \"class \");\n+\t\t\tif (is_class && (rec == is_class ||\n+\t\t\t\t\t\tisspace(is_class[-1]))) {\n+\t\t\t\txdl_find_method(xf, i_start, i, buf, sz, ll);\n+\t\t\t\treturn;\n+\t\t\t}\n \t\t\tif (len > sz)\n \t\t\t\tlen = sz;\n \t\t\twhile (0 < len && isspace((unsigned char)rec[len - 1]))\n-- \n1.5.0.1.2441.gaf8e-dirty\n"}]}