Go to the documentation of this file.00001 import os.path
00002 import re
00003
00004 AT_LEAST_THREE_DASHES = re.compile('^\-{3,}\r?$')
00005 FIELD_LINE = re.compile('([\w_/]+)(\[\d*\])?\s+([\w_]+)\s*(=.*)?(\s*\#.*)?$', re.DOTALL)
00006
00007
00008 class GeneratorField:
00009 def __init__(self, type, is_array, name, value):
00010 self.type = type
00011 self.is_array = is_array
00012 self.name = name
00013 self.value = value
00014
00015 def __repr__(self):
00016 s = self.type
00017 if self.is_array:
00018 s += '[]'
00019 s += ' '
00020 s += self.name
00021 if self.value:
00022 s += '='
00023 s += self.value
00024 return s
00025
00026
00027 class GeneratorSection:
00028 def __init__(self):
00029 self.contents = []
00030 self.fields = []
00031
00032 def add_line(self, line):
00033 stripped = line.strip()
00034 if not stripped or stripped[0] == '#':
00035 self.contents.append(line)
00036 return
00037 m = FIELD_LINE.match(line)
00038 if m:
00039 type, is_array, name, value, comment = m.groups()
00040 field = GeneratorField(type, is_array, name, value)
00041 self.contents.append(field)
00042 self.fields.append(field)
00043 if comment:
00044 self.contents.append(comment)
00045 else:
00046 self.contents.append('\n')
00047 else:
00048 raise Exception('Unable to parse generator line: ' + repr(line))
00049
00050 def __repr__(self):
00051 return ''.join(map(str, self.contents))
00052
00053
00054 class ROSGenerator:
00055 def __init__(self, rel_fn, file_path):
00056 self.file_path = file_path
00057 parts = os.path.splitext(rel_fn)
00058 self.base_name = os.path.split(parts[0])[-1]
00059 self.type = parts[-1][1:]
00060 self.name = os.path.basename(rel_fn)
00061 self.changed = False
00062 self.sections = [GeneratorSection()]
00063
00064 self.dependencies = set()
00065
00066 with open(file_path) as f:
00067 for line in f:
00068 if AT_LEAST_THREE_DASHES.match(line):
00069 self.sections.append(GeneratorSection())
00070 continue
00071 else:
00072 self.sections[-1].add_line(line)
00073
00074 for section in self.sections:
00075 for field in section.fields:
00076 if '/' not in field.type:
00077 continue
00078 package, part = field.type.split('/')
00079 if package != self.name:
00080 self.dependencies.add(package)
00081
00082 if self.type == 'action':
00083 self.dependencies.add('actionlib_msgs')
00084
00085 def output(self):
00086 return '---\n'.join(map(str, self.sections))
00087
00088 def write(self):
00089 if not self.changed:
00090 return
00091 with open(self.file_path, 'w') as f:
00092 f.write(self.output())
00093
00094 def __repr__(self):
00095 return self.name