Index: src/trusted/validator/x86/testing/tf/annotate_tf.py |
diff --git a/src/trusted/validator/x86/testing/tf/annotate_tf.py b/src/trusted/validator/x86/testing/tf/annotate_tf.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..7120a015ad54786ef7e60f9ab7122dc7711c5447 |
--- /dev/null |
+++ b/src/trusted/validator/x86/testing/tf/annotate_tf.py |
@@ -0,0 +1,118 @@ |
+#!/usr/bin/python |
+# |
+# Copyright (c) 2012 The Native Client Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+import cStringIO |
+import difflib |
+import glob |
+import optparse |
+import sys |
+ |
+import tf |
+import val_runner |
+ |
+ |
+def Annotate(validators, input_lines): |
+ test = tf.Test.Parse(input_lines) |
+ |
+ instrs = test.instructions |
+ |
+ for validator in validators: |
+ for i in instrs: |
+ i.outs[validator] = [] |
+ |
+ validation_results = test.RunValidator(validator) |
+ test.safe = validation_results.safe |
+ |
+ for offset, message in validation_results.errors: |
+ for i in reversed(instrs): |
+ if offset not in range(i.offset, i.end_offset): |
+ continue |
+ |
+ offset_prefix = '' |
+ if offset != i.offset: |
+ offset_prefix = '[at +%s] ' % (offset - i.offset) |
+ |
+ i.outs[validator].append(offset_prefix + message) |
+ break |
+ else: |
+ # If error does not belong to any instruction, |
+ # we just add it to the first instruction |
+ print '**************** orphan error:', (offset, message) |
+ i = instrs[0] |
+ i.outs[validator].append('[at +%s] %s' % (offset - i.offset, message)) |
+ |
+ fout = cStringIO.StringIO() |
+ test.Print(fout) |
+ fout.seek(0) |
+ return fout.readlines() |
+ |
+ |
+def main(): |
+ parser = optparse.OptionParser('%prog [options] <tf file or wildcard>') |
+ parser.add_option( |
+ '--update', |
+ action='store_true', |
+ default=False, |
+ help=('not only print diff for annotated files, but actually' |
+ 'update them in place') |
+ ) |
+ parser.add_option( |
+ '--validator', |
+ type=str, |
+ help=('only use one specific validator (one of the %s)' % |
+ ', '.join(val_runner.VALIDATORS)) |
+ ) |
+ val_runner.AddValidatorsOptions(parser) |
+ |
+ options, args = parser.parse_args() |
+ |
+ val_runner.ProcessValidatorsOptions(options) |
+ |
+ if len(args) != 1: |
+ parser.error('specify tf file or wildcard') |
+ |
+ if options.validator is not None: |
+ validators = [options.validator] |
+ else: |
+ validators = val_runner.VALIDATORS |
+ |
+ pattern = args[0] |
+ |
+ num_files = 0 |
+ differ = False |
+ for name in glob.glob(pattern): |
+ num_files += 1 |
+ if options.update: |
+ print '=' * 3, name |
+ |
+ with open(name) as fin: |
+ original_lines = fin.readlines() |
+ |
+ annotated_lines = Annotate(validators, original_lines) |
+ |
+ diff = difflib.unified_diff(original_lines, annotated_lines, |
+ fromfile=name, tofile=name) |
+ |
+ for line in diff: |
+ print line.rstrip() |
+ differ = True |
+ |
+ if options.update: |
+ # We are always using unix-style newlines. |
+ with open(name, mode='wb') as fout: |
+ fout.writelines(annotated_lines) |
+ |
+ if not options.update: |
+ if differ: |
+ print 'there were differences' |
+ sys.exit(1) |
+ else: |
+ print num_files, 'files were checked, no differences' |
+ sys.exit(0) |
+ |
+ |
+if __name__ == '__main__': |
+ main() |