| OLD | NEW |
| (Empty) |
| 1 #! /usr/bin/python | |
| 2 # -*- coding: utf-8 -*- | |
| 3 # | |
| 4 # Copyright (C) 2011-2014, International Business Machines | |
| 5 # Corporation and others. All Rights Reserved. | |
| 6 # | |
| 7 # file name: dependencies.py | |
| 8 # | |
| 9 # created on: 2011may26 | |
| 10 | |
| 11 """Reader module for dependency data for the ICU dependency tester. | |
| 12 | |
| 13 Reads dependencies.txt and makes the data available. | |
| 14 | |
| 15 Attributes: | |
| 16 files: Set of "library/filename.o" files mentioned in the dependencies file. | |
| 17 items: Map from library or group names to item maps. | |
| 18 Each item has a "type" ("library" or "group" or "system_symbols"). | |
| 19 A library or group item can have an optional set of "files" (as in the files
attribute). | |
| 20 Each item can have an optional set of "deps" (libraries & groups). | |
| 21 A group item also has a "library" name unless it is a group of system symbol
s. | |
| 22 The one "system_symbols" item and its groups have sets of "system_symbols" | |
| 23 with standard-library system symbol names. | |
| 24 libraries: Set of library names mentioned in the dependencies file. | |
| 25 file_to_item: Map from a symbol (ushoe.o) to library or group (shoesize) | |
| 26 """ | |
| 27 __author__ = "Markus W. Scherer" | |
| 28 | |
| 29 # TODO: Support binary items. | |
| 30 # .txt syntax: binary: tools/genrb | |
| 31 # item contents: {"type": "binary"} with optional files & deps | |
| 32 # A binary must not be used as a dependency for anything else. | |
| 33 | |
| 34 import sys | |
| 35 | |
| 36 files = set() | |
| 37 items = {} | |
| 38 libraries = set() | |
| 39 file_to_item = {} | |
| 40 | |
| 41 _line_number = 0 | |
| 42 _groups_to_be_defined = set() | |
| 43 | |
| 44 def _CheckLibraryName(name): | |
| 45 global _line_number | |
| 46 if not name: | |
| 47 sys.exit("Error:%d: \"library: \" without name" % _line_number) | |
| 48 if name.endswith(".o"): | |
| 49 sys.exit("Error:%d: invalid library name %s" % (_line_number, name)) | |
| 50 | |
| 51 def _CheckGroupName(name): | |
| 52 global _line_number | |
| 53 if not name: | |
| 54 sys.exit("Error:%d: \"group: \" without name" % _line_number) | |
| 55 if "/" in name or name.endswith(".o"): | |
| 56 sys.exit("Error:%d: invalid group name %s" % (_line_number, name)) | |
| 57 | |
| 58 def _CheckFileName(name): | |
| 59 global _line_number | |
| 60 if "/" in name or not name.endswith(".o"): | |
| 61 sys.exit("Error:%d: invalid file name %s" % (_line_number, name)) | |
| 62 | |
| 63 def _RemoveComment(line): | |
| 64 global _line_number | |
| 65 _line_number = _line_number + 1 | |
| 66 index = line.find("#") # Remove trailing comment. | |
| 67 if index >= 0: line = line[:index] | |
| 68 return line.rstrip() # Remove trailing newlines etc. | |
| 69 | |
| 70 def _ReadLine(f): | |
| 71 while True: | |
| 72 line = _RemoveComment(f.next()) | |
| 73 if line: return line | |
| 74 | |
| 75 def _ReadFiles(deps_file, item, library_name): | |
| 76 global files | |
| 77 item_files = item.get("files") | |
| 78 while True: | |
| 79 line = _ReadLine(deps_file) | |
| 80 if not line: continue | |
| 81 if not line.startswith(" "): return line | |
| 82 if item_files == None: item_files = item["files"] = set() | |
| 83 for file_name in line.split(): | |
| 84 _CheckFileName(file_name) | |
| 85 file_name = library_name + "/" + file_name | |
| 86 if file_name in files: | |
| 87 sys.exit("Error:%d: file %s listed in multiple groups" % (_line_number,
file_name)) | |
| 88 files.add(file_name) | |
| 89 item_files.add(file_name) | |
| 90 file_to_item[file_name] = item["name"] | |
| 91 | |
| 92 def _IsLibrary(item): return item and item["type"] == "library" | |
| 93 | |
| 94 def _IsLibraryGroup(item): return item and "library" in item | |
| 95 | |
| 96 def _ReadDeps(deps_file, item, library_name): | |
| 97 global items, _line_number, _groups_to_be_defined | |
| 98 item_deps = item.get("deps") | |
| 99 while True: | |
| 100 line = _ReadLine(deps_file) | |
| 101 if not line: continue | |
| 102 if not line.startswith(" "): return line | |
| 103 if item_deps == None: item_deps = item["deps"] = set() | |
| 104 for dep in line.split(): | |
| 105 _CheckGroupName(dep) | |
| 106 dep_item = items.get(dep) | |
| 107 if item["type"] == "system_symbols" and (_IsLibraryGroup(dep_item) or _IsL
ibrary(dep_item)): | |
| 108 sys.exit(("Error:%d: system_symbols depend on previously defined " + | |
| 109 "library or library group %s") % (_line_number, dep)) | |
| 110 if dep_item == None: | |
| 111 # Add this dependency as a new group. | |
| 112 items[dep] = {"type": "group"} | |
| 113 if library_name: items[dep]["library"] = library_name | |
| 114 _groups_to_be_defined.add(dep) | |
| 115 item_deps.add(dep) | |
| 116 | |
| 117 def _AddSystemSymbol(item, symbol): | |
| 118 exports = item.get("system_symbols") | |
| 119 if exports == None: exports = item["system_symbols"] = set() | |
| 120 exports.add(symbol) | |
| 121 | |
| 122 def _ReadSystemSymbols(deps_file, item): | |
| 123 global _line_number | |
| 124 while True: | |
| 125 line = _ReadLine(deps_file) | |
| 126 if not line: continue | |
| 127 if not line.startswith(" "): return line | |
| 128 line = line.lstrip() | |
| 129 if '"' in line: | |
| 130 # One double-quote-enclosed symbol on the line, allows spaces in a symbol
name. | |
| 131 symbol = line[1:-1] | |
| 132 if line.startswith('"') and line.endswith('"') and '"' not in symbol: | |
| 133 _AddSystemSymbol(item, symbol) | |
| 134 else: | |
| 135 sys.exit("Error:%d: invalid quoted symbol name %s" % (_line_number, line
)) | |
| 136 else: | |
| 137 # One or more space-separate symbols. | |
| 138 for symbol in line.split(): _AddSystemSymbol(item, symbol) | |
| 139 | |
| 140 def Load(): | |
| 141 """Reads "dependencies.txt" and populates the module attributes.""" | |
| 142 global items, libraries, _line_number, _groups_to_be_defined | |
| 143 deps_file = open("dependencies.txt") | |
| 144 try: | |
| 145 line = None | |
| 146 current_type = None | |
| 147 while True: | |
| 148 while not line: line = _RemoveComment(deps_file.next()) | |
| 149 | |
| 150 if line.startswith("library: "): | |
| 151 current_type = "library" | |
| 152 name = line[9:].lstrip() | |
| 153 _CheckLibraryName(name) | |
| 154 if name in items: | |
| 155 sys.exit("Error:%d: library definition using duplicate name %s" % (_li
ne_number, name)) | |
| 156 libraries.add(name) | |
| 157 item = items[name] = {"type": "library", "name": name} | |
| 158 line = _ReadFiles(deps_file, item, name) | |
| 159 elif line.startswith("group: "): | |
| 160 current_type = "group" | |
| 161 name = line[7:].lstrip() | |
| 162 _CheckGroupName(name) | |
| 163 if name not in items: | |
| 164 sys.exit("Error:%d: group %s defined before mentioned as a dependency"
% | |
| 165 (_line_number, name)) | |
| 166 if name not in _groups_to_be_defined: | |
| 167 sys.exit("Error:%d: group definition using duplicate name %s" % (_line
_number, name)) | |
| 168 _groups_to_be_defined.remove(name) | |
| 169 item = items[name] | |
| 170 item["name"] = name | |
| 171 library_name = item.get("library") | |
| 172 if library_name: | |
| 173 line = _ReadFiles(deps_file, item, library_name) | |
| 174 else: | |
| 175 line = _ReadSystemSymbols(deps_file, item) | |
| 176 elif line == " deps": | |
| 177 if current_type == "library": | |
| 178 line = _ReadDeps(deps_file, items[name], name) | |
| 179 elif current_type == "group": | |
| 180 item = items[name] | |
| 181 line = _ReadDeps(deps_file, item, item.get("library")) | |
| 182 elif current_type == "system_symbols": | |
| 183 item = items[current_type] | |
| 184 line = _ReadDeps(deps_file, item, None) | |
| 185 else: | |
| 186 sys.exit("Error:%d: deps before any library or group" % _line_number) | |
| 187 elif line == "system_symbols:": | |
| 188 current_type = "system_symbols" | |
| 189 if current_type in items: | |
| 190 sys.exit("Error:%d: duplicate entry for system_symbols" % _line_number
) | |
| 191 item = items[current_type] = {"type": current_type, "name": current_type
} | |
| 192 line = _ReadSystemSymbols(deps_file, item) | |
| 193 else: | |
| 194 sys.exit("Syntax error:%d: %s" % (_line_number, line)) | |
| 195 except StopIteration: | |
| 196 pass | |
| 197 if _groups_to_be_defined: | |
| 198 sys.exit("Error: some groups mentioned in dependencies are undefined: %s" %
_groups_to_be_defined) | |
| OLD | NEW |