1# Copyright 2020 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Defines a class used to write code to an output buffer.""" 15 16from typing import List 17 18 19class OutputFile: 20 """A buffer to which data is written. 21 22 Example: 23 24 ``` 25 output = Output("hello.c") 26 output.write_line('int main(void) {') 27 with output.indent(): 28 output.write_line('printf("Hello, world");') 29 output.write_line('return 0;') 30 output.write_line('}') 31 32 print(output.content()) 33 ``` 34 35 Produces: 36 ``` 37 int main(void) { 38 printf("Hello, world"); 39 return 0; 40 } 41 ``` 42 """ 43 44 INDENT_WIDTH = 2 45 46 def __init__(self, filename: str): 47 self._filename: str = filename 48 self._content: List[str] = [] 49 self._indentation: int = 0 50 51 def write_line(self, line: str = '') -> None: 52 if line: 53 self._content.append(' ' * self._indentation) 54 self._content.append(line) 55 self._content.append('\n') 56 57 def indent( 58 self, 59 amount: int = INDENT_WIDTH, 60 ) -> 'OutputFile._IndentationContext': 61 """Increases the indentation level of the output.""" 62 return self._IndentationContext(self, amount) 63 64 def name(self) -> str: 65 return self._filename 66 67 def content(self) -> str: 68 return ''.join(self._content) 69 70 class _IndentationContext: 71 """Context that increases the output's indentation when it is active.""" 72 def __init__(self, output: 'OutputFile', amount: int): 73 self._output = output 74 self._amount: int = amount 75 76 def __enter__(self): 77 self._output._indentation += self._amount 78 79 def __exit__(self, typ, value, traceback): 80 self._output._indentation -= self._amount 81