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

Annotation of pkgsrc/pkgtools/pkglint/files/vartype.go, Revision 1.17

1.1       rillig      1: package main
                      2:
                      3: import (
                      4:        "path"
                      5:        "strings"
                      6: )
                      7:
                      8: // Vartype is a combination of a data type and a permission specification.
                      9: // See vardefs.go for examples, and vartypecheck.go for the implementation.
                     10: type Vartype struct {
                     11:        kindOfList KindOfList
1.10      rillig     12:        basicType  *BasicType
1.13      rillig     13:        aclEntries []ACLEntry
1.5       rillig     14:        guessed    bool
1.1       rillig     15: }
                     16:
1.5       rillig     17: type KindOfList uint8
1.1       rillig     18:
                     19: const (
1.3       rillig     20:        lkNone  KindOfList = iota // Plain data type
                     21:        lkSpace                   // List entries are separated by whitespace; used in .for loops.
                     22:        lkShell                   // List entries are shell words; used in the :M, :S modifiers.
1.1       rillig     23: )
                     24:
1.13      rillig     25: type ACLEntry struct {
1.1       rillig     26:        glob        string // Examples: "Makefile", "*.mk"
1.13      rillig     27:        permissions ACLPermissions
1.1       rillig     28: }
                     29:
1.13      rillig     30: type ACLPermissions uint8
1.1       rillig     31:
                     32: const (
1.13      rillig     33:        aclpSet         ACLPermissions = 1 << iota // VAR = value
1.5       rillig     34:        aclpSetDefault                             // VAR ?= value
                     35:        aclpAppend                                 // VAR += value
                     36:        aclpUseLoadtime                            // OTHER := ${VAR}, OTHER != ${VAR}
                     37:        aclpUse                                    // OTHER = ${VAR}
                     38:        aclpUnknown
1.13      rillig     39:        aclpAll        = aclpAppend | aclpSetDefault | aclpSet | aclpUseLoadtime | aclpUse
                     40:        aclpAllRuntime = aclpAppend | aclpSetDefault | aclpSet | aclpUse
                     41:        aclpAllWrite   = aclpSet | aclpSetDefault | aclpAppend
                     42:        aclpAllRead    = aclpUseLoadtime | aclpUse
1.1       rillig     43: )
                     44:
1.13      rillig     45: func (perms ACLPermissions) Contains(subset ACLPermissions) bool {
1.5       rillig     46:        return perms&subset == subset
                     47: }
                     48:
1.13      rillig     49: func (perms ACLPermissions) String() string {
1.5       rillig     50:        if perms == 0 {
                     51:                return "none"
                     52:        }
                     53:        result := "" +
                     54:                ifelseStr(perms.Contains(aclpSet), "set, ", "") +
                     55:                ifelseStr(perms.Contains(aclpSetDefault), "set-default, ", "") +
                     56:                ifelseStr(perms.Contains(aclpAppend), "append, ", "") +
                     57:                ifelseStr(perms.Contains(aclpUseLoadtime), "use-loadtime, ", "") +
                     58:                ifelseStr(perms.Contains(aclpUse), "use, ", "") +
                     59:                ifelseStr(perms.Contains(aclpUnknown), "unknown, ", "")
                     60:        return strings.TrimRight(result, ", ")
                     61: }
                     62:
1.13      rillig     63: func (perms ACLPermissions) HumanString() string {
1.5       rillig     64:        result := "" +
                     65:                ifelseStr(perms.Contains(aclpSet), "set, ", "") +
                     66:                ifelseStr(perms.Contains(aclpSetDefault), "given a default value, ", "") +
                     67:                ifelseStr(perms.Contains(aclpAppend), "appended to, ", "") +
                     68:                ifelseStr(perms.Contains(aclpUseLoadtime), "used at load time, ", "") +
                     69:                ifelseStr(perms.Contains(aclpUse), "used, ", "")
                     70:        return strings.TrimRight(result, ", ")
                     71: }
                     72:
1.13      rillig     73: func (vt *Vartype) EffectivePermissions(fname string) ACLPermissions {
1.2       rillig     74:        for _, aclEntry := range vt.aclEntries {
1.1       rillig     75:                if m, _ := path.Match(aclEntry.glob, path.Base(fname)); m {
                     76:                        return aclEntry.permissions
                     77:                }
                     78:        }
1.5       rillig     79:        return aclpUnknown
1.1       rillig     80: }
                     81:
1.16      rillig     82: // Union returns the union of all possible permissions.
                     83: // This can be used to check whether a variable may be defined or used
                     84: // at all, or if it is read-only.
1.13      rillig     85: func (vt *Vartype) Union() ACLPermissions {
                     86:        var permissions ACLPermissions
1.2       rillig     87:        for _, aclEntry := range vt.aclEntries {
1.5       rillig     88:                permissions |= aclEntry.permissions
1.1       rillig     89:        }
                     90:        return permissions
                     91: }
                     92:
1.13      rillig     93: func (vt *Vartype) AllowedFiles(perms ACLPermissions) string {
1.5       rillig     94:        files := make([]string, 0, len(vt.aclEntries))
                     95:        for _, aclEntry := range vt.aclEntries {
                     96:                if aclEntry.permissions.Contains(perms) {
                     97:                        files = append(files, aclEntry.glob)
                     98:                }
                     99:        }
                    100:        return strings.Join(files, ", ")
                    101: }
                    102:
1.16      rillig    103: // IsConsideredList returns whether the type is considered a shell list.
1.11      rillig    104: // This distinction between "real lists" and "considered a list" makes
1.1       rillig    105: // the implementation of checklineMkVartype easier.
1.5       rillig    106: func (vt *Vartype) IsConsideredList() bool {
1.2       rillig    107:        switch vt.kindOfList {
1.3       rillig    108:        case lkShell:
1.1       rillig    109:                return true
1.3       rillig    110:        case lkSpace:
1.1       rillig    111:                return false
                    112:        }
1.10      rillig    113:        switch vt.basicType {
1.12      rillig    114:        case BtAwkCommand, BtSedCommands, BtShellCommand, BtShellCommands, BtLicense, BtConfFiles:
1.1       rillig    115:                return true
                    116:        }
                    117:        return false
                    118: }
                    119:
1.5       rillig    120: func (vt *Vartype) MayBeAppendedTo() bool {
                    121:        return vt.kindOfList != lkNone || vt.IsConsideredList()
1.1       rillig    122: }
                    123:
1.2       rillig    124: func (vt *Vartype) String() string {
1.16      rillig    125:        listPrefix := [...]string{"", "SpaceList of ", "ShellList of "}[vt.kindOfList]
1.15      rillig    126:        guessedSuffix := ifelseStr(vt.guessed, " (guessed)", "")
                    127:        return listPrefix + vt.basicType.name + guessedSuffix
1.1       rillig    128: }
                    129:
1.7       rillig    130: func (vt *Vartype) IsShell() bool {
1.10      rillig    131:        switch vt.basicType {
                    132:        case BtCFlag, // Subtype of ShellWord
                    133:                BtLdFlag, // Subtype of ShellWord
                    134:                BtSedCommands,
                    135:                BtShellCommand,
                    136:                BtShellCommands,
                    137:                BtShellWord:
1.7       rillig    138:                return true
                    139:        }
                    140:        return false
                    141: }
                    142:
1.11      rillig    143: // IsBasicSafe returns whether the basic vartype consists only of
                    144: // characters that don't need escaping in most contexts, like A-Za-z0-9-_.
1.7       rillig    145: func (vt *Vartype) IsBasicSafe() bool {
1.10      rillig    146:        switch vt.basicType {
                    147:        case BtBuildlinkDepmethod,
                    148:                BtCategory,
                    149:                BtDistSuffix,
                    150:                BtEmulPlatform,
                    151:                BtFileMode,
                    152:                BtFilename,
                    153:                BtIdentifier,
                    154:                BtInteger,
                    155:                BtMachineGnuPlatform,
                    156:                BtMachinePlatform,
                    157:                BtOption,
                    158:                BtPathname,
                    159:                BtPerl5Packlist,
                    160:                BtPkgName,
                    161:                BtPkgOptionsVar,
                    162:                BtPkgPath,
                    163:                BtPkgRevision,
                    164:                BtPrefixPathname,
                    165:                BtPythonDependency,
                    166:                BtRelativePkgDir,
                    167:                BtRelativePkgPath,
                    168:                BtStage,
1.14      rillig    169:                BtTool, // Sometimes contains a colon, but that should be ok.
1.10      rillig    170:                BtUserGroupName,
                    171:                BtVersion,
                    172:                BtWrkdirSubdirectory,
                    173:                BtYesNo,
                    174:                BtYesNoIndirectly:
1.7       rillig    175:                return true
                    176:        }
                    177:        return false
                    178: }
                    179:
                    180: func (vt *Vartype) IsPlainString() bool {
1.10      rillig    181:        switch vt.basicType {
                    182:        case BtComment, BtMessage, BtUnknown:
1.7       rillig    183:                return true
                    184:        }
                    185:        return false
                    186: }
                    187:
1.10      rillig    188: type BasicType struct {
1.1       rillig    189:        name    string
                    190:        checker func(*VartypeCheck)
                    191: }
                    192:
1.10      rillig    193: func (bt *BasicType) IsEnum() bool {
                    194:        return hasPrefix(bt.name, "enum: ")
1.1       rillig    195: }
1.10      rillig    196: func (bt *BasicType) HasEnum(value string) bool {
                    197:        return !contains(value, " ") && contains(bt.name, " "+value+" ")
1.1       rillig    198: }
1.10      rillig    199: func (bt *BasicType) AllowedEnums() string {
                    200:        return bt.name[6 : len(bt.name)-1]
1.1       rillig    201: }
                    202:
                    203: var (
1.10      rillig    204:        BtAwkCommand             = &BasicType{"AwkCommand", (*VartypeCheck).AwkCommand}
                    205:        BtBasicRegularExpression = &BasicType{"BasicRegularExpression", (*VartypeCheck).BasicRegularExpression}
                    206:        BtBuildlinkDepmethod     = &BasicType{"BuildlinkDepmethod", (*VartypeCheck).BuildlinkDepmethod}
                    207:        BtCategory               = &BasicType{"Category", (*VartypeCheck).Category}
                    208:        BtCFlag                  = &BasicType{"CFlag", (*VartypeCheck).CFlag}
                    209:        BtComment                = &BasicType{"Comment", (*VartypeCheck).Comment}
1.12      rillig    210:        BtConfFiles              = &BasicType{"ConfFiles", (*VartypeCheck).ConfFiles}
1.10      rillig    211:        BtDependency             = &BasicType{"Dependency", (*VartypeCheck).Dependency}
                    212:        BtDependencyWithPath     = &BasicType{"DependencyWithPath", (*VartypeCheck).DependencyWithPath}
                    213:        BtDistSuffix             = &BasicType{"DistSuffix", (*VartypeCheck).DistSuffix}
                    214:        BtEmulPlatform           = &BasicType{"EmulPlatform", (*VartypeCheck).EmulPlatform}
                    215:        BtFetchURL               = &BasicType{"FetchURL", (*VartypeCheck).FetchURL}
                    216:        BtFilename               = &BasicType{"Filename", (*VartypeCheck).Filename}
                    217:        BtFilemask               = &BasicType{"Filemask", (*VartypeCheck).Filemask}
                    218:        BtFileMode               = &BasicType{"FileMode", (*VartypeCheck).FileMode}
                    219:        BtHomepage               = &BasicType{"Homepage", (*VartypeCheck).Homepage}
                    220:        BtIdentifier             = &BasicType{"Identifier", (*VartypeCheck).Identifier}
                    221:        BtInteger                = &BasicType{"Integer", (*VartypeCheck).Integer}
                    222:        BtLdFlag                 = &BasicType{"LdFlag", (*VartypeCheck).LdFlag}
                    223:        BtLicense                = &BasicType{"License", (*VartypeCheck).License}
                    224:        BtMachineGnuPlatform     = &BasicType{"MachineGnuPlatform", (*VartypeCheck).MachineGnuPlatform}
                    225:        BtMachinePlatform        = &BasicType{"MachinePlatform", (*VartypeCheck).MachinePlatform}
                    226:        BtMachinePlatformPattern = &BasicType{"MachinePlatformPattern", (*VartypeCheck).MachinePlatformPattern}
                    227:        BtMailAddress            = &BasicType{"MailAddress", (*VartypeCheck).MailAddress}
                    228:        BtMessage                = &BasicType{"Message", (*VartypeCheck).Message}
                    229:        BtOption                 = &BasicType{"Option", (*VartypeCheck).Option}
                    230:        BtPathlist               = &BasicType{"Pathlist", (*VartypeCheck).Pathlist}
                    231:        BtPathmask               = &BasicType{"Pathmask", (*VartypeCheck).Pathmask}
                    232:        BtPathname               = &BasicType{"Pathname", (*VartypeCheck).Pathname}
                    233:        BtPerl5Packlist          = &BasicType{"Perl5Packlist", (*VartypeCheck).Perl5Packlist}
                    234:        BtPerms                  = &BasicType{"Perms", (*VartypeCheck).Perms}
1.17    ! rillig    235:        BtPkgName                = &BasicType{"Pkgname", (*VartypeCheck).Pkgname}
1.10      rillig    236:        BtPkgPath                = &BasicType{"PkgPath", (*VartypeCheck).PkgPath}
                    237:        BtPkgOptionsVar          = &BasicType{"PkgOptionsVar", (*VartypeCheck).PkgOptionsVar}
                    238:        BtPkgRevision            = &BasicType{"PkgRevision", (*VartypeCheck).PkgRevision}
                    239:        BtPrefixPathname         = &BasicType{"PrefixPathname", (*VartypeCheck).PrefixPathname}
                    240:        BtPythonDependency       = &BasicType{"PythonDependency", (*VartypeCheck).PythonDependency}
                    241:        BtRelativePkgDir         = &BasicType{"RelativePkgDir", (*VartypeCheck).RelativePkgDir}
                    242:        BtRelativePkgPath        = &BasicType{"RelativePkgPath", (*VartypeCheck).RelativePkgPath}
                    243:        BtRestricted             = &BasicType{"Restricted", (*VartypeCheck).Restricted}
                    244:        BtSedCommand             = &BasicType{"SedCommand", (*VartypeCheck).SedCommand}
                    245:        BtSedCommands            = &BasicType{"SedCommands", (*VartypeCheck).SedCommands}
                    246:        BtShellCommand           = &BasicType{"ShellCommand", nil}
                    247:        BtShellCommands          = &BasicType{"ShellCommands", nil}
                    248:        BtShellWord              = &BasicType{"ShellWord", nil}
                    249:        BtStage                  = &BasicType{"Stage", (*VartypeCheck).Stage}
                    250:        BtTool                   = &BasicType{"Tool", (*VartypeCheck).Tool}
                    251:        BtUnknown                = &BasicType{"Unknown", (*VartypeCheck).Unknown}
                    252:        BtURL                    = &BasicType{"URL", (*VartypeCheck).URL}
                    253:        BtUserGroupName          = &BasicType{"UserGroupName", (*VartypeCheck).UserGroupName}
                    254:        BtVariableName           = &BasicType{"VariableName", (*VartypeCheck).VariableName}
                    255:        BtVersion                = &BasicType{"Version", (*VartypeCheck).Version}
                    256:        BtWrapperReorder         = &BasicType{"WrapperReorder", (*VartypeCheck).WrapperReorder}
                    257:        BtWrapperTransform       = &BasicType{"WrapperTransform", (*VartypeCheck).WrapperTransform}
                    258:        BtWrkdirSubdirectory     = &BasicType{"WrkdirSubdirectory", (*VartypeCheck).WrkdirSubdirectory}
                    259:        BtWrksrcSubdirectory     = &BasicType{"WrksrcSubdirectory", (*VartypeCheck).WrksrcSubdirectory}
                    260:        BtYes                    = &BasicType{"Yes", (*VartypeCheck).Yes}
                    261:        BtYesNo                  = &BasicType{"YesNo", (*VartypeCheck).YesNo}
                    262:        BtYesNoIndirectly        = &BasicType{"YesNoIndirectly", (*VartypeCheck).YesNoIndirectly}
1.1       rillig    263: )
                    264:
                    265: func init() { // Necessary due to circular dependency
1.10      rillig    266:        BtShellCommand.checker = (*VartypeCheck).ShellCommand
                    267:        BtShellCommands.checker = (*VartypeCheck).ShellCommands
                    268:        BtShellWord.checker = (*VartypeCheck).ShellWord
1.1       rillig    269: }

CVSweb <webmaster@jp.NetBSD.org>