OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2017 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. |
| 5 |
| 6 """This script is used to network extract traffic annotations from Chromium. |
| 7 """ |
| 8 |
| 9 import argparse |
| 10 # import google.protobuf.text_format |
| 11 import os |
| 12 import subprocess |
| 13 import sys |
| 14 |
| 15 # out/Debug/protoc --python_out=tools/traffic_annotation/auditor |
| 16 # --proto_path=out/Debug/gen/components/policy/proto --proto_path= |
| 17 # tools/traffic_annotation tools/traffic_annotation/traffic_annotation.proto |
| 18 |
| 19 #import traffic_annotation_pb2 |
| 20 # import distutils.spawn |
| 21 # import glob |
| 22 # import os |
| 23 # import pipes |
| 24 # import re |
| 25 # import shutil |
| 26 # |
| 27 # import stat |
| 28 # |
| 29 # import tarfile |
| 30 # import tempfile |
| 31 # import time |
| 32 # import urllib2 |
| 33 # import zipfile |
| 34 |
| 35 |
| 36 def _RunClangTool(src_dir, build_dir, path_filters): |
| 37 """Executes the clang tool too extract annotations. |
| 38 Args: |
| 39 src_dir: str Path to the src directory of Chromium. |
| 40 build_dir: str Path to the build directory. |
| 41 path_filters: list of str List of paths to source directories for |
| 42 extraction. |
| 43 |
| 44 Returns: |
| 45 raw_annotaions: str Extracted content and meta data of annotations. |
| 46 """ |
| 47 raw_annotations = "" |
| 48 for path in path_filters: |
| 49 args = [ |
| 50 src_dir + "/tools/clang/scripts/run_tool.py", |
| 51 "--generate-compdb", |
| 52 "traffic_annotation_extractor", |
| 53 build_dir, path] |
| 54 command = subprocess.Popen(args, stdout=subprocess.PIPE, |
| 55 stderr=subprocess.PIPE) |
| 56 stdout_text, stderr_text = command.communicate() |
| 57 raw_annotations += stdout_text |
| 58 if stderr_text: |
| 59 print stderr_text |
| 60 return raw_annotations |
| 61 |
| 62 |
| 63 def _ParsRawAnnotations(raw_annotations): |
| 64 """Parses raw annotations texts. |
| 65 Args: |
| 66 raw_annotations: str Serialization of annotations and meta data. Each |
| 67 annotation should have the following lines: |
| 68 1- ==== NEW ANNOTATION ==== |
| 69 2- File path. |
| 70 3- Name of the function including this position. |
| 71 4- Line number. |
| 72 5- Unique id of annotation. |
| 73 6- Serialization of annotation text (several lines) |
| 74 n- ==== ANNOTATION ENDS ==== |
| 75 |
| 76 Returns: |
| 77 annotations: list of dict List of dictionaries including annotations and |
| 78 meta data. |
| 79 errors: list of dict List of errors. |
| 80 """ |
| 81 annotations = [] |
| 82 errors = [] |
| 83 |
| 84 lines = raw_annotations.split("\n") |
| 85 current = 0 |
| 86 |
| 87 try: |
| 88 while current < len(lines) - 1: |
| 89 if lines[current] != "==== NEW ANNOTATION ====": |
| 90 raise Exception( |
| 91 "Error at line %i, expected starting new annotaion." % current) |
| 92 if current + 5 >= len(lines): |
| 93 raise Exception( |
| 94 "Not enough header lines at line %i." % current) |
| 95 |
| 96 new_annotation = {'file_path': lines[current + 1], |
| 97 'function_name': lines[current + 2], |
| 98 'line_number': lines[current + 3], |
| 99 'unique_id': lines[current + 4]} |
| 100 current += 5 |
| 101 annotation_text = "" |
| 102 |
| 103 while current < len(lines): |
| 104 current += 1 |
| 105 if lines[current - 1] == "==== ANNOTATION ENDS ====": |
| 106 break |
| 107 else: |
| 108 annotation_text += lines[current - 1] |
| 109 else: |
| 110 raise Exception( |
| 111 "Error at line %i, expected annotation end tag." % current) |
| 112 |
| 113 # Parse annotation text. |
| 114 annotation_proto = traffic_annotation_pb2.NetworkTrafficAnnotations() |
| 115 |
| 116 |
| 117 new_annotation['annotation_text'] = annotation_text |
| 118 annotations.append(new_annotation) |
| 119 except Exception as error: |
| 120 print error |
| 121 return [], [] |
| 122 |
| 123 print annotations |
| 124 |
| 125 return annotations, errors |
| 126 |
| 127 |
| 128 def main(): |
| 129 parser = argparse.ArgumentParser(description='Traffic Annotation Auditor.') |
| 130 parser.add_argument('--build-dir', |
| 131 help='Path to the build directory.') |
| 132 parser.add_argument('--extractor-output', |
| 133 help='Optional path to the temporary file that extracted ' |
| 134 'annotations will be stored.') |
| 135 parser.add_argument('--extractor-input', |
| 136 help='Optional Path to the file that temporary extracted ' |
| 137 'annotations are already stored in. If this is ' |
| 138 'provided, clang tool is not run and this is used ' |
| 139 'as input.') |
| 140 parser.add_argument('--summary-file', |
| 141 help='Path to the output file.') |
| 142 parser.add_argument('path_filters', |
| 143 nargs='*', |
| 144 help='optional paths to filter what files the tool is ' |
| 145 'run on.') |
| 146 args = parser.parse_args() |
| 147 |
| 148 if not args.summary_file: |
| 149 print "Warning: Output file not specified." |
| 150 |
| 151 if args.extractor_input: |
| 152 with open(args.extractor_input, 'r') as raw_file: |
| 153 raw_annotations = raw_file.read() |
| 154 else: |
| 155 # Either extacted input file or build directory should be provided. |
| 156 if not args.build_dir: |
| 157 print "You must either specify the build directory to run the clang " \ |
| 158 "tool and extract annotations, or specify the input directory " \ |
| 159 "where extracted annotation files already exist.\n" |
| 160 return |
| 161 |
| 162 # Output diretory is usually two steps in src directory, so the path to |
| 163 # source is extracted by moving two directories up. |
| 164 raw_annotations = _RunClangTool( |
| 165 args.build_dir + "/../..", args.build_dir, |
| 166 args.path_filters if args.path_filters else ["./"]) |
| 167 |
| 168 if args.extractor_output: |
| 169 with open(args.extractor_output, 'w') as raw_file: |
| 170 raw_file.write(raw_annotations) |
| 171 |
| 172 _ParsRawAnnotations(raw_annotations) |
| 173 |
| 174 |
| 175 # if (instances.empty()) { |
| 176 # LOG(ERROR) << "Could not read any file.\n"; |
| 177 # return 1; |
| 178 # } else { |
| 179 # MarkRepeatedUniqueIds(&instances); |
| 180 # } |
| 181 |
| 182 # // Create Summary file if requested. |
| 183 # if (!summary_file.empty() && |
| 184 # !WriteSummaryFile(clang_tool_exit_code, instances, errors, summary_file)
) |
| 185 # return 1; |
| 186 |
| 187 |
| 188 |
| 189 |
| 190 |
| 191 if __name__ == '__main__': |
| 192 sys.exit(main()) |
OLD | NEW |