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