1from .abi import *
2from .markdown_naming import *
3
4
5class CNaming:
6    def __init__(self,
7                 prefix,
8                 md_prefix=None,
9                 c11=True,
10                 syscall_prefix=None,
11                 pointer_prefix=''):
12        self.prefix = prefix
13        self.md_prefix = md_prefix
14        self.c11 = c11
15        self.syscall_prefix = syscall_prefix
16        self.pointer_prefix = pointer_prefix
17
18    def typename(self, type):
19        if isinstance(type, VoidType):
20            return 'void'
21        elif isinstance(type, IntType):
22            if type.name == 'char':
23                return 'char'
24            return '{}_t'.format(type.name)
25        elif isinstance(type, UserDefinedType):
26            prefix = self.prefix
27            if self.md_prefix is not None and type.layout.machine_dep:
28                prefix = self.md_prefix
29            return '{}{}_t'.format(prefix, type.name)
30        elif isinstance(type, AtomicType):
31            if self.c11:
32                return '_Atomic({})'.format(self.typename(type.target_type))
33            else:
34                return self.typename(type.target_type)
35        elif isinstance(type, PointerType) or isinstance(type, ArrayType):
36            return self.vardecl(type, '')
37        else:
38            raise Exception('Unable to generate C declaration '
39                            'for type: {}'.format(type))
40
41    def valname(self, type, value):
42        return '{}{}{}'.format(self.prefix, type.cprefix, value.name).upper()
43
44    def syscallname(self, syscall):
45        if self.syscall_prefix is not None:
46            prefix = self.syscall_prefix
47        else:
48            prefix = self.prefix
49            if self.md_prefix is not None and syscall.machine_dep:
50                prefix = self.md_prefix
51            prefix += 'sys_'
52        return '{}{}'.format(prefix, syscall.name)
53
54    def vardecl(self, type, name, array_need_parens=False):
55        if isinstance(type, OutputPointerType):
56            return self.vardecl(
57                type.target_type, '*{}'.format(name), array_need_parens=True)
58        elif isinstance(type, PointerType):
59            decl = self.vardecl(
60                type.target_type,
61                '{}*{}'.format(self.pointer_prefix, name),
62                array_need_parens=True)
63            if type.const:
64                decl = 'const ' + decl
65            return decl
66        elif isinstance(type, ArrayType):
67            if array_need_parens:
68                name = '({})'.format(name)
69            return self.vardecl(type.element_type, '{}[{}]'.format(
70                name, type.count))
71        else:
72            return '{} {}'.format(self.typename(type), name)
73
74    def fieldname(self, name):
75        return name
76
77
78class MarkdownCNaming(MarkdownNaming, CNaming):
79    def typename(self, type, link=True, **kwargs):
80        if link:
81            return self.link(type, code=False)
82        else:
83            return super().typename(type, **kwargs)
84
85    def memname(self, *path):
86        name = self.typename(path[0], link=False)
87        name += '::'
88        name += '.'.join(m.name for m in path[1:])
89        return name
90
91    def syscallname(self, syscall):
92        return CNaming.syscallname(self, syscall) + '()'
93
94    def kinddesc(self, type):
95        if isinstance(type, IntLikeType):
96            return '{}{}'.format(
97                self.link(type.int_type), ' bitfield'
98                if isinstance(type, FlagsType) else '')
99        elif isinstance(type, StructType):
100            return '`struct`'
101        elif isinstance(type, FunctionType):
102            return 'function type'
103        else:
104            assert (False)
105