idl-parser 0.0.10__py2.7.egg

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
idl_parser/module.py ADDED
@@ -0,0 +1,259 @@
1
+ import os, sys, traceback
2
+
3
+ from . import node, type
4
+ from . import struct, typedef, interface, enum, const
5
+ global_namespace = '__global__'
6
+ sep = '::'
7
+
8
+ class IDLModule(node.IDLNode):
9
+
10
+ def __init__(self, name=None, parent = None):
11
+ super(IDLModule, self).__init__('IDLModule', name, parent)
12
+ self._verbose = False
13
+ if name is None:
14
+ self._name = global_namespace
15
+
16
+ self._interfaces = []
17
+ self._typedefs = []
18
+ self._structs = []
19
+ self._enums = []
20
+ self._consts = []
21
+ self._modules = []
22
+
23
+ @property
24
+ def is_global(self):
25
+ return self.name == global_namespace
26
+
27
+ @property
28
+ def full_path(self):
29
+ if self.parent is None:
30
+ return '' # self.name
31
+ else:
32
+ if len(self.parent.full_path) == 0:
33
+ return self.name
34
+ return self.parent.full_path + sep + self.name
35
+
36
+ def to_simple_dic(self, quiet=False):
37
+ dic = {'module %s' % self.name : [s.to_simple_dic(quiet) for s in self.structs] +
38
+ [i.to_simple_dic(quiet) for i in self.interfaces] +
39
+ [m.to_simple_dic(quiet) for m in self.modules] +
40
+ [e.to_simple_dic(quiet) for e in self.enums] +
41
+ [t.to_simple_dic(quiet) for t in self.typedefs] +
42
+ [t.to_simple_dic(quiet) for t in self.consts]}
43
+ return dic
44
+
45
+ def to_dic(self):
46
+ dic = { 'name' : self.name,
47
+ 'filepath' : self.filepath,
48
+ 'classname' : self.classname,
49
+ 'interfaces' : [i.to_dic() for i in self.interfaces],
50
+ 'typedefs' : [t.to_dic() for t in self.typedefs],
51
+ 'structs' : [s.to_dic() for s in self.structs],
52
+ 'enums' : [e.to_dic() for e in self.enums],
53
+ 'modules' : [m.to_dic() for m in self.modules],
54
+ 'consts' : [c.to_dic() for c in self.consts] }
55
+ return dic
56
+
57
+
58
+ def parse_tokens(self, token_buf, filepath=None):
59
+ self._filepath = filepath
60
+ if not self.name == global_namespace:
61
+ kakko = token_buf.pop()
62
+ if not kakko == '{':
63
+ if self._verbose: sys.stdout.write('# Error. No kakko "{".\n')
64
+ raise InvalidIDLSyntaxError()
65
+
66
+ while True:
67
+ token = token_buf.pop()
68
+ if token == None:
69
+ if self.name == global_namespace:
70
+ break
71
+ if self._verbose: sys.stdout.write('# Error. No kokka "}".\n')
72
+ raise InvalidIDLSyntaxError()
73
+ elif token == 'module':
74
+ name_ = token_buf.pop()
75
+ m = self.module_by_name(name_)
76
+ if m == None:
77
+ m = IDLModule(name_, self)
78
+ self._modules.append(m)
79
+ m.parse_tokens(token_buf, filepath=filepath)
80
+ elif token == 'typedef':
81
+ blocks = []
82
+ while True:
83
+ t = token_buf.pop()
84
+ if t == None:
85
+ raise InvalidIDLSyntaxError()
86
+ elif t == ';':
87
+ break
88
+ else:
89
+ blocks.append(t)
90
+ t = typedef.IDLTypedef(self)
91
+ self._typedefs.append(t)
92
+ t.parse_blocks(blocks, filepath=filepath)
93
+ elif token == 'struct':
94
+ name_ = token_buf.pop()
95
+ s_ = self.struct_by_name(name_)
96
+ s = struct.IDLStruct(name_, self)
97
+ s.parse_tokens(token_buf, filepath=filepath)
98
+ if s_:
99
+ if self._verbose: sys.stdout.write('# Error. Same Struct Defined (%s)\n' % name_)
100
+ # raise InvalidIDLSyntaxError
101
+ else:
102
+ self._structs.append(s)
103
+
104
+ elif token == 'interface':
105
+ name_ = token_buf.pop()
106
+ s = interface.IDLInterface(name_, self)
107
+ s.parse_tokens(token_buf, filepath=filepath)
108
+
109
+ s_ = self.interface_by_name(name_)
110
+ if s_:
111
+ if self._verbose: sys.stdout.write('# Error. Same Interface Defined (%s)\n' % name_)
112
+ # raise InvalidIDLSyntaxError
113
+ else:
114
+ self._interfaces.append(s)
115
+
116
+ elif token == 'enum':
117
+ name_ = token_buf.pop()
118
+ s = enum.IDLEnum(name_, self)
119
+ s.parse_tokens(token_buf, filepath)
120
+ s_ = self.enum_by_name(name_)
121
+ if s_:
122
+ if self._verbose: sys.stdout.write('# Error. Same Enum Defined (%s)\n' % name_)
123
+ # raise InvalidIDLSyntaxError
124
+ else:
125
+ self._enums.append(s)
126
+
127
+ pass
128
+
129
+ elif token == 'const':
130
+ values = []
131
+ while True:
132
+ t = token_buf.pop()
133
+ if t == ';':
134
+ break
135
+ values.append(t)
136
+
137
+ value_ = values[-1]
138
+ name_ = values[-3]
139
+ typename = ''
140
+ for t in values[:-3]:
141
+ typename = typename + ' ' + t
142
+ typename = typename.strip()
143
+ s = const.IDLConst(name_, typename, value_, self, filepath=filepath)
144
+ s_ = self.const_by_name(name_)
145
+ if s_:
146
+ if self._verbose: sys.stdout.write('# Error. Same Const Defined (%s)\n' % name_)
147
+ else:
148
+ self._consts.append(s)
149
+
150
+ elif token == '}':
151
+ break
152
+
153
+ return True
154
+
155
+
156
+
157
+ @property
158
+ def modules(self):
159
+ return self._modules
160
+
161
+ def module_by_name(self, name):
162
+ for m in self.modules:
163
+ if m.name == name:
164
+ return m
165
+ return None
166
+
167
+ def forEachModule(self, func):
168
+ for m in self.modules:
169
+ func(m)
170
+
171
+ @property
172
+ def interfaces(self):
173
+ return self._interfaces
174
+
175
+ def interface_by_name(self, name):
176
+ for i in self.interfaces:
177
+ if i.name == name:
178
+ return i
179
+ return None
180
+
181
+ def forEachInterface(self, func):
182
+ for m in self.interfaces:
183
+ func(m)
184
+
185
+ @property
186
+ def structs(self):
187
+ return self._structs
188
+
189
+ def struct_by_name(self, name):
190
+ for s in self.structs:
191
+ if s.name == name:
192
+ return s
193
+ return None
194
+
195
+ def forEachStruct(self, func):
196
+ for m in self.structs:
197
+ func(m)
198
+
199
+ @property
200
+ def enums(self):
201
+ return self._enums
202
+
203
+ def enum_by_name(self, name):
204
+ for e in self.enums:
205
+ if e.name == name:
206
+ return e
207
+ return None
208
+
209
+ def forEachEnum(self, func):
210
+ for m in self.enums:
211
+ func(m)
212
+
213
+ @property
214
+ def consts(self):
215
+ return self._consts
216
+
217
+ def const_by_name(self, name):
218
+ for c in self.consts:
219
+ if c.name == name:
220
+ return c
221
+ return None
222
+
223
+ def forEachConst(self, func):
224
+ for m in self.consts:
225
+ func(m)
226
+
227
+ @property
228
+ def typedefs(self):
229
+ return self._typedefs
230
+
231
+ def typedef_by_name(self, name):
232
+ for t in self.typedefs:
233
+ if t.name == name:
234
+ return t
235
+ return None
236
+
237
+ def forEachTypedef(self, func):
238
+ for m in self.typedefs:
239
+ func(m)
240
+
241
+ def find_types(self, full_typename):
242
+ if type.is_primitive(full_typename):
243
+ return [type.IDLType(full_typename, self)]
244
+ typenode = []
245
+
246
+ def parse_node(s, name=str(full_typename)):
247
+ if s.name == name.strip() or s.full_path == name.strip():
248
+ typenode.append(s)
249
+
250
+ def parse_module(m):
251
+ m.forEachModule(parse_module)
252
+ m.forEachStruct(parse_node)
253
+ m.forEachTypedef(parse_node)
254
+ m.forEachEnum(parse_node)
255
+ m.forEachInterface(parse_node)
256
+
257
+ parse_module(self)
258
+
259
+ return typenode
idl_parser/module.pyc ADDED
Binary file
idl_parser/node.py ADDED
@@ -0,0 +1,115 @@
1
+ class IDLNode(object):
2
+ def __init__(self, classname, name, parent):
3
+ self._classname = classname
4
+ self._parent = parent
5
+ self._name = name
6
+ self._filepath = None
7
+ self.sep = '::'
8
+
9
+ @property
10
+ def filepath(self):
11
+ return self._filepath
12
+
13
+ @property
14
+ def is_array(self):
15
+ return self._classname == 'IDLArray'
16
+
17
+ @property
18
+ def is_void(self):
19
+ return self._classname == 'IDLVoid'
20
+
21
+ @property
22
+ def is_struct(self):
23
+ return self._classname == 'IDLStruct'
24
+
25
+ @property
26
+ def is_typedef(self):
27
+ return self._classname == 'IDLTypedef'
28
+
29
+ @property
30
+ def is_sequence(self):
31
+ return self._classname == 'IDLSequence'
32
+
33
+ @property
34
+ def is_primitive(self):
35
+ return self._classname == 'IDLPrimitive'
36
+
37
+ @property
38
+ def is_interface(self):
39
+ return self._classname == 'IDLInterface'
40
+
41
+ @property
42
+ def is_enum(self):
43
+ return self._classname == 'IDLEnum'
44
+
45
+ @property
46
+ def is_const(self):
47
+ return self._classname == 'IDLConst'
48
+
49
+ @property
50
+ def classname(self):
51
+ return self._classname
52
+
53
+
54
+
55
+ @property
56
+ def name(self):
57
+ return self._name
58
+
59
+ @property
60
+ def basename(self):
61
+ return self._name.split(self.sep)[-1]
62
+
63
+ @property
64
+ def basename(self):
65
+ if self.name.find(self.sep) > 0:
66
+ return self.name[self.name.rfind('::')+2:]
67
+ return self.name
68
+
69
+ @property
70
+ def pathname(self):
71
+ if self.name.find(self.sep) > 0:
72
+ return self.name[:self.name.rfind('::')]
73
+ return ''
74
+
75
+
76
+ @property
77
+ def parent(self):
78
+ return self._parent
79
+
80
+ def _name_and_type(self, blocks):
81
+ name = blocks[-1]
82
+ type = ''
83
+ for t in blocks[:-1]:
84
+ type = type + ' ' + t
85
+ type = type.strip()
86
+ return (name, type)
87
+
88
+ @property
89
+ def is_root(self):
90
+ return self.parent == None
91
+
92
+ @property
93
+ def root_node(self):
94
+ roots = []
95
+ def find_root(n):
96
+ if n.is_root:
97
+ roots.append(n)
98
+ else:
99
+ find_root(n.parent)
100
+ find_root(self)
101
+ return roots[0]
102
+
103
+ def refine_typename(self, typ):
104
+ global_module = self.root_node
105
+ if typ.find('sequence') >= 0:
106
+ typ_ = typ[typ.find('<')+1 : typ.find('>')]
107
+ typ__ = self.refine_typename(typ_)
108
+ return 'sequence < ' + typ__ + ' >'
109
+ else:
110
+ #f True:
111
+ typs = global_module.find_types(typ)
112
+ if len(typs) == 0:
113
+ return typ
114
+ else:
115
+ return typs[0].full_path
idl_parser/node.pyc ADDED
Binary file
idl_parser/parser.py ADDED
@@ -0,0 +1,274 @@
1
+ import os, sys
2
+
3
+ from . import module, token_buffer
4
+ from . import type as idl_type
5
+
6
+
7
+
8
+ class IDLParser():
9
+
10
+ def __init__(self, idl_dirs=[]):
11
+ self._global_module = module.IDLModule()
12
+ self._dirs = idl_dirs
13
+ self._verbose = False
14
+ @property
15
+ def global_module(self):
16
+ return self._global_module
17
+
18
+ def is_primitive(self, name):
19
+ return idl_type.is_primitive(name)
20
+
21
+ @property
22
+ def dirs(self):
23
+ return self._dirs
24
+
25
+ def load(self, input_str, include_dirs=[]):
26
+ self._dirs = self._dirs + include_dirs
27
+ lines = [l for l in input_str.split('\n')]
28
+ self.parse_lines(lines)
29
+ return self._global_module
30
+
31
+ def parse(self, idls=[], idl_dirs=[], except_files=[]):
32
+ """ Parse IDL files. Result of parsing can be accessed via global_module property.
33
+ :param idls: List of IDL files. Must be fullpath.
34
+ :param idl_dirs: List of directory which contains target IDL files. Must be fullpath.
35
+ :param except_files: List of IDL files that should be ignored. Do not have to use fullpath.
36
+ :returns: None
37
+ """
38
+ self.forEachIDL(self.parse_idl, except_files=except_files, idls=idls, idl_dirs=idl_dirs)
39
+
40
+ def parse_idl(self, idl_path):
41
+ if self._verbose: sys.stdout.write(' - Parsing IDL (%s)\n' % idl_path)
42
+ f = open(idl_path, 'r')
43
+ lines = []
44
+ for line in f:
45
+ lines.append(line)
46
+
47
+ self.parse_lines(lines)
48
+
49
+ def parse_lines(self, lines):
50
+
51
+ lines = self._clear_comments(lines)
52
+ lines = self._paste_include(lines)
53
+ lines = self._clear_ifdef(lines)
54
+
55
+ self._token_buf = token_buffer.TokenBuffer(lines)
56
+
57
+ self._global_module.parse_tokens(self._token_buf, filepath=None)
58
+
59
+ def includes(self, idl_path):
60
+ included_filepaths = []
61
+ included_filenames = []
62
+ f = open(idl_path, 'r')
63
+ lines = []
64
+ for line in f:
65
+ if line.find('#include') >= 0:
66
+ if line.find('"') >= 0:
67
+ file = line[line.find('"')+1:line.rfind('"')].strip()
68
+ elif line.find('<') >= 0:
69
+ file = line[line.find('<')+1:line.rfind('>')].strip()
70
+ included_filenames.append(file)
71
+ def get_fullpath(idl_path):
72
+ if os.path.basename(idl_path) in included_filenames:
73
+ included_filepaths.append(idl_path)
74
+ included_filenames.remove(os.path.basename(idl_path))
75
+
76
+ self.forEachIDL(get_fullpath)
77
+ if len(included_filenames) > 0:
78
+ raise IDLCanNotFindException()
79
+
80
+ return included_filepaths
81
+
82
+
83
+ def forEachIDL(self, func, idl_dirs=[], except_files=[], idls=[]):
84
+ """ Parse IDLs and apply function.
85
+ :param func: Function. IDL file fullpath will be passed to the function.
86
+ :param idls: List of IDL files. Must be fullpath.
87
+ :param idl_dirs: List of directory which contains target IDL files. Must be fullpath.
88
+ :param except_files: List of IDL files that should be ignored. Do not have to use fullpath.
89
+ :returns: None
90
+ """
91
+ idl_dirs = self._dirs + idl_dirs
92
+ self._dirs = idl_dirs
93
+ idls_ = []
94
+ basenames_ = []
95
+ for idl_dir in idl_dirs:
96
+ for f in os.listdir(idl_dir):
97
+ if f.endswith('.idl'):
98
+ if not f in except_files:
99
+ path = os.path.join(idl_dir, f)
100
+ if not f in basenames_:
101
+ idls_.append(path)
102
+ basenames_.append(os.path.basename(path))
103
+
104
+ idls_ = idls_ + idls
105
+ for f in idls_:
106
+ if self._verbose: sys.stdout.write(' - Apply function to %s\n' % f)
107
+ func(f)
108
+
109
+ def _find_idl(self, filename, apply_func, idl_dirs=[]):
110
+ if self._verbose: sys.stdout.write(' --- Find %s\n' % filename)
111
+
112
+ global retval
113
+ retval = None
114
+ def func(filepath):
115
+ if os.path.basename(filepath) == filename:
116
+ global retval
117
+ retval = apply_func(filepath)
118
+
119
+ self.forEachIDL(func, idl_dirs=idl_dirs)
120
+ return retval
121
+
122
+ def _paste_include(self, lines):
123
+ output_lines = []
124
+ for line in lines:
125
+ output_line = ''
126
+ if line.startswith('#include'):
127
+ def _include_paste(filepath):
128
+ return filepath
129
+
130
+ if line.find('"') >= 7:
131
+ filename = line[line.find('"')+1 : line.rfind('"')]
132
+ if self._verbose: sys.stdout.write(' -- Includes %s\n' % filename)
133
+ p = self._find_idl(filename, _include_paste)
134
+ if p is None:
135
+ sys.stdout.write(' # IDL (%s) can not be found.\n' % filename)
136
+ raise IDLFileNotFoundErrorx
137
+ self.parse_idl(idl_path = p)
138
+
139
+ inc_lines = []
140
+ f = open(p, 'r')
141
+ for l in f:
142
+ inc_lines.append(l)
143
+ inc_lines = self._clear_comments(inc_lines)
144
+ inc_lines = self._paste_include(inc_lines)
145
+ output_lines = output_lines + inc_lines
146
+
147
+ elif line.find('<') >= 7:
148
+ filename = line[line.find('<')+1 : line.rfind('>')]
149
+ if self._verbose: sys.stdout.write(' -- Includes %s\n' % filename)
150
+ p = self._find_idl(filename, _include_paste)
151
+ if p is None:
152
+ sys.stdout.write(' # IDL (%s) can not be found.\n' % filename)
153
+ raise IDLFileNotFoundErrorx
154
+ inc_lines = []
155
+
156
+ self.parse_idl(idl_path = p)
157
+
158
+ f = open(p, 'r')
159
+ for l in f:
160
+ inc_lines.append(l)
161
+ inc_lines = self._clear_comments(inc_lines)
162
+ inc_lines = self._paste_include(inc_lines)
163
+ output_lines = output_lines + inc_lines
164
+
165
+ else:
166
+ output_line = line
167
+
168
+ output_lines.append(output_line)
169
+
170
+ return output_lines
171
+
172
+
173
+
174
+ def _clear_comments(self, lines):
175
+ output_lines = []
176
+ in_comment = False
177
+
178
+ for line in lines:
179
+ line = line.strip()
180
+ output_line = ''
181
+ if line.find('//') >= 0:
182
+ line = line[:line.find('//')]
183
+
184
+ for token in line.split(' '):
185
+
186
+ if in_comment and token.find('*/') >= 0:
187
+ in_comment = False
188
+ output_line = output_line + ' ' + token[token.find('*/')+2:].strip()
189
+
190
+ elif in_comment:
191
+ continue
192
+
193
+ elif token.startswith('//'):
194
+ break # ignore this line
195
+
196
+ elif token.find('/*') >= 0:
197
+ in_comment = True
198
+ output_line = output_line + ' ' + token[0: token.find('/*')]
199
+ else:
200
+ if token.find('{') >= 0:
201
+ token = token.replace('{', ' { ')
202
+ if token.find(';') >= 0:
203
+ token = token.replace(';', ' ;')
204
+ if token.find('(') >= 0:
205
+ token = token.replace('(', ' ( ')
206
+ token = token.replace(',', ' , ')
207
+ token = token.replace(')', ' ) ')
208
+ token = token.replace('}', ' } ')
209
+ output_line = output_line + ' ' + token.strip()
210
+ if len(output_line.strip()) > 0:
211
+ output_lines.append(output_line.strip() + '\n')
212
+
213
+ return output_lines
214
+
215
+ def _clear_ifdef(self, lines):
216
+ output_lines = []
217
+ def_tokens = []
218
+ global offset
219
+ offset = 0
220
+ def _parse(flag):
221
+ global offset
222
+ while offset < len(lines):
223
+ line = lines[offset]
224
+ if line.startswith('#define'):
225
+ def_token = line.split(' ')[1]
226
+ def_tokens.append(def_token)
227
+ offset = offset + 1
228
+ elif line.startswith('#ifdef'):
229
+ def_token = line.split(' ')[1]
230
+ offset = offset + 1
231
+ _parse(def_token in def_tokens)
232
+
233
+ elif line.startswith('#ifndef'):
234
+ def_token = line.split(' ')[1]
235
+ offset = offset + 1
236
+ _parse(not def_token in def_tokens)
237
+
238
+ elif line.startswith('#endif'):
239
+ offset = offset + 1
240
+ return
241
+
242
+ else:
243
+ offset = offset + 1
244
+ if flag:
245
+ output_lines.append(line)
246
+
247
+ _parse(True)
248
+ return output_lines
249
+
250
+
251
+ def generate_constructor_python(self, typ):
252
+ code = ''
253
+ if typ.is_sequence:
254
+ code = code + '[]'
255
+ if typ.is_array:
256
+ code = code + '['
257
+ for i in range(typ.size):
258
+ code = code + self.generate_constructor_python(typ.inner_type)
259
+ if i != typ.size-1:
260
+ code = code + ', '
261
+ code = code + ']'
262
+ elif typ.is_primitive:
263
+ code = code + '0'
264
+ elif typ.is_typedef:
265
+ code = code + self.generate_constructor_python(typ.type)
266
+ elif typ.is_struct:
267
+ code = code + typ.full_path + '('
268
+ for m in typ.members:
269
+ if m.type.is_primitive:
270
+ code = code + self.generate_constructor_python(m.type) + ', '
271
+ else:
272
+ code = code + self.generate_constructor_python(m.type.obj) + ', '
273
+ code = code[:-2] + ')'
274
+ return code.replace('::', '.')
idl_parser/parser.pyc ADDED
Binary file