pkgsrc-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[pkgsrc/trunk]: pkgsrc/pkgtools/pkglint pkgtools/pkglint: update to 5.7.19



details:   https://anonhg.NetBSD.org/pkgsrc/rev/8e61b594e28a
branches:  trunk
changeset: 399096:8e61b594e28a
user:      rillig <rillig%pkgsrc.org@localhost>
date:      Fri Aug 02 18:55:07 2019 +0000

description:
pkgtools/pkglint: update to 5.7.19

Changes since 5.7.18:

* The tricky construct for generating case-items from a Make variable
  no longer produces parse errors. Example:

  case $$expr in ${PATTERNS:@p@ (${p}) action ;; @} esac

diffstat:

 pkgtools/pkglint/Makefile                 |   4 +-
 pkgtools/pkglint/files/mkshparser.go      |  15 ++++++++
 pkgtools/pkglint/files/mkshparser_test.go |  56 +++++++++++++++++++++++++++++-
 pkgtools/pkglint/files/mkshtypes.go       |   1 +
 pkgtools/pkglint/files/mkshwalker.go      |   4 +-
 pkgtools/pkglint/files/shell.y            |  13 ++++--
 pkgtools/pkglint/files/shell_test.go      |   9 ++--
 7 files changed, 87 insertions(+), 15 deletions(-)

diffs (203 lines):

diff -r a340c986243e -r 8e61b594e28a pkgtools/pkglint/Makefile
--- a/pkgtools/pkglint/Makefile Fri Aug 02 17:17:18 2019 +0000
+++ b/pkgtools/pkglint/Makefile Fri Aug 02 18:55:07 2019 +0000
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.590 2019/08/01 22:38:49 rillig Exp $
+# $NetBSD: Makefile,v 1.591 2019/08/02 18:55:07 rillig Exp $
 
-PKGNAME=       pkglint-5.7.18
+PKGNAME=       pkglint-5.7.19
 CATEGORIES=    pkgtools
 DISTNAME=      tools
 MASTER_SITES=  ${MASTER_SITE_GITHUB:=golang/}
diff -r a340c986243e -r 8e61b594e28a pkgtools/pkglint/files/mkshparser.go
--- a/pkgtools/pkglint/files/mkshparser.go      Fri Aug 02 17:17:18 2019 +0000
+++ b/pkgtools/pkglint/files/mkshparser.go      Fri Aug 02 18:55:07 2019 +0000
@@ -243,6 +243,21 @@
                p := NewShTokenizer(dummyLine, token, false) // Just for converting the string to a ShToken
                lval.Word = p.ShToken()
                lex.atCommandStart = false
+
+               // Inside of a case statement, ${PATTERNS:@p@ (${p}) action ;; @} expands to
+               // a list of case-items, and after this list a new command starts.
+               // This is necessary to return a following "esac" as tkESAC instead of a
+               // simple word.
+               if lex.sinceCase >= 0 && len(lval.Word.Atoms) == 1 {
+                       if varUse := lval.Word.Atoms[0].VarUse(); varUse != nil {
+                               if len(varUse.modifiers) > 0 {
+                                       lastModifier := varUse.modifiers[len(varUse.modifiers)-1].Text
+                                       if hasPrefix(lastModifier, "@") {
+                                               lex.atCommandStart = true
+                                       }
+                               }
+                       }
+               }
        }
 
        return ttype
diff -r a340c986243e -r 8e61b594e28a pkgtools/pkglint/files/mkshparser_test.go
--- a/pkgtools/pkglint/files/mkshparser_test.go Fri Aug 02 17:17:18 2019 +0000
+++ b/pkgtools/pkglint/files/mkshparser_test.go Fri Aug 02 18:55:07 2019 +0000
@@ -384,6 +384,23 @@
                        b.CaseItem(
                                b.Words("if", "then", "else"),
                                b.List(), sepNone))))
+
+       // This could be regarded an evil preprocessor hack, but it's used
+       // in practice and is somewhat established, even though it is
+       // difficult to parse and understand, even for humans.
+       s.test("case $$expr in ${PATTERNS:@p@ (${p}) action ;; @} (*) ;; esac",
+               b.List().AddCommand(b.Case(
+                       b.Token("$$expr"),
+                       b.CaseItemVar("${PATTERNS:@p@ (${p}) action ;; @}"),
+                       b.CaseItem(
+                               b.Words("*"),
+                               b.List(), sepNone))))
+
+       // The default case may be omitted if PATTERNS can never be empty.
+       s.test("case $$expr in ${PATTERNS:@p@ (${p}) action ;; @} esac",
+               b.List().AddCommand(b.Case(
+                       b.Token("$$expr"),
+                       b.CaseItemVar("${PATTERNS:@p@ (${p}) action ;; @}"))))
 }
 
 func (s *ShSuite) Test_ShellParser__if_clause(c *check.C) {
@@ -555,11 +572,11 @@
                error:          ""}
        parser := shyyParserImpl{}
 
-       succeeded := parser.Parse(&lexer)
+       zeroMeansSuccess := parser.Parse(&lexer)
 
        c := s.c
 
-       if t.CheckEquals(succeeded, 0) && t.CheckEquals(lexer.error, "") {
+       if t.CheckEquals(zeroMeansSuccess, 0) && t.CheckEquals(lexer.error, "") {
                if !t.CheckDeepEquals(lexer.result, expected) {
                        actualJSON, actualErr := json.MarshalIndent(lexer.result, "", "  ")
                        expectedJSON, expectedErr := json.MarshalIndent(expected, "", "  ")
@@ -664,6 +681,35 @@
                "if cond ; then : ; fi")
 }
 
+func (s *Suite) Test_ShellLexer_Lex__case_patterns(c *check.C) {
+       t := s.Init(c)
+
+       test := func(shellProgram string, expectedTokens ...int) {
+               tokens, rest := splitIntoShellTokens(nil, shellProgram)
+               lexer := NewShellLexer(tokens, rest)
+
+               var actualTokens []int
+               for {
+                       var token shyySymType
+                       tokenType := lexer.Lex(&token)
+                       if tokenType <= 0 {
+                               break
+                       }
+                       actualTokens = append(actualTokens, tokenType)
+               }
+               t.CheckDeepEquals(actualTokens, expectedTokens)
+       }
+
+       test(
+               "case $$expr in ${PATTERNS:@p@(${p}) action ;; @} esac",
+
+               tkCASE,
+               tkWORD,
+               tkIN,
+               tkWORD,
+               tkESAC)
+}
+
 type MkShBuilder struct {
 }
 
@@ -728,7 +774,11 @@
 }
 
 func (b *MkShBuilder) CaseItem(patterns []*ShToken, action *MkShList, separator MkShSeparator) *MkShCaseItem {
-       return &MkShCaseItem{patterns, action, separator}
+       return &MkShCaseItem{patterns, action, separator, nil}
+}
+
+func (b *MkShBuilder) CaseItemVar(varUseText string) *MkShCaseItem {
+       return &MkShCaseItem{nil, nil, sepNone, b.Token(varUseText)}
 }
 
 func (b *MkShBuilder) While(cond, action *MkShList, redirects ...*MkShRedirection) *MkShCommand {
diff -r a340c986243e -r 8e61b594e28a pkgtools/pkglint/files/mkshtypes.go
--- a/pkgtools/pkglint/files/mkshtypes.go       Fri Aug 02 17:17:18 2019 +0000
+++ b/pkgtools/pkglint/files/mkshtypes.go       Fri Aug 02 18:55:07 2019 +0000
@@ -127,6 +127,7 @@
        Patterns  []*ShToken
        Action    *MkShList
        Separator MkShSeparator
+       Var       *ShToken // ${PATTERNS:@p@ (${p}) action ;; @}
 }
 
 // MkShIf is a conditional statement, possibly having
diff -r a340c986243e -r 8e61b594e28a pkgtools/pkglint/files/mkshwalker.go
--- a/pkgtools/pkglint/files/mkshwalker.go      Fri Aug 02 17:17:18 2019 +0000
+++ b/pkgtools/pkglint/files/mkshwalker.go      Fri Aug 02 18:55:07 2019 +0000
@@ -215,7 +215,9 @@
                        callback(caseItem)
                }
                w.walkWords(-1, caseItem.Patterns)
-               w.walkList(-1, caseItem.Action)
+               if caseItem.Action != nil {
+                       w.walkList(-1, caseItem.Action)
+               }
                w.pop()
        }
 
diff -r a340c986243e -r 8e61b594e28a pkgtools/pkglint/files/shell.y
--- a/pkgtools/pkglint/files/shell.y    Fri Aug 02 17:17:18 2019 +0000
+++ b/pkgtools/pkglint/files/shell.y    Fri Aug 02 18:55:07 2019 +0000
@@ -208,20 +208,23 @@
 }
 
 case_item_ns : case_selector linebreak {
-       $$ = &MkShCaseItem{$1, &MkShList{}, sepNone}
+       $$ = &MkShCaseItem{$1, &MkShList{}, sepNone, nil}
 }
 case_item_ns : case_selector linebreak term linebreak {
-       $$ = &MkShCaseItem{$1, $3, sepNone}
+       $$ = &MkShCaseItem{$1, $3, sepNone, nil}
 }
 case_item_ns : case_selector linebreak term separator_op linebreak {
-       $$ = &MkShCaseItem{$1, $3, $4}
+       $$ = &MkShCaseItem{$1, $3, $4, nil}
 }
 
 case_item : case_selector linebreak tkSEMISEMI linebreak {
-       $$ = &MkShCaseItem{$1, &MkShList{}, sepNone}
+       $$ = &MkShCaseItem{$1, &MkShList{}, sepNone, nil}
 }
 case_item : case_selector compound_list tkSEMISEMI linebreak {
-       $$ = &MkShCaseItem{$1, $2, sepNone}
+       $$ = &MkShCaseItem{$1, $2, sepNone, nil}
+}
+case_item : tkWORD {
+       $$ = &MkShCaseItem{Var: $1}
 }
 
 pattern : tkWORD {
diff -r a340c986243e -r 8e61b594e28a pkgtools/pkglint/files/shell_test.go
--- a/pkgtools/pkglint/files/shell_test.go      Fri Aug 02 17:17:18 2019 +0000
+++ b/pkgtools/pkglint/files/shell_test.go      Fri Aug 02 18:55:07 2019 +0000
@@ -1099,10 +1099,11 @@
 
        mklines.Check()
 
-       // FIXME: Support the above variable expansion.
-       t.CheckOutputLines(
-               "WARN: Makefile:4: Pkglint ShellLine.CheckShellCommand: " +
-                       "parse error at []string{\"*\", \")\", \"continue\", \";\", \"esac\"}")
+       // TODO: Ensure that the shell word is really only one variable use.
+       // TODO: Ensure that the last modifier is :@@@.
+       // TODO: Ensure that the replacement is a well-formed case-item.
+       // TODO: Ensure that the replacement contains ";;" as the last shell token.
+       t.CheckOutputEmpty()
 }
 
 func (s *Suite) Test_ShellLineChecker_checkHiddenAndSuppress(c *check.C) {



Home | Main Index | Thread Index | Old Index