comedilib/swig/ruby/lib/comedi.rb

331 lines
7.8 KiB
Ruby
Raw Permalink Normal View History

######################################################################
#
# $Source$
#
# $Revision$
# $Date$
#
# $Author$
#
# Copyright (C) 2003,2004 James Steven Jenkins
#
######################################################################
# This file is syntactic sugar for accessing the Ruby comedilib
# extension library generated by SWIG. The syntactic sugar is in
# several forms:
#
# (1) Method names without the 'comedi_' prefix. The Comedi module
# disambiguates the namespace.
#
# (2) Instance methods that take an explicit receiver instead of
# passing the target object as an initial pointer. For example:
# comedi_close(dev) can be written as dev.close.
#
# (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. If the comedi function returns both a status and a
# value (e.g., comedi_data_read), the status is not returned by the
# ruby method unless it carries information in addition to indication
# of failure (e.g., comedi_command_test).
#
# (5) Ruby booleans. Comedi functions that return C integer boolean values
# (comedi_range_is_chan_specific, comedi_maxdata_is_chan_specific) have
# corresponding boolean ruby methods with '?' appended to the method name.
require 'comedi.so'
include Comedi
# SWIG::TYPE_p_comedi_t_struct is returned by Comedi::open
class SWIG::TYPE_p_comedi_t_struct
# create an IO object to access the comedi_t_struct fileno
def 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_method is the basis for wrap_module_method and
# wrap_instance_method.
def wrap_method(mod, name, err, multi, arglist)
cname = name
ret = 'value'
status = 'value'
value = 'value'
# If name ends in '?', make ruby wrapper a boolean.
if bool = (name =~ /\?$/)
value = 'ret == 1'
cname = name.sub(/\?$/, '')
elsif multi == :simple
ret = 'status, value'
status = 'status'
value = 'value'
elsif multi == :compound
ret = 'status, value'
status = 'status'
value = 'status, value'
end
wrap_def = %Q{# Module: #{mod}\n\n}
wrap_def << %Q{def #{name}(*args)\n}
wrap_def << %Q{ #{ret} = comedi_#{cname}(#{arglist})\n}
# Raise exceptions if required.
unless err == :none
wrap_def << %Q{ raise ComediError.new if }
case err
when :neg
wrap_def << %Q{#{status} < 0\n}
when nil
wrap_def << %Q{#{status}.nil?\n}
else
wrap_def << %Q{#{status} == #{err}\n}
end
end
# Return value.
wrap_def << %Q{ return #{value}\n}
wrap_def << %Q{end\n\n}
# Execute definition.
puts wrap_def if __FILE__ == 'comedi.rb'
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, multi)
wrap_method(mod, name, err, multi, '*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. The wrapped method raises ComediError
# if the return value equals a specified value.
def wrap_instance_method(mod, name, err, multi)
wrap_method(mod, name, err, multi, 'self, *args')
end
# This struct holds information for methods with return class,
# error, and multi-return indication.
Method_group = Struct.new(:class, :err, :multi, :names)
# Define method groups.
module_methods = [
# Comedi module methods that return nil on error.
Method_group.new(Comedi, nil, nil, %w{
open
parse_calibration_file
}),
# Comedi module methods that do not indicate errors.
Method_group.new(Comedi, :none, nil, %w{
loglevel
perror
strerrno
errno
to_phys
from_phys
set_global_oor_behavior
to_physical
from_physical
}),
]
instance_methods = [
# SWIG::TYPE_p_comedi_t_struct methods that return -1 on error.
Method_group.new(SWIG::TYPE_p_comedi_t_struct, -1, nil, %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_hint
data_write
dio_get_config
dio_config
dio_write
cancel
command
poll
set_max_buffer_size
get_buffer_contents
mark_buffer_read
mark_buffer_written
get_buffer_offset
get_buffer_read_offset
get_buffer_write_offset
get_softcal_converter
get_hardcal_converter
internal_trigger
arm
arm_channel
disarm
disarm_channel
reset
reset_channel
set_counter_mode
set_clock_source
set_filter
set_gate_source
set_other_source
set_routing
get_hardware_buffer_size
digital_trigger_disable
digital_trigger_enable_edges
digital_trigger_enable_levels
set_read_subdevice
set_write_subdevice
}),
# SWIG::TYPE_p_comedi_t_struct methods that return status and a
# value. Status is -1 on error. Status is discarded.
Method_group.new(SWIG::TYPE_p_comedi_t_struct, -1, :simple, %w{
data_read
data_read_delayed
dio_read
dio_bitfield
dio_bitfield2
get_cmd_src_mask
get_cmd_generic_timed
get_gate_source
get_routing
get_buffer_read_count
get_buffer_write_count
}),
# TODO: add get_clock_source, but it returns status and two values.
# SWIG::TYPE_p_comedi_t_struct methods that return status and a
# value. Status is -1 on error. Status and value are both
# returned.
Method_group.new(SWIG::TYPE_p_comedi_t_struct, -1, :compound, %w{
command_test
}),
# SWIG::TYPE_p_comedi_t_struct methods that return 0 on error.
Method_group.new(SWIG::TYPE_p_comedi_t_struct, 0, nil, %w{
get_maxdata
}),
# SWIG::TYPE_p_comedi_t_struct methods that return <0 on error.
Method_group.new(SWIG::TYPE_p_comedi_t_struct, :neg, nil, %w{
apply_calibration
apply_parsed_calibration
}),
# SWIG::TYPE_p_comedi_t_struct methods that return nil on error.
Method_group.new(SWIG::TYPE_p_comedi_t_struct, nil, nil, %w{
get_driver_name
get_board_name
get_range
get_default_calibration_path
}),
# SWIG::TYPE_p_comedi_t_struct methods that do not indicate errors.
Method_group.new(SWIG::TYPE_p_comedi_t_struct, :none, nil, %w{
get_n_subdevices
get_version_code
}),
# Comedi_sv_t methods that return -1 on error.
Method_group.new(Comedi_sv_t, -1, nil, %w{
sv_init
sv_update
}),
# Comedi_sv_t methods that return status and a value. Status
# is -1 on error.
Method_group.new(Comedi_sv_t, -1, :simple, %w{
sv_measure
}),
# Comedi_calibration_t methods that do not indicate errors.
Method_group.new(Comedi_calibration_t, :none, nil, %w{
cleanup_calibration
})
]
# Wrap Comedi module methods.
module_methods.each do |d|
d.names.each do |n|
wrap_module_method(d.class, n, d.err, d.multi)
end
end
# Wrap instance methods.
instance_methods.each do |d|
d.names.each do |n|
wrap_instance_method(d.class, n, d.err, d.multi)
end
end
end