summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy@asynk.ch>2011-04-25 13:44:20 +0200
committerJérémy Zurcher <jeremy@asynk.ch>2011-04-25 13:44:20 +0200
commit63a9b8fc30b5ef929f350d2bf23ebbda66150bce (patch)
tree918589a53b117953c31a4443e3d288d494c02d07
parent0ed47e17e804d0f76835d011b536bc44e914b737 (diff)
downloadffi-efl-63a9b8fc30b5ef929f350d2bf23ebbda66150bce.zip
ffi-efl-63a9b8fc30b5ef929f350d2bf23ebbda66150bce.tar.gz
ecore_getopt + specs almost ready
-rw-r--r--lib/efl.rb13
-rw-r--r--lib/efl/ecore_getopt.rb264
-rw-r--r--lib/efl/ffi.rb13
-rw-r--r--spec/ecore_getopt_spec.rb151
4 files changed, 433 insertions, 8 deletions
diff --git a/lib/efl.rb b/lib/efl.rb
index cd5a05e..d93e5d7 100644
--- a/lib/efl.rb
+++ b/lib/efl.rb
@@ -3,12 +3,15 @@
#
#
module Efl
+ #
VERSION = '0.0.1'
- autoload :Eet, './lib/efl/eet.rb'
- autoload :Evas, './lib/efl/evas.rb'
- autoload :Ecore, './lib/efl/ecore.rb'
- autoload :Edje, './lib/efl/edje.rb'
- autoload :Elm, './lib/efl/elementary.rb'
+ #
+ autoload :Eet, './lib/efl/eet.rb'
+ autoload :Evas, './lib/efl/evas.rb'
+ autoload :Ecore, './lib/efl/ecore.rb'
+ autoload :EcoreGetopt, './lib/efl/ecore_getopt.rb'
+ autoload :Edje, './lib/efl/edje.rb'
+ autoload :Elm, './lib/efl/elementary.rb'
end
#
# EOF
diff --git a/lib/efl/ecore_getopt.rb b/lib/efl/ecore_getopt.rb
new file mode 100644
index 0000000..38c1f8c
--- /dev/null
+++ b/lib/efl/ecore_getopt.rb
@@ -0,0 +1,264 @@
+#! /usr/bin/env ruby
+# -*- coding: UTF-8 -*-
+#
+require 'efl/ecore/ecore_getopt-ffi'
+#
+module Efl
+ module API
+ #
+ class EcoreGetoptValue < FFI::Union
+ layout :strp, :pointer,
+ :boolp, :eina_bool_p,
+ :shortp, :short_p,
+ :intp, :int_p,
+ :longp, :long_p,
+ :ushortp, :ushort_p,
+ :uintp, :uint_p,
+ :ulongp, :ulong_p,
+ :doublep, :double_p,
+ :listp, :eina_list_p,
+ :ptrp, :void_p,
+ end
+ #
+ class EcoreGetoptDescStoreDef < FFI::Union
+ layout :strv, :pointer,
+ :boolv, :uchar,
+ :shortv, :short,
+ :intv, :int,
+ :longv, :long,
+ :ushortv, :ushort,
+ :uintv, :uint,
+ :ulongv, :ulong,
+ :doublev, :double,
+ end
+ #
+ class EcoreGetoptDescStore < FFI::Struct
+ layout :type, :ecore_getopt_type, # enum
+ :arg_req, :ecore_getopt_desc_arg_requirement, # enum
+ :def, EcoreGetoptDescStoreDef,
+ end
+ #
+ callback :ecore_getopt_desc_cb, [:ecore_getopt_p, :ecore_getopt_desc_p, :string, :pointer, :ecore_getopt_value_p ], :eina_bool
+ #
+ class EcoreGetoptDescCallback < FFI::Struct
+ layout :func, :ecore_getopt_desc_cb,
+ :data, :pointer,
+ :arg_req, :ecore_getopt_desc_arg_requirement, # enum
+ :def, :pointer,
+ end
+ #
+ class EcoreActionParam < FFI::Union
+ layout :store, EcoreGetoptDescStore,
+ :store_const, :pointer,
+ :choices, :pointer,
+ :append_type, :ecore_getopt_type, # enum
+ :callback, EcoreGetoptDescCallback,
+ :dummy, :pointer,
+ end
+ #
+ class EcoreGetoptDesc < FFI::Struct
+ layout :shortname, :char,
+ :longname, :pointer,
+ :help, :pointer,
+ :metavar, :pointer,
+ :action, :ecore_getopt_action, # enum
+ :action_param, EcoreActionParam,
+ end
+ #
+ class EcoreGetopt < FFI::Struct
+ layout :prog, :pointer,
+ :usage, :pointer,
+ :version, :pointer,
+ :copyright, :pointer,
+ :license, :pointer,
+ :description, :pointer,
+ :strict, :char
+# :descs, :pointer, # NULL terminated EcoreGetopt_Desc[]
+
+ def desc_ptr idx
+ EcoreGetoptDesc.new to_ptr+Efl::API::EcoreGetopt.size+(idx*Efl::API::EcoreGetoptDesc.size)
+ end
+ end
+ #
+ end
+ #
+ module EcoreGetopt
+ class Parser
+ def initialize desc
+ @desc = desc
+ @options = [
+ [ 0, FFI::Pointer::NULL, FFI::Pointer::NULL, FFI::Pointer::NULL, 0, {:dummy=>FFI::Pointer::NULL} ]
+ ]
+ @values = [
+ [ :ptrp, FFI::Pointer::NULL ]
+ ]
+ end
+ def << o
+ @options.insert -2, o
+ end
+ def value type, ptr
+ @values.insert -2, [ type, ptr ]
+ end
+ def create
+ @parser_p = Efl::API::EcoreGetopt.new FFI::MemoryPointer.new (Efl::API::EcoreGetopt.size+Efl::API::EcoreGetoptDesc.size*@options.length), 1
+ [:prog,:usage,:version,:copyright,:license,:description].each do |sym|
+ @parser_p[sym] = ( @desc.has_key?(sym) ? FFI::MemoryPointer.from_string(@desc[sym]) : FFI::Pointer::NULL )
+ end
+ @parser_p[:strict] = @desc[:strict] if @desc.has_key? :strict
+ @options.each_with_index do |o,i|
+ d = @parser_p.desc_ptr i
+ d[:shortname] = o[0].ord
+ d[:longname] = (o[1]==FFI::Pointer::NULL ? FFI::Pointer::NULL : FFI::MemoryPointer.from_string(o[1]))
+ d[:help] = (o[2]==FFI::Pointer::NULL ? FFI::Pointer::NULL : FFI::MemoryPointer.from_string(o[2]))
+ d[:metavar] = o[3]
+ d[:action] = o[4]
+ k, v = o[5]
+ case k
+ when :dummy
+ d[:action_param][:dummy] = v
+ when :callback
+ cb = d[:action_param][:callback]
+ cb[:func] = v[0]
+ cb[:data] = v[1]
+ cb[:arg_req] = v[2]
+ cb[:def] = v[3]
+ when :store
+ st = d[:action_param][:store]
+ st[:type] = v[0]
+ st[:arg_req] = v[1]
+ if not v[2].nil?
+ if v[2][0]==:strv
+ st[:def][:strv] = FFI::MemoryPointer.from_string v[2][1]
+ else
+ st[:def][v[2][0]] = v[2][1]
+ end
+ end
+ when :store_const
+ d[:action_param][:store_const] = v
+ when :choices
+ d[:action_param][:choices] = v
+ when :append
+ d[:action_param][:append_type] = v
+ else
+ d[:action_param][:dummy] = FFI::Pointer::NULL
+ end
+ end
+ @values_p = FFI::MemoryPointer.new Efl::API::EcoreGetoptValue, @values.length, false
+ @values.each_with_index do |v,i|
+ Efl::API::EcoreGetoptValue.new(@values_p+(i*Efl::API::EcoreGetoptValue.size))[v[0]] = v[1]
+ end
+ end
+ def parse argv
+ ptr = FFI::MemoryPointer.new(:pointer, argv.length+1)
+ argv.each_with_index do |s, i|
+ ptr[i].put_pointer 0, FFI::MemoryPointer.from_string(s)
+ end
+ ptr[argv.length].put_pointer 0, FFI::Pointer::NULL
+ Efl::EcoreGetopt.parse @parser_p, @values_p, argv.length, ptr
+ end
+ def store_full short, long, help, meta, type, arg_req, def_val
+ self << [ short, long, help, meta, :ecore_getopt_action_store, [:store, [type,arg_req, def_val] ] ]
+ end
+ def store short, long, help, type
+ store_full short, long, help, FFI::Pointer::NULL, type, :ecore_getopt_desc_arg_requirement_yes, nil
+ end
+ def store_type type, short, long, help
+ store short, long, help, ('ecore_getopt_type_'+type.to_s).to_sym
+ end
+ def store_metavar short, long, help, meta, type
+ store_full short, long, help, meta, type, :ecore_getopt_desc_arg_requirement_yes, nil
+ end
+ def store_meta_type type, short, long, help, meta
+ store_metavar short, long, help, meta, ('ecore_getopt_type_'+type.to_s).to_sym
+ end
+ def store_def short, long, help, type, def_val
+ store_full short, long, help, FFI::Pointer::NULL, type, :ecore_getopt_desc_arg_requirement_optional, def_val
+ end
+ def store_def_type type, short, long, help, def_val
+ store_def short, long, help, ('ecore_getopt_type_'+type.to_s).to_sym, [ (type.to_s+'v').to_sym, def_val ]
+ end
+ def store_full_type type, short, long, help, meta, arg_req, def_val
+ store_full short, long, help, meta, ('ecore_getopt_type_'+type.to_s).to_sym, arg_req, [ (type.to_s+'v').to_sym, def_val ]
+ end
+ def store_const short, long, help, value
+ self << [ short, long, help, FFI::Pointer::NULL, :ecore_getopt_action_store_const, [:store_const, value] ]
+ end
+ def store_true short, long, help
+ self << [ short, long, help, FFI::Pointer::NULL, :ecore_getopt_action_store_true, [:dummy,FFI::MemoryPointer::NULL] ]
+ end
+ def store_false short, long, help
+ self << [ short, long, help, FFI::Pointer::NULL, :ecore_getopt_action_store_false, [:dummy,FFI::MemoryPointer::NULL] ]
+ end
+ def choice short, long, help, choices
+ ptr = FFI::MemoryPointer.new(:pointer, choices.length+1)
+ choices.each_with_index do |s, i|
+ ptr[i].put_pointer 0, FFI::MemoryPointer.from_string(s)
+ end
+ ptr[choices.length].put_pointer 0, FFI::Pointer::NULL
+ self << [ short, long, help, FFI::Pointer::NULL, :ecore_getopt_action_choice, [:choices,ptr] ]
+ end
+ def choice_metavar short, long, help, meta, choices
+ ptr = FFI::MemoryPointer.new(:pointer, choices.length+1)
+ choices.each_with_index do |s, i|
+ ptr[i].put_pointer 0, FFI::MemoryPointer.from_string(s)
+ end
+ ptr[choices.length].put_pointer 0, FFI::Pointer::NULL
+ self << [ short, long, help, meta, :ecore_getopt_action_choice, [:choices,ptr] ]
+ end
+ def append short, long, help, sub_type
+ self << [ short, long, help, FFI::Pointer::NULL, :ecore_getopt_action_append, [:append,sub_type] ]
+ end
+ def append_metavar short, long, help, meta, sub_type
+ self << [ short, long, help, meta, :ecore_getopt_action_append, [:append,sub_type] ]
+ end
+ def count short, long, help
+ self << [ short, long, help, FFI::Pointer::NULL, :ecore_getopt_action_count, [:dummy,FFI::Pointer::NULL] ]
+ end
+ def callback_full short, long, help, meta, cb, data, arg_req, def_val
+ self << [ short, long, help, meta, :ecore_getopt_action_callback, [:callback, [cb, data, arg_req,def_val] ] ]
+ end
+ def callback_noargs short, long, help, cb, data
+ callback_full short, long, help, FFI::Pointer::NULL, cb, data, :ecore_getopt_desc_arg_requirement_no, FFI::Pointer::NULL
+ end
+ def callback_args short, long, help, meta, cb, data
+ callback_full short, long, help, meta, cb, data, :ecore_getopt_desc_arg_requirement_yes, FFI::Pointer::NULL
+ end
+ def help short, long
+ self << [ short, long, 'show this message.', FFI::Pointer::NULL, :ecore_getopt_action_help, [:dummy,FFI::Pointer::NULL] ]
+ end
+ def version short, long
+ self << [ short, long, 'show program version.', FFI::Pointer::NULL, :ecore_getopt_action_version, [:dummy,FFI::Pointer::NULL] ]
+ end
+ def copyright short, long
+ self << [ short, long, 'show copyright.', FFI::Pointer::NULL, :ecore_getopt_action_copyright, [:dummy,FFI::Pointer::NULL] ]
+ end
+ def license short, long
+ self << [ short, long, 'show license.', FFI::Pointer::NULL, :ecore_getopt_action_license, [:dummy,FFI::Pointer::NULL] ]
+ end
+# def sentinel
+# self << [ 0, FFI::Pointer::NULL, FFI::Pointer::NULL, FFI::Pointer::NULL, 0, {:dummy=>FFI::Pointer::NULL} ]
+# end
+ #
+ def debug
+ puts "#{self.class} : #{@parser_p.to_ptr}"
+ [:prog,:usage,:version,:copyright,:license,:description].each do |sym|
+ puts " #{sym.to_s} : #{@parser_p[sym]==FFI::Pointer::NULL ? 'NULL' : @parser_p[sym].read_string}"
+ end
+ puts " strict : #{@parser_p[:strict]}"
+ i=0
+ while true
+ d = @parser_p.desc_ptr i
+ break if d[:shortname]==0 and d[:longname] == FFI::Pointer::NULL
+ puts " desc #{d.to_ptr}"
+ puts " short: #{d[:shortname].chr}" unless d[:shortname]==0
+ puts " long: #{d[:longname].read_string}" unless d[:longname]==FFI::Pointer::NULL
+ puts " help: #{d[:help].read_string}" unless d[:help]==FFI::Pointer::NULL
+ i+=1
+ end
+ end
+ end
+ end
+ #
+end
+#
+# EOF
diff --git a/lib/efl/ffi.rb b/lib/efl/ffi.rb
index bcd6777..eaa45e7 100644
--- a/lib/efl/ffi.rb
+++ b/lib/efl/ffi.rb
@@ -20,12 +20,19 @@ module Efl
end
module_function :attach_fcts
#
+ typedef :pointer, :char_p
+ typedef :pointer, :short_p
typedef :pointer, :int_p
- typedef :pointer, :uint_p
- typedef :pointer, :void_p
- typedef :pointer, :uchar_p
+ typedef :pointer, :long_p
typedef :pointer, :float_p
typedef :pointer, :double_p
+ typedef :pointer, :uchar_p
+ typedef :pointer, :ushort_p
+ typedef :pointer, :uint_p
+ typedef :pointer, :ulong_p
+ typedef :pointer, :ufloat_p
+ typedef :pointer, :udouble_p
+ typedef :pointer, :void_p
typedef :pointer, :string_array
typedef :pointer, :string_array_p
#
diff --git a/spec/ecore_getopt_spec.rb b/spec/ecore_getopt_spec.rb
new file mode 100644
index 0000000..b900b23
--- /dev/null
+++ b/spec/ecore_getopt_spec.rb
@@ -0,0 +1,151 @@
+#! /usr/bin/env ruby
+# -*- coding: UTF-8 -*-
+#
+require 'stringio'
+require 'efl/ecore'
+require 'efl/ecore_getopt'
+#
+describe Efl::EcoreGetopt do
+ #
+ before(:each) do
+ Efl::Ecore.init
+ #
+ @p = Efl::EcoreGetopt::Parser.new :prog =>"Prog", :usage => "Usage", :version => "0.0.0", :copyright => "less", :license => "MIT", :description => "description", :strict => 1
+ def @p.cb parser, desc, string, data, value
+ puts parser, desc, string, data, value
+ true
+ end
+ #
+ @values = {
+ :license => FFI::MemoryPointer.new(:uchar),
+ :copyright => FFI::MemoryPointer.new(:uchar),
+ :version => FFI::MemoryPointer.new(:uchar),
+ :help => FFI::MemoryPointer.new(:uchar),
+ }
+ [ :license, :copyright, :version, :help ].each do |sym|
+ @values[sym].write_char 0
+ end
+ #
+ @p.license 'L', 'license'
+ @p.value :boolp, @values[:license]
+ @p.copyright 'C', 'copyright'
+ @p.value :boolp, @values[:copyright]
+ @p.version 'V', 'version'
+ @p.value :boolp, @values[:version]
+ @p.help 'H', 'help'
+ @p.value :boolp, @values[:help]
+# @p.store_type :int, 'i', 'int', 'store an integer'
+# @p.store_meta_type :double, 'd', 'double', 'store an double+meta', meta
+# @p.store_def_type :str, 's', 'str', 'store an string+default', "hello world"
+# @p.store_full_type :short, 's', 'short', 'store a short+full', 'meta', :ecore_getopt_desc_arg_requirement_yes, 666
+# @p.store_const 'c', 'const', 'store a constant', FFI::MemoryPointer.from_string("my constant")
+# @p.store_true 't', 'true', 'store true'
+# @p.store_false 'f', 'false', 'store false'
+# @p.choice 'm', 'many', 'store choice', ['ch1','ch2','ch3']
+# @p.append 'a', 'append', 'store append'
+# @p.count 'k', 'count', 'store count'
+# @p.callback_args 'b', 'callback', 'callback full', meta, p.method(:cb), 666
+ @p.create
+# @p.debug
+ #
+ end
+ #
+ describe "license copyright version help" do
+ it "should handle -L" do
+ #
+ [ :license, :copyright, :version, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ args = @p.parse ["My lovely prog name","-L"]
+ @values[:license].read_char.should eql 1
+ [ :copyright, :version, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ Efl::Ecore.shutdown
+ end
+ it "should handle --license" do
+ #
+ [ :license, :copyright, :version, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ args = @p.parse ["My lovely prog name","--license"]
+ @values[:license].read_char.should eql 1
+ [ :copyright, :version, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ Efl::Ecore.shutdown
+ end
+ it "should handle -C" do
+ #
+ [ :license, :copyright, :version, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ args = @p.parse ["progname","-C"]
+ @values[:copyright].read_char.should eql 1
+ [ :license, :version, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ Efl::Ecore.shutdown
+ end
+ it "should handle --copyright" do
+ #
+ [ :license, :copyright, :version, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ args = @p.parse ["My lovely prog name","--copyright"]
+ @values[:copyright].read_char.should eql 1
+ [ :license, :version, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ Efl::Ecore.shutdown
+ end
+ it "should handle -V" do
+ #
+ [ :license, :copyright, :version, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ args = @p.parse ["My lovely prog name","-V"]
+ @values[:version].read_char.should eql 1
+ [ :license, :copyright, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ Efl::Ecore.shutdown
+ end
+ it "should handle --version" do
+ #
+ [ :license, :copyright, :version, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ args = @p.parse ["progname","--version"]
+ @values[:version].read_char.should eql 1
+ [ :license, :copyright, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ Efl::Ecore.shutdown
+ end
+ it "should handle -H" do
+ #
+ [ :license, :copyright, :version, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ args = @p.parse ["My lovely prog name","-H"]
+ @values[:help].read_char.should eql 1
+ [ :license, :copyright, :version ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ Efl::Ecore.shutdown
+ end
+ it "should handle --help" do
+ #
+ [ :license, :copyright, :version, :help ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ args = @p.parse ["progname","--help"]
+ @values[:help].read_char.should eql 1
+ [ :license, :copyright, :version ].each do |sym|
+ @values[sym].read_char.should eql 0
+ end
+ Efl::Ecore.shutdown
+ end
+ end
+end