ia64/xen-unstable

view tools/python/xen/xend/PrettyPrint.py @ 6538:84ee014ebd41

Merge xen-vtx-unstable.hg
author adsharma@los-vmm.sc.intel.com
date Wed Aug 17 12:34:38 2005 -0800 (2005-08-17)
parents 23979fb12c49 f40c6650152e
children 99914b54f7bf
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
16 #============================================================================
18 """General pretty-printer, including support for SXP.
20 """
21 import sys
22 import types
23 import StringIO
24 import sxp
26 class PrettyItem:
28 def __init__(self, width):
29 self.width = width
31 def insert(self, block):
32 block.addtoline(self)
34 def get_width(self):
35 return self.width
37 def output(self, out):
38 print '***PrettyItem>output>', self
39 pass
41 def prettyprint(self, out, width):
42 print '***PrettyItem>prettyprint>', self
43 return width
45 class PrettyString(PrettyItem):
47 def __init__(self, x):
48 PrettyItem.__init__(self, len(x))
49 self.value = x
51 def output(self, out):
52 out.write(self.value)
54 def prettyprint(self, line):
55 line.output(self)
57 def show(self, out):
58 print >> out, ("(string (width %d) '%s')" % (self.width, self.value))
60 class PrettySpace(PrettyItem):
62 def output(self, out):
63 out.write(' ' * self.width)
65 def prettyprint(self, line):
66 line.output(self)
68 def show(self, out):
69 print >> out, ("(space (width %d))" % self.width)
71 class PrettyBreak(PrettyItem):
73 def __init__(self, width, indent):
74 PrettyItem.__init__(self, width)
75 self.indent = indent
76 self.space = 0
77 self.active = 0
79 def output(self, out):
80 out.write(' ' * self.width)
82 def prettyprint(self, line):
83 if line.breaks(self.space):
84 self.active = 1
85 line.newline(self.indent)
86 else:
87 line.output(self)
89 def show(self, out):
90 print >> out, ("(break (width %d) (indent %d) (space %d) (active %d))"
91 % (self.width, self.indent, self.space, self.lspace, self.active))
93 class PrettyNewline(PrettySpace):
95 def __init__(self, indent):
96 PrettySpace.__init__(self, indent)
98 def insert(self, block):
99 block.newline()
100 block.addtoline(self)
102 def output(self, out):
103 out.write(' ' * self.width)
105 def prettyprint(self, line):
106 line.newline(0)
107 line.output(self)
109 def show(self, out):
110 print >> out, ("(nl (indent %d))" % self.indent)
112 class PrettyLine(PrettyItem):
113 def __init__(self):
114 PrettyItem.__init__(self, 0)
115 self.content = []
117 def write(self, x):
118 self.content.append(x)
120 def end(self):
121 width = 0
122 lastwidth = 0
123 lastbreak = None
124 for x in self.content:
125 if isinstance(x, PrettyBreak):
126 if lastbreak:
127 lastbreak.space = (width - lastwidth)
128 lastbreak = x
129 lastwidth = width
130 width += x.get_width()
131 if lastbreak:
132 lastbreak.space = (width - lastwidth)
133 self.width = width
135 def prettyprint(self, line):
136 for x in self.content:
137 x.prettyprint(line)
139 def show(self, out):
140 print >> out, '(LINE (width %d)' % self.width
141 for x in self.content:
142 x.show(out)
143 print >> out, ')'
145 class PrettyBlock(PrettyItem):
147 def __init__(self, all=0, parent=None):
148 self.width = 0
149 self.lines = []
150 self.parent = parent
151 self.indent = 0
152 self.all = all
153 self.broken = 0
154 self.newline()
156 def add(self, item):
157 item.insert(self)
159 def end(self):
160 self.width = 0
161 for l in self.lines:
162 l.end()
163 if self.width < l.width:
164 self.width = l.width
166 def breaks(self, n):
167 return self.all and self.broken
169 def newline(self):
170 self.lines.append(PrettyLine())
172 def addtoline(self, x):
173 self.lines[-1].write(x)
175 def prettyprint(self, line):
176 self.indent = line.used
177 line.block = self
178 if not line.fits(self.width):
179 self.broken = 1
180 for l in self.lines:
181 l.prettyprint(line)
182 line.block = self.parent
184 def show(self, out):
185 print >> out, ('(BLOCK (width %d) (indent %d) (all %d) (broken %d)' %
186 (self.width, self.indent, self.all, self.broken))
187 for l in self.lines:
188 l.show(out)
189 print >> out, ')'
191 class Line:
193 def __init__(self, out, width):
194 self.out = out
195 self.width = width
196 self.used = 0
197 self.space = self.width
199 def newline(self, indent):
200 indent += self.block.indent
201 self.out.write('\n')
202 self.out.write(' ' * indent)
203 self.used = indent
204 self.space = self.width - self.used
206 def fits(self, n):
207 return self.space - n >= 0
209 def breaks(self, n):
210 return self.block.breaks(n) or not self.fits(n)
212 def output(self, x):
213 n = x.get_width()
214 self.space -= n
215 self.used += n
216 if self.space < 0:
217 self.space = 0
218 x.output(self.out)
220 class PrettyPrinter:
221 """A prettyprinter based on what I remember of Derek Oppen's
222 prettyprint algorithm from TOPLAS way back.
223 """
225 def __init__(self, width=40):
226 self.width = width
227 self.block = None
228 self.top = None
230 def write(self, x):
231 self.block.add(PrettyString(x))
233 def add(self, item):
234 self.block.add(item)
236 def addbreak(self, width=1, indent=4):
237 self.add(PrettyBreak(width, indent))
239 def addspace(self, width=1):
240 self.add(PrettySpace(width))
242 def addnl(self, indent=0):
243 self.add(PrettyNewline(indent))
245 def begin(self, all=0):
246 block = PrettyBlock(all=all, parent=self.block)
247 self.block = block
249 def end(self):
250 self.block.end()
251 if self.block.parent:
252 self.block.parent.add(self.block)
253 else:
254 self.top = self.block
255 self.block = self.block.parent
257 def prettyprint(self, out=sys.stdout):
258 line = Line(out, self.width)
259 self.top.prettyprint(line)
261 class SXPPrettyPrinter(PrettyPrinter):
262 """An SXP prettyprinter.
263 """
265 def pstring(self, x):
266 io = StringIO.StringIO()
267 sxp.show(x, out=io)
268 io.seek(0)
269 val = io.getvalue()
270 io.close()
271 return val
273 def pprint(self, l):
274 if isinstance(l, types.ListType):
275 self.begin(all=1)
276 self.write('(')
277 i = 0
278 for x in l:
279 if(i): self.addbreak()
280 self.pprint(x)
281 i += 1
282 self.addbreak(width=0, indent=0)
283 self.write(')')
284 self.end()
285 else:
286 self.write(self.pstring(l))
288 def prettyprint(sxpr, out=sys.stdout, width=80):
289 """Prettyprint an SXP form.
291 sxpr s-expression
292 out destination
293 width maximum output width
294 """
295 if isinstance(sxpr, types.ListType):
296 pp = SXPPrettyPrinter(width=width)
297 pp.pprint(sxpr)
298 pp.prettyprint(out=out)
299 else:
300 sxp.show(sxpr, out=out)
301 print >> out
303 def prettyprintstring(sxpr, width=80):
304 """Prettyprint an SXP form to a string.
306 sxpr s-expression
307 width maximum output width
308 """
309 io = StringIO.StringIO()
310 prettyprint(sxpr, out=io, width=width)
311 io.seek(0)
312 val = io.getvalue()
313 io.close()
314 return val
316 def main():
317 pin = sxp.Parser()
318 while 1:
319 buf = sys.stdin.read(100)
320 pin.input(buf)
321 if buf == '': break
322 l = pin.get_val()
323 prettyprint(l, width=80)
325 if __name__ == "__main__":
326 main()