1 # Copyright (c) 2013, Schneider Electric Buildings AB
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are met:
6 # * Redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer.
8 # * Redistributions in binary form must reproduce the above copyright
9 # notice, this list of conditions and the following disclaimer in the
10 # documentation and/or other materials provided with the distribution.
11 # * Neither the name of Schneider Electric Buildings AB nor the
12 # names of contributors may be used to endorse or promote products
13 # derived from this software without specific prior written permission.
15 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
19 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 from cStringIO import StringIO
31 from io import StringIO
33 from datetime import datetime
36 def auto_generated_header(source_filename=None):
37 prefix = '# Auto-generated'
39 prefix += ' from %s' % source_filename
41 return '%s by asn1ate on %s' % (prefix, datetime.now())
44 class NullBackend(object):
45 """ Code generator to create an empty file.
46 Used to create __init__.py files.
48 def __init__(self, *args):
51 def generate_code(self, *args):
55 class PythonWriter(object):
56 """ Indentation-aware text stream. """
57 def __init__(self, out_stream, indent_size=4):
59 self.indent_size = indent_size
60 self.current_indent = 0
62 def push_indent(self):
63 self.current_indent += self.indent_size
66 self.current_indent -= self.indent_size
68 def write_line(self, line):
70 line = self._indent(line) if line else line
71 self.out.write('%s\n' % line)
73 def write_blanks(self, count=1):
74 for i in range(0, count):
77 def write_block(self, block):
78 """ Reindents after every line break. """
79 block = block.rstrip()
80 for line in block.split('\n'):
83 def write_enumeration(self, items):
84 self.write_block(',\n'.join(items))
86 def get_fragment(self):
87 return PythonFragment(self.indent_size)
89 def _indent(self, line):
90 return ' ' * self.current_indent + line
93 class PythonFragment(PythonWriter):
94 """ A buffering python writer, useful for nested structures.
96 def __init__(self, indent_size=4):
98 super(PythonFragment, self).__init__(self.buf, indent_size)
101 return self.buf.getvalue()