1# 2# QAPI frontend source file info 3# 4# Copyright (c) 2019 Red Hat Inc. 5# 6# Authors: 7# Markus Armbruster <armbru@redhat.com> 8# 9# This work is licensed under the terms of the GNU GPL, version 2. 10# See the COPYING file in the top-level directory. 11 12import copy 13import sys 14from typing import List, Optional, TypeVar 15 16 17class QAPISchemaPragma: 18 # Replace with @dataclass in Python 3.7+ 19 # pylint: disable=too-few-public-methods 20 21 def __init__(self) -> None: 22 # Are documentation comments required? 23 self.doc_required = False 24 # Commands whose names may use '_' 25 self.command_name_exceptions: List[str] = [] 26 # Commands allowed to return a non-dictionary 27 self.command_returns_exceptions: List[str] = [] 28 # Types whose member names may violate case conventions 29 self.member_name_exceptions: List[str] = [] 30 31 32class QAPISourceInfo: 33 T = TypeVar('T', bound='QAPISourceInfo') 34 35 def __init__(self, fname: str, line: int, 36 parent: Optional['QAPISourceInfo']): 37 self.fname = fname 38 self.line = line 39 self.parent = parent 40 self.pragma: QAPISchemaPragma = ( 41 parent.pragma if parent else QAPISchemaPragma() 42 ) 43 self.defn_meta: Optional[str] = None 44 self.defn_name: Optional[str] = None 45 46 def set_defn(self, meta: str, name: str) -> None: 47 self.defn_meta = meta 48 self.defn_name = name 49 50 def next_line(self: T) -> T: 51 info = copy.copy(self) 52 info.line += 1 53 return info 54 55 def loc(self) -> str: 56 if self.fname is None: 57 return sys.argv[0] 58 ret = self.fname 59 if self.line is not None: 60 ret += ':%d' % self.line 61 return ret 62 63 def in_defn(self) -> str: 64 if self.defn_name: 65 return "%s: In %s '%s':\n" % (self.fname, 66 self.defn_meta, self.defn_name) 67 return '' 68 69 def include_path(self) -> str: 70 ret = '' 71 parent = self.parent 72 while parent: 73 ret = 'In file included from %s:\n' % parent.loc() + ret 74 parent = parent.parent 75 return ret 76 77 def __str__(self) -> str: 78 return self.include_path() + self.in_defn() + self.loc() 79