summaryrefslogtreecommitdiff
path: root/pkgtools
diff options
context:
space:
mode:
authorrillig <rillig>2016-03-13 13:40:10 +0000
committerrillig <rillig>2016-03-13 13:40:10 +0000
commitbde133f09395bdb072c221af6a0b035230fe9f0b (patch)
treeca2af3cf939d541a4377327fe61091a23ab2e02a /pkgtools
parent95570a154bfc53b1b18e5f37cc8487f37d5b8588 (diff)
downloadpkgsrc-bde133f09395bdb072c221af6a0b035230fe9f0b.tar.gz
Updated pkglint to 5.3.6.
Changes since 5.3.5: * Warn about !empty(${VARNAME}), which should be !empty(VARNAME) * Distinguish ${VARNAME} == "value" and ${VARNAME:Mpattern} * Corrected isQuotingNecessary for some variable types * Generally, parse files from mk/, since they define variables used by packages. This avoids wrong warnings about possible spelling mistakes. * Warn about $(VARNAME) (with parentheses instead of braces) * Warn about missing final @ in ${VAR:@var@...@} * Updated list of hardware architectures * Enabled CPU profiling on NetBSD
Diffstat (limited to 'pkgtools')
-rw-r--r--pkgtools/pkglint/Makefile5
-rw-r--r--pkgtools/pkglint/files/buildlink3.go4
-rw-r--r--pkgtools/pkglint/files/main.go14
-rw-r--r--pkgtools/pkglint/files/mkline.go47
-rw-r--r--pkgtools/pkglint/files/mkline_test.go13
-rw-r--r--pkgtools/pkglint/files/package.go13
-rw-r--r--pkgtools/pkglint/files/parser.go30
-rw-r--r--pkgtools/pkglint/files/parser_test.go19
-rw-r--r--pkgtools/pkglint/files/vardefs.go18
-rw-r--r--pkgtools/pkglint/files/vartype.go2
-rw-r--r--pkgtools/pkglint/files/vartypecheck.go113
-rw-r--r--pkgtools/pkglint/files/vartypecheck_test.go18
12 files changed, 208 insertions, 88 deletions
diff --git a/pkgtools/pkglint/Makefile b/pkgtools/pkglint/Makefile
index 446f790b789..e8da3006bf3 100644
--- a/pkgtools/pkglint/Makefile
+++ b/pkgtools/pkglint/Makefile
@@ -1,7 +1,6 @@
-# $NetBSD: Makefile,v 1.482 2016/02/23 20:18:12 bsiegert Exp $
+# $NetBSD: Makefile,v 1.483 2016/03/13 13:40:10 rillig Exp $
-PKGNAME= pkglint-5.3.5
-PKGREVISION= 1
+PKGNAME= pkglint-5.3.6
DISTFILES= # none
CATEGORIES= pkgtools
diff --git a/pkgtools/pkglint/files/buildlink3.go b/pkgtools/pkglint/files/buildlink3.go
index ab42134c7cd..5f93cb48d24 100644
--- a/pkgtools/pkglint/files/buildlink3.go
+++ b/pkgtools/pkglint/files/buildlink3.go
@@ -118,7 +118,7 @@ func ChecklinesBuildlink3Mk(mklines *MkLines) {
if varname == "BUILDLINK_ABI_DEPENDS."+pkgbase {
abiLine = line
- parser := NewParser(value)
+ parser := NewParser(line, value)
if dp := parser.Dependency(); dp != nil && parser.EOF() {
abi = dp
}
@@ -126,7 +126,7 @@ func ChecklinesBuildlink3Mk(mklines *MkLines) {
}
if varname == "BUILDLINK_API_DEPENDS."+pkgbase {
apiLine = line
- parser := NewParser(value)
+ parser := NewParser(line, value)
if dp := parser.Dependency(); dp != nil && parser.EOF() {
api = dp
}
diff --git a/pkgtools/pkglint/files/main.go b/pkgtools/pkglint/files/main.go
index 9d39e47f869..959c7a851f7 100644
--- a/pkgtools/pkglint/files/main.go
+++ b/pkgtools/pkglint/files/main.go
@@ -5,7 +5,6 @@ import (
"io"
"os"
"path/filepath"
- "runtime"
"runtime/pprof"
)
@@ -40,14 +39,13 @@ func (pkglint *Pkglint) Main(args ...string) (exitcode int) {
}
if G.opts.Profiling {
- if runtime.GOOS != "netbsd" { // See https://github.com/golang/go/issues/13914
- f, err := os.Create("pkglint.pprof")
- if err != nil {
- dummyLine.Fatalf("Cannot create profiling file: %s", err)
- }
- pprof.StartCPUProfile(f)
- defer pprof.StopCPUProfile()
+ f, err := os.Create("pkglint.pprof")
+ if err != nil {
+ dummyLine.Fatalf("Cannot create profiling file: %s", err)
}
+ pprof.StartCPUProfile(f)
+ defer pprof.StopCPUProfile()
+
G.rematch = NewHistogram()
G.renomatch = NewHistogram()
G.retime = NewHistogram()
diff --git a/pkgtools/pkglint/files/mkline.go b/pkgtools/pkglint/files/mkline.go
index aa51d9d4fe2..96677eb7b21 100644
--- a/pkgtools/pkglint/files/mkline.go
+++ b/pkgtools/pkglint/files/mkline.go
@@ -144,7 +144,7 @@ func (mkline *MkLine) Targets() string { return mkline.xs1 }
func (mkline *MkLine) Sources() string { return mkline.xs2 }
func (mkline *MkLine) Tokenize(s string) {
- p := NewParser(s)
+ p := NewParser(mkline.Line, s)
p.MkTokens()
if p.Rest() != "" {
mkline.Error1("Invalid Makefile syntax at %q.", p.Rest())
@@ -330,24 +330,24 @@ func (mkline *MkLine) WarnVaruseLocalbase() {
"(1) To locate a file or directory from another package.",
"(2) To refer to own files after installation.",
"",
- "In the first case, the example is:",
+ "Example for (1):",
"",
" STRLIST= ${LOCALBASE}/bin/strlist",
" do-build:",
" cd ${WRKSRC} && ${STRLIST} *.str",
"",
- "This should really be:",
+ "This should better be:",
"",
" EVAL_PREFIX= STRLIST_PREFIX=strlist",
" STRLIST= ${STRLIST_PREFIX}/bin/strlist",
" do-build:",
" cd ${WRKSRC} && ${STRLIST} *.str",
"",
- "In the second case, the example is:",
+ "Example for (2):",
"",
" CONFIGURE_ENV+= --with-datafiles=${LOCALBASE}/share/pkgbase",
"",
- "This should really be:",
+ "This should better be:",
"",
" CONFIGURE_ENV+= --with-datafiles=${PREFIX}/share/pkgbase")
}
@@ -816,7 +816,7 @@ func (mkline *MkLine) CheckCond() {
defer tracecall0()()
}
- p := NewParser(mkline.Args())
+ p := NewParser(mkline.Line, mkline.Args())
cond := p.MkCond()
if !p.EOF() {
mkline.Warn1("Invalid conditional %q.", mkline.Args())
@@ -826,6 +826,21 @@ func (mkline *MkLine) CheckCond() {
cond.Visit("empty", func(node *Tree) {
varuse := node.args[0].(MkVarUse)
varname := varuse.varname
+ if matches(varname, `^\$.*:[MN]`) {
+ mkline.Warn0("The empty() function takes a variable name as parameter, not a variable expression.")
+ Explain(
+ "Instead of empty(${VARNAME:Mpattern}), you should write either",
+ "of the following:",
+ "",
+ "\tempty(VARNAME:Mpattern)",
+ "\t${VARNAME:Mpattern} == \"\"",
+ "",
+ "Instead of !empty(${VARNAME:Mpattern}), you should write either",
+ "of the following:",
+ "",
+ "\t!empty(VARNAME:Mpattern)",
+ "\t${VARNAME:Mpattern}")
+ }
for _, modifier := range varuse.modifiers {
if modifier[0] == 'M' || modifier[0] == 'N' {
mkline.CheckVartype(varname, opUseMatch, modifier[1:], "")
@@ -838,7 +853,9 @@ func (mkline *MkLine) CheckCond() {
varname := varuse.varname
varmods := varuse.modifiers
value := node.args[2].(string)
- if len(varmods) == 0 || len(varmods) == 1 && matches(varmods[0], `^[MN]`) && value != "" {
+ if len(varmods) == 0 {
+ mkline.CheckVartype(varname, opUse, value, "")
+ } else if len(varmods) == 1 && matches(varmods[0], `^[MN]`) && value != "" {
mkline.CheckVartype(varname, opUseMatch, value, "")
}
})
@@ -976,21 +993,31 @@ func (mkline *MkLine) variableNeedsQuoting(varname string, vuc *VarUseContext) (
isPlainWord := vartype.checker.IsEnum()
switch vartype.checker {
- case CheckvarDistSuffix,
+ case CheckvarBuildlinkDepmethod,
+ CheckvarCategory,
+ CheckvarDistSuffix,
+ CheckvarEmulPlatform,
CheckvarFileMode,
CheckvarFilename,
CheckvarIdentifier,
+ CheckvarInteger,
CheckvarOption,
CheckvarPathname,
+ CheckvarPerl5Packlist,
CheckvarPkgName,
CheckvarPkgOptionsVar,
+ CheckvarPkgPath,
CheckvarPkgRevision,
+ CheckvarPrefixPathname,
+ CheckvarPythonDependency,
CheckvarRelativePkgDir,
CheckvarRelativePkgPath,
+ CheckvarStage,
CheckvarUserGroupName,
- CheckvarVarname,
CheckvarVersion,
- CheckvarWrkdirSubdirectory:
+ CheckvarWrkdirSubdirectory,
+ CheckvarYesNo,
+ CheckvarYesNoIndirectly:
isPlainWord = true
}
if isPlainWord {
diff --git a/pkgtools/pkglint/files/mkline_test.go b/pkgtools/pkglint/files/mkline_test.go
index 2f71f5d066e..baace91dfce 100644
--- a/pkgtools/pkglint/files/mkline_test.go
+++ b/pkgtools/pkglint/files/mkline_test.go
@@ -330,6 +330,18 @@ func (s *Suite) TestChecklineMkCondition(c *check.C) {
NewMkLine(NewLine("fname", 1, ".if !empty(IS_BUILTIN.Xfixes:M[yY][eE][sS])", nil)).CheckCond()
c.Check(s.Output(), equals, "")
+
+ NewMkLine(NewLine("fname", 1, ".if !empty(${IS_BUILTIN.Xfixes:M[yY][eE][sS]})", nil)).CheckCond()
+
+ c.Check(s.Output(), equals, "WARN: fname:1: The empty() function takes a variable name as parameter, not a variable expression.\n")
+
+ NewMkLine(NewLine("fname", 1, ".if ${EMUL_PLATFORM} == \"linux-x386\"", nil)).CheckCond()
+
+ c.Check(s.Output(), equals, "WARN: fname:1: \"x386\" is not valid for the hardware architecture part of EMUL_PLATFORM. Use one of { alpha amd64 arc arm arm32 cobalt convex dreamcast hpcmips hpcsh hppa i386 ia64 m68k m88k mips mips64 mips64eb mips64el mipseb mipsel mipsn32 ns32k pc532 pmax powerpc rs6000 s390 sh3eb sh3el sparc sparc64 vax x86_64 } instead.\n")
+
+ NewMkLine(NewLine("fname", 1, ".if ${EMUL_PLATFORM:Mlinux-x386}", nil)).CheckCond()
+
+ c.Check(s.Output(), equals, "WARN: fname:1: The pattern \"x386\" cannot match any of { alpha amd64 arc arm arm32 cobalt convex dreamcast hpcmips hpcsh hppa i386 ia64 m68k m88k mips mips64 mips64eb mips64el mipseb mipsel mipsn32 ns32k pc532 pmax powerpc rs6000 s390 sh3eb sh3el sparc sparc64 vax x86_64 } for the hardware architecture part of EMUL_PLATFORM.\n")
}
func (s *Suite) TestMkLine_variableNeedsQuoting(c *check.C) {
@@ -435,7 +447,6 @@ func (s *Suite) TestMkLine_CheckVarusePermissions(c *check.C) {
"WARN: options.mk:2: The user-defined variable GAMES_USER is used but not added to BUILD_DEFS.\n"+
"WARN: options.mk:3: PKGBASE should not be evaluated at load time.\n"+
"WARN: options.mk:4: The variable PYPKGPREFIX may not be set in this file; it would be ok in pyversion.mk.\n"+
- "WARN: options.mk:4: \"${PKGBASE}\" is not valid for PYPKGPREFIX. Use one of { py27 py33 py34 py35 } instead.\n"+
"WARN: options.mk:4: PKGBASE should not be evaluated indirectly at load time.\n"+
"NOTE: options.mk:4: This variable value should be aligned to column 17.\n")
}
diff --git a/pkgtools/pkglint/files/package.go b/pkgtools/pkglint/files/package.go
index 4419db20092..40232102c7a 100644
--- a/pkgtools/pkglint/files/package.go
+++ b/pkgtools/pkglint/files/package.go
@@ -164,6 +164,9 @@ func checkdirPackage(pkgpath string) {
}
for _, fname := range files {
+ if containsVarRef(fname) {
+ continue
+ }
if fname == G.CurrentDir+"/Makefile" {
if G.opts.CheckMakefile {
pkg.checkfilePackageMakefile(fname, lines)
@@ -294,7 +297,8 @@ func readMakefile(fname string, mainLines *MkLines, allLines *MkLines, including
G.Pkg.seenMakefileCommon = true
}
- if !contains(incDir, "/mk/") || strings.HasSuffix(includeFile, "/mk/haskell.mk") || contains(incDir, "/wip/mk/") {
+ skip := contains(fname, "/mk/") || hasSuffix(includeFile, "/bsd.pkg.mk") || hasSuffix(includeFile, "/bsd.prefs.mk")
+ if !skip {
dirname, _ := path.Split(fname)
dirname = cleanpath(dirname)
@@ -389,9 +393,10 @@ func (pkg *Package) checkfilePackageMakefile(fname string, mklines *MkLines) {
Warnf(fname, noLines, "No COMMENT given.")
}
- if vardef["USE_IMAKE"] != nil && vardef["USE_X11"] != nil {
- vardef["USE_IMAKE"].Note0("USE_IMAKE makes ...")
- vardef["USE_X11"].Note0("... USE_X11 superfluous.")
+ if imake, x11 := vardef["USE_IMAKE"], vardef["USE_X11"]; imake != nil && x11 != nil {
+ if !hasSuffix(x11.Line.Fname, "/mk/x11.buildlink3.mk") {
+ imake.Line.Note1("USE_IMAKE makes USE_X11 in %s superfluous.", x11.Line.ReferenceFrom(imake.Line))
+ }
}
pkg.checkUpdate()
diff --git a/pkgtools/pkglint/files/parser.go b/pkgtools/pkglint/files/parser.go
index 0b8b3b98206..f33bc1343c5 100644
--- a/pkgtools/pkglint/files/parser.go
+++ b/pkgtools/pkglint/files/parser.go
@@ -5,11 +5,12 @@ import (
)
type Parser struct {
+ line *Line
repl *PrefixReplacer
}
-func NewParser(s string) *Parser {
- return &Parser{NewPrefixReplacer(s)}
+func NewParser(line *Line, s string) *Parser {
+ return &Parser{line, NewPrefixReplacer(s)}
}
func (p *Parser) EOF() bool {
@@ -155,15 +156,16 @@ func (p *Parser) VarUse() *MkVarUse {
mark := repl.Mark()
if repl.AdvanceStr("${") || repl.AdvanceStr("$(") {
- closing := "}"
- if repl.Since(mark) == "$(" {
- closing = ")"
- }
+ usingRoundParen := repl.Since(mark) == "$("
+ closing := ifelseStr(usingRoundParen, ")", "}")
varnameMark := repl.Mark()
varname := p.Varname()
if varname != "" {
- modifiers := p.VarUseModifiers(closing)
+ if usingRoundParen {
+ p.line.Warn1("Please use curly braces {} instead of round parentheses () for %s.", varname)
+ }
+ modifiers := p.VarUseModifiers(varname, closing)
if repl.AdvanceStr(closing) {
return &MkVarUse{varname, modifiers}
}
@@ -174,7 +176,7 @@ func (p *Parser) VarUse() *MkVarUse {
rest := p.Rest()
if hasPrefix(rest, ":L") || hasPrefix(rest, ":sh") || hasPrefix(rest, ":?") {
varexpr := repl.Since(varnameMark)
- modifiers := p.VarUseModifiers(closing)
+ modifiers := p.VarUseModifiers(varexpr, closing)
if repl.AdvanceStr(closing) {
return &MkVarUse{varexpr, modifiers}
}
@@ -185,7 +187,7 @@ func (p *Parser) VarUse() *MkVarUse {
return nil
}
-func (p *Parser) VarUseModifiers(closing string) []string {
+func (p *Parser) VarUseModifiers(varname, closing string) []string {
repl := p.repl
var modifiers []string
@@ -243,12 +245,14 @@ func (p *Parser) VarUseModifiers(closing string) []string {
case '@':
if repl.AdvanceRegexp(`^@([\w.]+)@`) {
+ loopvar := repl.m[1]
for p.VarUse() != nil || repl.AdvanceRegexp(`^([^$:@`+closing+`\\]|\$\$|\\.)+`) {
}
- if repl.AdvanceStr("@") {
- modifiers = append(modifiers, repl.Since(modifierMark))
- continue
+ if !repl.AdvanceStr("@") {
+ p.line.Warn2("Modifier ${%s:@%s@...@} is missing the final \"@\".", varname, loopvar)
}
+ modifiers = append(modifiers, repl.Since(modifierMark))
+ continue
}
case '[':
@@ -365,7 +369,7 @@ func (p *Parser) mkCondAtom() *Tree {
}
case repl.AdvanceRegexp(`^empty\s*\(`):
if varname := p.Varname(); varname != "" {
- modifiers := p.VarUseModifiers(")")
+ modifiers := p.VarUseModifiers(varname, ")")
if repl.AdvanceStr(")") {
return NewTree("empty", MkVarUse{varname, modifiers})
}
diff --git a/pkgtools/pkglint/files/parser_test.go b/pkgtools/pkglint/files/parser_test.go
index 72dd8b8d12f..d094250b682 100644
--- a/pkgtools/pkglint/files/parser_test.go
+++ b/pkgtools/pkglint/files/parser_test.go
@@ -6,7 +6,7 @@ import (
func (s *Suite) TestParser_PkgbasePattern(c *check.C) {
test := func(pattern, expected, rest string) {
- parser := NewParser(pattern)
+ parser := NewParser(dummyLine, pattern)
actual := parser.PkgbasePattern()
c.Check(actual, equals, expected)
c.Check(parser.Rest(), equals, rest)
@@ -22,7 +22,7 @@ func (s *Suite) TestParser_PkgbasePattern(c *check.C) {
func (s *Suite) TestParser_Dependency(c *check.C) {
testDependencyRest := func(pattern string, expected DependencyPattern, rest string) {
- parser := NewParser(pattern)
+ parser := NewParser(dummyLine, pattern)
dp := parser.Dependency()
if c.Check(dp, check.NotNil) {
c.Check(*dp, equals, expected)
@@ -53,7 +53,7 @@ func (s *Suite) TestParser_Dependency(c *check.C) {
func (s *Suite) TestParser_MkTokens(c *check.C) {
parse := func(input string, expectedTokens []*MkToken, expectedRest string) {
- p := NewParser(input)
+ p := NewParser(dummyLine, input)
actualTokens := p.MkTokens()
c.Check(actualTokens, deepEquals, expectedTokens)
for i, expectedToken := range expectedTokens {
@@ -109,7 +109,6 @@ func (s *Suite) TestParser_MkTokens(c *check.C) {
token("${_PERL5_VARS_OUT:M${_var_:tl}=*:S/^${_var_:tl}=${_PERL5_PREFIX:=/}//}", varuse("_PERL5_VARS_OUT", "M${_var_:tl}=*", "S/^${_var_:tl}=${_PERL5_PREFIX:=/}//"))
token("${RUBY${RUBY_VER}_PATCHLEVEL}", varuse("RUBY${RUBY_VER}_PATCHLEVEL"))
token("${DISTFILES:M*.gem}", varuse("DISTFILES", "M*.gem"))
- token("$(GNUSTEP_USER_ROOT)", varuse("GNUSTEP_USER_ROOT"))
token("${LOCALBASE:S^/^_^}", varuse("LOCALBASE", "S^/^_^"))
token("${SOURCES:%.c=%.o}", varuse("SOURCES", "%.c=%.o"))
token("${GIT_TEMPLATES:@.t.@ ${EGDIR}/${GIT_TEMPLATEDIR}/${.t.} ${PREFIX}/${GIT_CORE_TEMPLATEDIR}/${.t.} @:M*}",
@@ -135,13 +134,21 @@ func (s *Suite) TestParser_MkTokens(c *check.C) {
token("${VAR:ts\\000012}", varuse("VAR", "ts\\000012")) // The separator character can be a long octal number.
token("${VAR:ts\\124}", varuse("VAR", "ts\\124")) // Or even decimal.
+ token("$(GNUSTEP_USER_ROOT)", varuse("GNUSTEP_USER_ROOT"))
+ c.Check(s.Output(), equals, "WARN: Please use curly braces {} instead of round parentheses () for GNUSTEP_USER_ROOT.\n")
+
parse("${VAR)", nil, "${VAR)") // Opening brace, closing parenthesis
parse("$(VAR}", nil, "$(VAR}") // Opening parenthesis, closing brace
+ c.Check(s.Output(), equals, "WARN: Please use curly braces {} instead of round parentheses () for VAR.\n")
+
+ token("${PLIST_SUBST_VARS:@var@${var}=${${var}:Q}@}", varuse("PLIST_SUBST_VARS", "@var@${var}=${${var}:Q}@"))
+ token("${PLIST_SUBST_VARS:@var@${var}=${${var}:Q}}", varuse("PLIST_SUBST_VARS", "@var@${var}=${${var}:Q}")) // Missing @ at the end
+ c.Check(s.Output(), equals, "WARN: Modifier ${PLIST_SUBST_VARS:@var@...@} is missing the final \"@\".\n")
}
func (s *Suite) TestParser_MkCond_Basics(c *check.C) {
condrest := func(input string, expectedTree *Tree, expectedRest string) {
- p := NewParser(input)
+ p := NewParser(dummyLine, input)
actualTree := p.MkCond()
c.Check(actualTree, deepEquals, expectedTree)
c.Check(p.Rest(), equals, expectedRest)
@@ -209,6 +216,8 @@ func (s *Suite) TestParser_MkCond_Basics(c *check.C) {
NewTree("compareVarNum", varuse("OS_VERSION"), ">=", "6.5"))
cond("${OS_VERSION} == 5.3",
NewTree("compareVarNum", varuse("OS_VERSION"), "==", "5.3"))
+ cond("!empty(${OS_VARIANT:MIllumos})", // Probably not intended
+ NewTree("not", NewTree("empty", varuse("${OS_VARIANT:MIllumos}"))))
// Errors
condrest("!empty(PKG_OPTIONS:Msndfile) || defined(PKG_OPTIONS:Msamplerate)",
diff --git a/pkgtools/pkglint/files/vardefs.go b/pkgtools/pkglint/files/vardefs.go
index 3352c07ee91..394ebaa6676 100644
--- a/pkgtools/pkglint/files/vardefs.go
+++ b/pkgtools/pkglint/files/vardefs.go
@@ -118,8 +118,8 @@ func (gd *GlobalData) InitVartypes() {
pkg("BOOTSTRAP_PKG", lkNone, CheckvarYesNo)
acl("BROKEN", lkNone, CheckvarMessage, "")
pkg("BROKEN_GETTEXT_DETECTION", lkNone, CheckvarYesNo)
- pkglist("BROKEN_EXCEPT_ON_PLATFORM", lkShell, CheckvarPlatformTriple)
- pkglist("BROKEN_ON_PLATFORM", lkSpace, CheckvarPlatformTriple)
+ pkglist("BROKEN_EXCEPT_ON_PLATFORM", lkShell, CheckvarPlatformPattern)
+ pkglist("BROKEN_ON_PLATFORM", lkSpace, CheckvarPlatformPattern)
sys("BSD_MAKE_ENV", lkShell, CheckvarShellWord)
acl("BUILDLINK_ABI_DEPENDS.*", lkSpace, CheckvarDependency, "*: append")
acl("BUILDLINK_API_DEPENDS.*", lkSpace, CheckvarDependency, "*: append")
@@ -334,8 +334,8 @@ func (gd *GlobalData) InitVartypes() {
pkglist("HEADER_TEMPLATES", lkShell, CheckvarPathname)
pkg("HOMEPAGE", lkNone, CheckvarURL)
acl("IGNORE_PKG.*", lkNone, CheckvarYes, "*: set, use-loadtime")
- acl("INCOMPAT_CURSES", lkSpace, CheckvarPlatformTriple, "Makefile: set, append")
- acl("INCOMPAT_ICONV", lkSpace, CheckvarPlatformTriple, "")
+ acl("INCOMPAT_CURSES", lkSpace, CheckvarPlatformPattern, "Makefile: set, append")
+ acl("INCOMPAT_ICONV", lkSpace, CheckvarPlatformPattern, "")
acl("INFO_DIR", lkNone, CheckvarPathname, "") // relative to PREFIX
pkg("INFO_FILES", lkNone, CheckvarYes)
sys("INSTALL", lkNone, CheckvarShellCommand)
@@ -392,7 +392,7 @@ func (gd *GlobalData) InitVartypes() {
sys("LOWER_OPSYS", lkNone, CheckvarIdentifier)
acl("LTCONFIG_OVERRIDE", lkShell, CheckvarPathmask, "Makefile: set, append; Makefile.common: append")
sys("MACHINE_ARCH", lkNone, CheckvarIdentifier)
- sys("MACHINE_GNU_PLATFORM", lkNone, CheckvarPlatformTriple)
+ sys("MACHINE_GNU_PLATFORM", lkNone, CheckvarPlatformPattern) // This one is actually not a pattern
acl("MAINTAINER", lkNone, CheckvarMailAddress, "Makefile: set; Makefile.common: default")
sys("MAKE", lkNone, CheckvarShellCommand)
pkglist("MAKEFLAGS", lkShell, CheckvarShellWord)
@@ -451,7 +451,7 @@ func (gd *GlobalData) InitVartypes() {
sys("NM", lkNone, CheckvarShellCommand)
sys("NONBINMODE", lkNone, CheckvarFileMode)
pkg("NOT_FOR_COMPILER", lkShell, enum("ccache ccc clang distcc f2c gcc hp icc ido mipspro mipspro-ucode pcc sunpro xlc"))
- pkglist("NOT_FOR_PLATFORM", lkSpace, CheckvarPlatformTriple)
+ pkglist("NOT_FOR_PLATFORM", lkSpace, CheckvarPlatformPattern)
pkg("NOT_FOR_UNPRIVILEGED", lkNone, CheckvarYesNo)
acl("NO_BIN_ON_CDROM", lkNone, CheckvarRestricted, "Makefile, Makefile.common: set")
acl("NO_BIN_ON_FTP", lkNone, CheckvarRestricted, "Makefile, Makefile.common: set")
@@ -465,7 +465,7 @@ func (gd *GlobalData) InitVartypes() {
acl("NO_SRC_ON_CDROM", lkNone, CheckvarRestricted, "Makefile, Makefile.common: set")
acl("NO_SRC_ON_FTP", lkNone, CheckvarRestricted, "Makefile, Makefile.common: set")
pkglist("ONLY_FOR_COMPILER", lkShell, enum("ccc clang gcc hp icc ido mipspro mipspro-ucode pcc sunpro xlc"))
- pkglist("ONLY_FOR_PLATFORM", lkSpace, CheckvarPlatformTriple)
+ pkglist("ONLY_FOR_PLATFORM", lkSpace, CheckvarPlatformPattern)
pkg("ONLY_FOR_UNPRIVILEGED", lkNone, CheckvarYesNo)
sys("OPSYS", lkNone, CheckvarIdentifier)
acl("OPSYSVARS", lkShell, CheckvarVarname, "Makefile, Makefile.common: append")
@@ -537,7 +537,7 @@ func (gd *GlobalData) InitVartypes() {
acl("PKG_HACKS", lkShell, CheckvarIdentifier, "hacks.mk: append")
sys("PKG_INFO", lkNone, CheckvarShellCommand)
sys("PKG_JAVA_HOME", lkNone, CheckvarPathname)
- jvms := enum("blackdown-jdk13 jdk jdk14 kaffe run-jdk13 sun-jdk14 sun-jdk15 sun-jdk6 openjdk7 openjdk7-bin sun-jdk7 openjdk8 oracle-jdk8")
+ jvms := enum("openjdk8 oracle-jdk8 openjdk7 sun-jdk7 sun-jdk6 jdk16 jdk15 kaffe") // See mk/java-vm.mk:/_PKG_JVMS/
sys("PKG_JVM", lkNone, jvms)
acl("PKG_JVMS_ACCEPTED", lkShell, jvms, "Makefile: set; Makefile.common: default, set")
usr("PKG_JVM_DEFAULT", lkNone, jvms)
@@ -724,7 +724,7 @@ func enum(values string) *VarChecker {
return
}
- if !vmap[cv.value] {
+ if cv.value == cv.valueNovar && !vmap[cv.value] {
cv.line.Warnf("%q is not valid for %s. Use one of { %s } instead.", cv.value, cv.varname, values)
}
}}
diff --git a/pkgtools/pkglint/files/vartype.go b/pkgtools/pkglint/files/vartype.go
index 686565e8dda..f88e548d5c3 100644
--- a/pkgtools/pkglint/files/vartype.go
+++ b/pkgtools/pkglint/files/vartype.go
@@ -179,7 +179,7 @@ var (
CheckvarPkgPath = &VarChecker{"PkgPath", (*VartypeCheck).PkgPath}
CheckvarPkgOptionsVar = &VarChecker{"PkgOptionsVar", (*VartypeCheck).PkgOptionsVar}
CheckvarPkgRevision = &VarChecker{"PkgRevision", (*VartypeCheck).PkgRevision}
- CheckvarPlatformTriple = &VarChecker{"PlatformTriple", (*VartypeCheck).PlatformTriple}
+ CheckvarPlatformPattern = &VarChecker{"PlatformPattern", (*VartypeCheck).PlatformPattern}
CheckvarPrefixPathname = &VarChecker{"PrefixPathname", (*VartypeCheck).PrefixPathname}
CheckvarPythonDependency = &VarChecker{"PythonDependency", (*VartypeCheck).PythonDependency}
CheckvarRelativePkgDir = &VarChecker{"RelativePkgDir", (*VartypeCheck).RelativePkgDir}
diff --git a/pkgtools/pkglint/files/vartypecheck.go b/pkgtools/pkglint/files/vartypecheck.go
index a91a1ce372d..bcf2deb5734 100644
--- a/pkgtools/pkglint/files/vartypecheck.go
+++ b/pkgtools/pkglint/files/vartypecheck.go
@@ -50,6 +50,26 @@ func (op MkOperator) String() string {
return [...]string{"=", "!=", ":=", "+=", "?=", "use", "use-loadtime", "use-match"}[op]
}
+const (
+ reEmulPlatform = "" +
+ "bitrig|bsdos|cygwin|darwin|dragonfly|freebsd|" +
+ "haiku|hpux|interix|irix|linux|mirbsd|netbsd|openbsd|osf1|solaris"
+ rePlatformOs = "" +
+ "Bitrig|BSDOS|Cygwin|Darwin|DragonFly|FreeBSD|" +
+ "Haiku|HPUX|Interix|IRIX|Linux|MirBSD|NetBSD|OpenBSD|OSF1|QNX|SunOS"
+ rePlatformArch = "" +
+ "alpha|amd64|arc|arm|arm32|cobalt|convex|dreamcast|" +
+ "hpcmips|hpcsh|hppa|i386|ia64|" +
+ "m68k|m88k|mips|mips64|mips64eb|mips64el|mipseb|mipsel|mipsn32|" +
+ "ns32k|pc532|pmax|powerpc|rs6000|s390|sh3eb|sh3el|sparc|sparc64|vax|x86_64"
+)
+
+var (
+ emulPlatformEnum = enum(strings.Replace(reEmulPlatform, "|", " ", -1))
+ platformOsEnum = enum(strings.Replace(rePlatformOs, "|", " ", -1))
+ platformArchEnum = enum(strings.Replace(rePlatformArch, "|", " ", -1))
+)
+
func (cv *VartypeCheck) AwkCommand() {
if G.opts.DebugUnchecked {
cv.line.Debug1("Unchecked AWK command: %q", cv.value)
@@ -137,7 +157,7 @@ func (cv *VartypeCheck) Comment() {
func (cv *VartypeCheck) Dependency() {
line, value := cv.line, cv.value
- parser := NewParser(value)
+ parser := NewParser(line, value)
deppat := parser.Dependency()
if deppat != nil && deppat.wildcard == "" && (parser.Rest() == "{,nb*}" || parser.Rest() == "{,nb[0-9]*}") {
line.Warn0("Dependency patterns of the form pkgbase>=1.0 don't need the \"{,nb*}\" extension.")
@@ -243,16 +263,34 @@ func (cv *VartypeCheck) DistSuffix() {
}
func (cv *VartypeCheck) EmulPlatform() {
+ const rePart = `(?:\[[^\]]+\]|[^-\[])+`
+ const rePair = `^(` + rePart + `)-(` + rePart + `)$`
+ if m, opsysPattern, archPattern := match2(cv.value, rePair); m {
+ opsysCv := &VartypeCheck{
+ cv.mkline,
+ cv.line,
+ "the operating system part of " + cv.varname,
+ cv.op,
+ opsysPattern,
+ opsysPattern,
+ cv.comment,
+ cv.listContext,
+ cv.guessed}
+ emulPlatformEnum.checker(opsysCv)
- if m, opsys, arch := match2(cv.value, `^(\w+)-(\w+)$`); m {
- if !matches(opsys, `^(?:bitrig|bsdos|cygwin|darwin|dragonfly|freebsd|haiku|hpux|interix|irix|linux|mirbsd|netbsd|openbsd|osf1|sunos|solaris)$`) {
- cv.line.Warn1("Unknown operating system: %s", opsys)
- }
// no check for os_version
- if !matches(arch, `^(?:i386|alpha|amd64|arc|arm|arm32|cobalt|convex|dreamcast|hpcmips|hpcsh|hppa|ia64|m68k|m88k|mips|mips64|mipsel|mipseb|mipsn32|ns32k|pc532|pmax|powerpc|rs6000|s390|sparc|sparc64|vax|x86_64)$`) {
- cv.line.Warn1("Unknown hardware architecture: %s", arch)
- }
+ archCv := &VartypeCheck{
+ cv.mkline,
+ cv.line,
+ "the hardware architecture part of " + cv.varname,
+ cv.op,
+ archPattern,
+ archPattern,
+ cv.comment,
+ cv.listContext,
+ cv.guessed}
+ platformArchEnum.checker(archCv)
} else {
cv.line.Warn1("%q is not a valid emulation platform.", cv.value)
Explain(
@@ -260,7 +298,9 @@ func (cv *VartypeCheck) EmulPlatform() {
"OPSYS is the lower-case name of the operating system, and",
"MACHINE_ARCH is the hardware architecture.",
"",
- "Examples: linux-i386, irix-mipsel.")
+ "Examples:",
+ "* linux-i386",
+ "* irix-mipsel")
}
}
@@ -535,31 +575,54 @@ func (cv *VartypeCheck) PkgRevision() {
}
}
-func (cv *VartypeCheck) PlatformTriple() {
+func (cv *VartypeCheck) PlatformPattern() {
if cv.value != cv.valueNovar {
return
}
- rePart := `(?:\[[^\]]+\]|[^-\[])+`
- reTriple := `^(` + rePart + `)-(` + rePart + `)-(` + rePart + `)$`
- if m, opsys, _, arch := match3(cv.value, reTriple); m {
- if !matches(opsys, `^(?:\*|Bitrig|BSDOS|Cygwin|Darwin|DragonFly|FreeBSD|Haiku|HPUX|Interix|IRIX|Linux|MirBSD|NetBSD|OpenBSD|OSF1|QNX|SunOS)$`) {
- cv.line.Warn1("Unknown operating system: %s", opsys)
- }
+ const rePart = `(?:\[[^\]]+\]|[^-\[])+`
+ const reTriple = `^(` + rePart + `)-(` + rePart + `)-(` + rePart + `)$`
+ if m, opsysPattern, _, archPattern := match3(cv.value, reTriple); m {
+ opsysCv := &VartypeCheck{
+ cv.mkline,
+ cv.line,
+ "the operating system part of " + cv.varname,
+ opUseMatch, // Always allow patterns, since this is a PlatformPattern.
+ opsysPattern,
+ opsysPattern,
+ cv.comment,
+ cv.listContext,
+ cv.guessed}
+ platformOsEnum.checker(opsysCv)
+
// no check for os_version
- if !matches(arch, `^(?:\*|i386|alpha|amd64|arc|arm|arm32|cobalt|convex|dreamcast|hpcmips|hpcsh|hppa|ia64|m68k|m88k|mips|mips64|mipsel|mipseb|mipsn32|ns32k|pc532|pmax|powerpc|rs6000|s390|sparc|sparc64|vax|x86_64)$`) {
- cv.line.Warn1("Unknown hardware architecture: %s", arch)
- }
+
+ archCv := &VartypeCheck{
+ cv.mkline,
+ cv.line,
+ "the hardware architecture part of " + cv.varname,
+ opUseMatch, // Always allow patterns, since this is a PlatformPattern.
+ archPattern,
+ archPattern,
+ cv.comment,
+ cv.listContext,
+ cv.guessed}
+ platformArchEnum.checker(archCv)
} else {
- cv.line.Warn1("%q is not a valid platform triple.", cv.value)
- Explain3(
- "A platform triple has the form <OPSYS>-<OS_VERSION>-<MACHINE_ARCH>.",
+ cv.line.Warn1("%q is not a valid platform pattern.", cv.value)
+ Explain(
+ "A platform pattern has the form <OPSYS>-<OS_VERSION>-<MACHINE_ARCH>.",
"Each of these components may be a shell globbing expression.",
- "Examples: NetBSD-*-i386, *-*-*, Linux-*-*.")
+ "",
+ "Examples:",
+ "* NetBSD-[456].*-i386",
+ "* *-*-*",
+ "* Linux-*-*")
}
}
+// A pathname relative to ${PREFIX}.
func (cv *VartypeCheck) PrefixPathname() {
if m, mansubdir := match1(cv.value, `^man/(.+)`); m {
cv.line.Warn2("Please use \"${PKGMANDIR}/%s\" instead of %q.", mansubdir, cv.value)
@@ -579,12 +642,12 @@ func (cv *VartypeCheck) PythonDependency() {
}
}
-// Refers to a package directory.
+// Refers to a package directory, e.g. ../../category/pkgbase.
func (cv *VartypeCheck) RelativePkgDir() {
cv.mkline.CheckRelativePkgdir(cv.value)
}
-// Refers to a file or directory.
+// Refers to a file or directory, e.g. ../../category/pkgbase, ../../category/pkgbase/Makefile.
func (cv *VartypeCheck) RelativePkgPath() {
cv.mkline.CheckRelativePath(cv.value, true)
}
diff --git a/pkgtools/pkglint/files/vartypecheck_test.go b/pkgtools/pkglint/files/vartypecheck_test.go
index 4cf8a54c4f7..dcd0615fe32 100644
--- a/pkgtools/pkglint/files/vartypecheck_test.go
+++ b/pkgtools/pkglint/files/vartypecheck_test.go
@@ -166,8 +166,8 @@ func (s *Suite) TestVartypeCheck_EmulPlatform(c *check.C) {
"${LINUX}")
c.Check(s.Output(), equals, ""+
- "WARN: fname:2: Unknown operating system: nextbsd\n"+
- "WARN: fname:2: Unknown hardware architecture: 8087\n"+
+ "WARN: fname:2: \"nextbsd\" is not valid for the operating system part of EMUL_PLATFORM. Use one of { bitrig bsdos cygwin darwin dragonfly freebsd haiku hpux interix irix linux mirbsd netbsd openbsd osf1 solaris } instead.\n"+
+ "WARN: fname:2: \"8087\" is not valid for the hardware architecture part of EMUL_PLATFORM. Use one of { alpha amd64 arc arm arm32 cobalt convex dreamcast hpcmips hpcsh hppa i386 ia64 m68k m88k mips mips64 mips64eb mips64el mipseb mipsel mipsn32 ns32k pc532 pmax powerpc rs6000 s390 sh3eb sh3el sparc sparc64 vax x86_64 } instead.\n"+
"WARN: fname:3: \"${LINUX}\" is not a valid emulation platform.\n")
}
@@ -287,16 +287,20 @@ func (s *Suite) TestVartypeCheck_PkgRevision(c *check.C) {
c.Check(s.Output(), equals, "")
}
-func (s *Suite) TestVartypeCheck_PlatformTriple(c *check.C) {
- runVartypeChecks("ONLY_FOR_PLATFORM", opAssign, (*VartypeCheck).PlatformTriple,
+func (s *Suite) TestVartypeCheck_PlatformPattern(c *check.C) {
+ runVartypeMatchChecks("ONLY_FOR_PLATFORM", (*VartypeCheck).PlatformPattern,
"linux-i386",
"nextbsd-5.0-8087",
+ "netbsd-7.0-l*",
+ "NetBSD-1.6.2-i386",
"${LINUX}")
c.Check(s.Output(), equals, ""+
- "WARN: fname:1: \"linux-i386\" is not a valid platform triple.\n"+
- "WARN: fname:2: Unknown operating system: nextbsd\n"+
- "WARN: fname:2: Unknown hardware architecture: 8087\n")
+ "WARN: fname:1: \"linux-i386\" is not a valid platform pattern.\n"+
+ "WARN: fname:2: The pattern \"nextbsd\" cannot match any of { Bitrig BSDOS Cygwin Darwin DragonFly FreeBSD Haiku HPUX Interix IRIX Linux MirBSD NetBSD OpenBSD OSF1 QNX SunOS } for the operating system part of ONLY_FOR_PLATFORM.\n"+
+ "WARN: fname:2: The pattern \"8087\" cannot match any of { alpha amd64 arc arm arm32 cobalt convex dreamcast hpcmips hpcsh hppa i386 ia64 m68k m88k mips mips64 mips64eb mips64el mipseb mipsel mipsn32 ns32k pc532 pmax powerpc rs6000 s390 sh3eb sh3el sparc sparc64 vax x86_64 } for the hardware architecture part of ONLY_FOR_PLATFORM.\n"+
+ "WARN: fname:3: The pattern \"netbsd\" cannot match any of { Bitrig BSDOS Cygwin Darwin DragonFly FreeBSD Haiku HPUX Interix IRIX Linux MirBSD NetBSD OpenBSD OSF1 QNX SunOS } for the operating system part of ONLY_FOR_PLATFORM.\n"+
+ "WARN: fname:3: The pattern \"l*\" cannot match any of { alpha amd64 arc arm arm32 cobalt convex dreamcast hpcmips hpcsh hppa i386 ia64 m68k m88k mips mips64 mips64eb mips64el mipseb mipsel mipsn32 ns32k pc532 pmax powerpc rs6000 s390 sh3eb sh3el sparc sparc64 vax x86_64 } for the hardware architecture part of ONLY_FOR_PLATFORM.\n")
}
func (s *Suite) TestVartypeCheck_PythonDependency(c *check.C) {