Modules |
Files |
Inheritance Tree |
Inheritance Graph |
Name Index |
Config
File: Synopsis/Formatter/DUMP.py
1| # $Id: DUMP.py,v 1.14 2002/12/12 17:25:32 chalky Exp $
2| #
3| # This file is a part of Synopsis.
4| # Copyright (C) 2000, 2001 Stephen Davies
5| #
6| # Synopsis is free software; you can redistribute it and/or modify it
7| # under the terms of the GNU General Public License as published by
8| # the Free Software Foundation; either version 2 of the License, or
9| # (at your option) any later version.
10| #
11| # This program is distributed in the hope that it will be useful,
12| # but WITHOUT ANY WARRANTY; without even the implied warranty of
13| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14| # General Public License for more details.
15| #
16| # You should have received a copy of the GNU General Public License
17| # along with this program; if not, write to the Free Software
18| # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19| # 02111-1307, USA.
20| #
21| # $Log: DUMP.py,v $
22| # Revision 1.14 2002/12/12 17:25:32 chalky
23| # Implemented Include support for C++ parser. A few other minor fixes.
24| #
25| # Revision 1.13 2002/12/09 04:00:58 chalky
26| # Added multiple file support to parsers, changed AST datastructure to handle
27| # new information, added a demo to demo/C++. AST Declarations now have a
28| # reference to a SourceFile (which includes a filename) instead of a filename.
29| #
30| # Revision 1.12 2002/04/26 01:21:13 chalky
31| # Bugs and cleanups
32| #
33| # Revision 1.11 2001/07/19 04:00:39 chalky
34| # New .syn file format. Added -d, -t and -f flags
35| #
36| # Revision 1.10 2001/05/25 13:45:49 stefan
37| # fix problem with getopt error reporting
38| #
39| # Revision 1.9 2001/02/13 06:55:23 chalky
40| # Made synopsis -l work again
41| #
42| # Revision 1.8 2001/01/31 06:51:24 stefan
43| # add support for '-v' to all modules; modified toc lookup to use additional url as prefix
44| #
45| # Revision 1.7 2001/01/24 01:38:36 chalky
46| # Added docstrings to all modules
47| #
48| # Revision 1.6 2001/01/22 19:54:41 stefan
49| # better support for help message
50| #
51| # Revision 1.5 2001/01/22 17:06:15 stefan
52| # added copyright notice, and switched on logging
53| #
54| """
55| Verbose attribute-oriented dump of AST. Pipe into less -r
56| """
57|
58| # THIS-IS-A-FORMATTER
59| import sys, getopt, os, os.path, string, types
60| from Synopsis.Core import Type, AST
61|
62| verbose = 0
63|
64| class Dumper:
65| def __init__(self):
66| self.handlers = {
67| types.NoneType : self.visitNone,
68| types.TypeType : self.visitType,
69| types.IntType : self.visitInt,
70| types.LongType : self.visitLong,
71| types.FloatType : self.visitFloat,
72| types.StringType : self.visitString,
73| types.TupleType : self.visitTuple,
74| types.ListType : self.visitList,
75| types.DictType : self.visitDict,
76| types.InstanceType : self.visitInstance,
77| }
78| self.clear()
79| def clear(self):
80| self.indent_level = 0
81| self.indent_string = ""
82| self.newline = 1
83| self.visited = {}
84| def writeln(self, text):
85| self.write(text)
86| self.newline = 1
87| def lnwrite(self, text):
88| self.newline = 1
89| self.write(text)
90| def write(self, text):
91| if self.newline:
92| sys.stdout.write("\n")
93| sys.stdout.write(self.indent_string)
94| self.newline = 0
95| sys.stdout.write(str(text))
96| def indent(self, str=" "):
97| self.indent_level = self.indent_level + 1
98| self.indent_string = self.indent_string+str
99| def outdent(self):
100| self.indent_level = self.indent_level - 1
101| self.indent_string = self.indent_string[:-2]
102|
103| def visit(self, obj):
104| i,t = id(obj), type(obj)
105| if self.visited.has_key(i):
106| if t == types.InstanceType: t = obj.__class__.__name__+" instance"
107| if hasattr(obj, 'name'):
108| self.write("<already visited %s ( %d ) '%s'>"%(t,i,string.join(obj.name(),"::")))
109| elif hasattr(obj, 'filename'):
110| self.write("<already visited %s ( %d ) '%s'>"%(t,i,obj.filename()))
111| else:
112| self.write("<already visited %s ( %d )>"%(t,i))
113| return
114| if self.handlers.has_key(t):
115| self.handlers[t](obj)
116| else:
117| self.write("Unknown type %s for object: '%s'"%(t,obj))
118|
119| def visitNone(self, obj):
120| self.write(obj)
121| def visitType(self, obj):
122| self.write(obj)
123| def visitInt(self, obj):
124| self.write(obj)
125| def visitLong(self, obj):
126| self.write(obj)
127| def visitFloat(self, obj):
128| self.write(obj)
129| def visitString(self, obj):
130| import string
131| self.write('"%s"'%string.replace(obj,"\n","\\n"))
132| def visitTuple(self, obj):
133| if len(obj) == 0:
134| self.write("()")
135| return
136| # Check if all strings
137| strings = 1
138| for elem in obj:
139| if type(elem) != types.StringType:
140| strings = 0
141| break
142| if strings:
143| self.write("( "+string.join(obj,"::")+" )")
144| return
145| # Else write one per line
146| self.writeln("( ")
147| self.indent()
148| if len(obj): self.visit(obj[0])
149| for elem in obj[1:]:
150| self.write(", ")
151| self.visit(elem)
152| self.outdent()
153| self.lnwrite(")")
154| def visitList(self, obj):
155| if len(obj) == 0:
156| self.write("[]")
157| return
158| # Check if all strings
159| strings = 1
160| for elem in obj:
161| if type(elem) != types.StringType:
162| strings = 0
163| break
164| if strings:
165| self.write("[ "+string.join(obj,"::")+" ]")
166| return
167| self.writeln("[ ")
168| self.indent()
169| if len(obj): self.visit(obj[0])
170| for elem in obj[1:]:
171| self.writeln(", ")
172| self.visit(elem)
173| self.outdent()
174| self.lnwrite("]")
175| def _dictKey(self, key):
176| self.visit(key)
177| self.write(":")
178| def visitDict(self, dict, namefunc=None):
179| items = dict.items()
180| if len(items) == 0:
181| self.write("{}")
182| return
183| items.sort()
184| self.writeln("{ ")
185| if namefunc is None:
186| self.indent()
187| namefunc = self._dictKey
188| else:
189| self.indent(". ")
190| if len(items):
191| namefunc(items[0][0])
192| self.visit(items[0][1])
193| for item in items[1:]:
194| self.writeln(", ")
195| namefunc(item[0])
196| self.visit(item[1])
197| self.outdent()
198| self.lnwrite("}")
199| def _instAttr(self, name):
200| if type(name) != types.StringType:
201| return self.visit(name)
202| if name[0] != '_':
203| return self.write(name+" = ")
204| index = string.find(name, '__')
205| if index < 0:
206| return self.write(name+" = ")
207| self.write("%s::%s = "%(
208| name[1:index],
209| name[index+2:]
210| ))
211|
212| def visitInstance(self, obj):
213| global show_forwards
214| if isinstance(obj, AST.Forward) and not show_forwards: return
215| if isinstance(obj, AST.SourceFile) and not show_sourcefiles:
216| self.write("SourceFile: '%s'"%obj.filename())
217| return
218| if isinstance(obj, AST.Include):
219| self.write("Include: (macro:%d, next:%d) '%s'"%(obj.is_macro(),
220| obj.is_next(), obj.target().filename()))
221| return
222| self.visited[id(obj)] = None
223| self.write("[1m%s.%s[m = "%(
224| obj.__class__.__module__,
225| obj.__class__.__name__
226| ))
227| self.visitDict(obj.__dict__, self._instAttr)
228|
229| def usage():
230| """Print usage to stdout"""
231| print \
232| """
233| -o <file> Output file
234| -d Show declarations
235| -t Show types
236| -f Show forwards also
237| (If none of -d, -t or -f specified, will default to -d, -t)
238| """
239|
240| def __parseArgs(args):
241| global output, verbose, show_decls, show_types, show_forwards, show_files
242| # Set defaults
243| output = sys.stdout
244| show_decls = 0
245| show_types = 0
246| show_forwards = 0
247| show_files = 1
248|
249| try:
250| opts,remainder = getopt.getopt(args, "o:vdtf")
251| except getopt.error, e:
252| sys.stderr.write("Error in arguments: " + str(e) + "\n")
253| sys.exit(1)
254|
255| for opt in opts:
256| o,a = opt
257|
258| if o == "-o": output = open(a, "w")
259| elif o == "-v": verbose = 1
260| elif o == "-d": show_decls = 1
261| elif o == "-t": show_types = 1
262| elif o == "-f": show_forwards = 1
263|
264| # Consolidate - if no show_ selected, show decls and types
265| if not (show_decls or show_types or show_forwards):
266| show_decls = 1
267| show_types = 1
268|
269| def format(args, ast, config_obj):
270| global output, show_sourcefiles
271| __parseArgs(args)
272| #formatter = ASCIIFormatter(output)
273| #for type in dictionary:
274| # type.output(formatter)
275| dumper = Dumper()
276| show_sourcefiles = 0
277| if show_decls:
278| print "*** Declarations:"
279| dumper.visit(ast.declarations())
280| if show_types:
281| if show_decls: print "\n\n\n"
282| print "*** Types:"
283| dumper.visit(ast.types())
284| if show_files:
285| show_sourcefiles = 1
286| print "\n\n\n"
287| print "*** Files:"
288| dumper.visit(ast.files())