Code cleanup: converted ALL_CAPS to camelCase

This commit is contained in:
rillig 2015-12-05 10:09:00 +00:00
parent 8ded4feb55
commit de6be10b33
27 changed files with 1110 additions and 1100 deletions

View file

@ -171,6 +171,6 @@ func checkdirCategory() {
saveAutofixChanges(lines)
if G.opts.Recursive {
G.todo = append(subdirs, G.todo...)
G.todo = append(append([]string(nil), subdirs...), G.todo...)
}
}

View file

@ -10,7 +10,7 @@ func CheckDirent(fname string) {
st, err := os.Lstat(fname)
if err != nil || !st.Mode().IsDir() && !st.Mode().IsRegular() {
errorf(fname, NO_LINES, "No such file or directory.")
errorf(fname, noLines, "No such file or directory.")
return
}
isDir := st.Mode().IsDir()
@ -22,7 +22,7 @@ func CheckDirent(fname string) {
G.isInfrastructure = matches(absCurrentDir, `/mk/|/mk$`)
G.curPkgsrcdir = findPkgsrcTopdir(G.currentDir)
if G.curPkgsrcdir == "" {
errorf(fname, NO_LINES, "Cannot determine the pkgsrc root directory for %q.", G.currentDir)
errorf(fname, noLines, "Cannot determine the pkgsrc root directory for %q.", G.currentDir)
return
}
@ -42,6 +42,6 @@ func CheckDirent(fname string) {
case ".":
checkdirToplevel()
default:
errorf(fname, NO_LINES, "Cannot check directories outside a pkgsrc tree.")
errorf(fname, noLines, "Cannot check directories outside a pkgsrc tree.")
}
}

View file

@ -18,7 +18,7 @@ func checklinesDistinfo(lines []*Line) {
if G.pkgContext != nil && hasSuffix(fname, "/lang/php54/distinfo") {
patchesDir = G.curPkgsrcdir + "/lang/php54/patches"
}
_ = G.opts.DebugMisc && debugf(fname, NO_LINES, "patchesDir=%q", patchesDir)
_ = G.opts.DebugMisc && debugf(fname, noLines, "patchesDir=%q", patchesDir)
ck := &distinfoLinesChecker{
fname, patchesDir, isCommitted(fname),
@ -109,14 +109,14 @@ func (ck *distinfoLinesChecker) checkPatchSha1(line *Line, patchFname, distinfoS
func (ck *distinfoLinesChecker) checkUnrecordedPatches() {
files, err := ioutil.ReadDir(G.currentDir + "/" + ck.patchdir)
if err != nil {
_ = G.opts.DebugUnchecked && debugf(ck.distinfoFilename, NO_LINES, "Cannot read patchesDir %q: %s", ck.patchdir, err)
_ = G.opts.DebugUnchecked && debugf(ck.distinfoFilename, noLines, "Cannot read patchesDir %q: %s", ck.patchdir, err)
return
}
for _, file := range files {
patch := file.Name()
if !ck.patches[patch] {
errorf(ck.distinfoFilename, NO_LINES, "patch %q is not recorded. Run \"%s makepatchsum\".", ck.patchdir+"/"+patch, confMake)
errorf(ck.distinfoFilename, noLines, "patch %q is not recorded. Run \"%s makepatchsum\".", ck.patchdir+"/"+patch, confMake)
}
}
}

View file

@ -9,11 +9,11 @@ import (
func LoadNonemptyLines(fname string, joinContinuationLines bool) []*Line {
lines, err := readLines(fname, joinContinuationLines)
if err != nil {
errorf(fname, NO_LINES, "Cannot be read.")
errorf(fname, noLines, "Cannot be read.")
return nil
}
if len(lines) == 0 {
errorf(fname, NO_LINES, "Must not be empty.")
errorf(fname, noLines, "Must not be empty.")
return nil
}
return lines
@ -22,7 +22,7 @@ func LoadNonemptyLines(fname string, joinContinuationLines bool) []*Line {
func LoadExistingLines(fname string, foldBackslashLines bool) []*Line {
lines, err := readLines(fname, foldBackslashLines)
if lines == nil || err != nil {
fatalf(fname, NO_LINES, "Cannot be read.")
fatalf(fname, noLines, "Cannot be read.")
}
return lines
}
@ -128,14 +128,14 @@ func saveAutofixChanges(lines []*Line) {
}
err := ioutil.WriteFile(tmpname, []byte(text), 0777)
if err != nil {
errorf(tmpname, NO_LINES, "Cannot write.")
errorf(tmpname, noLines, "Cannot write.")
continue
}
err = os.Rename(tmpname, fname)
if err != nil {
errorf(fname, NO_LINES, "Cannot overwrite with auto-fixed content.")
errorf(fname, noLines, "Cannot overwrite with auto-fixed content.")
continue
}
notef(fname, NO_LINES, "Has been auto-fixed. Please re-run pkglint.")
notef(fname, noLines, "Has been auto-fixed. Please re-run pkglint.")
}
}

View file

@ -37,7 +37,8 @@ func (o *Options) Parse(args []string) (remainingArgs []string, err error) {
arg := args[i]
switch {
case arg == "--":
return append(remainingArgs, args[i+1:]...), err
remainingArgs = append(remainingArgs, args[i+1:]...)
return
case hasPrefix(arg, "--"):
skip, err = o.parseLongOption(args, i, arg[2:])
i += skip

View file

@ -90,7 +90,7 @@ func (gd *GlobalData) loadDistSites() {
names["MASTER_SITE_SUSE_UPD"] = true
names["MASTER_SITE_LOCAL"] = true
_ = G.opts.DebugMisc && debugf(fname, NO_LINES, "Loaded %d MASTER_SITE_* URLs.", len(url2name))
_ = G.opts.DebugMisc && debugf(fname, noLines, "Loaded %d MASTER_SITE_* URLs.", len(url2name))
gd.masterSiteUrls = url2name
gd.masterSiteVars = names
}
@ -123,7 +123,7 @@ func (gd *GlobalData) loadTools() {
}
}
if len(toolFiles) <= 1 {
fatalf(toolFiles[0], NO_LINES, "Too few tool files.")
fatalf(toolFiles[0], noLines, "Too few tool files.")
}
tools := make(map[string]bool)
@ -329,7 +329,7 @@ func (gd *GlobalData) loadDocChanges() {
docdir := G.globalData.pkgsrcdir + "/doc"
files, err := ioutil.ReadDir(docdir)
if err != nil {
fatalf(docdir, NO_LINES, "Cannot be read.")
fatalf(docdir, noLines, "Cannot be read.")
}
var fnames []string

View file

@ -23,7 +23,7 @@ func checktoplevelUnusedLicenses() {
licensepath := licensedir + "/" + licensename
if fileExists(licensepath) {
if !G.ipcUsedLicenses[licensename] {
warnf(licensepath, NO_LINES, "This license seems to be unused.")
warnf(licensepath, noLines, "This license seems to be unused.")
}
}
}

View file

@ -44,7 +44,7 @@ func NewLine(fname, linenos, text string, rawLines []*RawLine) *Line {
}
func (ln *Line) rawLines() []*RawLine {
return append(ln.before, append(ln.raw, ln.after...)...)
return append(append(append([]*RawLine(nil), ln.before...), ln.raw...), ln.after...)
}
func (ln *Line) printSource(out io.Writer) {

View file

@ -4,8 +4,8 @@ import (
"io"
)
const NO_FILE = ""
const NO_LINES = ""
const noFile = ""
const noLines = ""
type LogLevel struct {
traditionalName string
@ -13,17 +13,17 @@ type LogLevel struct {
}
var (
LL_FATAL = LogLevel{"FATAL", "fatal"}
LL_ERROR = LogLevel{"ERROR", "error"}
LL_WARN = LogLevel{"WARN", "warning"}
LL_NOTE = LogLevel{"NOTE", "note"}
LL_DEBUG = LogLevel{"DEBUG", "debug"}
llFatal = LogLevel{"FATAL", "fatal"}
llError = LogLevel{"ERROR", "error"}
llWarn = LogLevel{"WARN", "warning"}
llNote = LogLevel{"NOTE", "note"}
llDebug = LogLevel{"DEBUG", "debug"}
)
var dummyLine = NewLine(NO_FILE, NO_LINES, "", nil)
var dummyLine = NewLine(noFile, noLines, "", nil)
func logMessage(level LogLevel, fname, lineno, message string) {
if fname != NO_FILE {
if fname != noFile {
fname = cleanpath(fname)
}
@ -32,10 +32,10 @@ func logMessage(level LogLevel, fname, lineno, message string) {
text += sep + level.traditionalName + ":"
sep = " "
}
if fname != NO_FILE {
if fname != noFile {
text += sep + fname
sep = ": "
if lineno != NO_LINES {
if lineno != noLines {
text += ":" + lineno
}
}
@ -44,7 +44,7 @@ func logMessage(level LogLevel, fname, lineno, message string) {
sep = " "
}
text += sep + message + "\n"
if level != LL_FATAL {
if level != llFatal {
io.WriteString(G.logOut, text)
} else {
io.WriteString(G.logErr, text)
@ -53,29 +53,29 @@ func logMessage(level LogLevel, fname, lineno, message string) {
func fatalf(fname, lineno, format string, args ...interface{}) bool {
message := sprintf(format, args...)
logMessage(LL_FATAL, fname, lineno, message)
logMessage(llFatal, fname, lineno, message)
panic(pkglintFatal{})
}
func errorf(fname, lineno, format string, args ...interface{}) bool {
message := sprintf(format, args...)
logMessage(LL_ERROR, fname, lineno, message)
logMessage(llError, fname, lineno, message)
G.errors++
return true
}
func warnf(fname, lineno, format string, args ...interface{}) bool {
message := sprintf(format, args...)
logMessage(LL_WARN, fname, lineno, message)
logMessage(llWarn, fname, lineno, message)
G.warnings++
return true
}
func notef(fname, lineno, format string, args ...interface{}) bool {
message := sprintf(format, args...)
logMessage(LL_NOTE, fname, lineno, message)
logMessage(llNote, fname, lineno, message)
return true
}
func debugf(fname, lineno, format string, args ...interface{}) bool {
message := sprintf(format, args...)
logMessage(LL_DEBUG, fname, lineno, message)
logMessage(llDebug, fname, lineno, message)
return true
}

View file

@ -479,22 +479,22 @@ func ChecklinesMk(lines []*Line) {
}
// Check if any of the value's types is not guessed.
guessed := GUESSED
guessed := guGuessed
for _, value := range splitOnSpace(values) {
if m, vname := match1(value, `^\$\{(.*)\}`); m {
vartype := getVariableType(line, vname)
if vartype != nil && !vartype.guessed {
guessed = NOT_GUESSED
guessed = guNotGuessed
}
}
}
forLoopType := &Vartype{LK_SPACE, CheckvarUnchecked, []AclEntry{{"*", "pu"}}, guessed}
forLoopType := &Vartype{lkSpace, CheckvarUnchecked, []AclEntry{{"*", "pu"}}, guessed}
forLoopContext := &VarUseContext{
VUC_TIME_LOAD,
vucTimeParse,
forLoopType,
VUC_SHW_FOR,
VUC_EXT_WORD,
vucQuotFor,
vucExtentWord,
}
for _, fvar := range extractUsedVariables(line, values) {
checklineMkVaruse(line, fvar, "", forLoopContext)

View file

@ -57,7 +57,7 @@ func checklineMkVaruse(line *Line, varname string, mod string, vuc *VarUseContex
vartype := getVariableType(line, varname)
if G.opts.WarnExtra &&
(vartype == nil || vartype.guessed == GUESSED) &&
(vartype == nil || vartype.guessed == guGuessed) &&
!varIsUsed(varname) &&
(G.mkContext == nil || !G.mkContext.forVars[varname]) {
line.warnf("%s is used but not defined. Spelling mistake?", varname)
@ -73,11 +73,11 @@ func checklineMkVaruse(line *Line, varname string, mod string, vuc *VarUseContex
needsQuoting := variableNeedsQuoting(line, varname, vuc)
if vuc.shellword == VUC_SHW_FOR {
if vuc.shellword == vucQuotFor {
checklineMkVaruseFor(line, varname, vartype, needsQuoting)
}
if G.opts.WarnQuoting && vuc.shellword != VUC_SHW_UNKNOWN && needsQuoting != NQ_DONT_KNOW {
if G.opts.WarnQuoting && vuc.shellword != vucQuotUnknown && needsQuoting != nqDontKnow {
checklineMkVaruseShellword(line, varname, vartype, vuc, mod, needsQuoting)
}
@ -102,10 +102,10 @@ func checklineMkVarusePerm(line *Line, varname string, vuc *VarUseContext) {
isIndirect := false
switch {
case vuc.vartype != nil && vuc.vartype.guessed == GUESSED:
case vuc.vartype != nil && vuc.vartype.guessed == guGuessed:
// Don't warn about unknown variables.
case vuc.time == VUC_TIME_LOAD && !contains(perms, "p"):
case vuc.time == vucTimeParse && !contains(perms, "p"):
isLoadTime = true
case vuc.vartype != nil && contains(vuc.vartype.union(), "p") && !contains(perms, "p"):
@ -177,10 +177,10 @@ func checklineMkVaruseFor(line *Line, varname string, vartype *Vartype, needsQuo
case vartype == nil:
// Cannot check anything here.
case vartype.kindOfList == LK_SPACE:
case vartype.kindOfList == lkSpace:
// Fine
case needsQuoting == NQ_DOESNT_MATTER || needsQuoting == NQ_NO:
case needsQuoting == nqDoesntMatter || needsQuoting == nqNo:
// Fine, this variable is not supposed to contain special characters.
default:
@ -212,8 +212,8 @@ func checklineMkVaruseShellword(line *Line, varname string, vartype *Vartype, vu
if mod == ":M*:Q" && !needMstar {
line.notef("The :M* modifier is not needed here.")
} else if mod != correctMod && needsQuoting == NQ_YES {
if vuc.shellword == VUC_SHW_PLAIN {
} else if mod != correctMod && needsQuoting == nqYes {
if vuc.shellword == vucQuotPlain {
line.warnf("Please use ${%s%s} instead of ${%s%s}.", varname, correctMod, varname, mod)
} else {
line.warnf("Please use ${%s%s} instead of ${%s%s} and make sure the variable appears outside of any quoting characters.", varname, correctMod, varname, mod)
@ -240,10 +240,10 @@ func checklineMkVaruseShellword(line *Line, varname string, vartype *Vartype, vu
}
switch needsQuoting {
case NQ_NO:
case nqNo:
line.warnf("The :Q operator should not be used for ${%s} here.", varname)
line.explain(expl...)
case NQ_DOESNT_MATTER:
case nqDoesntMatter:
line.notef("The :Q operator isn't necessary for ${%s} here.", varname)
line.explain(expl...)
}
@ -407,18 +407,18 @@ func checklineMkVarassign(line *Line, varname, op, value, comment string) {
}
}
time := VUC_TIME_RUN
time := vucTimeRun
switch op {
case ":=", "!=":
time = VUC_TIME_LOAD
time = vucTimeParse
}
usedVars := extractUsedVariables(line, value)
vuc := &VarUseContext{
time,
getVariableType(line, varname),
VUC_SHW_UNKNOWN,
VUC_EXTENT_UNKNOWN}
vucQuotUnknown,
vucExtentUnknown}
for _, usedVar := range usedVars {
checklineMkVaruse(line, usedVar, "", vuc)
}
@ -507,12 +507,12 @@ func checklineMkVartype(line *Line, varname, op, value, comment string) {
case op == "!=":
_ = G.opts.DebugMisc && line.debugf("Use of !=: %q", value)
case vartype.kindOfList == LK_NONE:
case vartype.kindOfList == lkNone:
checklineMkVartypePrimitive(line, varname, vartype.checker, op, value, comment, vartype.isConsideredList(), vartype.guessed)
default:
var words []string
if vartype.kindOfList == LK_SPACE {
if vartype.kindOfList == lkSpace {
words = splitOnSpace(value)
} else {
words, _ = splitIntoShellwords(line, value)
@ -520,7 +520,7 @@ func checklineMkVartype(line *Line, varname, op, value, comment string) {
for _, word := range words {
checklineMkVartypePrimitive(line, varname, vartype.checker, op, word, comment, true, vartype.guessed)
if vartype.kindOfList != LK_SPACE {
if vartype.kindOfList != lkSpace {
checklineMkShellword(line, word, true)
}
}
@ -533,7 +533,7 @@ func checklineMkVartype(line *Line, varname, op, value, comment string) {
func checklineMkVartypePrimitive(line *Line, varname string, checker *VarChecker, op, value, comment string, isList bool, guessed Guessed) {
defer tracecall("checklineMkVartypePrimitive", varname, op, value, comment, isList, guessed)()
ctx := &VartypeCheck{line, varname, op, value, "", comment, isList, guessed == GUESSED}
ctx := &VartypeCheck{line, varname, op, value, "", comment, isList, guessed == guGuessed}
ctx.valueNovar = withoutMakeVariables(line, value, isList)
checker.checker(ctx)

View file

@ -11,14 +11,14 @@ func (s *Suite) TestChecklineMkVartype_SimpleType(c *check.C) {
vartype1 := G.globalData.vartypes["COMMENT"]
c.Assert(vartype1, check.NotNil)
c.Check(vartype1.guessed, equals, NOT_GUESSED)
c.Check(vartype1.guessed, equals, guNotGuessed)
vartype := getVariableType(line, "COMMENT")
c.Assert(vartype, check.NotNil)
c.Check(vartype.checker.name, equals, "Comment")
c.Check(vartype.guessed, equals, NOT_GUESSED)
c.Check(vartype.kindOfList, equals, LK_NONE)
c.Check(vartype.guessed, equals, guNotGuessed)
c.Check(vartype.kindOfList, equals, lkNone)
checklineMkVartype(line, "COMMENT", "=", "A nice package", "")

View file

@ -68,7 +68,7 @@ func checkdirPackage(pkgpath string) {
// we need to handle the Makefile first to get some variables
lines := loadPackageMakefile(G.currentDir + "/Makefile")
if lines == nil {
errorf(G.currentDir+"/Makefile", NO_LINES, "Cannot be read.")
errorf(G.currentDir+"/Makefile", noLines, "Cannot be read.")
return
}
@ -116,12 +116,12 @@ func checkdirPackage(pkgpath string) {
if G.opts.CheckDistinfo && G.opts.CheckPatches {
if havePatches && !haveDistinfo {
warnf(G.currentDir+"/"+ctx.distinfoFile, NO_LINES, "File not found. Please run \"%s makepatchsum\".", confMake)
warnf(G.currentDir+"/"+ctx.distinfoFile, noLines, "File not found. Please run \"%s makepatchsum\".", confMake)
}
}
if !isEmptyDir(G.currentDir + "/scripts") {
warnf(G.currentDir+"/scripts", NO_LINES, "This directory and its contents are deprecated! Please call the script(s) explicitly from the corresponding target(s) in the pkg's Makefile.")
warnf(G.currentDir+"/scripts", noLines, "This directory and its contents are deprecated! Please call the script(s) explicitly from the corresponding target(s) in the pkg's Makefile.")
}
}
@ -134,16 +134,16 @@ func checkfilePackageMakefile(fname string, lines []*Line) {
vardef["META_PACKAGE"] == nil &&
!fileExists(G.currentDir+"/"+G.pkgContext.pkgdir+"/PLIST") &&
!fileExists(G.currentDir+"/"+G.pkgContext.pkgdir+"/PLIST.common") {
warnf(fname, NO_LINES, "Neither PLIST nor PLIST.common exist, and PLIST_SRC is unset. Are you sure PLIST handling is ok?")
warnf(fname, noLines, "Neither PLIST nor PLIST.common exist, and PLIST_SRC is unset. Are you sure PLIST handling is ok?")
}
if (vardef["NO_CHECKSUM"] != nil || vardef["META_PACKAGE"] != nil) && isEmptyDir(G.currentDir+"/"+G.pkgContext.patchdir) {
if distinfoFile := G.currentDir + "/" + G.pkgContext.distinfoFile; fileExists(distinfoFile) {
warnf(distinfoFile, NO_LINES, "This file should not exist if NO_CHECKSUM or META_PACKAGE is set.")
warnf(distinfoFile, noLines, "This file should not exist if NO_CHECKSUM or META_PACKAGE is set.")
}
} else {
if distinfoFile := G.currentDir + "/" + G.pkgContext.distinfoFile; !containsVarRef(distinfoFile) && !fileExists(distinfoFile) {
warnf(distinfoFile, NO_LINES, "File not found. Please run \"%s makesum\".", confMake)
warnf(distinfoFile, noLines, "File not found. Please run \"%s makesum\".", confMake)
}
}
@ -153,7 +153,7 @@ func checkfilePackageMakefile(fname string, lines []*Line) {
}
if vardef["LICENSE"] == nil {
errorf(fname, NO_LINES, "Each package must define its LICENSE.")
errorf(fname, noLines, "Each package must define its LICENSE.")
}
if vardef["GNU_CONFIGURE"] != nil && vardef["USE_LANGUAGES"] != nil {
@ -208,7 +208,7 @@ func checkfilePackageMakefile(fname string, lines []*Line) {
checkpackagePossibleDowngrade()
if vardef["COMMENT"] == nil {
warnf(fname, NO_LINES, "No COMMENT given.")
warnf(fname, noLines, "No COMMENT given.")
}
if vardef["USE_IMAKE"] != nil && vardef["USE_X11"] != nil {

View file

@ -10,13 +10,13 @@ import (
type FileType int
const (
FT_SOURCE FileType = iota
FT_SHELL
FT_MAKE
FT_TEXT
FT_CONFIGURE
FT_IGNORE
FT_UNKNOWN
ftSource FileType = iota
ftShell
ftMakefile
ftText
ftConfigure
ftIgnore
ftUnknown
)
// This is used to select the proper subroutine for detecting absolute pathnames.
@ -27,24 +27,24 @@ func guessFileType(line *Line, fname string) FileType {
switch {
case matches(basename, `^I?[Mm]akefile|\.ma?k$`):
return FT_MAKE
return ftMakefile
case basename == "configure" || basename == "configure.ac":
return FT_CONFIGURE
return ftConfigure
}
switch ext {
case "m4", "sh":
return FT_SHELL
return ftShell
case "c", "cc", "cpp", "cxx", "el", "h", "hh", "hpp", "l", "pl", "pm", "py", "s", "t", "y":
return FT_SOURCE
return ftSource
case "conf", "html", "info", "man", "po", "tex", "texi", "texinfo", "txt", "xml":
return FT_TEXT
return ftText
case "":
return FT_UNKNOWN
return ftUnknown
}
_ = G.opts.DebugMisc && line.debugf("Unknown file type for %q", fname)
return FT_UNKNOWN
return ftUnknown
}
func checkwordAbsolutePathname(line *Line, word string) {
@ -136,20 +136,20 @@ const (
type PatchState string
const (
PST_OUTSIDE PatchState = "PST_OUTSIDE" // Outside of a diff
pstOutside PatchState = "pstOutside" // Outside of a diff
PST_CTX_FILE_ADD PatchState = "PST_CTX_FILE_ADD" // After the DeleteFile line of a context diff
PST_CTX_HUNK PatchState = "PST_CTX_HUNK" // After the AddFile line of a context diff
PST_CTX_HUNK_DEL PatchState = "PST_CTX_HUNK_DEL" //
PST_CTX_LINE_DEL0 PatchState = "PST_CTX_LINE_DEL0" //
PST_CTX_LINE_DEL PatchState = "PST_CTX_LINE_DEL" //
PST_CTX_LINE_ADD0 PatchState = "PST_CTX_LINE_ADD0" //
PST_CTX_LINE_ADD PatchState = "PST_CTX_LINE_ADD" //
pstCtxFileAdd PatchState = "pstCtxFileAdd" // After the DeleteFile line of a context diff
pstCtxHunk PatchState = "pstCtxHunk" // After the AddFile line of a context diff
pstCtxHunkDel PatchState = "pstCtxHunkDel" //
pstCtxLineDel0 PatchState = "pstCtxLineDel0" //
pstCtxLineDel PatchState = "pstCtxLineDel" //
pstCtxLineAdd0 PatchState = "pstCtxLineAdd0" //
pstCtxLineAdd PatchState = "pstCtxLineAdd" //
PST_UNI_FILE_DEL_ERR PatchState = "PST_UNI_FILE_DEL_ERR" // Sometimes, the DeleteFile and AddFile are reversed
PST_UNI_FILE_ADD PatchState = "PST_UNI_FILE_ADD" // After the DeleteFile line of a unified diff
PST_UNI_HUNK PatchState = "PST_UNI_HUNK" // After the AddFile line of a unified diff
PST_UNI_LINE PatchState = "PST_UNI_LINE" // After reading the hunk header
pstUniFileDelErr PatchState = "pstUniFileDelErr" // Sometimes, the DeleteFile and AddFile are reversed
pstUniFileAdd PatchState = "pstUniFileAdd" // After the DeleteFile line of a unified diff
pstUniHunk PatchState = "pstUniHunk" // After the AddFile line of a unified diff
pstUniLine PatchState = "pstUniLine" // After reading the hunk header
)
func ptNop(ctx *CheckPatchContext) {}
@ -202,27 +202,27 @@ func (ctx *CheckPatchContext) checkBeginDiff() {
}
var patchTransitions = map[PatchState][]transition{
PST_OUTSIDE: {
{rePatchEmpty, PST_OUTSIDE, (*CheckPatchContext).checkOutside},
{rePatchTextError, PST_OUTSIDE, (*CheckPatchContext).checkOutside},
{rePatchCtxFileDel, PST_CTX_FILE_ADD, func(ctx *CheckPatchContext) {
pstOutside: {
{rePatchEmpty, pstOutside, (*CheckPatchContext).checkOutside},
{rePatchTextError, pstOutside, (*CheckPatchContext).checkOutside},
{rePatchCtxFileDel, pstCtxFileAdd, func(ctx *CheckPatchContext) {
ctx.checkBeginDiff()
ctx.line.warnf("Please use unified diffs (diff -u) for patches.")
}},
{rePatchUniFileDel, PST_UNI_FILE_ADD, (*CheckPatchContext).checkBeginDiff},
{rePatchUniFileAdd, PST_UNI_FILE_DEL_ERR, ptUniFileAdd},
{rePatchNonempty, PST_OUTSIDE, (*CheckPatchContext).checkOutside},
{rePatchUniFileDel, pstUniFileAdd, (*CheckPatchContext).checkBeginDiff},
{rePatchUniFileAdd, pstUniFileDelErr, ptUniFileAdd},
{rePatchNonempty, pstOutside, (*CheckPatchContext).checkOutside},
},
PST_UNI_FILE_DEL_ERR: {
{rePatchUniFileDel, PST_UNI_HUNK, func(ctx *CheckPatchContext) {
pstUniFileDelErr: {
{rePatchUniFileDel, pstUniHunk, func(ctx *CheckPatchContext) {
ctx.line.warnf("Unified diff headers should be first ---, then +++.")
}},
{"", PST_OUTSIDE, ptNop},
{"", pstOutside, ptNop},
},
PST_CTX_FILE_ADD: {
{rePatchCtxFileAdd, PST_CTX_HUNK, func(ctx *CheckPatchContext) {
pstCtxFileAdd: {
{rePatchCtxFileAdd, pstCtxHunk, func(ctx *CheckPatchContext) {
ctx.currentFilename = ctx.m[1]
ctx.currentFiletype = new(FileType)
*ctx.currentFiletype = guessFileType(ctx.line, ctx.currentFilename)
@ -232,15 +232,15 @@ var patchTransitions = map[PatchState][]transition{
}},
},
PST_CTX_HUNK: {
{rePatchCtxHunk, PST_CTX_HUNK_DEL, func(ctx *CheckPatchContext) {
pstCtxHunk: {
{rePatchCtxHunk, pstCtxHunkDel, func(ctx *CheckPatchContext) {
ctx.hunks++
}},
{"", PST_OUTSIDE, ptNop},
{"", pstOutside, ptNop},
},
PST_CTX_HUNK_DEL: {
{rePatchCtxHunkDel, PST_CTX_LINE_DEL0, func(ctx *CheckPatchContext) {
pstCtxHunkDel: {
{rePatchCtxHunkDel, pstCtxLineDel0, func(ctx *CheckPatchContext) {
if ctx.m[2] != "" {
ctx.dellines = 1 + toInt(ctx.m[2]) - toInt(ctx.m[1])
} else {
@ -249,17 +249,17 @@ var patchTransitions = map[PatchState][]transition{
}},
},
PST_CTX_LINE_DEL0: {
{rePatchCtxLineContext, PST_CTX_LINE_DEL, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, PST_CTX_LINE_DEL0)
pstCtxLineDel0: {
{rePatchCtxLineContext, pstCtxLineDel, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, pstCtxLineDel0)
}},
{rePatchCtxLineDel, PST_CTX_LINE_DEL, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, PST_CTX_LINE_DEL0)
{rePatchCtxLineDel, pstCtxLineDel, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, pstCtxLineDel0)
}},
{rePatchCtxLineMod, PST_CTX_LINE_DEL, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, PST_CTX_LINE_DEL0)
{rePatchCtxLineMod, pstCtxLineDel, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, pstCtxLineDel0)
}},
{rePatchCtxHunkAdd, PST_CTX_LINE_ADD0, func(ctx *CheckPatchContext) {
{rePatchCtxHunkAdd, pstCtxLineAdd0, func(ctx *CheckPatchContext) {
ctx.dellines = 0
if 2 < len(ctx.m) {
ctx.addlines = 1 + toInt(ctx.m[2]) - toInt(ctx.m[1])
@ -269,59 +269,59 @@ var patchTransitions = map[PatchState][]transition{
}},
},
PST_CTX_LINE_DEL: {
{rePatchCtxLineContext, PST_CTX_LINE_DEL, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, PST_CTX_LINE_DEL0)
pstCtxLineDel: {
{rePatchCtxLineContext, pstCtxLineDel, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, pstCtxLineDel0)
}},
{rePatchCtxLineDel, PST_CTX_LINE_DEL, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, PST_CTX_LINE_DEL0)
{rePatchCtxLineDel, pstCtxLineDel, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, pstCtxLineDel0)
}},
{rePatchCtxLineMod, PST_CTX_LINE_DEL, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, PST_CTX_LINE_DEL0)
{rePatchCtxLineMod, pstCtxLineDel, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, pstCtxLineDel0)
}},
{"", PST_CTX_LINE_DEL0, func(ctx *CheckPatchContext) {
{"", pstCtxLineDel0, func(ctx *CheckPatchContext) {
if ctx.dellines != 0 {
ctx.line.warnf("Invalid number of deleted lines (%d missing).", ctx.dellines)
}
}},
},
PST_CTX_LINE_ADD0: {
{rePatchCtxLineContext, PST_CTX_LINE_ADD, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, PST_CTX_HUNK)
pstCtxLineAdd0: {
{rePatchCtxLineContext, pstCtxLineAdd, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, pstCtxHunk)
}},
{rePatchCtxLineMod, PST_CTX_LINE_ADD, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, PST_CTX_HUNK)
{rePatchCtxLineMod, pstCtxLineAdd, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, pstCtxHunk)
}},
{rePatchCtxLineAdd, PST_CTX_LINE_ADD, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, PST_CTX_HUNK)
{rePatchCtxLineAdd, pstCtxLineAdd, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, pstCtxHunk)
}},
{"", PST_CTX_HUNK, ptNop},
{"", pstCtxHunk, ptNop},
},
PST_CTX_LINE_ADD: {
{rePatchCtxLineContext, PST_CTX_LINE_ADD, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, PST_CTX_HUNK)
pstCtxLineAdd: {
{rePatchCtxLineContext, pstCtxLineAdd, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, pstCtxHunk)
}},
{rePatchCtxLineMod, PST_CTX_LINE_ADD, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, PST_CTX_HUNK)
{rePatchCtxLineMod, pstCtxLineAdd, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, pstCtxHunk)
}},
{rePatchCtxLineAdd, PST_CTX_LINE_ADD, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, PST_CTX_HUNK)
{rePatchCtxLineAdd, pstCtxLineAdd, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, pstCtxHunk)
}},
{"", PST_CTX_LINE_ADD0, func(ctx *CheckPatchContext) {
{"", pstCtxLineAdd0, func(ctx *CheckPatchContext) {
if ctx.addlines != 0 {
ctx.line.warnf("Invalid number of added lines (%d missing).", ctx.addlines)
}
}},
},
PST_UNI_FILE_ADD: {
{rePatchUniFileAdd, PST_UNI_HUNK, ptUniFileAdd},
pstUniFileAdd: {
{rePatchUniFileAdd, pstUniHunk, ptUniFileAdd},
},
PST_UNI_HUNK: {
{rePatchUniHunk, PST_UNI_LINE, func(ctx *CheckPatchContext) {
pstUniHunk: {
{rePatchUniHunk, pstUniLine, func(ctx *CheckPatchContext) {
m := ctx.m
if m[1] != "" {
ctx.dellines = toInt(m[2])
@ -350,33 +350,33 @@ var patchTransitions = map[PatchState][]transition{
ctx.leadingContextLines = 0
ctx.trailingContextLines = 0
}},
{"", PST_OUTSIDE, func(ctx *CheckPatchContext) {
{"", pstOutside, func(ctx *CheckPatchContext) {
if ctx.hunks == 0 {
ctx.line.warnf("No hunks for file %q.", ctx.currentFilename)
}
}},
},
PST_UNI_LINE: {
{rePatchUniLineDel, PST_UNI_LINE, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, PST_UNI_HUNK)
pstUniLine: {
{rePatchUniLineDel, pstUniLine, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 0, pstUniHunk)
}},
{rePatchUniLineAdd, PST_UNI_LINE, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, PST_UNI_HUNK)
{rePatchUniLineAdd, pstUniLine, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(0, 1, pstUniHunk)
}},
{rePatchUniLineContext, PST_UNI_LINE, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 1, PST_UNI_HUNK)
{rePatchUniLineContext, pstUniLine, func(ctx *CheckPatchContext) {
ctx.checkHunkLine(1, 1, pstUniHunk)
}},
{rePatchUniLineNoNewline, PST_UNI_LINE, func(ctx *CheckPatchContext) {
{rePatchUniLineNoNewline, pstUniLine, func(ctx *CheckPatchContext) {
}},
{rePatchEmpty, PST_UNI_LINE, func(ctx *CheckPatchContext) {
{rePatchEmpty, pstUniLine, func(ctx *CheckPatchContext) {
if G.opts.WarnSpace {
ctx.line.notef("Leading white-space missing in hunk.")
ctx.line.replaceRegex(`^`, " ")
}
ctx.checkHunkLine(1, 1, PST_UNI_HUNK)
ctx.checkHunkLine(1, 1, pstUniHunk)
}},
{"", PST_UNI_HUNK, func(ctx *CheckPatchContext) {
{"", pstUniHunk, func(ctx *CheckPatchContext) {
if ctx.dellines != 0 || ctx.addlines != 0 {
ctx.line.warnf("Unexpected end of hunk (-%d,+%d expected).", ctx.dellines, ctx.addlines)
}
@ -389,7 +389,7 @@ func checklinesPatch(lines []*Line) {
checklineRcsid(lines[0], ``, "")
ctx := CheckPatchContext{state: PST_OUTSIDE, needEmptyLineNow: true}
ctx := CheckPatchContext{state: pstOutside, needEmptyLineNow: true}
for lineno := 1; lineno < len(lines); {
line := lines[lineno]
text := line.text
@ -424,13 +424,13 @@ func checklinesPatch(lines []*Line) {
if !found {
ctx.line.errorf("Internal pkglint error: checklinesPatch state=%s", ctx.state)
ctx.state = PST_OUTSIDE
ctx.state = pstOutside
lineno++
}
}
fname := lines[0].fname
for ctx.state != PST_OUTSIDE {
for ctx.state != pstOutside {
_ = G.opts.DebugPatches &&
debugf(fname, "EOF", "state=%s hunks=%d del=%d add=%d",
ctx.state, ctx.hunks, ctx.dellines, ctx.addlines)
@ -458,9 +458,9 @@ func checklinesPatch(lines []*Line) {
}
if ctx.patchedFiles > 1 {
warnf(fname, NO_LINES, "Contains patches for %d files, should be only one.", ctx.patchedFiles)
warnf(fname, noLines, "Contains patches for %d files, should be only one.", ctx.patchedFiles)
} else if ctx.patchedFiles == 0 {
errorf(fname, NO_LINES, "Contains no patch.")
errorf(fname, noLines, "Contains no patch.")
}
checklinesTrailingEmptyLines(lines)
@ -523,8 +523,8 @@ func (ctx *CheckPatchContext) checkAddedContents() {
addedText := ctx.m[1]
switch *ctx.currentFiletype {
case FT_SHELL:
case FT_MAKE:
case ftShell:
case ftMakefile:
// This check is not as accurate as the similar one in checklineMkShelltext.
shellwords, _ := splitIntoShellwords(line, addedText)
for _, shellword := range shellwords {
@ -532,9 +532,9 @@ func (ctx *CheckPatchContext) checkAddedContents() {
checklineMkAbsolutePathname(line, shellword)
}
}
case FT_SOURCE:
case ftSource:
checklineSourceAbsolutePathname(line, addedText)
case FT_CONFIGURE:
case ftConfigure:
if matches(addedText, `: Avoid regenerating within pkgsrc$`) {
line.errorf("This code must not be included in patches.")
line.explain(
@ -543,7 +543,7 @@ func (ctx *CheckPatchContext) checkAddedContents() {
"For more details, look for \"configure-scripts-override\" in",
"mk/configure/gnu-configure.mk.")
}
case FT_IGNORE:
case ftIgnore:
break
default:
checklineOtherAbsolutePathname(line, addedText)

View file

@ -42,12 +42,12 @@ func loadPackageMakefile(fname string) []*Line {
var mainLines, allLines []*Line
if !readMakefile(fname, &mainLines, &allLines) {
errorf(fname, NO_LINES, "Cannot be read.")
errorf(fname, noLines, "Cannot be read.")
return nil
}
if G.opts.DumpMakefile {
debugf(G.currentDir, NO_LINES, "Whole Makefile (with all included files) follows:")
debugf(G.currentDir, noLines, "Whole Makefile (with all included files) follows:")
for _, line := range allLines {
fmt.Printf("%s\n", line.String())
}
@ -128,11 +128,11 @@ func getVariableType(line *Line, varname string) *Vartype {
}
if G.globalData.varnameToToolname[varname] != "" {
return &Vartype{LK_NONE, CheckvarShellCommand, []AclEntry{{"*", "u"}}, NOT_GUESSED}
return &Vartype{lkNone, CheckvarShellCommand, []AclEntry{{"*", "u"}}, guNotGuessed}
}
if m, toolvarname := match1(varname, `^TOOLS_(.*)`); m && G.globalData.varnameToToolname[toolvarname] != "" {
return &Vartype{LK_NONE, CheckvarPathname, []AclEntry{{"*", "u"}}, NOT_GUESSED}
return &Vartype{lkNone, CheckvarPathname, []AclEntry{{"*", "u"}}, guNotGuessed}
}
allowAll := []AclEntry{{"*", "adpsu"}}
@ -142,33 +142,33 @@ func getVariableType(line *Line, varname string) *Vartype {
var gtype *Vartype
switch {
case hasSuffix(varname, "DIRS"):
gtype = &Vartype{LK_SHELL, CheckvarPathmask, allowRuntime, GUESSED}
gtype = &Vartype{lkShell, CheckvarPathmask, allowRuntime, guGuessed}
case hasSuffix(varname, "DIR"), hasSuffix(varname, "_HOME"):
gtype = &Vartype{LK_NONE, CheckvarPathname, allowRuntime, GUESSED}
gtype = &Vartype{lkNone, CheckvarPathname, allowRuntime, guGuessed}
case hasSuffix(varname, "FILES"):
gtype = &Vartype{LK_SHELL, CheckvarPathmask, allowRuntime, GUESSED}
gtype = &Vartype{lkShell, CheckvarPathmask, allowRuntime, guGuessed}
case hasSuffix(varname, "FILE"):
gtype = &Vartype{LK_NONE, CheckvarPathname, allowRuntime, GUESSED}
gtype = &Vartype{lkNone, CheckvarPathname, allowRuntime, guGuessed}
case hasSuffix(varname, "PATH"):
gtype = &Vartype{LK_NONE, CheckvarPathlist, allowRuntime, GUESSED}
gtype = &Vartype{lkNone, CheckvarPathlist, allowRuntime, guGuessed}
case hasSuffix(varname, "PATHS"):
gtype = &Vartype{LK_SHELL, CheckvarPathname, allowRuntime, GUESSED}
gtype = &Vartype{lkShell, CheckvarPathname, allowRuntime, guGuessed}
case hasSuffix(varname, "_USER"):
gtype = &Vartype{LK_NONE, CheckvarUserGroupName, allowAll, GUESSED}
gtype = &Vartype{lkNone, CheckvarUserGroupName, allowAll, guGuessed}
case hasSuffix(varname, "_GROUP"):
gtype = &Vartype{LK_NONE, CheckvarUserGroupName, allowAll, GUESSED}
gtype = &Vartype{lkNone, CheckvarUserGroupName, allowAll, guGuessed}
case hasSuffix(varname, "_ENV"):
gtype = &Vartype{LK_SHELL, CheckvarShellWord, allowRuntime, GUESSED}
gtype = &Vartype{lkShell, CheckvarShellWord, allowRuntime, guGuessed}
case hasSuffix(varname, "_CMD"):
gtype = &Vartype{LK_NONE, CheckvarShellCommand, allowRuntime, GUESSED}
gtype = &Vartype{lkNone, CheckvarShellCommand, allowRuntime, guGuessed}
case hasSuffix(varname, "_ARGS"):
gtype = &Vartype{LK_SHELL, CheckvarShellWord, allowRuntime, GUESSED}
gtype = &Vartype{lkShell, CheckvarShellWord, allowRuntime, guGuessed}
case hasSuffix(varname, "_CFLAGS"), hasSuffix(varname, "_CPPFLAGS"), hasSuffix(varname, "_CXXFLAGS"), hasSuffix(varname, "_LDFLAGS"):
gtype = &Vartype{LK_SHELL, CheckvarShellWord, allowRuntime, GUESSED}
gtype = &Vartype{lkShell, CheckvarShellWord, allowRuntime, guGuessed}
case hasSuffix(varname, "_MK"):
gtype = &Vartype{LK_NONE, CheckvarUnchecked, allowAll, GUESSED}
gtype = &Vartype{lkNone, CheckvarUnchecked, allowAll, guGuessed}
case hasPrefix(varname, "PLIST."):
gtype = &Vartype{LK_NONE, CheckvarYes, allowAll, GUESSED}
gtype = &Vartype{lkNone, CheckvarYes, allowAll, guGuessed}
}
if gtype != nil {
@ -425,19 +425,19 @@ func checkfile(fname string) {
basename := path.Base(fname)
if matches(basename, `^(?:work.*|.*~|.*\.orig|.*\.rej)$`) {
if G.opts.Import {
errorf(fname, NO_LINES, "Must be cleaned up before committing the package.")
errorf(fname, noLines, "Must be cleaned up before committing the package.")
}
return
}
st, err := os.Lstat(fname)
if err != nil {
errorf(fname, NO_LINES, "%s", err)
errorf(fname, noLines, "%s", err)
return
}
if st.Mode().IsRegular() && st.Mode().Perm()&0111 != 0 && !isCommitted(fname) {
line := NewLine(fname, NO_LINES, "", nil)
line := NewLine(fname, noLines, "", nil)
line.warnf("Should not be executable.")
line.explain(
"No package file should ever be executable. Even the INSTALL and",
@ -454,16 +454,16 @@ func checkfile(fname string) {
case matches(fname, `(?:^|/)files/[^/]*$`):
// Ok
case !isEmptyDir(fname):
warnf(fname, NO_LINES, "Unknown directory name.")
warnf(fname, noLines, "Unknown directory name.")
}
case st.Mode()&os.ModeSymlink != 0:
if !matches(basename, `^work`) {
warnf(fname, NO_LINES, "Unknown symlink name.")
warnf(fname, noLines, "Unknown symlink name.")
}
case !st.Mode().IsRegular():
errorf(fname, NO_LINES, "Only files and directories are allowed in pkgsrc.")
errorf(fname, noLines, "Only files and directories are allowed in pkgsrc.")
case basename == "ALTERNATIVES":
if G.opts.CheckAlternatives {
@ -512,11 +512,11 @@ func checkfile(fname string) {
case matches(fname, `(?:^|/)patches/manual[^/]*$`):
if G.opts.DebugUnchecked {
debugf(fname, NO_LINES, "Unchecked file %q.", fname)
debugf(fname, noLines, "Unchecked file %q.", fname)
}
case matches(fname, `(?:^|/)patches/[^/]*$`):
warnf(fname, NO_LINES, "Patch files should be named \"patch-\", followed by letters, '-', '_', '.', and digits only.")
warnf(fname, noLines, "Patch files should be named \"patch-\", followed by letters, '-', '_', '.', and digits only.")
case matches(basename, `^(?:.*\.mk|Makefile.*)$`) && !matches(fname, `files/`) && !matches(fname, `patches/`):
if G.opts.CheckMk {
@ -541,7 +541,7 @@ func checkfile(fname string) {
// Skip
default:
warnf(fname, NO_LINES, "Unexpected file found.")
warnf(fname, noLines, "Unexpected file found.")
if G.opts.CheckExtra {
checkfileExtra(fname)
}

View file

@ -43,7 +43,7 @@ func checklinesPlist(lines []*Line) {
}
// Collect all files and directories that appear in the PLIST file.
for _, line := range append(extraLines, lines...) {
for _, line := range append(append([]*Line(nil), extraLines...), lines...) {
text := line.text
if hasPrefix(text, "${") {

View file

@ -59,29 +59,29 @@ const (
type scState string
const (
SCST_START scState = "start"
SCST_CONT scState = "continuation"
SCST_INSTALL scState = "install"
SCST_INSTALL_D scState = "install -d"
SCST_MKDIR scState = "mkdir"
SCST_PAX scState = "pax"
SCST_PAX_S scState = "pax -s"
SCST_SED scState = "sed"
SCST_SED_E scState = "sed -e"
SCST_SET scState = "set"
SCST_SET_CONT scState = "set-continuation"
SCST_COND scState = "cond"
SCST_COND_CONT scState = "cond-continuation"
SCST_CASE scState = "case"
SCST_CASE_IN scState = "case in"
SCST_CASE_LABEL scState = "case label"
SCST_CASE_LABEL_CONT scState = "case-label-continuation"
SCST_FOR scState = "for"
SCST_FOR_IN scState = "for-in"
SCST_FOR_CONT scState = "for-continuation"
SCST_ECHO scState = "echo"
SCST_INSTALL_DIR scState = "install-dir"
SCST_INSTALL_DIR2 scState = "install-dir2"
scstStart scState = "start"
scstCont scState = "continuation"
scstInstall scState = "install"
scstInstallD scState = "install -d"
scstMkdir scState = "mkdir"
scstPax scState = "pax"
scstPaxS scState = "pax -s"
scstSed scState = "sed"
scstSedE scState = "sed -e"
scstSet scState = "set"
scstSetCont scState = "set-continuation"
scstCond scState = "cond"
scstCondCont scState = "cond-continuation"
scstCase scState = "case"
scstCaseIn scState = "case in"
scstCaseLabel scState = "case label"
scstCaseLabelCont scState = "case-label-continuation"
scstFor scState = "for"
scstForIn scState = "for-in"
scstForCont scState = "for-continuation"
scstEcho scState = "echo"
scstInstallDir scState = "install-dir"
scstInstallDir2 scState = "install-dir2"
)
type MkShellLine struct {
@ -99,8 +99,8 @@ func (msline *MkShellLine) checklineMkShellword(shellword string, checkQuoting b
return
}
shellcommandContextType := &Vartype{LK_NONE, CheckvarShellCommand, []AclEntry{{"*", "adsu"}}, NOT_GUESSED}
shellwordVuc := &VarUseContext{VUC_TIME_UNKNOWN, shellcommandContextType, VUC_SHW_PLAIN, VUC_EXT_WORD}
shellcommandContextType := &Vartype{lkNone, CheckvarShellCommand, []AclEntry{{"*", "adsu"}}, guNotGuessed}
shellwordVuc := &VarUseContext{vucTimeUnknown, shellcommandContextType, vucQuotPlain, vucExtentWord}
line := msline.line
if m, varname, mod := match2(shellword, `^\$\{(`+reVarnameDirect+`)(:[^{}]+)?\}$`); m {
@ -117,15 +117,15 @@ func (msline *MkShellLine) checklineMkShellword(shellword string, checkQuoting b
type ShellwordState string
const (
SWST_PLAIN ShellwordState = "plain"
SWST_SQUOT ShellwordState = "squot"
SWST_DQUOT ShellwordState = "dquot"
SWST_DQUOT_BACKT ShellwordState = "dquot+backt"
SWST_BACKT ShellwordState = "backt"
swstPlain ShellwordState = "plain"
swstSquot ShellwordState = "squot"
swstDquot ShellwordState = "dquot"
swstDquotBackt ShellwordState = "dquot+backt"
swstBackt ShellwordState = "backt"
)
rest := shellword
state := SWST_PLAIN
state := swstPlain
outer:
for rest != "" {
_ = G.opts.DebugShell && line.debugf("shell state %s: %q", state, rest)
@ -136,7 +136,7 @@ outer:
// reasonable to check the whole shell command
// recursively, instead of splitting off the first
// make(1) variable.
case state == SWST_BACKT || state == SWST_DQUOT_BACKT:
case state == swstBackt || state == swstDquotBackt:
// Scan for the end of the backticks, checking
// for single backslashes and removing one level
// of backslashes. Backslashes are only removed
@ -148,10 +148,10 @@ outer:
for rest != "" {
switch {
case replacePrefix(&rest, &m, "^`"):
if state == SWST_BACKT {
state = SWST_PLAIN
if state == swstBackt {
state = swstPlain
} else {
state = SWST_DQUOT
state = swstDquot
}
goto endOfBackticks
@ -162,7 +162,7 @@ outer:
line.warnf("Backslashes should be doubled inside backticks.")
stripped += m[1]
case state == SWST_DQUOT_BACKT && replacePrefix(&rest, &m, `^"`):
case state == swstDquotBackt && replacePrefix(&rest, &m, `^"`):
line.warnf("Double quotes inside backticks inside double quotes are error prone.")
line.explain(
"According to the SUSv3, they produce undefined results.",
@ -197,13 +197,13 @@ outer:
}
switch {
case state == SWST_PLAIN && hasSuffix(mod, ":Q"):
case state == swstPlain && hasSuffix(mod, ":Q"):
// Fine.
case state == SWST_BACKT:
case state == swstBackt:
// Don't check anything here, to avoid false positives for tool names.
case (state == SWST_SQUOT || state == SWST_DQUOT) && matches(varname, `^(?:.*DIR|.*FILE|.*PATH|.*_VAR|PREFIX|.*BASE|PKGNAME)$`):
case (state == swstSquot || state == swstDquot) && matches(varname, `^(?:.*DIR|.*FILE|.*PATH|.*_VAR|PREFIX|.*BASE|PKGNAME)$`):
// This is ok if we don't allow these variables to have embedded [\$\\\"\'\`].
case state == SWST_DQUOT && hasSuffix(mod, ":Q"):
case state == swstDquot && hasSuffix(mod, ":Q"):
line.warnf("Please don't use the :Q operator in double quotes.")
line.explain(
"Either remove the :Q or the double quotes. In most cases, it is more",
@ -211,18 +211,18 @@ outer:
}
if varname != "@" {
vucstate := VUC_SHW_UNKNOWN
vucstate := vucQuotUnknown
switch state {
case SWST_PLAIN:
vucstate = VUC_SHW_PLAIN
case SWST_DQUOT:
vucstate = VUC_SHW_DQUOT
case SWST_SQUOT:
vucstate = VUC_SHW_SQUOT
case SWST_BACKT:
vucstate = VUC_SHW_BACKT
case swstPlain:
vucstate = vucQuotPlain
case swstDquot:
vucstate = vucQuotDquot
case swstSquot:
vucstate = vucQuotSquot
case swstBackt:
vucstate = vucQuotBackt
}
vuc := &VarUseContext{VUC_TIME_UNKNOWN, shellcommandContextType, vucstate, VUC_EXT_WORDPART}
vuc := &VarUseContext{vucTimeUnknown, shellcommandContextType, vucstate, vucExtentWordpart}
checklineMkVaruse(line, varname, mod, vuc)
}
@ -245,16 +245,16 @@ outer:
}
}
case state == SWST_PLAIN:
case state == swstPlain:
switch {
case replacePrefix(&rest, &m, `^[!#\%&\(\)*+,\-.\/0-9:;<=>?@A-Z\[\]^_a-z{|}~]+`),
replacePrefix(&rest, &m, `^\\(?:[ !"#'\(\)*;?\\^{|}]|\$\$)`):
case replacePrefix(&rest, &m, `^'`):
state = SWST_SQUOT
state = swstSquot
case replacePrefix(&rest, &m, `^"`):
state = SWST_DQUOT
state = swstDquot
case replacePrefix(&rest, &m, "^`"):
state = SWST_BACKT
state = swstBackt
case replacePrefix(&rest, &m, `^\$\$([0-9A-Z_a-z]+|\#)`),
replacePrefix(&rest, &m, `^\$\$\{([0-9A-Z_a-z]+|\#)\}`),
replacePrefix(&rest, &m, `^\$\$(\$)\$`):
@ -297,10 +297,10 @@ outer:
break outer
}
case state == SWST_SQUOT:
case state == swstSquot:
switch {
case replacePrefix(&rest, &m, `^'`):
state = SWST_PLAIN
state = swstPlain
case replacePrefix(&rest, &m, `^[^\$\']+`):
// just skip
case replacePrefix(&rest, &m, `^\$\$`):
@ -309,12 +309,12 @@ outer:
break outer
}
case state == SWST_DQUOT:
case state == swstDquot:
switch {
case replacePrefix(&rest, &m, `^"`):
state = SWST_PLAIN
state = swstPlain
case replacePrefix(&rest, &m, "^`"):
state = SWST_DQUOT_BACKT
state = swstDquotBackt
case replacePrefix(&rest, &m, "^[^$\"\\\\`]+"):
// just skip
case replacePrefix(&rest, &m, "^\\\\(?:[\\\\\"`]|\\$\\$)"):
@ -392,24 +392,24 @@ func (msline *MkShellLine) checklineMkShelltext(shelltext string) {
msline.checkLineStart(hidden, macro, rest, &setE)
}
state := SCST_START
state := scstStart
for replacePrefix(&rest, &m, reShellword) {
shellword := m[1]
_ = G.opts.DebugShell && line.debugf("checklineMkShelltext state=%v shellword=%q", state, shellword)
{
quotingNecessary := state != SCST_CASE &&
state != SCST_FOR_CONT &&
state != SCST_SET_CONT &&
!(state == SCST_START && matches(shellword, reShVarassign))
quotingNecessary := state != scstCase &&
state != scstForCont &&
state != scstSetCont &&
!(state == scstStart && matches(shellword, reShVarassign))
msline.checklineMkShellword(shellword, quotingNecessary)
}
st := &ShelltextContext{line, state, shellword}
st.checkCommandStart()
st.checkConditionalCd()
if state != SCST_PAX_S && state != SCST_SED_E && state != SCST_CASE_LABEL {
if state != scstPaxS && state != scstSedE && state != scstCaseLabel {
checklineMkAbsolutePathname(line, shellword)
}
st.checkAutoMkdirs()
@ -420,7 +420,7 @@ func (msline *MkShellLine) checklineMkShelltext(shelltext string) {
st.checkPipeExitcode()
st.checkSetE(setE)
if state == SCST_SET && matches(shellword, `^-.*e`) || state == SCST_START && shellword == "${RUN}" {
if state == scstSet && matches(shellword, `^-.*e`) || state == scstStart && shellword == "${RUN}" {
setE = true
}
@ -485,7 +485,7 @@ func (ctx *ShelltextContext) checkCommandStart() {
defer tracecall("ShelltextContext.checkCommandStart", ctx.state, ctx.shellword)()
line, state, shellword := ctx.line, ctx.state, ctx.shellword
if state != SCST_START && state != SCST_COND {
if state != scstStart && state != scstCond {
return
}
@ -608,7 +608,7 @@ func (ctx *ShelltextContext) handleComment() bool {
func (ctx *ShelltextContext) checkConditionalCd() {
line, state, shellword := ctx.line, ctx.state, ctx.shellword
if state == SCST_COND && shellword == "cd" {
if state == scstCond && shellword == "cd" {
line.errorf("The Solaris /bin/sh cannot handle \"cd\" inside conditionals.")
line.explain(
"When the Solaris shell is in \"set -e\" mode and \"cd\" fails, the",
@ -620,9 +620,9 @@ func (ctx *ShelltextContext) checkConditionalCd() {
func (ctx *ShelltextContext) checkAutoMkdirs() {
line, state, shellword := ctx.line, ctx.state, ctx.shellword
if (state == SCST_INSTALL_D || state == SCST_MKDIR) && matches(shellword, `^(?:\$\{DESTDIR\})?\$\{PREFIX(?:|:Q)\}/`) {
if (state == scstInstallD || state == scstMkdir) && matches(shellword, `^(?:\$\{DESTDIR\})?\$\{PREFIX(?:|:Q)\}/`) {
line.warnf("Please use AUTO_MKDIRS instead of %q.",
ifelseStr(state == SCST_MKDIR, "${MKDIR}", "${INSTALL} -d"))
ifelseStr(state == scstMkdir, "${MKDIR}", "${INSTALL} -d"))
line.explain(
"Setting AUTO_MKDIRS=yes automatically creates all directories that are",
"mentioned in the PLIST. If you need additional directories, specify",
@ -630,7 +630,7 @@ func (ctx *ShelltextContext) checkAutoMkdirs() {
"${PREFIX}.")
}
if (state == SCST_INSTALL_DIR || state == SCST_INSTALL_DIR2) && !matches(shellword, reMkShellvaruse) {
if (state == scstInstallDir || state == scstInstallDir2) && !matches(shellword, reMkShellvaruse) {
if m, dirname := match1(shellword, `^(?:\$\{DESTDIR\})?\$\{PREFIX(?:|:Q)\}/(.*)`); m {
line.notef("You can use AUTO_MKDIRS=yes or \"INSTALLATION_DIRS+= %s\" instead of this command.", dirname)
line.explain(
@ -650,7 +650,7 @@ func (ctx *ShelltextContext) checkAutoMkdirs() {
func (ctx *ShelltextContext) checkInstallMulti() {
line, state, shellword := ctx.line, ctx.state, ctx.shellword
if state == SCST_INSTALL_DIR2 && hasPrefix(shellword, "$") {
if state == scstInstallDir2 && hasPrefix(shellword, "$") {
line.warnf("The INSTALL_*_DIR commands can only handle one directory at a time.")
line.explain(
"Many implementations of install(1) can handle more, but pkgsrc aims at",
@ -661,7 +661,7 @@ func (ctx *ShelltextContext) checkInstallMulti() {
func (ctx *ShelltextContext) checkPaxPe() {
line, state, shellword := ctx.line, ctx.state, ctx.shellword
if state == SCST_PAX && shellword == "-pe" {
if state == scstPax && shellword == "-pe" {
line.warnf("Please use the -pp option to pax(1) instead of -pe.")
line.explain(
"The -pe option tells pax to preserve the ownership of the files, which",
@ -673,7 +673,7 @@ func (ctx *ShelltextContext) checkPaxPe() {
func (ctx *ShelltextContext) checkQuoteSubstitution() {
line, state, shellword := ctx.line, ctx.state, ctx.shellword
if state == SCST_PAX_S || state == SCST_SED_E {
if state == scstPaxS || state == scstSedE {
if false && !matches(shellword, `"^[\"\'].*[\"\']$`) {
line.warnf("Substitution commands like %q should always be quoted.", shellword)
line.explain(
@ -687,7 +687,7 @@ func (ctx *ShelltextContext) checkQuoteSubstitution() {
func (ctx *ShelltextContext) checkEchoN() {
line, state, shellword := ctx.line, ctx.state, ctx.shellword
if state == SCST_ECHO && shellword == "-n" {
if state == scstEcho && shellword == "-n" {
line.warnf("Please use ${ECHO_N} instead of \"echo -n\".")
}
}
@ -695,7 +695,7 @@ func (ctx *ShelltextContext) checkEchoN() {
func (ctx *ShelltextContext) checkPipeExitcode() {
line, state, shellword := ctx.line, ctx.state, ctx.shellword
if G.opts.WarnExtra && state != SCST_CASE_LABEL_CONT && shellword == "|" {
if G.opts.WarnExtra && state != scstCaseLabelCont && shellword == "|" {
line.warnf("The exitcode of the left-hand-side command of the pipe operator is ignored.")
line.explain(
"In a shell command like \"cat *.txt | grep keyword\", if the command",
@ -709,7 +709,7 @@ func (ctx *ShelltextContext) checkPipeExitcode() {
func (ctx *ShelltextContext) checkSetE(eflag bool) {
line, state, shellword := ctx.line, ctx.state, ctx.shellword
if G.opts.WarnExtra && shellword == ";" && state != SCST_COND_CONT && state != SCST_FOR_CONT && !eflag {
if G.opts.WarnExtra && shellword == ";" && state != scstCondCont && state != scstForCont && !eflag {
line.warnf("Please switch to \"set -e\" mode before using a semicolon to separate commands.")
line.explain(
"Older versions of the NetBSD make(1) had run the shell commands using",
@ -768,105 +768,105 @@ func (msline *MkShellLine) checkCommandUse(shellcmd string) {
func nextState(line *Line, state scState, shellword string) scState {
switch {
case shellword == ";;":
return SCST_CASE_LABEL
case state == SCST_CASE_LABEL_CONT && shellword == "|":
return SCST_CASE_LABEL
return scstCaseLabel
case state == scstCaseLabelCont && shellword == "|":
return scstCaseLabel
case matches(shellword, `^[;&\|]+$`):
return SCST_START
case state == SCST_START:
return scstStart
case state == scstStart:
switch shellword {
case "${INSTALL}":
return SCST_INSTALL
return scstInstall
case "${MKDIR}":
return SCST_MKDIR
return scstMkdir
case "${PAX}":
return SCST_PAX
return scstPax
case "${SED}":
return SCST_SED
return scstSed
case "${ECHO}", "echo":
return SCST_ECHO
return scstEcho
case "${RUN}", "then", "else", "do", "(":
return SCST_START
return scstStart
case "set":
return SCST_SET
return scstSet
case "if", "elif", "while":
return SCST_COND
return scstCond
case "case":
return SCST_CASE
return scstCase
case "for":
return SCST_FOR
return scstFor
default:
switch {
case matches(shellword, `^\$\{INSTALL_[A-Z]+_DIR\}$`):
return SCST_INSTALL_DIR
return scstInstallDir
case matches(shellword, reShVarassign):
return SCST_START
return scstStart
default:
return SCST_CONT
return scstCont
}
}
case state == SCST_MKDIR:
return SCST_MKDIR
case state == SCST_INSTALL && shellword == "-d":
return SCST_INSTALL_D
case state == SCST_INSTALL, state == SCST_INSTALL_D:
case state == scstMkdir:
return scstMkdir
case state == scstInstall && shellword == "-d":
return scstInstallD
case state == scstInstall, state == scstInstallD:
if matches(shellword, `^-[ogm]$`) {
return SCST_CONT // XXX: why not keep the state?
return scstCont // XXX: why not keep the state?
}
return state
case state == SCST_INSTALL_DIR && hasPrefix(shellword, "-"):
return SCST_CONT
case state == SCST_INSTALL_DIR && hasPrefix(shellword, "$"):
return SCST_INSTALL_DIR2
case state == SCST_INSTALL_DIR || state == SCST_INSTALL_DIR2:
case state == scstInstallDir && hasPrefix(shellword, "-"):
return scstCont
case state == scstInstallDir && hasPrefix(shellword, "$"):
return scstInstallDir2
case state == scstInstallDir || state == scstInstallDir2:
return state
case state == SCST_PAX && shellword == "-s":
return SCST_PAX_S
case state == SCST_PAX && hasPrefix(shellword, "-"):
return SCST_PAX
case state == SCST_PAX:
return SCST_CONT
case state == SCST_PAX_S:
return SCST_PAX
case state == SCST_SED && shellword == "-e":
return SCST_SED_E
case state == SCST_SED && hasPrefix(shellword, "-"):
return SCST_SED
case state == SCST_SED:
return SCST_CONT
case state == SCST_SED_E:
return SCST_SED
case state == SCST_SET:
return SCST_SET_CONT
case state == SCST_SET_CONT:
return SCST_SET_CONT
case state == SCST_CASE:
return SCST_CASE_IN
case state == SCST_CASE_IN && shellword == "in":
return SCST_CASE_LABEL
case state == SCST_CASE_LABEL && shellword == "esac":
return SCST_CONT
case state == SCST_CASE_LABEL:
return SCST_CASE_LABEL_CONT
case state == SCST_CASE_LABEL_CONT && shellword == ")":
return SCST_START
case state == SCST_CONT:
return SCST_CONT
case state == SCST_COND:
return SCST_COND_CONT
case state == SCST_COND_CONT:
return SCST_COND_CONT
case state == SCST_FOR:
return SCST_FOR_IN
case state == SCST_FOR_IN && shellword == "in":
return SCST_FOR_CONT
case state == SCST_FOR_CONT:
return SCST_FOR_CONT
case state == SCST_ECHO:
return SCST_CONT
case state == scstPax && shellword == "-s":
return scstPaxS
case state == scstPax && hasPrefix(shellword, "-"):
return scstPax
case state == scstPax:
return scstCont
case state == scstPaxS:
return scstPax
case state == scstSed && shellword == "-e":
return scstSedE
case state == scstSed && hasPrefix(shellword, "-"):
return scstSed
case state == scstSed:
return scstCont
case state == scstSedE:
return scstSed
case state == scstSet:
return scstSetCont
case state == scstSetCont:
return scstSetCont
case state == scstCase:
return scstCaseIn
case state == scstCaseIn && shellword == "in":
return scstCaseLabel
case state == scstCaseLabel && shellword == "esac":
return scstCont
case state == scstCaseLabel:
return scstCaseLabelCont
case state == scstCaseLabelCont && shellword == ")":
return scstStart
case state == scstCont:
return scstCont
case state == scstCond:
return scstCondCont
case state == scstCondCont:
return scstCondCont
case state == scstFor:
return scstForIn
case state == scstForIn && shellword == "in":
return scstForCont
case state == scstForCont:
return scstForCont
case state == scstEcho:
return scstCont
default:
_ = G.opts.DebugShell && line.errorf("Internal pkglint error: shellword.nextState state=%s shellword=%q", state, shellword)
return SCST_START
return scstStart
}
}

View file

@ -54,33 +54,33 @@ func (s *Suite) TestChecklineMkShelltext(c *check.C) {
G.mkContext = newMkContext()
G.globalData.InitVartypes()
msline.checklineMkShelltext("echo ${PKGNAME:Q}") // VUC_SHW_PLAIN
msline.checklineMkShelltext("echo ${PKGNAME:Q}") // vucQuotPlain
c.Check(s.Output(), equals, ""+
"WARN: fname:1: PKGNAME may not be used in this file.\n"+
"NOTE: fname:1: The :Q operator isn't necessary for ${PKGNAME} here.\n")
msline.checklineMkShelltext("echo \"${CFLAGS:Q}\"") // VUC_SHW_DQUOT
msline.checklineMkShelltext("echo \"${CFLAGS:Q}\"") // vucQuotDquot
c.Check(s.Output(), equals, ""+
"WARN: fname:1: Please don't use the :Q operator in double quotes.\n"+
"WARN: fname:1: CFLAGS may not be used in this file.\n"+
"WARN: fname:1: Please use ${CFLAGS:M*:Q} instead of ${CFLAGS:Q} and make sure the variable appears outside of any quoting characters.\n")
msline.checklineMkShelltext("echo '${COMMENT:Q}'") // VUC_SHW_SQUOT
msline.checklineMkShelltext("echo '${COMMENT:Q}'") // vucQuotSquot
c.Check(s.Output(), equals, "WARN: fname:1: COMMENT may not be used in this file.\n")
msline.checklineMkShelltext("echo $$@")
msline.checklineMkShelltext("echo $$@")
c.Check(s.Output(), equals, "WARN: fname:1: The $@ shell variable should only be used in double quotes.\n")
msline.checklineMkShelltext("echo \"$$\"") // As seen by make(1); the shell sees: echo $
c.Check(s.Output(), equals, "WARN: fname:1: Unquoted $ or strange shell variable found.\n")
msline.checklineMkShelltext("echo \"\\n\"") // As seen by make(1); the shell sees: echo "\n"
c.Check(s.Output(), equals, "WARN: fname:1: Please use \"\\\\n\" instead of \"\\n\".\n")
}

View file

@ -56,7 +56,7 @@ func isEmptyDir(fname string) bool {
func getSubdirs(fname string) []string {
dirents, err := ioutil.ReadDir(fname)
if err != nil {
fatalf(fname, NO_LINES, "Cannot be read: %s", err)
fatalf(fname, noLines, "Cannot be read: %s", err)
}
var subdirs []string
@ -368,7 +368,7 @@ func stringStringMapKeys(m map[string]string) []string {
func abspath(fname string) string {
abs, err := filepath.Abs(fname)
if err != nil {
fatalf(fname, NO_LINES, "Cannot determine absolute path.")
fatalf(fname, noLines, "Cannot determine absolute path.")
}
return filepath.ToSlash(abs)
}

File diff suppressed because it is too large Load diff

View file

@ -3,10 +3,10 @@ package main
type NeedsQuoting int
const (
NQ_NO NeedsQuoting = iota
NQ_YES
NQ_DOESNT_MATTER
NQ_DONT_KNOW
nqNo NeedsQuoting = iota
nqYes
nqDoesntMatter
nqDontKnow
)
func variableNeedsQuoting(line *Line, varname string, vuc *VarUseContext) NeedsQuoting {
@ -14,7 +14,7 @@ func variableNeedsQuoting(line *Line, varname string, vuc *VarUseContext) NeedsQ
vartype := getVariableType(line, varname)
if vartype == nil || vuc.vartype == nil {
return NQ_DONT_KNOW
return nqDontKnow
}
isPlainWord := vartype.checker.IsEnum()
@ -31,23 +31,23 @@ func variableNeedsQuoting(line *Line, varname string, vuc *VarUseContext) NeedsQ
isPlainWord = true
}
if isPlainWord {
if vartype.kindOfList == LK_NONE {
return NQ_DOESNT_MATTER
if vartype.kindOfList == lkNone {
return nqDoesntMatter
}
if vartype.kindOfList == LK_SHELL && vuc.extent != VUC_EXT_WORDPART {
return NQ_NO
if vartype.kindOfList == lkShell && vuc.extent != vucExtentWordpart {
return nqNo
}
}
// In .for loops, the :Q operator is always misplaced, since
// the items are broken up at white-space, not as shell words
// like in all other parts of make(1).
if vuc.shellword == VUC_SHW_FOR {
return NQ_NO
if vuc.shellword == vucQuotFor {
return nqNo
}
// Determine whether the context expects a list of shell words or not.
wantList := vuc.vartype.isConsideredList() && (vuc.shellword == VUC_SHW_BACKT || vuc.extent != VUC_EXT_WORDPART)
wantList := vuc.vartype.isConsideredList() && (vuc.shellword == vucQuotBackt || vuc.extent != vucExtentWordpart)
haveList := vartype.isConsideredList()
_ = G.opts.DebugQuoting && line.debugf(
@ -55,9 +55,9 @@ func variableNeedsQuoting(line *Line, varname string, vuc *VarUseContext) NeedsQ
varname, vuc, vartype, wantList, haveList)
// A shell word may appear as part of a shell word, for example COMPILER_RPATH_FLAG.
if vuc.extent == VUC_EXT_WORDPART && vuc.shellword == VUC_SHW_PLAIN {
if vartype.kindOfList == LK_NONE && vartype.checker.name == "ShellWord" {
return NQ_NO
if vuc.extent == vucExtentWordpart && vuc.shellword == vucQuotPlain {
if vartype.kindOfList == lkNone && vartype.checker.name == "ShellWord" {
return nqNo
}
}
@ -66,12 +66,12 @@ func variableNeedsQuoting(line *Line, varname string, vuc *VarUseContext) NeedsQ
if G.globalData.varnameToToolname[varname] != "" {
shellword := vuc.shellword
switch {
case shellword == VUC_SHW_PLAIN && vuc.extent != VUC_EXT_WORDPART:
return NQ_NO
case shellword == VUC_SHW_BACKT:
return NQ_NO
case shellword == VUC_SHW_DQUOT || shellword == VUC_SHW_SQUOT:
return NQ_DOESNT_MATTER
case shellword == vucQuotPlain && vuc.extent != vucExtentWordpart:
return nqNo
case shellword == vucQuotBackt:
return nqNo
case shellword == vucQuotDquot || shellword == vucQuotSquot:
return nqDoesntMatter
}
}
@ -79,21 +79,21 @@ func variableNeedsQuoting(line *Line, varname string, vuc *VarUseContext) NeedsQ
// to be quoted. An exception is in the case of backticks,
// because the whole backticks expression is parsed as a single
// shell word by pkglint.
if vuc.extent == VUC_EXT_WORDPART && vuc.shellword != VUC_SHW_BACKT {
return NQ_YES
if vuc.extent == vucExtentWordpart && vuc.shellword != vucQuotBackt {
return nqYes
}
// Assigning lists to lists does not require any quoting, though
// there may be cases like "CONFIGURE_ARGS+= -libs ${LDFLAGS:Q}"
// where quoting is necessary.
if wantList && haveList {
return NQ_DOESNT_MATTER
return nqDoesntMatter
}
if wantList != haveList {
return NQ_YES
return nqYes
}
_ = G.opts.DebugQuoting && line.debugf("Don't know whether :Q is needed for %q", varname)
return NQ_DONT_KNOW
return nqDontKnow
}

View file

@ -10,8 +10,8 @@ func (s *Suite) TestVariableNeedsQuoting(c *check.C) {
pkgnameType := G.globalData.vartypes["PKGNAME"]
// In Makefile: PKGNAME := ${UNKNOWN}
vuc := &VarUseContext{VUC_TIME_LOAD, pkgnameType, VUC_SHW_UNKNOWN, VUC_EXTENT_UNKNOWN}
vuc := &VarUseContext{vucTimeParse, pkgnameType, vucQuotUnknown, vucExtentUnknown}
nq := variableNeedsQuoting(line, "UNKNOWN", vuc)
c.Check(nq, equals, NQ_DONT_KNOW)
c.Check(nq, equals, nqDontKnow)
}

View file

@ -17,9 +17,9 @@ type Vartype struct {
type KindOfList int
const (
LK_NONE KindOfList = iota // Plain data type
LK_SPACE // List entries are separated by whitespace; used in .for loops.
LK_SHELL // List entries are shell words; used in the :M, :S modifiers.
lkNone KindOfList = iota // Plain data type
lkSpace // List entries are separated by whitespace; used in .for loops.
lkShell // List entries are shell words; used in the :M, :S modifiers.
)
type AclEntry struct {
@ -27,11 +27,13 @@ type AclEntry struct {
permissions string // Some of: "a"ppend, "d"efault, "s"et; "p"reprocessing, "u"se
}
// Whether the type definition is guessed (based on the variable name)
// or explicitly defined (see vardefs.go).
type Guessed bool
const (
NOT_GUESSED Guessed = false
GUESSED Guessed = true
guNotGuessed Guessed = false
guGuessed Guessed = true
)
// The allowed actions in this file, or "?" if unknown.
@ -81,9 +83,9 @@ func (vt *Vartype) union() string {
// the implementation of checklineMkVartype easier.
func (vt *Vartype) isConsideredList() bool {
switch vt.kindOfList {
case LK_SHELL:
case lkShell:
return true
case LK_SPACE:
case lkSpace:
return false
}
switch vt.checker {
@ -94,18 +96,18 @@ func (vt *Vartype) isConsideredList() bool {
}
func (vt *Vartype) mayBeAppendedTo() bool {
return vt.kindOfList != LK_NONE ||
return vt.kindOfList != lkNone ||
vt.checker == CheckvarAwkCommand ||
vt.checker == CheckvarSedCommands
}
func (vt *Vartype) String() string {
switch vt.kindOfList {
case LK_NONE:
case lkNone:
return vt.checker.name
case LK_SPACE:
case lkSpace:
return "SpaceList of " + vt.checker.name
case LK_SHELL:
case lkShell:
return "ShellList of " + vt.checker.name
default:
panic("Unknown list type")

View file

@ -361,7 +361,7 @@ func (cv *VartypeCheck) Option() {
// The PATH environment variable
func (cv *VartypeCheck) Pathlist() {
if !contains(cv.value, ":") && cv.guessed == GUESSED {
if !contains(cv.value, ":") && cv.guessed == guGuessed {
checklineMkVartypePrimitive(cv.line, cv.varname, CheckvarPathname, cv.op, cv.value, cv.comment, cv.listContext, cv.guessed)
return
}

View file

@ -264,5 +264,5 @@ func (s *Suite) TestVartypeCheck_Yes(c *check.C) {
func newVartypeCheck(varname, op, value string) *VartypeCheck {
line := NewLine("fname", "1", "dummy", nil)
valueNovar := withoutMakeVariables(line, value, true)
return &VartypeCheck{line, varname, op, value, valueNovar, "", true, NOT_GUESSED}
return &VartypeCheck{line, varname, op, value, valueNovar, "", true, guNotGuessed}
}

View file

@ -4,55 +4,62 @@ package main
// or used. Whether that is allowed depends on:
//
// * The variables data type, as defined in vardefs.go.
// * Whether the variable is accessed at loading time (when the
// Makefiles are parsed) or at run time (when the shell commands are
// run). Especially at load time, there are several points of time
// (e.g. the bsd.pkg.mk file is loaded at the very end, therefore
// the variables that are defined there cannot be used at load time.)
// * When used on the right-hand side of an assigment, the variable can
// represent a list of words, a single word or even only part of a
// word. This distinction decides upon the correct use of the :Q
// operator.
// * When used in shell commands, the variable can appear inside single
// quotes, double quotes, backticks or some combination thereof. This
// also influences whether the variable is correctly used.
// * When used in preprocessing statements like .if or .for, the other
// operands of that statement should fit to the variable and are
// checked against the variable type. For example, comparing OPSYS to
// x86_64 doesnt make sense.
type VarUseContext struct {
time vucTime
vartype *Vartype
shellword vucShellword
shellword vucQuoting
extent vucExtent
}
type vucTime int
const (
VUC_TIME_UNKNOWN vucTime = iota
VUC_TIME_LOAD // During loading, not all variables are available yet.
VUC_TIME_RUN // All files have been read, especially bsd.pkg.mk.
vucTimeUnknown vucTime = iota
// When Makefiles are loaded, the operators := and != are evaluated,
// as well as the conditionals .if, .elif and .for.
// During loading, not all variables are available yet.
// Variable values are still subject to change, especially lists.
vucTimeParse
// All files have been read, all variables can be referenced.
// Variable values dont change anymore.
vucTimeRun
)
type vucShellword int
// The quoting context in which the variable is used.
// Depending on this context, the modifiers :Q or :M can be allowed or not.
type vucQuoting int
const (
VUC_SHW_UNKNOWN vucShellword = iota
VUC_SHW_PLAIN // Example: echo LOCALBASE=${LOCALBASE}
VUC_SHW_DQUOT // Example: echo "The version is ${PKGVERSION}."
VUC_SHW_SQUOT // Example: echo 'The version is ${PKGVERSION}.'
VUC_SHW_BACKT // Example: echo \`sed 1q ${WRKSRC}/README\`
VUC_SHW_FOR // Example: for f in ${EXAMPLE_FILES}
vucQuotUnknown vucQuoting = iota
vucQuotPlain // Example: echo LOCALBASE=${LOCALBASE}
vucQuotDquot // Example: echo "The version is ${PKGVERSION}."
vucQuotSquot // Example: echo 'The version is ${PKGVERSION}.'
vucQuotBackt // Example: echo \`sed 1q ${WRKSRC}/README\`
// The .for loop in Makefiles. This is the only place where
// variables are split on whitespace. Everywhere else (:Q, :M)
// they are split like in the shell.
//
// Example: .for f in ${EXAMPLE_FILES}
vucQuotFor
)
type vucExtent int
const (
VUC_EXTENT_UNKNOWN vucExtent = iota
VUC_EXT_WORD // Example: echo ${LOCALBASE}
VUC_EXT_WORDPART // Example: echo LOCALBASE=${LOCALBASE}
vucExtentUnknown vucExtent = iota
vucExtentWord // Example: echo ${LOCALBASE}
vucExtentWordpart // Example: echo LOCALBASE=${LOCALBASE}
)
func (vuc *VarUseContext) String() string {

View file

@ -7,7 +7,7 @@ import (
func (s *Suite) TestVarUseContext_ToString(c *check.C) {
G.globalData.InitVartypes()
vartype := getVariableType(s.DummyLine(), "PKGNAME")
vuc := &VarUseContext{VUC_TIME_UNKNOWN, vartype, VUC_SHW_BACKT, VUC_EXT_WORD}
vuc := &VarUseContext{vucTimeUnknown, vartype, vucQuotBackt, vucExtentWord}
c.Check(vuc.String(), equals, "(unknown PkgName backt word)")
}