{"thread":{"id":"38765","subject":"[GSoC][PATCH] userdiff: funcname and word patterns for sh","startedAt":"2015-03-09T16:36:38Z","lastAt":"2015-03-25T21:36:26Z","messageCount":7,"participants":["Adrien Schildknecht","Matthieu Moy","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"257410","messageId":"1425918999-11992-1-git-send-email-adrien+dev@schischi.me","threadId":"38765","inReplyTo":null,"subject":"[GSoC][PATCH] userdiff: funcname and word patterns for sh","fromName":"Adrien Schildknecht","fromEmail":"adrien+dev@schischi.me","sentAt":"2015-03-09T16:36:38Z","receivedAt":"2015-03-09T16:36:38Z","isPatch":true,"sender":{"key":"adrien+dev@schischi.me","avatar":"https://gravatar.com/avatar/cf68380ba79de861b757382c4f3858f2b3602903d931b97b7f03c73fe03848e8?d=mp&s=160"},"body":"Hi,\nI'm a french student from EPITA and I plan to apply for the GSoC.\n\nAdrien Schildknecht (1):\n  userdiff: funcname and word patterns for sh\n\n Documentation/gitattributes.txt |  2 ++\n t/t4018-diff-funcname.sh        |  1 +\n t/t4018/sh-function             |  4 ++++\n t/t4018/sh-function-comment     |  6 ++++++\n t/t4018/sh-function-nested      |  7 +++++++\n t/t4018/sh-function-prefix      |  4 ++++\n t/t4018/sh-function-string      |  4 ++++\n t/t4034-diff-words.sh           |  1 +\n t/t4034/sh/expect               | 46 +++++++++++++++++++++++++++++++++++++++++\n t/t4034/sh/post                 | 36 ++++++++++++++++++++++++++++++++\n t/t4034/sh/pre                  | 36 ++++++++++++++++++++++++++++++++\n userdiff.c                      |  7 +++++++\n 12 files changed, 154 insertions(+)\n create mode 100644 t/t4018/sh-function\n create mode 100644 t/t4018/sh-function-comment\n create mode 100644 t/t4018/sh-function-nested\n create mode 100644 t/t4018/sh-function-prefix\n create mode 100644 t/t4018/sh-function-string\n create mode 100644 t/t4034/sh/expect\n create mode 100644 t/t4034/sh/post\n create mode 100644 t/t4034/sh/pre\n\n-- \nAdrien Schildknecht\nhttp://schischi.me\n"},{"id":"257411","messageId":"1425918999-11992-2-git-send-email-adrien+dev@schischi.me","threadId":"38765","inReplyTo":"1425918999-11992-1-git-send-email-adrien+dev@schischi.me","subject":"[PATCH] userdiff: funcname and word patterns for sh","fromName":"Adrien Schildknecht","fromEmail":"adrien+dev@schischi.me","sentAt":"2015-03-09T16:36:39Z","receivedAt":"2015-03-09T16:36:39Z","isPatch":true,"sender":{"key":"adrien+dev@schischi.me","avatar":"https://gravatar.com/avatar/cf68380ba79de861b757382c4f3858f2b3602903d931b97b7f03c73fe03848e8?d=mp&s=160"},"body":"Add regexp based on the \"Shell Command Language\" specifications.\nBecause of the lax syntax of sh, some corner cases may not be\nhandled properly.\n\nSigned-off-by: Adrien Schildknecht <adrien+dev@schischi.me>\n---\n Documentation/gitattributes.txt |  2 ++\n t/t4018-diff-funcname.sh        |  1 +\n t/t4018/sh-function             |  4 ++++\n t/t4018/sh-function-comment     |  6 ++++++\n t/t4018/sh-function-nested      |  7 +++++++\n t/t4018/sh-function-prefix      |  4 ++++\n t/t4018/sh-function-string      |  4 ++++\n t/t4034-diff-words.sh           |  1 +\n t/t4034/sh/expect               | 46 +++++++++++++++++++++++++++++++++++++++++\n t/t4034/sh/post                 | 36 ++++++++++++++++++++++++++++++++\n t/t4034/sh/pre                  | 36 ++++++++++++++++++++++++++++++++\n userdiff.c                      |  7 +++++++\n 12 files changed, 154 insertions(+)\n create mode 100644 t/t4018/sh-function\n create mode 100644 t/t4018/sh-function-comment\n create mode 100644 t/t4018/sh-function-nested\n create mode 100644 t/t4018/sh-function-prefix\n create mode 100644 t/t4018/sh-function-string\n create mode 100644 t/t4034/sh/expect\n create mode 100644 t/t4034/sh/post\n create mode 100644 t/t4034/sh/pre\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex c892ffa..fb13761 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -545,6 +545,8 @@ patterns are available:\n \n - `ruby` suitable for source code in the Ruby language.\n \n+- `sh` suitable for source code in the Shell language.\n+\n - `tex` suitable for source code for LaTeX documents.\n \n \ndiff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh\nindex 1dbaa38..960b6e4 100755\n--- a/t/t4018-diff-funcname.sh\n+++ b/t/t4018-diff-funcname.sh\n@@ -40,6 +40,7 @@ diffpatterns=\"\n \tphp\n \tpython\n \truby\n+\tsh\n \ttex\n \tcustom1\n \tcustom2\ndiff --git a/t/t4018/sh-function b/t/t4018/sh-function\nnew file mode 100644\nindex 0000000..1d5096a\n--- /dev/null\n+++ b/t/t4018/sh-function\n@@ -0,0 +1,4 @@\n+RIGHT_foo()\n+{\n+\tChangeMe;\n+}\ndiff --git a/t/t4018/sh-function-comment b/t/t4018/sh-function-comment\nnew file mode 100644\nindex 0000000..f340ee7\n--- /dev/null\n+++ b/t/t4018/sh-function-comment\n@@ -0,0 +1,6 @@\n+  RIGHT_foo() # echo 'foo'\n+#bar()\n+{\n+\t#bar()\n+\tChangeMe;\n+}\ndiff --git a/t/t4018/sh-function-nested b/t/t4018/sh-function-nested\nnew file mode 100644\nindex 0000000..d3263f3\n--- /dev/null\n+++ b/t/t4018/sh-function-nested\n@@ -0,0 +1,7 @@\n+foo (     )\n+{\n+\tRIGHT_bar()\n+\t{\n+\t\techo ChangeMe\n+\t}\n+}\ndiff --git a/t/t4018/sh-function-prefix b/t/t4018/sh-function-prefix\nnew file mode 100644\nindex 0000000..e96eb7a\n--- /dev/null\n+++ b/t/t4018/sh-function-prefix\n@@ -0,0 +1,4 @@\n+function RIGHT_foo()\n+{\n+\tChangeMe;\n+}\ndiff --git a/t/t4018/sh-function-string b/t/t4018/sh-function-string\nnew file mode 100644\nindex 0000000..f60a899\n--- /dev/null\n+++ b/t/t4018/sh-function-string\n@@ -0,0 +1,4 @@\n+RIGHT_foo() {\n+\techo \"bar()\"\n+\tChangeMe;\n+}\ndiff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh\nindex f2f55fc..24fd9aa 100755\n--- a/t/t4034-diff-words.sh\n+++ b/t/t4034-diff-words.sh\n@@ -312,6 +312,7 @@ test_language_driver perl\n test_language_driver php\n test_language_driver python\n test_language_driver ruby\n+test_language_driver sh\n test_language_driver tex\n \n test_expect_success 'word-diff with diff.sbe' '\ndiff --git a/t/t4034/sh/expect b/t/t4034/sh/expect\nnew file mode 100644\nindex 0000000..1c6de2d\n--- /dev/null\n+++ b/t/t4034/sh/expect\n@@ -0,0 +1,46 @@\n+<BOLD>diff --git a/pre b/post<RESET>\n+<BOLD>index 20229c3..ab791db 100644<RESET>\n+<BOLD>--- a/pre<RESET>\n+<BOLD>+++ b/post<RESET>\n+<CYAN>@@ -1,36 +1,36 @@<RESET>\n+foo() {ls&echo}<RESET>\n+$((<RED>a<RESET><GREEN>x<RESET>++))\n+$((<RED>a<RESET><GREEN>x<RESET>--))\n+$((--<RED>a<RESET><GREEN>x<RESET>))\n+$((++<RED>a<RESET><GREEN>x<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>*<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>&<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>**<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>/<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>%<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>+<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>-<RED>b<RESET><GREEN>y<RESET>))\n+[ <RED>a<RESET><GREEN>x<RESET><=<RED>b<RESET><GREEN>y<RESET> ]\n+[ <RED>a<RESET><GREEN>x<RESET>>=<RED>b<RESET><GREEN>y<RESET> ]\n+[ <RED>a<RESET><GREEN>x<RESET>==<RED>b<RESET><GREEN>y<RESET> ]\n+[ <RED>a<RESET><GREEN>x<RESET>!=<RED>b<RESET><GREEN>y<RESET> ]\n+<RED>a<RESET><GREEN>x<RESET><<<RED>b a<RESET><GREEN>y x<RESET>>><RED>b a<RESET><GREEN>y x<RESET><<-<RED>b a<RESET><GREEN>y x<RESET><<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>|<RED>b a<RESET><GREEN>y x<RESET><&<RED>b a<RESET><GREEN>y x<RESET>>&<RED>b a<RESET><GREEN>y x<RESET><><RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>&&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>|<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>||<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>=<RED>b<RESET><GREEN>y<RESET>\n+$((<RED>a<RESET><GREEN>x<RESET>+=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>-=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>*=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>/=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>%=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET><<=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>>>=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>&=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>^=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>|=<RED>b<RESET><GREEN>y<RESET>))\n+*)<RED>a<RESET><GREEN>b<RESET>;;ls\n+FOO=42&<RED>foo<RESET><GREEN>fro<RESET>\n+BAR=$(0)<RESET>\n+[[ $<RED>a<RESET><GREEN>x<RESET> -eq $<RED>b<RESET><GREEN>y<RESET> ]]\ndiff --git a/t/t4034/sh/post b/t/t4034/sh/post\nnew file mode 100644\nindex 0000000..ab791db\n--- /dev/null\n+++ b/t/t4034/sh/post\n@@ -0,0 +1,36 @@\n+foo() {ls&echo}\n+$((x++))\n+$((x--))\n+$((--x))\n+$((++x))\n+$((x*y))\n+$((x&y))\n+$((x**y))\n+$((x/y))\n+$((x%y))\n+$((x+y))\n+$((x-y))\n+[ x<=y ]\n+[ x>=y ]\n+[ x==y ]\n+[ x!=y ]\n+x<<y x>>y x<<-y x<y x>y x>|y x<&y x>&y x<>y\n+x&y\n+x&&y\n+x|y\n+x||y\n+x=y\n+$((x+=y))\n+$((x-=y))\n+$((x*=y))\n+$((x/=y))\n+$((x%=y))\n+$((x<<=y))\n+$((x>>=y))\n+$((x&=y))\n+$((x^=y))\n+$((x|=y))\n+*)b;;ls\n+FOO=42&fro\n+BAR=$(0)\n+[[ $x -eq $y ]]\ndiff --git a/t/t4034/sh/pre b/t/t4034/sh/pre\nnew file mode 100644\nindex 0000000..20229c3\n--- /dev/null\n+++ b/t/t4034/sh/pre\n@@ -0,0 +1,36 @@\n+foo() {ls&echo}\n+$((a++))\n+$((a--))\n+$((--a))\n+$((++a))\n+$((a*b))\n+$((a&b))\n+$((a**b))\n+$((a/b))\n+$((a%b))\n+$((a+b))\n+$((a-b))\n+[ a<=b ]\n+[ a>=b ]\n+[ a==b ]\n+[ a!=b ]\n+a<<b a>>b a<<-b a<b a>b a>|b a<&b a>&b a<>b\n+a&b\n+a&&b\n+a|b\n+a||b\n+a=b\n+$((a+=b))\n+$((a-=b))\n+$((a*=b))\n+$((a/=b))\n+$((a%=b))\n+$((a<<=b))\n+$((a>>=b))\n+$((a&=b))\n+$((a^=b))\n+$((a|=b))\n+*)a;;ls\n+FOO=42&foo\n+BAR=$(0)\n+[[ $a -eq $b ]]\ndiff --git a/userdiff.c b/userdiff.c\nindex 2ccbee5..40b3dc0 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -146,6 +146,13 @@ PATTERNS(\"csharp\",\n \t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n \t \"|[-+*/<>%&^|=!]=|--|\\\\+\\\\+|<<=?|>>=?|&&|\\\\|\\\\||::|->\"),\n+PATTERNS(\"sh\",\n+\t\"^([ \\t]*(function[ \\t]*)?[a-zA-Z_][a-zA-Z0-9_]*[ \\t]*\\\\([ \\t]*\\\\).*)$\",\n+\t/* -- */\n+\t \"[a-zA-Z0-9_]+\"\n+\t \"|[-+0-9]+\"\n+\t \"|[-+*/<>%&^|=!]=|>>=?|<<=?|\\\\+\\\\+|--|\\\\*\\\\*|&&|\\\\|\\\\||\\\\[\\\\[|\\\\]\\\\]\"\n+\t \"|>\\\\||[<>]+&|<>|<<-|;;\"),\n { \"default\", NULL, -1, { NULL, 0 } },\n };\n #undef PATTERNS\n-- \nAdrien Schildknecht\nhttp://schischi.me\n"},{"id":"257427","messageId":"vpqy4n53o68.fsf@anie.imag.fr","threadId":"38765","inReplyTo":"1425918999-11992-2-git-send-email-adrien+dev@schischi.me","subject":"Re: [PATCH] userdiff: funcname and word patterns for sh","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-03-09T20:34:39Z","receivedAt":"2015-03-09T20:34:39Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Adrien Schildknecht <adrien+dev@schischi.me> writes:\n\n> +\t\"^([ \\t]*(function[ \\t]*)?[a-zA-Z_][a-zA-Z0-9_]*[ \\t]*\\\\([ \\t]*\\\\).*)$\",\n\nI guess this should be 'function[ \\t]+' (+, not *).\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"257436","messageId":"1425944432-23642-1-git-send-email-adrien+dev@schischi.me","threadId":"38765","inReplyTo":"1425918999-11992-2-git-send-email-adrien+dev@schischi.me","subject":"[PATCH v2] userdiff: funcname and word patterns for sh","fromName":"Adrien Schildknecht","fromEmail":"adrien+dev@schischi.me","sentAt":"2015-03-09T23:40:32Z","receivedAt":"2015-03-09T23:40:32Z","isPatch":true,"sender":{"key":"adrien+dev@schischi.me","avatar":"https://gravatar.com/avatar/cf68380ba79de861b757382c4f3858f2b3602903d931b97b7f03c73fe03848e8?d=mp&s=160"},"body":"Add regexp based on the \"Shell Command Language\" specifications.\nBecause of the lax syntax of sh, some corner cases may not be\nhandled properly.\n\nSigned-off-by: Adrien Schildknecht <adrien+dev@schischi.me>\n---\n Documentation/gitattributes.txt |  2 ++\n t/t4018-diff-funcname.sh        |  1 +\n t/t4018/sh-function             |  4 ++++\n t/t4018/sh-function-comment     |  6 ++++++\n t/t4018/sh-function-nested      |  7 +++++++\n t/t4018/sh-function-prefix      |  4 ++++\n t/t4018/sh-function-string      |  4 ++++\n t/t4034-diff-words.sh           |  1 +\n t/t4034/sh/expect               | 46 +++++++++++++++++++++++++++++++++++++++++\n t/t4034/sh/post                 | 36 ++++++++++++++++++++++++++++++++\n t/t4034/sh/pre                  | 36 ++++++++++++++++++++++++++++++++\n userdiff.c                      |  7 +++++++\n 12 files changed, 154 insertions(+)\n create mode 100644 t/t4018/sh-function\n create mode 100644 t/t4018/sh-function-comment\n create mode 100644 t/t4018/sh-function-nested\n create mode 100644 t/t4018/sh-function-prefix\n create mode 100644 t/t4018/sh-function-string\n create mode 100644 t/t4034/sh/expect\n create mode 100644 t/t4034/sh/post\n create mode 100644 t/t4034/sh/pre\n\ndiff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt\nindex c892ffa..fb13761 100644\n--- a/Documentation/gitattributes.txt\n+++ b/Documentation/gitattributes.txt\n@@ -545,6 +545,8 @@ patterns are available:\n \n - `ruby` suitable for source code in the Ruby language.\n \n+- `sh` suitable for source code in the Shell language.\n+\n - `tex` suitable for source code for LaTeX documents.\n \n \ndiff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh\nindex 1dbaa38..960b6e4 100755\n--- a/t/t4018-diff-funcname.sh\n+++ b/t/t4018-diff-funcname.sh\n@@ -40,6 +40,7 @@ diffpatterns=\"\n \tphp\n \tpython\n \truby\n+\tsh\n \ttex\n \tcustom1\n \tcustom2\ndiff --git a/t/t4018/sh-function b/t/t4018/sh-function\nnew file mode 100644\nindex 0000000..1d5096a\n--- /dev/null\n+++ b/t/t4018/sh-function\n@@ -0,0 +1,4 @@\n+RIGHT_foo()\n+{\n+\tChangeMe;\n+}\ndiff --git a/t/t4018/sh-function-comment b/t/t4018/sh-function-comment\nnew file mode 100644\nindex 0000000..f340ee7\n--- /dev/null\n+++ b/t/t4018/sh-function-comment\n@@ -0,0 +1,6 @@\n+  RIGHT_foo() # echo 'foo'\n+#bar()\n+{\n+\t#bar()\n+\tChangeMe;\n+}\ndiff --git a/t/t4018/sh-function-nested b/t/t4018/sh-function-nested\nnew file mode 100644\nindex 0000000..d3263f3\n--- /dev/null\n+++ b/t/t4018/sh-function-nested\n@@ -0,0 +1,7 @@\n+foo (     )\n+{\n+\tRIGHT_bar()\n+\t{\n+\t\techo ChangeMe\n+\t}\n+}\ndiff --git a/t/t4018/sh-function-prefix b/t/t4018/sh-function-prefix\nnew file mode 100644\nindex 0000000..e96eb7a\n--- /dev/null\n+++ b/t/t4018/sh-function-prefix\n@@ -0,0 +1,4 @@\n+function RIGHT_foo()\n+{\n+\tChangeMe;\n+}\ndiff --git a/t/t4018/sh-function-string b/t/t4018/sh-function-string\nnew file mode 100644\nindex 0000000..f60a899\n--- /dev/null\n+++ b/t/t4018/sh-function-string\n@@ -0,0 +1,4 @@\n+RIGHT_foo() {\n+\techo \"bar()\"\n+\tChangeMe;\n+}\ndiff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh\nindex f2f55fc..24fd9aa 100755\n--- a/t/t4034-diff-words.sh\n+++ b/t/t4034-diff-words.sh\n@@ -312,6 +312,7 @@ test_language_driver perl\n test_language_driver php\n test_language_driver python\n test_language_driver ruby\n+test_language_driver sh\n test_language_driver tex\n \n test_expect_success 'word-diff with diff.sbe' '\ndiff --git a/t/t4034/sh/expect b/t/t4034/sh/expect\nnew file mode 100644\nindex 0000000..1c6de2d\n--- /dev/null\n+++ b/t/t4034/sh/expect\n@@ -0,0 +1,46 @@\n+<BOLD>diff --git a/pre b/post<RESET>\n+<BOLD>index 20229c3..ab791db 100644<RESET>\n+<BOLD>--- a/pre<RESET>\n+<BOLD>+++ b/post<RESET>\n+<CYAN>@@ -1,36 +1,36 @@<RESET>\n+foo() {ls&echo}<RESET>\n+$((<RED>a<RESET><GREEN>x<RESET>++))\n+$((<RED>a<RESET><GREEN>x<RESET>--))\n+$((--<RED>a<RESET><GREEN>x<RESET>))\n+$((++<RED>a<RESET><GREEN>x<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>*<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>&<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>**<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>/<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>%<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>+<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>-<RED>b<RESET><GREEN>y<RESET>))\n+[ <RED>a<RESET><GREEN>x<RESET><=<RED>b<RESET><GREEN>y<RESET> ]\n+[ <RED>a<RESET><GREEN>x<RESET>>=<RED>b<RESET><GREEN>y<RESET> ]\n+[ <RED>a<RESET><GREEN>x<RESET>==<RED>b<RESET><GREEN>y<RESET> ]\n+[ <RED>a<RESET><GREEN>x<RESET>!=<RED>b<RESET><GREEN>y<RESET> ]\n+<RED>a<RESET><GREEN>x<RESET><<<RED>b a<RESET><GREEN>y x<RESET>>><RED>b a<RESET><GREEN>y x<RESET><<-<RED>b a<RESET><GREEN>y x<RESET><<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>|<RED>b a<RESET><GREEN>y x<RESET><&<RED>b a<RESET><GREEN>y x<RESET>>&<RED>b a<RESET><GREEN>y x<RESET><><RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>&&<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>|<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>||<RED>b<RESET>\n+<RED>a<RESET><GREEN>y<RESET>\n+<GREEN>x<RESET>=<RED>b<RESET><GREEN>y<RESET>\n+$((<RED>a<RESET><GREEN>x<RESET>+=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>-=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>*=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>/=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>%=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET><<=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>>>=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>&=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>^=<RED>b<RESET><GREEN>y<RESET>))\n+$((<RED>a<RESET><GREEN>x<RESET>|=<RED>b<RESET><GREEN>y<RESET>))\n+*)<RED>a<RESET><GREEN>b<RESET>;;ls\n+FOO=42&<RED>foo<RESET><GREEN>fro<RESET>\n+BAR=$(0)<RESET>\n+[[ $<RED>a<RESET><GREEN>x<RESET> -eq $<RED>b<RESET><GREEN>y<RESET> ]]\ndiff --git a/t/t4034/sh/post b/t/t4034/sh/post\nnew file mode 100644\nindex 0000000..ab791db\n--- /dev/null\n+++ b/t/t4034/sh/post\n@@ -0,0 +1,36 @@\n+foo() {ls&echo}\n+$((x++))\n+$((x--))\n+$((--x))\n+$((++x))\n+$((x*y))\n+$((x&y))\n+$((x**y))\n+$((x/y))\n+$((x%y))\n+$((x+y))\n+$((x-y))\n+[ x<=y ]\n+[ x>=y ]\n+[ x==y ]\n+[ x!=y ]\n+x<<y x>>y x<<-y x<y x>y x>|y x<&y x>&y x<>y\n+x&y\n+x&&y\n+x|y\n+x||y\n+x=y\n+$((x+=y))\n+$((x-=y))\n+$((x*=y))\n+$((x/=y))\n+$((x%=y))\n+$((x<<=y))\n+$((x>>=y))\n+$((x&=y))\n+$((x^=y))\n+$((x|=y))\n+*)b;;ls\n+FOO=42&fro\n+BAR=$(0)\n+[[ $x -eq $y ]]\ndiff --git a/t/t4034/sh/pre b/t/t4034/sh/pre\nnew file mode 100644\nindex 0000000..20229c3\n--- /dev/null\n+++ b/t/t4034/sh/pre\n@@ -0,0 +1,36 @@\n+foo() {ls&echo}\n+$((a++))\n+$((a--))\n+$((--a))\n+$((++a))\n+$((a*b))\n+$((a&b))\n+$((a**b))\n+$((a/b))\n+$((a%b))\n+$((a+b))\n+$((a-b))\n+[ a<=b ]\n+[ a>=b ]\n+[ a==b ]\n+[ a!=b ]\n+a<<b a>>b a<<-b a<b a>b a>|b a<&b a>&b a<>b\n+a&b\n+a&&b\n+a|b\n+a||b\n+a=b\n+$((a+=b))\n+$((a-=b))\n+$((a*=b))\n+$((a/=b))\n+$((a%=b))\n+$((a<<=b))\n+$((a>>=b))\n+$((a&=b))\n+$((a^=b))\n+$((a|=b))\n+*)a;;ls\n+FOO=42&foo\n+BAR=$(0)\n+[[ $a -eq $b ]]\ndiff --git a/userdiff.c b/userdiff.c\nindex 2ccbee5..40b3dc0 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -146,6 +146,13 @@ PATTERNS(\"csharp\",\n \t \"[a-zA-Z_][a-zA-Z0-9_]*\"\n \t \"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?\"\n \t \"|[-+*/<>%&^|=!]=|--|\\\\+\\\\+|<<=?|>>=?|&&|\\\\|\\\\||::|->\"),\n+PATTERNS(\"sh\",\n+\t\"^([ \\t]*(function[ \\t]+)?[a-zA-Z_][a-zA-Z0-9_]*[ \\t]*\\\\([ \\t]*\\\\).*)$\",\n+\t/* -- */\n+\t \"[a-zA-Z0-9_]+\"\n+\t \"|[-+0-9]+\"\n+\t \"|[-+*/<>%&^|=!]=|>>=?|<<=?|\\\\+\\\\+|--|\\\\*\\\\*|&&|\\\\|\\\\||\\\\[\\\\[|\\\\]\\\\]\"\n+\t \"|>\\\\||[<>]+&|<>|<<-|;;\"),\n { \"default\", NULL, -1, { NULL, 0 } },\n };\n #undef PATTERNS\n-- \nAdrien Schildknecht\nhttp://schischi.me\n"},{"id":"257662","messageId":"xmqqy4n0xiu2.fsf@gitster.dls.corp.google.com","threadId":"38765","inReplyTo":"1425944432-23642-1-git-send-email-adrien+dev@schischi.me","subject":"Re: [PATCH v2] userdiff: funcname and word patterns for sh","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-03-14T05:13:09Z","receivedAt":"2015-03-14T05:13:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Adrien Schildknecht <adrien+dev@schischi.me> writes:\n\n> Add regexp based on the \"Shell Command Language\" specifications.\n> Because of the lax syntax of sh, some corner cases may not be\n> handled properly.\n>\n> Signed-off-by: Adrien Schildknecht <adrien+dev@schischi.me>\n> ---\n\nThose of you who helped in the first round of review, any comments,\n\"This round looks good\"'s, ...?\n\n> +PATTERNS(\"sh\",\n> +\t\"^([ \\t]*(function[ \\t]+)?[a-zA-Z_][a-zA-Z0-9_]*[ \\t]*\\\\([ \\t]*\\\\).*)$\",\n> +\t/* -- */\n\nI do not think it is wrong per-se to try to be as precise as\npossible, but I wonder if it is sufficient to cheat and make these\n\"what is a word?\" expressions a bit looser, by declaring that it is\nOK if a simpler pattern allows something that are syntactically\nillegal in shell, as long as it splits valid shell construct\ncorrectly.  For example:\n\n> +\t \"[a-zA-Z0-9_]+\"\n> +\t \"|[-+0-9]+\"\n\nThe first one matches an identifier (e.g. If you have frotz=\"a b c\"\nand $frotz, two appearances of 'frotz' are matched) and the second\none I think is trying to catch possibly signed integers, but the\nlatter also matches 0+1+++2 which is already loose (but I do not\nthink it is a problem).  Perhaps it is sufficient to collapse the\nabove into a single \"[-+a-zA-Z0-9_$]+\"?\n\n> +\t \"|[-+*/<>%&^|=!]=|>>=?|<<=?|\\\\+\\\\+|--|\\\\*\\\\*|&&|\\\\|\\\\||\\\\[\\\\[|\\\\]\\\\]\"\n> +\t \"|>\\\\||[<>]+&|<>|<<-|;;\"),\n\nLikewise.  I wonder if something like \"[-~!@#%^&*+=|;/]+\" gives too\nmany false matches.\n\n>  { \"default\", NULL, -1, { NULL, 0 } },\n>  };\n>  #undef PATTERNS\n"},{"id":"257678","messageId":"vpqoanvjy3k.fsf@anie.imag.fr","threadId":"38765","inReplyTo":"1425944432-23642-1-git-send-email-adrien+dev@schischi.me","subject":"Re: [PATCH v2] userdiff: funcname and word patterns for sh","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-03-14T17:19:27Z","receivedAt":"2015-03-14T17:19:27Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"On overall, the patch looks good. Some suggestions to improve the tests\nand a minor nitpick below.\n\nAdrien Schildknecht <adrien+dev@schischi.me> writes:\n\n> +++ b/t/t4034/sh/post\n> @@ -0,0 +1,36 @@\n> +foo() {ls&echo}\n\nThis part is unchanged here and in the pre file. What does it test?\n\n> +$((x++))\n> +$((x--))\n> +$((--x))\n> +$((++x))\n> +$((x*y))\n> +$((x&y))\n> +$((x**y))\n> +$((x/y))\n> +$((x%y))\n> +$((x+y))\n> +$((x-y))\n> +[ x<=y ]\n> +[ x>=y ]\n> +[ x==y ]\n> +[ x!=y ]\n\nNot sure what the last ones are testing. If it's \"[\" as \"the test\ncommand, spelled as [\", then spaces are mandatory around the operators\n(and equality should be written =, not == in POSIX).\n\n> +x<<y x>>y x<<-y x<y x>y x>|y x<&y x>&y x<>y\n> +x&y\n> +x&&y\n> +x|y\n> +x||y\n> +x=y\n> +$((x+=y))\n> +$((x-=y))\n> +$((x*=y))\n> +$((x/=y))\n> +$((x%=y))\n> +$((x<<=y))\n> +$((x>>=y))\n> +$((x&=y))\n> +$((x^=y))\n> +$((x|=y))\n\nI think you should test the case of multiple-letters identifiers. One of\nthe benefit of having a proper word-diff pattern is that e.g.\n\n- pre=foo\n+ post=bar\n\nwill consider the change \"pre\" -> \"post\", and not an unmodified \"p\" with\nthe change \"re\" -> \"ost\" (otherwise, --color-words=. just works).\n\n> +PATTERNS(\"sh\",\n> +\t\"^([ \\t]*(function[ \\t]+)?[a-zA-Z_][a-zA-Z0-9_]*[ \\t]*\\\\([ \\t]*\\\\).*)$\",\n> +\t/* -- */\n> +\t \"[a-zA-Z0-9_]+\"\n\nNitpick: the indentation is not homogeneous. You should add a space\nafter the tab on the first two lines to get a correct alignment.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"258526","messageId":"xmqqiodo2205.fsf@gitster.dls.corp.google.com","threadId":"38765","inReplyTo":"1425944432-23642-1-git-send-email-adrien+dev@schischi.me","subject":"Re: [PATCH v2] userdiff: funcname and word patterns for sh","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-03-25T21:36:26Z","receivedAt":"2015-03-25T21:36:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Adrien Schildknecht <adrien+dev@schischi.me> writes:\n\n> Add regexp based on the \"Shell Command Language\" specifications.\n> Because of the lax syntax of sh, some corner cases may not be\n> handled properly.\n>\n> Signed-off-by: Adrien Schildknecht <adrien+dev@schischi.me>\n> ---\n\nIs a reroll for this patch coming, or should I drop this from my\ntree for now?\n\nThanks.\n"}]}