s3: smbd: Deliberately currupt an uninitialized pointer.
[Samba.git] / buildtools / wafsamba / samba_cross.py
blob7ec1edc52ea50fcf85472033e79689562716efe9
1 # functions for handling cross-compilation
3 import os, sys, re, shlex
4 from waflib import Utils, Logs, Options, Errors, Context
5 from waflib.Configure import conf
6 from wafsamba import samba_utils
8 real_Popen = None
10 ANSWER_UNKNOWN = (254, "")
11 ANSWER_NO = (1, "")
12 ANSWER_OK = (0, "")
14 cross_answers_incomplete = False
17 def add_answer(ca_file, msg, answer):
18 '''add an answer to a set of cross answers'''
19 try:
20 f = open(ca_file, 'a')
21 except:
22 Logs.error("Unable to open cross-answers file %s" % ca_file)
23 sys.exit(1)
24 (retcode, retstring) = answer
25 # if retstring is more than one line then we probably
26 # don't care about its actual content (the tests should
27 # yield one-line output in order to comply with the cross-answer
28 # format)
29 retstring = retstring.strip()
30 if len(retstring.split('\n')) > 1:
31 retstring = ''
32 answer = (retcode, retstring)
34 if answer == ANSWER_OK:
35 f.write('%s: OK\n' % msg)
36 elif answer == ANSWER_UNKNOWN:
37 f.write('%s: UNKNOWN\n' % msg)
38 elif answer == ANSWER_NO:
39 f.write('%s: NO\n' % msg)
40 else:
41 if retcode == 0:
42 f.write('%s: "%s"\n' % (msg, retstring))
43 else:
44 f.write('%s: (%d, "%s")\n' % (msg, retcode, retstring))
45 f.close()
48 def cross_answer(ca_file, msg):
49 '''return a (retcode,retstring) tuple from a answers file'''
50 try:
51 f = open(ca_file, 'r')
52 except:
53 return ANSWER_UNKNOWN
54 for line in f:
55 line = line.strip()
56 if line == '' or line[0] == '#':
57 continue
58 if line.find(':') != -1:
59 a = line.split(':', 1)
60 thismsg = a[0].strip()
61 if thismsg != msg:
62 continue
63 ans = a[1].strip()
64 if ans == "OK" or ans == "YES":
65 f.close()
66 return ANSWER_OK
67 elif ans == "UNKNOWN":
68 f.close()
69 return ANSWER_UNKNOWN
70 elif ans == "FAIL" or ans == "NO":
71 f.close()
72 return ANSWER_NO
73 elif ans[0] == '"':
74 f.close()
75 return (0, ans.strip('"'))
76 elif ans[0] == "'":
77 f.close()
78 return (0, ans.strip("'"))
79 else:
80 m = re.match(r'\(\s*(-?\d+)\s*,\s*\"(.*)\"\s*\)', ans)
81 if m:
82 f.close()
83 return (int(m.group(1)), m.group(2))
84 else:
85 raise Errors.WafError("Bad answer format '%s' in %s" % (line, ca_file))
86 f.close()
87 return ANSWER_UNKNOWN
90 class cross_Popen(Utils.subprocess.Popen):
91 '''cross-compilation wrapper for Popen'''
92 def __init__(*k, **kw):
93 (obj, args) = k
94 use_answers = False
95 ans = ANSWER_UNKNOWN
97 # Three possibilities:
98 # 1. Only cross-answers - try the cross-answers file, and if
99 # there's no corresponding answer, add to the file and mark
100 # the configure process as unfinished.
101 # 2. Only cross-execute - get the answer from cross-execute
102 # 3. Both - try the cross-answers file, and if there is no
103 # corresponding answer - use cross-execute to get an answer,
104 # and add that answer to the file.
105 if '--cross-answers' in args:
106 # when --cross-answers is set, then change the arguments
107 # to use the cross answers if available
108 use_answers = True
109 i = args.index('--cross-answers')
110 ca_file = args[i+1]
111 msg = args[i+2]
112 ans = cross_answer(ca_file, msg)
114 if '--cross-execute' in args and ans == ANSWER_UNKNOWN:
115 # when --cross-execute is set, then change the arguments
116 # to use the cross emulator
117 i = args.index('--cross-execute')
118 newargs = shlex.split(args[i+1])
119 newargs.extend(args[0:i])
120 if use_answers:
121 p = real_Popen(newargs,
122 stdout=Utils.subprocess.PIPE,
123 stderr=Utils.subprocess.PIPE,
124 env=kw.get('env', {}))
125 ce_out, ce_err = p.communicate()
126 ans = (p.returncode, samba_utils.get_string(ce_out))
127 add_answer(ca_file, msg, ans)
128 else:
129 args = newargs
131 if use_answers:
132 if ans == ANSWER_UNKNOWN:
133 global cross_answers_incomplete
134 cross_answers_incomplete = True
135 add_answer(ca_file, msg, ans)
136 (retcode, retstring) = ans
137 args = ['/bin/sh', '-c', "printf %%s '%s'; exit %d" % (retstring, retcode)]
138 real_Popen.__init__(*(obj, args), **kw)
141 @conf
142 def SAMBA_CROSS_ARGS(conf, msg=None):
143 '''get test_args to pass when running cross compiled binaries'''
144 if not conf.env.CROSS_COMPILE:
145 return []
147 global real_Popen
148 if real_Popen is None:
149 real_Popen = Utils.subprocess.Popen
150 Utils.subprocess.Popen = cross_Popen
151 Utils.run_process = Utils.run_regular_process
152 Utils.get_process = Utils.alloc_process_pool = Utils.nada
154 ret = []
156 if conf.env.CROSS_EXECUTE:
157 ret.extend(['--cross-execute', conf.env.CROSS_EXECUTE])
159 if conf.env.CROSS_ANSWERS:
160 if msg is None:
161 raise Errors.WafError("Cannot have NULL msg in cross-answers")
162 ret.extend(['--cross-answers', os.path.join(Context.launch_dir, conf.env.CROSS_ANSWERS), msg])
164 if ret == []:
165 raise Errors.WafError("Cannot cross-compile without either --cross-execute or --cross-answers")
167 return ret
169 @conf
170 def SAMBA_CROSS_CHECK_COMPLETE(conf):
171 '''check if we have some unanswered questions'''
172 global cross_answers_incomplete
173 if conf.env.CROSS_COMPILE and cross_answers_incomplete:
174 raise Errors.WafError("Cross answers file %s is incomplete" % conf.env.CROSS_ANSWERS)
175 return True