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

Annotation of pkgsrc/pkgtools/pkglint/files/category.go, Revision 1.4

1.1       rillig      1: package main
                      2:
                      3: import (
                      4:        "sort"
                      5: )
                      6:
1.4     ! rillig      7: func CheckdirCategory() {
        !             8:        if G.opts.DebugTrace {
        !             9:                defer tracecall1(G.CurrentDir)()
        !            10:        }
1.1       rillig     11:
1.4     ! rillig     12:        lines := LoadNonemptyLines(G.CurrentDir+"/Makefile", true)
1.1       rillig     13:        if lines == nil {
                     14:                return
                     15:        }
1.4     ! rillig     16:
        !            17:        mklines := NewMkLines(lines)
        !            18:        mklines.Check()
1.1       rillig     19:
                     20:        exp := NewExpecter(lines)
1.4     ! rillig     21:        for exp.AdvanceIfPrefix("#") {
1.1       rillig     22:        }
1.4     ! rillig     23:        exp.ExpectEmptyLine()
1.1       rillig     24:
1.4     ! rillig     25:        if exp.AdvanceIfMatches(`^COMMENT=\t*(.*)`) {
        !            26:                mklines.mklines[exp.index-1].CheckValidCharactersInValue(`[- '(),/0-9A-Za-z]`)
        !            27:        } else {
        !            28:                exp.CurrentLine().Error0("COMMENT= line expected.")
1.1       rillig     29:        }
1.4     ! rillig     30:        exp.ExpectEmptyLine()
1.1       rillig     31:
1.4     ! rillig     32:        type subdir struct {
        !            33:                name   string
        !            34:                line   *Line
        !            35:                active bool
1.1       rillig     36:        }
                     37:
                     38:        // And now to the most complicated part of the category Makefiles,
                     39:        // the (hopefully) sorted list of SUBDIRs. The first step is to
                     40:        // collect the SUBDIRs in the Makefile and in the file system.
                     41:
1.4     ! rillig     42:        fSubdirs := getSubdirs(G.CurrentDir)
1.1       rillig     43:        sort.Sort(sort.StringSlice(fSubdirs))
1.2       rillig     44:        var mSubdirs []subdir
1.1       rillig     45:
                     46:        prevSubdir := ""
1.4     ! rillig     47:        for !exp.EOF() {
        !            48:                line := exp.CurrentLine()
        !            49:                text := line.Text
1.1       rillig     50:
1.2       rillig     51:                if m, commentFlag, indentation, name, comment := match4(text, `^(#?)SUBDIR\+=(\s*)(\S+)\s*(?:#\s*(.*?)\s*|)$`); m {
1.1       rillig     52:                        commentedOut := commentFlag == "#"
                     53:                        if commentedOut && comment == "" {
1.4     ! rillig     54:                                line.Warn1("%q commented out without giving a reason.", name)
1.1       rillig     55:                        }
                     56:
                     57:                        if indentation != "\t" {
1.4     ! rillig     58:                                line.Warn0("Indentation should be a single tab character.")
1.1       rillig     59:                        }
                     60:
1.2       rillig     61:                        if name == prevSubdir {
1.4     ! rillig     62:                                line.Error1("%q must only appear once.", name)
1.2       rillig     63:                        } else if name < prevSubdir {
1.4     ! rillig     64:                                line.Warn2("%q should come before %q.", name, prevSubdir)
1.1       rillig     65:                        } else {
                     66:                                // correctly ordered
                     67:                        }
                     68:
1.2       rillig     69:                        mSubdirs = append(mSubdirs, subdir{name, line, !commentedOut})
                     70:                        prevSubdir = name
1.4     ! rillig     71:                        exp.Advance()
1.1       rillig     72:
                     73:                } else {
1.4     ! rillig     74:                        if line.Text != "" {
        !            75:                                line.Error0("SUBDIR+= line or empty line expected.")
1.1       rillig     76:                        }
                     77:                        break
                     78:                }
                     79:        }
                     80:
                     81:        // To prevent unnecessary warnings about subdirectories that are
                     82:        // in one list, but not in the other, we generate the sets of
                     83:        // subdirs of each list.
                     84:        fCheck := make(map[string]bool)
                     85:        mCheck := make(map[string]bool)
                     86:        for _, fsub := range fSubdirs {
                     87:                fCheck[fsub] = true
                     88:        }
                     89:        for _, msub := range mSubdirs {
1.2       rillig     90:                mCheck[msub.name] = true
1.1       rillig     91:        }
                     92:
1.2       rillig     93:        fIndex, fAtend, fNeednext, fCurrent := 0, false, true, ""
                     94:        mIndex, mAtend, mNeednext, mCurrent := 0, false, true, ""
1.1       rillig     95:
                     96:        var subdirs []string
                     97:
                     98:        var line *Line
1.2       rillig     99:        mActive := false
1.1       rillig    100:
1.2       rillig    101:        for !(mAtend && fAtend) {
                    102:                if !mAtend && mNeednext {
                    103:                        mNeednext = false
                    104:                        if mIndex >= len(mSubdirs) {
                    105:                                mAtend = true
1.4     ! rillig    106:                                line = exp.CurrentLine()
1.1       rillig    107:                                continue
                    108:                        } else {
1.2       rillig    109:                                mCurrent = mSubdirs[mIndex].name
                    110:                                line = mSubdirs[mIndex].line
                    111:                                mActive = mSubdirs[mIndex].active
                    112:                                mIndex++
1.1       rillig    113:                        }
                    114:                }
                    115:
1.2       rillig    116:                if !fAtend && fNeednext {
                    117:                        fNeednext = false
                    118:                        if fIndex >= len(fSubdirs) {
                    119:                                fAtend = true
1.1       rillig    120:                                continue
                    121:                        } else {
1.2       rillig    122:                                fCurrent = fSubdirs[fIndex]
                    123:                                fIndex++
1.1       rillig    124:                        }
                    125:                }
                    126:
1.2       rillig    127:                if !fAtend && (mAtend || fCurrent < mCurrent) {
                    128:                        if !mCheck[fCurrent] {
1.4     ! rillig    129:                                if !line.AutofixInsertBefore("SUBDIR+=\t" + fCurrent) {
        !           130:                                        line.Error1("%q exists in the file system, but not in the Makefile.", fCurrent)
        !           131:                                }
1.2       rillig    132:                        }
                    133:                        fNeednext = true
                    134:
                    135:                } else if !mAtend && (fAtend || mCurrent < fCurrent) {
                    136:                        if !fCheck[mCurrent] {
1.4     ! rillig    137:                                if !line.AutofixDelete() {
        !           138:                                        line.Error1("%q exists in the Makefile, but not in the file system.", mCurrent)
        !           139:                                }
1.1       rillig    140:                        }
1.2       rillig    141:                        mNeednext = true
1.1       rillig    142:
                    143:                } else { // f_current == m_current
1.2       rillig    144:                        fNeednext = true
                    145:                        mNeednext = true
                    146:                        if mActive {
1.4     ! rillig    147:                                subdirs = append(subdirs, G.CurrentDir+"/"+mCurrent)
1.1       rillig    148:                        }
                    149:                }
                    150:        }
                    151:
                    152:        // the pkgsrc-wip category Makefile defines its own targets for
                    153:        // generating indexes and READMEs. Just skip them.
1.4     ! rillig    154:        if G.Wip {
1.1       rillig    155:                exp.index = len(exp.lines) - 2
                    156:        }
                    157:
1.4     ! rillig    158:        exp.ExpectEmptyLine()
        !           159:        exp.ExpectText(".include \"../mk/misc/category.mk\"")
        !           160:        if !exp.EOF() {
        !           161:                exp.CurrentLine().Error0("The file should end here.")
1.1       rillig    162:        }
                    163:
1.4     ! rillig    164:        SaveAutofixChanges(lines)
1.1       rillig    165:
                    166:        if G.opts.Recursive {
1.4     ! rillig    167:                G.Todo = append(append([]string(nil), subdirs...), G.Todo...)
1.1       rillig    168:        }
                    169: }

CVSweb <webmaster@jp.NetBSD.org>