patch from Steven Jenkins -------

The attached patch updates files in comedilib/swig/ruby. lib/comedi.rb is
updated to raise Ruby exceptions as indicated by the comedilib API
documentation. README and demo/cmd are updated accordingly.
This commit is contained in:
Frank Mori Hess 2004-03-06 22:13:37 +00:00
parent b48bfe080a
commit 41ce3f70a0
3 changed files with 185 additions and 61 deletions

View file

@ -12,7 +12,7 @@ Instructions for building by hand (you shouldn't need to do this):
library and the file lib/comedi.rb, which provides more
Ruby-like method syntax.
The file 'lib/comedi.rb' provides syntactic sugar in three forms:
The file 'lib/comedi.rb' provides syntactic sugar in four forms:
1. Method names without the 'comedi_' prefix. The Comedi module
disambiguates the namespace. For example, you can say
@ -26,6 +26,10 @@ The file 'lib/comedi.rb' provides syntactic sugar in three forms:
reading from the file descriptor associated with the comedi device.
Data from comedi device 'dev' can be read by 'dev.ios.read'.
4. A ComediError exception class. If the underlying comedi
function returns an error indication, the ruby method will raise
ComediError.
The file 'demo/cmd' is a straight port of 'cmd.c' from the
Comedilib 'demo' directory. It illustrates the basics of programming
Comedi commands using Ruby.
@ -44,4 +48,4 @@ omitted from the parameter list. For example:
Steven Jenkins
steven.jenkins@ieee.org
2004-01-12
2004-03-02

View file

@ -51,16 +51,18 @@ ret, cmd = dev.prepare_cmd_lib($subdevice, $freq, Comedi_cmd_struct.new)
$stderr.printf("command before testing:\n")
dump_cmd($stderr, cmd)
ret, cmd = dev.command_test(cmd)
if ret < 0
begin
ret, cmd = dev.command_test(cmd)
rescue
comedi_perror("comedi_command_test")
exit 1
end
$stderr.printf("first test returned %d (%s)\n", ret, cmdtest_messages[ret])
dump_cmd($stderr, cmd)
ret, cmd = dev.command_test(cmd)
if ret < 0
begin
ret, cmd = dev.command_test(cmd)
rescue
comedi_perror("comedi_command_test")
exit 1
end
@ -70,8 +72,9 @@ dump_cmd($stderr, cmd)
tstart = Time.new
$stderr.printf("start time: %d.%06d\n", tstart.tv_sec, tstart.tv_usec)
ret = dev.command(cmd)
if ret < 0
begin
ret = dev.command(cmd)
rescue
comedi_perror("comedi_command")
exit 1
end

View file

@ -13,7 +13,7 @@
# This file is syntactic sugar for accessing the Ruby comedilib
# extension library generated by SWIG. The syntactic sugar is in
# three forms:
# four forms:
#
# (1) Method names without the 'comedi_' prefix. The Comedi module
# disambiguates the namespace.
@ -25,94 +25,211 @@
# (3) A pre-defined IO object and an accessor method to simplify
# reading from the file descriptor associated with the comedi device.
# Data from comedi device dev can be accessed with dev.ios.read.
#
# (4) A ComediError exception class. If the underlying comedi
# function returns an error indication, the ruby method will raise
# ComediError.
require 'comedi.so'
include Comedi
include SWIG
module SWIG
# SWIG::TYPE_p_comedi_t is returned by Comedi::open
# TYPE_p_comedi_t is returned by Comedi::open
class TYPE_p_comedi_t
class SWIG::TYPE_p_comedi_t
# create an IO object to access the comedi_t fileno
def ios
@ios = IO.new(fileno, 'r') if @ios.nil?
@ios
def self.ios
@ios
end
@ios = IO.new(fileno, 'r')
end
end
# ComediError is raised by methods whose underlying comedi functions return
# indication of an error.
class ComediError < SystemCallError
def initialize
@comedi_errno = Comedi::errno
end
attr_reader :comedi_errno
end
module Comedi
private
# wrap_module_method defines Comedi module methods without the
# unnecessary comedi_ prefix.
# wrap_method is the basis for wrap_module_method and
# wrap_instance_method.
def wrap_module_method(mod, name)
mod.module_eval <<-EOF
def wrap_method(mod, name, err, arglist)
wrap_def = %Q{
def #{name}(*args)
comedi_#{name}(*args)
ret = comedi_#{name}(#{arglist})
}
unless err == :none
wrap_def << %Q{ raise ComediError.new if }
case err
when :neg
wrap_def << %Q{ ret < 0 }
when nil
wrap_def << %Q{ ret.nil? }
else
wrap_def << %Q{ ret == #{err} }
end
EOF
end
wrap_def << %Q{
ret
end
}
mod.module_eval wrap_def
end
# wrap_module_method defines Comedi module methods without the
# unnecessary comedi_ prefix. The wrapped method raises
# ComediError if the return value equals a specified value.
def wrap_module_method(mod, name, err)
wrap_method(mod, name, err, '*args')
end
# wrap_instance_method defines instance methods for any of several
# classes. It removes the comedi_ prefix and allows use of an
# explicit receiver.
# explicit receiver. The wrapped method raises ComediError
# if the return value equals a specified value.
def wrap_instance_method(mod, name)
mod.module_eval <<-EOF
def #{name}(*args)
comedi_#{name}(self, *args)
end
EOF
def wrap_instance_method(mod, name, err)
wrap_method(mod, name, err, 'self, *args')
end
# Comedi module methods
# This struct holds information for methods with return class and
# error indication.
%w{ open loglevel perror strerrno errno to_phys from_phys
set_global_oor_behavior parse_calibration_file
}.each do |name|
wrap_module_method(Comedi, name)
Method_group = Struct.new(:class, :err, :names)
# Wrap Comedi module methods
[
# Comedi module methods that return nil on error.
Method_group.new(Comedi, nil, %w{
open
parse_calibration_file
}),
# Comedi module methods that do not indicate errors.
Method_group.new(Comedi, :none, %w{
loglevel
perror
strerrno
errno
to_phys
from_phys
set_global_oor_behavior
}),
].each do |d|
d.names.each do |n|
wrap_module_method(d.class, n, d.err)
end
end
# Comedi_t_struct instance methods
# Wrap Instance methods
%w{ close fileno get_n_subdevices get_version_code
get_driver_name get_board_name get_subdevice_type
find_subdevice_by_type get_read_subdevice get_write_device
get_subdevice_flags get_n_channels range_is_chan_specific
maxdata_is_chan_specific get_maxdata get_n_ranges
get_range find_range get_buffer size
get_max_buffer_size set_buffer_size trigger
do_insnlist do_insn lock unlock data_read
data_read_delayed data_read_hint data_write dio_config
dio_read dio_write dio_bitfield get_cmd_src_mask
get_cmd_generic_timed cancel command command_test poll
set_max_buffer_size get_buffer_contents
mark_buffer_read get_buffer_offset apply_calibration
apply_parsed_calibration get_default_calibration_path
}.each do |name|
wrap_instance_method(SWIG::TYPE_p_comedi_t, name)
end
[
# SWIG::TYPE_p_comedi_t methods that return -1 on error.
# Comedi_sv_t instance methods
Method_group.new(SWIG::TYPE_p_comedi_t, -1, %w{
close
fileno
get_subdevice_type
find_subdevice_by_type
get_read_subdevice
get_write_device
get_subdevice_flags
get_n_channels
range_is_chan_specific
maxdata_is_chan_specific
get_n_ranges
find_range
get_buffer_size
get_max_buffer_size
set_buffer_size
trigger
do_insnlist
do_insn
lock
unlock
data_read
data_read_delayed
data_write
dio_config
dio_read
dio_write
dio_bitfield
get_cmd_src_mask
get_cmd_generic_timed
cancel
command
command_test
poll
set_max_buffer_size
get_buffer_contents
mark_buffer_read
get_buffer_offset
}),
%w{ sv_init sv_update sv_measure
}.each do |name|
wrap_instance_method(Comedi_sv_t, name)
end
# SWIG::TYPE_p_comedi_t methods that return 0 on error.
# Comedi_calibration_t instance methods
Method_group.new(SWIG::TYPE_p_comedi_t, 0, %w{
get_maxdata
}),
%w{ cleanup_calibration_file
}.each do |name|
wrap_instance_method(Comedi_calibration_t, name)
# SWIG::TYPE_p_comedi_t methods that return <0 on error.
Method_group.new(SWIG::TYPE_p_comedi_t, :neg, %w{
apply_calibration
apply_parsed_calibration
}),
# SWIG::TYPE_p_comedi_t methods that return nil on error.
Method_group.new(SWIG::TYPE_p_comedi_t, nil, %w{
get_driver_name
get_board_name
get_range
get_default_calibration_path
}),
# SWIG::TYPE_p_comedi_t methods that do not indicate errors.
Method_group.new(SWIG::TYPE_p_comedi_t, :none, %w{
get_n_subdevices
get_version_code
data_read_hint
}),
# Comedi_sv_t methods that return -1 on errors.
Method_group.new(Comedi_sv_t, -1, %w{
sv_init
sv_update
sv_measure
}),
# Comedi_calibration_t methods that do not indicate errors.
Method_group.new(Comedi_calibration_t, :none, %w{
cleanup_calibration_file
})
].each do |d|
d.names.each do |n|
wrap_instance_method(d.class, n, d.err)
end
end
end