pkgsrc-Changes archive

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

CVS commit: pkgsrc/pkgtools/pkglint



Module Name:    pkgsrc
Committed By:   rillig
Date:           Fri Aug  2 18:55:07 UTC 2019

Modified Files:
        pkgsrc/pkgtools/pkglint: Makefile
        pkgsrc/pkgtools/pkglint/files: mkshparser.go mkshparser_test.go
            mkshtypes.go mkshwalker.go shell.y shell_test.go

Log Message:
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


To generate a diff of this commit:
cvs rdiff -u -r1.590 -r1.591 pkgsrc/pkgtools/pkglint/Makefile
cvs rdiff -u -r1.13 -r1.14 pkgsrc/pkgtools/pkglint/files/mkshparser.go
cvs rdiff -u -r1.16 -r1.17 pkgsrc/pkgtools/pkglint/files/mkshparser_test.go
cvs rdiff -u -r1.12 -r1.13 pkgsrc/pkgtools/pkglint/files/mkshtypes.go
cvs rdiff -u -r1.10 -r1.11 pkgsrc/pkgtools/pkglint/files/mkshwalker.go
cvs rdiff -u -r1.4 -r1.5 pkgsrc/pkgtools/pkglint/files/shell.y
cvs rdiff -u -r1.50 -r1.51 pkgsrc/pkgtools/pkglint/files/shell_test.go

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: pkgsrc/pkgtools/pkglint/Makefile
diff -u pkgsrc/pkgtools/pkglint/Makefile:1.590 pkgsrc/pkgtools/pkglint/Makefile:1.591
--- pkgsrc/pkgtools/pkglint/Makefile:1.590      Thu Aug  1 22:38:49 2019
+++ pkgsrc/pkgtools/pkglint/Makefile    Fri Aug  2 18:55:07 2019
@@ -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/}

Index: pkgsrc/pkgtools/pkglint/files/mkshparser.go
diff -u pkgsrc/pkgtools/pkglint/files/mkshparser.go:1.13 pkgsrc/pkgtools/pkglint/files/mkshparser.go:1.14
--- pkgsrc/pkgtools/pkglint/files/mkshparser.go:1.13    Sun Jun 30 20:56:19 2019
+++ pkgsrc/pkgtools/pkglint/files/mkshparser.go Fri Aug  2 18:55:07 2019
@@ -243,6 +243,21 @@ func (lex *ShellLexer) Lex(lval *shyySym
                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

Index: pkgsrc/pkgtools/pkglint/files/mkshparser_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mkshparser_test.go:1.16 pkgsrc/pkgtools/pkglint/files/mkshparser_test.go:1.17
--- pkgsrc/pkgtools/pkglint/files/mkshparser_test.go:1.16       Sun Jul 14 21:25:47 2019
+++ pkgsrc/pkgtools/pkglint/files/mkshparser_test.go    Fri Aug  2 18:55:07 2019
@@ -384,6 +384,23 @@ func (s *ShSuite) Test_ShellParser__case
                        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 @@ func (s *ShSuite) test(program string, e
                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 @@ func (s *ShSuite) Test_ShellLexer_Lex__k
                "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) Case(selector *ShT
 }
 
 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 {

Index: pkgsrc/pkgtools/pkglint/files/mkshtypes.go
diff -u pkgsrc/pkgtools/pkglint/files/mkshtypes.go:1.12 pkgsrc/pkgtools/pkglint/files/mkshtypes.go:1.13
--- pkgsrc/pkgtools/pkglint/files/mkshtypes.go:1.12     Sun Jun 30 20:56:19 2019
+++ pkgsrc/pkgtools/pkglint/files/mkshtypes.go  Fri Aug  2 18:55:07 2019
@@ -127,6 +127,7 @@ type MkShCaseItem struct {
        Patterns  []*ShToken
        Action    *MkShList
        Separator MkShSeparator
+       Var       *ShToken // ${PATTERNS:@p@ (${p}) action ;; @}
 }
 
 // MkShIf is a conditional statement, possibly having

Index: pkgsrc/pkgtools/pkglint/files/mkshwalker.go
diff -u pkgsrc/pkgtools/pkglint/files/mkshwalker.go:1.10 pkgsrc/pkgtools/pkglint/files/mkshwalker.go:1.11
--- pkgsrc/pkgtools/pkglint/files/mkshwalker.go:1.10    Sun Jun 30 20:56:19 2019
+++ pkgsrc/pkgtools/pkglint/files/mkshwalker.go Fri Aug  2 18:55:07 2019
@@ -215,7 +215,9 @@ func (w *MkShWalker) walkCase(caseClause
                        callback(caseItem)
                }
                w.walkWords(-1, caseItem.Patterns)
-               w.walkList(-1, caseItem.Action)
+               if caseItem.Action != nil {
+                       w.walkList(-1, caseItem.Action)
+               }
                w.pop()
        }
 

Index: pkgsrc/pkgtools/pkglint/files/shell.y
diff -u pkgsrc/pkgtools/pkglint/files/shell.y:1.4 pkgsrc/pkgtools/pkglint/files/shell.y:1.5
--- pkgsrc/pkgtools/pkglint/files/shell.y:1.4   Mon Dec 17 00:15:39 2018
+++ pkgsrc/pkgtools/pkglint/files/shell.y       Fri Aug  2 18:55:07 2019
@@ -208,20 +208,23 @@ case_selector : pattern tkRPAREN {
 }
 
 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 {

Index: pkgsrc/pkgtools/pkglint/files/shell_test.go
diff -u pkgsrc/pkgtools/pkglint/files/shell_test.go:1.50 pkgsrc/pkgtools/pkglint/files/shell_test.go:1.51
--- pkgsrc/pkgtools/pkglint/files/shell_test.go:1.50    Sun Jul 14 21:25:47 2019
+++ pkgsrc/pkgtools/pkglint/files/shell_test.go Fri Aug  2 18:55:07 2019
@@ -1099,10 +1099,11 @@ func (s *Suite) Test_ShellLineChecker_Ch
 
        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