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 Aug 8 22:04:15 UTC 2021
Modified Files:
pkgsrc/pkgtools/pkglint: Makefile
pkgsrc/pkgtools/pkglint/files: mkassignchecker.go
mkassignchecker_test.go pkgsrc.go vartype.go
pkgsrc/pkgtools/pkglint/files/makepat: pat.go pat_test.go
pkgsrc/pkgtools/pkglint/files/textproc: lexer.go
Log Message:
pkgtools/pkglint: update to 21.2.2
Changes since 21.2.1:
Check the variable names of OPSYS-specific variables for typos, such as
'Dragonfly' with a lowercase 'f'. Suggested by David A. Holland in
PR pkg/56352.
Warn if variables like CFLAGS are assigned using the operator '='.
Suggested by David A. Holland in PR pkg/56352.
To generate a diff of this commit:
cvs rdiff -u -r1.691 -r1.692 pkgsrc/pkgtools/pkglint/Makefile
cvs rdiff -u -r1.9 -r1.10 pkgsrc/pkgtools/pkglint/files/mkassignchecker.go
cvs rdiff -u -r1.7 -r1.8 \
pkgsrc/pkgtools/pkglint/files/mkassignchecker_test.go
cvs rdiff -u -r1.61 -r1.62 pkgsrc/pkgtools/pkglint/files/pkgsrc.go
cvs rdiff -u -r1.52 -r1.53 pkgsrc/pkgtools/pkglint/files/vartype.go
cvs rdiff -u -r1.2 -r1.3 pkgsrc/pkgtools/pkglint/files/makepat/pat.go
cvs rdiff -u -r1.3 -r1.4 pkgsrc/pkgtools/pkglint/files/makepat/pat_test.go
cvs rdiff -u -r1.11 -r1.12 pkgsrc/pkgtools/pkglint/files/textproc/lexer.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.691 pkgsrc/pkgtools/pkglint/Makefile:1.692
--- pkgsrc/pkgtools/pkglint/Makefile:1.691 Tue Jul 13 11:36:37 2021
+++ pkgsrc/pkgtools/pkglint/Makefile Sun Aug 8 22:04:15 2021
@@ -1,7 +1,6 @@
-# $NetBSD: Makefile,v 1.691 2021/07/13 11:36:37 bsiegert Exp $
+# $NetBSD: Makefile,v 1.692 2021/08/08 22:04:15 rillig Exp $
-PKGNAME= pkglint-21.2.1
-PKGREVISION= 1
+PKGNAME= pkglint-21.2.2
CATEGORIES= pkgtools
DISTNAME= tools
MASTER_SITES= ${MASTER_SITE_GITHUB:=golang/}
Index: pkgsrc/pkgtools/pkglint/files/mkassignchecker.go
diff -u pkgsrc/pkgtools/pkglint/files/mkassignchecker.go:1.9 pkgsrc/pkgtools/pkglint/files/mkassignchecker.go:1.10
--- pkgsrc/pkgtools/pkglint/files/mkassignchecker.go:1.9 Fri Jun 12 19:14:45 2020
+++ pkgsrc/pkgtools/pkglint/files/mkassignchecker.go Sun Aug 8 22:04:15 2021
@@ -1,6 +1,7 @@
package pkglint
import (
+ "netbsd.org/pkglint/textproc"
"strconv"
"strings"
)
@@ -29,6 +30,7 @@ func (ck *MkAssignChecker) checkLeft() {
}
ck.checkLeftNotUsed()
+ ck.checkLeftOpsys()
ck.checkLeftDeprecated()
ck.checkLeftBsdPrefs()
if !ck.checkLeftUserSettable() {
@@ -38,7 +40,7 @@ func (ck *MkAssignChecker) checkLeft() {
ck.checkLeftRationale()
NewMkLineChecker(ck.MkLines, ck.MkLine).checkTextVarUse(
- ck.MkLine.Varname(),
+ varname,
NewVartype(BtVariableName, NoVartypeOptions, NewACLEntry("*", aclpAll)),
VucLoadTime)
}
@@ -91,6 +93,33 @@ func (ck *MkAssignChecker) checkLeftNotU
"see mk/subst.mk for an example of such a documentation comment.")
}
+// checkLeftOpsys checks whether the variable name is one of the OPSYS
+// variables, which get merged with their corresponding VAR.${OPSYS} in
+// bsd.pkg.mk.
+func (ck *MkAssignChecker) checkLeftOpsys() {
+ varname := ck.MkLine.Varname()
+ varbase := varnameBase(varname)
+ if !G.Pkgsrc.IsOpsysVar(varbase) {
+ return
+ }
+
+ varparam := varnameParam(varname)
+ if varparam == "" || varparam == "*" ||
+ textproc.Lower.Contains(varparam[0]) {
+ return
+ }
+
+ platforms := G.Pkgsrc.VariableType(ck.MkLines, "OPSYS").basicType
+ if platforms.HasEnum(varparam) {
+ return
+ }
+
+ ck.MkLine.Warnf(
+ "Since %s is an OPSYS variable, "+
+ "its parameter %q should be one of %s.",
+ varbase, varparam, platforms.AllowedEnums())
+}
+
func (ck *MkAssignChecker) checkLeftDeprecated() {
varname := ck.MkLine.Varname()
if fix := G.Pkgsrc.Deprecated[varname]; fix != "" {
@@ -344,6 +373,7 @@ func (ck *MkAssignChecker) checkLeftRati
func (ck *MkAssignChecker) checkOp() {
ck.checkOpShell()
+ ck.checkOpAppendOnly()
}
func (ck *MkAssignChecker) checkOpShell() {
@@ -393,6 +423,51 @@ func (ck *MkAssignChecker) checkOpShell(
"or .for directive.")
}
+// https://gnats.netbsd.org/56352
+func (ck *MkAssignChecker) checkOpAppendOnly() {
+
+ if ck.MkLine.Op() != opAssign {
+ return
+ }
+
+ varname := ck.MkLine.Varname()
+ varbase := varnameBase(varname)
+
+ // See pkgtools/bootstrap-mk-files/files/sys.mk
+ switch varbase {
+ case
+ "CFLAGS", // C
+ "OBJCFLAGS", // Objective C
+ "FFLAGS", // Fortran
+ "RFLAGS", // Ratfor
+ "LFLAGS", // Lex
+ "LDFLAGS", // Linker
+ "LINTFLAGS", // Lint
+ "PFLAGS", // Pascal
+ "YFLAGS", // Yacc
+ "LDADD": // Just for symmetry
+ break
+ default:
+ return
+ }
+
+ // At this point, it does not matter whether bsd.prefs.mk has been
+ // included or not since the above variables get their default values
+ // in sys.mk already, which is loaded even before the very first line
+ // of the package Makefile.
+
+ // The parameterized OPSYS variants do not get any default values before
+ // the package Makefile is included. Therefore, as long as bsd.prefs.mk
+ // has not been included, the operator '=' can still be used. Testing for
+ // bsd.prefs.mk is only half the story, any other accidental overwrites
+ // are caught by RedundantScope.
+ if varbase != varname && !ck.MkLines.Tools.SeenPrefs {
+ return
+ }
+
+ ck.MkLine.Warnf("Assignments to %q should use \"+=\", not \"=\".", varname)
+}
+
// checkLeft checks everything to the right of the assignment operator.
func (ck *MkAssignChecker) checkRight() {
mkline := ck.MkLine
Index: pkgsrc/pkgtools/pkglint/files/mkassignchecker_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mkassignchecker_test.go:1.7 pkgsrc/pkgtools/pkglint/files/mkassignchecker_test.go:1.8
--- pkgsrc/pkgtools/pkglint/files/mkassignchecker_test.go:1.7 Fri Jun 12 19:14:45 2020
+++ pkgsrc/pkgtools/pkglint/files/mkassignchecker_test.go Sun Aug 8 22:04:15 2021
@@ -200,6 +200,36 @@ func (s *Suite) Test_MkAssignChecker_che
"WARN: ~/category/package/Makefile:22: UNDOCUMENTED is used but not defined.")
}
+// https://gnats.netbsd.org/56352
+func (s *Suite) Test_MkAssignChecker_checkLeftOpsys(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpVartypes()
+
+ mklines := t.NewMkLines("filename.mk",
+ MkCvsID,
+ "",
+ "CPPFLAGS.mumble+=\t-DMACRO",
+ "CPPFLAGS.Linux+=\t-DMACRO",
+ "CFLAGS.NebTSD+=\t\t-Wall",
+ "CFLAGS.NetBSD+=\t\t-Wall",
+ "CXXFLAGS.DragonFly=\t-Wall",
+ "CXXFLAGS.DragonFlyBSD=\t-Wall",
+ "LDFLAGS.SunOS+=\t\t-lX11 -lm",
+ "LDFLAGS.SunOS+=\t\t-lX11 -lm",
+ "LDFLAGS.*+=\t\t-lfallback")
+
+ mklines.Check()
+
+ t.CheckOutputLines(
+ "WARN: filename.mk:5: Since CFLAGS is an OPSYS variable, "+
+ "its parameter \"NebTSD\" should be one of "+
+ "Cygwin DragonFly FreeBSD Linux NetBSD SunOS.",
+ "WARN: filename.mk:8: Since CXXFLAGS is an OPSYS variable, "+
+ "its parameter \"DragonFlyBSD\" should be one of "+
+ "Cygwin DragonFly FreeBSD Linux NetBSD SunOS.")
+}
+
func (s *Suite) Test_MkAssignChecker_checkLeftDeprecated(c *check.C) {
t := s.Init(c)
@@ -725,6 +755,23 @@ func (s *Suite) Test_MkAssignChecker_che
"WARN: ~/category/package/standalone.mk:15: Please use \"${ECHO}\" instead of \"echo\".")
}
+func (s *Suite) Test_MkAssignChecker_checkOpAppendOnly(c *check.C) {
+ t := s.Init(c)
+
+ t.SetUpVartypes()
+ mklines := t.NewMkLines("filename.mk",
+ MkCvsID,
+ "",
+ "CFLAGS=\t\t-O2",
+ "CFLAGS.SunOS=\t-O0")
+
+ mklines.Check()
+
+ t.CheckOutputLines(
+ "WARN: filename.mk:3: " +
+ "Assignments to \"CFLAGS\" should use \"+=\", not \"=\".")
+}
+
func (s *Suite) Test_MkAssignChecker_checkRight(c *check.C) {
t := s.Init(c)
Index: pkgsrc/pkgtools/pkglint/files/pkgsrc.go
diff -u pkgsrc/pkgtools/pkglint/files/pkgsrc.go:1.61 pkgsrc/pkgtools/pkglint/files/pkgsrc.go:1.62
--- pkgsrc/pkgtools/pkglint/files/pkgsrc.go:1.61 Fri Jun 25 14:15:01 2021
+++ pkgsrc/pkgtools/pkglint/files/pkgsrc.go Sun Aug 8 22:04:15 2021
@@ -1169,6 +1169,19 @@ func (src *Pkgsrc) IsBuildDef(varname st
return src.buildDefs[varname]
}
+func (src *Pkgsrc) IsOpsysVar(varbase string) bool {
+ // See mk/bsd.pkg.mk, "OPSYSVARS".
+ switch varbase {
+ case "CFLAGS", "CXXFLAGS", "CPPFLAGS", "LDFLAGS", "LIBS",
+ "CMAKE_ARGS", "CONFIGURE_ARGS", "CONFIGURE_ENV",
+ "BUILDLINK_TRANSFORM", "SUBST_CLASSES",
+ "BUILD_TARGET", "MAKE_ENV", "MAKE_FLAGS", "USE_TOOLS":
+ return true
+ }
+ // TODO: Packages can add their own variables to OPSYSVARS as well.
+ return false
+}
+
// ReadDir lists the files and subdirectories from the given directory
// (relative to the pkgsrc root).
//
Index: pkgsrc/pkgtools/pkglint/files/vartype.go
diff -u pkgsrc/pkgtools/pkglint/files/vartype.go:1.52 pkgsrc/pkgtools/pkglint/files/vartype.go:1.53
--- pkgsrc/pkgtools/pkglint/files/vartype.go:1.52 Sun Jun 6 11:46:43 2021
+++ pkgsrc/pkgtools/pkglint/files/vartype.go Sun Aug 8 22:04:15 2021
@@ -29,22 +29,26 @@ const (
// and as lists of arbitrary things.
List vartypeOptions = 1 << iota
- // The variable is not defined by the pkgsrc infrastructure.
+ // Guessed means that the variable is not defined by the pkgsrc
+ // infrastructure.
// It follows the common naming convention, therefore its type can be guessed.
// Sometimes, with files and paths, this leads to wrong decisions.
Guessed
- // The variable can, or in some cases must, be defined by the package.
+ // PackageSettable means that the variable can, or in some cases must,
+ // be defined by the package.
// For several of these variables, the pkgsrc infrastructure provides
// a reasonable default value, either in bsd.prefs.mk or in bsd.pkg.mk.
PackageSettable
- // The variable can be defined by the pkgsrc user in mk.conf.
+ // UserSettable means that the variable can be defined by the pkgsrc
+ // user in mk.conf.
// Its value is available at load time after bsd.prefs.mk has been included.
UserSettable
- // This variable is provided by either the pkgsrc infrastructure in
- // mk/*, or by <sys.mk>, which is included at the very beginning.
+ // SystemProvided means that this variable is provided by either the
+ // pkgsrc infrastructure in mk/*, or by <sys.mk>, which is included
+ // at the very beginning.
//
// TODO: Clearly distinguish between:
// * sys.mk
@@ -56,14 +60,14 @@ const (
// expressive enough. This is related to the scope and lifetime of
// variables and should be modelled separately.
//
- // See DefinedInSysMk.
+ // See DefinedIfInScope.
SystemProvided
- // This variable may be provided in the command line by the pkgsrc
- // user when building a package.
+ // CommandLineProvided means that this variable may be provided in the
+ // command line by the pkgsrc user when building a package.
//
- // Since the values of these variables are not written down in any
- // file, they must not influence the generated binary packages.
+ // Since the values of these variables are not recorded in any file,
+ // they must not influence the generated binary packages.
//
// See UserSettable.
CommandLineProvided
@@ -72,8 +76,8 @@ const (
// describing why they are set. Typical examples are NOT_FOR_* variables.
NeedsRationale
- // When something is appended to this variable, each additional
- // value should be on a line of its own.
+ // OnePerLine means that when something is appended to this variable,
+ // each additional value should be on a line of its own.
OnePerLine
// AlwaysInScope is true when the variable is always available.
@@ -134,8 +138,8 @@ const (
// X11_TYPE (user-settable)
NonemptyIfDefined
- // Unique is true if it doesn't make sense to append the same
- // value more than once to the variable.
+ // Unique marks variables where it doesn't make sense to append the same
+ // value more than once.
//
// A typical example is CATEGORIES.
Unique
Index: pkgsrc/pkgtools/pkglint/files/makepat/pat.go
diff -u pkgsrc/pkgtools/pkglint/files/makepat/pat.go:1.2 pkgsrc/pkgtools/pkglint/files/makepat/pat.go:1.3
--- pkgsrc/pkgtools/pkglint/files/makepat/pat.go:1.2 Sat Jun 20 07:00:44 2020
+++ pkgsrc/pkgtools/pkglint/files/makepat/pat.go Sun Aug 8 22:04:15 2021
@@ -32,20 +32,16 @@ func Compile(pattern string) (*Pattern,
lex := textproc.NewLexer(pattern)
for !lex.EOF() {
+ ch := lex.NextByte()
- if lex.SkipByte('*') {
+ switch ch {
+ case '*':
p.AddTransition(s, 0, 255, s)
- continue
- }
-
- if lex.SkipByte('?') {
+ case '?':
next := p.AddState(false)
p.AddTransition(s, 0, 255, next)
s = next
- continue
- }
-
- if lex.SkipByte('\\') {
+ case '\\':
if lex.EOF() {
return nil, errors.New("unfinished escape sequence")
}
@@ -53,23 +49,17 @@ func Compile(pattern string) (*Pattern,
next := p.AddState(false)
p.AddTransition(s, ch, ch, next)
s = next
- continue
- }
-
- ch := lex.NextByte()
- if ch != '[' {
+ case '[':
+ next, err := compileCharClass(&p, lex, ch, s)
+ if err != nil {
+ return nil, err
+ }
+ s = next
+ default:
next := p.AddState(false)
p.AddTransition(s, ch, ch, next)
s = next
- continue
- }
-
- next, err := compileCharClass(&p, lex, ch, s)
- if err != nil {
- return nil, err
}
-
- s = next
}
p.states[s].end = true
@@ -144,13 +134,17 @@ func (p *Pattern) AddTransition(from Sta
// Match tests whether a pattern matches the given string.
func (p *Pattern) Match(s string) bool {
+ if len(p.states) == 0 {
+ return false
+ }
+
curr := make([]bool, len(p.states))
next := make([]bool, len(p.states))
curr[0] = true
for _, ch := range []byte(s) {
ok := false
- for i, _ := range next {
+ for i := range next {
next[i] = false
}
@@ -183,21 +177,33 @@ func (p *Pattern) Match(s string) bool {
// match at the same time.
func Intersect(p1, p2 *Pattern) *Pattern {
var res Pattern
- for i1 := 0; i1 < len(p1.states); i1++ {
- for i2 := 0; i2 < len(p2.states); i2++ {
- res.AddState(p1.states[i1].end && p2.states[i2].end)
+
+ newState := make(map[[2]StateID]StateID)
+
+ // stateFor returns the state ID in the intersection,
+ // creating it if necessary.
+ stateFor := func(s1, s2 StateID) StateID {
+ key := [2]StateID{s1, s2}
+ ns, ok := newState[key]
+ if !ok {
+ ns = res.AddState(p1.states[s1].end && p2.states[s2].end)
+ newState[key] = ns
}
+ return ns
}
- for i1 := 0; i1 < len(p1.states); i1++ {
- for i2 := 0; i2 < len(p2.states); i2++ {
- for _, t1 := range p1.states[i1].transitions {
- for _, t2 := range p2.states[i2].transitions {
+ // Each pattern needs a start node.
+ stateFor(0, 0)
+
+ for i1, s1 := range p1.states {
+ for i2, s2 := range p2.states {
+ for _, t1 := range s1.transitions {
+ for _, t2 := range s2.transitions {
min := bmax(t1.min, t2.min)
max := bmin(t1.max, t2.max)
if min <= max {
- from := StateID(i1*len(p2.states) + i2)
- to := t1.to*StateID(len(p2.states)) + t2.to
+ from := stateFor(StateID(i1), StateID(i2))
+ to := stateFor(t1.to, t2.to)
res.AddTransition(from, min, max, to)
}
}
@@ -209,33 +215,101 @@ func Intersect(p1, p2 *Pattern) *Pattern
}
func (p *Pattern) optimized() *Pattern {
- var opt Pattern
+ reachable := p.reachable()
+ relevant := p.relevant(reachable)
+ return p.compressed(relevant)
+}
- var todo []StateID
- hasNewID := make([]bool, len(p.states))
- newIDs := make([]StateID, len(p.states))
+// reachable returns all states that are reachable from the start state.
+// In optimized patterns, each state is reachable.
+func (p *Pattern) reachable() []bool {
+ reachable := make([]bool, len(p.states))
+
+ progress := make([]int, len(p.states)) // 0 = unseen, 1 = to do, 2 = done
- todo = append(todo, 0)
- newIDs[0] = opt.AddState(p.states[0].end)
- hasNewID[0] = true
+ progress[0] = 1
+
+ for {
+ changed := false
+ for i, pr := range progress {
+ if pr == 1 {
+ reachable[i] = true
+ progress[i] = 2
+ changed = true
+ for _, tr := range p.states[i].transitions {
+ if progress[tr.to] == 0 {
+ progress[tr.to] = 1
+ }
+ }
+ }
+ }
+
+ if !changed {
+ break
+ }
+ }
- for len(todo) > 0 {
- oldStateID := todo[len(todo)-1]
- todo = todo[:len(todo)-1]
+ return reachable
+}
- oldState := p.states[oldStateID]
+// relevant returns all states from which and end state is reachable.
+// In optimized patterns, each state is relevant.
+func (p *Pattern) relevant(reachable []bool) []bool {
+ relevant := make([]bool, len(p.states))
+
+ progress := make([]int, len(p.states)) // 0 = unseen, 1 = to do, 2 = done
+
+ for i, state := range p.states {
+ if state.end && reachable[i] {
+ progress[i] = 1
+ }
+ }
- for _, t := range oldState.transitions {
- if !hasNewID[t.to] {
- hasNewID[t.to] = true
- newIDs[t.to] = opt.AddState(p.states[t.to].end)
- todo = append(todo, t.to)
+ for {
+ changed := false
+ for to, pr := range progress {
+ if pr != 1 {
+ continue
+ }
+ progress[to] = 2
+ relevant[to] = true
+ changed = true
+ for from, st := range p.states {
+ for _, tr := range st.transitions {
+ if tr.to == StateID(to) && reachable[from] &&
+ progress[from] == 0 {
+ progress[from] = 1
+ }
+ }
}
- opt.AddTransition(newIDs[oldStateID], t.min, t.max, newIDs[t.to])
+ }
+
+ if !changed {
+ break
+ }
+ }
+
+ return relevant
+}
+
+// compressed creates a pattern that contains only the relevant states.
+func (p *Pattern) compressed(relevant []bool) *Pattern {
+ var opt Pattern
+
+ newIDs := make([]StateID, len(p.states))
+ for i, r := range relevant {
+ if r {
+ newIDs[i] = opt.AddState(p.states[i].end)
}
}
- // TODO: remove transitions that point to a dead end
+ for from, s := range p.states {
+ for _, t := range s.transitions {
+ if relevant[from] && relevant[t.to] {
+ opt.AddTransition(newIDs[from], t.min, t.max, newIDs[t.to])
+ }
+ }
+ }
return &opt
}
@@ -246,25 +320,12 @@ func (p *Pattern) optimized() *Pattern {
// [^]
// Intersect("*.c", "*.h")
func (p *Pattern) CanMatch() bool {
- reachable := make([]bool, len(p.states))
- reachable[0] = true
-
-again:
- changed := false
- for i, s := range p.states {
- if reachable[i] {
- for _, t := range s.transitions {
- if !reachable[t.to] {
- reachable[t.to] = true
- changed = true
- }
- }
- }
- }
- if changed {
- goto again
+ if len(p.states) == 0 {
+ return false
}
+ reachable := p.reachable()
+
for i, s := range p.states {
if reachable[i] && s.end {
return true
Index: pkgsrc/pkgtools/pkglint/files/makepat/pat_test.go
diff -u pkgsrc/pkgtools/pkglint/files/makepat/pat_test.go:1.3 pkgsrc/pkgtools/pkglint/files/makepat/pat_test.go:1.4
--- pkgsrc/pkgtools/pkglint/files/makepat/pat_test.go:1.3 Fri Jun 25 14:15:01 2021
+++ pkgsrc/pkgtools/pkglint/files/makepat/pat_test.go Sun Aug 8 22:04:15 2021
@@ -44,10 +44,11 @@ func Test_compileCharClass(t *testing.T)
p, err := Compile(tt.pattern)
if err != nil {
t.Fail()
- }
- got := p.Match(tt.str)
- if got != tt.want {
- t.Errorf("got %v, want %v", got, tt.want)
+ } else {
+ got := p.Match(tt.str)
+ if got != tt.want {
+ t.Errorf("got %v, want %v", got, tt.want)
+ }
}
})
}
@@ -176,6 +177,8 @@ func Test_Intersect(t *testing.T) {
{"N-9.99.*", "N-[1-9].*", "", false, true},
{"N-9.99.*", "N-[1-9][0-9].*", "", false, false},
{"*.c", "*.h", "", false, false},
+ {"a*", "*b", "ab", true, true},
+ {"a*bc", "ab*c", "abc", true, true},
}
for _, tt := range tests {
t.Run(tt.str, func(t *testing.T) {
@@ -220,6 +223,48 @@ func Test_Pattern_optimized(t *testing.T
}
}
+func Test_Pattern_reachable(t *testing.T) {
+ p, err := Compile("N-*")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ reachable := p.reachable()
+
+ if !reflect.DeepEqual(reachable, []bool{true, true, true}) {
+ t.Errorf("%#v", reachable)
+ }
+}
+
+func Test_Pattern_relevant(t *testing.T) {
+ p, err := Compile("N-*")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ reachable := p.reachable()
+ relevant := p.relevant(reachable)
+
+ if !reflect.DeepEqual(relevant, []bool{true, true, true}) {
+ t.Errorf("%#v", relevant)
+ }
+}
+
+func Test_Pattern_compressed(t *testing.T) {
+ p, err := Compile("N-*")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ reachable := p.reachable()
+ relevant := p.relevant(reachable)
+ compressed := p.compressed(relevant)
+
+ if !reflect.DeepEqual(compressed, p) {
+ t.Errorf("%#v", compressed)
+ }
+}
+
func Test_Pattern_CanMatch(t *testing.T) {
tests := []struct {
p1 string
Index: pkgsrc/pkgtools/pkglint/files/textproc/lexer.go
diff -u pkgsrc/pkgtools/pkglint/files/textproc/lexer.go:1.11 pkgsrc/pkgtools/pkglint/files/textproc/lexer.go:1.12
--- pkgsrc/pkgtools/pkglint/files/textproc/lexer.go:1.11 Sun Jun 6 11:46:44 2021
+++ pkgsrc/pkgtools/pkglint/files/textproc/lexer.go Sun Aug 8 22:04:15 2021
@@ -76,7 +76,7 @@ func (l *Lexer) NextString(prefix string
return ""
}
-// SkipText skips over the given string, if the remaining string starts
+// SkipString skips over the given string, if the remaining string starts
// with it. It returns whether it actually skipped.
func (l *Lexer) SkipString(prefix string) bool {
skipped := strings.HasPrefix(l.rest, prefix)
@@ -199,8 +199,8 @@ func (l *Lexer) SkipRegexp(re *regexp.Re
}
// NextRegexp tests whether the remaining string matches the given regular
-// expression, and in that case, skips over it and returns the matched substrings,
-// as in regexp.FindStringSubmatch.
+// expression, and in that case, chops it off and returns the matched
+// substrings, as in regexp.FindStringSubmatch.
// If the regular expression does not match, returns nil.
func (l *Lexer) NextRegexp(re *regexp.Regexp) []string {
if !strings.HasPrefix(re.String(), "^") {
Home |
Main Index |
Thread Index |
Old Index