Allows for a different mporting origin/HEAD origin/master
authorDuncan Mac-Vicar P <dmacvicar@suse.de>
Fri, 23 Nov 2007 10:00:12 +0000 (11:00 +0100)
committerDuncan Mac-Vicar P <dmacvicar@suse.de>
Fri, 23 Nov 2007 10:00:12 +0000 (11:00 +0100)
Instead of

require 'yast'
m = YaST::Module.new("Foo")
m.hello

We do

require 'ycp'
require 'ycp/foo'
YCP::Foo::hello

Much nicer and the symbols are declared so
you can even ask the module for its methods

Minor other improvements.
Calling is broken for now

12 files changed:
examples/ruby/module-storage-2.rb [new file with mode: 0644]
examples/ruby/ruby_from_ycp.ycp
examples/ruby/ycp-1.rb [new file with mode: 0644]
src/CMakeLists.txt
src/ruby/YCP.cc
src/ruby/YCP.rb [deleted file]
src/ruby/YaPI.pm.in [deleted file]
src/ruby/yast.rb
src/swig/CMakeLists.txt
src/swig/yast.i
src/swig/ycp.i [new file with mode: 0644]
src/swig/ycp.rb [new file with mode: 0644]

diff --git a/examples/ruby/module-storage-2.rb b/examples/ruby/module-storage-2.rb
new file mode 100644 (file)
index 0000000..ea89a9f
--- /dev/null
@@ -0,0 +1,10 @@
+require 'yast'
+require 'ycp/storage'
+
+
+puts YCP::Storage.methods
+
+dp = YCP::Storage::GetDiskPartition("/dev/sda1")
+dp.each do | key, value |
+  puts "#{key} #{value}"
+end
\ No newline at end of file
index b61bd3c..fb1cf52 100644 (file)
@@ -1,6 +1,6 @@
 
 {
-    import "Duncan";
+    import "Foo";
     string result = (string) multiply_by_eight(10);
     UI::OpenDialog(
          `VBox(
diff --git a/examples/ruby/ycp-1.rb b/examples/ruby/ycp-1.rb
new file mode 100644 (file)
index 0000000..9ff723f
--- /dev/null
@@ -0,0 +1,9 @@
+require 'ycp'
+include Ycpx
+
+f = File.new('/usr/share/YaST2/modules/Arch.ycp')
+p = Parser.new( f.fileno, 'Arch')
+puts p.class
+y = p.parse
+puts y.methods
+y.is_block
index 2a3b5fa..279b801 100644 (file)
@@ -1,2 +1,2 @@
-#ADD_SUBDIRECTORY(swig)
+ADD_SUBDIRECTORY(swig)
 ADD_SUBDIRECTORY(ruby)
\ No newline at end of file
index a2188df..3ffb58b 100644 (file)
@@ -56,8 +56,13 @@ as published by the Free Software Foundation; either version
 #include "Y2RubyTypeConv.h"
 #include "YRuby.h"
 
+#define GetY2Object(obj, po) \
+    Data_Get_Struct(obj, Y2Namespace, po)
+
 static VALUE rb_mYaST;
+static VALUE rb_mY2ModuleProxy;
 static VALUE rb_mUi;
+static VALUE rb_mYCP;
 static VALUE rb_cBroker;
 
 // make the compiler happy when
@@ -77,13 +82,13 @@ Y2Component *owned_wfmc = 0;
 
 static
 Y2Namespace *
-getNs (const char * ns_name, const char * func_name)
+getNs (const char * ns_name)
 {
   Import import(ns_name);  // has a static cache
   Y2Namespace *ns = import.nameSpace();
   if (ns == NULL)
   {
-    y2error ("... for a Ruby call of %s", func_name);
+    y2error ("Ruby call: Can't import namespace '%s'", ns_name);
   }
   else
   {
@@ -207,11 +212,90 @@ yast_module_methods( VALUE self )
 //forward declaration
 YCPValue ycp_call_builtin ( const string &module_name, const string &func_name, int argc, VALUE *argv );
 
+/**
+ * looks a component for a namespace
+ * throws
+ */
+static VALUE
+ycp_module_lookup_namespace_component(VALUE self, VALUE name)
+{
+  Y2Component *c;
+  c = Y2ComponentBroker::getNamespaceComponent(RSTRING(name)->ptr);
+  if (c == NULL)
+  {
+    y2internal("No component can provide namespace %s\n", RSTRING (name)->ptr);
+    rb_raise( rb_eRuntimeError, "No YaST component can provide namespace %s\n", RSTRING (name)->ptr);
+  }
+  y2internal("component name %s\n", c->name().c_str());
+  return Qtrue;
+}
+
+/*
+ tries to import a namespace and throws a NameError if
+ failed
+*/
+static VALUE
+ycp_module_import_namespace( VALUE self, VALUE namespace_name)
+{
+  Y2Namespace *ns = getNs( RSTRING (namespace_name)->ptr);
+  if (ns == NULL)
+  {
+    rb_raise( rb_eNameError, "Component cannot import namespace '%s'", RSTRING (namespace_name)->ptr);
+    return Qnil;
+  }
+  else
+  {
+    y2internal("Namespace created from %s\n", ns->filename().c_str());
+  }
+  return Qtrue;
+}
+
+static VALUE
+ycp_module_import( VALUE self, VALUE name)
+{
+  ycp_module_lookup_namespace_component(self,name);
+  ycp_module_import_namespace(self,name);
+}
+
+/**
+ * iterates all symbols in a namespace and yields the
+ * symbol name and category
+ */
+VALUE
+ycp_module_each_symbol(VALUE self, VALUE namespace_name)
+{
+  Y2Namespace *ns = getNs( RSTRING (namespace_name)->ptr);
+  if (ns == NULL)
+  {
+    rb_raise( rb_eRuntimeError, "Error getting namespace '%s'", RSTRING (namespace_name)->ptr );
+    return Qnil;
+  }
+  else
+  {
+    y2internal("Got namespace from %s\n", ns->filename().c_str());
+  }
+
+  for (int i=0; i < ns->symbolCount(); ++i)
+  {
+    SymbolEntryPtr s = ns->symbolEntry(i);
+    VALUE arr = rb_ary_new();
+    rb_ary_push(arr, rb_str_new2(s->name()));
+    rb_ary_push(arr, ID2SYM(rb_intern(s->catString().c_str())));
+    rb_yield(arr);
+  }
+  return Qnil;
+}
+
+/**
+ * Forwards a ruby call to the namespace
+ * First argument is the namespace
+ * then function name and arguments
+ */
 VALUE
-yast_module_proxy_method( int argc, VALUE *argv, VALUE self )
+ycp_module_forward_call(int argc, VALUE *argv, VALUE self)
 {
-  VALUE symbol = argv[0];
-  VALUE namespace_name = rb_iv_get(self, "@namespace_name");
+  VALUE symbol = argv[1];
+  VALUE namespace_name = argv[0];
 
   // the func name (1st argument, is a symbol
   // lets convert it to string
@@ -238,30 +322,21 @@ yast_module_proxy_method( int argc, VALUE *argv, VALUE self )
     //return Qnil;
   }
 
-  Y2Component *c;
-  c = Y2ComponentBroker::getNamespaceComponent(RSTRING (namespace_name)->ptr);
-  if (c == NULL)
-  {
-    y2internal("No component can provide namespace %s\n", RSTRING (namespace_name)->ptr);
-    rb_raise( rb_eRuntimeError, "No component can provide namespace %s\n", RSTRING (namespace_name)->ptr);
-    return 2;
-  }
-  y2internal("component name %s\n", c->name().c_str());
+  ycp_module_lookup_namespace_component(self, namespace_name);
 
   // import the namespace
   //Y2Namespace *ns = c->import(RSTRING (namespace_name)->ptr);
-  Y2Namespace *ns = getNs( RSTRING (namespace_name)->ptr, RSTRING(symbol_str)->ptr);
+  Y2Namespace *ns = getNs( RSTRING (namespace_name)->ptr);
   if (ns == NULL)
   {
-    rb_raise( rb_eRuntimeError, "Component cannot import namespace %s", RSTRING (namespace_name)->ptr );
+    rb_raise( rb_eRuntimeError, "Component cannot import namespace '%s' for symbol '%s'", RSTRING (namespace_name)->ptr, RSTRING(symbol_str)->ptr );
     return Qnil;
   }
   else
   {
     y2internal("Namespace created from %s\n", ns->filename().c_str());
   }
-  // ensure it is an initialized namespace
-  //ns->initialize ();
+
   y2internal("Namespace %s initialized\n", RSTRING (namespace_name)->ptr);
 
   TableEntry *sym_te = ns->table()->find (RSTRING(symbol_str)->ptr);
@@ -276,6 +351,7 @@ yast_module_proxy_method( int argc, VALUE *argv, VALUE self )
   if (sym_te->sentry ()->isVariable () ||
       sym_te->sentry ()->isReference ())
   {
+    y2internal ("Variable or reference %s\n", RSTRING(symbol_str)->ptr);
     // set the variable
     //ret_yv = YCP_getset_variable (aTHX_ ns_name, sym_te->sentry (), args);
   }
@@ -286,15 +362,16 @@ yast_module_proxy_method( int argc, VALUE *argv, VALUE self )
     if (call == NULL)
     {
       y2internal ("Cannot create function call %s\n", RSTRING(symbol_str)->ptr);
-      return 4;
+      rb_raise( rb_eRuntimeError, "Can't create call to %s::%s", RSTRING (namespace_name)->ptr, RSTRING(symbol_str)->ptr);
     }
 
     // add the parameters
-    for (int i=1; i<argc; i++)
+    for (int i=2; i < argc; i++)
     {
       VALUE arg = argv[i];
+      y2internal ("Appending parameter #%d\n", i);
       YCPValue v = rbvalue_2_ycpvalue(arg);
-      //y2internal ("Appending parameter %s\n", v->toString());
+      y2internal ("Appending parameter #%s : %s\n", i, v->toString());
       call->appendParameter (v);
     }
     call->finishParameters ();
@@ -455,16 +532,25 @@ extern "C"
     }
 
     rb_mYaST = rb_define_module("YaST");
-    rb_mUi = rb_define_module_under(rb_mYaST, "Ui");
+
+    //rb_mYCP = rb_define_module_under(rb_mYaST, "YCP");
+    rb_mYCP = rb_define_module("YCP");
+    rb_define_singleton_method( rb_mYCP, "import", RB_METHOD(ycp_module_import), 1);
+    rb_define_singleton_method( rb_mYCP, "forward_call", RB_METHOD(ycp_module_forward_call), -1);
+    rb_define_singleton_method( rb_mYCP, "each_symbol", RB_METHOD(ycp_module_each_symbol), 1);
+    
+
+    rb_mUi = rb_define_module_under(rb_mYCP, "Ui");
     rb_define_singleton_method( rb_mUi, "init", RB_METHOD(rb_init_ui), -1);
     
+    
     rb_define_method( rb_mYaST, "y2_logger", RB_METHOD(rb_y2_logger), -1);
     
     rb_cBroker = rb_define_class_under( rb_mYaST, "Module", rb_cObject);
     //rb_define_singleton_method( rb_cBroker, "new", RB_METHOD(module_new), 1);
     rb_define_alloc_func(rb_cBroker, yast_module_allocate);
     rb_define_method(rb_cBroker, "initialize", RB_METHOD(yast_module_initialize), 1);
-    rb_define_method( rb_cBroker, "method_missing", RB_METHOD(yast_module_proxy_method), -1);
+    //rb_define_method( rb_cBroker, "method_missing", RB_METHOD(yast_module_proxy_method), -1);
     rb_define_method( rb_cBroker, "name", RB_METHOD(yast_module_name), -1);
 
     ryast_path_init(rb_mYaST);
diff --git a/src/ruby/YCP.rb b/src/ruby/YCP.rb
deleted file mode 100644 (file)
index fb820b5..0000000
+++ /dev/null
@@ -1,520 +0,0 @@
-#! /usr/bin/perl -w
-# Martin Vidner
-# $Id: YCP.pm 33405 2006-10-13 13:12:42Z mvidner $
-
-=head1 NAME
-
-YaST::YCP - a binary interface between Perl and YCP
-
-=head1 SYNOPSIS
-
- use YaST::YCP qw(:DATA :LOGGING);
-
- YaST::YCP::Import ("SCR");
- my $m = SCR->Read (".sysconfig.displaymanager.DISPLAYMANAGER");
- SCR->Write (".sysconfig.kernel.CRASH_OFTEN", Boolean (1));
-
-=head1 DATA TYPES
-
-YaST has a richer and stricter data type system than Perl.
-
-Note that the stdio-communicating agents, based on the modules
-L<YaST::SCRAgent|YaST::SCRAgent> and L<ycp|ycp>, have a similar but
-not the same data type mapping.
-
-When the language binding knows what type to expect, eg. when passing
-an argument to a YCP function, it will convert a Perl scalar to the
-desired type.
-
-On the other hand, if the type is not known, expressed
-in YCP as C<any>, scalars will be passed as strings. If you want
-a specific data type, use one of the data classes like
-L<YaST::YCP::Integer|/Integer>. Of course these work also when
-the type is known.
-
-=over 4
-
-=item void
-
-Has only one value, C<nil>, which is represented as C<undef>.
-Any data type can have C<nil> as a value.
-
-=item any
-
-A union of all data types. Any data type can be assigned to it.
-
-=item string, integer, float, boolean
-
-B<YCP to Perl:> Becomes a scalar
-
-B<Perl to YCP:> Any scalar will become a string
-(even if it looks like a number).
-Use L</String>, L</Integer>, L</Float> or L</Boolean>
-if you want a specific data type.
-
-=item list E<lt>TE<gt>
-
-B<YCP to Perl:> A list becomes a reference to an array.
-(Note that it refers to a B<copy>.)
-
-B<Perl to YCP:> A reference to an array becomes a list.
-I<This was different before SL9.1 Beta1:>
-Perl functions returning multiple values should not return a list
-but a reference to it. YCP will always set a scalar calling context,
-even if the result is assigned to a list.
-
-=item map E<lt>T1, T2E<gt>
-
-B<YCP to Perl:> A map becomes a reference to a hash.
-(Note that it refers to a B<copy>.)
-
-B<Perl to YCP:> A reference to a hash becomes a map.
-
-=item path
-
-B<YCP to Perl:> NOT IMPLEMENTED YET.
-
-B<Perl to YCP:> If a path is expected, a scalar like C<".foo.bar">
-will be converted to C<.foo.bar>.
-Otherwise use L</Path> (which is NOT IMPLEMENTED YET).
-
-=item symbol
-
-B<YCP to Perl:> Becomes a L</Symbol>.
-
-B<Perl to YCP:> If a symbol is expected, a scalar like C<"foo">
-will be converted to C<`foo>.
-Otherwise use L</Symbol>.
-
-=item term
-
-B<YCP to Perl:> Becomes a L</Term>.
-
-B<Perl to YCP:> Use L</Term>.
-
-=item byteblock
-
-B<YCP to Perl:> Becomes a scalar.
-
-B<Perl to YCP:> If a byteblock is expected, a scalar like C<"\0\1">
-will be converted to C<#[0001]>.
-Otherwise use L</Byteblock>.
-
-=item locale, block E<lt>TE<gt>, ...
-
-Not implemented.
-
-=back
-
-=head1 YaST::YCP
-
-The DATA tag (in C<use YaST::YCP qw(:DATA)>) imports the data
-constructor functions such as Boolean, Symbol or Term.
-
-=cut
-
-package YaST::YCP;
-use strict;
-use warnings;
-use diagnostics;
-
-require Exporter;
-our @ISA = qw(Exporter);
-my @e_data = qw(Boolean Byteblock Integer Float String Symbol Term);
-my @e_logging = qw(y2debug y2milestone y2warning y2error y2security y2internal);
-our @EXPORT_OK = (@e_data, @e_logging, "sformat");
-our %EXPORT_TAGS = ( DATA => [@e_data], LOGGING => [@e_logging] );
-
-=head2 debug
-
- $olddebug = YaST::YCP::debug (1);
- YaST::YCP::...
- YaST::YCP::debug ($olddebug);
-
-Enables miscellaneous unscpecified debugging
-
-=cut
-
-my $debug = 0;
-sub debug (;$)
-{
-    my $param = shift;
-    if (defined $param)
-    {
-       $debug = $param;
-    }
-    return $debug;
-}
-
-
-## calls boot_YaST__YCP
-require XSLoader;
-XSLoader::load ('YaST::YCP');
-
-=head2 init_ui
-
- YaST::YCP::init_ui ();
- YaST::YCP::init_ui "qt";
-
-Initializes the user interface, "ncurses" (the default) or "qt".
-
-=cut
-
-# ensure that the ncurses window is closed
-# and wfm and its agents are closed (#39519)
-END {
-    close_components (); # XS
-}
-
-=head2 Import
-
- YaST::YCP::Import "Namespace";
- Namespace->foo ("bar");
-
-Imports a YaST namespace (in YCP or Perl or any supported language).
-Equivalent to YCP C<import>, similar to Perl C<use>.
-
-If C<Namespace> is in YCP, its constructor is executed later than if
-it were imported from YCP. This can have subtle effects, for example
-in testsuites. To get closer to the YCP import behavior, call
-C<Import> from a C<BEGIN> block.
-
-=cut
-
-sub Import ($)
-{
-    my $package = shift;
-    print "Importing $package\n" if debug;
-
-    no strict;
-    # let it get our autoload
-    *{"${package}::AUTOLOAD"} = \&YaST::YCP::Autoload::AUTOLOAD;
-}
-
-=head2 logging
-
-These functions go via liby2util and thus use log.conf.
-See also ycp::y2milestone.
-
-The multiple arguments are simply joined by a space.
-
- y2debug ($message, $message2, ...)
- y2milestone ($message, $message2, ...)
- y2warning ($message, $message2, ...)
- y2error ($message, $message2, ...)
- y2security ($message, $message2, ...)
- y2internal ($message, $message2, ...)
-
-=cut
-
-sub y2_logger_helper ($@)
-{
-    my $level = shift;
-    # look _two_ frames up for the subroutine
-    # when called from the main script, it will be undef
-    my ($package, $filename, $line, $subroutine) = caller (2);
-    # look _one_ frame up for file and line
-    # (is it because of optimization?)
-    ($package, $filename, $line) = caller (1);
-    # this is a XS:
-    y2_logger ($level, "Perl", $filename, $line, $subroutine || "",
-              join (" ", @_));
-}
-
-sub y2debug (@)                { y2_logger_helper (0, @_); }
-sub y2milestone (@)    { y2_logger_helper (1, @_); }
-sub y2warning (@)      { y2_logger_helper (2, @_); }
-sub y2error (@)                { y2_logger_helper (3, @_); }
-sub y2security (@)     { y2_logger_helper (4, @_); }
-sub y2internal (@)     { y2_logger_helper (5, @_); }
-
-=head2 sformat
-
-Implements the sformat YCP builtin:
-
-C<sformat ('%2 %% %1', "a", "b")> returns C<'b % a'>
-
-It is useful mainly for messages marked for translation.
-
-=cut
-
-sub sformat ($@)
-{
-    # don't shift
-    # now the % indices can be used for @_
-    my $format = $_[0];
-
-    # g: global, replace all occurences
-    # e: expression, not a string
-    $format =~ s{%([1-9%])}{
-       ($1 eq '%') ? '%' : $_[$1]
-    }ge;
-
-    return $format;
-}
-
-# shortcuts for the data types
-# for POD see packages below
-
-sub Boolean ($)
-{
-    return new YaST::YCP::Boolean (@_);
-}
-
-sub Byteblock ($)
-{
-    return new YaST::YCP::Byteblock (@_);
-}
-
-sub Integer ($)
-{
-    return new YaST::YCP::Integer (@_);
-}
-
-sub Float ($)
-{
-    return new YaST::YCP::Float (@_);
-}
-
-sub String ($)
-{
-    return new YaST::YCP::String (@_);
-}
-
-sub Symbol ($)
-{
-    return new YaST::YCP::Symbol (@_);
-}
-
-sub Term ($@)
-{
-    return new YaST::YCP::Term (@_);
-}
-
-# by defining AUTOLOAD in a separate package, undefined functions in
-# the main one will be detected
-package YaST::YCP::Autoload;
-use strict;
-use warnings;
-use diagnostics;
-
-# cannot rely on UNIVERSAL::AUTOLOAD getting automatically called
-# http://www.rocketaware.com/perl/perldelta/Deprecated_Inherited_C_AUTOLOAD.htm
-
-# Gets called instead of all functions in Import'ed modules
-# It assumes a normal function, not a class or instance method
-sub AUTOLOAD
-{
-    our $AUTOLOAD;
-
-    # strip $self on the way from Perl to YCP,
-    # just as it is added in the reverse direction
-    my $himself = shift;
-    print "$himself $AUTOLOAD (", join (", ", @_), ")\n" if YaST::YCP::debug;
-
-    my @components = split ("::", $AUTOLOAD);
-    my $func = pop (@components);
-    return YaST::YCP::call_ycp (join ("::", @components), $func, @_);
-}
-
-=head2 Boolean
-
- $b = YaST::YCP::Boolean (1);
- $b->value (0);
- print $b->value, "\n";
- SCR::Write (".foo", $b);
-
-=cut
-
-package YaST::YCP::Boolean;
-use strict;
-use warnings;
-use diagnostics;
-
-# a Boolean is just a blessed reference to a scalar
-
-sub new
-{
-    my $class = shift;
-    my $val = shift;
-    return bless \$val, $class
-}
-
-# get/set
-sub value
-{
-    # see "Constructors and Instance Methods" in perltoot
-    my $self = shift;
-    if (@_) { $$self = shift; }
-    return $$self;
-}
-
-=head2 Byteblock
-
-A chunk of binary data.
-
- use YaST::YCP qw(:DATA);
-
- read ($dev_random_fh, $r, 100);
- $b = Byteblock ($r);
- $b->value ("Hello\0world\0");
- print $b->value, "\n";
- return $b;
-
-=cut
-
-package YaST::YCP::Byteblock;
-use strict;
-use warnings;
-use diagnostics;
-
-# a Byteblock is just a blessed reference to a scalar
-# just like Boolean, so use it!
-
-our @ISA = qw (YaST::YCP::Boolean);
-
-=head2 Integer
-
-An explicitly typed integer, useful to put in heterogenous data structures.
-
- use YaST::YCP qw(:DATA);
-
- $i = Integer ("42 and more");
- $i->value ("43, actually");
- print $i->value, "\n";
- return [ $i ];
-
-=cut
-
-package YaST::YCP::Integer;
-use strict;
-use warnings;
-use diagnostics;
-
-
-# an Integer is just a blessed reference to a scalar
-# just like Boolean, so use it!
-
-our @ISA = qw (YaST::YCP::Boolean);
-
-=head2 Float
-
-An explicitly typed float, useful to put in heterogenous data structures.
-
- use YaST::YCP qw(:DATA);
-
- $f = Float ("3.41 is PI");
- $f->value ("3.14 is PI");
- print $f->value, "\n";
- return [ $f ];
-
-=cut
-
-package YaST::YCP::Float;
-use strict;
-use warnings;
-use diagnostics;
-
-
-# a Float is just a blessed reference to a scalar
-# just like Boolean, so use it!
-
-our @ISA = qw (YaST::YCP::Boolean);
-
-=head2 Path
-
-Not implemented yet.
-
-=cut
-
-=head2 String
-
-An explicitly typed string, useful to put in heterogenous data structures.
-
- use YaST::YCP qw(:DATA);
-
- $s = String (42);
- $s->value (1 + 1);
- print $s->value, "\n";
- return [ $s ];
-
-=cut
-
-package YaST::YCP::String;
-use strict;
-use warnings;
-use diagnostics;
-
-# a String is just a blessed reference to a scalar
-# just like Boolean, so use it!
-
-our @ISA = qw (YaST::YCP::Boolean);
-
-=head2 Symbol
-
- use YaST::YCP qw(:DATA);
-
- $s = Symbol ("next");
- $s->value ("back");
- print $s->value, "\n";
- return Term ("id", $s);
-
-=cut
-
-package YaST::YCP::Symbol;
-use strict;
-use warnings;
-use diagnostics;
-
-
-# a Symbol is just a blessed reference to a scalar
-# just like Boolean, so use it!
-
-our @ISA = qw (YaST::YCP::Boolean);
-
-=head2 Term
-
- $t = new YaST::YCP::Term("CzechBox", "Accept spam", new YaST::YCP::Boolean(0));
- $t->name ("CheckBox");
- print $t->args->[0], "\n";
- UIx::OpenDialog ($t);
-
-=cut
-
-package YaST::YCP::Term;
-use strict;
-use warnings;
-use diagnostics;
-
-# a Term has a name and arguments
-
-sub new
-{
-    my $class = shift;
-    my $name = shift;
-    my $args = [ @_ ];
-    return bless { name => $name, args => $args }, $class
-}
-
-# get/set
-sub name
-{
-    # see "Constructors and Instance Methods" in perltoot
-    my $self = shift;
-    if (@_) { $self->{name} = shift; }
-    return $self->{name};
-}
-
-# get/set
-sub args
-{
-    # see "Constructors and Instance Methods" in perltoot
-    my $self = shift;
-    if (@_) { @{ $self->{args} } = @_; }
-    # HACK:
-    # because I don't want to process multiple return values,
-    # I return it as a reference
-    return $self->{args};
-}
-
-1;
diff --git a/src/ruby/YaPI.pm.in b/src/ruby/YaPI.pm.in
deleted file mode 100644 (file)
index c991d30..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-# -*- perl -*-
-# @configure_input@
-# $Id: YaPI.pm.in 33405 2006-10-13 13:12:42Z mvidner $
-
-package YaPI;
-
-=head1 NAME
-
-YaPI - common functions for modules implementing YaST API
-
-=cut
-
-BEGIN {
-    # substituted by configure
-    my $modules = '@yast2dir4perl@/modules';
-    # unconditional 'use lib' could override a "use lib ." that
-    # we do during compilation, #197099
-    grep { $_ eq $modules } @INC or unshift(@INC, $modules);
-}
-use strict;
-
-use Exporter;
-our @ISA = qw(Exporter);
-our @EXPORT = qw(textdomain __);
-
-use YaST::YCP;
-use ycp;
-
-use Locale::gettext ("!textdomain");
-use POSIX ();     # Needed for setlocale()
-
-POSIX::setlocale(&POSIX::LC_MESSAGES, "");
-
-our %TYPEINFO;
-my %__error = ();
-my $VERSION = "";
-our @CAPABILITIES = ();
-
-=head2 base functions
-
-These are to be used by modules that use YaPI as their base class.
-
-  use YaPI;
-  our @ISA = ("YaPI");
-
-=head3 Interface
-
-Returns a reference to a list of hashes describing the functions
-in the current package. The information is taken from TYPEINFO.
-
-  [
-   {
-      functionName => "contains",
-      return => "boolean",
-      argument => [ "string", ["list", "string"]],
-   },
-   ...
-  ]
-
-=cut
-
-BEGIN { $TYPEINFO{Interface} = ["function", "any"]; }
-sub Interface {
-    my $self = shift;
-    my @ret = ();
-
-    no strict "refs";
-    my %TI = %{"${self}::TYPEINFO"};
-
-    foreach my $k (keys %TYPEINFO) {
-        $TI{$k} = $TYPEINFO{$k};
-    }
-
-    foreach my $funcName (sort keys %TI) {
-        my @dummy = @{$TI{$funcName}};
-        my $hash = {};
-
-        $hash->{'functionName'} = $funcName;
-        $hash->{'return'}       = $dummy[1];
-        splice(@dummy, 0, 2);
-        $hash->{'argument'} = \@dummy;
-        push @ret, $hash;
-    }
-    return \@ret;
-}
-
-=head3 Version
-
-Returns the version of the current package.
-
-=cut
-
-BEGIN { $TYPEINFO{Version} = ["function", "string"]; }
-sub Version {
-    my $self = shift;
-    no strict "refs";
-    return ${"${self}::VERSION"};
-}
-
-=head3 Supports
-
-Greps C<@CAPABILITIES> of the current package.
-
-  if (YaPI::Foo->Supports ("frobnicate")) {...}
-
-=cut
-
-BEGIN { $TYPEINFO{Supports} = ["function", "boolean", "string"]; }
-sub Supports {
-    my $self = shift;
-    my $cap  = shift;
-
-    no strict "refs";
-    my @c = @{"${self}::CAPABILITIES"};
-    foreach my $k (@CAPABILITIES) {
-        push @c, $k;
-    }
-
-    return !!grep( ($_ eq $cap), @c);
-}
-
-
-=head3 SetError
-
-Logs an error and remembers it for L</Error>.
-
-Error map:
-
-  {
-    code               # mandatory, an uppercase short string
-    summary
-    description
-  # if all of the following are missing, caller () is used
-    package
-    file
-    line
-  }
-
-=cut
-
-BEGIN { $TYPEINFO{SetError} = ["function", "boolean", ["map", "string", "any" ]]; }
-sub SetError {
-    my $self = shift;
-    %__error = @_;
-    if( !$__error{package} && !$__error{file} && !$__error{line})
-    {
-        @__error{'package','file','line'} = caller();
-    }
-    if ( defined $__error{summary} ) {
-        y2error($__error{code}."[".$__error{line}.":".$__error{file}."] ".$__error{summary});
-    } else {
-        y2error($__error{code});
-    }
-    if(defined $__error{description} && $__error{description} ne "") {
-        y2error("Description: ".$__error{description});
-    }
-
-    return undef;
-}
-
-=head3 Error
-
-Returns the error set by L</SetError>
-
-=cut
-
-BEGIN { $TYPEINFO{Error} = ["function", ["map", "string", "any"] ]; }
-sub Error {
-    my $self = shift;
-    return \%__error;
-}
-
-=head2 i18n
-
-C<< use YaPI; >>
-
-C<< textdomain "mydomain"; >>
-
-Just use a double underscore to mark text to be translated: C<__("my text")>.
-Both C<textdomain> and C<__> are exported to the calling package.
-
-These must not be used any longer because they collide with symbols
-exported by this module:
-
- #  use Locale::gettext;    # textdomain
- #  sub _ { ... }
-
-These don't hurt but aren't necessary:
-
- #  use POSIX ();
- #  POSIX::setlocale(LC_MESSAGES, "");    # YaPI calls it itself now
-
-=head3 textdomain
-
-Calls Locale::gettext::textdomain
-and also
-remembers an association between the calling package and the
-domain. Later calls of __ use this domain as an argument to dgettext.
-
-=cut
-
-# See also bug 38613 where untranslated texts were seen because
-# a random textdomain was used instead of the proper one.
-my %textdomains;
-
-sub textdomain
-{
-    my $domain = shift;
-    my ($package, $filename, $line) = caller;
-
-    if (defined ($textdomains{package}))
-    {
-       if ($textdomains{package} ne $domain)
-       {
-           y2error ("Textdomain '$domain' overrides old textdomain '$textdomains{package}' in package $package, $filename:$line");
-       }
-    }
-    $textdomains{$package} = $domain;
-    return Locale::gettext::textdomain ($domain);
-}
-
-=head3 __ (double underscore)
-
-Calls Locale::gettext::dgettext, supplying the textdomain of the calling
-package (set by calling textdomain).
-
-Note: the single underscore function (_) will be removed because it
-is automaticaly exported to main:: which causes namespace conflicts.
-
-=cut
-
-# bug 39954: __ better than _
-sub __ {
-    my $msgid = shift;
-    my $package = caller;
-    my $domain = $textdomains{$package};
-    return Locale::gettext::dgettext ($domain, $msgid);
-}
-
-# Compatibility by partial typeglob assignment:
-# &_ will call &__ but $_ will not be $__ which would happen
-# if we just asigned *_ = *__.
-# Cannot just call __ from _ because of "caller".
-*_ = \&__;
-
-1;
index e205cc0..9bc01e9 100644 (file)
@@ -23,6 +23,44 @@ ENV['LD_LIBRARY_PATH'] = "/usr/lib/YaST2/plugin"
 # Load the native part (.so)
 require 'yastx'
 
+module YCP
+  def self.method_missing(id, *args)
+    puts "stop"
+  end
+
+  def self.add_ycp_module(mname)
+    puts "import #{mname}"
+    YCP::import(mname)
+    m = Module.new
+    YCP::each_symbol(mname) do |sname,stype|
+      if (stype == :function) and !sname.empty?
+        m.module_eval <<-"END"
+          def self.#{sname}(*args)
+            args.insert(0, "#{mname}")
+            args.insert(0, :#{sname})
+            puts "to forward call #{sname.to_s} in #{mname}"
+            return YCP::forward_call(args)
+          end
+        END
+      end
+    end
+    YCP.const_set(mname, m)
+  end
+end
+
+module Kernel
+  alias require_ require 
+  def require(name)
+    if name =~ /^ycp\/(.+)$/
+      ycpns = $1
+      YCP::add_ycp_module(ycpns.capitalize)
+      return true
+    end
+    return require_(name)
+  end
+end
+
+
 module YaST
   module Ui
     #my @e_logging = qw(y2debug y2milestone y2warning y2error y2security y2internal);
index 2ecda54..8e858a5 100644 (file)
@@ -1,30 +1,32 @@
 
-SET( SWIG_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/yast_wrap.cxx" )
-SET( SWIG_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/yast.i" )
+SET( SWIG_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/ycp_wrap.cxx" )
+SET( SWIG_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/ycp.i" )
 
 ADD_CUSTOM_COMMAND (
-   OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/yast_wrap.cxx
+   OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/ycp_wrap.cxx
    COMMAND ${CMAKE_COMMAND} -E echo_append "Creating wrapper code..."
 #COMMAND ${SWIG_EXECUTABLE} -c++ -ruby -autorename -xmlout parse.xml -I/usr/include swig/zypp.i
-   COMMAND ${SWIG_EXECUTABLE} -I${YAST_INCLUDE_DIR} -c++ -ruby -autorename -xmlout ${CMAKE_CURRENT_BINARY_DIR}/parse.xml -o ${CMAKE_CURRENT_BINARY_DIR}/yast_wrap.cxx -I${ZYPP_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/yast.i
+   COMMAND ${SWIG_EXECUTABLE} -I${YAST_INCLUDE_DIR} -c++ -ruby -autorename -xmlout ${CMAKE_CURRENT_BINARY_DIR}/parse.xml -o ${CMAKE_CURRENT_BINARY_DIR}/ycp_wrap.cxx -I${ZYPP_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/ycp.i
    COMMAND ${CMAKE_COMMAND} -E echo "Done."
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/yast.i
+   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/ycp.i
 )
 
 ADD_CUSTOM_TARGET( glue
    DEPENDS ${SWIG_OUTPUT}
 )
 
-ADD_LIBRARY( ryast SHARED "${CMAKE_CURRENT_BINARY_DIR}/yast_wrap.cxx" )
-SET_TARGET_PROPERTIES( ryast PROPERTIES PREFIX "" )
-ADD_DEPENDENCIES( ryast glue )
+ADD_LIBRARY( ycpx SHARED "${CMAKE_CURRENT_BINARY_DIR}/ycp_wrap.cxx" )
+SET_TARGET_PROPERTIES( ycpx PROPERTIES PREFIX "" )
+ADD_DEPENDENCIES( ycpx glue )
 
 INCLUDE_DIRECTORIES( ${RUBY_INCLUDE_PATH} )
 INCLUDE_DIRECTORIES( ${YAST_INCLUDE_DIR} )
-TARGET_LINK_LIBRARIES( ryast ${YAST_LIBRARY} )
-TARGET_LINK_LIBRARIES( ryast ${YAST_YCP_LIBRARY} )
-TARGET_LINK_LIBRARIES( ryast ${YAST_PLUGIN_WFM_LIBRARY} )
-TARGET_LINK_LIBRARIES( ryast ${RUBY_LIBRARY} )
+TARGET_LINK_LIBRARIES( ycpx ${YAST_LIBRARY} )
+TARGET_LINK_LIBRARIES( ycpx ${YAST_YCP_LIBRARY} )
+TARGET_LINK_LIBRARIES( ycpx ${YAST_PLUGIN_WFM_LIBRARY} )
+TARGET_LINK_LIBRARIES( ycpx ${RUBY_LIBRARY} )
 
-INSTALL(TARGETS ryast LIBRARY DESTINATION ${RUBY_ARCH_DIR} )
\ No newline at end of file
+INSTALL(TARGETS ycpx LIBRARY DESTINATION ${RUBY_ARCH_DIR} )
+
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ycp.rb DESTINATION ${RUBY_VENDORLIB_DIR} )
\ No newline at end of file
index 5562714..14af158 100644 (file)
@@ -1,8 +1,12 @@
-%module ryast
+%module ycp
 %include std_string.i
 %include stl.i
  %{
 /* Includes the header in the wrapper code */
+#define y2log_component "Y2Ruby"
+#include <y2util/y2log.h>
+
+#include <ycp/YCode.h>
 #include <ycp/YCPCode.h>
 #include <ycp/YCPElement.h>
 #include <ycp/YCPExternal.h>
 #include <ycp/YCPString.h>
 #include <ycp/YCPInteger.h>
 #include <ycp/YCPFloat.h>
-
-#include <y2/Y2ComponentBroker.h>
-#include <y2/Y2Namespace.h>
-#include <y2/Y2Component.h>
-#include <y2/Y2Function.h>
-#include <y2/SymbolEntry.h>
-#include <y2util/Ustring.h>
-#include <Y2.h>
-
+#include <ycp/YCPPath.h>
+#include <ycp/YCPTerm.h>
+#include <ycp/YCPVoid.h>
 #include <ycp/Import.h>
-
+#include <ycp/YBlock.h>
+#include <ycp/YCPByteblock.h>
+#include <ycp/Parser.h>
 #include <ycp/pathsearch.h>
 
-#define y2log_component "Y2Ruby"
 
 //static swig_type_info _swigt__p_YCPValue;
 
- %}
+%}
 
 #ifdef SWIGRUBY
 //%include "ruby.i"
 %rename("!=") "operator!=";
 %rename("!") "operator!";
 %rename("==") "operator==";
-    
-%typemap(in) int YCPValue {
-  // TODO conver integers, and add support for lists, ah, and boleans!
-  switch (TYPE($1))
-  {
-    case T_STRING:
-    $result = YCPString(RSTRING ($1)->ptr);
-    break;
-    case T_TRUE:
-    $result = YCPBoolean(true);
-    break;
-    case T_FALSE:
-    $result = YCPBoolean(false);
-    break;
-    case T_FIXNUM:
-    $result = YCPInteger(NUM2LONG($1));
-    break;
-    case T_FLOAT:
-    $result = YCPFloat(NUM2DBL($1));
-    break;
-    case T_ARRAY:
-    // FIXME
-    break;
-    case T_HASH:
-    // FIXME
-    break;
-    case T_DATA:
-    rb_raise( rb_eRuntimeError, "Object");
-    break;
-  }
-  std::cout << TYPE($1) << std::endl;
-  rb_raise( rb_eRuntimeError, "Conversion of Ruby type not supported");
-  $result = YCPValue();
-}
-
-%typemap(out) YCPValue {
-  // TODO
-  // YT_BYTEBLOCK YT_PATH YT_SYMBOL YT_LIST YT_TERM YT_MAP YT_CODE YT_RETURN YT_BREAK YT_ENTRY YT_ERROR  YT_REFERENCE YT_EXTERNA
-  if($1->isVoid())
-  {
-    $result = Qnil;
-  }
-  else if($1->isBoolean())
-  {
-    $result = $1->asBoolean()->value() ? Qtrue : Qfalse;
-  }
-  else if($1->isString())
-  {
-    $result = rb_str_new2($1->asString()->value().c_str());
-  }
-  else if($1->isInteger())
-  {
-    $result = INT2NUM( $1->asInteger()->value() );
-  }
-  else if( $1->isMap() )
-  {
-    VALUE rbhash;
-    rbhash = rb_hash_new();
-    YCPMap map = $1->asMap();
-    printf("map size %d\n", map.size());
-    
-    for ( YCPMapIterator it = map.begin(); it != map.end(); ++it )
-    {
-      YCPValue *key = new YCPValue(it.key());
-      YCPValue *value = new YCPValue(it.value());
-      VALUE rkey = SWIG_NewPointerObj(key, SWIGTYPE_p_YCPValue, 1);
-      VALUE rvalue = SWIG_NewPointerObj(value, SWIGTYPE_p_YCPValue, 1);
-      rb_hash_aset(rbhash, rkey, rvalue );
-    }
-    $result = rbhash;
-  }
-  else if($1->isList())
-  {
-    VALUE rblist;
-    rblist = rb_ary_new();
-    YCPList list = $1->asList();
-    printf("list size %d\n",list.size()); 
-    for (int i=0; i < list.size(); i++)
-    {
-      YCPValue *value = new YCPValue(list.value(i));
-       VALUE rvalue = SWIG_NewPointerObj(value, SWIGTYPE_p_YCPValue, 1);
-      rb_ary_push( rblist, rvalue);
-    }
-    $result = rblist;
-  }
-  rb_raise( rb_eRuntimeError, "Conversion of YCP type %s not supported", $1->toString().c_str() );
-  $result = Qnil;
-}
-
-//%include "y2util/RepDef.h"
-%include "y2/Y2ComponentBroker.h"
-%include "y2/Y2Namespace.h"
-%include "y2/Y2Component.h"
-%include "y2/Y2Function.h"
-
-%ignore SymbolEntryPtr::_nameHash;
-%ignore SymbolEntry::emptyUstring;
-    
-class SymbolEntry
-{
-public:
-    //static UstringHash* _nameHash;
-    //static Ustring emptyUstring;
-public:
-    typedef enum {
-       c_unspec = 0,           //  0 unspecified local symbol (sets m_global = false)
-       c_global,               //  1 unspecified global symbol (translates to c_unspec, sets m_global = true)
-       c_module,               //  2 a module identifier
-       c_variable,             //  3 a variable
-       c_reference,            //  4 a reference to a variable
-       c_function,             //  5 a defined function
-       c_builtin,              //  6 a builtin function
-       c_typedef,              //  7 a type
-       c_const,                //  8 a constant (a read-only c_variable)
-       c_namespace,            //  9 a namespace identifier
-       c_self,                 // 10 the current namespace (namespace prefix used in namespace definition)
-       c_predefined,           // 11 a predefined namespace identifier
-       c_filename              // 12 a filename (used in conjunction with TableEntry to store definition locations)
-    } category_t;
-public:
-    // create symbol beloging to namespace (at position)
-    SymbolEntry (const Y2Namespace* name_space, unsigned int position, const char *name, category_t cat, constTypePtr type);
-
-    virtual ~SymbolEntry ();
-
-    // symbols link to the defining namespace
-    const Y2Namespace *nameSpace () const;
-    void setNamespace (const Y2Namespace *name_space);
-    virtual bool onlyDeclared () const { return false; }
-
-    unsigned int position () const;
-    void setPosition (unsigned int position);
-
-    bool isGlobal () const;
-    void setGlobal (bool global);
-
-    bool isModule () const { return m_category == c_module; }
-    bool isVariable () const { return m_category == c_variable; }
-    bool isReference () const { return m_category == c_reference; }
-    bool isFunction () const { return m_category == c_function; }
-    bool isBuiltin () const { return m_category == c_builtin; }
-    bool isNamespace () const { return m_category == c_namespace; }
-    bool isSelf () const { return m_category == c_self; }
-    bool isFilename () const { return m_category == c_filename; }
-    bool isPredefined () const { return m_category == c_predefined; }
-
-    bool likeNamespace () const { return isModule() || isNamespace() || isSelf(); }
-
-    const char *name () const;
-    category_t category () const;
-    void setCategory (category_t cat);
-    constTypePtr type () const;
-    string catString () const;
-    void setType (constTypePtr type);
-    YCPValue setValue (YCPValue value);
-    YCPValue value () const;
-    
-    void push ();
-    void pop ();
-
-    virtual string toString (bool with_type = true) const;
-};
-
-template < typename T >
-class Ptr {
-  public:
-  T *operator->();
-};
-%template (SymbolEntryPtr) Ptr<SymbolEntry>;
-
-%include "ycp/SymbolTable.h"
-
-%include "ycp/Import.h"
-%include "ycp/Type.h"
-%include "ycp/TypePtr.h"
+
+%include <ycp/YCode.h>
+%include <ycp/YCPCode.h>
+//%include <ycp/YCPElement.h>
+//%include <ycp/YCPExternal.h>
+%include <ycp/YCPValue.h>
+
+%nodefaultctor YCPBoolean;
+%include <ycp/YCPBoolean.h>
+
+//%include <ycp/YCPList.h>
+//%include <ycp/YCPMap.h>
+
+%nodefaultctor YCPString;
+%include <ycp/YCPString.h>
+
+%nodefaultctor YCPInteger;
+%include <ycp/YCPInteger.h>
+
+%nodefaultctor YCPFloat;
+%include <ycp/YCPFloat.h>
+
+//%include <ycp/Import.h>
+
+%nodefaultctor YCPExternal;
+%include <ycp/YCPExternal.h>
+
+%nodefaultctor YCPSymbol;
+%include <ycp/YCPSymbol.h>
+
+%nodefaultctor YCPTerm;
+%include <ycp/YCPTerm.h>
+
+%nodefaultctor YCPByteblock;
+%include <ycp/YCPByteblock.h>
+
+%include <ycp/YBlock.h>
+%include <ycp/Parser.h>
+//%include <ycp/pathsearch.h>
+
diff --git a/src/swig/ycp.i b/src/swig/ycp.i
new file mode 100644 (file)
index 0000000..66cb9fd
--- /dev/null
@@ -0,0 +1,93 @@
+%module ycpx
+%include std_string.i
+%include stl.i
+%include file.i
+ %{
+/* Includes the header in the wrapper code */
+#define y2log_component "Y2Ruby"
+#include <y2util/y2log.h>
+
+#include <ycp/YCode.h>
+#include <ycp/YCPCode.h>
+#include <ycp/YCPElement.h>
+#include <ycp/YCPExternal.h>
+#include <ycp/YCPValue.h>
+#include <ycp/YCPBoolean.h>
+#include <ycp/YCPList.h>
+#include <ycp/YCPMap.h>
+#include <ycp/YCPString.h>
+#include <ycp/YCPInteger.h>
+#include <ycp/YCPFloat.h>
+#include <ycp/YCPPath.h>
+#include <ycp/YCPTerm.h>
+#include <ycp/YCPVoid.h>
+#include <ycp/Import.h>
+#include <ycp/YBlock.h>
+#include <ycp/YCPByteblock.h>
+#include <ycp/Parser.h>
+#include <ycp/pathsearch.h>
+#include <y2util/Rep.h>
+
+//static swig_type_info _swigt__p_YCPValue;
+
+%}
+
+%rename("+") "operator+";
+%rename("<<") "operator<<";
+%rename("!=") "operator!=";
+%rename("!") "operator!";
+%rename("==") "operator==";
+
+//%include <y2util/Rep.h>
+
+%include <ycp/YCPCode.h>
+
+//%include <ycp/YCPElement.h>
+//%include <ycp/YCPExternal.h>
+%include <ycp/YCPValue.h>
+
+%nodefaultctor YCPBoolean;
+%include <ycp/YCPBoolean.h>
+
+//%include <ycp/YCPList.h>
+//%include <ycp/YCPMap.h>
+
+%nodefaultctor YCPString;
+%include <ycp/YCPString.h>
+
+%nodefaultctor YCPInteger;
+%include <ycp/YCPInteger.h>
+
+%nodefaultctor YCPFloat;
+%include <ycp/YCPFloat.h>
+
+//%include <ycp/Import.h>
+
+%nodefaultctor YCPExternal;
+%include <ycp/YCPExternal.h>
+
+%nodefaultctor YCPSymbol;
+%include <ycp/YCPSymbol.h>
+
+%nodefaultctor YCPTerm;
+%include <ycp/YCPTerm.h>
+
+%nodefaultctor YCPByteblock;
+%include <ycp/YCPByteblock.h>
+
+%include <ycp/YCode.h>
+%predicate YCode::isBlock();
+%predicate YCode::isStatement();
+
+class YCodePtr
+{
+  public:
+  YCodePtr(const YCodePtr &);
+  YCodePtr(YCode*);
+  YCode* operator->();
+};
+
+%include <ycp/Parser.h>
+//%include <ycp/pathsearch.h>
+
+%include <ycp/YBlock.h>
\ No newline at end of file
diff --git a/src/swig/ycp.rb b/src/swig/ycp.rb
new file mode 100644 (file)
index 0000000..2a4fc1d
--- /dev/null
@@ -0,0 +1,24 @@
+# -----------------------------------------------------------------------\
+# |                                                                      |
+# |                      __   __    ____ _____ ____                      |
+# |                      \ \ / /_ _/ ___|_   _|___ \                     |
+# |                       \ V / _` \___ \ | |   __) |                    |
+# |                        | | (_| |___) || |  / __/                     |
+# |                        |_|\__,_|____/ |_| |_____|                    |
+# |                                                                      |
+# |                                                                      |
+# | ruby language support                              (C) Novell Inc.   |
+# \----------------------------------------------------------------------/
+#
+# Author: Duncan Mac-Vicar <dmacvicar@suse.de>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version
+# 2 of the License, or (at your option) any later version.
+#
+
+ENV['LD_LIBRARY_PATH'] = "/usr/lib/YaST2/plugin"
+
+# Load the native part (.so)
+require 'ycpx'
\ No newline at end of file