Modules |
Files |
Inheritance Tree |
Inheritance Graph |
Name Index |
Config
File: Synopsis/Linker/XRefCompiler.py
1| # $Id: XRefCompiler.py,v 1.4 2002/12/09 04:00:59 chalky Exp $
2| #
3| # This file is a part of Synopsis.
4| # Copyright (C) 2000, 2001 Stefan Seefeld
5| # Copyright (C) 2000, 2001 Stephen Davies
6| #
7| # Synopsis is free software; you can redistribute it and/or modify it
8| # under the terms of the GNU General Public License as published by
9| # the Free Software Foundation; either version 2 of the License, or
10| # (at your option) any later version.
11| #
12| # This program is distributed in the hope that it will be useful,
13| # but WITHOUT ANY WARRANTY; without even the implied warranty of
14| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15| # General Public License for more details.
16| #
17| # You should have received a copy of the GNU General Public License
18| # along with this program; if not, write to the Free Software
19| # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20| # 02111-1307, USA.
21| #
22| # $Log: XRefCompiler.py,v $
23| # Revision 1.4 2002/12/09 04:00:59 chalky
24| # Added multiple file support to parsers, changed AST datastructure to handle
25| # new information, added a demo to demo/C++. AST Declarations now have a
26| # reference to a SourceFile (which includes a filename) instead of a filename.
27| #
28| # Revision 1.3 2002/11/03 06:08:56 chalky
29| # Tolerate file not found errors
30| #
31| # Revision 1.2 2002/10/29 12:43:25 chalky
32| # Added no_locals support which is on by default, and strips local variables
33| # from cross reference tables
34| #
35| # Revision 1.1 2002/10/29 07:34:29 chalky
36| # New linker module, compiles xref files into data structure
37| #
38| #
39|
40| import string, cPickle, urllib
41|
42| from Synopsis.Core import AST, Type, Util
43|
44| from Linker import config, Operation
45|
46| def do_compile(input_files, output_file, no_locals):
47| # Init data structures
48| data = {}
49| index = {}
50| file_data = (data, index)
51|
52| # Read input files
53| for file in input_files:
54| if config.verbose: print "XRefCompiler: Reading",file
55| try:
56| f = open(file, 'rt')
57| except IOError, e:
58| print "Error opening %s: %s"%(file, e)
59| continue
60|
61| lines = f.readlines()
62| f.close()
63|
64| for line in lines:
65| target, file, line, scope, context = string.split(line)
66| target = tuple(map(intern, string.split(urllib.unquote(target), '\t')))
67| scope = map(intern, string.split(urllib.unquote(scope), '\t'))
68| line = int(line)
69| file = intern(file)
70|
71| if no_locals:
72| bad = 0
73| for i in range(len(target)):
74| if len(target[i]) > 0 and target[i][0] == '`':
75| # Don't store local function variables
76| bad = 1
77| break
78| if bad: continue
79|
80| for i in range(len(scope)):
81| if len(scope[i]) > 0 and scope[i][0] == '`':
82| # Function scope, truncate here
83| del scope[i+1:]
84| scope[i] = scope[i][1:]
85| break
86| scope = tuple(scope)
87|
88| target_data = data.setdefault(target, [[],[],[]])
89| if context == 'DEF':
90| target_data[0].append( (file, line, scope) )
91| elif context == 'CALL':
92| target_data[1].append( (file, line, scope) )
93| elif context == 'REF':
94| target_data[2].append( (file, line, scope) )
95| else:
96| print "Warning: Unknown context:",context
97|
98| # Sort the data
99| for target, target_data in data.items():
100| target_data[1].sort()
101| target_data[2].sort()
102|
103| name = target[-1]
104| index.setdefault(name,[]).append(target)
105| # If it's a function name, also add without the parameters
106| paren = name.find('(')
107| if paren != -1:
108| index.setdefault(name[:paren],[]).append(target)
109|
110| if config.verbose: print "XRefCompiler: Writing",output_file
111| f = open(output_file, 'wb')
112| cPickle.dump(file_data, f)
113| f.close()
114|
115| class XRefCompiler(Operation):
116| """This class compiles a set of text-based xref files from the C++ parser
117| into a cPickled data structure with a name index.
118|
119| The format of the data structure is:
120| <pre>
121| (data, index) = cPickle.load()
122| data = dict<scoped targetname, target_data>
123| index = dict<name, list<scoped targetname>>
124| target_data = (definitions = list<target_info>,
125| func calls = list<target_info>,
126| references = list<target_info>)
127| target_info = (filename, int(line number), scoped context name)
128| </pre>
129| The scoped targetnames in the index are guaranteed to exist in the data
130| dictionary.
131| """
132| def __init__(self):
133| self.__xref_path = './%s-xref'
134| self.__xref_file = 'compiled.xref'
135| self.__no_locals = 1
136| if hasattr(config.obj, 'XRefCompiler'):
137| obj = config.obj.XRefCompiler
138| if hasattr(obj, 'xref_path'):
139| self.__xref_path = obj.xref_path
140| if hasattr(obj, 'xref_file'):
141| self.__xref_file = obj.xref_file
142| if hasattr(obj, 'no_locals'):
143| self.__no_locals = obj.no_locals
144| def execute(self, ast):
145| filenames = map(lambda x: x[0],
146| filter(lambda x: x[1].is_main(),
147| ast.files().items()))
148| filenames = map(lambda x:self.__xref_path%x, filenames)
149| do_compile(filenames, self.__xref_file, self.__no_locals)
150|
151| linkerOperation = XRefCompiler