241 @param module module name associated with the source text |
241 @param module module name associated with the source text |
242 @type str |
242 @type str |
243 @return dictionary containing the extracted data |
243 @return dictionary containing the extracted data |
244 @rtype dict |
244 @rtype dict |
245 """ |
245 """ |
|
246 def calculateEndline(lineno, lines): |
|
247 """ |
|
248 Function to calculate the end line. |
|
249 |
|
250 @param lineno line number to start at (one based) |
|
251 @type int |
|
252 @param lines list of source lines |
|
253 @type list of str |
|
254 @return end line (one based) |
|
255 @rtype int |
|
256 """ |
|
257 # convert lineno to be zero based |
|
258 lineno -= 1 |
|
259 # 1. search for opening brace '{' |
|
260 while lineno < len(lines) and not "{" in lines[lineno]: |
|
261 lineno += 1 |
|
262 depth = lines[lineno].count("{") - lines[lineno].count("}") |
|
263 # 2. search for ending line, i.e. matching closing brace '}' |
|
264 while depth > 0 and lineno < len(lines) - 1: |
|
265 lineno += 1 |
|
266 depth += lines[lineno].count("{") - lines[lineno].count("}") |
|
267 if depth == 0: |
|
268 # found a matching brace |
|
269 return lineno + 1 |
|
270 else: |
|
271 # nothing found |
|
272 return -1 |
|
273 |
246 # convert eol markers the Python style |
274 # convert eol markers the Python style |
247 src = src.replace("\r\n", "\n").replace("\r", "\n") |
275 src = src.replace("\r\n", "\n").replace("\r", "\n") |
|
276 srcLines = src.splitlines() |
248 |
277 |
249 dictionary = {} |
278 dictionary = {} |
250 |
279 |
251 classstack = [] # stack of (class, indent) pairs |
280 classstack = [] # stack of (class, indent) pairs |
252 indent = 0 |
281 indent = 0 |
253 |
282 |
254 lineno, last_lineno_pos = 1, 0 |
283 lineno, last_lineno_pos = 1, 0 |
255 lastGlobalEntry = None |
|
256 cur_obj = None |
|
257 i = 0 |
284 i = 0 |
258 while True: |
285 while True: |
259 m = _getnext(src, i) |
286 m = _getnext(src, i) |
260 if not m: |
287 if not m: |
261 break |
288 break |
317 lineno = lineno + src.count('\n', last_lineno_pos, start) |
337 lineno = lineno + src.count('\n', last_lineno_pos, start) |
318 last_lineno_pos = start |
338 last_lineno_pos = start |
319 message_name = m.group("MessageName") |
339 message_name = m.group("MessageName") |
320 # close all messages/services indented at least as much |
340 # close all messages/services indented at least as much |
321 while classstack and classstack[-1][1] >= thisindent: |
341 while classstack and classstack[-1][1] >= thisindent: |
322 if classstack[-1][0] is not None: |
|
323 # record the end line |
|
324 classstack[-1][0].setEndLine(lineno - 1) |
|
325 del classstack[-1] |
342 del classstack[-1] |
326 # remember this message |
343 # remember this message |
327 cur_class = Message(module, message_name, file, lineno) |
344 cur_class = Message(module, message_name, file, lineno) |
|
345 endline = calculateEndline(lineno, srcLines) |
|
346 cur_class.setEndLine(endline) |
328 if not classstack: |
347 if not classstack: |
329 dictionary[message_name] = cur_class |
348 dictionary[message_name] = cur_class |
330 else: |
349 else: |
331 msg = classstack[-1][0] |
350 msg = classstack[-1][0] |
332 msg._addclass(message_name, cur_class) |
351 msg._addclass(message_name, cur_class) |
333 if not classstack: |
|
334 if lastGlobalEntry: |
|
335 lastGlobalEntry.setEndLine(lineno - 1) |
|
336 lastGlobalEntry = cur_class |
|
337 cur_obj = cur_class |
|
338 classstack.append((cur_class, thisindent)) |
352 classstack.append((cur_class, thisindent)) |
339 |
353 |
340 elif m.start("Enum") >= 0: |
354 elif m.start("Enum") >= 0: |
341 # we found a message definition |
355 # we found a message definition |
342 thisindent = indent |
356 thisindent = indent |
343 indent += 1 |
357 indent += 1 |
344 # close all messages/services indented at least as much |
358 # close all messages/services indented at least as much |
345 while classstack and classstack[-1][1] >= thisindent: |
359 while classstack and classstack[-1][1] >= thisindent: |
346 if classstack[-1][0] is not None: |
|
347 # record the end line |
|
348 classstack[-1][0].setEndLine(lineno - 1) |
|
349 del classstack[-1] |
360 del classstack[-1] |
350 lineno = lineno + src.count('\n', last_lineno_pos, start) |
361 lineno = lineno + src.count('\n', last_lineno_pos, start) |
351 last_lineno_pos = start |
362 last_lineno_pos = start |
352 enum_name = m.group("EnumName") |
363 enum_name = m.group("EnumName") |
353 # remember this Enum |
364 # remember this Enum |
354 cur_class = Enum(module, enum_name, file, lineno) |
365 cur_class = Enum(module, enum_name, file, lineno) |
|
366 endline = calculateEndline(lineno, srcLines) |
|
367 cur_class.setEndLine(endline) |
355 if not classstack: |
368 if not classstack: |
356 dictionary[enum_name] = cur_class |
369 dictionary[enum_name] = cur_class |
357 else: |
370 else: |
358 enum = classstack[-1][0] |
371 enum = classstack[-1][0] |
359 enum._addclass(enum_name, cur_class) |
372 enum._addclass(enum_name, cur_class) |
360 if not classstack: |
|
361 if lastGlobalEntry: |
|
362 lastGlobalEntry.setEndLine(lineno - 1) |
|
363 lastGlobalEntry = cur_class |
|
364 cur_obj = cur_class |
|
365 classstack.append((cur_class, thisindent)) |
373 classstack.append((cur_class, thisindent)) |
366 |
374 |
367 elif m.start("Service") >= 0: |
375 elif m.start("Service") >= 0: |
368 # we found a message definition |
376 # we found a message definition |
369 thisindent = indent |
377 thisindent = indent |
370 indent += 1 |
378 indent += 1 |
371 # close all messages/services indented at least as much |
379 # close all messages/services indented at least as much |
372 while classstack and classstack[-1][1] >= thisindent: |
380 while classstack and classstack[-1][1] >= thisindent: |
373 if classstack[-1][0] is not None: |
|
374 # record the end line |
|
375 classstack[-1][0].setEndLine(lineno - 1) |
|
376 del classstack[-1] |
381 del classstack[-1] |
377 lineno = lineno + src.count('\n', last_lineno_pos, start) |
382 lineno = lineno + src.count('\n', last_lineno_pos, start) |
378 last_lineno_pos = start |
383 last_lineno_pos = start |
379 service_name = m.group("ServiceName") |
384 service_name = m.group("ServiceName") |
380 # remember this Service |
385 # remember this Service |
381 cur_class = Service(module, service_name, file, lineno) |
386 cur_class = Service(module, service_name, file, lineno) |
|
387 endline = calculateEndline(lineno, srcLines) |
|
388 cur_class.setEndLine(endline) |
382 if not classstack: |
389 if not classstack: |
383 dictionary[service_name] = cur_class |
390 dictionary[service_name] = cur_class |
384 else: |
391 else: |
385 service = classstack[-1][0] |
392 service = classstack[-1][0] |
386 service._addclass(service_name, cur_class) |
393 service._addclass(service_name, cur_class) |
387 if not classstack: |
|
388 if lastGlobalEntry: |
|
389 lastGlobalEntry.setEndLine(lineno - 1) |
|
390 lastGlobalEntry = cur_class |
|
391 cur_obj = cur_class |
|
392 classstack.append((cur_class, thisindent)) |
394 classstack.append((cur_class, thisindent)) |
393 |
395 |
394 elif m.start("Begin") >= 0: |
396 elif m.start("Begin") >= 0: |
395 # a begin of a block we are not interested in |
397 # a begin of a block we are not interested in |
396 indent += 1 |
398 indent += 1 |