Merge branch 'ab/userdiff-tests'
A bit of code clean-up and a lot of test clean-up around userdiff area. * ab/userdiff-tests: blame tests: simplify userdiff driver test blame tests: don't rely on t/t4018/ directory userdiff: remove support for "broken" tests userdiff tests: list builtin drivers via test-tool userdiff tests: explicitly test "default" pattern userdiff: add and use for_each_userdiff_driver() userdiff style: normalize pascal regex declaration userdiff style: declare patterns with consistent style userdiff style: re-order drivers in alphabetical order
This commit is contained in:
commit
ab99efc817
1
Makefile
1
Makefile
@ -753,6 +753,7 @@ TEST_BUILTINS_OBJS += test-submodule-nested-repo-config.o
|
|||||||
TEST_BUILTINS_OBJS += test-subprocess.o
|
TEST_BUILTINS_OBJS += test-subprocess.o
|
||||||
TEST_BUILTINS_OBJS += test-trace2.o
|
TEST_BUILTINS_OBJS += test-trace2.o
|
||||||
TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
|
TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
|
||||||
|
TEST_BUILTINS_OBJS += test-userdiff.o
|
||||||
TEST_BUILTINS_OBJS += test-wildmatch.o
|
TEST_BUILTINS_OBJS += test-wildmatch.o
|
||||||
TEST_BUILTINS_OBJS += test-windows-named-pipe.o
|
TEST_BUILTINS_OBJS += test-windows-named-pipe.o
|
||||||
TEST_BUILTINS_OBJS += test-write-cache.o
|
TEST_BUILTINS_OBJS += test-write-cache.o
|
||||||
|
@ -479,22 +479,26 @@ test_expect_success 'blame -L ^:RE (absolute: end-of-file)' '
|
|||||||
check_count -f hello.c -L$n -L^:ma.. F 4 G 1 H 1
|
check_count -f hello.c -L$n -L^:ma.. F 4 G 1 H 1
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'setup -L :funcname with userdiff driver' '
|
|
||||||
echo "fortran-* diff=fortran" >.gitattributes &&
|
|
||||||
fortran_file=fortran-external-function &&
|
|
||||||
orig_file="$TEST_DIRECTORY/t4018/$fortran_file" &&
|
|
||||||
cp "$orig_file" . &&
|
|
||||||
git add "$fortran_file" &&
|
|
||||||
GIT_AUTHOR_NAME="A" GIT_AUTHOR_EMAIL="A@test.git" \
|
|
||||||
git commit -m "add fortran file" &&
|
|
||||||
sed -e "s/ChangeMe/IWasChanged/" <"$orig_file" >"$fortran_file" &&
|
|
||||||
git add "$fortran_file" &&
|
|
||||||
GIT_AUTHOR_NAME="B" GIT_AUTHOR_EMAIL="B@test.git" \
|
|
||||||
git commit -m "change fortran file"
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'blame -L :funcname with userdiff driver' '
|
test_expect_success 'blame -L :funcname with userdiff driver' '
|
||||||
check_count -f fortran-external-function -L:RIGHT A 7 B 1
|
cat >file.template <<-\EOF &&
|
||||||
|
DO NOT MATCH THIS LINE
|
||||||
|
function RIGHT(a, b) result(c)
|
||||||
|
AS THE DEFAULT DRIVER WOULD
|
||||||
|
|
||||||
|
integer, intent(in) :: ChangeMe
|
||||||
|
EOF
|
||||||
|
|
||||||
|
fortran_file=file.f03 &&
|
||||||
|
test_when_finished "rm .gitattributes" &&
|
||||||
|
echo "$fortran_file diff=fortran" >.gitattributes &&
|
||||||
|
|
||||||
|
test_commit --author "A <A@test.git>" \
|
||||||
|
"add" "$fortran_file" \
|
||||||
|
"$(cat file.template)" &&
|
||||||
|
test_commit --author "B <B@test.git>" \
|
||||||
|
"change" "$fortran_file" \
|
||||||
|
"$(cat file.template | sed -e s/ChangeMe/IWasChanged/)" &&
|
||||||
|
check_count -f "$fortran_file" -L:RIGHT A 3 B 1
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'setup incremental' '
|
test_expect_success 'setup incremental' '
|
||||||
|
@ -73,6 +73,7 @@ static struct test_cmd cmds[] = {
|
|||||||
{ "submodule-nested-repo-config", cmd__submodule_nested_repo_config },
|
{ "submodule-nested-repo-config", cmd__submodule_nested_repo_config },
|
||||||
{ "subprocess", cmd__subprocess },
|
{ "subprocess", cmd__subprocess },
|
||||||
{ "trace2", cmd__trace2 },
|
{ "trace2", cmd__trace2 },
|
||||||
|
{ "userdiff", cmd__userdiff },
|
||||||
{ "urlmatch-normalization", cmd__urlmatch_normalization },
|
{ "urlmatch-normalization", cmd__urlmatch_normalization },
|
||||||
{ "xml-encode", cmd__xml_encode },
|
{ "xml-encode", cmd__xml_encode },
|
||||||
{ "wildmatch", cmd__wildmatch },
|
{ "wildmatch", cmd__wildmatch },
|
||||||
|
@ -63,6 +63,7 @@ int cmd__submodule_config(int argc, const char **argv);
|
|||||||
int cmd__submodule_nested_repo_config(int argc, const char **argv);
|
int cmd__submodule_nested_repo_config(int argc, const char **argv);
|
||||||
int cmd__subprocess(int argc, const char **argv);
|
int cmd__subprocess(int argc, const char **argv);
|
||||||
int cmd__trace2(int argc, const char **argv);
|
int cmd__trace2(int argc, const char **argv);
|
||||||
|
int cmd__userdiff(int argc, const char **argv);
|
||||||
int cmd__urlmatch_normalization(int argc, const char **argv);
|
int cmd__urlmatch_normalization(int argc, const char **argv);
|
||||||
int cmd__xml_encode(int argc, const char **argv);
|
int cmd__xml_encode(int argc, const char **argv);
|
||||||
int cmd__wildmatch(int argc, const char **argv);
|
int cmd__wildmatch(int argc, const char **argv);
|
||||||
|
46
t/helper/test-userdiff.c
Normal file
46
t/helper/test-userdiff.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include "test-tool.h"
|
||||||
|
#include "cache.h"
|
||||||
|
#include "userdiff.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
static int driver_cb(struct userdiff_driver *driver,
|
||||||
|
enum userdiff_driver_type type, void *priv)
|
||||||
|
{
|
||||||
|
enum userdiff_driver_type *want_type = priv;
|
||||||
|
if (type & *want_type && driver->funcname.pattern)
|
||||||
|
puts(driver->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd__userdiff_config(const char *var, const char *value, void *cb)
|
||||||
|
{
|
||||||
|
if (userdiff_config(var, value) < 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd__userdiff(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
enum userdiff_driver_type want = 0;
|
||||||
|
if (argc != 2)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "list-drivers"))
|
||||||
|
want = (USERDIFF_DRIVER_TYPE_BUILTIN |
|
||||||
|
USERDIFF_DRIVER_TYPE_CUSTOM);
|
||||||
|
else if (!strcmp(argv[1], "list-builtin-drivers"))
|
||||||
|
want = USERDIFF_DRIVER_TYPE_BUILTIN;
|
||||||
|
else if (!strcmp(argv[1], "list-custom-drivers"))
|
||||||
|
want = USERDIFF_DRIVER_TYPE_CUSTOM;
|
||||||
|
else
|
||||||
|
return error("unknown argument %s", argv[1]);
|
||||||
|
|
||||||
|
if (want & USERDIFF_DRIVER_TYPE_CUSTOM) {
|
||||||
|
setup_git_directory();
|
||||||
|
git_config(cmd__userdiff_config, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each_userdiff_driver(driver_cb, &want);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -25,34 +25,26 @@ test_expect_success 'setup' '
|
|||||||
echo B >B.java
|
echo B >B.java
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'setup: test-tool userdiff' '
|
||||||
|
# Make sure additions to builtin_drivers are sorted
|
||||||
|
test_when_finished "rm builtin-drivers.sorted" &&
|
||||||
|
test-tool userdiff list-builtin-drivers >builtin-drivers &&
|
||||||
|
test_file_not_empty builtin-drivers &&
|
||||||
|
sort <builtin-drivers >builtin-drivers.sorted &&
|
||||||
|
test_cmp builtin-drivers.sorted builtin-drivers &&
|
||||||
|
|
||||||
|
# Ditto, but "custom" requires the .git directory and config
|
||||||
|
# to be setup and read.
|
||||||
|
test_when_finished "rm custom-drivers.sorted" &&
|
||||||
|
test-tool userdiff list-custom-drivers >custom-drivers &&
|
||||||
|
test_file_not_empty custom-drivers &&
|
||||||
|
sort <custom-drivers >custom-drivers.sorted &&
|
||||||
|
test_cmp custom-drivers.sorted custom-drivers
|
||||||
|
'
|
||||||
|
|
||||||
diffpatterns="
|
diffpatterns="
|
||||||
ada
|
$(cat builtin-drivers)
|
||||||
bash
|
$(cat custom-drivers)
|
||||||
bibtex
|
|
||||||
cpp
|
|
||||||
csharp
|
|
||||||
css
|
|
||||||
dts
|
|
||||||
elixir
|
|
||||||
fortran
|
|
||||||
fountain
|
|
||||||
golang
|
|
||||||
html
|
|
||||||
java
|
|
||||||
markdown
|
|
||||||
matlab
|
|
||||||
objc
|
|
||||||
pascal
|
|
||||||
perl
|
|
||||||
php
|
|
||||||
python
|
|
||||||
ruby
|
|
||||||
rust
|
|
||||||
scheme
|
|
||||||
tex
|
|
||||||
custom1
|
|
||||||
custom2
|
|
||||||
custom3
|
|
||||||
"
|
"
|
||||||
|
|
||||||
for p in $diffpatterns
|
for p in $diffpatterns
|
||||||
@ -102,13 +94,7 @@ test_expect_success 'setup hunk header tests' '
|
|||||||
# check each individual file
|
# check each individual file
|
||||||
for i in $(git ls-files)
|
for i in $(git ls-files)
|
||||||
do
|
do
|
||||||
if grep broken "$i" >/dev/null 2>&1
|
test_expect_success "hunk header: $i" "
|
||||||
then
|
|
||||||
result=failure
|
|
||||||
else
|
|
||||||
result=success
|
|
||||||
fi
|
|
||||||
test_expect_$result "hunk header: $i" "
|
|
||||||
git diff -U1 $i >actual &&
|
git diff -U1 $i >actual &&
|
||||||
grep '@@ .* @@.*RIGHT' actual
|
grep '@@ .* @@.*RIGHT' actual
|
||||||
"
|
"
|
||||||
|
@ -7,9 +7,6 @@ at least two lines from the line that must appear in the hunk header.
|
|||||||
The text that must appear in the hunk header must contain the word
|
The text that must appear in the hunk header must contain the word
|
||||||
"right", but in all upper-case, like in the title above.
|
"right", but in all upper-case, like in the title above.
|
||||||
|
|
||||||
To mark a test case that highlights a malfunction, insert the word
|
|
||||||
BROKEN in all lower-case somewhere in the file.
|
|
||||||
|
|
||||||
This text is a bit twisted and out of order, but it is itself a
|
This text is a bit twisted and out of order, but it is itself a
|
||||||
test case for the default hunk header pattern. Know what you are doing
|
test case for the default hunk header pattern. Know what you are doing
|
||||||
if you change it.
|
if you change it.
|
||||||
|
167
userdiff.c
167
userdiff.c
@ -44,6 +44,46 @@ PATTERNS("bash",
|
|||||||
/* -- */
|
/* -- */
|
||||||
/* Characters not in the default $IFS value */
|
/* Characters not in the default $IFS value */
|
||||||
"[^ \t]+"),
|
"[^ \t]+"),
|
||||||
|
PATTERNS("bibtex",
|
||||||
|
"(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$",
|
||||||
|
/* -- */
|
||||||
|
"[={}\"]|[^={}\" \t]+"),
|
||||||
|
PATTERNS("cpp",
|
||||||
|
/* Jump targets or access declarations */
|
||||||
|
"!^[ \t]*[A-Za-z_][A-Za-z_0-9]*:[[:space:]]*($|/[/*])\n"
|
||||||
|
/* functions/methods, variables, and compounds at top level */
|
||||||
|
"^((::[[:space:]]*)?[A-Za-z_].*)$",
|
||||||
|
/* -- */
|
||||||
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
|
"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lLuU]*"
|
||||||
|
"|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->\\*?|\\.\\*"),
|
||||||
|
PATTERNS("csharp",
|
||||||
|
/* Keywords */
|
||||||
|
"!^[ \t]*(do|while|for|if|else|instanceof|new|return|switch|case|throw|catch|using)\n"
|
||||||
|
/* Methods and constructors */
|
||||||
|
"^[ \t]*(((static|public|internal|private|protected|new|virtual|sealed|override|unsafe|async)[ \t]+)*[][<>@.~_[:alnum:]]+[ \t]+[<>@._[:alnum:]]+[ \t]*\\(.*\\))[ \t]*$\n"
|
||||||
|
/* Properties */
|
||||||
|
"^[ \t]*(((static|public|internal|private|protected|new|virtual|sealed|override|unsafe)[ \t]+)*[][<>@.~_[:alnum:]]+[ \t]+[@._[:alnum:]]+)[ \t]*$\n"
|
||||||
|
/* Type definitions */
|
||||||
|
"^[ \t]*(((static|public|internal|private|protected|new|unsafe|sealed|abstract|partial)[ \t]+)*(class|enum|interface|struct)[ \t]+.*)$\n"
|
||||||
|
/* Namespace */
|
||||||
|
"^[ \t]*(namespace[ \t]+.*)$",
|
||||||
|
/* -- */
|
||||||
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
|
"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
|
||||||
|
"|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
|
||||||
|
IPATTERN("css",
|
||||||
|
"![:;][[:space:]]*$\n"
|
||||||
|
"^[:[@.#]?[_a-z0-9].*$",
|
||||||
|
/* -- */
|
||||||
|
/*
|
||||||
|
* This regex comes from W3C CSS specs. Should theoretically also
|
||||||
|
* allow ISO 10646 characters U+00A0 and higher,
|
||||||
|
* but they are not handled in this regex.
|
||||||
|
*/
|
||||||
|
"-?[_a-zA-Z][-_a-zA-Z0-9]*" /* identifiers */
|
||||||
|
"|-?[0-9]+|\\#[0-9a-fA-F]+" /* numbers */
|
||||||
|
),
|
||||||
PATTERNS("dts",
|
PATTERNS("dts",
|
||||||
"!;\n"
|
"!;\n"
|
||||||
"!=\n"
|
"!=\n"
|
||||||
@ -83,7 +123,9 @@ IPATTERN("fortran",
|
|||||||
* they would have been matched above as a variable anyway. */
|
* they would have been matched above as a variable anyway. */
|
||||||
"|[-+]?[0-9.]+([AaIiDdEeFfLlTtXx][Ss]?[-+]?[0-9.]*)?(_[a-zA-Z0-9][a-zA-Z0-9_]*)?"
|
"|[-+]?[0-9.]+([AaIiDdEeFfLlTtXx][Ss]?[-+]?[0-9.]*)?(_[a-zA-Z0-9][a-zA-Z0-9_]*)?"
|
||||||
"|//|\\*\\*|::|[/<>=]="),
|
"|//|\\*\\*|::|[/<>=]="),
|
||||||
IPATTERN("fountain", "^((\\.[^.]|(int|ext|est|int\\.?/ext|i/e)[. ]).*)$",
|
IPATTERN("fountain",
|
||||||
|
"^((\\.[^.]|(int|ext|est|int\\.?/ext|i/e)[. ]).*)$",
|
||||||
|
/* -- */
|
||||||
"[^ \t-]+"),
|
"[^ \t-]+"),
|
||||||
PATTERNS("golang",
|
PATTERNS("golang",
|
||||||
/* Functions */
|
/* Functions */
|
||||||
@ -94,7 +136,9 @@ PATTERNS("golang",
|
|||||||
"[a-zA-Z_][a-zA-Z0-9_]*"
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
"|[-+0-9.eE]+i?|0[xX]?[0-9a-fA-F]+i?"
|
"|[-+0-9.eE]+i?|0[xX]?[0-9a-fA-F]+i?"
|
||||||
"|[-+*/<>%&^|=!:]=|--|\\+\\+|<<=?|>>=?|&\\^=?|&&|\\|\\||<-|\\.{3}"),
|
"|[-+*/<>%&^|=!:]=|--|\\+\\+|<<=?|>>=?|&\\^=?|&&|\\|\\||<-|\\.{3}"),
|
||||||
PATTERNS("html", "^[ \t]*(<[Hh][1-6]([ \t].*)?>.*)$",
|
PATTERNS("html",
|
||||||
|
"^[ \t]*(<[Hh][1-6]([ \t].*)?>.*)$",
|
||||||
|
/* -- */
|
||||||
"[^<>= \t]+"),
|
"[^<>= \t]+"),
|
||||||
PATTERNS("java",
|
PATTERNS("java",
|
||||||
"!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
|
"!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
|
||||||
@ -106,6 +150,7 @@ PATTERNS("java",
|
|||||||
"|--|\\+\\+|<<=?|>>>?=?|&&|\\|\\|"),
|
"|--|\\+\\+|<<=?|>>>?=?|&&|\\|\\|"),
|
||||||
PATTERNS("markdown",
|
PATTERNS("markdown",
|
||||||
"^ {0,3}#{1,6}[ \t].*",
|
"^ {0,3}#{1,6}[ \t].*",
|
||||||
|
/* -- */
|
||||||
"[^<>= \t]+"),
|
"[^<>= \t]+"),
|
||||||
PATTERNS("matlab",
|
PATTERNS("matlab",
|
||||||
/*
|
/*
|
||||||
@ -114,6 +159,7 @@ PATTERNS("matlab",
|
|||||||
* that is understood by both.
|
* that is understood by both.
|
||||||
*/
|
*/
|
||||||
"^[[:space:]]*((classdef|function)[[:space:]].*)$|^(%%%?|##)[[:space:]].*$",
|
"^[[:space:]]*((classdef|function)[[:space:]].*)$|^(%%%?|##)[[:space:]].*$",
|
||||||
|
/* -- */
|
||||||
"[a-zA-Z_][a-zA-Z0-9_]*|[-+0-9.e]+|[=~<>]=|\\.[*/\\^']|\\|\\||&&"),
|
"[a-zA-Z_][a-zA-Z0-9_]*|[-+0-9.e]+|[=~<>]=|\\.[*/\\^']|\\|\\||&&"),
|
||||||
PATTERNS("objc",
|
PATTERNS("objc",
|
||||||
/* Negate C statements that can look like functions */
|
/* Negate C statements that can look like functions */
|
||||||
@ -129,9 +175,8 @@ PATTERNS("objc",
|
|||||||
"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
|
"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
|
||||||
"|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
|
"|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
|
||||||
PATTERNS("pascal",
|
PATTERNS("pascal",
|
||||||
"^(((class[ \t]+)?(procedure|function)|constructor|destructor|interface|"
|
"^(((class[ \t]+)?(procedure|function)|constructor|destructor|interface"
|
||||||
"implementation|initialization|finalization)[ \t]*.*)$"
|
"|implementation|initialization|finalization)[ \t]*.*)$\n"
|
||||||
"\n"
|
|
||||||
"^(.*=[ \t]*(class|record).*)$",
|
"^(.*=[ \t]*(class|record).*)$",
|
||||||
/* -- */
|
/* -- */
|
||||||
"[a-zA-Z_][a-zA-Z0-9_]*"
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
@ -174,13 +219,15 @@ PATTERNS("php",
|
|||||||
"[a-zA-Z_][a-zA-Z0-9_]*"
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
"|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+"
|
"|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+"
|
||||||
"|[-+*/<>%&^|=!.]=|--|\\+\\+|<<=?|>>=?|===|&&|\\|\\||::|->"),
|
"|[-+*/<>%&^|=!.]=|--|\\+\\+|<<=?|>>=?|===|&&|\\|\\||::|->"),
|
||||||
PATTERNS("python", "^[ \t]*((class|(async[ \t]+)?def)[ \t].*)$",
|
PATTERNS("python",
|
||||||
|
"^[ \t]*((class|(async[ \t]+)?def)[ \t].*)$",
|
||||||
/* -- */
|
/* -- */
|
||||||
"[a-zA-Z_][a-zA-Z0-9_]*"
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
"|[-+0-9.e]+[jJlL]?|0[xX]?[0-9a-fA-F]+[lL]?"
|
"|[-+0-9.e]+[jJlL]?|0[xX]?[0-9a-fA-F]+[lL]?"
|
||||||
"|[-+*/<>%&^|=!]=|//=?|<<=?|>>=?|\\*\\*=?"),
|
"|[-+*/<>%&^|=!]=|//=?|<<=?|>>=?|\\*\\*=?"),
|
||||||
/* -- */
|
/* -- */
|
||||||
PATTERNS("ruby", "^[ \t]*((class|module|def)[ \t].*)$",
|
PATTERNS("ruby",
|
||||||
|
"^[ \t]*((class|module|def)[ \t].*)$",
|
||||||
/* -- */
|
/* -- */
|
||||||
"(@|@@|\\$)?[a-zA-Z_][a-zA-Z0-9_]*"
|
"(@|@@|\\$)?[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
"|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+|\\?(\\\\C-)?(\\\\M-)?."
|
"|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+|\\?(\\\\C-)?(\\\\M-)?."
|
||||||
@ -200,46 +247,8 @@ PATTERNS("scheme",
|
|||||||
"\\|([^\\\\]*)\\|"
|
"\\|([^\\\\]*)\\|"
|
||||||
/* All other words should be delimited by spaces or parentheses */
|
/* All other words should be delimited by spaces or parentheses */
|
||||||
"|([^][)(}{[ \t])+"),
|
"|([^][)(}{[ \t])+"),
|
||||||
PATTERNS("bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$",
|
|
||||||
"[={}\"]|[^={}\" \t]+"),
|
|
||||||
PATTERNS("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$",
|
PATTERNS("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$",
|
||||||
"\\\\[a-zA-Z@]+|\\\\.|[a-zA-Z0-9\x80-\xff]+"),
|
"\\\\[a-zA-Z@]+|\\\\.|[a-zA-Z0-9\x80-\xff]+"),
|
||||||
PATTERNS("cpp",
|
|
||||||
/* Jump targets or access declarations */
|
|
||||||
"!^[ \t]*[A-Za-z_][A-Za-z_0-9]*:[[:space:]]*($|/[/*])\n"
|
|
||||||
/* functions/methods, variables, and compounds at top level */
|
|
||||||
"^((::[[:space:]]*)?[A-Za-z_].*)$",
|
|
||||||
/* -- */
|
|
||||||
"[a-zA-Z_][a-zA-Z0-9_]*"
|
|
||||||
"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lLuU]*"
|
|
||||||
"|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->\\*?|\\.\\*"),
|
|
||||||
PATTERNS("csharp",
|
|
||||||
/* Keywords */
|
|
||||||
"!^[ \t]*(do|while|for|if|else|instanceof|new|return|switch|case|throw|catch|using)\n"
|
|
||||||
/* Methods and constructors */
|
|
||||||
"^[ \t]*(((static|public|internal|private|protected|new|virtual|sealed|override|unsafe|async)[ \t]+)*[][<>@.~_[:alnum:]]+[ \t]+[<>@._[:alnum:]]+[ \t]*\\(.*\\))[ \t]*$\n"
|
|
||||||
/* Properties */
|
|
||||||
"^[ \t]*(((static|public|internal|private|protected|new|virtual|sealed|override|unsafe)[ \t]+)*[][<>@.~_[:alnum:]]+[ \t]+[@._[:alnum:]]+)[ \t]*$\n"
|
|
||||||
/* Type definitions */
|
|
||||||
"^[ \t]*(((static|public|internal|private|protected|new|unsafe|sealed|abstract|partial)[ \t]+)*(class|enum|interface|struct)[ \t]+.*)$\n"
|
|
||||||
/* Namespace */
|
|
||||||
"^[ \t]*(namespace[ \t]+.*)$",
|
|
||||||
/* -- */
|
|
||||||
"[a-zA-Z_][a-zA-Z0-9_]*"
|
|
||||||
"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
|
|
||||||
"|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
|
|
||||||
IPATTERN("css",
|
|
||||||
"![:;][[:space:]]*$\n"
|
|
||||||
"^[:[@.#]?[_a-z0-9].*$",
|
|
||||||
/* -- */
|
|
||||||
/*
|
|
||||||
* This regex comes from W3C CSS specs. Should theoretically also
|
|
||||||
* allow ISO 10646 characters U+00A0 and higher,
|
|
||||||
* but they are not handled in this regex.
|
|
||||||
*/
|
|
||||||
"-?[_a-zA-Z][-_a-zA-Z0-9]*" /* identifiers */
|
|
||||||
"|-?[0-9]+|\\#[0-9a-fA-F]+" /* numbers */
|
|
||||||
),
|
|
||||||
{ "default", NULL, -1, { NULL, 0 } },
|
{ "default", NULL, -1, { NULL, 0 } },
|
||||||
};
|
};
|
||||||
#undef PATTERNS
|
#undef PATTERNS
|
||||||
@ -259,20 +268,33 @@ static struct userdiff_driver driver_false = {
|
|||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct userdiff_driver *userdiff_find_by_namelen(const char *k, size_t len)
|
struct find_by_namelen_data {
|
||||||
|
const char *name;
|
||||||
|
size_t len;
|
||||||
|
struct userdiff_driver *driver;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int userdiff_find_by_namelen_cb(struct userdiff_driver *driver,
|
||||||
|
enum userdiff_driver_type type, void *priv)
|
||||||
{
|
{
|
||||||
int i;
|
struct find_by_namelen_data *cb_data = priv;
|
||||||
for (i = 0; i < ndrivers; i++) {
|
|
||||||
struct userdiff_driver *drv = drivers + i;
|
if (!strncmp(driver->name, cb_data->name, cb_data->len) &&
|
||||||
if (!strncmp(drv->name, k, len) && !drv->name[len])
|
!driver->name[cb_data->len]) {
|
||||||
return drv;
|
cb_data->driver = driver;
|
||||||
|
return 1; /* tell the caller to stop iterating */
|
||||||
}
|
}
|
||||||
for (i = 0; i < ARRAY_SIZE(builtin_drivers); i++) {
|
return 0;
|
||||||
struct userdiff_driver *drv = builtin_drivers + i;
|
|
||||||
if (!strncmp(drv->name, k, len) && !drv->name[len])
|
|
||||||
return drv;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
|
static struct userdiff_driver *userdiff_find_by_namelen(const char *name, size_t len)
|
||||||
|
{
|
||||||
|
struct find_by_namelen_data udcbdata = {
|
||||||
|
.name = name,
|
||||||
|
.len = len,
|
||||||
|
};
|
||||||
|
for_each_userdiff_driver(userdiff_find_by_namelen_cb, &udcbdata);
|
||||||
|
return udcbdata.driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_funcname(struct userdiff_funcname *f, const char *k,
|
static int parse_funcname(struct userdiff_funcname *f, const char *k,
|
||||||
@ -379,3 +401,36 @@ struct userdiff_driver *userdiff_get_textconv(struct repository *r,
|
|||||||
|
|
||||||
return driver;
|
return driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int for_each_userdiff_driver_list(each_userdiff_driver_fn fn,
|
||||||
|
enum userdiff_driver_type type, void *cb_data,
|
||||||
|
struct userdiff_driver *drv,
|
||||||
|
int drv_size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
for (i = 0; i < drv_size; i++) {
|
||||||
|
struct userdiff_driver *item = drv + i;
|
||||||
|
if ((ret = fn(item, type, cb_data)))
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int for_each_userdiff_driver(each_userdiff_driver_fn fn, void *cb_data)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = for_each_userdiff_driver_list(fn, USERDIFF_DRIVER_TYPE_CUSTOM,
|
||||||
|
cb_data, drivers, ndrivers);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = for_each_userdiff_driver_list(fn, USERDIFF_DRIVER_TYPE_BUILTIN,
|
||||||
|
cb_data, builtin_drivers,
|
||||||
|
ARRAY_SIZE(builtin_drivers));
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
13
userdiff.h
13
userdiff.h
@ -21,6 +21,12 @@ struct userdiff_driver {
|
|||||||
struct notes_cache *textconv_cache;
|
struct notes_cache *textconv_cache;
|
||||||
int textconv_want_cache;
|
int textconv_want_cache;
|
||||||
};
|
};
|
||||||
|
enum userdiff_driver_type {
|
||||||
|
USERDIFF_DRIVER_TYPE_BUILTIN = 1<<0,
|
||||||
|
USERDIFF_DRIVER_TYPE_CUSTOM = 1<<1,
|
||||||
|
};
|
||||||
|
typedef int (*each_userdiff_driver_fn)(struct userdiff_driver *,
|
||||||
|
enum userdiff_driver_type, void *);
|
||||||
|
|
||||||
int userdiff_config(const char *k, const char *v);
|
int userdiff_config(const char *k, const char *v);
|
||||||
struct userdiff_driver *userdiff_find_by_name(const char *name);
|
struct userdiff_driver *userdiff_find_by_name(const char *name);
|
||||||
@ -34,4 +40,11 @@ struct userdiff_driver *userdiff_find_by_path(struct index_state *istate,
|
|||||||
struct userdiff_driver *userdiff_get_textconv(struct repository *r,
|
struct userdiff_driver *userdiff_get_textconv(struct repository *r,
|
||||||
struct userdiff_driver *driver);
|
struct userdiff_driver *driver);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iterate over all userdiff drivers. The userdiff_driver_type
|
||||||
|
* argument to each_userdiff_driver_fn indicates their type. Return
|
||||||
|
* non-zero to exit early from the loop.
|
||||||
|
*/
|
||||||
|
int for_each_userdiff_driver(each_userdiff_driver_fn, void *);
|
||||||
|
|
||||||
#endif /* USERDIFF */
|
#endif /* USERDIFF */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user