cloudstack/python/lib/cloud_PrettyPrint.py
Manuel Amador (Rudd-O) 05c020e1f6 Source code committed
2010-08-11 09:13:29 -07:00

325 lines
8.1 KiB
Python

#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005 XenSource Ltd
#============================================================================
"""General pretty-printer, including support for SXP.
"""
import sys
import types
import StringIO
#from xen.xend import sxp
import cloud_sxp as sxp
class PrettyItem:
def __init__(self, width):
self.width = width
def insert(self, block):
block.addtoline(self)
def get_width(self):
return self.width
def output(self, _):
print '***PrettyItem>output>', self
pass
def prettyprint(self, _):
print '***PrettyItem>prettyprint>', self
return self.width
class PrettyString(PrettyItem):
def __init__(self, x):
PrettyItem.__init__(self, len(x))
self.value = x
def output(self, out):
out.write(self.value)
def prettyprint(self, line):
line.output(self)
def show(self, out):
print >> out, ("(string (width %d) '%s')" % (self.width, self.value))
class PrettySpace(PrettyItem):
def output(self, out):
out.write(' ' * self.width)
def prettyprint(self, line):
line.output(self)
def show(self, out):
print >> out, ("(space (width %d))" % self.width)
class PrettyBreak(PrettyItem):
def __init__(self, width, indent):
PrettyItem.__init__(self, width)
self.indent = indent
self.space = 0
self.active = 0
def output(self, out):
out.write(' ' * self.width)
def prettyprint(self, line):
if line.breaks(self.space):
self.active = 1
line.newline(self.indent)
else:
line.output(self)
def show(self, out):
print >> out, ("(break (width %d) (indent %d) (space %d) (active %d))"
% (self.width, self.indent, self.space, self.active))
class PrettyNewline(PrettySpace):
def insert(self, block):
block.newline()
block.addtoline(self)
def prettyprint(self, line):
line.newline(0)
line.output(self)
def show(self, out):
print >> out, ("(nl (width %d))" % self.width)
class PrettyLine(PrettyItem):
def __init__(self):
PrettyItem.__init__(self, 0)
self.content = []
def write(self, x):
self.content.append(x)
def end(self):
width = 0
lastwidth = 0
lastbreak = None
for x in self.content:
if isinstance(x, PrettyBreak):
if lastbreak:
lastbreak.space = (width - lastwidth)
lastbreak = x
lastwidth = width
width += x.get_width()
if lastbreak:
lastbreak.space = (width - lastwidth)
self.width = width
def prettyprint(self, line):
for x in self.content:
x.prettyprint(line)
def show(self, out):
print >> out, '(LINE (width %d)' % self.width
for x in self.content:
x.show(out)
print >> out, ')'
class PrettyBlock(PrettyItem):
def __init__(self, all=0, parent=None):
PrettyItem.__init__(self, 0)
self.lines = []
self.parent = parent
self.indent = 0
self.all = all
self.broken = 0
self.newline()
def add(self, item):
item.insert(self)
def end(self):
self.width = 0
for l in self.lines:
l.end()
if self.width < l.width:
self.width = l.width
def breaks(self, _):
return self.all and self.broken
def newline(self):
self.lines.append(PrettyLine())
def addtoline(self, x):
self.lines[-1].write(x)
def prettyprint(self, line):
self.indent = line.used
line.block = self
if not line.fits(self.width):
self.broken = 1
for l in self.lines:
l.prettyprint(line)
line.block = self.parent
def show(self, out):
print >> out, ('(BLOCK (width %d) (indent %d) (all %d) (broken %d)' %
(self.width, self.indent, self.all, self.broken))
for l in self.lines:
l.show(out)
print >> out, ')'
class Line:
def __init__(self, out, width):
self.block = None
self.out = out
self.width = width
self.used = 0
self.space = self.width
def newline(self, indent):
indent += self.block.indent
self.out.write('\n')
self.out.write(' ' * indent)
self.used = indent
self.space = self.width - self.used
def fits(self, n):
return self.space - n >= 0
def breaks(self, n):
return self.block.breaks(n) or not self.fits(n)
def output(self, x):
n = x.get_width()
self.space -= n
self.used += n
if self.space < 0:
self.space = 0
x.output(self.out)
class PrettyPrinter:
"""A prettyprinter based on what I remember of Derek Oppen's
prettyprint algorithm from TOPLAS way back.
"""
def __init__(self, width=40):
self.width = width
self.block = None
self.top = None
def write(self, x):
self.block.add(PrettyString(x))
def add(self, item):
self.block.add(item)
def addbreak(self, width=1, indent=4):
self.add(PrettyBreak(width, indent))
def addspace(self, width=1):
self.add(PrettySpace(width))
def addnl(self, indent=0):
self.add(PrettyNewline(indent))
def begin(self, all=0):
block = PrettyBlock(all=all, parent=self.block)
self.block = block
def end(self):
self.block.end()
if self.block.parent:
self.block.parent.add(self.block)
else:
self.top = self.block
self.block = self.block.parent
def prettyprint(self, out=sys.stdout):
self.top.prettyprint(Line(out, self.width))
class SXPPrettyPrinter(PrettyPrinter):
"""An SXP prettyprinter.
"""
def pstring(self, x):
io = StringIO.StringIO()
sxp.show(x, out=io)
io.seek(0)
val = io.getvalue()
io.close()
return val
def pprint(self, l):
if isinstance(l, types.ListType):
self.begin(all=1)
self.write('(')
i = 0
for x in l:
if(i): self.addbreak()
self.pprint(x)
i += 1
self.addbreak(width=0, indent=0)
self.write(')')
self.end()
else:
self.write(self.pstring(l))
def prettyprint(sxpr, out=sys.stdout, width=80):
"""Prettyprint an SXP form.
sxpr s-expression
out destination
width maximum output width
"""
if isinstance(sxpr, types.ListType):
pp = SXPPrettyPrinter(width=width)
pp.pprint(sxpr)
pp.prettyprint(out=out)
else:
sxp.show(sxpr, out=out)
print >> out
def prettyprintstring(sxpr, width=80):
"""Prettyprint an SXP form to a string.
sxpr s-expression
width maximum output width
"""
io = StringIO.StringIO()
prettyprint(sxpr, out=io, width=width)
io.seek(0)
val = io.getvalue()
io.close()
return val
def main():
pin = sxp.Parser()
while 1:
buf = sys.stdin.read(100)
pin.input(buf)
if buf == '': break
l = pin.get_val()
prettyprint(l, width=80)
if __name__ == "__main__":
main()