ia64/xen-unstable

view tools/python/xen/xend/PrettyPrint.py @ 12725:36fe7ca48e54

Tidy up the creation of directories that Xend needs. This avoids potential
races in this creation.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Fri Dec 01 11:32:32 2006 +0000 (2006-12-01)
parents 6ffb8705f894
children
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 # Copyright (C) 2005 XenSource Ltd
17 #============================================================================
19 """General pretty-printer, including support for SXP.
21 """
22 import sys
23 import types
24 import StringIO
25 from xen.xend import sxp
27 class PrettyItem:
29 def __init__(self, width):
30 self.width = width
32 def insert(self, block):
33 block.addtoline(self)
35 def get_width(self):
36 return self.width
38 def output(self, _):
39 print '***PrettyItem>output>', self
40 pass
42 def prettyprint(self, _):
43 print '***PrettyItem>prettyprint>', self
44 return self.width
46 class PrettyString(PrettyItem):
48 def __init__(self, x):
49 PrettyItem.__init__(self, len(x))
50 self.value = x
52 def output(self, out):
53 out.write(self.value)
55 def prettyprint(self, line):
56 line.output(self)
58 def show(self, out):
59 print >> out, ("(string (width %d) '%s')" % (self.width, self.value))
61 class PrettySpace(PrettyItem):
63 def output(self, out):
64 out.write(' ' * self.width)
66 def prettyprint(self, line):
67 line.output(self)
69 def show(self, out):
70 print >> out, ("(space (width %d))" % self.width)
72 class PrettyBreak(PrettyItem):
74 def __init__(self, width, indent):
75 PrettyItem.__init__(self, width)
76 self.indent = indent
77 self.space = 0
78 self.active = 0
80 def output(self, out):
81 out.write(' ' * self.width)
83 def prettyprint(self, line):
84 if line.breaks(self.space):
85 self.active = 1
86 line.newline(self.indent)
87 else:
88 line.output(self)
90 def show(self, out):
91 print >> out, ("(break (width %d) (indent %d) (space %d) (active %d))"
92 % (self.width, self.indent, self.space, self.active))
94 class PrettyNewline(PrettySpace):
96 def insert(self, block):
97 block.newline()
98 block.addtoline(self)
100 def prettyprint(self, line):
101 line.newline(0)
102 line.output(self)
104 def show(self, out):
105 print >> out, ("(nl (width %d))" % self.width)
107 class PrettyLine(PrettyItem):
108 def __init__(self):
109 PrettyItem.__init__(self, 0)
110 self.content = []
112 def write(self, x):
113 self.content.append(x)
115 def end(self):
116 width = 0
117 lastwidth = 0
118 lastbreak = None
119 for x in self.content:
120 if isinstance(x, PrettyBreak):
121 if lastbreak:
122 lastbreak.space = (width - lastwidth)
123 lastbreak = x
124 lastwidth = width
125 width += x.get_width()
126 if lastbreak:
127 lastbreak.space = (width - lastwidth)
128 self.width = width
130 def prettyprint(self, line):
131 for x in self.content:
132 x.prettyprint(line)
134 def show(self, out):
135 print >> out, '(LINE (width %d)' % self.width
136 for x in self.content:
137 x.show(out)
138 print >> out, ')'
140 class PrettyBlock(PrettyItem):
142 def __init__(self, all=0, parent=None):
143 PrettyItem.__init__(self, 0)
145 self.lines = []
146 self.parent = parent
147 self.indent = 0
148 self.all = all
149 self.broken = 0
150 self.newline()
152 def add(self, item):
153 item.insert(self)
155 def end(self):
156 self.width = 0
157 for l in self.lines:
158 l.end()
159 if self.width < l.width:
160 self.width = l.width
162 def breaks(self, _):
163 return self.all and self.broken
165 def newline(self):
166 self.lines.append(PrettyLine())
168 def addtoline(self, x):
169 self.lines[-1].write(x)
171 def prettyprint(self, line):
172 self.indent = line.used
173 line.block = self
174 if not line.fits(self.width):
175 self.broken = 1
176 for l in self.lines:
177 l.prettyprint(line)
178 line.block = self.parent
180 def show(self, out):
181 print >> out, ('(BLOCK (width %d) (indent %d) (all %d) (broken %d)' %
182 (self.width, self.indent, self.all, self.broken))
183 for l in self.lines:
184 l.show(out)
185 print >> out, ')'
187 class Line:
189 def __init__(self, out, width):
190 self.block = None
191 self.out = out
192 self.width = width
193 self.used = 0
194 self.space = self.width
196 def newline(self, indent):
197 indent += self.block.indent
198 self.out.write('\n')
199 self.out.write(' ' * indent)
200 self.used = indent
201 self.space = self.width - self.used
203 def fits(self, n):
204 return self.space - n >= 0
206 def breaks(self, n):
207 return self.block.breaks(n) or not self.fits(n)
209 def output(self, x):
210 n = x.get_width()
211 self.space -= n
212 self.used += n
213 if self.space < 0:
214 self.space = 0
215 x.output(self.out)
217 class PrettyPrinter:
218 """A prettyprinter based on what I remember of Derek Oppen's
219 prettyprint algorithm from TOPLAS way back.
220 """
222 def __init__(self, width=40):
223 self.width = width
224 self.block = None
225 self.top = None
227 def write(self, x):
228 self.block.add(PrettyString(x))
230 def add(self, item):
231 self.block.add(item)
233 def addbreak(self, width=1, indent=4):
234 self.add(PrettyBreak(width, indent))
236 def addspace(self, width=1):
237 self.add(PrettySpace(width))
239 def addnl(self, indent=0):
240 self.add(PrettyNewline(indent))
242 def begin(self, all=0):
243 block = PrettyBlock(all=all, parent=self.block)
244 self.block = block
246 def end(self):
247 self.block.end()
248 if self.block.parent:
249 self.block.parent.add(self.block)
250 else:
251 self.top = self.block
252 self.block = self.block.parent
254 def prettyprint(self, out=sys.stdout):
255 self.top.prettyprint(Line(out, self.width))
257 class SXPPrettyPrinter(PrettyPrinter):
258 """An SXP prettyprinter.
259 """
261 def pstring(self, x):
262 io = StringIO.StringIO()
263 sxp.show(x, out=io)
264 io.seek(0)
265 val = io.getvalue()
266 io.close()
267 return val
269 def pprint(self, l):
270 if isinstance(l, types.ListType):
271 self.begin(all=1)
272 self.write('(')
273 i = 0
274 for x in l:
275 if(i): self.addbreak()
276 self.pprint(x)
277 i += 1
278 self.addbreak(width=0, indent=0)
279 self.write(')')
280 self.end()
281 else:
282 self.write(self.pstring(l))
284 def prettyprint(sxpr, out=sys.stdout, width=80):
285 """Prettyprint an SXP form.
287 sxpr s-expression
288 out destination
289 width maximum output width
290 """
291 if isinstance(sxpr, types.ListType):
292 pp = SXPPrettyPrinter(width=width)
293 pp.pprint(sxpr)
294 pp.prettyprint(out=out)
295 else:
296 sxp.show(sxpr, out=out)
297 print >> out
299 def prettyprintstring(sxpr, width=80):
300 """Prettyprint an SXP form to a string.
302 sxpr s-expression
303 width maximum output width
304 """
305 io = StringIO.StringIO()
306 prettyprint(sxpr, out=io, width=width)
307 io.seek(0)
308 val = io.getvalue()
309 io.close()
310 return val
312 def main():
313 pin = sxp.Parser()
314 while 1:
315 buf = sys.stdin.read(100)
316 pin.input(buf)
317 if buf == '': break
318 l = pin.get_val()
319 prettyprint(l, width=80)
321 if __name__ == "__main__":
322 main()