waf: always close cross answers file
[Samba.git] / buildtools / wafsamba / samba_cross.py
blob877ead8581528695aa1062296186156121eb8151
1 # functions for handling cross-compilation
3 import Utils, Logs, sys, os, Options, re
4 from Configure import conf
6 real_Popen = None
8 ANSWER_UNKNOWN = (254, "")
9 ANSWER_FAIL = (255, "")
10 ANSWER_OK = (0, "")
12 cross_answers_incomplete = False
15 def add_answer(ca_file, msg, answer):
16 '''add an answer to a set of cross answers'''
17 try:
18 f = open(ca_file, 'a')
19 except:
20 Logs.error("Unable to open cross-answers file %s" % ca_file)
21 sys.exit(1)
22 if answer == ANSWER_OK:
23 f.write('%s: OK\n' % msg)
24 elif answer == ANSWER_UNKNOWN:
25 f.write('%s: UNKNOWN\n' % msg)
26 elif answer == ANSWER_FAIL:
27 f.write('%s: FAIL\n' % msg)
28 else:
29 (retcode, retstring) = answer
30 f.write('%s: (%d, "%s")' % (msg, retcode, retstring))
31 f.close()
34 def cross_answer(ca_file, msg):
35 '''return a (retcode,retstring) tuple from a answers file'''
36 try:
37 f = open(ca_file, 'r')
38 except:
39 add_answer(ca_file, msg, ANSWER_UNKNOWN)
40 return ANSWER_UNKNOWN
41 for line in f:
42 line = line.strip()
43 if line == '' or line[0] == '#':
44 continue
45 if line.find(':') != -1:
46 a = line.split(':')
47 thismsg = a[0].strip()
48 if thismsg != msg:
49 continue
50 ans = a[1].strip()
51 if ans == "OK" or ans == "YES":
52 f.close()
53 return ANSWER_OK
54 elif ans == "UNKNOWN":
55 f.close()
56 return ANSWER_UNKNOWN
57 elif ans == "FAIL" or ans == "NO":
58 f.close()
59 return ANSWER_FAIL
60 elif ans[0] == '"':
61 f.close()
62 return (0, ans.strip('"'))
63 elif ans[0] == "'":
64 f.close()
65 return (0, ans.strip("'"))
66 else:
67 m = re.match('\(\s*(-?\d+)\s*,\s*\"(.*)\"\s*\)', ans)
68 if m:
69 f.close()
70 return (int(m.group(1)), m.group(2))
71 else:
72 raise Utils.WafError("Bad answer format '%s' in %s" % (line, ca_file))
73 f.close()
74 add_answer(ca_file, msg, ANSWER_UNKNOWN)
75 return ANSWER_UNKNOWN
78 class cross_Popen(Utils.pproc.Popen):
79 '''cross-compilation wrapper for Popen'''
80 def __init__(*k, **kw):
81 (obj, args) = k
83 if '--cross-execute' in args:
84 # when --cross-execute is set, then change the arguments
85 # to use the cross emulator
86 i = args.index('--cross-execute')
87 newargs = args[i+1].split()
88 newargs.extend(args[0:i])
89 args = newargs
90 elif '--cross-answers' in args:
91 # when --cross-answers is set, then change the arguments
92 # to use the cross answers if available
93 i = args.index('--cross-answers')
94 ca_file = args[i+1]
95 msg = args[i+2]
96 ans = cross_answer(ca_file, msg)
97 if ans == ANSWER_UNKNOWN:
98 global cross_answers_incomplete
99 cross_answers_incomplete = True
100 (retcode, retstring) = ans
101 args = ['/bin/sh', '-c', "echo -n '%s'; exit %d" % (retstring, retcode)]
102 real_Popen.__init__(*(obj, args), **kw)
105 @conf
106 def SAMBA_CROSS_ARGS(conf, msg=None):
107 '''get exec_args to pass when running cross compiled binaries'''
108 if not conf.env.CROSS_COMPILE:
109 return []
111 global real_Popen
112 if real_Popen is None:
113 real_Popen = Utils.pproc.Popen
114 Utils.pproc.Popen = cross_Popen
116 ret = []
118 if conf.env.CROSS_EXECUTE:
119 ret.extend(['--cross-execute', conf.env.CROSS_EXECUTE])
120 elif conf.env.CROSS_ANSWERS:
121 if msg is None:
122 raise Utils.WafError("Cannot have NULL msg in cross-answers")
123 ret.extend(['--cross-answers', os.path.join(Options.launch_dir, conf.env.CROSS_ANSWERS), msg])
125 if ret == []:
126 raise Utils.WafError("Cannot cross-compile without either --cross-execute or --cross-answers")
128 return ret
130 @conf
131 def SAMBA_CROSS_CHECK_COMPLETE(conf):
132 '''check if we have some unanswered questions'''
133 global cross_answers_incomplete
134 if conf.env.CROSS_COMPILE and cross_answers_incomplete:
135 raise Utils.WafError("Cross answers file %s is incomplete" % conf.env.CROSS_ANSWERS)
136 return True