3373: decompress-all: cleaned up code a bit. Fail properly with error message on...
[arvados.git] / crunch_scripts / subst.py
1 import os
2 import glob
3
4 def search(c):
5     DEFAULT = 0
6     DOLLAR = 1
7
8     i = 0
9     state = DEFAULT
10     start = None
11     depth = 0
12     while i < len(c):
13         if c[i] == '\\':
14             i += 1
15         elif state == DEFAULT:
16             if c[i] == '$':
17                 state = DOLLAR
18                 if depth == 0:
19                     start = i
20             elif c[i] == ')':
21                 if depth == 1:
22                     return [start, i]
23                 if depth > 0:
24                     depth -= 1
25         elif state == DOLLAR:
26             if c[i] == '(':
27                 depth += 1
28             state = DEFAULT
29         i += 1
30     if depth != 0:
31         raise Exception("Substitution error, mismatched parentheses {}".format(c))
32     return None
33
34 def sub_file(v):
35     return os.path.join(os.environ['TASK_KEEPMOUNT'], v)
36
37 def sub_dir(v):
38     d = os.path.dirname(v)
39     if d == '':
40         d = v
41     return os.path.join(os.environ['TASK_KEEPMOUNT'], d)
42
43 def sub_basename(v):
44     return os.path.splitext(os.path.basename(v))[0]
45
46 def sub_glob(v):
47     l = glob.glob(v)
48     if len(l) == 0:
49         raise Exception("$(glob): No match on '%s'" % v)
50     else:
51         return l[0]
52
53 default_subs = {"file ": sub_file,
54                 "dir ": sub_dir,
55                 "basename ": sub_basename,
56                 "glob ": sub_glob}
57
58 def do_substitution(p, c, subs=default_subs):
59     while True:
60         #print("c is", c)
61         m = search(c)
62         if m != None:
63             v = do_substitution(p, c[m[0]+2 : m[1]])
64             var = True
65             for sub in subs:
66                 if v.startswith(sub):
67                     r = subs[sub](v[len(sub):])
68                     var = False
69                     break
70             if var:
71                 r = p[v]
72
73             c = c[:m[0]] + r + c[m[1]+1:]
74         else:
75             return c