pkgsrc-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: pkgsrc/pkgtools/pkglint



Module Name:    pkgsrc
Committed By:   rillig
Date:           Mon Nov 14 01:08:23 UTC 2016

Modified Files:
        pkgsrc/pkgtools/pkglint: Makefile
        pkgsrc/pkgtools/pkglint/files: globaldata.go globalvars.go logging.go
            main.go mkline.go mkline_test.go package.go pkglint.go
            plist_test.go util.go util_test.go vardefs.go

Log Message:
Updated pkglint to 5.4.11.

Changes since 5.4.10:

* Replaced regular expression with hand-written matching code, since
  it is 30 times as fast.
* Reduced number of syscalls by remembering os.Lstat results and
  CVS/Entries.
* Reduced number of syscalls by querying the current user only once.
* Added warning for comparing ${PKGSRC_COMPILER} == "clang", which
  should rather be ${PKGSRC_COMPILER:Mclang}.
* Added variable definitions for NOT_PAX_ASLR_SAFE and NOT_PAX_MPROTECT_SAFE.


To generate a diff of this commit:
cvs rdiff -u -r1.499 -r1.500 pkgsrc/pkgtools/pkglint/Makefile
cvs rdiff -u -r1.14 -r1.15 pkgsrc/pkgtools/pkglint/files/globaldata.go
cvs rdiff -u -r1.3 -r1.4 pkgsrc/pkgtools/pkglint/files/globalvars.go
cvs rdiff -u -r1.5 -r1.6 pkgsrc/pkgtools/pkglint/files/logging.go \
    pkgsrc/pkgtools/pkglint/files/util_test.go
cvs rdiff -u -r1.8 -r1.9 pkgsrc/pkgtools/pkglint/files/main.go
cvs rdiff -u -r1.16 -r1.17 pkgsrc/pkgtools/pkglint/files/mkline.go
cvs rdiff -u -r1.17 -r1.18 pkgsrc/pkgtools/pkglint/files/mkline_test.go \
    pkgsrc/pkgtools/pkglint/files/vardefs.go
cvs rdiff -u -r1.12 -r1.13 pkgsrc/pkgtools/pkglint/files/package.go
cvs rdiff -u -r1.13 -r1.14 pkgsrc/pkgtools/pkglint/files/pkglint.go
cvs rdiff -u -r1.9 -r1.10 pkgsrc/pkgtools/pkglint/files/plist_test.go \
    pkgsrc/pkgtools/pkglint/files/util.go

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: pkgsrc/pkgtools/pkglint/Makefile
diff -u pkgsrc/pkgtools/pkglint/Makefile:1.499 pkgsrc/pkgtools/pkglint/Makefile:1.500
--- pkgsrc/pkgtools/pkglint/Makefile:1.499      Tue Nov  1 21:40:25 2016
+++ pkgsrc/pkgtools/pkglint/Makefile    Mon Nov 14 01:08:23 2016
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.499 2016/11/01 21:40:25 rillig Exp $
+# $NetBSD: Makefile,v 1.500 2016/11/14 01:08:23 rillig Exp $
 
-PKGNAME=       pkglint-5.4.10
+PKGNAME=       pkglint-5.4.11
 DISTFILES=     # none
 CATEGORIES=    pkgtools
 

Index: pkgsrc/pkgtools/pkglint/files/globaldata.go
diff -u pkgsrc/pkgtools/pkglint/files/globaldata.go:1.14 pkgsrc/pkgtools/pkglint/files/globaldata.go:1.15
--- pkgsrc/pkgtools/pkglint/files/globaldata.go:1.14    Tue Sep  6 20:54:21 2016
+++ pkgsrc/pkgtools/pkglint/files/globaldata.go Mon Nov 14 01:08:23 2016
@@ -114,7 +114,7 @@ func (gd *GlobalData) loadTools() {
                fname := G.globalData.Pkgsrcdir + "/mk/tools/bsd.tools.mk"
                lines := LoadExistingLines(fname, true)
                for _, line := range lines {
-                       if m, _, _, includefile := match3(line.Text, reMkInclude); m {
+                       if m, _, _, includefile := MatchMkInclude(line.Text); m {
                                if !contains(includefile, "/") {
                                        toolFiles = append(toolFiles, includefile)
                                }

Index: pkgsrc/pkgtools/pkglint/files/globalvars.go
diff -u pkgsrc/pkgtools/pkglint/files/globalvars.go:1.3 pkgsrc/pkgtools/pkglint/files/globalvars.go:1.4
--- pkgsrc/pkgtools/pkglint/files/globalvars.go:1.3     Sun Jun  5 11:24:32 2016
+++ pkgsrc/pkgtools/pkglint/files/globalvars.go Mon Nov 14 01:08:23 2016
@@ -11,12 +11,15 @@ type GlobalVars struct {
        Pkg        *Package   // The package that is currently checked.
        Mk         *MkLines   // The Makefile (or fragment) that is currently checked.
 
-       Todo           []string // The files or directories that still need to be checked.
-       CurrentDir     string   // The currently checked directory, relative to the cwd
-       CurPkgsrcdir   string   // The pkgsrc directory, relative to currentDir
-       Wip            bool     // Is the currently checked directory from pkgsrc-wip?
-       Infrastructure bool     // Is the currently checked item from the pkgsrc infrastructure?
-       Testing        bool     // Is pkglint in self-testing mode (only during development)?
+       Todo            []string // The files or directories that still need to be checked.
+       CurrentDir      string   // The currently checked directory, relative to the cwd
+       CurPkgsrcdir    string   // The pkgsrc directory, relative to currentDir
+       Wip             bool     // Is the currently checked directory from pkgsrc-wip?
+       Infrastructure  bool     // Is the currently checked item from the pkgsrc infrastructure?
+       Testing         bool     // Is pkglint in self-testing mode (only during development)?
+       CurrentUsername string   // For checking against OWNER and MAINTAINER
+       CvsEntriesDir   string   // Cached to avoid I/O
+       CvsEntriesLines []*Line
 
        Hash         map[string]*Hash // Maps "alg:fname" => hash (inter-package check).
        UsedLicenses map[string]bool  // Maps "license name" => true (inter-package check).
@@ -32,10 +35,10 @@ type GlobalVars struct {
        logErr                io.Writer
        debugOut              io.Writer
 
-       res       map[string]*regexp.Regexp
+       res       map[string]*regexp.Regexp // Compiled regular expressions
        rematch   *Histogram
        renomatch *Histogram
-       retime    *Histogram
+       retime    *Histogram // Total time taken by matching a regular expression
        loghisto  *Histogram
 }
 

Index: pkgsrc/pkgtools/pkglint/files/logging.go
diff -u pkgsrc/pkgtools/pkglint/files/logging.go:1.5 pkgsrc/pkgtools/pkglint/files/logging.go:1.6
--- pkgsrc/pkgtools/pkglint/files/logging.go:1.5        Sun Jun  5 11:24:32 2016
+++ pkgsrc/pkgtools/pkglint/files/logging.go    Mon Nov 14 01:08:23 2016
@@ -105,7 +105,7 @@ func Explain(explanation ...string) {
                                print(fmt.Sprintf("Long explanation line (%d): %s\n", l, s))
                        }
                        if m, before := match1(s, `(.+)\. [^ ]`); m {
-                               if !matches(before, `\d$`) {
+                               if !matches(before, `\d$|e\.g`) {
                                        print(fmt.Sprintf("Short space after period: %s\n", s))
                                }
                        }
Index: pkgsrc/pkgtools/pkglint/files/util_test.go
diff -u pkgsrc/pkgtools/pkglint/files/util_test.go:1.5 pkgsrc/pkgtools/pkglint/files/util_test.go:1.6
--- pkgsrc/pkgtools/pkglint/files/util_test.go:1.5      Sat Jul  9 09:43:48 2016
+++ pkgsrc/pkgtools/pkglint/files/util_test.go  Mon Nov 14 01:08:23 2016
@@ -2,6 +2,7 @@ package main
 
 import (
        check "gopkg.in/check.v1"
+       "testing"
 )
 
 func (s *Suite) Test_MkopSubst__middle(c *check.C) {
@@ -86,3 +87,60 @@ func (s *Suite) Test_PrefixReplacer_Sinc
        repl.AdvanceRegexp(`^\w+`)
        c.Check(repl.Since(mark), equals, "hello")
 }
+
+const reMkIncludeBenchmark = `^\.(\s*)(s?include)\s+\"([^\"]+)\"\s*(?:#.*)?$`
+const reMkIncludeBenchmarkPositive = `^\.(\s*)(s?include)\s+\"(.+)\"\s*(?:#.*)?$`
+
+func Benchmark_match3_buildlink3(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               match3(".include \"../../category/package/buildlink3.mk\"", reMkIncludeBenchmark)
+       }
+}
+
+func Benchmark_match3_bsd_pkg_mk(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               match3(".include \"../../mk/bsd.pkg.mk\"", reMkIncludeBenchmark)
+       }
+}
+
+func Benchmark_match3_samedir(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               match3(".include \"options.mk\"", reMkIncludeBenchmark)
+       }
+}
+
+func Benchmark_match3_bsd_pkg_mk_comment(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               match3(".include \"../../mk/bsd.pkg.mk\"          # infrastructure     ", reMkIncludeBenchmark)
+       }
+}
+
+func Benchmark_match3_buildlink3_positive(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               match3(".include \"../../category/package/buildlink3.mk\"", reMkIncludeBenchmarkPositive)
+       }
+}
+
+func Benchmark_match3_bsd_pkg_mk_positive(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               match3(".include \"../../mk/bsd.pkg.mk\"", reMkIncludeBenchmarkPositive)
+       }
+}
+
+func Benchmark_match3_samedir_positive(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               match3(".include \"options.mk\"", reMkIncludeBenchmarkPositive)
+       }
+}
+
+func Benchmark_match3_bsd_pkg_mk_comment_positive(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               match3(".include \"../../mk/bsd.pkg.mk\"          # infrastructure     ", reMkIncludeBenchmarkPositive)
+       }
+}
+
+func Benchmark_match3_explicit(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               MatchMkInclude(".include \"../../mk/bsd.pkg.mk\"          # infrastructure     ")
+       }
+}

Index: pkgsrc/pkgtools/pkglint/files/main.go
diff -u pkgsrc/pkgtools/pkglint/files/main.go:1.8 pkgsrc/pkgtools/pkglint/files/main.go:1.9
--- pkgsrc/pkgtools/pkglint/files/main.go:1.8   Sun Jul 10 21:24:47 2016
+++ pkgsrc/pkgtools/pkglint/files/main.go       Mon Nov 14 01:08:23 2016
@@ -4,6 +4,7 @@ import (
        "fmt"
        "io"
        "os"
+       "os/user"
        "path/filepath"
        "runtime/pprof"
 )
@@ -61,6 +62,12 @@ func (pkglint *Pkglint) Main(args ...str
 
        G.globalData.Initialize()
 
+       currentUser, err := user.Current()
+       if err == nil {
+               // On Windows, this is `Computername\Username`.
+               G.CurrentUsername = regcomp(`^.*\\`).ReplaceAllString(currentUser.Username, "")
+       }
+
        for len(G.Todo) != 0 {
                item := G.Todo[0]
                G.Todo = G.Todo[1:]

Index: pkgsrc/pkgtools/pkglint/files/mkline.go
diff -u pkgsrc/pkgtools/pkglint/files/mkline.go:1.16 pkgsrc/pkgtools/pkglint/files/mkline.go:1.17
--- pkgsrc/pkgtools/pkglint/files/mkline.go:1.16        Tue Nov  1 21:40:25 2016
+++ pkgsrc/pkgtools/pkglint/files/mkline.go     Mon Nov 14 01:08:23 2016
@@ -118,7 +118,7 @@ func NewMkLine(line *Line) (mkline *MkLi
                return
        }
 
-       if m, indent, directive, includefile := match3(text, reMkInclude); m {
+       if m, indent, directive, includefile := MatchMkInclude(text); m {
                mkline.xtype = 6
                mkline.data = mkLineInclude{directive == "include", indent, includefile, ""}
                return
@@ -1196,6 +1196,14 @@ func (mkline *MkLine) CheckCond() {
                value := node.args[2].(string)
                if len(varmods) == 0 {
                        mkline.CheckVartype(varname, opUse, value, "")
+                       if varname == "PKGSRC_COMPILER" {
+                               op := node.args[1].(string)
+                               mkline.Line.Warnf("Use ${PKGSRC_COMPILER:%s%s} instead of the %s operator.", ifelseStr(op == "==", "M", "N"), value, op)
+                               Explain(
+                                       "The PKGSRC_COMPILER can be a list of chained compilers, e.g. \"ccache",
+                                       "distcc clang\".  Therefore, comparing it using == or != leads to",
+                                       "wrong results in these cases.")
+                       }
                } else if len(varmods) == 1 && matches(varmods[0], `^[MN]`) && value != "" {
                        mkline.CheckVartype(varname, opUseMatch, value, "")
                }

Index: pkgsrc/pkgtools/pkglint/files/mkline_test.go
diff -u pkgsrc/pkgtools/pkglint/files/mkline_test.go:1.17 pkgsrc/pkgtools/pkglint/files/mkline_test.go:1.18
--- pkgsrc/pkgtools/pkglint/files/mkline_test.go:1.17   Tue Nov  1 21:40:25 2016
+++ pkgsrc/pkgtools/pkglint/files/mkline_test.go        Mon Nov 14 01:08:23 2016
@@ -760,7 +760,21 @@ func (s *Suite) Test_MkLine_CheckCond_co
 
        G.Mk.Check()
 
-       c.Check(s.Output(), equals, "") // Don’t warn about unknown shell command "cc".
+       // Don’t warn about unknown shell command "cc".
+       c.Check(s.Output(), equals, "WARN: security/openssl/Makefile:2: Use ${PKGSRC_COMPILER:Mgcc} instead of the == operator.\n")
+}
+
+func (s *Suite) Test_MkLine_CheckCond_comparing_PKGSRC_COMPILER_with_eqeq(c *check.C) {
+       s.UseCommandLine(c, "-Wall")
+       G.globalData.InitVartypes()
+       G.Mk = s.NewMkLines("audio/pulseaudio/Makefile",
+               mkrcsid,
+               ".if ${OPSYS} == \"Darwin\" && ${PKGSRC_COMPILER} == \"clang\"",
+               ".endif")
+
+       G.Mk.Check()
+
+       c.Check(s.Output(), equals, "WARN: audio/pulseaudio/Makefile:2: Use ${PKGSRC_COMPILER:Mclang} instead of the == operator.\n")
 }
 
 func (s *Suite) Test_MkLine_Pkgmandir(c *check.C) {
Index: pkgsrc/pkgtools/pkglint/files/vardefs.go
diff -u pkgsrc/pkgtools/pkglint/files/vardefs.go:1.17 pkgsrc/pkgtools/pkglint/files/vardefs.go:1.18
--- pkgsrc/pkgtools/pkglint/files/vardefs.go:1.17       Mon Oct  3 12:25:36 2016
+++ pkgsrc/pkgtools/pkglint/files/vardefs.go    Mon Nov 14 01:08:23 2016
@@ -504,6 +504,8 @@ func (gd *GlobalData) InitVartypes() {
        pkglist("NOT_FOR_BULK_PLATFORM", lkSpace, BtMachinePlatformPattern)
        pkglist("NOT_FOR_PLATFORM", lkSpace, BtMachinePlatformPattern)
        pkg("NOT_FOR_UNPRIVILEGED", lkNone, BtYesNo)
+       pkglist("NOT_PAX_ASLR_SAFE", lkShell, BtPathmask)
+       pkglist("NOT_PAX_MPROTECT_SAFE", lkShell, BtPathmask)
        acl("NO_BIN_ON_CDROM", lkNone, BtRestricted, "Makefile, Makefile.common: set")
        acl("NO_BIN_ON_FTP", lkNone, BtRestricted, "Makefile, Makefile.common: set")
        acl("NO_BUILD", lkNone, BtYes, "Makefile, Makefile.common: set; Makefile.*: default, set")

Index: pkgsrc/pkgtools/pkglint/files/package.go
diff -u pkgsrc/pkgtools/pkglint/files/package.go:1.12 pkgsrc/pkgtools/pkglint/files/package.go:1.13
--- pkgsrc/pkgtools/pkglint/files/package.go:1.12       Tue Nov  1 21:40:25 2016
+++ pkgsrc/pkgtools/pkglint/files/package.go    Mon Nov 14 01:08:23 2016
@@ -2,7 +2,6 @@ package main
 
 import (
        "fmt"
-       "os/user"
        "path"
        "regexp"
        "strconv"
@@ -329,11 +328,13 @@ func (pkg *Package) readMakefile(fname s
                                // current file and in the current working directory.
                                // Pkglint doesn’t have an include dir list, like make(1) does.
                                if !fileExists(dirname + "/" + includeFile) {
-                                       dirname = G.CurrentDir
-                               }
-                               if !fileExists(dirname + "/" + includeFile) {
-                                       line.Error1("Cannot read %q.", dirname+"/"+includeFile)
-                                       return false
+                                       if dirname != G.CurrentDir { // Prevent unnecessary syscalls
+                                               dirname = G.CurrentDir
+                                               if !fileExists(dirname + "/" + includeFile) {
+                                                       line.Error1("Cannot read %q.", dirname+"/"+includeFile)
+                                                       return false
+                                               }
+                                       }
                                }
 
                                if G.opts.Debug {
@@ -808,13 +809,7 @@ func (pkg *Package) checkLocallyModified
                return
        }
 
-       user, err := user.Current()
-       if err != nil || user.Username == "" {
-               return
-       }
-       // On Windows, this is `Computername\Username`.
-       username := regcomp(`^.*\\`).ReplaceAllString(user.Username, "")
-
+       username := G.CurrentUsername
        if G.opts.Debug {
                traceStep("user=%q owner=%q maintainer=%q", username, owner, maintainer)
        }

Index: pkgsrc/pkgtools/pkglint/files/pkglint.go
diff -u pkgsrc/pkgtools/pkglint/files/pkglint.go:1.13 pkgsrc/pkgtools/pkglint/files/pkglint.go:1.14
--- pkgsrc/pkgtools/pkglint/files/pkglint.go:1.13       Tue Nov  1 21:40:25 2016
+++ pkgsrc/pkgtools/pkglint/files/pkglint.go    Mon Nov 14 01:08:23 2016
@@ -7,8 +7,7 @@ import (
 )
 
 const (
-       reMkInclude = `^\.(\s*)(s?include)\s+\"([^\"]+)\"\s*(?:#.*)?$`
-       rePkgname   = `^([\w\-.+]+)-(\d(?:\w|\.\d)*)$`
+       rePkgname = `^([\w\-.+]+)-(\d(?:\w|\.\d)*)$`
 )
 
 // Returns the pkgsrc top-level directory, relative to the given file or directory.
@@ -386,6 +385,66 @@ func MatchVarassign(text string) (m bool
        return
 }
 
+func MatchMkInclude(text string) (bool, string, string, string) {
+       goto start
+fail:
+       return false, "", "", ""
+
+start:
+       len := len(text)
+       if len == 0 || text[0] != '.' {
+               goto fail
+       }
+
+       i := 1
+
+       spaceStart := i
+       for i < len && (text[i] == ' ' || text[i] == '\t') {
+               i++
+       }
+       spaceEnd := i
+
+       directiveStart := i
+       if i < len && text[i] == 's' {
+               i++
+       }
+       if !(i+7 < len && text[i] == 'i' && text[i+1] == 'n' && text[i+2] == 'c' && text[i+3] == 'l' && text[i+4] == 'u' && text[i+5] == 'd' && text[i+6] == 'e') {
+               goto fail
+       }
+       i += 7
+       directiveEnd := i
+
+       for i < len && (text[i] == ' ' || text[i] == '\t') {
+               i++
+       }
+       if !(i < len && text[i] == '"') {
+               goto fail
+       }
+       i++
+
+       pathStart := i
+       for i < len && text[i] != '"' {
+               i++
+       }
+       pathEnd := i
+       if !(pathStart < pathEnd) {
+               goto fail
+       }
+
+       if !(i < len && text[i] == '"') {
+               goto fail
+       }
+       i++
+
+       for i < len && (text[i] == ' ' || text[i] == '\t') {
+               i++
+       }
+       if !(i == len || i < len && text[i] == '#') {
+               goto fail
+       }
+       return true, text[spaceStart:spaceEnd], text[directiveStart:directiveEnd], text[pathStart:pathEnd]
+}
+
 type DependencyPattern struct {
        pkgbase  string // "freeciv-client", "{gcc48,gcc48-libs}", "${EMACS_REQD}"
        lowerOp  string // ">=", ">"

Index: pkgsrc/pkgtools/pkglint/files/plist_test.go
diff -u pkgsrc/pkgtools/pkglint/files/plist_test.go:1.9 pkgsrc/pkgtools/pkglint/files/plist_test.go:1.10
--- pkgsrc/pkgtools/pkglint/files/plist_test.go:1.9     Tue Nov  1 21:40:25 2016
+++ pkgsrc/pkgtools/pkglint/files/plist_test.go Mon Nov 14 01:08:23 2016
@@ -221,7 +221,7 @@ func (s *Suite) Test_PlistChecker__autof
                "AUTOFIX: ~/PLIST: Has been auto-fixed. Please re-run pkglint.\n")
        c.Check(len(lines), equals, len(fixedLines))
        c.Check(s.LoadTmpFile(c, "PLIST"), equals, ""+
-               "@comment $NetBSD: plist_test.go,v 1.9 2016/11/01 21:40:25 rillig Exp $\n"+
+               "@comment $"+"NetBSD$\n"+
                "${PLIST.xen}lib/libvirt/connection-driver/libvirt_driver_libxl.la\n"+
                "${PLIST.hal}lib/libvirt/connection-driver/libvirt_driver_nodedev.la\n"+
                "lib/libvirt/connection-driver/libvirt_driver_storage.la\n"+
Index: pkgsrc/pkgtools/pkglint/files/util.go
diff -u pkgsrc/pkgtools/pkglint/files/util.go:1.9 pkgsrc/pkgtools/pkglint/files/util.go:1.10
--- pkgsrc/pkgtools/pkglint/files/util.go:1.9   Sat Jul  9 09:43:48 2016
+++ pkgsrc/pkgtools/pkglint/files/util.go       Mon Nov 14 01:08:23 2016
@@ -71,13 +71,10 @@ func getSubdirs(fname string) []string {
 
 // Checks whether a file is already committed to the CVS repository.
 func isCommitted(fname string) bool {
-       basename := path.Base(fname)
-       lines, err := readLines(path.Dir(fname)+"/CVS/Entries", false)
-       if err != nil {
-               return false
-       }
+       lines := loadCvsEntries(fname)
+       needle := "/" + path.Base(fname) + "/"
        for _, line := range lines {
-               if hasPrefix(line.Text, "/"+basename+"/") {
+               if hasPrefix(line.Text, needle) {
                        return true
                }
        }
@@ -85,13 +82,10 @@ func isCommitted(fname string) bool {
 }
 
 func isLocallyModified(fname string) bool {
-       basename := path.Base(fname)
-       lines, err := readLines(path.Dir(fname)+"/CVS/Entries", false)
-       if err != nil {
-               return false
-       }
+       lines := loadCvsEntries(fname)
+       needle := "/" + path.Base(fname) + "/"
        for _, line := range lines {
-               if hasPrefix(line.Text, "/"+basename+"/") {
+               if hasPrefix(line.Text, needle) {
                        cvsModTime, err := time.Parse(time.ANSIC, strings.Split(line.Text, "/")[3])
                        if err != nil {
                                return false
@@ -112,6 +106,21 @@ func isLocallyModified(fname string) boo
        return false
 }
 
+func loadCvsEntries(fname string) []*Line {
+       dir := path.Dir(fname)
+       if dir == G.CvsEntriesDir {
+               return G.CvsEntriesLines
+       }
+
+       lines, err := readLines(dir+"/CVS/Entries", false)
+       if err != nil {
+               return nil
+       }
+       G.CvsEntriesDir = dir
+       G.CvsEntriesLines = lines
+       return lines
+}
+
 // Returns the number of columns that a string occupies when printed with
 // a tabulator size of 8.
 func tabLength(s string) int {



Home | Main Index | Thread Index | Old Index