28 from Cheetah.Template
import Template
29 from roslib.message
import get_message_class, get_service_class
30 from collections
import namedtuple
32 pp = pprint.PrettyPrinter(indent=1)
37 accessor = default_accessor
43 prefix_template =
'{0}for(auto {1} : {2}) \n{0}{{\n' 44 suffix_template =
'{0}}}\n' 45 result_template =
'{0}->process({1}{2});\n' 48 while (field.count(
'[].') > 0):
49 splitfield = field.split(
'[].', 1)
51 container = accessor + splitfield[0]
52 accessor = splitfield[0].split(
'.')[-1].rstrip(
's')+
get_accessor(indent_level)
53 field =
''.join(splitfield[1:])
55 prefix = prefix + prefix_template.format(
57 suffix = suffix_template.format(
format_indent(indent_level)) + suffix
60 inset =
format_indent(indent_level) + result_template.format(processor, accessor, field)
62 result = prefix + inset + suffix
68 return ''.join([
' ' for s
in xrange(indent_level)])
81 def find_fields(msg_srv_class, field_name_pattern=None, field_type_pattern=None):
84 if field_name_pattern
is None:
85 field_name_pattern =
".*" 86 if field_type_pattern
is None:
87 field_type_pattern =
".*" 89 name_regex = re.compile(field_name_pattern)
90 type_regex = re.compile(field_type_pattern)
93 if hasattr(msg_srv_class,
'__slots__'):
94 for (field_name, field_type)
in zip(msg_srv_class.__slots__, msg_srv_class._slot_types):
96 if name_regex.match(field_name)
is not None and type_regex.match(field_type)
is not None:
97 fields.append(field_name)
104 field_type = field_type.rstrip(
"[]")
105 child_fields =
find_fields(get_message_class(field_type), field_name_pattern, field_type_pattern)
106 for child_field
in child_fields:
107 fields.append(
"{0}.{1}".format(field_name, child_field))
113 return field_type.find(
'/') == -1
117 return field_type[-2:] ==
'[]' 120 if __name__ ==
"__main__":
121 parser = argparse.ArgumentParser(description=
'Generate message processor headers and sources.')
122 parser.add_argument(
'pkg_name', metavar=
'package_name', help=
'Package Name')
123 parser.add_argument(
'--msg-names', metavar=
'*.msg', nargs=
'*', help=
'Message file paths')
124 parser.add_argument(
'--srv-names', metavar=
'*.srv', nargs=
'*', help=
'Service file paths')
125 parser.add_argument(
'--cpp-tmpl', metavar=
'*.cpp.tmpl', help=
'Source template file')
126 parser.add_argument(
'--h-tmpl', metavar=
'*.h.tmpl', help=
'Header template file')
127 parser.add_argument(
'--cpp-out', metavar=
'*.cpp', help=
'Output source file')
128 parser.add_argument(
'--h-out', metavar=
'*.h', help=
'Output header file')
130 args = parser.parse_args()
132 args.cpp_out = args.pkg_name +
"_message_processor.cpp" 134 args.h_out = args.pkg_name +
"_message_processor.h" 137 FIELD_NAME_FILTER =
'field_name_filter' 138 FIELD_TYPE_FILTER =
'field_type_filter' 142 ServiceComponent = namedtuple(
"ServiceComponent",
"name accessor member_class")
143 SERVICE_COMPONENTS = [
ServiceComponent(name=
"req", accessor=
"req.", member_class=
"_request_class"),
144 ServiceComponent(name=
"res", accessor=
"res.", member_class=
"_response_class")]
154 'frame_id_processor': {
155 FIELD_NAME_FILTER:
'.*frame_id.*',
156 FIELD_TYPE_FILTER:
'string',
159 FIELD_NAME_FILTER:
None,
160 FIELD_TYPE_FILTER:
'time',
164 for processor_name, processor
in processors.iteritems():
165 processor[MESSAGES] = {}
166 for msg_name
in args.msg_names:
167 msg_base = msg_name.partition(
'/')[2]
168 msg_class = get_message_class(msg_name)
169 fields =
find_fields(msg_srv_class=msg_class, field_name_pattern=processor[FIELD_NAME_FILTER],
170 field_type_pattern=processor[FIELD_TYPE_FILTER])
172 processor[MESSAGES][msg_base] = field_processors
175 processor[SERVICES] = {}
176 for srv_name
in args.srv_names:
177 srv_base = srv_name.partition(
'/')[2]
178 srv_class = get_service_class(srv_name)
179 processor[SERVICES][srv_base] = {}
181 for component
in SERVICE_COMPONENTS:
182 if hasattr(srv_class, component.member_class):
183 fields =
find_fields(msg_srv_class=getattr(srv_class, component.member_class),
184 field_name_pattern=processor[FIELD_NAME_FILTER],
185 field_type_pattern=processor[FIELD_TYPE_FILTER])
188 processor[SERVICES][srv_base][component.name] = field_processors
190 template_namespace = {}
191 template_namespace[
'processors'] = processors
192 template_namespace[
'pkg_name'] = args.pkg_name
193 template_namespace[MESSAGES] = [msg_name.partition(
'/')[2]
for msg_name
in args.msg_names]
194 template_namespace[SERVICES] = [srv_name.partition(
'/')[2]
for srv_name
in args.srv_names]
197 pp.pprint(
"Generating templates for package " + args.pkg_name)
198 with open(args.cpp_tmpl,
'r') as f: 199 source_template = Template(f.read(), searchList=[template_namespace]) 200 with open(args.h_tmpl, 'r') as f: 201 header_template = Template(f.read(), searchList=[template_namespace]) 203 with open(args.cpp_out, 'w')
as f:
204 f.write(str(source_template))
205 with open(args.h_out,
'w')
as f:
206 f.write(str(header_template))
def is_msg_array(field_type)
def is_primitive_msg(field_type)
def generate_cpp_iteration(field, default_accessor, processor)
def format_indent(indent_level)
def get_accessor(indent_level)
def find_fields(msg_srv_class, field_name_pattern=None, field_type_pattern=None)