| 1 | # Copyright 2019 Wilke Schwiedop. All rights reserved.
|
| 2 | # Licensed under the Apache License, Version 2.0 (the "License");
|
| 3 | # you may not use this file except in compliance with the License.
|
| 4 | # You may obtain a copy of the License at
|
| 5 | #
|
| 6 | # http://www.apache.org/licenses/LICENSE-2.0
|
| 7 | """
|
| 8 | eval.py: evaluator for find.
|
| 9 | """
|
| 10 |
|
| 11 | from __future__ import print_function
|
| 12 |
|
| 13 | import fnmatch
|
| 14 | import os
|
| 15 | import stat
|
| 16 | import sys
|
| 17 |
|
| 18 | from _devbuild.gen import find_asdl as asdl
|
| 19 |
|
| 20 | def _path(v):
|
| 21 | return v.path
|
| 22 | def _basename(v):
|
| 23 | return os.path.basename(v.path)
|
| 24 |
|
| 25 | pathAccMap = {
|
| 26 | asdl.pathAccessor_e.FullPath.enum_id : _path,
|
| 27 | asdl.pathAccessor_e.Filename.enum_id : _basename,
|
| 28 | }
|
| 29 |
|
| 30 | def _accessTime(v):
|
| 31 | assert False
|
| 32 | return stat.ST_ATIME(v.stat.st_mode)
|
| 33 | def _creationTime(v):
|
| 34 | assert False
|
| 35 | return stat.ST_CTIME(v.stat.st_mode)
|
| 36 | def _modificationTime(v):
|
| 37 | assert False
|
| 38 | return stat.ST_MTIME(v.stat.st_mode)
|
| 39 | def _filesystem(v):
|
| 40 | assert False
|
| 41 | return stat.ST_DEV(v.stat.st_mode) # ???
|
| 42 | def _inode(v):
|
| 43 | return stat.ST_INO(v.stat.st_mode)
|
| 44 | def _linkCount(v):
|
| 45 | return stat.ST_NLINK(v.stat.st_mode)
|
| 46 | def _mode(v):
|
| 47 | return stat.S_IMODE(v.stat.st_mode)
|
| 48 | def _filetype(v):
|
| 49 | return stat.S_IFMT(v.stat.st_mode)
|
| 50 | def _uid(v):
|
| 51 | return stat.ST_UID(v.stat.st_mode)
|
| 52 | def _gid(v):
|
| 53 | return stat.ST_GID(v.stat.st_mode)
|
| 54 | def _username(v):
|
| 55 | assert False
|
| 56 | def _groupname(v):
|
| 57 | assert False
|
| 58 | def _size(v):
|
| 59 | return stat.ST_SIZE(v.stat.st_mode)
|
| 60 |
|
| 61 | statAccMap = {
|
| 62 | asdl.statAccessor_e.AccessTime.enum_id : _accessTime,
|
| 63 | asdl.statAccessor_e.CreationTime.enum_id : _creationTime,
|
| 64 | asdl.statAccessor_e.ModificationTime.enum_id : _modificationTime,
|
| 65 | asdl.statAccessor_e.Filesystem.enum_id : _filesystem,
|
| 66 | asdl.statAccessor_e.Inode.enum_id : _inode,
|
| 67 | # asdl.statAccessor_e.LinkCount.enum_id : _linkCount,
|
| 68 | asdl.statAccessor_e.Mode.enum_id : _mode,
|
| 69 | asdl.statAccessor_e.Filetype.enum_id : _filetype,
|
| 70 | asdl.statAccessor_e.Uid.enum_id : _uid,
|
| 71 | asdl.statAccessor_e.Gid.enum_id : _gid,
|
| 72 | asdl.statAccessor_e.Username.enum_id : _username,
|
| 73 | asdl.statAccessor_e.Groupname.enum_id : _groupname,
|
| 74 | asdl.statAccessor_e.Size.enum_id : _size,
|
| 75 | }
|
| 76 |
|
| 77 | def _stringMatch(acc, test):
|
| 78 | string = test.p.str
|
| 79 | return lambda x: acc(x) == string
|
| 80 | def _globMatch(acc, test):
|
| 81 | glob = test.p.glob
|
| 82 | return lambda x: fnmatch.fnmatch(acc(x), glob)
|
| 83 | def _regexMatch(acc, test):
|
| 84 | assert False
|
| 85 | def _eq(acc, test):
|
| 86 | n = test.p.n
|
| 87 | return lambda x: acc(x) == n
|
| 88 | def _ge(acc, test):
|
| 89 | n = test.p.n
|
| 90 | return lambda x: acc(x) >= n
|
| 91 | def _le(acc, test):
|
| 92 | n = test.p.n
|
| 93 | return lambda x: acc(x) <= n
|
| 94 | def _readable(acc, test):
|
| 95 | return lambda x: os.access(acc(x), os.R_OK)
|
| 96 | def _writable(acc, test):
|
| 97 | return lambda x: os.access(acc(x), os.W_OK)
|
| 98 | def _executable(acc, test):
|
| 99 | return lambda x: os.access(acc(x), os.X_OK)
|
| 100 |
|
| 101 | predicateMap = {
|
| 102 | asdl.predicate_e.StringMatch : _stringMatch,
|
| 103 | asdl.predicate_e.GlobMatch : _globMatch,
|
| 104 | asdl.predicate_e.RegexMatch : _regexMatch,
|
| 105 | asdl.predicate_e.EQ : _eq,
|
| 106 | asdl.predicate_e.GE : _ge,
|
| 107 | asdl.predicate_e.LE : _le,
|
| 108 | asdl.predicate_e.Readable : _readable,
|
| 109 | asdl.predicate_e.Writable : _writable,
|
| 110 | asdl.predicate_e.Executable : _executable,
|
| 111 | }
|
| 112 |
|
| 113 | def _true(_):
|
| 114 | return lambda _: True
|
| 115 | def _false(_):
|
| 116 | return lambda _: False
|
| 117 | def _concatenation(test):
|
| 118 | return lambda x: [EvalExpr(e)(x) for e in test.exprs][-1]
|
| 119 | def _disjunction(test):
|
| 120 | return lambda x: any(EvalExpr(e)(x) for e in test.exprs)
|
| 121 | def _conjunction(test):
|
| 122 | return lambda x: all(EvalExpr(e)(x) for e in test.exprs)
|
| 123 | def _negation(test):
|
| 124 | return lambda x: not EvalExpr(test.expr)(x)
|
| 125 | def _pathTest(test):
|
| 126 | pred = predicateMap[test.p.tag]
|
| 127 | acc = pathAccMap[test.a.enum_id]
|
| 128 | return pred(acc, test)
|
| 129 | def _statTest(test):
|
| 130 | pred = predicateMap[test.p.tag]
|
| 131 | acc = statAccMap[test.a.enum_id]
|
| 132 | return pred(acc, test)
|
| 133 | def _delete(_):
|
| 134 | def __delete(v):
|
| 135 | print("pretend delete", v, file=sys.stderr)
|
| 136 | return True
|
| 137 | return __delete
|
| 138 | def _prune(_):
|
| 139 | def __prune(v):
|
| 140 | v.prune = True
|
| 141 | return True
|
| 142 | return __prune
|
| 143 | def _quit(_):
|
| 144 | def __quit(v):
|
| 145 | v.quit = True
|
| 146 | return True
|
| 147 | return __quit
|
| 148 | def _print(action):
|
| 149 | # TODO handle output-file
|
| 150 | # TODO handle format
|
| 151 | def __print(v):
|
| 152 | print(v.path)
|
| 153 | return True
|
| 154 | return __print
|
| 155 | def _ls(action):
|
| 156 | return _true
|
| 157 | def _exec(action):
|
| 158 | # TODO return exit status
|
| 159 | return _true
|
| 160 |
|
| 161 | exprMap = {
|
| 162 | asdl.expr_e.True_ : _true,
|
| 163 | asdl.expr_e.False_ : _false,
|
| 164 | asdl.expr_e.Concatenation : _concatenation,
|
| 165 | asdl.expr_e.Disjunction : _disjunction,
|
| 166 | asdl.expr_e.Conjunction : _conjunction,
|
| 167 | asdl.expr_e.Negation : _negation,
|
| 168 | asdl.expr_e.PathTest : _pathTest,
|
| 169 | asdl.expr_e.StatTest : _statTest,
|
| 170 | asdl.expr_e.DeleteAction : _delete,
|
| 171 | asdl.expr_e.PruneAction : _prune,
|
| 172 | asdl.expr_e.QuitAction : _quit,
|
| 173 | asdl.expr_e.PrintAction : _print,
|
| 174 | asdl.expr_e.LsAction : _ls,
|
| 175 | asdl.expr_e.ExecAction : _exec,
|
| 176 | }
|
| 177 |
|
| 178 | def EvalExpr(ast):
|
| 179 | return exprMap[ast.tag](ast)
|
| 180 |
|
| 181 | class Thing:
|
| 182 | def __init__(self, path, stat=None):
|
| 183 | self.path = path
|
| 184 | self._stat = stat
|
| 185 | self.prune = False
|
| 186 | self.quit = False
|
| 187 | @property
|
| 188 | def stat(self):
|
| 189 | if self._stat is None:
|
| 190 | # TODO stat for tests that require it?
|
| 191 | self._stat = os.lstat(self.path)
|
| 192 | return self._stat
|
| 193 | def __repr__(self):
|
| 194 | return self.path
|