OILS / tools / find / eval.py View on Github | oilshell.org

194 lines, 167 significant
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"""
8eval.py: evaluator for find.
9"""
10
11from __future__ import print_function
12
13import fnmatch
14import os
15import stat
16import sys
17
18from _devbuild.gen import find_asdl as asdl
19
20def _path(v):
21 return v.path
22def _basename(v):
23 return os.path.basename(v.path)
24
25pathAccMap = {
26 asdl.pathAccessor_e.FullPath.enum_id : _path,
27 asdl.pathAccessor_e.Filename.enum_id : _basename,
28}
29
30def _accessTime(v):
31 assert False
32 return stat.ST_ATIME(v.stat.st_mode)
33def _creationTime(v):
34 assert False
35 return stat.ST_CTIME(v.stat.st_mode)
36def _modificationTime(v):
37 assert False
38 return stat.ST_MTIME(v.stat.st_mode)
39def _filesystem(v):
40 assert False
41 return stat.ST_DEV(v.stat.st_mode) # ???
42def _inode(v):
43 return stat.ST_INO(v.stat.st_mode)
44def _linkCount(v):
45 return stat.ST_NLINK(v.stat.st_mode)
46def _mode(v):
47 return stat.S_IMODE(v.stat.st_mode)
48def _filetype(v):
49 return stat.S_IFMT(v.stat.st_mode)
50def _uid(v):
51 return stat.ST_UID(v.stat.st_mode)
52def _gid(v):
53 return stat.ST_GID(v.stat.st_mode)
54def _username(v):
55 assert False
56def _groupname(v):
57 assert False
58def _size(v):
59 return stat.ST_SIZE(v.stat.st_mode)
60
61statAccMap = {
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
77def _stringMatch(acc, test):
78 string = test.p.str
79 return lambda x: acc(x) == string
80def _globMatch(acc, test):
81 glob = test.p.glob
82 return lambda x: fnmatch.fnmatch(acc(x), glob)
83def _regexMatch(acc, test):
84 assert False
85def _eq(acc, test):
86 n = test.p.n
87 return lambda x: acc(x) == n
88def _ge(acc, test):
89 n = test.p.n
90 return lambda x: acc(x) >= n
91def _le(acc, test):
92 n = test.p.n
93 return lambda x: acc(x) <= n
94def _readable(acc, test):
95 return lambda x: os.access(acc(x), os.R_OK)
96def _writable(acc, test):
97 return lambda x: os.access(acc(x), os.W_OK)
98def _executable(acc, test):
99 return lambda x: os.access(acc(x), os.X_OK)
100
101predicateMap = {
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
113def _true(_):
114 return lambda _: True
115def _false(_):
116 return lambda _: False
117def _concatenation(test):
118 return lambda x: [EvalExpr(e)(x) for e in test.exprs][-1]
119def _disjunction(test):
120 return lambda x: any(EvalExpr(e)(x) for e in test.exprs)
121def _conjunction(test):
122 return lambda x: all(EvalExpr(e)(x) for e in test.exprs)
123def _negation(test):
124 return lambda x: not EvalExpr(test.expr)(x)
125def _pathTest(test):
126 pred = predicateMap[test.p.tag]
127 acc = pathAccMap[test.a.enum_id]
128 return pred(acc, test)
129def _statTest(test):
130 pred = predicateMap[test.p.tag]
131 acc = statAccMap[test.a.enum_id]
132 return pred(acc, test)
133def _delete(_):
134 def __delete(v):
135 print("pretend delete", v, file=sys.stderr)
136 return True
137 return __delete
138def _prune(_):
139 def __prune(v):
140 v.prune = True
141 return True
142 return __prune
143def _quit(_):
144 def __quit(v):
145 v.quit = True
146 return True
147 return __quit
148def _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
155def _ls(action):
156 return _true
157def _exec(action):
158 # TODO return exit status
159 return _true
160
161exprMap = {
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
178def EvalExpr(ast):
179 return exprMap[ast.tag](ast)
180
181class 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