[BACK]Return to linelexer.go CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / pkgsrc / pkgtools / pkglint / files

File: [cvs.NetBSD.org] / pkgsrc / pkgtools / pkglint / files / Attic / linelexer.go (download)

Revision 1.1, Sat Jan 26 16:31:33 2019 UTC (5 years, 2 months ago) by rillig
Branch: MAIN

pkgtools/pkglint: update to 5.6.12

Changes since 5.6.11:

* In buildlink3.mk files, print the paths relative
  to the line, not to the pkgsrc root.

* When explaining that a variable cannot be set/used because of wrong
  permissions, list the permissions. This provides more transparency
  than just stating that the desired action is not allowed.

* When pkglint checks a pkgsrc-wip package, don't warn about malformed
  lines in doc/CHANGES-* since pkgsrc-wip users typically cannot do
  anything about these errors.

* In profiling mode, not only the code coverage and the performance
  statistics are dumped, the whole heap is also dumped to see which
  parts of pkglint consume the most heap memory. Pkglint now needs
  less heap memory than before, which mainly affects full scans.

* The checks for absolute pathnames have gone. They were of questionable
  value since pkglint has failed to give proper advice on how to fix
  them properly, at least for the last 12 years.

* The check that pkgsrc-wip packages should only use exact CVS Ids
  (the unexpanded variant) has been disabled again. It occurred about
  16000 times but even fixing it wouldn't improve anything since it
  was mostly a formatting issue without any practical consequences.

* Warn about trailing variable modifiers like in ${VAR:S,from,to,extra}.

* Properly parse ${VAR:!command!}.

* Suggest to replace SUBST_SED with SUBST_VARS where possible, even
  with complicated shell quoting. Pkglint can autofix most of these
  overly verbose cases.

* Load builtin.mk whenever the corresponding buildlink3.mk file is
  included. This fixes several warnings about undefined variables
  (especially for packages using OpenSSL).

* Parse .for lines like bmake does since 2015, splitting words like
  in brk_string.

* Optionally show a warning even if it cannot be autofixed by pkglint.
  This is useful for the SUBST_VARS replacement since even when
  pkglint cannot automatically replace the code, there are still cases
  where it can warn at least.

* As always, several refactorings.

package pkglint

import (
	"netbsd.org/pkglint/regex"
	"strings"
)

// LinesLexer records the state when checking a list of lines from top to bottom.
type LinesLexer struct {
	lines Lines
	index int
}

func NewLinesLexer(lines Lines) *LinesLexer {
	return &LinesLexer{lines, 0}
}

func (llex *LinesLexer) CurrentLine() Line {
	if llex.index < llex.lines.Len() {
		return llex.lines.Lines[llex.index]
	}
	return NewLineEOF(llex.lines.FileName)
}

func (llex *LinesLexer) PreviousLine() Line {
	return llex.lines.Lines[llex.index-1]
}

func (llex *LinesLexer) EOF() bool {
	return !(llex.index < llex.lines.Len())
}

// Skip skips the current line and returns true.
func (llex *LinesLexer) Skip() bool {
	if llex.EOF() {
		return false
	}
	llex.index++
	return true
}

func (llex *LinesLexer) Undo() {
	llex.index--
}

func (llex *LinesLexer) NextRegexp(re regex.Pattern) []string {
	if trace.Tracing {
		defer trace.Call(llex.CurrentLine().Text, re)()
	}

	if !llex.EOF() {
		if m := G.res.Match(llex.lines.Lines[llex.index].Text, re); m != nil {
			llex.index++
			return m
		}
	}
	return nil
}

func (llex *LinesLexer) SkipRegexp(re regex.Pattern) bool {
	return llex.NextRegexp(re) != nil
}

func (llex *LinesLexer) SkipPrefix(prefix string) bool {
	if trace.Tracing {
		defer trace.Call2(llex.CurrentLine().Text, prefix)()
	}

	return !llex.EOF() && strings.HasPrefix(llex.lines.Lines[llex.index].Text, prefix) && llex.Skip()
}

func (llex *LinesLexer) SkipString(text string) bool {
	if trace.Tracing {
		defer trace.Call2(llex.CurrentLine().Text, text)()
	}

	return !llex.EOF() && llex.lines.Lines[llex.index].Text == text && llex.Skip()
}

func (llex *LinesLexer) SkipEmptyOrNote() bool {
	if llex.SkipString("") {
		return true
	}

	if G.Opts.WarnSpace {
		if llex.index == 0 {
			fix := llex.CurrentLine().Autofix()
			fix.Notef("Empty line expected before this line.")
			fix.InsertBefore("")
			fix.Apply()
		} else {
			fix := llex.PreviousLine().Autofix()
			fix.Notef("Empty line expected after this line.")
			fix.InsertAfter("")
			fix.Apply()
		}
	}
	return false
}

func (llex *LinesLexer) SkipContainsOrWarn(text string) bool {
	result := llex.SkipString(text)
	if !result {
		llex.CurrentLine().Warnf("This line should contain the following text: %s", text)
	}
	return result
}

// MkLinesLexer records the state when checking a list of Makefile lines from top to bottom.
type MkLinesLexer struct {
	mklines MkLines
	LinesLexer
}

func NewMkLinesLexer(mklines MkLines) *MkLinesLexer {
	return &MkLinesLexer{mklines, *NewLinesLexer(mklines.lines)}
}

func (mlex *MkLinesLexer) PreviousMkLine() MkLine {
	return mlex.mklines.mklines[mlex.index-1]
}

func (mlex *MkLinesLexer) CurrentMkLine() MkLine {
	return mlex.mklines.mklines[mlex.index]
}

func (mlex *MkLinesLexer) SkipWhile(pred func(mkline MkLine) bool) {
	if trace.Tracing {
		defer trace.Call(mlex.CurrentMkLine().Text)()
	}

	for !mlex.EOF() && pred(mlex.CurrentMkLine()) {
		mlex.Skip()
	}
}

func (mlex *MkLinesLexer) SkipIf(pred func(mkline MkLine) bool) bool {
	return !mlex.EOF() && pred(mlex.CurrentMkLine()) && mlex.Skip()
}