43 from genmsg
import SrvSpec, MsgSpec, MsgContext
44 from genmsg.msg_loader
import load_srv_from_file, load_msg_by_type
45 import genmsg.gentools
48 from cStringIO
import StringIO
50 from io
import StringIO
57 return t
in [
'byte',
'char',
'int8',
'uint8',
'int16',
'uint16',
'int32',
'uint32',
'int64',
'uint64']
60 return t
in [
'byte',
'int8',
'int16',
'int32',
'int64']
63 return t
in [
'char',
'uint8',
'uint16',
'uint32',
'uint64']
72 return t
in [
'float16',
'float32',
'float64']
75 return t
in [
'time',
'duration']
79 elt_type =
lisp_type(f.base_type, f.is_array)
85 "returns (package, msg_or_srv)"
86 if f.base_type ==
'Header':
87 return (
'std_msgs',
'Header')
89 return f.base_type.split(
'/')
92 "returns roseus namespace package::msg_or_srv"
94 return '%s::%s'%(pkg, msg)
97 if t ==
'uint8' and array:
110 raise ValueError(
'%s is not a recognized primitive type'%t)
114 if f.is_builtin
and not f.is_array:
116 return '(round %s)'%var
118 return '(float %s)'%var
120 return '(string %s)'%var
125 elt_type =
lisp_type(f.base_type, f.is_array)
127 elt_type =
':'+elt_type
129 len = f.array_len
or 0
131 return '(make-array %s :initial-element %s :element-type %s)'%(len, initvalue, elt_type)
133 return '(let (r) (dotimes (i %s) (push %s r)) r)'%(len, initvalue)
145 return '(instance ros::time :init)'
149 raise ValueError(
'%s is not a recognized primitive type'%t)
163 raise ValueError(
'%s is not a recognized primitive type'%t)
165 NUM_BYTES = {
'byte': 1,
'int8': 1,
'int16': 2,
'int32': 4,
'int64': 8,
166 'char': 1,
'uint8': 1,
'uint16': 2,
'uint32': 4,
'uint64': 8}
181 def write(self, s, indent=True, newline=True):
219 self.
writer.block_next_indent()
225 "Writes the beginning of the file: a comment saying it's auto-generated and the in-package form"
227 s.write(
';; Auto-generated. Do not edit!\n\n', newline=
False)
228 suffix =
'srv' if is_service
else 'msg'
230 spec.actual_name=spec.short_name
231 s.write(
'(when (boundp \'%s::%s)'%(spec.package, spec.actual_name))
232 s.write(
' (if (not (find-package "%s"))'%(spec.package.upper()))
233 s.write(
' (make-package "%s"))'%(spec.package.upper()))
234 s.write(
' (shadow \'%s (find-package "%s")))'%(spec.actual_name, spec.package.upper()))
235 s.write(
'(unless (find-package "%s::%s")'%(spec.package.upper(), spec.actual_name.upper()))
236 s.write(
' (make-package "%s::%s"))'%(spec.package.upper(), spec.actual_name.upper()))
238 s.write(
'(unless (find-package "%s::%sREQUEST")'%(spec.package.upper(), spec.actual_name.upper()))
239 s.write(
' (make-package "%s::%sREQUEST"))'%(spec.package.upper(), spec.actual_name.upper()))
240 s.write(
'(unless (find-package "%s::%sRESPONSE")'%(spec.package.upper(), spec.actual_name.upper()))
241 s.write(
' (make-package "%s::%sRESPONSE"))'%(spec.package.upper(), spec.actual_name.upper()))
243 s.write(
'(in-package "ROS")')
248 s.write(
';;//! \\htmlinclude %s.msg.html'%spec.actual_name, newline=
False)
249 for msg_type
in sorted(set([
parse_msg_type(field)[0]
for field
in spec.parsed_fields()
if not field.is_builtin
and parse_msg_type(field)[0] != spec.package])):
250 s.write(
'(if (not (find-package "%s"))'%msg_type.upper())
251 s.write(
' (ros::roseus-add-msgs "%s"))'%msg_type)
256 "Write the definition of a slot corresponding to a single message field"
257 s.write(
'_%s '%field.name, indent=
False, newline=
False)
261 "Write the key arguments of a slot corresponding to a single message field"
268 s.write(
'((:%s __%s) (let (r) (dotimes (i %s) (push (instance %s :init) r)) r))'%(var, var, field.array_len,
field_type(field)))
270 s.write(
'((:%s __%s) ())'%(var, var))
272 s.write(
'((:%s __%s) (instance %s :init))'%(var, var,
field_type(field)))
275 "Write the initialization of a slot corresponding to a single message field"
279 "Writes the defclass that defines the message type"
280 s.write(
'(defclass %s::%s'%(spec.package, spec.actual_name))
282 s.write(
':super ros::object')
284 with Indent(s, inc=1, indent_first=
False):
285 for field
in spec.parsed_fields():
287 s.write(
'))', indent=
False)
291 s.write(
'(defmethod %s::%s'%(spec.package, spec.actual_name))
297 for field
in spec.parsed_fields():
300 s.write(
'(send-super :init)')
301 for field
in spec.parsed_fields():
308 for field
in spec.parsed_fields():
309 s.write(
'(:%s'%field.name)
310 var =
'_%s'%field.name
313 if field.type ==
"bool":
314 s.write(
'(&optional (_%s :null))'%var)
315 s.write(
'(if (not (eq _%s :null)) (setq %s _%s)) %s)'%(var,var,var,var))
317 s.write(
'(&optional _%s)'%var)
318 s.write(
'(if _%s (setq %s _%s)) %s)'%(var,var,var,var))
320 s.write(
'(&rest _%s)'%var)
321 s.write(
'(if (keywordp (car _%s))'%var)
322 s.write(
' (send* %s _%s)'%(var,var))
325 s.write(
' (if _%s (setq %s (car _%s)))'%(var,var,var))
326 s.write(
' %s)))'%var)
330 s.write(
'(write-long (length %s) s)'%(v))
332 s.write(
'(write-long (length %s) s) (princ %s s)'%(v,v))
337 s.write(
'(write-byte %s s)'%v)
339 s.write(
'(write-word %s s)'%v)
341 s.write(
'(write-long %s s)'%v)
343 s.write(
'\n', indent=
False)
344 s.write(
'#+(or :alpha :irix6 :x86_64)', indent=
False, newline=
False)
345 s.write(
'(progn (sys::poke %s (send s :buffer) (send s :count) :long) (incf (stream-count s) 8))'%v)
346 s.write(
'\n', indent=
False)
347 s.write(
'#-(or :alpha :irix6 :x86_64)', indent=
False)
348 s.write(
'(cond ((and (class %s) (= (length (%s . bv)) 2)) ;; bignum'%(v,v))
349 s.write(
' (write-long (ash (elt (%s . bv) 0) 0) s)'%v)
350 s.write(
' (write-long (ash (elt (%s . bv) 1) -1) s))'%v)
351 s.write(
' ((and (class %s) (= (length (%s . bv)) 1)) ;; big1'%(v,v))
352 s.write(
' (write-long (elt (%s . bv) 0) s)'%v)
353 s.write(
' (write-long (if (>= %s 0) 0 #xffffffff) s))'%v)
354 s.write(
' (t ;; integer')
355 s.write(
' (write-long %s s)(write-long (if (>= %s 0) 0 #xffffffff) s)))'%(v,v))
362 if f.base_type ==
'string':
364 elif f.base_type ==
'float32':
365 s.write(
'(sys::poke %s (send s :buffer) (send s :count) :float) (incf (stream-count s) 4)'%v)
366 elif f.base_type ==
'float64':
367 s.write(
'(sys::poke %s (send s :buffer) (send s :count) :double) (incf (stream-count s) 8)'%v)
368 elif f.base_type ==
'bool':
369 s.write(
'(if %s (write-byte -1 s) (write-byte 0 s))'%v)
370 elif f.base_type
in [
'byte',
'char']:
371 s.write(
'(write-byte %s s)'%v)
372 elif f.base_type
in [
'duration',
'time']:
373 s.write(
'(write-long (send %s :sec) s) (write-long (send %s :nsec) s)'%(v,v))
379 raise ValueError(
'Unknown type: %s', f.base_type)
382 s.write(
';; %s _%s'%(f.type, f.name))
385 if f.is_array
and f.base_type ==
'uint8':
387 s.write(
'(write-long (length %s) s)'%slot)
388 s.write(
'(princ %s s)'%slot)
389 elif f.is_array
and is_string(f.base_type):
390 s.write(
'(write-long (length %s) s)'%slot)
391 s.write(
'(dolist (elem %s)'%slot)
396 if f.is_builtin
and f.array_len:
397 s.write(
'(dotimes (i %s)'%f.array_len)
398 elif f.is_builtin
and not f.array_len:
399 s.write(
'(dotimes (i (length %s))'%var)
401 s.write(
'(dolist (elem %s)'%slot)
403 var =
'(elt %s i)'%var
404 s.block_next_indent()
407 if f.is_array
and f.base_type ==
'uint8':
414 s.write(
'(send %s :serialize s)'%slot)
416 if f.is_array
and f.base_type !=
'uint8':
421 Write the serialize method
424 s.write(
'(:serialize')
426 s.write(
'(&optional strm)')
427 s.write(
'(let ((s (if strm strm')
428 s.write(
' (make-string-output-stream (send self :serialization-length)))))')
430 for f
in spec.parsed_fields():
433 s.write(
'(if (null strm) (get-output-stream-string s))))')
439 s.write(
'(setq n (sys::peek buf ptr- :integer)) (incf ptr- 4)')
440 s.write(
'(setq %s (let (r) (dotimes (i n) (push (instance %s :init) r)) r))'%(v,
field_type(f)))
442 set =
'setf' if v[0] ==
'(' else 'setq'
443 s.write(
'(let (n) (setq n (sys::peek buf ptr- :integer)) (incf ptr- 4) (%s %s (subseq buf ptr- (+ ptr- n))) (incf ptr- n))'%(set, v))
457 raise ValueError(
'Unknown size: %s', num_bytes)
459 set =
'setf' if v[0] ==
'(' else 'setq'
460 s.write(
'(%s %s (sys::peek buf ptr- %s)) (incf ptr- %s)'%(set,v,type,num_bytes))
463 if num_bytes
in [1,2,4]:
466 s.write(
'\n', indent=
False)
467 s.write(
'#+(or :alpha :irix6 :x86_64)', indent=
False)
468 s.write(
' (setf %s (prog1 (sys::peek buf ptr- :long) (incf ptr- 8)))\n'%v)
469 s.write(
'#-(or :alpha :irix6 :x86_64)', indent=
False)
470 s.write(
' (setf %s (let ((b0 (prog1 (sys::peek buf ptr- :integer) (incf ptr- 4)))'%v)
471 s.write(
' (b1 (prog1 (sys::peek buf ptr- :integer) (incf ptr- 4))))')
472 s.write(
' (cond ((= b1 -1) b0)')
473 s.write(
' ((and (= b1 0)')
474 s.write(
' (<= lisp::most-negative-fixnum b0 lisp::most-positive-fixnum))')
476 s.write(
' ((= b1 0) (make-instance bignum :size 1 :bv (integer-vector b0)))')
477 s.write(
' (t (make-instance bignum :size 2 :bv (integer-vector b0 (ash b1 1)))))))')
480 set =
'setf' if v[0] ==
'(' else 'setq'
481 if f.base_type ==
'string':
483 elif f.base_type ==
'float32':
484 s.write(
'(%s %s (sys::peek buf ptr- :float)) (incf ptr- 4)'%(set, v))
485 elif f.base_type ==
'float64':
486 s.write(
'(%s %s (sys::peek buf ptr- :double)) (incf ptr- 8)'%(set, v))
487 elif f.base_type ==
'bool':
488 s.write(
'(%s %s (not (= 0 (sys::peek buf ptr- :char)))) (incf ptr- 1)'%(set, v))
489 elif f.base_type
in [
'duration',
'time']:
490 s.write(
'(send %s :sec (sys::peek buf ptr- :integer)) (incf ptr- 4) (send %s :nsec (sys::peek buf ptr- :integer)) (incf ptr- 4)'%(v,v))
493 if NUM_BYTES[f.base_type] == 1:
494 s.write(
'(if (> %s 127) (%s %s (- %s 256)))'%(v,set,v,v))
498 raise ValueError(
'%s unknown'%f.base_type)
502 s.write(
';; %s %s'%(f.type, var))
505 if f.base_type ==
'uint8':
507 s.write(
'(setq %s (make-array %d :element-type :char))'%(var,f.array_len))
508 s.write(
'(replace %s buf :start2 ptr-) (incf ptr- %d)'%(var,f.array_len))
510 s.write(
'(let ((n (sys::peek buf ptr- :integer))) (incf ptr- 4)')
511 s.write(
' (setq %s (make-array n :element-type :char))'%var)
512 s.write(
' (replace %s buf :start2 ptr-) (incf ptr- n))'%(var))
514 s.write(
'(dotimes (i (length %s))'%var)
515 var =
'(elt %s i)'%var
520 s.write(
'(setq n (sys::peek buf ptr- :integer)) (incf ptr- 4)')
522 s.write(
'(setq %s (make-list n))'%var)
524 s.write(
'(setq %s (instantiate %s-vector n))'%(var,
lisp_type(f.base_type, f.is_array)))
525 s.write(
'(dotimes (i n)')
526 var =
'(elt %s i)'%var
531 s.write(
'(dolist (%s _%s)'%(var, f.name))
534 s.write(
'(dotimes (i %s)'%f.array_len)
535 var =
'(elt _%s i)'%f.name
540 s.write(
'(dolist (%s _%s)'%(var, f.name))
541 if f.is_array
and f.base_type ==
'uint8':
548 s.write(
'(send %s :deserialize buf ptr-) (incf ptr- (send %s :serialization-length))'%(var, var))
550 if f.is_array
and not f.base_type ==
'uint8':
560 Write the deserialize method
563 s.write(
'(:deserialize')
565 s.write(
'(buf &optional (ptr- 0))')
566 for f
in spec.parsed_fields():
574 md5sum = genmsg.compute_md5(msg_context, parent
or spec)
575 s.write(
'(setf (get %s::%s :md5sum-) "%s")'%(spec.package, spec.actual_name, md5sum))
578 s.write(
'(setf (get %s::%s :datatype-) "%s/%s")'%(spec.package, spec.actual_name, spec.package, spec.actual_name))
581 s.write(
'(setf (get %s::%s :definition-)'%(spec.package, spec.actual_name))
584 definition = genmsg.compute_full_text(msg_context, spec)
585 lines = definition.split(
'\n')
587 l = line.replace(
'\\',
'\\\\')
588 l = l.replace(
'"',
'\\"')
589 s.write(
'%s\n'%l, indent=
False, newline=
False)
590 s.write(
'")', newline=
False)
594 s.write(
'(setf (get %s::%s :definition-)'%(parent.package, parent.actual_name))
597 for spec_service
in [spec.request, spec.response]:
598 definition = genmsg.compute_full_text(msg_context, spec_service)
599 lines = definition.split(
'\n')
600 for line
in lines[:-1]:
601 l = line.replace(
'\\',
'\\\\')
602 l = l.replace(
'"',
'\\"')
603 s.write(
'%s\n'%l, indent=
False, newline=
False)
604 if spec_service == spec.request:
605 s.write(
'---\n', indent=
False, newline=
False)
606 s.write(
'")', newline=
False)
609 if f.base_type
in [
'int8',
'uint8']:
611 elif f.base_type
in [
'int16',
'uint16']:
613 elif f.base_type
in [
'int32',
'uint32',
'float32']:
615 elif f.base_type
in [
'int64',
'uint64',
'float64',
'duration',
'time']:
617 elif f.base_type ==
'string':
618 s.write(
'4 (length _%s)'%f.name)
619 elif f.base_type
in [
'bool',
'byte',
'char']:
622 raise ValueError(
'Unknown: %s', f.base_type)
626 s.write(
'(:serialization-length')
631 if not spec.parsed_fields():
633 for field
in spec.parsed_fields():
634 s.write(
';; %s _%s'%(field.type, field.name))
636 if field.is_builtin
and not is_string(field.base_type):
639 s.write(
'(apply #\'+ ')
640 s.block_next_indent()
643 if not field.array_len:
645 s.write(
'(mapcar #\'(lambda (x) (+ 4 (length x))) _%s)) 4'%(field.name))
648 s.write(
'(length _%s)) 4'%field.name, newline=
False)
651 s.write(
'%s)'%field.array_len, newline=
False)
654 s.write(
'(send-all _%s :serialization-length))'%field.name)
656 s.write(
'(send-all _%s :serialization-length)) 4'%field.name)
661 s.write(
'(send _%s :serialization-length)'%field.name)
667 md5sum = genmsg.compute_md5(msg_context, spec)
668 s.write(
'(provide :%s/%s "%s")'%(spec.package, spec.actual_name,md5sum))
673 for c
in spec.constants:
674 s.write(
'(intern "*%s*" (find-package "%s::%s"))'%(c.name.upper(), spec.package.upper(), spec.actual_name.upper()))
675 s.write(
'(shadow \'*%s* (find-package "%s::%s"))'%(c.name.upper(), spec.package.upper(), spec.actual_name.upper()))
676 if c.type ==
'string':
677 s.write(
'(defconstant %s::%s::*%s* "%s")'%(spec.package, spec.actual_name, c.name.upper(), c.val.replace(
'"',
'\\"')))
678 elif c.type ==
'bool':
679 s.write(
'(defconstant %s::%s::*%s* %s)'%(spec.package, spec.actual_name, c.name.upper(),
"t" if c.val ==
True else "nil"))
681 s.write(
'(defconstant %s::%s::*%s* %s)'%(spec.package, spec.actual_name, c.name.upper(), c.val))
683 s.write(
'(defun %s::%s-to-symbol (const)'%(spec.package, spec.actual_name))
685 for c
in [c
for c
in spec.constants
if is_integer(c.type)]:
686 s.write(
" ((= const %s) '%s::%s::*%s*)"%(c.val, spec.package, spec.actual_name, c.name))
687 s.write(
' (t nil)))')
691 spec.component_type=
'service'
702 s.write(
'(defclass %s::%s'%(spec.package, spec.actual_name))
704 s.write(
':super ros::object')
705 s.write(
':slots ())')
709 s.write(
'(setf (get %s::%s :request) %s::%s)'%(spec.package, spec.actual_name, spec.request.package, spec.request.actual_name))
710 s.write(
'(setf (get %s::%s :response) %s::%s)'%(spec.package, spec.actual_name, spec.response.package, spec.response.actual_name))
712 s.write(
'(defmethod %s::%s'%(spec.request.package, spec.request.actual_name))
713 s.write(
' (:response () (instance %s::%s :init)))'%(spec.response.package, spec.response.actual_name))
715 for spec_service
in [spec.request, spec.response]:
722 s.write(
'\n', newline=
False)
726 Generate euslisp code for all messages in a package
728 msg_context = MsgContext.create_default()
730 f = os.path.abspath(f)
731 infile = os.path.basename(f)
732 full_type = genmsg.gentools.compute_full_type_name(pkg, infile)
733 spec = genmsg.msg_loader.load_msg_from_file(msg_context, f, full_type)
738 Generate euslisp code for all services in a package
740 msg_context = MsgContext.create_default()
742 f = os.path.abspath(f)
743 infile = os.path.basename(f)
744 full_type = genmsg.gentools.compute_full_type_name(pkg, infile)
745 spec = genmsg.msg_loader.load_srv_from_file(msg_context, f, full_type)
749 dir_list = search_path[pkg]
752 files.extend([f
for f
in os.listdir(d)
if f.endswith(ext)])
753 return [f[:-len(ext)]
for f
in files]
759 @param msg_path: The path to the .msg file
762 genmsg.msg_loader.load_depends(msg_context, spec, search_path)
763 spec.actual_name=spec.short_name
764 spec.component_type=
'message'
765 msgs =
msg_list(package, search_path,
'.msg')
767 genmsg.load_msg_by_type(msg_context,
'%s/%s'%(package, m), search_path)
790 if (
not os.path.exists(output_dir)):
794 os.makedirs(output_dir)
798 with open(
'%s/%s.l'%(output_dir, spec.short_name),
'w')
as f:
799 f.write(io.getvalue() +
"\n")
805 "Generate code from .srv file"
806 genmsg.msg_loader.load_depends(msg_context, spec, search_path)
808 srvs = [f[:-len(ext)]
for f
in os.listdir(os.path.dirname(path))
if f.endswith(ext)]
810 load_srv_from_file(msg_context, path,
'%s/%s'%(package, s))
821 spec.request.actual_name=
'%sRequest'%spec.short_name
822 spec.response.actual_name=
'%sResponse'%spec.short_name
827 with open(
'%s/%s.l'%(output_dir, spec.short_name),
'w')
as f:
828 f.write(io.getvalue())