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:           Sun Jun  6 11:46:44 UTC 2021

Modified Files:
        pkgsrc/pkgtools/pkglint: Makefile
        pkgsrc/pkgtools/pkglint/files: category.go mkcondchecker.go mkline.go
            vardefs.go vartype.go vartypecheck.go vartypecheck_test.go
        pkgsrc/pkgtools/pkglint/files/licenses: licenses.go
        pkgsrc/pkgtools/pkglint/files/textproc: lexer.go lexer_test.go

Log Message:
pkgtools/pkglint: update to 21.1.4

Changes since 21.1.3:

Allow slash in Git tags like 'refs/tags/v1.0.0', as well as in make
targets like 'subdir/build'.


To generate a diff of this commit:
cvs rdiff -u -r1.687 -r1.688 pkgsrc/pkgtools/pkglint/Makefile
cvs rdiff -u -r1.35 -r1.36 pkgsrc/pkgtools/pkglint/files/category.go
cvs rdiff -u -r1.10 -r1.11 pkgsrc/pkgtools/pkglint/files/mkcondchecker.go
cvs rdiff -u -r1.83 -r1.84 pkgsrc/pkgtools/pkglint/files/mkline.go
cvs rdiff -u -r1.101 -r1.102 pkgsrc/pkgtools/pkglint/files/vardefs.go
cvs rdiff -u -r1.51 -r1.52 pkgsrc/pkgtools/pkglint/files/vartype.go
cvs rdiff -u -r1.94 -r1.95 pkgsrc/pkgtools/pkglint/files/vartypecheck.go
cvs rdiff -u -r1.86 -r1.87 pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go
cvs rdiff -u -r1.7 -r1.8 pkgsrc/pkgtools/pkglint/files/licenses/licenses.go
cvs rdiff -u -r1.10 -r1.11 pkgsrc/pkgtools/pkglint/files/textproc/lexer.go \
    pkgsrc/pkgtools/pkglint/files/textproc/lexer_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.687 pkgsrc/pkgtools/pkglint/Makefile:1.688
--- pkgsrc/pkgtools/pkglint/Makefile:1.687      Sun Jun  6 07:41:34 2021
+++ pkgsrc/pkgtools/pkglint/Makefile    Sun Jun  6 11:46:43 2021
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.687 2021/06/06 07:41:34 rillig Exp $
+# $NetBSD: Makefile,v 1.688 2021/06/06 11:46:43 rillig Exp $
 
-PKGNAME=       pkglint-21.1.3
+PKGNAME=       pkglint-21.1.4
 CATEGORIES=    pkgtools
 DISTNAME=      tools
 MASTER_SITES=  ${MASTER_SITE_GITHUB:=golang/}

Index: pkgsrc/pkgtools/pkglint/files/category.go
diff -u pkgsrc/pkgtools/pkglint/files/category.go:1.35 pkgsrc/pkgtools/pkglint/files/category.go:1.36
--- pkgsrc/pkgtools/pkglint/files/category.go:1.35      Mon Mar 22 23:26:30 2021
+++ pkgsrc/pkgtools/pkglint/files/category.go   Sun Jun  6 11:46:43 2021
@@ -25,7 +25,7 @@ func CheckdirCategory(dir CurrPath) {
        if mlex.SkipIf(func(mkline *MkLine) bool { return mkline.IsVarassign() && mkline.Varname() == "COMMENT" }) {
                mkline := mlex.PreviousMkLine()
 
-               valid := textproc.NewByteSet("--- '(),/0-9A-Za-z")
+               valid := textproc.NewByteSet("- '(),/0-9A-Za-z")
                invalid := invalidCharacters(mkline.Value(), valid)
                if invalid != "" {
                        mkline.Warnf("%s contains invalid characters (%s).",

Index: pkgsrc/pkgtools/pkglint/files/mkcondchecker.go
diff -u pkgsrc/pkgtools/pkglint/files/mkcondchecker.go:1.10 pkgsrc/pkgtools/pkglint/files/mkcondchecker.go:1.11
--- pkgsrc/pkgtools/pkglint/files/mkcondchecker.go:1.10 Wed Jul  1 13:17:41 2020
+++ pkgsrc/pkgtools/pkglint/files/mkcondchecker.go      Sun Jun  6 11:46:43 2021
@@ -152,11 +152,13 @@ func (ck *MkCondChecker) checkEmptyType(
 // mkCondStringLiteralUnquoted contains a safe subset of the characters
 // that may be used without surrounding quotes in a comparison such as
 // ${PKGPATH} == category/package.
-var mkCondStringLiteralUnquoted = textproc.NewByteSet("+---./0-9@A-Z_a-z")
+// TODO: Check whether the ',' really needs to be here.
+var mkCondStringLiteralUnquoted = textproc.NewByteSet("-+,./0-9@A-Z_a-z")
 
 // mkCondModifierPatternLiteral contains a safe subset of the characters
 // that are interpreted literally in the :M and :N modifiers.
-var mkCondModifierPatternLiteral = textproc.NewByteSet("+---./0-9<=>@A-Z_a-z")
+// TODO: Check whether the ',' really needs to be here.
+var mkCondModifierPatternLiteral = textproc.NewByteSet("-+,./0-9<=>@A-Z_a-z")
 
 // simplify replaces an unnecessarily complex condition with
 // a simpler condition that's still equivalent.

Index: pkgsrc/pkgtools/pkglint/files/mkline.go
diff -u pkgsrc/pkgtools/pkglint/files/mkline.go:1.83 pkgsrc/pkgtools/pkglint/files/mkline.go:1.84
--- pkgsrc/pkgtools/pkglint/files/mkline.go:1.83        Sat Apr 17 18:10:14 2021
+++ pkgsrc/pkgtools/pkglint/files/mkline.go     Sun Jun  6 11:46:43 2021
@@ -700,7 +700,7 @@ func (mkline *MkLine) RelMkLine(other *M
 }
 
 var (
-       LowerDash                  = textproc.NewByteSet("a-z---")
+       LowerDash                  = textproc.NewByteSet("a-z-")
        AlnumDot                   = textproc.NewByteSet("A-Za-z0-9_.")
        unescapeMkCommentSafeChars = textproc.NewByteSet("\\#[\n").Inverse()
 )
@@ -1327,8 +1327,10 @@ func (ind *Indentation) CheckFinish(file
 // TODO: The allowed characters differ between the basename and the parameter
 //  of the variable. The square bracket is only allowed in the parameter part.
 var (
-       VarbaseBytes  = textproc.NewByteSet("A-Za-z_0-9+---")
-       VarparamBytes = textproc.NewByteSet("A-Za-z_0-9#*+---./[")
+       // TODO: remove the ','
+       VarbaseBytes = textproc.NewByteSet("A-Za-z_0-9-+,")
+       // TODO: Check whether the ',' really needs to be here.
+       VarparamBytes = textproc.NewByteSet("A-Za-z_0-9-#*+,./[")
 )
 
 func MatchMkInclude(text string) (m bool, indentation, directive string, filename RelPath) {

Index: pkgsrc/pkgtools/pkglint/files/vardefs.go
diff -u pkgsrc/pkgtools/pkglint/files/vardefs.go:1.101 pkgsrc/pkgtools/pkglint/files/vardefs.go:1.102
--- pkgsrc/pkgtools/pkglint/files/vardefs.go:1.101      Mon Oct 26 22:13:23 2020
+++ pkgsrc/pkgtools/pkglint/files/vardefs.go    Sun Jun  6 11:46:43 2021
@@ -1032,8 +1032,8 @@ func (reg *VarTypeRegistry) Init(src *Pk
        reg.pkglist("BUILD_ENV", BtShellWord)
        reg.sys("BUILD_MAKE_CMD", BtShellCommand)
        reg.pkglist("BUILD_MAKE_FLAGS", BtShellWord)
-       reg.pkglist("BUILD_TARGET", BtIdentifierIndirect)
-       reg.pkglist("BUILD_TARGET.*", BtIdentifierIndirect)
+       reg.pkglist("BUILD_TARGET", BtMakeTarget)
+       reg.pkglist("BUILD_TARGET.*", BtMakeTarget)
        reg.pkg("BUILD_USES_MSGFMT", BtYes)
        reg.acl("BUILTIN_PKG", BtIdentifierDirect,
                PackageSettable,
@@ -1143,12 +1143,12 @@ func (reg *VarTypeRegistry) Init(src *Pk
        reg.pkg("DISTNAME", BtFilename)
        reg.pkg("DIST_SUBDIR", BtPathname)
        reg.pkglist("DJB_BUILD_ARGS", BtShellWord)
-       reg.pkglist("DJB_BUILD_TARGETS", BtIdentifierIndirect)
+       reg.pkglist("DJB_BUILD_TARGETS", BtMakeTarget)
        reg.pkgappend("DJB_CONFIG_CMDS", BtShellCommands)
        reg.pkglist("DJB_CONFIG_DIRS", BtWrksrcSubdirectory)
        reg.pkg("DJB_CONFIG_HOME", BtFilename)
        reg.pkg("DJB_CONFIG_PREFIX", BtPathname)
-       reg.pkglist("DJB_INSTALL_TARGETS", BtIdentifierIndirect)
+       reg.pkglist("DJB_INSTALL_TARGETS", BtMakeTarget)
        reg.pkg("DJB_MAKE_TARGETS", BtYesNo)
        reg.pkg("DJB_RESTRICTED", BtYesNo)
        reg.pkg("DJB_SLASHPACKAGE", BtYesNo)
@@ -1230,7 +1230,7 @@ func (reg *VarTypeRegistry) Init(src *Pk
        reg.pkglistbl3rat("GCC_REQD", BtGccReqd)
        reg.pkgappend("GENERATE_PLIST", BtShellCommands)
        reg.pkg("GITHUB_PROJECT", BtIdentifierIndirect)
-       reg.pkg("GITHUB_TAG", BtIdentifierIndirect)
+       reg.pkg("GITHUB_TAG", BtGitTag)
        reg.pkg("GITHUB_RELEASE", BtFilename)
        reg.pkg("GITHUB_TYPE", enum("tag release"))
        reg.pkgrat("GMAKE_REQD", BtVersion)
@@ -1282,7 +1282,7 @@ func (reg *VarTypeRegistry) Init(src *Pk
        reg.syslist("INSTALL_SCRIPTS_ENV", BtShellWord)
        reg.sys("INSTALL_SCRIPT_DIR", BtShellCommand)
        reg.pkglist("INSTALL_SRC", BtPathname)
-       reg.pkglist("INSTALL_TARGET", BtIdentifierIndirect)
+       reg.pkglist("INSTALL_TARGET", BtMakeTarget)
        reg.pkglist("INSTALL_TEMPLATES", BtPathname)
        reg.pkgload("INSTALL_UNSTRIPPED", BtYesNo)
        reg.pkglist("INTERACTIVE_STAGE", enum("fetch extract configure build test install"))
@@ -1729,7 +1729,7 @@ func (reg *VarTypeRegistry) Init(src *Pk
        reg.pkglist("TEST_DEPENDS", BtDependencyWithPath)
        reg.pkglist("TEST_DIRS", BtWrksrcSubdirectory)
        reg.pkglist("TEST_ENV", BtShellWord)
-       reg.pkglist("TEST_TARGET", BtIdentifierIndirect)
+       reg.pkglist("TEST_TARGET", BtMakeTarget)
        reg.pkglistrat("TEXINFO_REQD", BtVersion)
        reg.pkglistbl3("TOOL_DEPENDS", BtDependencyWithPath)
        reg.syslist("TOOLS_ALIASES", BtFilename)

Index: pkgsrc/pkgtools/pkglint/files/vartype.go
diff -u pkgsrc/pkgtools/pkglint/files/vartype.go:1.51 pkgsrc/pkgtools/pkglint/files/vartype.go:1.52
--- pkgsrc/pkgtools/pkglint/files/vartype.go:1.51       Sat Jun  6 20:42:56 2020
+++ pkgsrc/pkgtools/pkglint/files/vartype.go    Sun Jun  6 11:46:43 2021
@@ -358,6 +358,7 @@ func (bt *BasicType) NeedsQ() bool {
                BtEmulPlatform,
                BtFileMode,
                BtFilename,
+               BtGitTag,
                BtIdentifierDirect,
                BtIdentifierIndirect,
                BtInteger,
@@ -428,6 +429,7 @@ var (
        BtFilePattern            = &BasicType{"FilePattern", (*VartypeCheck).FilePattern}
        BtFileMode               = &BasicType{"FileMode", (*VartypeCheck).FileMode}
        BtGccReqd                = &BasicType{"GccReqd", (*VartypeCheck).GccReqd}
+       BtGitTag                 = &BasicType{"GitTag", (*VartypeCheck).GitTag}
        BtHomepage               = &BasicType{"Homepage", (*VartypeCheck).Homepage}
        BtIdentifierDirect       = &BasicType{"Identifier", (*VartypeCheck).IdentifierDirect}
        BtIdentifierIndirect     = &BasicType{"Identifier", (*VartypeCheck).IdentifierIndirect}
@@ -438,6 +440,7 @@ var (
        BtMachinePlatform        = &BasicType{"MachinePlatform", (*VartypeCheck).MachinePlatform}
        BtMachinePlatformPattern = &BasicType{"MachinePlatformPattern", (*VartypeCheck).MachinePlatformPattern}
        BtMailAddress            = &BasicType{"MailAddress", (*VartypeCheck).MailAddress}
+       BtMakeTarget             = &BasicType{"MakeTarget", (*VartypeCheck).MakeTarget}
        BtMessage                = &BasicType{"Message", (*VartypeCheck).Message}
        BtOption                 = &BasicType{"Option", (*VartypeCheck).Option}
        BtPathlist               = &BasicType{"Pathlist", (*VartypeCheck).Pathlist}

Index: pkgsrc/pkgtools/pkglint/files/vartypecheck.go
diff -u pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.94 pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.95
--- pkgsrc/pkgtools/pkglint/files/vartypecheck.go:1.94  Fri Jul 31 22:39:36 2020
+++ pkgsrc/pkgtools/pkglint/files/vartypecheck.go       Sun Jun  6 11:46:43 2021
@@ -21,7 +21,7 @@ type VartypeCheck struct {
        Varname    string
        Op         MkOperator
        Value      string
-       ValueNoVar string
+       ValueNoVar string // The Value with all expressions removed.
        MkComment  string // The comment including the "#".
        Guessed    bool   // Whether the type definition is guessed (based on the variable name) or explicitly defined (see vardefs.go).
 }
@@ -676,6 +676,29 @@ func (cv *VartypeCheck) GccReqd() {
        }
 }
 
+// GitTag checks for a fixed reference to a Git commit.
+//
+// https://git-scm.com/docs/gitrevisions
+func (cv *VartypeCheck) GitTag() {
+       tag := cv.ValueNoVar
+
+       valid := textproc.NewByteSet("0-9A-Za-z-+._/")
+       invalid := invalidCharacters(tag, valid)
+       if invalid != "" {
+               cv.Warnf("Invalid characters %q in Git tag.", invalid)
+               return
+       }
+
+       if tag == "master" || hasPrefix(tag, "refs/heads/") {
+               cv.Warnf("The Git tag %q refers to a moving target.", tag)
+               return
+       }
+
+       if len(tag) < 7 && matches(tag, `^[A-Fa-f0-9]+$`) {
+               cv.Warnf("The git commit name %q is too short to be reliable.", tag)
+       }
+}
+
 func (cv *VartypeCheck) Homepage() {
        cv.URL()
 
@@ -683,8 +706,8 @@ func (cv *VartypeCheck) Homepage() {
        ck.Check()
 }
 
-// Identifier checks for valid identifiers in various contexts, limiting the
-// valid characters to A-Za-z0-9_.
+// IdentifierDirect checks for valid identifiers in various contexts,
+// limiting the valid characters to A-Za-z0-9_.
 func (cv *VartypeCheck) IdentifierDirect() {
        if cv.Op == opUseMatch {
                if cv.Value == cv.ValueNoVar && !matches(cv.Value, `^[\w*\-?\[\]]+$`) {
@@ -703,8 +726,8 @@ func (cv *VartypeCheck) IdentifierDirect
        }
 }
 
-// Identifier checks for valid identifiers in various contexts, limiting the
-// valid characters to A-Za-z0-9_.
+// IdentifierIndirect checks for valid identifiers in various contexts,
+// limiting the valid characters to A-Za-z0-9_.
 func (cv *VartypeCheck) IdentifierIndirect() {
        if cv.Value == cv.ValueNoVar {
                cv.IdentifierDirect()
@@ -847,6 +870,16 @@ func (cv *VartypeCheck) MailAddress() {
        }
 }
 
+func (cv *VartypeCheck) MakeTarget() {
+       if cv.Op == opUseMatch || cv.ValueNoVar != cv.Value {
+               return
+       }
+
+       if !matches(cv.ValueNoVar, `^[+\-.\w/]+$`) {
+               cv.Warnf("Invalid make target %q.", cv.Value)
+       }
+}
+
 // Message is a plain string. When defining a message variable, it should
 // not be enclosed in quotes since that is the job of the code that uses
 // the message.
@@ -980,8 +1013,9 @@ func (cv *VartypeCheck) Pathname() {
                invalid)
 }
 
-// Like Pathname, but may contain spaces as well.
-// Because the spaces must be quoted, backslashes and quotes are allowed as well.
+// PathnameSpace is like Pathname, but may contain spaces as well.
+// Because the spaces must be quoted, backslashes and quotes are allowed as
+// well.
 func (cv *VartypeCheck) PathnameSpace() {
        valid := regex.Pattern(condStr(
                cv.Op == opUseMatch,
@@ -1108,7 +1142,7 @@ func (cv *VartypeCheck) PlistIdentifier(
        }
 
        if cv.Op == opUseMatch {
-               invalidPatternChars := textproc.NewByteSet("A-Za-z0-9---_*?[]")
+               invalidPatternChars := textproc.NewByteSet("A-Za-z0-9-_*?[]")
                invalid := invalidCharacters(cond, invalidPatternChars)
                if invalid != "" {
                        cv.Warnf("PLIST identifier pattern %q contains invalid characters (%s).",
@@ -1120,7 +1154,7 @@ func (cv *VartypeCheck) PlistIdentifier(
                return
        }
 
-       invalidChars := textproc.NewByteSet("A-Za-z0-9---_")
+       invalidChars := textproc.NewByteSet("A-Za-z0-9-_")
        invalid := invalidCharacters(cond, invalidChars)
        if invalid != "" {
                cv.Errorf("PLIST identifier %q contains invalid characters (%s).",
@@ -1448,7 +1482,7 @@ func (cv *VartypeCheck) UserGroupName() 
        if value != cv.ValueNoVar {
                return
        }
-       invalid := invalidCharacters(value, textproc.NewByteSet("---0-9_a-z"))
+       invalid := invalidCharacters(value, textproc.NewByteSet("-0-9_a-z"))
        if invalid != "" {
                cv.Warnf("User or group name %q contains invalid characters: %s",
                        value, invalid)

Index: pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go
diff -u pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.86 pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.87
--- pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go:1.86     Fri Jul 31 22:39:36 2020
+++ pkgsrc/pkgtools/pkglint/files/vartypecheck_test.go  Sun Jun  6 11:46:43 2021
@@ -1126,6 +1126,32 @@ func (s *Suite) Test_VartypeCheck_GccReq
                "WARN: filename.mk:7: GCC version numbers should only contain the major version (7).")
 }
 
+func (s *Suite) Test_VartypeCheck_GitTag(c *check.C) {
+       vt := NewVartypeCheckTester(s.Init(c), BtGitTag)
+
+       vt.Varname("GITHUB_TAG")
+       vt.Values(
+               "master", // Bad since it is a moving target.
+               "v1.2.3",
+               "refs/heads/devel", // Bad since it is a moving target.
+               "refs/tags/v1.2.3",
+               "v${PKGVERSION_NOREV}",
+               "1234567812345678123456781234567812345678",
+               "1234567",
+               "123456", // Too short in practice.
+               "${DISTNAME}",
+               "invalid:char",  // Bad since ':' is not supported.
+               "invalid:;char", // Bad since neither ':' nor ';' is supported.
+               "jdk-11.0.10+9-1",
+       )
+       vt.Output(
+               "WARN: filename.mk:1: The Git tag \"master\" refers to a moving target.",
+               "WARN: filename.mk:3: The Git tag \"refs/heads/devel\" refers to a moving target.",
+               "WARN: filename.mk:8: The git commit name \"123456\" is too short to be reliable.",
+               "WARN: filename.mk:10: Invalid characters \":\" in Git tag.",
+               "WARN: filename.mk:11: Invalid characters \": ;\" in Git tag.")
+}
+
 func (s *Suite) Test_VartypeCheck_Homepage(c *check.C) {
        t := s.Init(c)
        vt := NewVartypeCheckTester(t, BtHomepage)
@@ -1448,6 +1474,33 @@ func (s *Suite) Test_VartypeCheck_MailAd
                "WARN: filename.mk:4: \"user1%example.org@localhost,user2%example.org@localhost\" is not a valid mail address.")
 }
 
+func (s *Suite) Test_VartypeCheck_MakeTarget(c *check.C) {
+       t := s.Init(c)
+       vt := NewVartypeCheckTester(t, BtMakeTarget)
+
+       vt.Varname("BUILD_TARGET")
+       vt.Values(
+               "${OTHER_VAR}",
+               "spaces in target lists are ok",
+               "target/may/contain/slashes",
+               "target:must:not:contain:colons",
+               "id-${OTHER_VAR}",
+               "")
+
+       vt.Output(
+               "WARN: filename.mk:4: Invalid make target " +
+                       "\"target:must:not:contain:colons\".")
+
+       vt.Op(opUseMatch)
+       vt.Values(
+               "[A-Z]",
+               "[A-Z.]",
+               "${PKG_OPTIONS:Moption}",
+               "A*B")
+
+       vt.OutputEmpty()
+}
+
 func (s *Suite) Test_VartypeCheck_Message(c *check.C) {
        vt := NewVartypeCheckTester(s.Init(c), BtMessage)
 

Index: pkgsrc/pkgtools/pkglint/files/licenses/licenses.go
diff -u pkgsrc/pkgtools/pkglint/files/licenses/licenses.go:1.7 pkgsrc/pkgtools/pkglint/files/licenses/licenses.go:1.8
--- pkgsrc/pkgtools/pkglint/files/licenses/licenses.go:1.7      Sat Nov 30 20:35:11 2019
+++ pkgsrc/pkgtools/pkglint/files/licenses/licenses.go  Sun Jun  6 11:46:44 2021
@@ -67,7 +67,7 @@ type licenseLexer struct {
        error  string
 }
 
-var licenseNameChars = textproc.NewByteSet("A-Za-z0-9---._")
+var licenseNameChars = textproc.NewByteSet("A-Za-z0-9-._")
 
 func (lexer *licenseLexer) Lex(llval *liyySymType) int {
        lex := lexer.lexer

Index: pkgsrc/pkgtools/pkglint/files/textproc/lexer.go
diff -u pkgsrc/pkgtools/pkglint/files/textproc/lexer.go:1.10 pkgsrc/pkgtools/pkglint/files/textproc/lexer.go:1.11
--- pkgsrc/pkgtools/pkglint/files/textproc/lexer.go:1.10        Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/textproc/lexer.go     Sun Jun  6 11:46:44 2021
@@ -240,8 +240,8 @@ func (l *Lexer) Copy() *Lexer { return &
 func (l *Lexer) Commit(other *Lexer) bool { l.rest = other.rest; return true }
 
 // NewByteSet creates a bit mask out of a string like "0-9A-Za-z_".
-// To add an actual hyphen to the bit mask, write it as "---"
-// (a range from hyphen to hyphen).
+// To add an actual hyphen to the bit mask, write it either at the beginning
+// or at the end of the string, or directly after a range like "a-z".
 //
 // The bit mask can be used with Lexer.NextBytesSet.
 func NewByteSet(chars string) *ByteSet {
Index: pkgsrc/pkgtools/pkglint/files/textproc/lexer_test.go
diff -u pkgsrc/pkgtools/pkglint/files/textproc/lexer_test.go:1.10 pkgsrc/pkgtools/pkglint/files/textproc/lexer_test.go:1.11
--- pkgsrc/pkgtools/pkglint/files/textproc/lexer_test.go:1.10   Sat Jan  4 19:53:14 2020
+++ pkgsrc/pkgtools/pkglint/files/textproc/lexer_test.go        Sun Jun  6 11:46:44 2021
@@ -359,18 +359,81 @@ func (s *Suite) Test_NewByteSet(c *check
 }
 
 // Demonstrates how to specify a byte set that includes a hyphen,
-// since that is also used for byte ranges.
-// The hyphen must be written as ---, which is a range from hyphen to hyphen.
-func (s *Suite) Test_NewByteSet__range_hyphen(c *check.C) {
+// since that character is also used for byte ranges.
+// The hyphen is written as ---, which is a range from hyphen to hyphen.
+func (s *Suite) Test_NewByteSet__range_hyphen_beginning(c *check.C) {
        set := NewByteSet("---a-z")
 
-       expected := "abcdefghijklmnopqrstuvwxyz-"
+       var actual strings.Builder
        for i := 0; i < 256; i++ {
-               c.Check(
-                       set.Contains(byte(i)),
-                       equals,
-                       strings.IndexByte(expected, byte(i)) != -1)
+               if set.Contains(byte(i)) {
+                       actual.WriteByte(byte(i))
+               }
+       }
+
+       c.Check(actual.String(), equals, "-abcdefghijklmnopqrstuvwxyz")
+}
+
+// The byte set "x---a" is interpreted as 3 parts: "x--", "-", "a".
+//
+// The range "x--" is empty since U+0078 'x' comes later in Unicode than
+// U+002D '-'.
+func (s *Suite) Test_NewByteSet__range_hyphen_middle(c *check.C) {
+       set := NewByteSet("x---a")
+
+       var actual strings.Builder
+       for i := 0; i < 256; i++ {
+               if set.Contains(byte(i)) {
+                       actual.WriteByte(byte(i))
+               }
+       }
+
+       c.Check(actual.String(), equals, "-a")
+}
+
+// When a hyphen is listed at the very beginning, it is not considered part
+// of a byte range but interpreted literally.
+func (s *Suite) Test_NewByteSet__hyphen_beginning(c *check.C) {
+       set := NewByteSet("-ax")
+
+       var actual strings.Builder
+       for i := 0; i < 256; i++ {
+               if set.Contains(byte(i)) {
+                       actual.WriteByte(byte(i))
+               }
        }
+
+       c.Check(actual.String(), equals, "-ax")
+}
+
+// When a hyphen is listed directly after a range ('+-+' in this case),
+// it is interpreted literally.
+func (s *Suite) Test_NewByteSet__hyphen_after_range(c *check.C) {
+       set := NewByteSet("+-+-")
+
+       var actual strings.Builder
+       for i := 0; i < 256; i++ {
+               if set.Contains(byte(i)) {
+                       actual.WriteByte(byte(i))
+               }
+       }
+
+       c.Check(actual.String(), equals, "+-")
+}
+
+// When a hyphen is listed at the very end, it is not considered part
+// of a byte range but interpreted literally.
+func (s *Suite) Test_NewByteSet__hyphen_end(c *check.C) {
+       set := NewByteSet("ax-")
+
+       var actual strings.Builder
+       for i := 0; i < 256; i++ {
+               if set.Contains(byte(i)) {
+                       actual.WriteByte(byte(i))
+               }
+       }
+
+       c.Check(actual.String(), equals, "-ax")
 }
 
 func (s *Suite) Test_ByteSet_Inverse(c *check.C) {



Home | Main Index | Thread Index | Old Index