Statistics
| Branch: | Revision:

root / scripts / qapi.py @ 0f923be2

History | View | Annotate | Download (4.8 kB)

1 0f923be2 Michael Roth
#
2 0f923be2 Michael Roth
# QAPI helper library
3 0f923be2 Michael Roth
#
4 0f923be2 Michael Roth
# Copyright IBM, Corp. 2011
5 0f923be2 Michael Roth
#
6 0f923be2 Michael Roth
# Authors:
7 0f923be2 Michael Roth
#  Anthony Liguori <aliguori@us.ibm.com>
8 0f923be2 Michael Roth
#
9 0f923be2 Michael Roth
# This work is licensed under the terms of the GNU GPLv2.
10 0f923be2 Michael Roth
# See the COPYING.LIB file in the top-level directory.
11 0f923be2 Michael Roth
12 0f923be2 Michael Roth
from ordereddict import OrderedDict
13 0f923be2 Michael Roth
14 0f923be2 Michael Roth
def tokenize(data):
15 0f923be2 Michael Roth
    while len(data):
16 0f923be2 Michael Roth
        if data[0] in ['{', '}', ':', ',', '[', ']']:
17 0f923be2 Michael Roth
            yield data[0]
18 0f923be2 Michael Roth
            data = data[1:]
19 0f923be2 Michael Roth
        elif data[0] in ' \n':
20 0f923be2 Michael Roth
            data = data[1:]
21 0f923be2 Michael Roth
        elif data[0] == "'":
22 0f923be2 Michael Roth
            data = data[1:]
23 0f923be2 Michael Roth
            string = ''
24 0f923be2 Michael Roth
            while data[0] != "'":
25 0f923be2 Michael Roth
                string += data[0]
26 0f923be2 Michael Roth
                data = data[1:]
27 0f923be2 Michael Roth
            data = data[1:]
28 0f923be2 Michael Roth
            yield string
29 0f923be2 Michael Roth
30 0f923be2 Michael Roth
def parse(tokens):
31 0f923be2 Michael Roth
    if tokens[0] == '{':
32 0f923be2 Michael Roth
        ret = OrderedDict()
33 0f923be2 Michael Roth
        tokens = tokens[1:]
34 0f923be2 Michael Roth
        while tokens[0] != '}':
35 0f923be2 Michael Roth
            key = tokens[0]
36 0f923be2 Michael Roth
            tokens = tokens[1:]
37 0f923be2 Michael Roth
38 0f923be2 Michael Roth
            tokens = tokens[1:] # :
39 0f923be2 Michael Roth
40 0f923be2 Michael Roth
            value, tokens = parse(tokens)
41 0f923be2 Michael Roth
42 0f923be2 Michael Roth
            if tokens[0] == ',':
43 0f923be2 Michael Roth
                tokens = tokens[1:]
44 0f923be2 Michael Roth
45 0f923be2 Michael Roth
            ret[key] = value
46 0f923be2 Michael Roth
        tokens = tokens[1:]
47 0f923be2 Michael Roth
        return ret, tokens
48 0f923be2 Michael Roth
    elif tokens[0] == '[':
49 0f923be2 Michael Roth
        ret = []
50 0f923be2 Michael Roth
        tokens = tokens[1:]
51 0f923be2 Michael Roth
        while tokens[0] != ']':
52 0f923be2 Michael Roth
            value, tokens = parse(tokens)
53 0f923be2 Michael Roth
            if tokens[0] == ',':
54 0f923be2 Michael Roth
                tokens = tokens[1:]
55 0f923be2 Michael Roth
            ret.append(value)
56 0f923be2 Michael Roth
        tokens = tokens[1:]
57 0f923be2 Michael Roth
        return ret, tokens
58 0f923be2 Michael Roth
    else:
59 0f923be2 Michael Roth
        return tokens[0], tokens[1:]
60 0f923be2 Michael Roth
61 0f923be2 Michael Roth
def evaluate(string):
62 0f923be2 Michael Roth
    return parse(map(lambda x: x, tokenize(string)))[0]
63 0f923be2 Michael Roth
64 0f923be2 Michael Roth
def parse_schema(fp):
65 0f923be2 Michael Roth
    exprs = []
66 0f923be2 Michael Roth
    expr = ''
67 0f923be2 Michael Roth
    expr_eval = None
68 0f923be2 Michael Roth
69 0f923be2 Michael Roth
    for line in fp:
70 0f923be2 Michael Roth
        if line.startswith('#') or line == '\n':
71 0f923be2 Michael Roth
            continue
72 0f923be2 Michael Roth
73 0f923be2 Michael Roth
        if line.startswith(' '):
74 0f923be2 Michael Roth
            expr += line
75 0f923be2 Michael Roth
        elif expr:
76 0f923be2 Michael Roth
            expr_eval = evaluate(expr)
77 0f923be2 Michael Roth
            if expr_eval.has_key('enum'):
78 0f923be2 Michael Roth
                add_enum(expr_eval['enum'])
79 0f923be2 Michael Roth
            elif expr_eval.has_key('union'):
80 0f923be2 Michael Roth
                add_enum('%sKind' % expr_eval['union'])
81 0f923be2 Michael Roth
            exprs.append(expr_eval)
82 0f923be2 Michael Roth
            expr = line
83 0f923be2 Michael Roth
        else:
84 0f923be2 Michael Roth
            expr += line
85 0f923be2 Michael Roth
86 0f923be2 Michael Roth
    if expr:
87 0f923be2 Michael Roth
        expr_eval = evaluate(expr)
88 0f923be2 Michael Roth
        if expr_eval.has_key('enum'):
89 0f923be2 Michael Roth
            add_enum(expr_eval['enum'])
90 0f923be2 Michael Roth
        elif expr_eval.has_key('union'):
91 0f923be2 Michael Roth
            add_enum('%sKind' % expr_eval['union'])
92 0f923be2 Michael Roth
        exprs.append(expr_eval)
93 0f923be2 Michael Roth
94 0f923be2 Michael Roth
    return exprs
95 0f923be2 Michael Roth
96 0f923be2 Michael Roth
def parse_args(typeinfo):
97 0f923be2 Michael Roth
    for member in typeinfo:
98 0f923be2 Michael Roth
        argname = member
99 0f923be2 Michael Roth
        argentry = typeinfo[member]
100 0f923be2 Michael Roth
        optional = False
101 0f923be2 Michael Roth
        structured = False
102 0f923be2 Michael Roth
        if member.startswith('*'):
103 0f923be2 Michael Roth
            argname = member[1:]
104 0f923be2 Michael Roth
            optional = True
105 0f923be2 Michael Roth
        if isinstance(argentry, OrderedDict):
106 0f923be2 Michael Roth
            structured = True
107 0f923be2 Michael Roth
        yield (argname, argentry, optional, structured)
108 0f923be2 Michael Roth
109 0f923be2 Michael Roth
def de_camel_case(name):
110 0f923be2 Michael Roth
    new_name = ''
111 0f923be2 Michael Roth
    for ch in name:
112 0f923be2 Michael Roth
        if ch.isupper() and new_name:
113 0f923be2 Michael Roth
            new_name += '_'
114 0f923be2 Michael Roth
        if ch == '-':
115 0f923be2 Michael Roth
            new_name += '_'
116 0f923be2 Michael Roth
        else:
117 0f923be2 Michael Roth
            new_name += ch.lower()
118 0f923be2 Michael Roth
    return new_name
119 0f923be2 Michael Roth
120 0f923be2 Michael Roth
def camel_case(name):
121 0f923be2 Michael Roth
    new_name = ''
122 0f923be2 Michael Roth
    first = True
123 0f923be2 Michael Roth
    for ch in name:
124 0f923be2 Michael Roth
        if ch in ['_', '-']:
125 0f923be2 Michael Roth
            first = True
126 0f923be2 Michael Roth
        elif first:
127 0f923be2 Michael Roth
            new_name += ch.upper()
128 0f923be2 Michael Roth
            first = False
129 0f923be2 Michael Roth
        else:
130 0f923be2 Michael Roth
            new_name += ch.lower()
131 0f923be2 Michael Roth
    return new_name
132 0f923be2 Michael Roth
133 0f923be2 Michael Roth
def c_var(name):
134 0f923be2 Michael Roth
    return '_'.join(name.split('-')).lstrip("*")
135 0f923be2 Michael Roth
136 0f923be2 Michael Roth
def c_list_type(name):
137 0f923be2 Michael Roth
    return '%sList' % name
138 0f923be2 Michael Roth
139 0f923be2 Michael Roth
def type_name(name):
140 0f923be2 Michael Roth
    if type(name) == list:
141 0f923be2 Michael Roth
        return c_list_type(name[0])
142 0f923be2 Michael Roth
    return name
143 0f923be2 Michael Roth
144 0f923be2 Michael Roth
enum_types = []
145 0f923be2 Michael Roth
146 0f923be2 Michael Roth
def add_enum(name):
147 0f923be2 Michael Roth
    global enum_types
148 0f923be2 Michael Roth
    enum_types.append(name)
149 0f923be2 Michael Roth
150 0f923be2 Michael Roth
def is_enum(name):
151 0f923be2 Michael Roth
    global enum_types
152 0f923be2 Michael Roth
    return (name in enum_types)
153 0f923be2 Michael Roth
154 0f923be2 Michael Roth
def c_type(name):
155 0f923be2 Michael Roth
    if name == 'str':
156 0f923be2 Michael Roth
        return 'char *'
157 0f923be2 Michael Roth
    elif name == 'int':
158 0f923be2 Michael Roth
        return 'int64_t'
159 0f923be2 Michael Roth
    elif name == 'bool':
160 0f923be2 Michael Roth
        return 'bool'
161 0f923be2 Michael Roth
    elif name == 'number':
162 0f923be2 Michael Roth
        return 'double'
163 0f923be2 Michael Roth
    elif type(name) == list:
164 0f923be2 Michael Roth
        return '%s *' % c_list_type(name[0])
165 0f923be2 Michael Roth
    elif is_enum(name):
166 0f923be2 Michael Roth
        return name
167 0f923be2 Michael Roth
    elif name == None or len(name) == 0:
168 0f923be2 Michael Roth
        return 'void'
169 0f923be2 Michael Roth
    elif name == name.upper():
170 0f923be2 Michael Roth
        return '%sEvent *' % camel_case(name)
171 0f923be2 Michael Roth
    else:
172 0f923be2 Michael Roth
        return '%s *' % name
173 0f923be2 Michael Roth
174 0f923be2 Michael Roth
def genindent(count):
175 0f923be2 Michael Roth
    ret = ""
176 0f923be2 Michael Roth
    for i in range(count):
177 0f923be2 Michael Roth
        ret += " "
178 0f923be2 Michael Roth
    return ret
179 0f923be2 Michael Roth
180 0f923be2 Michael Roth
indent_level = 0
181 0f923be2 Michael Roth
182 0f923be2 Michael Roth
def push_indent(indent_amount=4):
183 0f923be2 Michael Roth
    global indent_level
184 0f923be2 Michael Roth
    indent_level += indent_amount
185 0f923be2 Michael Roth
186 0f923be2 Michael Roth
def pop_indent(indent_amount=4):
187 0f923be2 Michael Roth
    global indent_level
188 0f923be2 Michael Roth
    indent_level -= indent_amount
189 0f923be2 Michael Roth
190 0f923be2 Michael Roth
def cgen(code, **kwds):
191 0f923be2 Michael Roth
    indent = genindent(indent_level)
192 0f923be2 Michael Roth
    lines = code.split('\n')
193 0f923be2 Michael Roth
    lines = map(lambda x: indent + x, lines)
194 0f923be2 Michael Roth
    return '\n'.join(lines) % kwds + '\n'
195 0f923be2 Michael Roth
196 0f923be2 Michael Roth
def mcgen(code, **kwds):
197 0f923be2 Michael Roth
    return cgen('\n'.join(code.split('\n')[1:-1]), **kwds)
198 0f923be2 Michael Roth
199 0f923be2 Michael Roth
def basename(filename):
200 0f923be2 Michael Roth
    return filename.split("/")[-1]
201 0f923be2 Michael Roth
202 0f923be2 Michael Roth
def guardname(filename):
203 0f923be2 Michael Roth
    return filename.replace("/", "_").replace("-", "_").split(".")[0].upper()