From e730033a4f625b7086c7ba2af7940fe9e8136db6 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Wed, 23 Nov 2022 03:46:06 +0900 Subject: [PATCH] [EXPERIMENTAL] Sh: extract variables in variable assignments Signed-off-by: Masatake YAMATO --- Units/parser-sh.r/sh-comments.d/expected.tags | 4 ++ Units/parser-sh.r/sh-quotes.d/expected.tags | 5 +++ parsers/sh.c | 40 +++++++++++++++++-- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/Units/parser-sh.r/sh-comments.d/expected.tags b/Units/parser-sh.r/sh-comments.d/expected.tags index 0cb132b138..48532f69de 100644 --- a/Units/parser-sh.r/sh-comments.d/expected.tags +++ b/Units/parser-sh.r/sh-comments.d/expected.tags @@ -2,3 +2,7 @@ afterpound1 input.sh /^foo="#"; afterpound1() {}$/;" f afterpound2 input.sh /^foo="#\\""; afterpound2() {}$/;" f afterpound3 input.sh /^foo='#'; afterpound3() {}$/;" f afterpound4 input.sh /^foo='#'''; afterpound4() {}$/;" f +foo input.sh /^foo="#"; afterpound1() {}$/;" v +foo input.sh /^foo="#\\""; afterpound2() {}$/;" v +foo input.sh /^foo='#'''; afterpound4() {}$/;" v +foo input.sh /^foo='#'; afterpound3() {}$/;" v diff --git a/Units/parser-sh.r/sh-quotes.d/expected.tags b/Units/parser-sh.r/sh-quotes.d/expected.tags index 0cb132b138..1c71b53595 100644 --- a/Units/parser-sh.r/sh-quotes.d/expected.tags +++ b/Units/parser-sh.r/sh-quotes.d/expected.tags @@ -2,3 +2,8 @@ afterpound1 input.sh /^foo="#"; afterpound1() {}$/;" f afterpound2 input.sh /^foo="#\\""; afterpound2() {}$/;" f afterpound3 input.sh /^foo='#'; afterpound3() {}$/;" f afterpound4 input.sh /^foo='#'''; afterpound4() {}$/;" f +foo input.sh /^foo="#"; afterpound1() {}$/;" v +foo input.sh /^foo="#\\""; afterpound2() {}$/;" v +foo input.sh /^foo="nofunction()"$/;" v +foo input.sh /^foo='#'''; afterpound4() {}$/;" v +foo input.sh /^foo='#'; afterpound3() {}$/;" v diff --git a/parsers/sh.c b/parsers/sh.c index 2dc6520b55..47a28b3791 100644 --- a/parsers/sh.c +++ b/parsers/sh.c @@ -38,6 +38,7 @@ typedef enum { K_FUNCTION, K_SCRIPT, K_HEREDOCLABEL, + K_VARIABLE, } shKind; typedef enum { @@ -86,8 +87,9 @@ static roleDefinition ZshFunctionRoles [] = { .referenceOnly = false, FUNCTION_ROLES_SPEC }, \ { true, 's', "script", "script files", \ .referenceOnly = true, ATTACH_ROLES (SCRIPT_ROLES) }, \ - .referenceOnly = false, ATTACH_ROLES (HEREDOC_ROLES) } { true, 'h', "heredoc", "labels for here document", \ + .referenceOnly = false, ATTACH_ROLES (HEREDOC_ROLES) }, \ + { true, 'v', "variable", "variables assigment (experimental)" } static kindDefinition ShKinds [] = { SH_KINDS_COMMON(ShScriptRoles, ShHeredocRoles,), @@ -456,6 +458,34 @@ static size_t handleZshKeyword (int keyword, return vStringLength(token); } +static bool handleVariableAssignment (vString *input) +{ + const char *base = vStringValue (input); + const char *cp = base; + + while (*cp != '\0') + { + if (*cp == '=') + { + size_t len = cp - base; + /* Ignore VAR in if [[ \ + VAR == ... ]] */ + if (*(cp + 1) != '=' && len > 0) + { + vStringTruncate (input, len); + return true; + } + break; + } + else if ( ((cp == base)? + isIdentChar0: isIdentChar) ((unsigned char)*cp) ) + cp++; + else + break; + } + return false; +} + typedef bool (* checkCharFunc) (int); static void findShTagsCommon (size_t (* keyword_handler) (int, vString *, @@ -653,8 +683,9 @@ static void findShTagsCommon (size_t (* keyword_handler) (int, while (isspace ((int) *cp)) ++cp; - if ((found_kind != K_SCRIPT) - && *cp == '(') + if (found_kind == K_SCRIPT) + ; /* Do NOTHING */ + else if (*cp == '(') { ++cp; while (isspace ((int) *cp)) @@ -680,6 +711,9 @@ static void findShTagsCommon (size_t (* keyword_handler) (int, ++cp; } } + else if (found_kind == K_NOTHING + && handleVariableAssignment (name)) + found_kind = K_VARIABLE; if (found_kind != K_NOTHING) {