mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			325 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			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()
 | |
|     
 |